]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/fr_tms570.c
Merge branch 'master' of rtime.felk.cvut.cz:pes-rpp/rpp-lib
[pes-rpp/rpp-lib.git] / rpp / src / drv / fr_tms570.c
1 /*
2  * fr_rms570.c
3  *
4  *  Created on: 9.7.2013
5  *      Author: michal
6  */
7
8 #include "drv/fr_tms570.h"
9 #include "sys/ti_drv_fray.h"
10 #include "binary.h"
11 #include "hal/port_def.h"
12
13 /**
14  * The structure maps a RX/TX buffer to a slot in the communication cycle.
15  */
16 typedef struct Fr_slot_buffer_map_st {
17         const Fr_TMS570LS_BufferConfigType* buffer_ptr; /**< Address of a buffer configuration assigned to the slot slot_id */
18         uint16_t slot_id; /**< An ID of the slot in the communication cycle. The value may not be equal to the slot_id value in the buffer configuration, after reconfiguration is done. */
19 } Fr_slot_buffer_map_t;
20
21 static Std_VersionInfoType Fr_versionInfo = {
22                 .vendorID = 0x00000001,
23                 .moduleID = 0x00000002,
24                 .sw_major_version = 0,
25                 .sw_minor_version = 1,
26                 .sw_patch_version = 0
27 };
28
29 /** Prepared spi command */
30 static uint32_t fray_spi_cmd = FRAY_SPICMD_INIT_VAL;
31 /** Shadow variable used during command sending */
32 static uint32_t fray_spi_cmd_sh;
33 /** Array of responses for each fray driver */
34 static uint32_t fray_spi_resp[FRAY_NUM_PORTS];
35 /** Array of port names to be easily accessible by indexing */
36 static const char* fray_port_names[FRAY_NUM_PORTS] = { PORT_NAME_FRAY1, PORT_NAME_FRAY2 };
37 /** Array of integers, where FlexRay cluster and node configuration
38  * parameters are stored to be accessible by indexes defined in Fr_GeneralTypes.h.
39  */
40 static uint32_t Fr_ConfigParPtrs[FR_CIDX_CNT];
41 /**
42  * Address of the unified structure with complete configuration of
43  * the FlexRay node (cluster, node, message RAM and buffer configuration)
44  */
45 static const Fr_ConfigType* Fr_Config;
46 /** Map of the buffers to their slot ID */
47 static Fr_slot_buffer_map_t Fr_buffer_slot_map[FR_MAX_BUFFERS_CNT];
48 /** Array of flags to determine if the buffer was or was not configured. */
49 static boolean_t Fr_BuffersConfigured[FR_MAX_BUFFERS_CNT];
50 /**  Array of computed data pointers addresses for each buffer. */
51 static int Fr_MsgRAMDataPtrs[FR_MAX_BUFFERS_CNT];
52 /**
53  * Address of the next free position in message RAM, which can be assigned
54  * to configured buffer. Addresses 32b words.
55  */
56 static uint32_t Fr_MsgRAMDataOffset;
57 /**
58  * Address of the first free position in message RAM, which can be assigned
59  * to the first configured buffer. Addresses 32b words.
60  */
61 static uint32_t Fr_MsgRAMDataStartAddress;
62
63 /**
64  *  Development error detection.
65  *  Comment this line to disable error detection and make function processing
66  *  faster, but more dangerous.
67  */
68
69 #define DET_ACTIVATED
70
71
72 #ifdef DET_ACTIVATED
73 /**
74  * A variable for driver state monitoring. The state value is used in several
75  * functions to determine if they are called in right order.
76  */
77 static Fr_TMS570LS_DriverState Fr_DrvState = FR_ST_DRV_NOT_INITIALIZED;
78 #endif
79
80 /**
81  *  Compute CRC for message RAM header data
82  *
83  *  @param[in] Fr_LPduPtr   Pointer to header data
84  *  @return CRC code
85  */
86 static int Fr_header_crc_calc(const wrhs *Fr_LPduPtr) {
87   unsigned int header;
88
89   int CrcInit = 0x1A;
90   int length  = 20;
91   int CrcNext;
92   unsigned long CrcPoly  = 0x385;
93   unsigned long CrcReg_X = CrcInit;
94   unsigned long header_temp, reg_temp;
95
96   header  = ((Fr_LPduPtr->sync & 0x1)  << 19) | ((Fr_LPduPtr->sfi & 0x1) << 18);
97   header |= ((Fr_LPduPtr->fid & 0x7FF) <<  7) |  (Fr_LPduPtr->pl & 0x7F);
98
99   header   <<= 11;
100   CrcReg_X <<= 21;
101   CrcPoly  <<= 21;
102
103   while(length--) {
104     header    <<= 1;
105     header_temp = header & 0x80000000;
106     reg_temp    = CrcReg_X & 0x80000000;
107
108     if(header_temp ^ reg_temp){  // Step 1
109       CrcNext = 1;
110     } else {
111       CrcNext = 0;
112     }
113
114     CrcReg_X <<= 1;              // Step 2
115
116     if(CrcNext) {
117       CrcReg_X ^= CrcPoly;       // Step 3
118     }
119   }
120
121   CrcReg_X >>= 21;
122
123   return CrcReg_X;
124 }
125
126 /**
127  *  Retrieve data and header from message buffer into output buffer.
128  *
129  *  Upper software layers have to read the header and data from RDDS and RDHS registers.
130  *  @param[in]  buf_num     Number of buffer
131  */
132 static void Fr_buffer_receive_data_header(uint32_t buf_num) {
133     bc read_buffer;
134
135     read_buffer.obrs=buf_num;  // output buffer number
136     read_buffer.rdss=1;  // read data section
137     read_buffer.rhss=1;  // read header section
138
139     // ensure no transfer in progress on shadow registers
140     while (((frayREG->OBCR_UN.OBCR_UL) & 0x00008000) != 0);
141     frayREG->OBCM_UN.OBCM_UL=(((read_buffer.rdss & 0x1) << 1) | (read_buffer.rhss & 0x1));
142     frayREG->OBCR_UN.OBCR_UL=((1 << 9) | (read_buffer.obrs & 0x3F)); //req=1, view=0
143     // wait for completion on shadow registers
144     while (((frayREG->OBCR_UN.OBCR_UL) & 0x00008000) != 0);
145
146     frayREG->OBCM_UN.OBCM_UL=(((read_buffer.rdss & 0x1) << 1) | (read_buffer.rhss & 0x1));
147     frayREG->OBCR_UN.OBCR_UL=((1 << 8) | (read_buffer.obrs & 0x3F)); //req=0, view=1
148
149 }
150
151 /**
152  *  Transfer data to the message RAM using the input buffer
153  *
154  *  @param[in] Fr_LSduPtr   Pointer to data structure with input buffer settings
155  */
156 inline void Fr_transmit_tx_LPdu(const bc *Fr_LSduPtr) {
157     // ensure nothing is pending
158     while ((frayREG->IBCR_UN.IBCR_UL & 0x0008000) != 0);
159     frayREG->IBCM_UN.IBCM_UL=((Fr_LSduPtr->stxrh & 0x1) << 2) | ((Fr_LSduPtr->ldsh & 0x1) << 1) | (Fr_LSduPtr->lhsh & 0x1);
160     frayREG->IBCR_UN.IBCR_UL=(Fr_LSduPtr->ibrh & 0x3F);
161     // optimization possible for future by not gating like below
162     // wait for completion on host registers
163     while ((Fr_LSduPtr->ibsyh != 0) && ((frayREG->IBCR_UN.IBCR_UL & 0x00008000) != 0));
164     // wait for completion on shadow registers
165     while ((Fr_LSduPtr->ibsys != 0) && ((frayREG->IBCR_UN.IBCR_UL & 0x80000000) != 0));
166 }
167
168 /**
169  *  Fill the buffer configuration data structure with given data and transfer it to the message RAM header using the input buffer.
170  *
171  *  @param[in]  buf_num     number of buffer to be configured (0-128)
172  *  @param[in]  mode        Flag array for buffer configuration. Flags are defined in header file with prefix FRAY_BUF_
173  *  @param[in]  cyc_filter  Setting for cycle filter. 0 - disabled
174  *  @param[in]  frame_id    Id of the frame to be associated with the buffer
175  *  @param[in]  payload     Maximum data size in half-word
176  *  @param[in]  data_pointer    Address of the first word of data in buffer
177  */
178 static void Fr_config_buffer(uint32_t buf_num, uint16_t mode, uint32_t cyc_filter, uint32_t frame_id, uint32_t payload, uint32_t data_pointer) {
179     wrhs Fr_LPdu;
180     bc Fr_LSdu;
181     int wrhs1;
182     int wrhs2;
183
184     Fr_LPdu.mbi  = (mode&FRAY_BUF_MBI_EN) ? 1 : 0;   // message buffer interrupt
185     Fr_LPdu.txm  = (mode&FRAY_BUF_TX_MODE_CONTINUOUS) ? 0 : 1;   // transmission mode(0=continuous mode, 1=single mode)
186     Fr_LPdu.ppit = (mode&FRAY_BUF_NM_EN) ? 1 : 0;   // network management Enable
187     Fr_LPdu.cfg  = (mode&FRAY_BUF_TX) ? 1 : 0;   // message buffer configuration bit (0=RX, 1 = TX)
188     Fr_LPdu.chb  = (mode&FRAY_BUF_CHB_EN) ? 1 : 0;   // Ch B
189     Fr_LPdu.cha  = (mode&FRAY_BUF_CHA_EN) ? 1 : 0;   // Ch A
190     Fr_LPdu.cyc  = cyc_filter;   // Cycle Filtering Code (no cycle filtering)
191     Fr_LPdu.fid  = frame_id;   // Frame ID
192
193     // Write Header Section 2 (WRHS2)
194     Fr_LPdu.pl   = payload;   // Payload Length
195
196     // Write Header Section 3 (WRHS3)
197     Fr_LPdu.dp   = data_pointer;   // Pointer to start of data in message RAM
198
199     Fr_LPdu.sfi  = (mode&FRAY_BUF_SFI_EN) ? 1 : 0;   // startup frame indicator
200     Fr_LPdu.sync = (mode&FRAY_BUF_SYNC_EN) ? 1 : 0;   // sync frame indicator
201
202     // Write Header Section 2 (WRHS2)
203     Fr_LPdu.crc  = (mode&FRAY_BUF_TX) ? Fr_header_crc_calc(&Fr_LPdu) : 0;
204
205     // Input buffer configuration
206     Fr_LSdu.ibrh = buf_num;  // input buffer number
207     Fr_LSdu.ibsyh = 1; // check for input buffer busy host
208     Fr_LSdu.ibsys = 1; // check for input buffer busy shadow
209
210     Fr_LSdu.stxrh= (mode&FRAY_BUF_TXREQ_EN) ? 1 : 0;  // set transmission request
211     Fr_LSdu.ldsh = 0;  // load data section
212     Fr_LSdu.lhsh = 1;  // load header section
213     Fr_LSdu.obrs = 0;  // output buffer number
214     Fr_LSdu.rdss = 0;  // read data section
215     Fr_LSdu.rhss = 0;  // read header section
216
217     wrhs1  = ((Fr_LPdu.mbi) & 0x1)  <<29;
218     wrhs1 |= (Fr_LPdu.txm & 0x1)  << 28;
219     wrhs1 |= (Fr_LPdu.ppit & 0x1) << 27;
220     wrhs1 |= (Fr_LPdu.cfg & 0x1)  << 26;
221     wrhs1 |= (Fr_LPdu.chb & 0x1)  << 25;
222     wrhs1 |= (Fr_LPdu.cha & 0x1)  << 24;
223     wrhs1 |= (Fr_LPdu.cyc & 0x7F) << 16;
224     wrhs1 |= (Fr_LPdu.fid & 0x7FF);
225     frayREG->WRHS1_UN.WRHS1_UL = wrhs1;
226
227     wrhs2  = ((Fr_LPdu.pl & 0x7F) << 16) | (Fr_LPdu.crc & 0x7FF);
228     frayREG->WRHS2_UN.WRHS2_UL = wrhs2;
229
230     frayREG->WRHS3_UN.WRHS3_UL = (Fr_LPdu.dp & 0x7FF);
231
232     Fr_transmit_tx_LPdu(&Fr_LSdu);
233 }
234
235 /**
236  *  Fill FIFO filter rejection configuration and configure the buffer.
237  *
238  *  @param[in]  buf_num     number of buffer to be configured (0-128)
239  *  @param[in]  mode        Flag array for buffer configuration. Flags are defined in header file with prefix FRAY_BUF_
240  *  @param[in]  cyc_filter  Setting for cycle filter. 0 - disabled
241  *  @param[in]  frame_id    Id of the frame to be associated with the buffer
242  *  @param[in]  payload     Maximum data size in half-word
243  *  @param[in]  data_pointer    Address of the first word of data in buffer
244  */
245 static void Fr_configure_fifo_buffer(uint32_t buf_num, uint16_t mode, uint32_t cyc_filter, uint32_t frame_id, uint32_t payload, uint32_t data_pointer) {
246         frayREG->FRF_UN.FRF_ST.rnf = (mode&FRAY_BUF_REJECT_NULL_FRAMES) ? 1 : 0;
247         frayREG->FRF_UN.FRF_ST.rss = (mode&FRAY_BUF_REJECT_STATIC_SEGMENT) ? 1 : 0;
248         frayREG->FRF_UN.FRF_ST.fid_B11 = frame_id;
249         frayREG->FRFM_UN.FRFM_ST.mfid_B11 = 0x0;
250         frayREG->FRF_UN.FRF_ST.cyf_B7 = cyc_filter;
251         if (mode&FRAY_BUF_CHB_EN && mode&FRAY_BUF_CHA_EN) {
252                 frayREG->FRF_UN.FRF_ST.ch_B2 = 0;
253         }
254         else if (mode&FRAY_BUF_CHA_EN) {
255                 frayREG->FRF_UN.FRF_ST.ch_B2 = 3;
256         }
257         else {
258                 frayREG->FRF_UN.FRF_ST.ch_B2 = 2;
259         }
260         frame_id = 0;
261         Fr_config_buffer(buf_num, mode, cyc_filter, frame_id, payload, data_pointer);
262 }
263
264 /**
265  *  Load data to message buffer. Data must be copied into WRDS register before this function is called.
266  *
267  *  @param[in]  buf_num     Number of buffer
268  *  @param[in]  len         Number of words to be loaded from data to buffer
269  */
270 static void Fr_buffer_transmit_data(uint32_t buf_num) {
271     bc write_buffer;
272
273     write_buffer.ibrh = buf_num;  // input buffer number
274     write_buffer.stxrh= 1;  // set transmission request
275     write_buffer.ldsh = 1;  // load data section
276     write_buffer.lhsh = 0;  // load header section
277     write_buffer.ibsys = 0; // check for input buffer busy shadow
278     write_buffer.ibsyh = 1; // check for input buffer busy host
279     Fr_transmit_tx_LPdu(&write_buffer);
280 }
281
282
283 /** @fn wait_for_POC_ready(void)
284 *   @brief Wait until POC is not busy
285 */
286 inline void Fr_wait_for_POC_ready() {
287         // Wait for PBSY bit to clear - POC not busy.
288         // 1: Signals that the POC is busy and cannot accept a command from the host. CMD(3-0) is locked against write accesses.
289         while(((frayREG->SUCC1_UN.SUCC1_UL) & 0x00000080) != 0);
290 }
291
292 /** @fn clear_msg_ram(void)
293 *   @brief Clears FRAY message RAMs
294 *
295 *   Send command to POC to set all bits of message RAM to 0.
296 *   @return SUCCESS or FAILURE when command was not accepted
297 */
298 static int Fr_clear_msg_RAM() {
299     Fr_wait_for_POC_ready();
300     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_CLEAR_RAMS;
301     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted) {
302         return FAILURE;
303     }
304     Fr_wait_for_POC_ready();
305     return SUCCESS;
306 }
307
308
309 /**
310  * @brief Switch POC to config state from any other state
311  *
312  * After command to switch into config state is passed into CHI,
313  * the response is checked and if POC has reacted on the command,
314  * the function is waiting until POC is ready
315  *
316  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
317  */
318 static Std_ReturnType Fr_POC_go_to_config() {
319         // write SUCC1 configuration
320     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_CONFIG;
321     // Check if POC has accepted last command
322     if ((frayREG->SUCC1_UN.SUCC1_UL & 0xF) == 0x0)
323         return E_NOT_OK;
324     // Wait for PBSY bit to clear - POC not busy
325     Fr_wait_for_POC_ready();
326     return E_OK;
327 }
328
329 /**
330  * @brief Switch POC to ready state from config state
331  *
332  * After command to switch into ready state is passed into CHI,
333  * the response is checked and if POC has reacted on the command,
334  * the function is waiting until POC is ready
335  *
336  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
337  */
338 static Std_ReturnType Fr_POC_go_to_ready_from_config() {
339     Fr_wait_for_POC_ready();
340     // For CHA and CHB network
341     if (frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 && frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
342         // Unlock sequence
343         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
344         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
345         frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
346         // Unlock sequence
347         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
348         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
349         frayREG->SUCC1_UN.SUCC1_ST.mtsa_B1 = 1U;
350         // Unlock sequence
351         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
352         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
353         frayREG->SUCC1_UN.SUCC1_ST.mtsb_B1 = 1U;
354     }
355     // For CHA  network
356     else if(frayREG->SUCC1_UN.SUCC1_ST.ccha_B1){
357         // Unlock sequence
358         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
359         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
360         frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
361         // Unlock sequence
362         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
363         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
364         frayREG->SUCC1_UN.SUCC1_ST.mtsa_B1 = 1U;
365     }
366     // For CHB  network
367     else if (frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
368         // Unlock sequence
369         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
370         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
371         frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
372         // Unlock sequence
373         frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
374         frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
375         frayREG->SUCC1_UN.SUCC1_ST.mtsb_B1 = 1U;
376     }
377     else frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
378
379     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
380         return E_NOT_OK;
381
382     while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01)
383             ; // Waiting for READY state
384     return E_OK;
385 }
386
387 /**
388  * @brief Switch POC to ready state from startup state
389  *
390  * After command to switch into ready state is passed into CHI,
391  * the response is checked and if POC has reacted on the command,
392  * the function is waiting until POC is ready
393  *
394  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
395  */
396 static Std_ReturnType Fr_POC_go_to_ready_from_startup() {
397         Fr_wait_for_POC_ready();
398     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
399     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
400         return E_NOT_OK;
401     while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01); // Wait until POC is not in ready state
402         Fr_wait_for_POC_ready();
403     return E_OK;
404 }
405
406 /**
407  * @brief Switch POC to startup state from ready state
408  *
409  * After command to switch into startup state is passed into CHI,
410  * the response is checked and if POC has reacted on the command,
411  * the function is waiting until POC is ready
412  *
413  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
414  */
415 static Std_ReturnType Fr_POC_go_to_startup() {
416     Fr_wait_for_POC_ready();
417     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_RUN;
418     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
419         return (E_NOT_OK);
420     Fr_wait_for_POC_ready();
421     return (E_OK);
422 }
423
424 /**
425  * @brief Copy cluster config parameters into FlexRay configuration registers.
426  *
427  * This function does not check values ranges. This is a responsibility of higher
428  * layers. Cluster configuration parameters are copied from data structure
429  * into right bit position in configuration registers.
430  *
431  * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
432  */
433 void Fr_config_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr) {
434         frayREG->SUCC1_UN.SUCC1_ST.csa_B5 =  clusterConfigPtr->gColdStartAttempts;
435         frayREG->GTUC9_UN.GTUC9_ST.apo_B5 = clusterConfigPtr->gdActionPointOffset;
436         frayREG->PRTC1_UN.PRTC1_ST.casm_B7 =  clusterConfigPtr->gdCASRxLowMax;
437         frayREG->GTUC9_UN.GTUC9_ST.dsi_B2 = clusterConfigPtr->gdDynamicSlotIdlePhase;
438         frayREG->GTUC8_UN.GTUC8_ST.msl_B6 = clusterConfigPtr->gdMinislot;
439         frayREG->GTUC9_UN.GTUC9_ST.mapo_B5 =  clusterConfigPtr->gdMinislotActionPointOffset;
440         frayREG->GTUC7_UN.GTUC7_ST.ssl_B10 =  clusterConfigPtr->gdStaticSlot;
441         frayREG->PRTC1_UN.PRTC1_ST.tsst_B4 =  clusterConfigPtr->gdTSSTransmitter;
442         frayREG->PRTC2_UN.PRTC2_ST.rxi_B6 =  clusterConfigPtr->gdWakeupSymbolRxIdle;
443         frayREG->PRTC2_UN.PRTC2_ST.rxl_B6 =  clusterConfigPtr->gdWakeupSymbolRxLow;
444         frayREG->PRTC1_UN.PRTC1_ST.rxw_B9 =  clusterConfigPtr->gdWakeupSymbolRxWindow;
445         frayREG->PRTC2_UN.PRTC2_ST.txi_B8 =  clusterConfigPtr->gdWakeupSymbolTxIdle;
446         frayREG->PRTC2_UN.PRTC2_ST.txl_B6 =  clusterConfigPtr->gdWakeupSymbolTxLow;
447         frayREG->SUCC2_UN.SUCC2_ST.ltn_B4 =  clusterConfigPtr->gListenNoise;
448         frayREG->GTUC2_UN.GTUC2_ST.mpc_B14 = clusterConfigPtr->gMacroPerCycle;
449         frayREG->SUCC3_UN.SUCC3_ST.wcf_B4 = clusterConfigPtr->gMaxWithoutClockCorrectionFatal;
450         frayREG->SUCC3_UN.SUCC3_ST.wcp_B4 = clusterConfigPtr->gMaxWithoutClockCorrectionPassive;
451         frayREG->GTUC8_UN.GTUC8_ST.nms_B13 = clusterConfigPtr->gNumberOfMinislots;
452         frayREG->GTUC7_UN.GTUC7_ST.nss_B10 = clusterConfigPtr->gNumberOfStaticSlots;
453         frayREG->GTUC4_UN.GTUC4_ST.ocs_B14 = clusterConfigPtr->gOffsetCorrectionStart;
454         frayREG->MHDC_UN.MHDC_ST.sfdl_B7 = clusterConfigPtr->gPayloadLengthStatic;
455         frayREG->GTUC2_UN.GTUC2_ST.snm_B4 = clusterConfigPtr->gSyncNodeMax;
456         frayREG->GTUC4_UN.GTUC4_ST.nit_B14 = clusterConfigPtr->gdNIT;
457         frayREG->PRTC1_UN.PRTC1_ST.brp_B2 = clusterConfigPtr->gdSampleClockPeriod;
458         frayREG->NEMC_UN.NEMC_ST.nml_B4 = clusterConfigPtr->gNetworkManagementVectorLength;
459 }
460
461 #define __notInRange(val, min, max)     (((val) < (min)) || ((val) > (max)))
462
463 /**
464  * @brief Check cluster configuration parameters.
465  *
466  * This function checks values of the cluster configuration parameters,
467  * if they are in ranges noted in FlexRay specification.
468  *
469  * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
470  * @param [out] errCode Address where error flags will be stored.
471  *              We have 26 parameters to check. Every one of them has assigned its bit in this flag.
472  *              Error flags are defined as macros ERR_PARAM_nameOfParameter.
473  * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
474  */
475 Std_ReturnType Fr_check_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr, uint32_t* errCode) {
476         *errCode = ERR_PARAM_NO_ERROR;
477
478         if (__notInRange(clusterConfigPtr->gColdStartAttempts, 2, 31))          *errCode |= ERR_PARAM_gColdStartAttempts;
479         if (__notInRange(clusterConfigPtr->gdActionPointOffset, 1, 63))         *errCode |= ERR_PARAM_gdActionPointOffset;
480         if (__notInRange(clusterConfigPtr->gdCASRxLowMax, 67, 99))                      *errCode |= ERR_PARAM_gdCASRxLowMax;
481         if (clusterConfigPtr->gdDynamicSlotIdlePhase > 2)                                       *errCode |= ERR_PARAM_gdDynamicSlotIdlePhase;
482         if (__notInRange(clusterConfigPtr->gdMinislot, 2, 63))                          *errCode |= ERR_PARAM_gdMinislot;
483         if (__notInRange(clusterConfigPtr->gdMinislotActionPointOffset,
484                         1, 31))                                                                                                         *errCode |= ERR_PARAM_gdMinislotActionPointOffset;
485         if (__notInRange(clusterConfigPtr->gdStaticSlot, 4, 661))                       *errCode |= ERR_PARAM_gdStaticSlot;
486         if (__notInRange(clusterConfigPtr->gdTSSTransmitter, 3, 15))            *errCode |= ERR_PARAM_gdTSSTransmitter;
487         if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxIdle, 14, 59))       *errCode |= ERR_PARAM_gdWakeupSymbolRxIdle;
488         if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxLow, 11, 59))        *errCode |= ERR_PARAM_gdWakeupSymbolRxLow;
489         if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxWindow,
490                         76, 301))                                                                                                       *errCode |= ERR_PARAM_gdWakeupSymbolRxWindow;
491         if (__notInRange(clusterConfigPtr->gdWakeupSymbolTxIdle, 45, 180))      *errCode |= ERR_PARAM_gdWakeupSymbolTxIdle;
492         if (__notInRange(clusterConfigPtr->gdWakeupSymbolTxLow, 15, 60))        *errCode |= ERR_PARAM_gdWakeupSymbolTxLow;
493         if (__notInRange(clusterConfigPtr->gListenNoise, 2, 16))                        *errCode |= ERR_PARAM_gListenNoise;
494         if (__notInRange(clusterConfigPtr->gMacroPerCycle, 10, 16000))          *errCode |= ERR_PARAM_gMacroPerCycle;
495         if (__notInRange(clusterConfigPtr->gMaxWithoutClockCorrectionFatal,
496                         clusterConfigPtr->gMaxWithoutClockCorrectionPassive, 15))       *errCode |= ERR_PARAM_gMaxWithoutClockCorrectionFatal;
497         if (__notInRange(clusterConfigPtr->gMaxWithoutClockCorrectionPassive,
498                         1, 15))                                                                                                         *errCode |= ERR_PARAM_gMaxWithoutClockCorrectionPassive;
499         if (clusterConfigPtr->gNumberOfMinislots > 7986)                                        *errCode |= ERR_PARAM_gNumberOfMinislots;
500         if (__notInRange(clusterConfigPtr->gNumberOfStaticSlots,
501                         2, cStaticSlotIDMax))                                                                           *errCode |= ERR_PARAM_gNumberOfStaticSlots;
502         if (__notInRange(clusterConfigPtr->gOffsetCorrectionStart,
503                         9, 15999))                                                                                                      *errCode |= ERR_PARAM_gOffsetCorrectionStart;
504         if (clusterConfigPtr->gPayloadLengthStatic > cPayloadLengthMax)         *errCode |= ERR_PARAM_gPayloadLengthStatic;
505         if (__notInRange(clusterConfigPtr->gSyncNodeMax, 2, cSyncNodeMax))      *errCode |= ERR_PARAM_gSyncNodeMax;
506         if (__notInRange(clusterConfigPtr->gdNIT, 7, 0x3E7D))                                   *errCode |= ERR_PARAM_gdNIT;
507         if (clusterConfigPtr->gdSampleClockPeriod > 3)                                          *errCode |= ERR_PARAM_gdSampleClockPeriod;
508         if (clusterConfigPtr->gNetworkManagementVectorLength > 12)                      *errCode |= ERR_PARAM_gNetworkManagementVectorLength;
509
510         return (*errCode == 0) ? E_OK : E_NOT_OK;
511 }
512
513 /**
514  * @brief Copy node config parameters into FlexRay configuration registers.
515  *
516  * This function does not check values ranges. This is a responsibility of higher
517  * layers. Node configuration parameters are copied from data structure
518  * into right bit position in configuration registers.
519  *
520  * @param [in] nodeConfigPtr Address of structure with node configuration parameters
521  */
522 void Fr_config_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr) {
523         frayREG->SUCC1_UN.SUCC1_ST.hcse_B1 = nodeConfigPtr->pAllowHaltDueToClock;
524         frayREG->SUCC1_UN.SUCC1_ST.pta_B5 = nodeConfigPtr->pAllowPassiveToActive;
525         if (nodeConfigPtr->pChannels == FR_CHANNEL_AB) {
526                 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 1;
527                 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 1;
528         }
529         else if (nodeConfigPtr->pChannels == FR_CHANNEL_A) {
530                 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 1;
531                 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 0;
532         }
533         else {
534                 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 0;
535                 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 1;
536         }
537         frayREG->GTUC6_UN.GTUC6_ST.asr_B11 = nodeConfigPtr->pdAcceptedStartupRange;
538         frayREG->GTUC5_UN.GTUC5_ST.cdd_B5 = nodeConfigPtr->pClusterDriftDamping;
539         frayREG->GTUC5_UN.GTUC5_ST.dca_B8 = nodeConfigPtr->pDelayCompensationA;
540         frayREG->GTUC5_UN.GTUC5_ST.dcb_B8 = nodeConfigPtr->pDelayCompensationB;
541         frayREG->GTUC5_UN.GTUC5_ST.dec_B8 = nodeConfigPtr->pDecodingCorrection;
542         frayREG->SUCC2_UN.SUCC2_ST.lt_B21 = nodeConfigPtr->pdListenTimeout;
543         frayREG->GTUC6_UN.GTUC6_ST.mod_B11 = nodeConfigPtr->pdMaxDrift;
544         frayREG->GTUC11_UN.GTUC11_ST.eoc_B3 = nodeConfigPtr->pExternOffsetCorrection;
545         frayREG->GTUC11_UN.GTUC11_ST.erc_B3 = nodeConfigPtr->pExternRateCorrection;
546         frayREG->SUCC1_UN.SUCC1_ST.txst_B1 = nodeConfigPtr->pKeySlotUsedForStartup;
547         frayREG->SUCC1_UN.SUCC1_ST.txsy_B1 = nodeConfigPtr->pKeySlotUsedForSync;
548         frayREG->MHDC_UN.MHDC_ST.slt_B13 =  nodeConfigPtr->pLatestTx;
549         frayREG->GTUC3_UN.GTUC3_ST.mioa_B7 = nodeConfigPtr->pMacroInitialOffsetA;
550         frayREG->GTUC3_UN.GTUC3_ST.miob_B7 = nodeConfigPtr->pMacroInitialOffsetB;
551         frayREG->GTUC3_UN.GTUC3_ST.uioa_B8 = nodeConfigPtr->pMicroInitialOffsetA;
552         frayREG->GTUC3_UN.GTUC3_ST.uiob_B8 = nodeConfigPtr->pMicroInitialOffsetB;
553         frayREG->GTUC1_UN.GTUC1_ST.ut_B20 = nodeConfigPtr->pMicroPerCycle;
554         frayREG->GTUC10_UN.GTUC10_ST.moc_B13 = nodeConfigPtr->pRateCorrectionOut;
555         frayREG->GTUC10_UN.GTUC10_ST.mrc_B11 = nodeConfigPtr->pOffsetCorrectionOut;
556         frayREG->SUCC1_UN.SUCC1_ST.tsm_B1 = nodeConfigPtr->pSingleSlotEnabled;
557         if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_A) {
558                 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 0;
559         }
560         else if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_B) {
561                 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 1;
562         }
563         frayREG->PRTC1_UN.PRTC1_ST.rwp_B6 = nodeConfigPtr->pWakeupPattern;
564         frayREG->PRTC1_UN.PRTC1_ST.brp_B2 = nodeConfigPtr->pSamplesPerMicrotick;
565 }
566
567 /**
568  * @brief Check node configuration parameters.
569  *
570  * This function checks values of the node configuration parameters,
571  * if they are in ranges noted in FlexRay specification.
572  *
573  * @param [in] nodeConfigPtr Address of structure with node configuration parameters
574  * @param [out] errCode Address where error flags will be stored.
575  *              We have 24 parameters to check. Every one of them has assigned its bit in this flag.
576  *              Error flags are defined as macros ERR_PARAM_nameOfParameter.
577  * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
578  */
579 Std_ReturnType Fr_check_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr, uint32_t* errCode) {
580         *errCode = ERR_PARAM_NO_ERROR;
581
582         if (nodeConfigPtr->pAllowPassiveToActive > 31)          *errCode |= ERR_PARAM_pAllowPassiveToActive;
583         if (nodeConfigPtr->pChannels != FR_CHANNEL_A &&
584                 nodeConfigPtr->pChannels != FR_CHANNEL_B &&
585                 nodeConfigPtr->pChannels != FR_CHANNEL_AB )             *errCode |= ERR_PARAM_pChannels;
586         if (nodeConfigPtr->pdAcceptedStartupRange > 1875)       *errCode |= ERR_PARAM_pdAcceptedStartupRange;
587         if (nodeConfigPtr->pClusterDriftDamping > 20)           *errCode |= ERR_PARAM_pClusterDriftDamping;
588         if (nodeConfigPtr->pDelayCompensationA > 200)           *errCode |= ERR_PARAM_pDelayCompensationA;
589         if (nodeConfigPtr->pDelayCompensationB > 200)           *errCode |= ERR_PARAM_pDelayCompensationB;
590         if (__notInRange(nodeConfigPtr->pdListenTimeout, 1284, 1283846))        *errCode |= ERR_PARAM_pdListenTimeout;
591         if (__notInRange(nodeConfigPtr->pdMaxDrift, 2, 1923))                           *errCode |= ERR_PARAM_pdMaxDrift;
592         if (nodeConfigPtr->pExternOffsetCorrection > 7)         *errCode |= ERR_PARAM_pExternOffsetCorrection;
593         if (nodeConfigPtr->pExternRateCorrection > 7)           *errCode |= ERR_PARAM_pExternRateCorrection;
594         if (nodeConfigPtr->pKeySlotUsedForStartup == TRUE &&
595                 nodeConfigPtr->pKeySlotUsedForSync == FALSE)    *errCode |= ERR_PARAM_pKeySlotUsedForSync
596                                                                                                                                  |  ERR_PARAM_pKeySlotUsedForStartup;   // If pKeySlotUsedForStartup is set to true then pKeySlotUsedForSync must also be set to true.
597         if (nodeConfigPtr->pLatestTx > 7980)                            *errCode |= ERR_PARAM_pLatestTx;
598         if (__notInRange(nodeConfigPtr->pMacroInitialOffsetA, 2, 68))           *errCode |= ERR_PARAM_pMacroInitialOffsetA;
599         if (__notInRange(nodeConfigPtr->pMacroInitialOffsetB, 2, 68))           *errCode |= ERR_PARAM_pMacroInitialOffsetB;
600         if (nodeConfigPtr->pMicroInitialOffsetA > 239)          *errCode |= ERR_PARAM_pMicroInitialOffsetA;
601         if (nodeConfigPtr->pMicroInitialOffsetB > 239)          *errCode |= ERR_PARAM_pMicroInitialOffsetB;
602         if (__notInRange(nodeConfigPtr->pMicroPerCycle, 640, 640000)) *errCode |= ERR_PARAM_pMicroPerCycle;
603         if (__notInRange(nodeConfigPtr->pRateCorrectionOut, 2, 1923)) *errCode |= ERR_PARAM_pRateCorrectionOut;
604         if (__notInRange(nodeConfigPtr->pOffsetCorrectionOut, 5, 0x3BA2)) *errCode |= ERR_PARAM_pOffsetCorrectionOut;
605         if (nodeConfigPtr->pWakeupChannel != FR_CHANNEL_A &&
606                 nodeConfigPtr->pWakeupChannel != FR_CHANNEL_B ) *errCode |= ERR_PARAM_pWakeupChannel;
607         if (__notInRange(nodeConfigPtr->pWakeupPattern, 2, 63)) *errCode |= ERR_PARAM_pWakeupPattern;
608         if (nodeConfigPtr->pSamplesPerMicrotick > 3)            *errCode |= ERR_PARAM_pSamplesPerMicrotick;
609         if (__notInRange(nodeConfigPtr->pDecodingCorrection, 0xF, 0x8F))        *errCode |= ERR_PARAM_pDecodingCorrection;
610
611         return (*errCode == 0) ? E_OK : E_NOT_OK;
612 }
613
614 /**
615  * @brief Check Configuration parameters for all buffers
616  *
617  * This function checks configuration parameters.
618  * For FIFO buffers:
619  *              - All of them have to be RX
620  *              - All of them have the same payload <= 256B
621  *              - Same channels active
622  *              - Same cycle counter filter
623  *              - not coldstart
624  *              - not single/auto
625  *              - not reconfigurable
626  *              - frame ID can be 0, which means that all messages not received by others buffers are received in FIFO.
627  * For dynamic segment buffers and static segment buffers:
628  *              - frame ID must not be 0
629  *              - payload <= 256B
630  * The sum of all configured payloads must be <= 8KB.
631  *
632  * @param [in] statBufCfgPtr Address of structure with static buffers configuration parameters
633  * @param [in] dynBufCfgPtr Address of structure with dynamic buffers configuration parameters
634  * @param [in] fifoBufCfgPtr Address of structure with fifo buffers configuration parameters
635  * @param [in] statBufCnt Number of static buffers to be configured
636  * @param [in] dynBufCnt Number of dynamic buffers to be configured
637  * @param [in] fifoBufCnt Number of fifo buffers to be configured
638  * @param [out] errCode Address where error flags will be stored.
639  *              Flags are defined as ERR_PARAM_BUF.....
640  * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
641  */
642 Std_ReturnType Fr_check_buffer_parameters(const Fr_TMS570LS_BufferConfigType* statBufCfgPtr, const Fr_TMS570LS_BufferConfigType* dynBufCfgPtr, const Fr_TMS570LS_BufferConfigType* fifoBufCfgPtr,
643                 uint8_t statBufCnt, uint8_t dynBufCnt, uint8_t fifoBufCnt, uint32_t* errCode) {
644         uint32_t payloadTotal = 0;
645         *errCode = ERR_PARAM_NO_ERROR;
646         uint8_t fifoPayload;
647         Fr_ChannelType fifoChannels;
648         uint8_t fifoCycleCounterFiltering;
649         uint8_t i;
650
651         /* Check FIFO buffer parameters */
652         if (fifoBufCnt != 0 && fifoBufCfgPtr != NULL) {
653                 fifoPayload = fifoBufCfgPtr[0].maxPayload;
654                 fifoChannels = fifoBufCfgPtr[0].channel;
655                 fifoCycleCounterFiltering = fifoBufCfgPtr[0].cycleCounterFiltering;
656                 if (fifoPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFFIFO_PAYLOAD_HIGH;
657                 for (i = 0; i < fifoBufCnt; i++) {
658                         if (fifoBufCfgPtr[i].isTx == TRUE) *errCode |= ERR_PARAM_BUFFIFO_NOT_RX;
659                         if (fifoBufCfgPtr[i].maxPayload != fifoPayload) *errCode |= ERR_PARAM_BUFFIFO_PAYLOAD_DIFFERS;
660                         if (fifoBufCfgPtr[i].channel != fifoChannels) *errCode |= ERR_PARAM_BUFFIFO_CHANNEL_DIFFERS;
661                         if (fifoBufCfgPtr[i].cycleCounterFiltering != fifoCycleCounterFiltering) *errCode |= ERR_PARAM_BUFFIFO_CCFILTER_DIFFERS;
662                         payloadTotal += fifoBufCfgPtr[i].maxPayload;
663                 }
664         }
665         if (dynBufCfgPtr != NULL) {
666                 for (i = 0; i < dynBufCnt; i++) {
667                         if (dynBufCfgPtr[i].slotId == 0) *errCode |= ERR_PARAM_BUFDYN_FRAMEID_INVALID;
668                         if (dynBufCfgPtr[i].maxPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFDYN_PAYLOAD_HIGH;
669                         if (dynBufCfgPtr[i].channel == FR_CHANNEL_AB) *errCode |= ERR_PARAM_BUFDYN_CHANNELS;
670                         payloadTotal += dynBufCfgPtr[i].maxPayload;
671                 }
672         }
673
674         if (statBufCfgPtr != NULL) {
675                 for (i = 0; i < statBufCnt; i++) {
676                         if (statBufCfgPtr[i].slotId == 0) *errCode |= ERR_PARAM_BUFSTAT_FRAMEID_INVALID;
677                         if (statBufCfgPtr[i].maxPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFSTAT_PAYLOAD_HIGH;
678                         payloadTotal += statBufCfgPtr[i].maxPayload;
679                 }
680         }
681
682         if (payloadTotal > 8192/2) *errCode |= ERR_PARAM_BUF_TOTAL_PAYLOAD_HIGH;
683
684         return (*errCode == 0) ? E_OK : E_NOT_OK;
685 }
686
687 /**
688  * @brief Compute and set message RAM config parameters into FlexRay configuration registers.
689  *
690  * This function does not check values ranges. This is a responsibility of other functions.
691  * Message RAM configuration parameters are computed from data in the structure and
692  * written into right bit position in configuration registers.
693  *
694  * @param [in] msgRAMConfigPtr Address of structure with message RAM configuration parameters
695  * @return Number of configured buffers
696  */
697 uint8_t Fr_config_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr) {
698         /* If dynSegmentBufferCount is not 0 then first dynamic buffer = statSegmentBufferCount.
699          * If dynSegmentBufferCount is 0 then first dynamic buffer is 0x80 (see TMS570LS31x documentation)
700          */
701         if (msgRAMConfigPtr->dynSegmentBufferCount == 0) {
702                 frayREG->MRC_UN.MRC_ST.fdb_B8 = 0x80;
703         }
704         else {
705                 frayREG->MRC_UN.MRC_ST.fdb_B8 = msgRAMConfigPtr->statSegmentBufferCount;
706         }
707         /* If fifoBufferCount is not 0 then first fifo buffer = statSegmentBufferCount + dynSegmentBufferCount
708          * If fifoBufferCount is 0 then first fifo buffer is 0x80 (see TMS570LS31x documentation)
709          */
710         if (msgRAMConfigPtr->fifoBufferCount == 0) {
711                 frayREG->MRC_UN.MRC_ST.ffb_B8 = 0x80;
712         }
713         else {
714                 frayREG->MRC_UN.MRC_ST.ffb_B8 = msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount;
715         }
716         /* Last configured buffer = statSegmentBufferCount + dynSegmentBufferCount + fifoBufferCount - 1 */
717         frayREG->MRC_UN.MRC_ST.lcb_B8 = msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount - 1;
718
719         /* Secure buffers setting */
720         if (msgRAMConfigPtr->secureBuffers == FR_SB_RECONFIG_ENABLED) {
721                 frayREG->MRC_UN.MRC_ST.sec_B2 = 0;
722         }
723         else if (msgRAMConfigPtr->secureBuffers == FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED) {
724                 frayREG->MRC_UN.MRC_ST.sec_B2 = 1;
725         }
726         else if (msgRAMConfigPtr->secureBuffers == FR_SB_ALL_REC_DISABLED) {
727                 frayREG->MRC_UN.MRC_ST.sec_B2 = 2;
728         }
729         else {
730                 frayREG->MRC_UN.MRC_ST.sec_B2 = 3;
731         }
732
733         /* Sync frame payload multiplex setting */
734         if (msgRAMConfigPtr->syncFramePayloadMultiplexEnabled == TRUE) {
735                 frayREG->MRC_UN.MRC_ST.splm_B1 = 1;
736         }
737         else {
738                 frayREG->MRC_UN.MRC_ST.splm_B1 = 0;
739         }
740
741         return msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount;
742 }
743
744 #define __notInRange(val, min, max)     (((val) < (min)) || ((val) > (max)))
745
746 /**
747  * @brief Check message RAM configuration parameters.
748  *
749  * This function checks values of the message RAM configuration parameters.
750  * FlexRay implementation in TMS570 can have up to 128 buffers configured, so
751  * the sum of all values buffer count must not exceed this ceiling.
752  *
753  *
754  * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
755  * @param [out] errCode Address where error flags will be stored.
756  *              Error flags are defined as macros ERR_PARAM_nameOfParameter.
757  * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
758  */
759 Std_ReturnType Fr_check_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr, uint32_t* errCode) {
760         *errCode = ERR_PARAM_NO_ERROR;
761
762         if (__notInRange(msgRAMConfigPtr->statSegmentBufferCount, 1, 127))      *errCode |= ERR_PARAM_statSegmentBufferCount;
763         if (msgRAMConfigPtr->dynSegmentBufferCount >= FR_MAX_BUFFERS_CNT)       *errCode |= ERR_PARAM_dynSegmentBufferCount;
764         if (msgRAMConfigPtr->fifoBufferCount >= FR_MAX_BUFFERS_CNT)                     *errCode |= ERR_PARAM_fifoBufferCount;
765         if ((msgRAMConfigPtr->statSegmentBufferCount +
766                 msgRAMConfigPtr->dynSegmentBufferCount +
767                 msgRAMConfigPtr->fifoBufferCount) >= FR_MAX_BUFFERS_CNT)                *errCode |= ERR_PARAM_maxBuffLimit;
768
769         return (*errCode == 0) ? E_OK : E_NOT_OK;
770 }
771
772 void Fr_Init(const Fr_ConfigType* Fr_ConfigPtr) {
773         uint32_t i;
774
775 #ifdef DET_ACTIVATED
776         if (Fr_ConfigPtr == NULL) {
777                 return;
778         }
779         if (Fr_DrvState != FR_ST_DRV_NOT_INITIALIZED) {
780                 return;
781         }
782 #endif
783         /* Save pointers for parameters indexed by CIDX indexes
784          * This array representation is used by Fr_ReadCCConfig function.
785          * Parameter thet are not configurable in tms570 FlexRay implementation
786          * are set as NULL.
787          */
788         Fr_ConfigParPtrs[FR_CIDX_GDCYCLE] = 0;
789         Fr_ConfigParPtrs[FR_CIDX_PMICROPERCYCLE] = Fr_ConfigPtr->nodeConfiguration->pMicroPerCycle;
790         Fr_ConfigParPtrs[FR_CIDX_PDLISTENTIMEOUT] = Fr_ConfigPtr->clusterConfiguration->gMacroPerCycle;
791         Fr_ConfigParPtrs[FR_CIDX_GDMACROTICK] = 0;
792         Fr_ConfigParPtrs[FR_CIDX_GNUMBEROFMINISLOTS] = Fr_ConfigPtr->clusterConfiguration->gNumberOfMinislots;
793         Fr_ConfigParPtrs[FR_CIDX_GNUMBEROFSTATICSLOTS] = Fr_ConfigPtr->clusterConfiguration->gNumberOfStaticSlots;
794         Fr_ConfigParPtrs[FR_CIDX_GDNIT] = Fr_ConfigPtr->clusterConfiguration->gdNIT;
795         Fr_ConfigParPtrs[FR_CIDX_GDSTATICSLOT] = Fr_ConfigPtr->clusterConfiguration->gdNIT;
796         Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXWINDOW] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolRxWindow;
797         Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTID] = 0;
798         Fr_ConfigParPtrs[FR_CIDX_PLATESTTX] = Fr_ConfigPtr->nodeConfiguration->pLatestTx;
799         Fr_ConfigParPtrs[FR_CIDX_POFFSETCORRECTIONOUT] = 0;
800         Fr_ConfigParPtrs[FR_CIDX_POFFSETCORRECTIONSTART] = 0;
801         Fr_ConfigParPtrs[FR_CIDX_PRATECORRECTIONOUT] = Fr_ConfigPtr->nodeConfiguration->pRateCorrectionOut;
802         Fr_ConfigParPtrs[FR_CIDX_PSECONDKEYSLOTID] = 0;
803         Fr_ConfigParPtrs[FR_CIDX_PDACCEPTEDSTARTUPRANGE] = Fr_ConfigPtr->nodeConfiguration->pdAcceptedStartupRange;
804         Fr_ConfigParPtrs[FR_CIDX_GCOLDSTARTATTEMPTS] = Fr_ConfigPtr->clusterConfiguration->gColdStartAttempts;
805         Fr_ConfigParPtrs[FR_CIDX_GCYCLECOUNTMAX] = 0;
806         Fr_ConfigParPtrs[FR_CIDX_GLISTENNOISE] = Fr_ConfigPtr->clusterConfiguration->gListenNoise;
807         Fr_ConfigParPtrs[FR_CIDX_GMAXWITHOUTCLOCKCORRECTFATAL] = Fr_ConfigPtr->clusterConfiguration->gMaxWithoutClockCorrectionFatal;
808         Fr_ConfigParPtrs[FR_CIDX_GMAXWITHOUTCLOCKCORRECTPASSIVE] = Fr_ConfigPtr->clusterConfiguration->gMaxWithoutClockCorrectionPassive;
809         Fr_ConfigParPtrs[FR_CIDX_GNETWORKMANAGEMENTVECTORLENGTH] = Fr_ConfigPtr->clusterConfiguration->gNetworkManagementVectorLength;
810         Fr_ConfigParPtrs[FR_CIDX_GPAYLOADLENGTHSTATIC] = Fr_ConfigPtr->clusterConfiguration->gPayloadLengthStatic;
811         Fr_ConfigParPtrs[FR_CIDX_GSYNCFRAMEIDCOUNTMAX] = 0;
812         Fr_ConfigParPtrs[FR_CIDX_GDACTIONPOINTOFFSET] = Fr_ConfigPtr->clusterConfiguration->gdActionPointOffset;
813         Fr_ConfigParPtrs[FR_CIDX_GDBIT] = 0;
814         Fr_ConfigParPtrs[FR_CIDX_GDCASRXLOWMAX] = Fr_ConfigPtr->clusterConfiguration->gdCASRxLowMax;
815         Fr_ConfigParPtrs[FR_CIDX_GDDYNAMICSLOTIDLEPHASE] = Fr_ConfigPtr->clusterConfiguration->gdDynamicSlotIdlePhase;
816         Fr_ConfigParPtrs[FR_CIDX_GDMINISLOTACTIONPOINTOFFSET] = Fr_ConfigPtr->clusterConfiguration->gdMinislotActionPointOffset;
817         Fr_ConfigParPtrs[FR_CIDX_GDMINISLOT] = Fr_ConfigPtr->clusterConfiguration->gdMinislot;
818         Fr_ConfigParPtrs[FR_CIDX_GDSAMPLECLOCKPERIOD] = Fr_ConfigPtr->clusterConfiguration->gdSampleClockPeriod;
819         Fr_ConfigParPtrs[FR_CIDX_GDSYMBOLWINDOW] = 0;
820         Fr_ConfigParPtrs[FR_CIDX_GDSYMBOLWINDOWACTIONPOINTOFFSET] = 0;
821         Fr_ConfigParPtrs[FR_CIDX_GDTSSTRANSMITTER] = Fr_ConfigPtr->clusterConfiguration->gdTSSTransmitter;
822         Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXIDLE] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolRxIdle;
823         Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXLOW] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolRxLow;
824         Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPTXACTIVE] = 0;
825         Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPTXIDLE] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolTxIdle;
826         Fr_ConfigParPtrs[FR_CIDX_PALLOWPASSIVETOACTIVE] = Fr_ConfigPtr->nodeConfiguration->pAllowPassiveToActive;
827         Fr_ConfigParPtrs[FR_CIDX_PCHANNELS] = Fr_ConfigPtr->nodeConfiguration->pChannels;
828         Fr_ConfigParPtrs[FR_CIDX_PCLUSTERDRIFTDAMPING] = Fr_ConfigPtr->nodeConfiguration->pClusterDriftDamping;
829         Fr_ConfigParPtrs[FR_CIDX_PDECODINGCORRECTION] = 0;
830         Fr_ConfigParPtrs[FR_CIDX_PDELAYCOMPENSATIONA] = Fr_ConfigPtr->nodeConfiguration->pDelayCompensationA;
831         Fr_ConfigParPtrs[FR_CIDX_PDELAYCOMPENSATIONB] = Fr_ConfigPtr->nodeConfiguration->pDelayCompensationB;
832         Fr_ConfigParPtrs[FR_CIDX_PMACROINITIALOFFSETA] = Fr_ConfigPtr->nodeConfiguration->pMacroInitialOffsetA;
833         Fr_ConfigParPtrs[FR_CIDX_PMACROINITIALOFFSETB] = Fr_ConfigPtr->nodeConfiguration->pMacroInitialOffsetB;
834         Fr_ConfigParPtrs[FR_CIDX_PMICROINITIALOFFSETA] = Fr_ConfigPtr->nodeConfiguration->pMicroInitialOffsetA;
835         Fr_ConfigParPtrs[FR_CIDX_PMICROINITIALOFFSETB] = Fr_ConfigPtr->nodeConfiguration->pMicroInitialOffsetB;
836         Fr_ConfigParPtrs[FR_CIDX_PPAYLOADLENGTHDYNMAX] = 0;
837         Fr_ConfigParPtrs[FR_CIDX_PSAMPLESPERMICROTICK] = Fr_ConfigPtr->nodeConfiguration->pSamplesPerMicrotick;
838         Fr_ConfigParPtrs[FR_CIDX_PWAKEUPCHANNEL] = Fr_ConfigPtr->nodeConfiguration->pWakeupChannel;
839         Fr_ConfigParPtrs[FR_CIDX_PWAKEUPPATTERN] = Fr_ConfigPtr->nodeConfiguration->pWakeupPattern;
840         Fr_ConfigParPtrs[FR_CIDX_PDMICROTICK] = 0;
841         Fr_ConfigParPtrs[FR_CIDX_GDIGNOREAFTERTX] = 0;
842         Fr_ConfigParPtrs[FR_CIDX_PALLOWHALTDUETOCLOCK] = Fr_ConfigPtr->nodeConfiguration->pAllowHaltDueToClock;
843         Fr_ConfigParPtrs[FR_CIDX_PEXTERNALSYNC] = 0;
844         Fr_ConfigParPtrs[FR_CIDX_PFALLBACKINTERNAL] = 0;
845         Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTONLYENABLED] = 0;
846         Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSTARTUP] = Fr_ConfigPtr->nodeConfiguration->pKeySlotUsedForStartup;
847         Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSYNC] = Fr_ConfigPtr->nodeConfiguration->pKeySlotUsedForSync;
848         Fr_ConfigParPtrs[FR_CIDX_PNMVECTOREARLYUPDATE] = 0;
849         Fr_ConfigParPtrs[FR_CIDX_PTWOKEYSLOTMODE] = 0;
850
851         /* Store whole configuration address
852          * This structured representation is used by other function in API.
853          */
854         Fr_Config = Fr_ConfigPtr;
855
856         /* Store pointers to structures with configuration parameters of buffers
857          * Reset configured flags for all buffers */
858         for (i = 0; i < Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount; ++i) { // Statis segment buffers
859                 Fr_buffer_slot_map[i].buffer_ptr = &Fr_ConfigPtr->staticBufferConfigs[i];
860                 Fr_buffer_slot_map[i].slot_id = Fr_ConfigPtr->staticBufferConfigs[i].slotId;
861                 Fr_BuffersConfigured[i] = FALSE;
862         }
863         for (i = 0; i < Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount; ++i) { // Dynamic segment buffers
864                 Fr_buffer_slot_map[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount].buffer_ptr = &Fr_ConfigPtr->dynamicBufferConfigs[i];
865                 Fr_buffer_slot_map[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount].slot_id = Fr_ConfigPtr->dynamicBufferConfigs[i].slotId;
866                 Fr_BuffersConfigured[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount] = FALSE;
867         }
868         for (i = 0; i < Fr_ConfigPtr->msgRAMConfig->fifoBufferCount; ++i) { // Fifo buffrers
869                 Fr_buffer_slot_map[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount].buffer_ptr = &Fr_ConfigPtr->fifoBufferConfigs[i];
870                 Fr_buffer_slot_map[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount].slot_id = Fr_ConfigPtr->fifoBufferConfigs[i].slotId;
871                 Fr_BuffersConfigured[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount] = FALSE;
872         }
873
874 #ifdef DET_ACTIVATED
875         Fr_DrvState = FR_ST_DRV_INITIALIZED;
876 #endif
877 }
878
879 Std_ReturnType Fr_ControllerInit(uint8_t Fr_CtrlIdx) {
880         uint32_t errCode = ERR_PARAM_NO_ERROR;
881         uint32_t i;
882         uint8_t totalBufferCount;
883
884 #ifdef DET_ACTIVATED
885         if (Fr_DrvState != FR_ST_DRV_INITIALIZED) {
886                 return E_NOT_OK;
887         }
888 #endif
889
890         /* Switch CC into â€˜POC:config’ (from any other POCState) */
891         if (Fr_POC_go_to_config() == E_NOT_OK) {
892                 return E_NOT_OK;
893         }
894         /* Check Cluster config parameters */
895         if (Fr_check_cluster_parameters(Fr_Config->clusterConfiguration, &errCode) == E_NOT_OK) {
896                 return E_NOT_OK | errCode | FR_INIT_ERR_CLUSTER_CONFIG;
897         }
898         /* Check node config parameters */
899         if (Fr_check_node_parameters(Fr_Config->nodeConfiguration, &errCode) == E_NOT_OK) {
900                 return E_NOT_OK | errCode | FR_INIT_ERR_NODE_CONFIG;
901         }
902         /* Check msgRAM config parameters */
903         if (Fr_check_msgRAM_parameters(Fr_Config->msgRAMConfig, &errCode) == E_NOT_OK) {
904                 return E_NOT_OK | errCode | FR_INIT_ERR_MSGRAM_CONFIG;
905         }
906         /* Check buffers parameters */
907         if (Fr_check_buffer_parameters(Fr_Config->staticBufferConfigs, Fr_Config->dynamicBufferConfigs, Fr_Config->fifoBufferConfigs,
908                         Fr_Config->msgRAMConfig->statSegmentBufferCount, Fr_Config->msgRAMConfig->dynSegmentBufferCount, Fr_Config->msgRAMConfig->fifoBufferCount, &errCode) == E_NOT_OK) {
909                 return E_NOT_OK | errCode | FR_INIT_ERR_BUFFPARAM_CONFIG;
910         }
911
912         /* Clear message RAM */
913         if (Fr_clear_msg_RAM() == FAILURE) {
914                 return E_NOT_OK;
915         }
916
917         /* Configure all FlexRay cluster, node and msgRAM parameters */
918         Fr_config_cluster_parameters(Fr_Config->clusterConfiguration);
919         Fr_config_node_parameters(Fr_Config->nodeConfiguration);
920
921         // Wait until CLEAR_RAMS command is complete
922         while (frayREG->MHDS_UN.MHDS_ST.cram_B1 == 1)
923                 ;
924
925         totalBufferCount = Fr_config_msgRAM_parameters(Fr_Config->msgRAMConfig);
926         Fr_MsgRAMDataStartAddress = totalBufferCount*4U; // First data section after headers sections in message RAM.
927         Fr_MsgRAMDataOffset = Fr_MsgRAMDataStartAddress;
928         /* Configure all transmit/receive resources */
929         for (i = 0; i < totalBufferCount; i++) {
930                 if (Fr_PrepareLPdu(Fr_CtrlIdx, Fr_buffer_slot_map[i].buffer_ptr->slotId) == E_NOT_OK) {
931                         return E_NOT_OK | FR_INIT_ERR_BUFF_CONFIG;
932                 }
933         }
934
935         /* Switch POC to ready state */
936         if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
937                 return E_NOT_OK;
938         }
939 #ifdef DET_ACTIVATED
940         Fr_DrvState = FR_ST_CTRL_INITIALIZED;
941 #endif
942         return E_OK;
943 }
944
945 Std_ReturnType Fr_StartCommunication(uint8_t Fr_CtrlIdx) {
946         uint32_t counter;
947         uint32_t state_value;
948         uint32_t csa;
949 #ifdef DET_ACTIVATED
950         if (Fr_CtrlIdx != 0) {
951                 return E_NOT_OK;
952         }
953         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
954                 return E_NOT_OK;
955         }
956         if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_HALT) {
957                 return E_NOT_OK;
958         }
959 #endif
960         // Node halted, switch to ready
961         if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_HALT) {
962                 if (Fr_POC_go_to_config() == E_NOT_OK) {
963                         return E_NOT_OK;
964                 }
965                 if (Fr_POC_go_to_config() == E_NOT_OK) {
966                         return E_NOT_OK;
967                 }
968                 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
969                         return E_NOT_OK;
970                 }
971         }
972
973         // Node is configured as coldstart
974         if (Fr_Config->nodeConfiguration->pKeySlotUsedForStartup == TRUE) {
975         // Start up loop
976         while(1) {
977             counter = 0;
978             // Try to integrate into an existing network as following coldstarter
979             if (Fr_POC_go_to_startup() == E_NOT_OK) {
980                 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_FOLLOW;        // Switch to run state error
981             }
982
983             do {        // Wait until NORMAL_ACTIVE state or timeout
984                 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
985                 counter++;
986             } while ((state_value != FR_POCS_NORMAL_ACTIVE) && (counter < FR_FCS_LISTEN_TIMEOUT));
987
988             // No success in integration, try to initiate FlexRay network as leading coldstarter.
989             if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_INTEGRATION_LISTEN){
990                 csa = frayREG->CCSV_UN.CCSV_ST.rca_B5;
991                 if (csa != 0) { // Some cold start attempts remaining
992                     if (Fr_AllowColdstart(Fr_CtrlIdx) == E_NOT_OK) {
993                         return E_NOT_OK | FR_STARTUP_ERR_CSINH_DIS;             // Cold start inhibit disabled error
994                     }
995                 }
996             }
997             do { // Wait until NORMAL_ACTIVE or INTEGRATION_LISTEN state
998                 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
999             } while ( (state_value != FR_POCS_NORMAL_ACTIVE) && (state_value != FR_POCS_INTEGRATION_LISTEN));
1000             if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_NORMAL_ACTIVE) // Success, break the start up loop
1001                 break;
1002             if (Fr_POC_go_to_ready_from_startup() == E_NOT_OK) { // No success. Switch back to READY state
1003                 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_READY;
1004             }
1005         }
1006         }
1007     // The node is not coldstarter, try to integrate into an existing network.
1008     else {
1009         if(Fr_POC_go_to_startup() == E_NOT_OK)  {
1010             return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_AS_NCOLD; // Switching to startup state as non-cold start node
1011         }
1012         else {
1013             // Wait until NORMAL_ACTIVE
1014             do {
1015                 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
1016             } while (state_value != FR_POCS_NORMAL_ACTIVE);
1017         }
1018     }
1019         return E_OK;
1020 }
1021
1022 Std_ReturnType Fr_AllowColdstart(uint8_t Fr_CtrlIdx) {
1023 #ifdef DET_ACTIVATED
1024         if (Fr_CtrlIdx != 0) {
1025                 return E_NOT_OK;
1026         }
1027         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1028                 return E_NOT_OK;
1029         }
1030 #endif
1031     Fr_wait_for_POC_ready();
1032     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_ALLOW_COLDSTART;
1033     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1034         return E_NOT_OK;
1035     Fr_wait_for_POC_ready();
1036     return E_OK;
1037 }
1038
1039 Std_ReturnType Fr_AllSlots(uint8_t Fr_CtrlIdx) {
1040 #ifdef DET_ACTIVATED
1041         if (Fr_CtrlIdx != 0) {
1042                 return E_NOT_OK;
1043         }
1044         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1045                 return E_NOT_OK;
1046         }
1047 #endif
1048     Fr_wait_for_POC_ready();
1049     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_ALL_SLOTS;
1050     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1051         return E_NOT_OK;
1052     Fr_wait_for_POC_ready();
1053     return E_OK;
1054 }
1055
1056 Std_ReturnType Fr_HaltCommunication(uint8_t Fr_CtrlIdx) {
1057 #ifdef DET_ACTIVATED
1058         if (Fr_CtrlIdx != 0) {
1059                 return E_NOT_OK;
1060         }
1061         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1062                 return E_NOT_OK;
1063         }
1064 #endif
1065     Fr_wait_for_POC_ready();
1066     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_HALT;
1067     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1068         return E_NOT_OK;
1069     Fr_wait_for_POC_ready();
1070         return E_OK;
1071 }
1072
1073 Std_ReturnType Fr_AbortCommunication(uint8_t Fr_CtrlIdx) {
1074 #ifdef DET_ACTIVATED
1075         if (Fr_CtrlIdx != 0) {
1076                 return E_NOT_OK;
1077         }
1078         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1079                 return E_NOT_OK;
1080         }
1081 #endif
1082     Fr_wait_for_POC_ready();
1083     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_FREEZE;
1084     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1085         return E_NOT_OK;
1086     Fr_wait_for_POC_ready();
1087         return E_OK;
1088 }
1089
1090 Std_ReturnType Fr_SendWUP(uint8_t Fr_CtrlIdx) {
1091 #ifdef DET_ACTIVATED
1092         if (Fr_CtrlIdx != 0) {
1093                 return E_NOT_OK;
1094         }
1095         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1096                 return E_NOT_OK;
1097         }
1098 #endif
1099     Fr_wait_for_POC_ready();
1100     frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_WAKEUP;
1101     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1102         return E_NOT_OK;
1103     Fr_wait_for_POC_ready();
1104         return E_OK;
1105 }
1106
1107 Std_ReturnType Fr_SetWakeupChannel(uint8_t Fr_CtrlIdx, Fr_ChannelType Fr_ChnlIdx) {
1108         Std_ReturnType retVal = E_OK;
1109
1110 #ifdef DET_ACTIVATED
1111         if (Fr_CtrlIdx != 0) {
1112                 return E_NOT_OK;
1113         }
1114         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1115                 return E_NOT_OK;
1116         }
1117         if (Fr_ChnlIdx == FR_CHANNEL_AB) {
1118                 return E_NOT_OK;
1119         }
1120         if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY) {
1121                 return E_NOT_OK;
1122         }
1123 #endif
1124         if (Fr_POC_go_to_config() == E_NOT_OK) {
1125                 return E_NOT_OK;
1126         }
1127         if (Fr_ChnlIdx == FR_CHANNEL_A) {
1128                 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 0;
1129                 retVal = E_OK;
1130         }
1131         else if (Fr_ChnlIdx == FR_CHANNEL_B) {
1132                 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 1;
1133                 retVal = E_OK;
1134         }
1135         else {
1136                 retVal = E_NOT_OK;
1137         }
1138         if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
1139                 retVal = E_NOT_OK;
1140         }
1141
1142         return retVal;
1143 }
1144
1145 Std_ReturnType Fr_GetPOCStatus(uint8_t Fr_CtrlIdx, Fr_POCStatusType* Fr_POCStatusPtr) {
1146 #ifdef DET_ACTIVATED
1147         if (Fr_CtrlIdx != 0) {
1148                 return E_NOT_OK;
1149         }
1150         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1151                 return E_NOT_OK;
1152         }
1153         if (Fr_POCStatusPtr == NULL) {
1154                 return E_NOT_OK;
1155         }
1156 #endif
1157         /* Slot mode detection */
1158         switch (frayREG->CCSV_UN.CCSV_ST.slm_B2) {
1159         case 0x0:       /* SINGLE */
1160                 Fr_POCStatusPtr->SlotMode = FR_SLOTMODE_KEYSLOT;
1161                 break;
1162         case 0x2:       /* ALL PENDING */
1163                 Fr_POCStatusPtr->SlotMode = FR_SLOTMODE_ALL_PENDING;
1164                 break;
1165         case 0x3:       /* ALL */
1166                 Fr_POCStatusPtr->SlotMode = FR_SLOTMODE_ALL;
1167                 break;
1168         default:
1169                 return E_NOT_OK;
1170         }
1171         /* Freeze request detection */
1172         Fr_POCStatusPtr->Freeze = (frayREG->CCSV_UN.CCSV_ST.fsi_B1 == 1) ? TRUE : FALSE;
1173         /* Halt request detection */
1174         Fr_POCStatusPtr->CHIHaltRequest = (frayREG->CCSV_UN.CCSV_ST.hrq_B1 == 1) ? TRUE : FALSE;
1175         /* Coldstart noise detection */
1176         Fr_POCStatusPtr->ColdstartNoise = (frayREG->CCSV_UN.CCSV_ST.csni_B1 == 1) ? TRUE : FALSE;
1177         /* Coldstart noise detection */
1178         Fr_POCStatusPtr->ColdstartNoise = (frayREG->CCSV_UN.CCSV_ST.csni_B1 == 1) ? TRUE : FALSE;
1179         /* Error mode detection */
1180         switch (frayREG->CCEV_UN.CCEV_ST.errm_B2) {
1181         case 0x0:       /* ACTIVE */
1182                 Fr_POCStatusPtr->ErrorMode = FR_ERRORMODE_ACTIVE;
1183                 break;
1184         case 0x1:       /* PASSIVE */
1185                 Fr_POCStatusPtr->ErrorMode = FR_ERRORMODE_PASSIVE;
1186                 break;
1187         case 0x2:       /* COMM_HALT */
1188                 Fr_POCStatusPtr->ErrorMode = FR_ERRORMODE_COMM_HALT;
1189                 break;
1190         default:
1191                 return E_NOT_OK;
1192         }
1193         /* POC state detection */
1194         switch (frayREG->CCSV_UN.CCSV_ST.pocs_B6) {
1195         case FR_POCS_ABORT_STARTUP:
1196         case FR_POCS_COLDSTART_COLLISION_RESOLUTION:
1197         case FR_POCS_COLDSTART_CONSISTENCY_CHECK:
1198         case FR_POCS_COLDSTART_GAP:
1199         case FR_POCS_COLDSTART_JOIN:
1200         case FR_POCS_COLDSTART_LISTEN:
1201         case FR_POCS_INITIALIZE_SCHEDULE:
1202         case FR_POCS_INTEGRATION_COLDSTART_CHECK:
1203         case FR_POCS_INTEGRATION_CONSISTENCY_CHECK:
1204         case FR_POCS_INTEGRATION_LISTEN:
1205         case FR_POCS_STARTUP_PREPARE:
1206                 Fr_POCStatusPtr->State = FR_POCSTATE_STARTUP;
1207                 break;
1208         case FR_POCS_CONFIG:
1209                 Fr_POCStatusPtr->State = FR_POCSTATE_CONFIG;
1210                 break;
1211         case FR_POCS_DEFAULT_CONFIG:
1212                 Fr_POCStatusPtr->State = FR_POCSTATE_DEFAULT_CONFIG;
1213                 break;
1214         case FR_POCS_HALT:
1215                 Fr_POCStatusPtr->State = FR_POCSTATE_HALT;
1216                 break;
1217         case FR_POCS_LOOPBACK:
1218                 Fr_POCStatusPtr->State = FR_POCSTATE_LOOPBACK;
1219                 break;
1220         case FR_POCS_MONITOR_MODE:
1221                 Fr_POCStatusPtr->State = FR_POCSTATE_MONITOR;
1222                 break;
1223         case FR_POCS_NORMAL_ACTIVE:
1224                 Fr_POCStatusPtr->State = FR_POCSTATE_NORMAL_ACTIVE;
1225                 break;
1226         case FR_POCS_NORMAL_PASSIVE:
1227                 Fr_POCStatusPtr->State = FR_POCSTATE_NORMAL_PASSIVE;
1228                 break;
1229         case FR_POCS_READY:
1230                 Fr_POCStatusPtr->State = FR_POCSTATE_READY;
1231                 break;
1232         case FR_POCS_WAKEUP_DETECT:
1233         case FR_POCS_WAKEUP_LISTEN:
1234         case FR_POCS_WAKEUP_SEND:
1235         case FR_POCS_WAKEUP_STANDBY:
1236                 Fr_POCStatusPtr->State = FR_POCSTATE_WAKEUP;
1237                 break;
1238         default:
1239                 return E_NOT_OK;
1240         }
1241         /* Wakeup substate detection */
1242         switch (frayREG->CCSV_UN.CCSV_ST.wsv_B3) {
1243         case FR_WSV_COLLISION_HEADER:
1244                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_COLLISION_HEADER;
1245                 break;
1246         case FR_WSV_COLLISION_UNKNOWN:
1247                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_COLLISION_UNKNOWN;
1248                 break;
1249         case FR_WSV_COLLISION_WUP:
1250                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_COLLISION_WUP;
1251                 break;
1252         case FR_WSV_RECEIVED_HEADER:
1253                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_RECEIVED_HEADER;
1254                 break;
1255         case FR_WSV_RECEIVED_WUP:
1256                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_RECEIVED_WUP;
1257                 break;
1258         case FR_WSV_TRANSMITTED:
1259                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_TRANSMITTED;
1260                 break;
1261         case FR_WSV_UNDEFINED:
1262                 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_UNDEFINED;
1263                 break;
1264         default:
1265                 return E_NOT_OK;
1266         }
1267         /* Startup substate detection */
1268         switch (frayREG->CCSV_UN.CCSV_ST.pocs_B6) {
1269         case FR_POCS_ABORT_STARTUP:
1270                 Fr_POCStatusPtr->StartupState = FR_STARTUP_ABORT;
1271                 break;
1272         case FR_POCS_COLDSTART_COLLISION_RESOLUTION:
1273                 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_COLLISION_RESOLUTION;
1274                 break;
1275         case FR_POCS_COLDSTART_CONSISTENCY_CHECK:
1276                 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_CONSISTENCY_CHECK;
1277                 break;
1278         case FR_POCS_COLDSTART_GAP:
1279                 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_GAP;
1280                 break;
1281         case FR_POCS_COLDSTART_JOIN:
1282                 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_JOIN;
1283                 break;
1284         case FR_POCS_COLDSTART_LISTEN:
1285                 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_LISTEN;
1286                 break;
1287         case FR_POCS_INITIALIZE_SCHEDULE:
1288                 Fr_POCStatusPtr->StartupState = FR_STARTUP_INITIALIZE_SCHEDULE;
1289                 break;
1290         case FR_POCS_INTEGRATION_COLDSTART_CHECK:
1291                 Fr_POCStatusPtr->StartupState = FR_STARTUP_INTEGRATION_COLDSTART_CHECK;
1292                 break;
1293         case FR_POCS_INTEGRATION_CONSISTENCY_CHECK:
1294                 Fr_POCStatusPtr->StartupState = FR_STARTUP_INTEGRATION_CONSISTENCY_CHECK;
1295                 break;
1296         case FR_POCS_INTEGRATION_LISTEN:
1297                 Fr_POCStatusPtr->StartupState = FR_STARTUP_INTEGRATION_LISTEN;
1298                 break;
1299         case FR_POCS_STARTUP_PREPARE:
1300                 Fr_POCStatusPtr->StartupState = FR_STARTUP_PREPARE;
1301                 break;
1302         default:
1303                 Fr_POCStatusPtr->StartupState = FR_STARTUP_UNDEFINED;
1304                 break;
1305         }
1306         return E_OK;
1307 }
1308
1309 Std_ReturnType Fr_TransmitTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, const uint8_t* Fr_LSduPtr, uint8_t Fr_LSduLength) {
1310         uint32_t byte, word, buffer, index, bufferIndex;
1311 #ifdef DET_ACTIVATED
1312         if (Fr_CtrlIdx != 0) {
1313                 return E_NOT_OK;
1314         }
1315         if (Fr_LPduIdx > cSlotIDMax) {
1316                 return E_NOT_OK;
1317         }
1318         if (Fr_LSduPtr == NULL) {
1319                 return E_NOT_OK;
1320         }
1321         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1322                 return E_NOT_OK;
1323         }
1324
1325 #endif
1326         /* Find the index of the buffer in configuration data array */
1327         for (bufferIndex = 0; bufferIndex <= frayREG->MRC_UN.MRC_ST.lcb_B8; bufferIndex++) {
1328                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1329                         if (Fr_BuffersConfigured[bufferIndex] == TRUE && Fr_buffer_slot_map[bufferIndex].buffer_ptr->isTx == TRUE) {    // Buffer was configured already and is TX
1330                                 memset((void *)frayREG->WRDS, 0, sizeof(frayREG->WRDS));
1331                                 for (word = 0; word < (Fr_LSduLength+3)/4; word++) {
1332                                         buffer = 0;
1333                                         for (byte = 0; byte < 4; byte++) {
1334                                                 index = word*4+byte;
1335                                                 if (index < Fr_LSduLength) {
1336                                                         buffer |= Fr_LSduPtr[index] << byte*8;
1337                                                 }
1338                                         }
1339                                         frayREG->WRDS[word] = buffer;
1340                                 }
1341                                 Fr_buffer_transmit_data(bufferIndex);
1342                                 return E_OK;
1343                         }
1344                 }
1345         }
1346         return E_NOT_OK;
1347 }
1348
1349 Std_ReturnType Fr_CancelTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
1350         uint8_t bufferIndex;
1351         uint8_t mode;
1352 #ifdef DET_ACTIVATED
1353         boolean_t canceled = FALSE;
1354         if (Fr_CtrlIdx != 0) {
1355                 return E_NOT_OK;
1356         }
1357         if (Fr_LPduIdx > cSlotIDMax) {
1358                 return E_NOT_OK;
1359         }
1360         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1361                 return E_NOT_OK;
1362         }
1363         if (Fr_Config->msgRAMConfig->secureBuffers != FR_SB_RECONFIG_ENABLED) {
1364                 return E_NOT_OK;
1365         }
1366 #endif
1367
1368         /* If bit IBCM.STXR in the input buffer command mask register is set (STXR = 1), the transmission request
1369          * flag TXR of the selected message buffer is automatically set after the message buffer has been updated.
1370          * If bit IBCM.STXR in the input buffer command mask register is reset (STXR = 0), the transmission request
1371          * flag TXR of the selected message buffer is reset. This can be used to stop transmission from message
1372          * buffers operated in continuous mode.
1373          */
1374
1375         /*
1376          * Write the same configuration into buffer headers with TXREQ disabled.
1377          */
1378
1379         for (bufferIndex = 0; bufferIndex <= frayREG->MRC_UN.MRC_ST.lcb_B8; bufferIndex++) {
1380                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1381                         if (Fr_BuffersConfigured[bufferIndex] == TRUE) {        // Buffer was already configured
1382                                 if (bufferIndex == 0) {
1383                                         if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE ||
1384                                                 Fr_Config->nodeConfiguration->pSingleSlotEnabled == TRUE
1385                                                 ) {
1386                                                 continue;       // The first buffer is used for synchronization and can not be reconfigured.
1387                                         }
1388
1389                                 }
1390                                 else if (bufferIndex == 1) {
1391                                         if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE &&
1392                                                 Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled == TRUE) {
1393                                                 continue;       // Sync frame payload multiplexing is enabled and the second buffer is used for synchronization and can not be reconfigured.
1394                                         }
1395                                 }
1396                                 mode = (Fr_buffer_slot_map[bufferIndex].buffer_ptr->singleTransmit == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
1397                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
1398                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
1399                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
1400                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_A || Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
1401                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_B || Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
1402                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->rejectNullFrames == TRUE) ? FRAY_BUF_REJECT_NULL_FRAMES : FRAY_BUF_ACCEPT_NULL_FRAMES;
1403                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->rejectStaticSegment == TRUE) ? FRAY_BUF_REJECT_STATIC_SEGMENT : FRAY_BUF_ACCEPT_STATIC_SEGMENT;
1404                                 mode |= FRAY_BUF_TXREQ_DIS;
1405                                 if (Fr_buffer_slot_map[bufferIndex].buffer_ptr->isTx == TRUE) {
1406                                         Fr_config_buffer(bufferIndex, mode, Fr_buffer_slot_map[bufferIndex].buffer_ptr->cycleCounterFiltering,  Fr_buffer_slot_map[bufferIndex].buffer_ptr->slotId, Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload, Fr_MsgRAMDataPtrs[bufferIndex]);
1407 #ifdef DET_ACTIVATED
1408                                         canceled = TRUE;
1409 #endif
1410                                 }
1411                         }
1412                 }
1413         }
1414
1415 #ifdef DET_ACTIVATED
1416         return (canceled == TRUE) ? E_OK : E_NOT_OK;
1417 #else
1418         return E_OK;
1419 #endif
1420 }
1421
1422 Std_ReturnType Fr_ReceiveRxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, uint8_t* Fr_LSduPtr, Fr_RxLPduStatusType* Fr_LPduStatusPtr, uint8_t* Fr_LSduLengthPtr) {
1423         volatile unsigned long * ndat[4] = {&frayREG->NDAT1_UN.NDAT1_UL, &frayREG->NDAT2_UN.NDAT2_UL, &frayREG->NDAT3_UN.NDAT3_UL, &frayREG->NDAT4_UN.NDAT4_UL};
1424         uint32_t bufferIndex;
1425         uint8_t halfWord;
1426 #ifdef DET_ACTIVATED
1427         if (Fr_CtrlIdx != 0) {
1428                 return E_NOT_OK;
1429         }
1430         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1431                 return E_NOT_OK;
1432         }
1433         if (Fr_LPduIdx > cSlotIDMax) {
1434                 return E_NOT_OK;
1435         }
1436         if (Fr_LSduPtr == NULL) {
1437                 return E_NOT_OK;
1438         }
1439         if (Fr_LPduStatusPtr == NULL) {
1440                 return E_NOT_OK;
1441         }
1442         if (Fr_LSduLengthPtr == NULL) {
1443                 return E_NOT_OK;
1444         }
1445 #endif
1446         /* Find the index of the buffer in configuration data array */
1447         *Fr_LSduLengthPtr = 0;
1448         *Fr_LPduStatusPtr = FR_NOT_RECEIVED;
1449         for (bufferIndex = 0; bufferIndex <= frayREG->MRC_UN.MRC_ST.lcb_B8; bufferIndex++) {
1450                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1451                         if (Fr_BuffersConfigured[bufferIndex] == TRUE) {        // Buffer was configured already
1452                                 /*
1453                                  * Determine if buffer is FIFO or standard static or dynamic buffer.
1454                                  * For FIFO:
1455                                  *      - Pop data and header into an output buffer.
1456                                  *      - Detect if more data is available in the FIFO and set Fr_LPduStatusPtr.
1457                                  *      - Store loaded payload from header of the output buffer.
1458                                  *      - Copy data from the output buffer to the Fr_LSduPtr address.
1459                                  * For S/D buffer:
1460                                  *      - Check New Data flag, if no new data received, return.
1461                                  *      - Load received data and header into the output buffer.
1462                                  *      - Store loaded payload from header of the output buffer.
1463                                  *      - Copy data from the output buffer to the Fr_LSduPtr address.
1464                                  */
1465                                 // FIXME: Receiving for FID rejection filter other than zero is not working. Why?
1466                                 if (bufferIndex >= frayREG->MRC_UN.MRC_ST.ffb_B8 &&  frayREG->FSR_UN.FSR_ST.rfne_B1 == 1) { // This is RX FIFO buffer and it is not empty
1467                                         Fr_buffer_receive_data_header(frayREG->MRC_UN.MRC_ST.ffb_B8);  // Consume first element from FIFO
1468                                         if (frayREG->FSR_UN.FSR_ST.rfne_B1 == 1) {      // FIFO not empty after last pop
1469                                                 *Fr_LPduStatusPtr = FR_RECEIVED_MORE_DATA_AVAILABLE;
1470                                         }
1471                                         else {  // FIFO empty after last pop
1472                                                 *Fr_LPduStatusPtr = FR_RECEIVED;
1473                                         }
1474                                 }
1475                                 else {  // Static/dynamic segment buffer
1476                                         if (*ndat[bufferIndex/32] & (0x1 << bufferIndex%32)) {          // New data received
1477                                                 Fr_buffer_receive_data_header(bufferIndex);     // Read data and header into output buffer
1478                                                 *Fr_LPduStatusPtr = FR_RECEIVED;
1479                                         }
1480                                         else {          // No new data received
1481                                                 return E_OK;
1482                                         }
1483                                 }
1484                                 /*
1485                                  * Copy data from output register into address from parameter Fr_LSduPtr.
1486                                  * Data in the output register are 32b words,
1487                                  * Data in Fr_LSduPtr are 8b words.
1488                                  */
1489                                 *Fr_LSduLengthPtr = frayREG->RDHS2_UN.RDHS2_ST.plr_B7*2;        // Number of bytes copied into Fr_LSduPtr
1490                                 for (halfWord = 0; halfWord < frayREG->RDHS2_UN.RDHS2_ST.plr_B7; halfWord++) {
1491                                         if (halfWord%2 == 0) {
1492                                                 Fr_LSduPtr[halfWord*2] = frayREG->RDDS[halfWord/2] & 0xFF;
1493                                                 Fr_LSduPtr[halfWord*2+1] = (frayREG->RDDS[halfWord/2] & 0xFF00) >> 8;
1494                                         }
1495                                         else {
1496                                                 Fr_LSduPtr[halfWord*2] = (frayREG->RDDS[halfWord/2] & 0xFF0000) >> 16;
1497                                                 Fr_LSduPtr[halfWord*2+1] = (frayREG->RDDS[halfWord/2] & 0xFF000000) >> 24;
1498                                         }
1499                                 }
1500                                 return E_OK;
1501                         }
1502                         else {  // Accessing buffer which was not yet configured.
1503                                 return E_NOT_OK;
1504                         }
1505                 }
1506         }
1507         return E_NOT_OK;        // No buffer with Fr_LPduIdx was found.
1508 }
1509
1510 Std_ReturnType Fr_CheckTxLPduStatus(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, Fr_TxLPduStatusType* Fr_TxLPduStatusPtr) {
1511         volatile unsigned long * txrq[4] = {&frayREG->TXRQ1_UN.TXRQ1_UL, &frayREG->TXRQ2_UN.TXRQ2_UL, &frayREG->TXRQ3_UN.TXRQ3_UL, &frayREG->TXRQ4_UN.TXRQ4_UL};
1512         uint8_t bufferIndex;
1513 #ifdef DET_ACTIVATED
1514         if (Fr_CtrlIdx != 0) {
1515                 return E_NOT_OK;
1516         }
1517         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1518                 return E_NOT_OK;
1519         }
1520         if (Fr_LPduIdx > cSlotIDMax) {
1521                 return E_NOT_OK;
1522         }
1523         if (Fr_TxLPduStatusPtr == NULL) {
1524                 return E_NOT_OK;
1525         }
1526 #endif
1527         for (bufferIndex = 0; bufferIndex <= frayREG->MRC_UN.MRC_ST.lcb_B8; bufferIndex++) {
1528                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1529                         if (Fr_BuffersConfigured[bufferIndex] == TRUE) {        // Buffer was configured already
1530                                 if (Fr_buffer_slot_map[bufferIndex].buffer_ptr->isTx == TRUE) {
1531                                         if (*txrq[bufferIndex/32] & (0x1 << bufferIndex%32)) {  // Transmit request is pending
1532                                                 *Fr_TxLPduStatusPtr = FR_NOT_TRANSMITTED;
1533                                         }
1534                                         else {
1535                                                 *Fr_TxLPduStatusPtr = FR_TRANSMITTED;
1536                                         }
1537                                         break;
1538                                 }
1539                         }
1540                 }
1541         }
1542         return E_OK;
1543 }
1544
1545 Std_ReturnType Fr_PrepareLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
1546         uint32_t bufferIndex;
1547         uint32_t mode;
1548
1549 #ifdef DET_ACTIVATED
1550         if (Fr_CtrlIdx != 0) {
1551                 return E_NOT_OK;
1552         }
1553         if (Fr_DrvState != FR_ST_DRV_INITIALIZED) {
1554                 return E_NOT_OK;
1555         }
1556         if (Fr_LPduIdx > cSlotIDMax) {
1557                 return E_NOT_OK;
1558         }
1559 #endif
1560         /* Find the index of the buffer in configuration data array */
1561         for (bufferIndex = 0; bufferIndex <= frayREG->MRC_UN.MRC_ST.lcb_B8; bufferIndex++) {
1562                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1563                         if (Fr_BuffersConfigured[bufferIndex] == FALSE) {       // Buffer was not yet configured
1564                                 mode = (Fr_buffer_slot_map[bufferIndex].buffer_ptr->msgBufferInterrupt == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
1565                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
1566                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
1567                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
1568                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_A || Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
1569                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_B || Fr_buffer_slot_map[bufferIndex].buffer_ptr->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
1570                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->rejectNullFrames == TRUE) ? FRAY_BUF_REJECT_NULL_FRAMES : FRAY_BUF_ACCEPT_NULL_FRAMES;
1571                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->rejectStaticSegment == TRUE) ? FRAY_BUF_REJECT_STATIC_SEGMENT : FRAY_BUF_ACCEPT_STATIC_SEGMENT;
1572                                 mode |= FRAY_BUF_TXREQ_DIS;
1573                                 if (bufferIndex == 0 || (bufferIndex == 1 && Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled == TRUE)) {      // Buffer 0 is always a key slot, if payload multiplexing is enabled, then buffer 1 serves for key slot as well.
1574                                         if (Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSTARTUP] == 1) {
1575                                                 mode |= FRAY_BUF_SFI_EN;
1576                                         }
1577                                         if (Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSYNC] == 1) {
1578                                                 mode |= FRAY_BUF_SYNC_EN;
1579                                         }
1580                                 }
1581                                 Fr_MsgRAMDataPtrs[bufferIndex] = Fr_MsgRAMDataOffset;
1582                                 if (bufferIndex >= frayREG->MRC_UN.MRC_ST.ffb_B8) { // This is RX FIFO buffer
1583                                         Fr_configure_fifo_buffer(bufferIndex, mode, Fr_buffer_slot_map[bufferIndex].buffer_ptr->cycleCounterFiltering,  Fr_buffer_slot_map[bufferIndex].buffer_ptr->slotId, Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload, Fr_MsgRAMDataPtrs[bufferIndex]);
1584                                 }
1585                                 else {  // Static/dynamic segment buffer
1586                                         Fr_config_buffer(bufferIndex, mode, Fr_buffer_slot_map[bufferIndex].buffer_ptr->cycleCounterFiltering,  Fr_buffer_slot_map[bufferIndex].buffer_ptr->slotId, Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload, Fr_MsgRAMDataPtrs[bufferIndex]);
1587                                 }
1588                                 /*
1589                                  * Calculate new address.
1590                                  * Payload contains the number of two-bytes words, Fr_MsgRAMDataPtrs contains addresses of 4B words in message RAM, all msgRAM addresses have
1591                                  * to be 4B aligned.
1592                                  * Offset has to be divided by two each time because  payload is in 2B words and msgRAM addresses are in 4B words.
1593                                  */
1594                                 Fr_MsgRAMDataOffset += ((Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload)%2U == 0U ? (Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload) : ((Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload)+1U))/2;
1595                                 Fr_BuffersConfigured[bufferIndex] = TRUE;
1596                         }
1597                 }
1598         }
1599         return E_OK;
1600 }
1601
1602 Std_ReturnType Fr_ReconfigLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, uint16_t Fr_FrameId, Fr_ChannelType Fr_ChnlIdx, uint8_t Fr_CycleFiltering, uint8_t Fr_PayloadLength) {
1603         uint32_t bufferIndex;
1604         uint8_t lowest_index = 0;
1605         uint8_t highest_index = frayREG->MRC_UN.MRC_ST.ffb_B8;
1606         uint32_t mode;
1607
1608 #ifdef DET_ACTIVATED
1609         boolean_t reconfigured = FALSE;
1610         if (Fr_CtrlIdx != 0) {
1611                 return E_NOT_OK;
1612         }
1613         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1614                 return E_NOT_OK;
1615         }
1616 #endif
1617         if (Fr_Config->msgRAMConfig->secureBuffers == FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED) {
1618                 lowest_index = frayREG->MRC_UN.MRC_ST.fdb_B8;
1619         }
1620         else if (Fr_Config->msgRAMConfig->secureBuffers == FR_SB_RECONFIG_ENABLED) {
1621                 if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync) {
1622                         if (Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled) {
1623                                 lowest_index = 2;
1624                         }
1625                         else {
1626                                 lowest_index = 1;
1627                         }
1628                 }
1629                 else {
1630                         lowest_index = 0;
1631                 }
1632         }
1633         else {
1634                 return E_NOT_OK | ERR_PARAM_RECONFIG_NOT_ALLOWED;
1635         }
1636
1637         if (Fr_FrameId == 0) {
1638                 return E_NOT_OK | ERR_PARAM_INVALID_FRAME_ID;
1639         }
1640         if (Fr_FrameId > Fr_Config->clusterConfiguration->gNumberOfStaticSlots &&
1641                         Fr_ChnlIdx == FR_CHANNEL_AB) {
1642                 return E_NOT_OK | ERR_PARAM_INVALID_CHANNEL;
1643         }
1644
1645         for (bufferIndex = lowest_index; bufferIndex < highest_index; bufferIndex++) {
1646                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1647                         if (Fr_BuffersConfigured[bufferIndex] == TRUE) {        // Buffer was configured already
1648                                 if (Fr_PayloadLength > Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload) {
1649                                         return E_NOT_OK | ERR_PARAM_PAYLOAD_TOO_BIG;
1650                                 }
1651                                 Fr_buffer_slot_map[bufferIndex].slot_id = Fr_FrameId;
1652                                 mode = (Fr_buffer_slot_map[bufferIndex].buffer_ptr->msgBufferInterrupt == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
1653                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
1654                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
1655                                 mode |= (Fr_buffer_slot_map[bufferIndex].buffer_ptr->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
1656                                 mode |= (Fr_ChnlIdx == FR_CHANNEL_A || Fr_ChnlIdx == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
1657                                 mode |= (Fr_ChnlIdx == FR_CHANNEL_B || Fr_ChnlIdx == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
1658                                 mode |= FRAY_BUF_TXREQ_DIS;
1659                                 Fr_config_buffer(bufferIndex, mode, Fr_CycleFiltering, Fr_FrameId, Fr_PayloadLength, Fr_MsgRAMDataPtrs[bufferIndex]);
1660 #ifdef DET_ACTIVATED
1661                                 reconfigured = TRUE;
1662 #endif
1663                         }
1664                 }
1665         }
1666
1667
1668         /* TODO: Implement */
1669 #ifdef DET_ACTIVATED
1670         if (reconfigured == FALSE)
1671                 return E_NOT_OK | ERR_PARAM_NO_BUFFER_FOUND;
1672 #endif
1673         return E_OK;
1674 }
1675
1676 Std_ReturnType Fr_DisableLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
1677         uint8_t bufferIndexLimit;
1678         uint8_t bufferIndex;
1679         uint8_t mode;
1680 #ifdef DET_ACTIVATED
1681         boolean_t disabled = FALSE;
1682         if (Fr_CtrlIdx != 0) {
1683                 return E_NOT_OK;
1684         }
1685         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1686                 return E_NOT_OK;
1687         }
1688         if (Fr_LPduIdx > cSlotIDMax) {
1689                 return E_NOT_OK;
1690         }
1691         if (Fr_Config->msgRAMConfig->secureBuffers != FR_SB_RECONFIG_ENABLED) {
1692                 return E_NOT_OK;
1693         }
1694 #endif
1695         /* Determine reconfigurable buffers from the data in MRC.SET bits */
1696         switch (frayREG->MRC_UN.MRC_ST.sec_B2) {
1697         case 0:
1698                 bufferIndexLimit = frayREG->MRC_UN.MRC_ST.ffb_B8;
1699                 break;
1700         case 1:
1701                 bufferIndexLimit = frayREG->MRC_UN.MRC_ST.fdb_B8;
1702                 break;
1703         default:
1704                 return E_OK;    // No reconfiguration enabled
1705         }
1706
1707         /* Find the index of the buffer in configuration data array */
1708         for (bufferIndex = 0; bufferIndex <= frayREG->MRC_UN.MRC_ST.lcb_B8; bufferIndex++) {
1709                 if (Fr_buffer_slot_map[bufferIndex].slot_id == Fr_LPduIdx) {
1710                         if (Fr_BuffersConfigured[bufferIndex] == TRUE) {        // Buffer was not yet configured
1711                                 if (bufferIndex == 0) {
1712                                         if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE ||
1713                                                 Fr_Config->nodeConfiguration->pSingleSlotEnabled == TRUE
1714                                                 ) {
1715                                                 continue;       // The first buffer is used for synchronization and can not be reconfigured.
1716                                         }
1717
1718                                 }
1719                                 else if (bufferIndex == 1) {
1720                                         if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE &&
1721                                                 Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled == TRUE) {
1722                                                 continue;       // Sync frame payload multiplexing is enabled and the second buffer is used for synchronization and can not be reconfigured.
1723                                         }
1724                                 }
1725                                 if (bufferIndex < bufferIndexLimit) {   // Buffer is reconfigurable, reset its configuration registers.
1726                                         mode = 0;
1727                                         Fr_MsgRAMDataPtrs[bufferIndex] = 0;
1728                                         Fr_BuffersConfigured[bufferIndex] = FALSE;
1729                                         Fr_config_buffer(bufferIndex, mode, Fr_buffer_slot_map[bufferIndex].buffer_ptr->cycleCounterFiltering,  Fr_buffer_slot_map[bufferIndex].buffer_ptr->slotId, Fr_buffer_slot_map[bufferIndex].buffer_ptr->maxPayload, Fr_MsgRAMDataPtrs[bufferIndex]);
1730 #ifdef DET_ACTIVATED
1731                                         disabled = TRUE;
1732 #endif
1733                                 }
1734                         }
1735                 }
1736         }
1737 #ifdef DET_ACTIVATED
1738         return (disabled == TRUE) ? E_OK : E_NOT_OK;
1739 #else
1740         return E_OK;
1741 #endif
1742 }
1743
1744 Std_ReturnType Fr_GetGlobalTime(uint8_t Fr_CtrlIdx, uint8_t* Fr_CyclePtr, uint16_t* Fr_MacroTickPtr) {
1745 #ifdef DET_ACTIVATED
1746         if (Fr_CtrlIdx != 0) {
1747                 return E_NOT_OK;
1748         }
1749         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1750                 return E_NOT_OK;
1751         }
1752         if (Fr_CyclePtr == NULL) {
1753                 return E_NOT_OK;
1754         }
1755         if (Fr_MacroTickPtr == NULL) {
1756                 return E_NOT_OK;
1757         }
1758 #endif
1759         uint32_t time = frayREG->MTCCV_UN.MTCCV_UL;
1760         *Fr_CyclePtr = __mfld2val(MTCCV_CCV_MSK, time);
1761         *Fr_MacroTickPtr = __mfld2val(MTCCV_MTV_MSK, time);
1762         return E_OK;
1763 }
1764
1765 static inline uint32_t swap32(uint32_t x)
1766 {
1767         return  (x & 0x000000ff) << 24 |
1768                 (x & 0x0000ff00) << 8 |
1769                 (x & 0x00ff0000) >> 8 |
1770                 (x & 0xff000000) >> 24;
1771 }
1772
1773 Std_ReturnType Fr_GetNmVector(uint8_t Fr_CtrlIdx, uint8_t* Fr_NmVectorPtr) {
1774 #ifdef DET_ACTIVATED
1775         if (Fr_CtrlIdx != 0) {
1776                 return E_NOT_OK;
1777         }
1778         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1779                 return E_NOT_OK;
1780         }
1781         if (Fr_NmVectorPtr == NULL) {
1782                 return E_NOT_OK;
1783         }
1784 #endif
1785         *((uint32_t*)(Fr_NmVectorPtr+0)) = swap32(frayREG->NMV1_UN.NMV1_UL);
1786         *((uint32_t*)(Fr_NmVectorPtr+4)) = swap32(frayREG->NMV2_UN.NMV2_UL);
1787         *((uint32_t*)(Fr_NmVectorPtr+8)) = swap32(frayREG->NMV3_UL);
1788         return E_OK;
1789 }
1790
1791 Std_ReturnType Fr_GetNumOfStartupFrames(uint8_t Fr_CtrlIdx, uint8_t* Fr_NumOfStartupFramesPtr) {
1792         /* TODO: Implement - can not find this information in the datasheet */
1793         return E_OK;
1794 }
1795
1796 Std_ReturnType Fr_GetChannelStatus(uint8_t Fr_CtrlIdx, uint16_t* Fr_ChannelAStatusPtr, uint16_t* Fr_ChannelBStatusPtr) {
1797 #ifdef DET_ACTIVATED
1798         if (Fr_CtrlIdx != 0) {
1799                 return E_NOT_OK;
1800         }
1801         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1802                 return E_NOT_OK;
1803         }
1804         if (Fr_ChannelAStatusPtr == NULL) {
1805                 return E_NOT_OK;
1806         }
1807         if (Fr_ChannelBStatusPtr == NULL) {
1808                 return E_NOT_OK;
1809         }
1810 #endif
1811         *Fr_ChannelAStatusPtr = 0;
1812         *Fr_ChannelBStatusPtr = 0;
1813
1814         *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.vfra_B1;
1815         *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.seda_B1 << 1;
1816         *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.ceda_B1 << 2;
1817         *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.cia_B1 << 3;
1818         *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.sbva_B1 << 4;
1819         *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.mtsa_B1 << 8;
1820         *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sesa_B1 << 9;
1821         *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbsa_B1 << 10;
1822         *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.tcsa_B1 << 11;
1823         *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sena_B1 << 12;
1824         *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbna_B1 << 13;
1825
1826         *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.vfrb_B1;
1827         *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.sedb_B1 << 1;
1828         *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.cedb_B1 << 2;
1829         *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.cib_B1 << 3;
1830         *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.sbvb_B1 << 4;
1831         *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.mtsb_B1 << 8;
1832         *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sesb_B1 << 9;
1833         *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbsb_B1 << 10;
1834         *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.tcsb_B1 << 11;
1835         *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.senb_B1 << 12;
1836         *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbnb_B1 << 13;
1837
1838         return E_OK;
1839 }
1840
1841 Std_ReturnType Fr_GetClockCorrection(uint8_t Fr_CtrlIdx, int16_t* Fr_RateCorrectionPtr, int32_t* Fr_OffsetCorrectionPtr) {
1842 #ifdef DET_ACTIVATED
1843         if (Fr_CtrlIdx != 0) {
1844                 return E_NOT_OK;
1845         }
1846         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1847                 return E_NOT_OK;
1848         }
1849         if (Fr_RateCorrectionPtr == NULL) {
1850                 return E_NOT_OK;
1851         }
1852         if (Fr_OffsetCorrectionPtr == NULL) {
1853                 return E_NOT_OK;
1854         }
1855 #endif
1856         *Fr_RateCorrectionPtr = frayREG->RCV_UN.RCV_ST.rcv_B12;
1857         *Fr_OffsetCorrectionPtr = frayREG->OCV_UN.OCV_ST.ocv_B14;
1858
1859         return E_OK;
1860 }
1861
1862 Std_ReturnType Fr_GetSyncFrameList(uint8_t Fr_CtrlIdx, uint8_t Fr_ListSize, uint16_t* Fr_ChannelAEvenListPtr, uint16_t* Fr_ChannelBEvenListPtr, uint16_t* Fr_ChannelAOddListPtr, uint16_t* Fr_ChannelBOddListPtr) {
1863         uint32_t esid;
1864         uint32_t osid;
1865         uint8_t i;
1866 #ifdef DET_ACTIVATED
1867         if (Fr_CtrlIdx != 0) {
1868                 return E_NOT_OK;
1869         }
1870         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1871                 return E_NOT_OK;
1872         }
1873         if (Fr_ChannelAEvenListPtr == NULL) {
1874                 return E_NOT_OK;
1875         }
1876         if (Fr_ChannelBEvenListPtr == NULL) {
1877                 return E_NOT_OK;
1878         }
1879         if (Fr_ChannelAOddListPtr == NULL) {
1880                 return E_NOT_OK;
1881         }
1882         if (Fr_ChannelBOddListPtr == NULL) {
1883                 return E_NOT_OK;
1884         }
1885 #endif
1886
1887         if (Fr_ListSize > FR_MAX_SYNC_FRAME_LIST_SIZE) { // Limit list size to 15
1888                 Fr_ListSize = FR_MAX_SYNC_FRAME_LIST_SIZE;
1889         }
1890
1891         for (i = 0; i < Fr_ListSize; i++) {
1892                 esid = frayREG->ESID_UL[i];
1893                 osid = frayREG->OSID_UL[i];
1894
1895                 Fr_ChannelAEvenListPtr[i] = (__mfld2val(ESID_RXEA_MSK, esid) == 1) ? __mfld2val(ESID_EID_MSK, esid) : 0;
1896                 Fr_ChannelBEvenListPtr[i] = (__mfld2val(ESID_RXEB_MSK, esid) == 1) ? __mfld2val(ESID_EID_MSK, esid) : 0;
1897                 Fr_ChannelAOddListPtr[i] = (__mfld2val(OSID_RXOA_MSK, osid) == 1) ? __mfld2val(OSID_OID_MSK, osid) : 0;
1898                 Fr_ChannelBOddListPtr[i] = (__mfld2val(OSID_RXOB_MSK, osid) == 1) ? __mfld2val(OSID_OID_MSK, osid) : 0;
1899         }
1900
1901         for (i = Fr_ListSize; i < 15; i++) {
1902                 Fr_ChannelAEvenListPtr[i] = 0;
1903                 Fr_ChannelBEvenListPtr[i] = 0;
1904                 Fr_ChannelAOddListPtr[i] = 0;
1905                 Fr_ChannelBOddListPtr[i] = 0;
1906         }
1907
1908         return E_OK;
1909 }
1910
1911 Std_ReturnType Fr_GetWakeupRxStatus(uint8_t Fr_CtrlIdx, uint8_t* Fr_WakeupRxStatusPtr) {
1912 #ifdef DET_ACTIVATED
1913         if (Fr_CtrlIdx != 0) {
1914                 return E_NOT_OK;
1915         }
1916         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1917                 return E_NOT_OK;
1918         }
1919         if (Fr_WakeupRxStatusPtr == NULL) {
1920                 return E_NOT_OK;
1921         }
1922 #endif
1923
1924         *Fr_WakeupRxStatusPtr = 0;
1925         *Fr_WakeupRxStatusPtr |= frayREG->SIR_UN.SIR_ST.wupa_B1;
1926         *Fr_WakeupRxStatusPtr |= frayREG->SIR_UN.SIR_ST.wupb_B1 << 1;
1927         // Reset flags
1928         frayREG->SIR_UN.SIR_ST.wupa_B1 = 1;
1929         frayREG->SIR_UN.SIR_ST.wupb_B1 = 1;
1930         return E_OK;
1931 }
1932
1933 Std_ReturnType Fr_SetAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, uint8_t Fr_Cycle, uint16_t Fr_Offset) {
1934 #ifdef DET_ACTIVATED
1935         if (Fr_CtrlIdx != 0) {
1936                 return E_NOT_OK;
1937         }
1938         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1939                 return E_NOT_OK;
1940         }
1941         if (Fr_AbsTimerIdx > 1) {
1942                 return E_NOT_OK;
1943         }
1944         if (Fr_Offset > Fr_Config->clusterConfiguration->gMacroPerCycle) {
1945                 return E_NOT_OK;
1946         }
1947         if (Fr_Cycle & 0x80) {
1948                 return E_NOT_OK;
1949         }
1950 #endif
1951         if (Fr_AbsTimerIdx == 0) {
1952                 frayREG->T0C_UN.T0C_ST.t0rc_B1 = 0;
1953                 frayREG->T0C_UN.T0C_ST.t0ms_B1 = 1;
1954                 frayREG->T0C_UN.T0C_ST.t0cc_B7 = Fr_Cycle;
1955                 frayREG->T0C_UN.T0C_ST.t0mo_B14 = Fr_Offset;
1956                 frayREG->SIR_UN.SIR_ST.ti0_B1 = 1;      // Reset interrupt
1957                 frayREG->T0C_UN.T0C_ST.t0rc_B1 = 1;
1958         }
1959         else if (Fr_AbsTimerIdx == 1) {
1960                 frayREG->T1C_UN.T1C_ST.t1rc_B1 = 0;
1961                 frayREG->T1C_UN.T1C_ST.t1ms_B1 = 1;
1962                 frayREG->T1C_UN.T1C_ST.t1mc_B14 = Fr_Cycle*Fr_Config->clusterConfiguration->gMacroPerCycle+Fr_Offset;
1963                 frayREG->SIR_UN.SIR_ST.ti1_B1 = 1;// Reset interrupt
1964                 frayREG->T1C_UN.T1C_ST.t1rc_B1 = 1;
1965         }
1966         else {
1967                 return E_NOT_OK;
1968         }
1969
1970         return E_OK;
1971 }
1972
1973 Std_ReturnType Fr_CancelAbsoluteTimer(uint8_t Fr_CtrlIdx,       uint8_t Fr_AbsTimerIdx) {
1974 #ifdef DET_ACTIVATED
1975         if (Fr_CtrlIdx != 0) {
1976                 return E_NOT_OK;
1977         }
1978         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1979                 return E_NOT_OK;
1980         }
1981         if (Fr_AbsTimerIdx > 1) {
1982                 return E_NOT_OK;
1983         }
1984 #endif
1985         if (Fr_AbsTimerIdx == 0) {
1986                 frayREG->T0C_UN.T0C_ST.t0rc_B1 = 0;
1987         }
1988         else if (Fr_AbsTimerIdx == 1) {
1989                 frayREG->T1C_UN.T1C_ST.t1rc_B1 = 0;
1990         }
1991         else {
1992                 return E_NOT_OK;
1993         }
1994         return E_OK;
1995 }
1996
1997 Std_ReturnType Fr_EnableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
1998 #ifdef DET_ACTIVATED
1999         if (Fr_CtrlIdx != 0) {
2000                 return E_NOT_OK;
2001         }
2002         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2003                 return E_NOT_OK;
2004         }
2005         if (Fr_AbsTimerIdx > 1) {
2006                 return E_NOT_OK;
2007         }
2008 #endif
2009         frayREG->ILE_UN.ILE_ST.eint0_B1 = 1;
2010         if (Fr_AbsTimerIdx == 0) {
2011                 frayREG->SIES_UN.SIES_ST.ti0e_B1 = 1;
2012         }
2013         else if (Fr_AbsTimerIdx == 1) {
2014                 frayREG->SIES_UN.SIES_ST.ti0e_B1 = 1;
2015         }
2016         else {
2017                 return E_NOT_OK;
2018         }
2019         return E_OK;
2020 }
2021
2022 Std_ReturnType Fr_AckAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
2023 #ifdef DET_ACTIVATED
2024         if (Fr_CtrlIdx != 0) {
2025                 return E_NOT_OK;
2026         }
2027         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2028                 return E_NOT_OK;
2029         }
2030         if (Fr_AbsTimerIdx > 1) {
2031                 return E_NOT_OK;
2032         }
2033 #endif
2034         if (Fr_AbsTimerIdx == 0) {
2035                 frayREG->SIR_UN.SIR_ST.ti0_B1 = 1;
2036         }
2037         else if (Fr_AbsTimerIdx == 1) {
2038                 frayREG->SIR_UN.SIR_ST.ti1_B1 = 1;
2039         }
2040         else {
2041                 return E_NOT_OK;
2042         }
2043         return E_OK;
2044 }
2045
2046 Std_ReturnType Fr_DisableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
2047 #ifdef DET_ACTIVATED
2048         if (Fr_CtrlIdx != 0) {
2049                 return E_NOT_OK;
2050         }
2051         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2052                 return E_NOT_OK;
2053         }
2054         if (Fr_AbsTimerIdx > 1) {
2055                 return E_NOT_OK;
2056         }
2057 #endif
2058         if (Fr_AbsTimerIdx == 0) {
2059                 frayREG->SIER_UN.SIER_ST.ti0e_B1 = 1;
2060         }
2061         else if (Fr_AbsTimerIdx == 1) {
2062                 frayREG->SIER_UN.SIER_ST.ti0e_B1 = 1;
2063         }
2064         else {
2065                 return E_NOT_OK;
2066         }
2067         return E_OK;
2068 }
2069
2070 Std_ReturnType Fr_GetAbsoluteTimerIRQStatus(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, boolean_t* Fr_IRQStatusPtr) {
2071 #ifdef DET_ACTIVATED
2072         if (Fr_CtrlIdx != 0) {
2073                 return E_NOT_OK;
2074         }
2075         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2076                 return E_NOT_OK;
2077         }
2078         if (Fr_AbsTimerIdx > 1) {
2079                 return E_NOT_OK;
2080         }
2081         if (Fr_IRQStatusPtr == NULL) {
2082                 return E_NOT_OK;
2083         }
2084 #endif
2085         if (Fr_AbsTimerIdx == 0) {
2086                 *Fr_IRQStatusPtr = (frayREG->SIR_UN.SIR_ST.ti0_B1 == 1) ? TRUE : FALSE;
2087         }
2088         else if (Fr_AbsTimerIdx == 1) {
2089                 *Fr_IRQStatusPtr = (frayREG->SIR_UN.SIR_ST.ti1_B1 == 1) ? TRUE : FALSE;
2090         }
2091         else {
2092                 return E_NOT_OK;
2093         }
2094         return E_OK;
2095 }
2096
2097 void Fr_GetVersionInfo(Std_VersionInfoType* VersioninfoPtr) {
2098 #ifdef DET_ACTIVATED
2099         if (VersioninfoPtr == NULL) {
2100                 return;
2101         }
2102 #endif
2103         VersioninfoPtr->vendorID = Fr_versionInfo.vendorID;
2104         VersioninfoPtr->moduleID = Fr_versionInfo.moduleID;
2105         VersioninfoPtr->sw_major_version = Fr_versionInfo.sw_major_version;
2106         VersioninfoPtr->sw_minor_version= Fr_versionInfo.sw_minor_version;
2107         VersioninfoPtr->sw_patch_version= Fr_versionInfo.sw_patch_version;
2108 }
2109
2110 Std_ReturnType Fr_ReadCCConfig( uint8_t Fr_CtrlIdx, uint8_t Fr_ConfigParamIdx, uint32_t* Fr_ConfigParamValuePtr) {
2111
2112 #ifdef DET_ACTIVATED
2113         if (Fr_CtrlIdx != 0) {
2114                 return E_NOT_OK;
2115         }
2116         if (Fr_ConfigParamIdx >= FR_CIDX_CNT) {
2117                 return E_NOT_OK;
2118         }
2119         if (Fr_ConfigParamValuePtr == NULL) {
2120                 return E_NOT_OK;
2121         }
2122         if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2123                 return E_NOT_OK;
2124         }
2125 #endif
2126
2127         *Fr_ConfigParamValuePtr = Fr_ConfigParPtrs[Fr_ConfigParamIdx];
2128         return E_OK;
2129 }
2130
2131 int Fr_spi_transfer(uint8_t port) {
2132     uint32_t commands[2];
2133     port_desc_t* desc;
2134
2135     if (port > FRAY_NUM_PORTS) return -1;
2136     desc = hal_port_get_dsc(fray_port_names[port], -1);
2137     fray_spi_cmd_sh = fray_spi_cmd;
2138     commands[0] = (fray_spi_cmd_sh & 0xFF00) >> 8;
2139     commands[1] = (fray_spi_cmd_sh & 0xFF);
2140
2141     fray_spi_resp[port] = desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
2142     return 0;
2143 }
2144
2145 int Fr_spi_response(uint8_t port) {
2146     if (port > FRAY_NUM_PORTS) return -1;
2147     return fray_spi_resp[port];
2148 }
2149
2150 int Fr_spi_get_cmd(uint8_t port) {
2151     if (port > FRAY_NUM_PORTS) return -1;
2152     return fray_spi_cmd;
2153 }