1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_sei_drv.h"
9 
sei_tranceiver_config_init(SEI_Type * ptr,uint8_t idx,sei_tranceiver_config_t * config)10 hpm_stat_t sei_tranceiver_config_init(SEI_Type *ptr, uint8_t idx, sei_tranceiver_config_t *config)
11 {
12     uint32_t tmp;
13     uint32_t baudrate;
14     uint32_t baud_div;
15     uint32_t sync_point;
16     uint8_t data_len;
17     uint32_t ck0_point;
18     uint32_t ck1_point;
19     uint32_t txd_point;
20     uint32_t rxd_point;
21 
22     tmp = SEI_CTRL_XCVR_CTRL_TRISMP_SET(config->tri_sample)
23         | SEI_CTRL_XCVR_CTRL_MODE_SET(config->mode);
24     ptr->CTRL[idx].XCVR.CTRL = tmp;
25 
26     switch (config->mode) {
27     case sei_synchronous_master_mode:
28         tmp = SEI_CTRL_XCVR_TYPE_CFG_DA_IDLEZ_SET(config->synchronous_master_config.data_idle_high_z)
29             | SEI_CTRL_XCVR_TYPE_CFG_DA_IDLEV_SET(config->synchronous_master_config.data_idle_state)
30             | SEI_CTRL_XCVR_TYPE_CFG_CK_IDLEZ_SET(config->synchronous_master_config.clock_idle_high_z)
31             | SEI_CTRL_XCVR_TYPE_CFG_CK_IDLEV_SET(config->synchronous_master_config.clock_idle_state);
32         ptr->CTRL[idx].XCVR.TYPE_CFG = tmp;
33 
34         baud_div = (config->src_clk_freq + (config->synchronous_master_config.baudrate >> 1u)) / config->synchronous_master_config.baudrate;
35         sync_point = baud_div >> 1u;
36         tmp = SEI_CTRL_XCVR_BAUD_CFG_SYNC_POINT_SET(sync_point)
37             | SEI_CTRL_XCVR_BAUD_CFG_BAUD_DIV_SET(baud_div - 1u);
38         ptr->CTRL[idx].XCVR.BAUD_CFG = tmp;
39 
40         ck0_point = baud_div >> 2u;
41         ck1_point = ck0_point * 3u;
42         tmp = SEI_CTRL_XCVR_CLK_CFG_CK0_POINT_SET(ck0_point)
43             | SEI_CTRL_XCVR_CLK_CFG_CK1_POINT_SET(ck1_point);
44         ptr->CTRL[idx].XCVR.CLK_CFG = tmp;
45         break;
46 
47     case sei_synchronous_slave_mode:
48         tmp = SEI_CTRL_XCVR_TYPE_CFG_DA_IDLEZ_SET(config->synchronous_slave_config.data_idle_high_z)
49             | SEI_CTRL_XCVR_TYPE_CFG_DA_IDLEV_SET(config->synchronous_slave_config.data_idle_state)
50             | SEI_CTRL_XCVR_TYPE_CFG_CK_IDLEZ_SET(config->synchronous_slave_config.clock_idle_high_z)
51             | SEI_CTRL_XCVR_TYPE_CFG_CK_IDLEV_SET(config->synchronous_slave_config.clock_idle_state);
52         ptr->CTRL[idx].XCVR.TYPE_CFG = tmp;
53 
54         baud_div = (config->src_clk_freq + (config->synchronous_slave_config.max_baudrate >> 1u)) / config->synchronous_slave_config.max_baudrate;
55         sync_point = (baud_div * 3u) >> 3u;
56         tmp = SEI_CTRL_XCVR_BAUD_CFG_SYNC_POINT_SET(sync_point)
57             | SEI_CTRL_XCVR_BAUD_CFG_BAUD_DIV_SET(baud_div - 1u);
58         ptr->CTRL[idx].XCVR.BAUD_CFG = tmp;
59 
60         ck0_point = config->synchronous_slave_config.ck0_timeout_us * (config->src_clk_freq / 1000000u);
61         if (ck0_point > 0x7FFFu) {
62             ck0_point = 0x7FFFu;
63         }
64         ck1_point = config->synchronous_slave_config.ck1_timeout_us * (config->src_clk_freq / 1000000u);
65         if (ck1_point > 0x7FFFu) {
66             ck1_point = 0x7FFFu;
67         }
68         ck1_point += 0x8000u;
69         tmp = SEI_CTRL_XCVR_CLK_CFG_CK0_POINT_SET(ck0_point)
70             | SEI_CTRL_XCVR_CLK_CFG_CK1_POINT_SET(ck1_point);
71         ptr->CTRL[idx].XCVR.CLK_CFG = tmp;
72     break;
73 
74     case sei_asynchronous_mode:
75     default:
76         data_len = config->asynchronous_config.data_len;
77         if (data_len > 0u) {
78             data_len--;
79         }
80         tmp = SEI_CTRL_XCVR_TYPE_CFG_WAIT_LEN_SET(config->asynchronous_config.wait_len)
81             | SEI_CTRL_XCVR_TYPE_CFG_DATA_LEN_SET(data_len)
82             | SEI_CTRL_XCVR_TYPE_CFG_PAR_POL_SET(config->asynchronous_config.parity)
83             | SEI_CTRL_XCVR_TYPE_CFG_PAR_EN_SET(config->asynchronous_config.parity_enable)
84             | SEI_CTRL_XCVR_TYPE_CFG_DA_IDLEZ_SET(config->asynchronous_config.data_idle_high_z)
85             | SEI_CTRL_XCVR_TYPE_CFG_DA_IDLEV_SET(config->asynchronous_config.data_idle_state);
86         ptr->CTRL[idx].XCVR.TYPE_CFG = tmp;
87 
88 #if defined(HPM_IP_FEATURE_SEI_ASYNCHRONOUS_MODE_V2) && HPM_IP_FEATURE_SEI_ASYNCHRONOUS_MODE_V2
89         baudrate = config->asynchronous_config.baudrate;
90         baud_div = (config->src_clk_freq + (baudrate >> 1u)) / baudrate;
91         sync_point = baud_div >> 1u;
92 #else
93         baudrate = (config->asynchronous_config.baudrate / 100) * 102;
94         baud_div = (config->src_clk_freq + (baudrate >> 1u)) / baudrate;
95         sync_point = (baud_div + 2u);
96 #endif
97         tmp = SEI_CTRL_XCVR_BAUD_CFG_SYNC_POINT_SET(sync_point)
98             | SEI_CTRL_XCVR_BAUD_CFG_BAUD_DIV_SET(baud_div - 1u);
99         ptr->CTRL[idx].XCVR.BAUD_CFG = tmp;
100 
101         txd_point = 0;
102         rxd_point = baud_div >> 1u;
103         tmp = SEI_CTRL_XCVR_DATA_CFG_TXD_POINT_SET(txd_point)
104             | SEI_CTRL_XCVR_DATA_CFG_RXD_POINT_SET(rxd_point);
105         ptr->CTRL[idx].XCVR.DATA_CFG = tmp;
106         break;
107     }
108 
109     return status_success;
110 }
111 
sei_cmd_data_format_config_init(SEI_Type * ptr,bool cmd_data_select,uint8_t idx,sei_data_format_config_t * config)112 hpm_stat_t sei_cmd_data_format_config_init(SEI_Type *ptr, bool cmd_data_select, uint8_t idx, sei_data_format_config_t *config)
113 {
114     uint32_t tmp;
115     uint8_t word_len;
116     uint8_t crc_len;
117 
118     if (cmd_data_select)
119 #if defined(HPM_IP_FEATURE_SEI_HAVE_CTRL2_12) && HPM_IP_FEATURE_SEI_HAVE_CTRL2_12
120         assert(idx < 13);
121 #else
122         assert(idx < 2);
123 #endif
124     else
125 #if defined(HPM_IP_FEATURE_SEI_HAVE_DAT10_31) && HPM_IP_FEATURE_SEI_HAVE_DAT10_31
126         assert(idx < 32);
127 #else
128         assert(idx < 10);
129 #endif
130 
131     word_len = config->word_len;
132     if (word_len > 0u) {
133         word_len--;
134     }
135     crc_len = config->crc_len;
136     if (crc_len > 0u) {
137         crc_len--;
138     }
139     tmp = SEI_DAT_MODE_MODE_SET(config->mode)
140         | SEI_DAT_MODE_SIGNED_SET(config->signed_flag)
141         | SEI_DAT_MODE_BORDER_SET(config->bit_order)
142         | SEI_DAT_MODE_WORDER_SET(config->word_order)
143         | SEI_DAT_MODE_CRC_INV_SET(config->crc_invert)
144         | SEI_DAT_MODE_CRC_SHIFT_SET(config->crc_shift_mode)
145         | SEI_DAT_MODE_WLEN_SET(word_len)
146         | SEI_DAT_MODE_CRC_LEN_SET(crc_len);
147     if (cmd_data_select) {
148         ptr->CTRL[idx].CMD.MODE = tmp;
149     } else {
150         ptr->DAT[idx].MODE = tmp;
151     }
152 
153     tmp = SEI_DAT_IDX_LAST_BIT_SET(config->last_bit)
154         | SEI_DAT_IDX_FIRST_BIT_SET(config->first_bit)
155         | SEI_DAT_IDX_MAX_BIT_SET(config->max_bit)
156         | SEI_DAT_IDX_MIN_BIT_SET(config->min_bit);
157     if (cmd_data_select) {
158         ptr->CTRL[idx].CMD.IDX = tmp;
159     } else {
160         ptr->DAT[idx].IDX = tmp;
161     }
162 
163     tmp = SEI_DAT_GOLD_GOLD_VALUE_SET(config->gold_value);
164     if (!cmd_data_select) {
165         ptr->DAT[idx].GOLD = tmp;
166     }
167 
168     tmp = SEI_DAT_CRCINIT_CRC_INIT_SET(config->crc_init_value);
169     if (!cmd_data_select) {
170         ptr->DAT[idx].CRCINIT = tmp;
171     }
172 
173     tmp = SEI_DAT_CRCPOLY_CRC_POLY_SET(config->crc_poly);
174     if (!cmd_data_select) {
175         ptr->DAT[idx].CRCPOLY = tmp;
176     }
177 
178     if (cmd_data_select) {
179         ptr->CTRL[idx].CMD.MODE |= SEI_CTRL_CMD_MODE_REWIND_MASK;
180     } else {
181         ptr->DAT[idx].MODE |= SEI_DAT_MODE_REWIND_MASK;
182     }
183 
184     return status_success;
185 }
186 
sei_cmd_table_config_init(SEI_Type * ptr,uint8_t idx,uint8_t table_idx,sei_command_table_config_t * config)187 hpm_stat_t sei_cmd_table_config_init(SEI_Type *ptr, uint8_t idx, uint8_t table_idx, sei_command_table_config_t *config)
188 {
189     uint32_t tmp;
190 
191     tmp = SEI_CTRL_CMD_TABLE_MIN_CMD_MIN_SET(config->cmd_min_value);
192     ptr->CTRL[idx].CMD_TABLE[table_idx].MIN = tmp;
193 
194     tmp = SEI_CTRL_CMD_TABLE_MAX_CMD_MAX_SET(config->cmd_max_value);
195     ptr->CTRL[idx].CMD_TABLE[table_idx].MAX = tmp;
196 
197     tmp = SEI_CTRL_CMD_TABLE_MSK_CMD_MASK_SET(config->cmd_mask_value);
198     ptr->CTRL[idx].CMD_TABLE[table_idx].MSK = tmp;
199 
200     tmp = SEI_CTRL_CMD_TABLE_PTA_PTR3_SET(config->instr_idx[3])
201         | SEI_CTRL_CMD_TABLE_PTA_PTR2_SET(config->instr_idx[2])
202         | SEI_CTRL_CMD_TABLE_PTA_PTR1_SET(config->instr_idx[1])
203         | SEI_CTRL_CMD_TABLE_PTA_PTR0_SET(config->instr_idx[0]);
204     ptr->CTRL[idx].CMD_TABLE[table_idx].PTA = tmp;
205 
206     tmp = SEI_CTRL_CMD_TABLE_PTB_PTR7_SET(config->instr_idx[7])
207         | SEI_CTRL_CMD_TABLE_PTB_PTR6_SET(config->instr_idx[6])
208         | SEI_CTRL_CMD_TABLE_PTB_PTR5_SET(config->instr_idx[5])
209         | SEI_CTRL_CMD_TABLE_PTB_PTR4_SET(config->instr_idx[4]);
210     ptr->CTRL[idx].CMD_TABLE[table_idx].PTB = tmp;
211 #if defined(HPM_IP_FEATURE_SEI_HAVE_PTCD) && HPM_IP_FEATURE_SEI_HAVE_PTCD
212     tmp = SEI_CTRL_CMD_TABLE_PTC_PTR11_SET(config->instr_idx[11])
213         | SEI_CTRL_CMD_TABLE_PTC_PTR10_SET(config->instr_idx[10])
214         | SEI_CTRL_CMD_TABLE_PTC_PTR9_SET(config->instr_idx[9])
215         | SEI_CTRL_CMD_TABLE_PTC_PTR8_SET(config->instr_idx[8]);
216     ptr->CTRL[idx].CMD_TABLE[table_idx].PTC = tmp;
217 
218     tmp = SEI_CTRL_CMD_TABLE_PTD_PTR15_SET(config->instr_idx[15])
219         | SEI_CTRL_CMD_TABLE_PTD_PTR14_SET(config->instr_idx[14])
220         | SEI_CTRL_CMD_TABLE_PTD_PTR13_SET(config->instr_idx[13])
221         | SEI_CTRL_CMD_TABLE_PTD_PTR12_SET(config->instr_idx[12]);
222     ptr->CTRL[idx].CMD_TABLE[table_idx].PTD = tmp;
223 #endif
224 
225     return status_success;
226 }
227 
sei_state_transition_config_init(SEI_Type * ptr,uint8_t idx,uint8_t latch_idx,uint8_t state,sei_state_transition_config_t * config)228 hpm_stat_t sei_state_transition_config_init(SEI_Type *ptr, uint8_t idx, uint8_t latch_idx, uint8_t state, sei_state_transition_config_t *config)
229 {
230 #if defined(HPM_IP_FEATURE_SEI_RX_LATCH_FEATURE) && HPM_IP_FEATURE_SEI_RX_LATCH_FEATURE
231     uint32_t tmp;
232     tmp = SEI_CTRL_LATCH_TRAN_POINTER_SET(config->instr_ptr_value)
233         | SEI_CTRL_LATCH_TRAN_CFG_TM_SET(config->timeout_cfg)
234         | SEI_CTRL_LATCH_TRAN_CFG_TXD_SET(config->txd_cfg)
235         | SEI_CTRL_LATCH_TRAN_CFG_RXD_SET(config->rxd_cfg)
236         | SEI_CTRL_LATCH_TRAN_CFG_CLK_SET(config->clk_cfg)
237         | SEI_CTRL_LATCH_TRAN_CFG_PTR_SET(config->instr_ptr_cfg)
238         | SEI_CTRL_LATCH_TRAN_OV_TM_SET(config->disable_timeout_check)
239         | SEI_CTRL_LATCH_TRAN_OV_TXD_SET(config->disable_txd_check)
240         | SEI_CTRL_LATCH_TRAN_OV_RXD_SET(config->disable_rxd_check)
241         | SEI_CTRL_LATCH_TRAN_OV_CLK_SET(config->disable_clk_check)
242         | SEI_CTRL_LATCH_TRAN_OV_PTR_SET(config->disable_instr_ptr_check);
243 #else
244     uint32_t tmp = 0x08u;
245     tmp |= SEI_CTRL_LATCH_TRAN_POINTER_SET(config->instr_ptr_value)
246         | SEI_CTRL_LATCH_TRAN_CFG_TM_SET(config->timeout_cfg)
247         | SEI_CTRL_LATCH_TRAN_CFG_TXD_SET(config->txd_cfg)
248         | SEI_CTRL_LATCH_TRAN_CFG_CLK_SET(config->clk_cfg)
249         | SEI_CTRL_LATCH_TRAN_CFG_PTR_SET(config->instr_ptr_cfg)
250         | SEI_CTRL_LATCH_TRAN_OV_TM_SET(config->disable_timeout_check)
251         | SEI_CTRL_LATCH_TRAN_OV_TXD_SET(config->disable_txd_check)
252         | SEI_CTRL_LATCH_TRAN_OV_CLK_SET(config->disable_clk_check)
253         | SEI_CTRL_LATCH_TRAN_OV_PTR_SET(config->disable_instr_ptr_check);
254 #endif
255     ptr->CTRL[idx].LATCH[latch_idx].TRAN[state] = tmp;
256     return status_success;
257 }
258 
sei_state_transition_latch_config_init(SEI_Type * ptr,uint8_t idx,uint8_t latch_idx,sei_state_transition_latch_config_t * config)259 hpm_stat_t sei_state_transition_latch_config_init(SEI_Type *ptr, uint8_t idx, uint8_t latch_idx, sei_state_transition_latch_config_t *config)
260 {
261     uint32_t tmp;
262 
263     tmp = SEI_CTRL_LATCH_CFG_DELAY_SET(config->delay)
264         | SEI_CTRL_LATCH_CFG_SELECT_SET(config->output_select)
265         | SEI_CTRL_LATCH_CFG_EN_SET(config->enable);
266     ptr->CTRL[idx].LATCH[latch_idx].CFG = tmp;
267 
268     return status_success;
269 }
270 
sei_sample_config_init(SEI_Type * ptr,uint8_t idx,sei_sample_config_t * config)271 hpm_stat_t sei_sample_config_init(SEI_Type *ptr, uint8_t idx, sei_sample_config_t *config)
272 {
273     uint32_t tmp;
274 
275     tmp = SEI_CTRL_POS_SMP_CFG_ONCE_SET(config->sample_once)
276         | SEI_CTRL_POS_SMP_CFG_LAT_SEL_SET(config->latch_select)
277         | SEI_CTRL_POS_SMP_CFG_WINDOW_SET(config->sample_window);
278     ptr->CTRL[idx].POS.SMP_CFG = tmp;
279 
280     ptr->CTRL[idx].POS.SMP_DAT = SEI_CTRL_POS_SMP_DAT_DAT_SEL_SET(config->data_register_select);
281 
282     tmp = SEI_CTRL_POS_SMP_EN_ACC_EN_SET(config->acc_data_use_rx)
283         | SEI_CTRL_POS_SMP_EN_ACC_SEL_SET(config->acc_data_idx)
284         | SEI_CTRL_POS_SMP_EN_SPD_EN_SET(config->spd_data_use_rx)
285         | SEI_CTRL_POS_SMP_EN_SPD_SEL_SET(config->spd_data_idx)
286         | SEI_CTRL_POS_SMP_EN_REV_EN_SET(config->rev_data_use_rx)
287         | SEI_CTRL_POS_SMP_EN_REV_SEL_SET(config->rev_data_idx)
288         | SEI_CTRL_POS_SMP_EN_POS_EN_SET(config->pos_data_use_rx)
289         | SEI_CTRL_POS_SMP_EN_POS_SEL_SET(config->pos_data_idx);
290     ptr->CTRL[idx].POS.SMP_EN = tmp;
291 
292     return status_success;
293 }
294 
sei_update_config_init(SEI_Type * ptr,uint8_t idx,sei_update_config_t * config)295 hpm_stat_t sei_update_config_init(SEI_Type *ptr, uint8_t idx, sei_update_config_t *config)
296 {
297     uint32_t tmp;
298 
299     tmp = SEI_CTRL_POS_UPD_CFG_TIME_OVRD_SET(config->time_use_override)
300         | SEI_CTRL_POS_UPD_CFG_ONERR_SET(config->update_on_err)
301         | SEI_CTRL_POS_UPD_CFG_LAT_SEL_SET(config->latch_select);
302     ptr->CTRL[idx].POS.UPD_CFG = tmp;
303 
304     ptr->CTRL[idx].POS.UPD_DAT = SEI_CTRL_POS_UPD_DAT_DAT_SEL_SET(config->data_register_select);
305 
306     tmp = SEI_CTRL_POS_UPD_EN_ACC_EN_SET(config->acc_data_use_rx)
307         | SEI_CTRL_POS_UPD_EN_ACC_SEL_SET(config->acc_data_idx)
308         | SEI_CTRL_POS_UPD_EN_SPD_EN_SET(config->spd_data_use_rx)
309         | SEI_CTRL_POS_UPD_EN_SPD_SEL_SET(config->spd_data_idx)
310         | SEI_CTRL_POS_UPD_EN_REV_EN_SET(config->rev_data_use_rx)
311         | SEI_CTRL_POS_UPD_EN_REV_SEL_SET(config->rev_data_idx)
312         | SEI_CTRL_POS_UPD_EN_POS_EN_SET(config->pos_data_use_rx)
313         | SEI_CTRL_POS_UPD_EN_POS_SEL_SET(config->pos_data_idx);
314     ptr->CTRL[idx].POS.UPD_EN = tmp;
315 
316     return status_success;
317 }
318 
sei_trigger_input_config_init(SEI_Type * ptr,uint8_t idx,sei_trigger_input_config_t * config)319 hpm_stat_t sei_trigger_input_config_init(SEI_Type *ptr, uint8_t idx, sei_trigger_input_config_t *config)
320 {
321     uint32_t tmp;
322     uint32_t period;
323 
324     tmp = SEI_CTRL_TRG_PRD_CFG_ARMING_SET(config->trig_period_arming_mode)
325         | SEI_CTRL_TRG_PRD_CFG_SYNC_SET(config->trig_period_sync_enable);
326     ptr->CTRL[idx].TRG.PRD_CFG = tmp;
327 
328     period = config->trig_period_time;
329     if (period > 0) {
330         period--;
331     }
332     ptr->CTRL[idx].TRG.PRD = SEI_CTRL_TRG_PRD_PERIOD_SET(period);
333 
334     tmp = SEI_CTRL_TRG_IN_CFG_PRD_EN_SET(config->trig_period_enable)
335         | SEI_CTRL_TRG_IN_CFG_SYNC_SEL_SET(config->trig_period_sync_select)
336         | SEI_CTRL_TRG_IN_CFG_IN1_EN_SET(config->trig_in1_enable)
337         | SEI_CTRL_TRG_IN_CFG_IN1_SEL_SET(config->trig_in1_select)
338         | SEI_CTRL_TRG_IN_CFG_IN0_EN_SET(config->trig_in0_enable)
339         | SEI_CTRL_TRG_IN_CFG_IN0_SEL_SET(config->trig_in0_select)
340 #if defined(HPM_IP_FEATURE_SEI_TIMEOUT_REWIND_FEATURE) && HPM_IP_FEATURE_SEI_TIMEOUT_REWIND_FEATURE
341         | SEI_CTRL_TRG_IN_CFG_REWIND_EN_SET(config->rewind_enable)
342         | SEI_CTRL_TRG_IN_CFG_REWIND_SEL_SET(config->rewind_select)
343 #endif
344         ;
345     ptr->CTRL[idx].TRG.IN_CFG = tmp;
346 
347     return status_success;
348 }
349 
sei_trigger_output_config_init(SEI_Type * ptr,uint8_t idx,sei_trigger_output_config_t * config)350 hpm_stat_t sei_trigger_output_config_init(SEI_Type *ptr, uint8_t idx, sei_trigger_output_config_t *config)
351 {
352     uint32_t tmp;
353 
354     tmp = ptr->CTRL[idx].TRG.OUT_CFG;
355     if (config->src_latch_select == SEI_LATCH_0) {
356         tmp &= ~(SEI_CTRL_TRG_OUT_CFG_OUT0_SEL_MASK | SEI_CTRL_TRG_OUT_CFG_OUT0_EN_MASK);
357         tmp |= SEI_CTRL_TRG_OUT_CFG_OUT0_EN_SET(config->trig_out_enable) | SEI_CTRL_TRG_OUT_CFG_OUT0_SEL_SET(config->trig_out_select);
358     } else if (config->src_latch_select == SEI_LATCH_1) {
359         tmp &= ~(SEI_CTRL_TRG_OUT_CFG_OUT1_SEL_MASK | SEI_CTRL_TRG_OUT_CFG_OUT1_EN_MASK);
360         tmp |= SEI_CTRL_TRG_OUT_CFG_OUT1_EN_SET(config->trig_out_enable) | SEI_CTRL_TRG_OUT_CFG_OUT1_SEL_SET(config->trig_out_select);
361     } else if (config->src_latch_select == SEI_LATCH_2) {
362         tmp &= ~(SEI_CTRL_TRG_OUT_CFG_OUT2_SEL_MASK | SEI_CTRL_TRG_OUT_CFG_OUT2_EN_MASK);
363         tmp |= SEI_CTRL_TRG_OUT_CFG_OUT2_EN_SET(config->trig_out_enable) | SEI_CTRL_TRG_OUT_CFG_OUT2_SEL_SET(config->trig_out_select);
364     } else if (config->src_latch_select == SEI_LATCH_3) {
365         tmp &= ~(SEI_CTRL_TRG_OUT_CFG_OUT3_SEL_MASK | SEI_CTRL_TRG_OUT_CFG_OUT3_EN_MASK);
366         tmp |= SEI_CTRL_TRG_OUT_CFG_OUT3_EN_SET(config->trig_out_enable) | SEI_CTRL_TRG_OUT_CFG_OUT3_SEL_SET(config->trig_out_select);
367     } else {
368         return status_invalid_argument;
369     }
370     ptr->CTRL[idx].TRG.OUT_CFG = tmp;
371 
372     return status_success;
373 }
374 
sei_engine_config_init(SEI_Type * ptr,uint8_t idx,sei_engine_config_t * config)375 hpm_stat_t sei_engine_config_init(SEI_Type *ptr, uint8_t idx, sei_engine_config_t *config)
376 {
377     uint32_t tmp;
378 
379     tmp = SEI_CTRL_ENGINE_PTR_CFG_DAT_CDM_SET(config->data_cdm_idx)
380         | SEI_CTRL_ENGINE_PTR_CFG_DAT_BASE_SET(config->data_base_idx)
381         | SEI_CTRL_ENGINE_PTR_CFG_POINTER_WDOG_SET(config->wdg_instr_idx)
382         | SEI_CTRL_ENGINE_PTR_CFG_POINTER_INIT_SET(config->init_instr_idx);
383     ptr->CTRL[idx].ENGINE.PTR_CFG = tmp;
384 
385     ptr->CTRL[idx].ENGINE.WDG_CFG = SEI_CTRL_ENGINE_WDG_CFG_WDOG_TIME_SET(config->wdg_time);
386 
387     tmp = SEI_CTRL_ENGINE_CTRL_WATCH_SET(config->wdg_enable)
388         | SEI_CTRL_ENGINE_CTRL_EXCEPT_SET(config->wdg_action)
389         | SEI_CTRL_ENGINE_CTRL_ARMING_SET(config->arming_mode);
390     ptr->CTRL[idx].ENGINE.CTRL = tmp;
391 
392     return status_success;
393 }
394 
sei_set_instr(SEI_Type * ptr,uint8_t idx,uint8_t op,uint8_t ck,uint8_t crc,uint8_t data,uint8_t opr)395 void sei_set_instr(SEI_Type *ptr, uint8_t idx, uint8_t op, uint8_t ck, uint8_t crc, uint8_t data, uint8_t opr)
396 {
397     uint32_t tmp;
398 
399 #if !defined(HPM_IP_FEATURE_SEI_HAVE_INTR64_255) || !HPM_IP_FEATURE_SEI_HAVE_INTR64_255
400     assert(idx < 64);
401 #endif
402     if ((op != SEI_INSTR_OP_HALT) && (op != SEI_INSTR_OP_JUMP) && (opr > 0)) {
403         opr--;
404     }
405     if (opr > 0x1F) {
406         opr = 0x1F;
407     }
408     tmp = SEI_INSTR_OP_SET(op)
409         | SEI_INSTR_CK_SET(ck)
410         | SEI_INSTR_CRC_SET(crc)
411         | SEI_INSTR_DAT_SET(data)
412         | SEI_INSTR_OPR_SET(opr);
413 
414     ptr->INSTR[idx] = tmp;
415 }
416