123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- /*
- * Copyright (c) 2023 HPMicro
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
- #ifndef HPM_PLB_DRV_H
- #define HPM_PLB_DRV_H
- #include "hpm_common.h"
- #include "hpm_plb_regs.h"
- /**
- * @brief PLB driver APIs
- * @defgroup plb_interface PLB driver APIs
- * @ingroup io_interfaces
- * @{
- */
- #define PLB_SLICE_MASK (0xf)
- #define PLB_SLICE_HIGH_BIT_MASK_SET(slice) (PLB_SLICE_MASK << ((slice - plb_type_b_slice_8) << 2))
- #define PLB_SLICE_HIGH_BIT_SHIFT(slice) ((slice - plb_type_b_slice_8) << 2)
- #define PLB_SLICE_LOW_BIT_MASK_SET(slice) (PLB_SLICE_MASK << (slice << 2))
- #define PLB_SLICE_LOW_BIT_SHIFT(slice) (slice << 2)
- /**
- * @brief plb channels
- *
- */
- typedef enum plb_chn {
- #ifdef PLB_TYPE_B_0
- plb_chn0 = PLB_TYPE_B_0,
- #endif
- #ifdef PLB_TYPE_B_1
- plb_chn1 = PLB_TYPE_B_1,
- #endif
- #ifdef PLB_TYPE_B_2
- plb_chn2 = PLB_TYPE_B_2,
- #endif
- #ifdef PLB_TYPE_B_3
- plb_chn3 = PLB_TYPE_B_3,
- #endif
- #ifdef PLB_TYPE_B_4
- plb_chn4 = PLB_TYPE_B_4,
- #endif
- #ifdef PLB_TYPE_B_5
- plb_chn5 = PLB_TYPE_B_5,
- #endif
- #ifdef PLB_TYPE_B_6
- plb_chn6 = PLB_TYPE_B_6,
- #endif
- #ifdef PLB_TYPE_B_7
- plb_chn7 = PLB_TYPE_B_7,
- #endif
- } plb_chn_t;
- /**
- * @brief PLB look-up table unit
- *
- */
- typedef enum plb_type_a_lut_num {
- #ifdef PLB_TYPE_A_0
- plb_type_a_table0 = PLB_TYPE_A_0,
- #endif
- #ifdef PLB_TYPE_A_1
- plb_type_a_table1 = PLB_TYPE_A_1,
- #endif
- #ifdef PLB_TYPE_A_2
- plb_type_a_table2 = PLB_TYPE_A_2,
- #endif
- #ifdef PLB_TYPE_A_3
- plb_type_a_table3 = PLB_TYPE_A_3,
- #endif
- #ifdef PLB_TYPE_A_4
- plb_type_a_table4 = PLB_TYPE_A_4,
- #endif
- #ifdef PLB_TYPE_A_5
- plb_type_a_table5 = PLB_TYPE_A_5,
- #endif
- #ifdef PLB_TYPE_A_6
- plb_type_a_table6 = PLB_TYPE_A_6,
- #endif
- #ifdef PLB_TYPE_A_7
- plb_type_a_table7 = PLB_TYPE_A_7,
- #endif
- } plb_type_a_lut_num_t;
- /**
- * @brief PLB truth table configuration unit
- *
- */
- typedef union {
- struct {
- uint16_t index0_1bit_out: 1;
- uint16_t index1_1bit_out: 1;
- uint16_t index2_1bit_out: 1;
- uint16_t index3_1bit_out: 1;
- uint16_t index4_1bit_out: 1;
- uint16_t index5_1bit_out: 1;
- uint16_t index6_1bit_out: 1;
- uint16_t index7_1bit_out: 1;
- uint16_t index8_1bit_out: 1;
- uint16_t index9_1bit_out: 1;
- uint16_t index10_1bit_out: 1;
- uint16_t index11_1bit_out: 1;
- uint16_t index12_1bit_out: 1;
- uint16_t index13_1bit_out: 1;
- uint16_t index14_1bit_out: 1;
- uint16_t index15_1bit_out: 1;
- };
- uint16_t val;
- } plb_type_a_truth_t;
- /**
- * @brief Index of slice
- *
- */
- typedef enum plb_type_b_lut_slice {
- plb_type_b_slice_0 = 0,
- plb_type_b_slice_1 = 1,
- plb_type_b_slice_2 = 2,
- plb_type_b_slice_3 = 3,
- plb_type_b_slice_4 = 4,
- plb_type_b_slice_5 = 5,
- plb_type_b_slice_6 = 6,
- plb_type_b_slice_7 = 7,
- plb_type_b_slice_8 = 8,
- plb_type_b_slice_9 = 9,
- plb_type_b_slice_10 = 10,
- plb_type_b_slice_11 = 11,
- plb_type_b_slice_12 = 12,
- plb_type_b_slice_13 = 13,
- plb_type_b_slice_14 = 14,
- plb_type_b_slice_15 = 15,
- } plb_type_b_lut_slice_t;
- /**
- * @brief Configuration of slice
- *
- */
- typedef enum plb_type_b_slice_opt {
- plb_slice_opt_keep = 0, /**< The data unit keeps the value of the previous cycle */
- plb_slice_opt_get_cmp0_val = 1, /**< The data unit will take the value of the cmp0 register as the value for the next cycle */
- plb_slice_opt_get_cmp1_val = 2, /**< The data unit will take the value of the cmp1 register as the value for the next cycle */
- plb_slice_opt_get_cmp2_val = 3, /**< The data unit will take the value of the cmp2 register as the value for the next cycle */
- plb_slice_opt_add_one = 4, /**< The next cycle value of the data cell is the current value plus 1 */
- plb_slice_opt_add_two = 5, /**< The next cycle value of the data cell is the current value plus 2 */
- plb_slice_opt_sub_one = 6, /**< The next cycle value of the data cell is the current value minus 1 */
- plb_slice_opt_sub_two = 7, /**< The next cycle value of the data cell is the current value minus 2 */
- plb_slice_opt_shift_left = 4 << 8, /**< The value of the next cycle of the data cell is shifted one place to the left of the current value */
- plb_slice_opt_shift_left_add_one = 5 << 8, /**< The next cycle value of the data cell is the current value shifted one place to the left, with the lower bit complemented by one */
- plb_slice_opt_shift_right = 6 << 8, /**< The value of the next cycle of the data cell is shifted one place to the right of the current value */
- plb_slice_opt_shift_right_add_one = 7 << 8, /**< The next cycle value of the data cell is the current value shifted one place to the right, with the lower bit complemented by one */
- } plb_type_b_slice_opt_t;
- /**
- * @brief Comparator index
- *
- */
- typedef enum plb_type_b_cmp {
- plb_type_b_cmp0 = PLB_TYPE_B_CMP_0,
- plb_type_b_cmp1 = PLB_TYPE_B_CMP_1,
- plb_type_b_cmp2 = PLB_TYPE_B_CMP_2,
- plb_type_b_cmp3 = PLB_TYPE_B_CMP_3,
- } plb_type_b_cmp_t;
- /**
- * @brief Comparator operation
- *
- */
- typedef enum plb_type_b_cmp_mode {
- plb_cmp_mode_out_zero = 0, /**< output zero */
- plb_cmp_mode_out_one = 1, /**< output one */
- plb_cmp_mode_gt = 2, /**< Data unit greater than cmp output one, otherwise output zero */
- plb_cmp_mode_lt = 3, /**< Data unit less than cmp output one, otherwise output zero */
- plb_cmp_mode_eq = 4, /**< Data unit equal to cmp output one, otherwise output zero */
- plb_cmp_mode_ne = 5, /**< Data unit not equal to cmp output one, otherwise output zero */
- plb_cmp_mode_ge = 6, /**< Data unit greater than or equal to cmp output one, otherwise output zero */
- plb_cmp_mode_le = 7, /**< Data unit less than or equal to cmp output one, otherwise output zero */
- plb_cmp_mode_and_mask = 10, /**< The data cell corresponding to the bit set to one by cmp is and */
- plb_cmp_mode_or_mask = 11, /**< The data cell corresponding to the bit set to one by cmp is or */
- plb_cmp_mode_xor_mask = 12, /**< The data cell corresponding to the bit set to one by cmp is xor */
- plb_cmp_mode_nand_mask = 13, /**< The data cell corresponding to the bit set to one by cmp is nand */
- plb_cmp_mode_nor_mask = 14, /**< The data cell corresponding to the bit set to one by cmp is nor */
- plb_cmp_mode_xnor_mask = 15, /**< The data cell corresponding to the bit set to one by cmp is xnor */
- } plb_type_b_cmp_mode_t;
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * @brief Configuring the truth table for lookup tables
- *
- * @param plb @ref PLB_Type plb base
- * @param chn @ref plb_chn_t
- * @param lut_num @ref plb_type_a_lut_num_t
- * @param truth @ref plb_type_a_truth_t
- */
- static inline void plb_type_a_set_lut(PLB_Type *plb, plb_chn_t chn, plb_type_a_lut_num_t lut_num, plb_type_a_truth_t *truth)
- {
- plb->TYPE_A[chn].LOOKUP_TABLE[lut_num] = PLB_TYPE_A_LOOKUP_TABLE_LOOKUP_TABLE_SET(truth->val);
- }
- /**
- * @brief The software injects a cycle value into the TYPE A channel.
- *
- * @param plb @ref PLB_Type plb base
- * @param chn @ref plb_chn_t
- * @param inject_val Injected values
- */
- static inline void plb_type_a_inject_by_sw(PLB_Type *plb, plb_chn_t chn, uint8_t inject_val)
- {
- plb->TYPE_A[chn].SW_INJECT = PLB_TYPE_A_SW_INJECT_SW_INJECT_SET(inject_val);
- }
- /**
- * @brief Configure the value of the CMP
- *
- * @param plb @ref PLB_Type plb base
- * @param chn @ref plb_chn_t
- * @param cmp_index @ref plb_type_b_cmp_t
- * @param val CMP value
- */
- static inline void plb_type_b_set_cmp_val(PLB_Type *plb, plb_chn_t chn, plb_type_b_cmp_t cmp_index, uint32_t val)
- {
- plb->TYPE_B[chn].CMP[cmp_index] = PLB_TYPE_B_CMP_CMP_VALUE_SET(val);
- }
- /**
- * @brief Setting the mode of the CMP
- *
- * @param plb @ref PLB_Type plb base
- * @param chn @ref plb_chn_t
- * @param cmp_index @ref plb_type_b_cmp_t
- * @param cmp_mode @ref plb_type_b_cmp_mode_t
- */
- static inline void plb_type_b_set_cmp_mode(PLB_Type *plb, plb_chn_t chn, plb_type_b_cmp_t cmp_index, plb_type_b_cmp_mode_t cmp_mode)
- {
- plb->TYPE_B[chn].MODE = (plb->TYPE_B[chn].MODE & (~(PLB_TYPE_B_MODE_OUT0_SEL_MASK << (cmp_index << 2)))) |
- ((PLB_TYPE_B_MODE_OUT0_SEL_MASK & cmp_mode) << (cmp_index << 2));
- }
- /**
- * @brief Software injection values
- *
- * @param plb @ref PLB_Type plb base
- * @param chn @ref plb_chn_t
- * @param val value
- */
- static inline void plb_type_b_inject_by_sw(PLB_Type *plb, plb_chn_t chn, uint32_t val)
- {
- plb->TYPE_B[chn].SW_INJECT = val;
- }
- /**
- * @brief Configuring the PLB type_b's lookup table
- *
- * @param plb @ref PLB_Type plb base
- * @param chn @ref plb_chn_t
- * @param slice @ref plb_type_b_lut_slice_t
- * @param opt @ref plb_type_b_slice_opt_t
- */
- void plb_type_b_set_lut(PLB_Type *plb, plb_chn_t chn, plb_type_b_lut_slice_t slice, plb_type_b_slice_opt_t opt);
- #ifdef __cplusplus
- }
- #endif
- /**
- * @}
- */
- #endif /* HPM_PLB_DRV_H */
|