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