1 /* Copyright (C) 2012-2013, 2015 Czech Technical University in Prague
4 * - Michal Horn <hornmich@fel.cvut.cz>
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
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
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.
30 * FlexRay Communication driver for TMS570 source file.
34 #include "sys/ti_drv_fray.h"
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.
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;
52 static Std_VersionInfoType Fr_versionInfo = {
53 .vendorID = 0x00000001,
54 .moduleID = 0x00000002,
55 .sw_major_version = 0,
56 .sw_minor_version = 1,
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.
71 static uint32_t Fr_ConfigParPtrs[FR_CIDX_CNT];
73 * Address of the unified structure with complete configuration of
74 * the FlexRay node (cluster, node, message RAM and buffer configuration)
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];
84 * Address of the next free position in message RAM, which can be assigned
85 * to configured buffer. Addresses 32b words.
87 static uint32_t Fr_MsgRAMDataOffset;
89 * Address of the first free position in message RAM, which can be assigned
90 * to the first configured buffer. Addresses 32b words.
92 static uint32_t Fr_MsgRAMDataStartAddress;
95 * Development error detection.
96 * Comment this line to disable error detection and make function processing
97 * faster, but more dangerous.
102 * How much times should be the CC test repeated
104 * The CC test verifies the values written to the FlexRay configuration registers.
106 uint32_t FrCtrlTestCount = 50;
109 * Fr_PrepareLPdu and Fr_ReconfigLPdu functions enabled
111 * If the value of this variable is false, the only one API function that is allowed to configure buffers is the Fr_ControllerInit.
113 boolean_t FrBufferReconfig = TRUE;
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.
120 static Fr_TMS570LS_DriverState Fr_DrvState = FR_ST_DRV_NOT_INITIALIZED;
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.
127 * @param[in] buffer_cfg_ptr Address of the buffer configuration parameters
128 * @param[in] index of the buffer to which belong the parameters
130 * @return Buffer configuration flags. Their definition can be found in fr_tms570.h file as macros with prefixes FRAY_BUF_
132 uint32_t Fr_buffer_config_flags(const Fr_TMS570LS_BufferConfigType *buffer_cfg_ptr, uint8_t bufferIndex)
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;
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
158 * RX FIFO buffer is never configurable.
160 * @return -1 if buffer reconfiguration is prohibited, otherwise returns index of the first buffer, which is reconfigurable.
162 int Fr_reconfigurable_buffer_index()
164 int lowest_index = -1;
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
172 if (Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled)
186 * Compute CRC for message RAM header data
188 * @param[in] Fr_LPduPtr Pointer to header data
191 static int Fr_header_crc_calc(const wrhs *Fr_LPduPtr)
198 unsigned long CrcPoly = 0x385;
199 unsigned long CrcReg_X = CrcInit;
200 unsigned long header_temp, reg_temp;
202 header = ((Fr_LPduPtr->sync & 0x1) << 19) | ((Fr_LPduPtr->sfi & 0x1) << 18);
203 header |= ((Fr_LPduPtr->fid & 0x7FF) << 7) | (Fr_LPduPtr->pl & 0x7F);
211 header_temp = header & 0x80000000;
212 reg_temp = CrcReg_X & 0x80000000;
214 if (header_temp ^ reg_temp) // Step 1
219 CrcReg_X <<= 1; // Step 2
222 CrcReg_X ^= CrcPoly; // Step 3
231 * Retrieve data and header from message buffer into output buffer.
233 * Upper software layers have to read the header and data from RDDS and RDHS registers.
234 * @param[in] buf_num Number of buffer
236 static void Fr_buffer_receive_data_header(uint32_t buf_num)
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
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) ;
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
256 * Transfer data to the message RAM using the input buffer
258 * @param[in] Fr_LSduPtr Pointer to data structure with input buffer settings
260 inline void Fr_transmit_tx_LPdu(const bc *Fr_LSduPtr)
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)) ;
274 * Fill the buffer configuration data structure with given data and transfer it to the message RAM header using the input buffer.
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
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)
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
299 // Write Header Section 2 (WRHS2)
300 Fr_LPdu.pl = payload; // Payload Length
302 // Write Header Section 3 (WRHS3)
303 Fr_LPdu.dp = data_pointer; // Pointer to start of data in message RAM
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
308 // Write Header Section 2 (WRHS2)
309 Fr_LPdu.crc = (mode&FRAY_BUF_TX) ? Fr_header_crc_calc(&Fr_LPdu) : 0;
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
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
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;
333 wrhs2 = ((Fr_LPdu.pl & 0x7F) << 16) | (Fr_LPdu.crc & 0x7FF);
334 frayREG->WRHS2_UN.WRHS2_UL = wrhs2;
336 frayREG->WRHS3_UN.WRHS3_UL = (Fr_LPdu.dp & 0x7FF);
338 Fr_transmit_tx_LPdu(&Fr_LSdu);
342 * Fill FIFO filter rejection configuration and configure the buffer.
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
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)
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;
365 frayREG->FRF_UN.FRF_ST.ch_B2 = 3;
366 Fr_config_buffer(buf_num, mode, cyc_filter, frame_id, payload, data_pointer);
370 * Load data to message buffer. Data must be copied into WRDS register before this function is called.
372 * @param[in] buf_num Number of buffer
373 * @param[in] len Number of words to be loaded from data to buffer
375 static void Fr_buffer_transmit_data(uint32_t buf_num)
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);
389 /** @fn wait_for_POC_ready(void)
390 * @brief Wait until POC is not busy
392 inline void Fr_wait_for_POC_ready()
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) ;
399 /** @fn clear_msg_ram(void)
400 * @brief Clears FRAY message RAMs
402 * Send command to POC to set all bits of message RAM to 0.
403 * @return SUCCESS or FAILURE when command was not accepted
405 static int Fr_clear_msg_RAM()
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)
411 Fr_wait_for_POC_ready();
417 * @brief Switch POC to config state from any other state
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
423 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
425 static Std_ReturnType Fr_POC_go_to_config()
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)
432 // Wait for PBSY bit to clear - POC not busy
433 Fr_wait_for_POC_ready();
438 * @brief Switch POC to ready state from config state
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
444 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
446 static Std_ReturnType Fr_POC_go_to_ready_from_config()
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) {
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;
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;
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;
465 else if (frayREG->SUCC1_UN.SUCC1_ST.ccha_B1) {
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;
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;
476 else if (frayREG->SUCC1_UN.SUCC1_ST.cchb_B1) {
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;
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;
486 else frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
488 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
491 while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01)
492 ; // Waiting for READY state
497 * @brief Switch POC to ready state from startup state
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
503 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
505 static Std_ReturnType Fr_POC_go_to_ready_from_startup()
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)
511 while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01) ; // Wait until POC is not in ready state
512 Fr_wait_for_POC_ready();
517 * @brief Switch POC to startup state from ready state
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
523 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
525 static Std_ReturnType Fr_POC_go_to_startup()
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)
531 Fr_wait_for_POC_ready();
536 * @brief Copy cluster config parameters into FlexRay configuration registers.
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.
542 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
544 void Fr_config_cluster_parameters(const Fr_TMS570LS_ClusterConfigType *clusterConfigPtr)
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;
573 Std_ReturnType Fr_verify_cluster_parameters(const Fr_TMS570LS_ClusterConfigType *clusterConfigPtr)
575 boolean_t error = FALSE;
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;
605 #define __notInRange(val, min, max) (((val) < (min)) || ((val) > (max)))
608 * @brief Check cluster configuration parameters.
610 * This function checks values of the cluster configuration parameters,
611 * if they are in ranges noted in FlexRay specification.
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.
619 Std_ReturnType Fr_check_cluster_parameters(const Fr_TMS570LS_ClusterConfigType *clusterConfigPtr, uint32_t *errCode)
621 *errCode = ERR_PARAM_NO_ERROR;
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;
654 return (*errCode == 0) ? E_OK : E_NOT_OK;
658 * @brief Copy node config parameters into FlexRay configuration registers.
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.
664 * @param [in] nodeConfigPtr Address of structure with node configuration parameters
666 void Fr_config_node_parameters(const Fr_TMS570LS_NodeConfigType *nodeConfigPtr)
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;
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;
679 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 0;
680 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 1;
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;
711 Std_ReturnType Fr_verify_node_parameters(const Fr_TMS570LS_NodeConfigType *nodeConfigPtr)
713 boolean_t error = FALSE;
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;
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;
726 error |= frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 == 0;
727 error |= frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 == 1;
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;
760 * @brief Check node configuration parameters.
762 * This function checks values of the node configuration parameters,
763 * if they are in ranges noted in FlexRay specification.
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.
771 Std_ReturnType Fr_check_node_parameters(const Fr_TMS570LS_NodeConfigType *nodeConfigPtr, uint32_t *errCode)
773 *errCode = ERR_PARAM_NO_ERROR;
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;
804 return (*errCode == 0) ? E_OK : E_NOT_OK;
808 * @brief Check Configuration parameters for all buffers
810 * This function checks configuration parameters.
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
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
823 * The sum of all configured payloads must be <= 8KB.
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.
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)
838 uint32_t payloadTotal = 0;
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;
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;
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;
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;
885 if (payloadTotal > 8192/2) *errCode |= ERR_PARAM_BUF_TOTAL_PAYLOAD_HIGH;
887 return (*errCode == 0) ? E_OK : E_NOT_OK;
891 * @brief Compute and set message RAM config parameters into FlexRay configuration registers.
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.
897 * @param [in] msgRAMConfigPtr Address of structure with message RAM configuration parameters
898 * @return Number of configured buffers
900 uint8_t Fr_config_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig *msgRAMConfigPtr)
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)
905 if (msgRAMConfigPtr->dynSegmentBufferCount == 0)
906 frayREG->MRC_UN.MRC_ST.fdb_B8 = 0x80;
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)
912 if (msgRAMConfigPtr->fifoBufferCount == 0)
913 frayREG->MRC_UN.MRC_ST.ffb_B8 = 0x80;
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;
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;
927 frayREG->MRC_UN.MRC_ST.sec_B2 = 3;
929 /* Sync frame payload multiplex setting */
930 if (msgRAMConfigPtr->syncFramePayloadMultiplexEnabled == TRUE)
931 frayREG->MRC_UN.MRC_ST.splm_B1 = 1;
933 frayREG->MRC_UN.MRC_ST.splm_B1 = 0;
935 return msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount;
938 Std_ReturnType Fr_verify_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig *msgRAMConfigPtr)
940 boolean_t error = FALSE;
942 if (msgRAMConfigPtr->dynSegmentBufferCount == 0)
943 error |= frayREG->MRC_UN.MRC_ST.fdb_B8 == 0x80;
945 error |= frayREG->MRC_UN.MRC_ST.fdb_B8 == msgRAMConfigPtr->statSegmentBufferCount;
947 if (msgRAMConfigPtr->fifoBufferCount == 0)
948 error |= frayREG->MRC_UN.MRC_ST.ffb_B8 == 0x80;
950 error |= frayREG->MRC_UN.MRC_ST.ffb_B8 == msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount;
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;
960 error |= frayREG->MRC_UN.MRC_ST.sec_B2 == 3;
962 if (msgRAMConfigPtr->syncFramePayloadMultiplexEnabled == TRUE)
963 error |= frayREG->MRC_UN.MRC_ST.splm_B1 == 1;
965 error |= frayREG->MRC_UN.MRC_ST.splm_B1 == 0;
967 return (error == FALSE) ? E_OK : E_NOT_OK;
971 #define __notInRange(val, min, max) (((val) < (min)) || ((val) > (max)))
974 * @brief Check message RAM configuration parameters.
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.
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.
986 Std_ReturnType Fr_check_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig *msgRAMConfigPtr, uint32_t *errCode)
988 *errCode = ERR_PARAM_NO_ERROR;
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;
997 return (*errCode == 0) ? E_OK : E_NOT_OK;
1001 * @brief Master function to prepare buffers for communication
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.
1007 Std_ReturnType Fr_PrepareLPdu_master(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx)
1010 const Fr_TMS570LS_BufferConfigType *buffer_cfg_ptr;
1012 #ifdef DET_ACTIVATED
1013 if (Fr_CtrlIdx != 0)
1015 if (Fr_DrvState < FR_ST_DRV_INITIALIZED)
1017 if (Fr_LPduIdx > FR_MAX_BUFFERS_CNT)
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]);
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
1035 * Offset has to be divided by two each time because payload is in 2B words and msgRAM addresses are in 4B words.
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;
1044 void Fr_Init(const Fr_ConfigType *Fr_ConfigPtr)
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;
1051 #ifdef DET_ACTIVATED
1052 if (Fr_ConfigPtr == NULL)
1054 if (Fr_DrvState != FR_ST_DRV_NOT_INITIALIZED)
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
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;
1126 /* Store whole configuration address
1127 * This structured representation is used by other function in API.
1129 Fr_Config = Fr_ConfigPtr;
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;
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;
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;
1170 #ifdef DET_ACTIVATED
1171 Fr_DrvState = FR_ST_DRV_INITIALIZED;
1175 Std_ReturnType Fr_ControllerInit(uint8_t Fr_CtrlIdx)
1177 uint32_t errCode = ERR_PARAM_NO_ERROR;
1179 uint8_t totalBufferCount;
1181 #ifdef DET_ACTIVATED
1182 if (Fr_DrvState < FR_ST_DRV_INITIALIZED)
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)
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;
1215 /* Clear message RAM */
1216 if (Fr_clear_msg_RAM() == FAILURE)
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);
1223 // Wait until CLEAR_RAMS command is complete
1224 while (frayREG->MHDS_UN.MHDS_ST.cram_B1 == 1)
1227 totalBufferCount = Fr_config_msgRAM_parameters(Fr_Config->msgRAMConfig);
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) {
1241 Fr_MsgRAMDataStartAddress = totalBufferCount*4U; // First data section after headers sections in message RAM.
1242 Fr_MsgRAMDataOffset = Fr_MsgRAMDataStartAddress;
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;
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;
1258 if (passed == FALSE)
1261 /* Switch POC to ready state */
1262 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK)
1264 /* Enable all interrupts */
1265 frayREG->EIES_UN.EIES_UL = 0xFFFFFFFF;
1266 frayREG->SIES_UN.SIES_UL = 0xFFFFFFFF;
1268 #ifdef DET_ACTIVATED
1269 Fr_DrvState = FR_ST_CTRL_INITIALIZED;
1274 Std_ReturnType Fr_StartCommunication(uint8_t Fr_CtrlIdx)
1277 uint32_t state_value;
1280 #ifdef DET_ACTIVATED
1281 if (Fr_CtrlIdx != 0)
1283 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED)
1285 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY)
1289 // Node is configured as coldstart
1290 if (Fr_Config->nodeConfiguration->pKeySlotUsedForStartup == TRUE)
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
1298 do { // Wait until NORMAL_ACTIVE state or timeout
1299 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
1301 } while ((state_value != FR_POCS_NORMAL_ACTIVE) && (counter < FR_FCS_LISTEN_TIMEOUT));
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
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
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;
1318 // The node is not coldstarter, try to integrate into an existing network.
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
1323 // Wait until NORMAL_ACTIVE
1325 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
1326 } while (state_value != FR_POCS_NORMAL_ACTIVE);
1332 Std_ReturnType Fr_AllowColdstart(uint8_t Fr_CtrlIdx)
1334 #ifdef DET_ACTIVATED
1335 if (Fr_CtrlIdx != 0)
1337 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
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)
1345 Fr_wait_for_POC_ready();
1349 Std_ReturnType Fr_AllSlots(uint8_t Fr_CtrlIdx)
1351 #ifdef DET_ACTIVATED
1352 if (Fr_CtrlIdx != 0)
1354 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1356 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_ACTIVE && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_PASSIVE)
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)
1364 Fr_wait_for_POC_ready();
1368 Std_ReturnType Fr_HaltCommunication(uint8_t Fr_CtrlIdx)
1370 #ifdef DET_ACTIVATED
1371 if (Fr_CtrlIdx != 0)
1373 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1375 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_ACTIVE && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_PASSIVE)
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)
1383 Fr_wait_for_POC_ready();
1387 Std_ReturnType Fr_AbortCommunication(uint8_t Fr_CtrlIdx)
1389 #ifdef DET_ACTIVATED
1390 if (Fr_CtrlIdx != 0)
1392 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
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)
1400 Fr_wait_for_POC_ready();
1404 Std_ReturnType Fr_SendWUP(uint8_t Fr_CtrlIdx)
1406 #ifdef DET_ACTIVATED
1407 if (Fr_CtrlIdx != 0)
1409 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1411 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY)
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)
1419 Fr_wait_for_POC_ready();
1423 Std_ReturnType Fr_SetWakeupChannel(uint8_t Fr_CtrlIdx, Fr_ChannelType Fr_ChnlIdx)
1425 Std_ReturnType retVal = E_OK;
1427 #ifdef DET_ACTIVATED
1428 if (Fr_CtrlIdx != 0)
1430 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1432 if (Fr_ChnlIdx == FR_CHANNEL_AB)
1434 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY)
1438 if (Fr_POC_go_to_config() == E_NOT_OK)
1440 if (Fr_ChnlIdx == FR_CHANNEL_A) {
1441 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 0;
1444 else if (Fr_ChnlIdx == FR_CHANNEL_B) {
1445 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 1;
1450 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK)
1456 Std_ReturnType Fr_GetPOCStatus(uint8_t Fr_CtrlIdx, Fr_POCStatusType *Fr_POCStatusPtr)
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
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
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
1474 #ifdef DET_ACTIVATED
1475 if (Fr_CtrlIdx != 0)
1477 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1479 if (Fr_POCStatusPtr == NULL)
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 */
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];
1505 Fr_POCStatusPtr->State = FR_POCSTATE_INVALID;
1507 /* Wakeup substate detection */
1508 Fr_POCStatusPtr->WakeupStatus = wup_state[frayREG->CCSV_UN.CCSV_ST.wsv_B3];
1513 Std_ReturnType Fr_TransmitTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, const uint8_t *Fr_LSduPtr, uint8_t Fr_LSduLength)
1515 uint32_t word, buffer, index, mode;
1516 uint8_t actualPayload = (Fr_LSduLength+1)/2;
1517 Fr_TMS570LS_BufferConfigType tmp_buffer;
1519 #ifdef DET_ACTIVATED
1520 if (Fr_CtrlIdx != 0)
1522 if (Fr_LPduIdx > FR_MAX_BUFFERS_CNT)
1524 if (Fr_LSduPtr == NULL)
1526 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
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]);
1547 for (word = 0; word < (Fr_LSduLength+3)/4; word++) {
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;
1555 Fr_buffer_transmit_data(Fr_LPduIdx);
1562 /* Fr_LPduIdx should be buffer index, not slot number */
1563 Std_ReturnType Fr_CancelTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx)
1566 const Fr_TMS570LS_BufferConfigType *buffer_cfg_ptr;
1568 #ifdef DET_ACTIVATED
1569 if (Fr_CtrlIdx != 0)
1571 if (Fr_LPduIdx > FR_MAX_BUFFERS_CNT)
1573 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1575 if (Fr_Config->msgRAMConfig->secureBuffers != FR_SB_RECONFIG_ENABLED)
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.
1588 * Write the same configuration into buffer headers with TXREQ disabled.
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]);
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)
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;
1609 boolean_t bufferFound = FALSE;
1610 const Fr_TMS570LS_BufferConfigType *buffer_cfg_ptr;
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
1614 #ifdef DET_ACTIVATED
1615 if (Fr_CtrlIdx != 0)
1617 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1619 if (Fr_LPduIdx > FR_MAX_BUFFERS_CNT)
1621 if (Fr_LSduPtr == NULL)
1623 if (Fr_LPduStatusPtr == NULL)
1625 if (Fr_LSduLengthPtr == NULL)
1629 /* Find the index of the buffer in configuration data array */
1630 *Fr_LSduLengthPtr = 0;
1631 *Fr_LPduStatusPtr = FR_NOT_RECEIVED;
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.
1649 if (Fr_LPduIdx < frayREG->MRC_UN.MRC_ST.ffb_B8) {
1650 if (Fr_BuffersConfigured[Fr_LPduIdx] == TRUE) { // Buffer was configured already
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;
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)) ) {
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;
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.
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;
1683 Fr_LSduPtr[byte] = (byte < *Fr_LSduLengthPtr) ? (frayREG->RDDS[word] & 0xFF00) >> 8 : 0;
1685 Fr_LSduPtr[byte] = (byte < *Fr_LSduLengthPtr) ? (frayREG->RDDS[word] & 0xFF0000) >> 16 : 0;
1687 Fr_LSduPtr[byte] = (byte < *Fr_LSduLengthPtr) ? (frayREG->RDDS[word] & 0xFF000000) >> 24 : 0;
1691 return (bufferFound == TRUE) ? E_OK : E_NOT_OK;
1692 #undef fifo_not_empty
1695 Std_ReturnType Fr_CheckTxLPduStatus(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, Fr_TxLPduStatusType *Fr_TxLPduStatusPtr)
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};
1699 #ifdef DET_ACTIVATED
1700 if (Fr_CtrlIdx != 0)
1702 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1704 if (Fr_LPduIdx > FR_MAX_BUFFERS_CNT)
1706 if (Fr_TxLPduStatusPtr == NULL)
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;
1716 *Fr_TxLPduStatusPtr = FR_TRANSMITTED;
1724 Std_ReturnType Fr_PrepareLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx)
1726 if (FrBufferReconfig == TRUE)
1727 return Fr_PrepareLPdu_master(Fr_CtrlIdx, Fr_LPduIdx);
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)
1734 if (FrBufferReconfig == FALSE)
1737 int lowest_index = 0;
1738 uint8_t highest_index = frayREG->MRC_UN.MRC_ST.ffb_B8;
1740 Fr_TMS570LS_BufferConfigType buffer_cfg;
1742 #ifdef DET_ACTIVATED
1743 boolean_t reconfigured = FALSE;
1746 if (Fr_CtrlIdx != 0)
1748 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1750 if (Fr_CycleOffset >= Fr_CycleRepetition)
1752 for (pow2 = 1, is_pow2 = FALSE; pow2 < 128; pow2 *= 2) {
1753 if (Fr_CycleRepetition == pow2) {
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;
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;
1796 #ifdef DET_ACTIVATED
1797 if (reconfigured == FALSE)
1798 return E_NOT_OK | ERR_PARAM_NO_BUFFER_FOUND;
1803 Std_ReturnType Fr_DisableLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx)
1805 if (FrBufferReconfig == FALSE)
1808 uint8_t bufferIndexLimit;
1811 #ifdef DET_ACTIVATED
1812 if (Fr_CtrlIdx != 0)
1814 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1816 if (Fr_LPduIdx > FR_MAX_BUFFERS_CNT)
1818 if (Fr_Config->msgRAMConfig->secureBuffers != FR_SB_RECONFIG_ENABLED)
1822 /* Determine reconfigurable buffers from the data in MRC.SET bits */
1823 switch (frayREG->MRC_UN.MRC_ST.sec_B2) {
1825 bufferIndexLimit = frayREG->MRC_UN.MRC_ST.ffb_B8;
1828 bufferIndexLimit = frayREG->MRC_UN.MRC_ST.fdb_B8;
1831 return E_OK; // No reconfiguration enabled
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
1840 if (Fr_LPduIdx < lowest_index)
1842 if (Fr_LPduIdx < bufferIndexLimit) { // Buffer is reconfigurable, reset its configuration registers.
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]);
1857 Std_ReturnType Fr_GetGlobalTime(uint8_t Fr_CtrlIdx, uint8_t *Fr_CyclePtr, uint16_t *Fr_MacroTickPtr)
1859 #ifdef DET_ACTIVATED
1860 if (Fr_CtrlIdx != 0)
1862 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1864 if (Fr_CyclePtr == NULL)
1866 if (Fr_MacroTickPtr == NULL)
1868 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_ACTIVE && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_PASSIVE)
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);
1878 static inline uint32_t swap32(uint32_t x)
1880 return (x & 0x000000ff) << 24 |
1881 (x & 0x0000ff00) << 8 |
1882 (x & 0x00ff0000) >> 8 |
1883 (x & 0xff000000) >> 24;
1886 Std_ReturnType Fr_GetNmVector(uint8_t Fr_CtrlIdx, uint8_t *Fr_NmVectorPtr)
1888 #ifdef DET_ACTIVATED
1889 if (Fr_CtrlIdx != 0)
1891 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1893 if (Fr_NmVectorPtr == NULL)
1895 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_ACTIVE && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_PASSIVE)
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);
1905 Std_ReturnType Fr_GetNumOfStartupFrames(uint8_t Fr_CtrlIdx, uint8_t *Fr_NumOfStartupFramesPtr)
1907 /* TODO: Implement - can not find this information in the datasheet */
1911 Std_ReturnType Fr_GetChannelStatus(uint8_t Fr_CtrlIdx, uint16_t *Fr_ChannelAStatusPtr, uint16_t *Fr_ChannelBStatusPtr)
1913 #ifdef DET_ACTIVATED
1914 if (Fr_CtrlIdx != 0)
1916 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1918 if (Fr_ChannelAStatusPtr == NULL)
1920 if (Fr_ChannelBStatusPtr == NULL)
1922 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_ACTIVE && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_PASSIVE)
1926 *Fr_ChannelAStatusPtr = 0;
1927 *Fr_ChannelBStatusPtr = 0;
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;
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;
1956 Std_ReturnType Fr_GetClockCorrection(uint8_t Fr_CtrlIdx, int16_t *Fr_RateCorrectionPtr, int32_t *Fr_OffsetCorrectionPtr)
1958 #ifdef DET_ACTIVATED
1959 if (Fr_CtrlIdx != 0)
1961 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1963 if (Fr_RateCorrectionPtr == NULL)
1965 if (Fr_OffsetCorrectionPtr == NULL)
1969 *Fr_RateCorrectionPtr = frayREG->RCV_UN.RCV_ST.rcv_B12;
1970 *Fr_OffsetCorrectionPtr = frayREG->OCV_UN.OCV_ST.ocv_B14;
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)
1981 #ifdef DET_ACTIVATED
1982 if (Fr_CtrlIdx != 0)
1984 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
1986 if (Fr_ChannelAEvenListPtr == NULL)
1988 if (Fr_ChannelBEvenListPtr == NULL)
1990 if (Fr_ChannelAOddListPtr == NULL)
1992 if (Fr_ChannelBOddListPtr == NULL)
1997 if (Fr_ListSize > FR_MAX_SYNC_FRAME_LIST_SIZE) // Limit list size to 15
1998 Fr_ListSize = FR_MAX_SYNC_FRAME_LIST_SIZE;
2000 for (i = 0; i < Fr_ListSize; i++) {
2001 esid = frayREG->ESID_UL[i];
2002 osid = frayREG->OSID_UL[i];
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;
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;
2020 Std_ReturnType Fr_GetWakeupRxStatus(uint8_t Fr_CtrlIdx, uint8_t *Fr_WakeupRxStatusPtr)
2022 #ifdef DET_ACTIVATED
2023 if (Fr_CtrlIdx != 0)
2025 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2027 if (Fr_WakeupRxStatusPtr == NULL)
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;
2036 frayREG->SIR_UN.SIR_ST.wupa_B1 = 1;
2037 frayREG->SIR_UN.SIR_ST.wupb_B1 = 1;
2041 Std_ReturnType Fr_SetAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, uint8_t Fr_Cycle, uint16_t Fr_Offset)
2043 #ifdef DET_ACTIVATED
2044 if (Fr_CtrlIdx != 0)
2046 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2048 if (Fr_AbsTimerIdx > 1)
2050 if (Fr_Offset > Fr_Config->clusterConfiguration->gMacroPerCycle)
2052 if (Fr_Cycle & 0x80)
2054 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_ACTIVE && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_NORMAL_PASSIVE)
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;
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;
2078 Std_ReturnType Fr_CancelAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx)
2080 #ifdef DET_ACTIVATED
2081 if (Fr_CtrlIdx != 0)
2083 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2085 if (Fr_AbsTimerIdx > 1)
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;
2098 Std_ReturnType Fr_EnableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx)
2100 #ifdef DET_ACTIVATED
2101 if (Fr_CtrlIdx != 0)
2103 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2105 if (Fr_AbsTimerIdx > 1)
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;
2119 Std_ReturnType Fr_AckAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx)
2121 #ifdef DET_ACTIVATED
2122 if (Fr_CtrlIdx != 0)
2124 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2126 if (Fr_AbsTimerIdx > 1)
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;
2139 Std_ReturnType Fr_DisableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx)
2141 #ifdef DET_ACTIVATED
2142 if (Fr_CtrlIdx != 0)
2144 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2146 if (Fr_AbsTimerIdx > 1)
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;
2159 Std_ReturnType Fr_GetAbsoluteTimerIRQStatus(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, boolean_t *Fr_IRQStatusPtr)
2161 #ifdef DET_ACTIVATED
2162 if (Fr_CtrlIdx != 0)
2164 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2166 if (Fr_AbsTimerIdx > 1)
2168 if (Fr_IRQStatusPtr == NULL)
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;
2181 void Fr_GetVersionInfo(Std_VersionInfoType *VersioninfoPtr)
2183 #ifdef DET_ACTIVATED
2184 if (VersioninfoPtr == NULL)
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;
2195 Std_ReturnType Fr_ReadCCConfig( uint8_t Fr_CtrlIdx, uint8_t Fr_ConfigParamIdx, uint32_t *Fr_ConfigParamValuePtr)
2198 #ifdef DET_ACTIVATED
2199 if (Fr_CtrlIdx != 0)
2201 if (Fr_ConfigParamIdx >= FR_CIDX_CNT)
2203 if (Fr_ConfigParamValuePtr == NULL)
2205 if (Fr_DrvState < FR_ST_CTRL_INITIALIZED)
2210 *Fr_ConfigParamValuePtr = Fr_ConfigParPtrs[Fr_ConfigParamIdx];
2214 int Fr_spi_transfer(uint8_t port)
2216 uint32_t commands[2];
2217 const struct port_desc *pd;
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);
2225 fray_spi_resp[port] = pd->set(pd, commands, sizeof(commands));
2229 int Fr_spi_response(uint8_t port)
2231 if (port > FRAY_NUM_PORTS) return -1;
2232 return fray_spi_resp[port];
2235 int Fr_spi_get_cmd(uint8_t port)
2237 if (port > FRAY_NUM_PORTS) return -1;
2238 return fray_spi_cmd;