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