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