8 #include "drv/fr_tms570.h"
9 #include "sys/ti_drv_fray.h"
11 #include "hal/port_def.h"
13 static Std_VersionInfoType Fr_versionInfo = {
14 .vendorID = 0x00000001,
15 .moduleID = 0x00000002,
16 .sw_major_version = 0,
17 .sw_minor_version = 1,
21 /** Prepared spi command */
22 static uint32_t fray_spi_cmd = FRAY_SPICMD_INIT_VAL;
23 /** Shadow variable used during command sending */
24 static uint32_t fray_spi_cmd_sh;
25 /** Array of responses for each fray driver */
26 static uint32_t fray_spi_resp[FRAY_NUM_PORTS];
27 /** Array of port names to be easily accessible by indexing */
28 static const char* fray_port_names[FRAY_NUM_PORTS] = { PORT_NAME_FRAY1, PORT_NAME_FRAY2 };
29 /** Array of integers, where FlexRay cluster and node configuration
30 * parameters are stored to be accessible by indexes defined in Fr_GeneralTypes.h.
32 static uint32_t Fr_ConfigParPtrs[FR_CIDX_CNT];
34 * Address of the unified structure with complete configuration of
35 * the FlexRay node (cluster, node, message RAM and buffer configuration)
37 static const Fr_ConfigType* Fr_Config;
38 /** Array of address of configuration data to each buffer. */
39 static Fr_TMS570LS_BufferConfigType* Fr_BuffersPtrs[FR_MAX_BUFFERS_CNT];
40 /** Array of flags to determine if the buffer was or was not configured. */
41 static boolean_t Fr_BuffersConfigured[FR_MAX_BUFFERS_CNT];
42 /** Array of computed data pointers addresses for each buffer. */
43 static int Fr_MsgRAMDataPtrs[FR_MAX_BUFFERS_CNT];
45 * Address of the next free position in message RAM, which can be assigned
46 * to configured buffer. Addresses 32b words.
48 static uint32_t Fr_MsgRAMDataOffset;
50 * Address of the first free position in message RAM, which can be assigned
51 * to the first configured buffer. Addresses 32b words.
53 static uint32_t Fr_MsgRAMDataStartAddress;
56 * Development error detection.
57 * Comment this line to disable error detection and make function processing
58 * faster, but more dangerous.
66 * A variable for driver state monitoring. The state value is used in several
67 * functions to determine if they are called in right order.
69 static Fr_TMS570LS_DriverState Fr_DrvState = FR_ST_DRV_NOT_INITIALIZED;
73 * Compute CRC for message RAM header data
75 * @param[in] Fr_LPduPtr Pointer to header data
78 static int Fr_header_crc_calc(const wrhs *Fr_LPduPtr) {
84 unsigned long CrcPoly = 0x385;
85 unsigned long CrcReg_X = CrcInit;
86 unsigned long header_temp, reg_temp;
88 header = ((Fr_LPduPtr->sync & 0x1) << 19) | ((Fr_LPduPtr->sfi & 0x1) << 18);
89 header |= ((Fr_LPduPtr->fid & 0x7FF) << 7) | (Fr_LPduPtr->pl & 0x7F);
97 header_temp = header & 0x80000000;
98 reg_temp = CrcReg_X & 0x80000000;
100 if(header_temp ^ reg_temp){ // Step 1
106 CrcReg_X <<= 1; // Step 2
109 CrcReg_X ^= CrcPoly; // Step 3
119 * Retrieve data and header from message buffer into output buffer.
121 * Upper software layers have to read the header and data from RDDS and RDHS registers.
122 * @param[in] buf_num Number of buffer
124 static void Fr_buffer_receive_data_header(uint32_t buf_num) {
127 read_buffer.obrs=buf_num; // output buffer number
128 read_buffer.rdss=1; // read data section
129 read_buffer.rhss=1; // read header section
131 // ensure no transfer in progress on shadow registers
132 while (((frayREG->OBCR_UN.OBCR_UL) & 0x00008000) != 0);
133 frayREG->OBCM_UN.OBCM_UL=(((read_buffer.rdss & 0x1) << 1) | (read_buffer.rhss & 0x1));
134 frayREG->OBCR_UN.OBCR_UL=((1 << 9) | (read_buffer.obrs & 0x3F)); //req=1, view=0
135 // wait for completion on shadow registers
136 while (((frayREG->OBCR_UN.OBCR_UL) & 0x00008000) != 0);
138 frayREG->OBCM_UN.OBCM_UL=(((read_buffer.rdss & 0x1) << 1) | (read_buffer.rhss & 0x1));
139 frayREG->OBCR_UN.OBCR_UL=((1 << 8) | (read_buffer.obrs & 0x3F)); //req=0, view=1
144 * Transfer data to the message RAM using the input buffer
146 * @param[in] Fr_LSduPtr Pointer to data structure with input buffer settings
148 inline void Fr_transmit_tx_LPdu(const bc *Fr_LSduPtr) {
149 // ensure nothing is pending
150 while ((frayREG->IBCR_UN.IBCR_UL & 0x0008000) != 0);
151 frayREG->IBCM_UN.IBCM_UL=((Fr_LSduPtr->stxrh & 0x1) << 2) | ((Fr_LSduPtr->ldsh & 0x1) << 1) | (Fr_LSduPtr->lhsh & 0x1);
152 frayREG->IBCR_UN.IBCR_UL=(Fr_LSduPtr->ibrh & 0x3F);
153 // optimization possible for future by not gating like below
154 // wait for completion on host registers
155 while ((Fr_LSduPtr->ibsyh != 0) && ((frayREG->IBCR_UN.IBCR_UL & 0x00008000) != 0));
156 // wait for completion on shadow registers
157 while ((Fr_LSduPtr->ibsys != 0) && ((frayREG->IBCR_UN.IBCR_UL & 0x80000000) != 0));
161 * Fill the buffer configuration data structure with given data and transfer it to the message RAM header using the input buffer.
163 * @param[in] buf_num number of buffer to be configured (0-128)
164 * @param[in] mode Flag array for buffer configuration. Flags are defined in header file with prefix FRAY_BUF_
165 * @param[in] cyc_filter Setting for cycle filter. 0 - disabled
166 * @param[in] frame_id Id of the frame to be associated with the buffer
167 * @param[in] payload Maximum data size in half-word
168 * @param[in] data_pointer Address of the first word of data in buffer
170 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) {
176 Fr_LPdu.mbi = (mode&FRAY_BUF_MBI_EN) ? 1 : 0; // message buffer interrupt
177 Fr_LPdu.txm = (mode&FRAY_BUF_TX_MODE_CONTINUOUS) ? 0 : 1; // transmission mode(0=continuous mode, 1=single mode)
178 Fr_LPdu.ppit = (mode&FRAY_BUF_NM_EN) ? 1 : 0; // network management Enable
179 Fr_LPdu.cfg = (mode&FRAY_BUF_TX) ? 1 : 0; // message buffer configuration bit (0=RX, 1 = TX)
180 Fr_LPdu.chb = (mode&FRAY_BUF_CHB_EN) ? 1 : 0; // Ch B
181 Fr_LPdu.cha = (mode&FRAY_BUF_CHA_EN) ? 1 : 0; // Ch A
182 Fr_LPdu.cyc = cyc_filter; // Cycle Filtering Code (no cycle filtering)
183 Fr_LPdu.fid = frame_id; // Frame ID
185 // Write Header Section 2 (WRHS2)
186 Fr_LPdu.pl = payload; // Payload Length
188 // Write Header Section 3 (WRHS3)
189 Fr_LPdu.dp = data_pointer; // Pointer to start of data in message RAM
191 Fr_LPdu.sfi = (mode&FRAY_BUF_SFI_EN) ? 1 : 0; // startup frame indicator
192 Fr_LPdu.sync = (mode&FRAY_BUF_SYNC_EN) ? 1 : 0; // sync frame indicator
194 // Write Header Section 2 (WRHS2)
195 Fr_LPdu.crc = (mode&FRAY_BUF_TX) ? Fr_header_crc_calc(&Fr_LPdu) : 0;
197 // Input buffer configuration
198 Fr_LSdu.ibrh = buf_num; // input buffer number
199 Fr_LSdu.ibsyh = 1; // check for input buffer busy host
200 Fr_LSdu.ibsys = 1; // check for input buffer busy shadow
202 Fr_LSdu.stxrh= (mode&FRAY_BUF_TXREQ_EN) ? 1 : 0; // set transmission request
203 Fr_LSdu.ldsh = 0; // load data section
204 Fr_LSdu.lhsh = 1; // load header section
205 Fr_LSdu.obrs = 0; // output buffer number
206 Fr_LSdu.rdss = 0; // read data section
207 Fr_LSdu.rhss = 0; // read header section
209 wrhs1 = ((Fr_LPdu.mbi) & 0x1) <<29;
210 wrhs1 |= (Fr_LPdu.txm & 0x1) << 28;
211 wrhs1 |= (Fr_LPdu.ppit & 0x1) << 27;
212 wrhs1 |= (Fr_LPdu.cfg & 0x1) << 26;
213 wrhs1 |= (Fr_LPdu.chb & 0x1) << 25;
214 wrhs1 |= (Fr_LPdu.cha & 0x1) << 24;
215 wrhs1 |= (Fr_LPdu.cyc & 0x7F) << 16;
216 wrhs1 |= (Fr_LPdu.fid & 0x7FF);
217 frayREG->WRHS1_UN.WRHS1_UL = wrhs1;
219 wrhs2 = ((Fr_LPdu.pl & 0x7F) << 16) | (Fr_LPdu.crc & 0x7FF);
220 frayREG->WRHS2_UN.WRHS2_UL = wrhs2;
222 frayREG->WRHS3_UN.WRHS3_UL = (Fr_LPdu.dp & 0x7FF);
224 Fr_transmit_tx_LPdu(&Fr_LSdu);
228 * Fill FIFO filter rejection configuration and configure the buffer.
230 * @param[in] buf_num number of buffer to be configured (0-128)
231 * @param[in] mode Flag array for buffer configuration. Flags are defined in header file with prefix FRAY_BUF_
232 * @param[in] cyc_filter Setting for cycle filter. 0 - disabled
233 * @param[in] frame_id Id of the frame to be associated with the buffer
234 * @param[in] payload Maximum data size in half-word
235 * @param[in] data_pointer Address of the first word of data in buffer
237 static void Fr_configure_fifo_buffer(uint32_t buf_num, uint16_t mode, uint32_t cyc_filter, uint32_t frame_id, uint32_t payload, uint32_t data_pointer) {
238 frayREG->FRF_UN.FRF_ST.rnf = (mode&FRAY_BUF_REJECT_NULL_FRAMES) ? 1 : 0;
239 frayREG->FRF_UN.FRF_ST.rss = (mode&FRAY_BUF_REJECT_STATIC_SEGMENT) ? 1 : 0;
240 frayREG->FRF_UN.FRF_ST.fid_B11 = frame_id;
241 frayREG->FRFM_UN.FRFM_ST.mfid_B11 = 0x0;
242 frayREG->FRF_UN.FRF_ST.cyf_B7 = cyc_filter;
243 if (mode&FRAY_BUF_CHB_EN && mode&FRAY_BUF_CHA_EN) {
244 frayREG->FRF_UN.FRF_ST.ch_B2 = 0;
246 else if (mode&FRAY_BUF_CHA_EN) {
247 frayREG->FRF_UN.FRF_ST.ch_B2 = 3;
250 frayREG->FRF_UN.FRF_ST.ch_B2 = 2;
253 Fr_config_buffer(buf_num, mode, cyc_filter, frame_id, payload, data_pointer);
257 * Load data to message buffer. Data must be copied into WRDS register before this function is called.
259 * @param[in] buf_num Number of buffer
260 * @param[in] len Number of words to be loaded from data to buffer
262 static void Fr_buffer_transmit_data(uint32_t buf_num) {
265 write_buffer.ibrh = buf_num; // input buffer number
266 write_buffer.stxrh= 1; // set transmission request
267 write_buffer.ldsh = 1; // load data section
268 write_buffer.lhsh = 0; // load header section
269 write_buffer.ibsys = 0; // check for input buffer busy shadow
270 write_buffer.ibsyh = 1; // check for input buffer busy host
271 Fr_transmit_tx_LPdu(&write_buffer);
275 /** @fn wait_for_POC_ready(void)
276 * @brief Wait until POC is not busy
278 inline void Fr_wait_for_POC_ready() {
279 // Wait for PBSY bit to clear - POC not busy.
280 // 1: Signals that the POC is busy and cannot accept a command from the host. CMD(3-0) is locked against write accesses.
281 while(((frayREG->SUCC1_UN.SUCC1_UL) & 0x00000080) != 0);
284 /** @fn clear_msg_ram(void)
285 * @brief Clears FRAY message RAMs
287 * Send command to POC to set all bits of message RAM to 0.
288 * @return SUCCESS or FAILURE when command was not accepted
290 static int Fr_clear_msg_RAM() {
291 Fr_wait_for_POC_ready();
292 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_CLEAR_RAMS;
293 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted) {
296 Fr_wait_for_POC_ready();
302 * @brief Switch POC to config state from any other state
304 * After command to switch into config state is passed into CHI,
305 * the response is checked and if POC has reacted on the command,
306 * the function is waiting until POC is ready
308 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
310 static Std_ReturnType Fr_POC_go_to_config() {
311 // write SUCC1 configuration
312 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_CONFIG;
313 // Check if POC has accepted last command
314 if ((frayREG->SUCC1_UN.SUCC1_UL & 0xF) == 0x0)
316 // Wait for PBSY bit to clear - POC not busy
317 Fr_wait_for_POC_ready();
322 * @brief Switch POC to ready state from config state
324 * After command to switch into ready state is passed into CHI,
325 * the response is checked and if POC has reacted on the command,
326 * the function is waiting until POC is ready
328 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
330 static Std_ReturnType Fr_POC_go_to_ready_from_config() {
331 Fr_wait_for_POC_ready();
332 // For CHA and CHB network
333 if (frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 && frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
335 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
336 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
337 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
339 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
340 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
341 frayREG->SUCC1_UN.SUCC1_ST.mtsa_B1 = 1U;
343 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
344 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
345 frayREG->SUCC1_UN.SUCC1_ST.mtsb_B1 = 1U;
348 else if(frayREG->SUCC1_UN.SUCC1_ST.ccha_B1){
350 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
351 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
352 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
354 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
355 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
356 frayREG->SUCC1_UN.SUCC1_ST.mtsa_B1 = 1U;
359 else if (frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
361 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
362 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
363 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
365 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
366 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
367 frayREG->SUCC1_UN.SUCC1_ST.mtsb_B1 = 1U;
369 else frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
371 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
374 while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01)
375 ; // Waiting for READY state
380 * @brief Switch POC to ready state from startup state
382 * After command to switch into ready state is passed into CHI,
383 * the response is checked and if POC has reacted on the command,
384 * the function is waiting until POC is ready
386 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
388 static Std_ReturnType Fr_POC_go_to_ready_from_startup() {
389 Fr_wait_for_POC_ready();
390 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
391 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
393 while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01); // Wait until POC is not in ready state
394 Fr_wait_for_POC_ready();
399 * @brief Switch POC to startup state from ready state
401 * After command to switch into startup state is passed into CHI,
402 * the response is checked and if POC has reacted on the command,
403 * the function is waiting until POC is ready
405 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
407 static Std_ReturnType Fr_POC_go_to_startup() {
408 Fr_wait_for_POC_ready();
409 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_RUN;
410 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
412 Fr_wait_for_POC_ready();
417 * @brief Copy cluster config parameters into FlexRay configuration registers.
419 * This function does not check values ranges. This is a responsibility of higher
420 * layers. Cluster configuration parameters are copied from data structure
421 * into right bit position in configuration registers.
423 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
425 void Fr_config_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr) {
426 frayREG->SUCC1_UN.SUCC1_ST.csa_B5 = clusterConfigPtr->gColdStartAttempts;
427 frayREG->GTUC9_UN.GTUC9_ST.apo_B5 = clusterConfigPtr->gdActionPointOffset;
428 frayREG->PRTC1_UN.PRTC1_ST.casm_B7 = clusterConfigPtr->gdCASRxLowMax;
429 frayREG->GTUC9_UN.GTUC9_ST.dsi_B2 = clusterConfigPtr->gdDynamicSlotIdlePhase;
430 frayREG->GTUC8_UN.GTUC8_ST.msl_B6 = clusterConfigPtr->gdMinislot;
431 frayREG->GTUC9_UN.GTUC9_ST.mapo_B5 = clusterConfigPtr->gdMinislotActionPointOffset;
432 frayREG->GTUC7_UN.GTUC7_ST.ssl_B10 = clusterConfigPtr->gdStaticSlot;
433 frayREG->PRTC1_UN.PRTC1_ST.tsst_B4 = clusterConfigPtr->gdTSSTransmitter;
434 frayREG->PRTC2_UN.PRTC2_ST.rxi_B6 = clusterConfigPtr->gdWakeupSymbolRxIdle;
435 frayREG->PRTC2_UN.PRTC2_ST.rxl_B6 = clusterConfigPtr->gdWakeupSymbolRxLow;
436 frayREG->PRTC1_UN.PRTC1_ST.rxw_B9 = clusterConfigPtr->gdWakeupSymbolRxWindow;
437 frayREG->PRTC2_UN.PRTC2_ST.txi_B8 = clusterConfigPtr->gdWakeupSymbolTxIdle;
438 frayREG->PRTC2_UN.PRTC2_ST.txl_B6 = clusterConfigPtr->gdWakeupSymbolTxLow;
439 frayREG->SUCC2_UN.SUCC2_ST.ltn_B4 = clusterConfigPtr->gListenNoise;
440 frayREG->GTUC2_UN.GTUC2_ST.mpc_B14 = clusterConfigPtr->gMacroPerCycle;
441 frayREG->SUCC3_UN.SUCC3_ST.wcf_B4 = clusterConfigPtr->gMaxWithoutClockCorrectionFatal;
442 frayREG->SUCC3_UN.SUCC3_ST.wcp_B4 = clusterConfigPtr->gMaxWithoutClockCorrectionPassive;
443 frayREG->GTUC8_UN.GTUC8_ST.nms_B13 = clusterConfigPtr->gNumberOfMinislots;
444 frayREG->GTUC7_UN.GTUC7_ST.nss_B10 = clusterConfigPtr->gNumberOfStaticSlots;
445 frayREG->GTUC4_UN.GTUC4_ST.ocs_B14 = clusterConfigPtr->gOffsetCorrectionStart;
446 frayREG->MHDC_UN.MHDC_ST.sfdl_B7 = clusterConfigPtr->gPayloadLengthStatic;
447 frayREG->GTUC2_UN.GTUC2_ST.snm_B4 = clusterConfigPtr->gSyncNodeMax;
448 frayREG->GTUC4_UN.GTUC4_ST.nit_B14 = clusterConfigPtr->gdNIT;
449 frayREG->PRTC1_UN.PRTC1_ST.brp_B2 = clusterConfigPtr->gdSampleClockPeriod;
450 frayREG->NEMC_UN.NEMC_ST.nml_B4 = clusterConfigPtr->gNetworkManagementVectorLength;
453 #define __notInRange(val, min, max) (((val) < (min)) || ((val) > (max)))
456 * @brief Check cluster configuration parameters.
458 * This function checks values of the cluster configuration parameters,
459 * if they are in ranges noted in FlexRay specification.
461 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
462 * @param [out] errCode Address where error flags will be stored.
463 * We have 26 parameters to check. Every one of them has assigned its bit in this flag.
464 * Error flags are defined as macros ERR_PARAM_nameOfParameter.
465 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
467 Std_ReturnType Fr_check_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr, uint32_t* errCode) {
468 *errCode = ERR_PARAM_NO_ERROR;
470 if (__notInRange(clusterConfigPtr->gColdStartAttempts, 2, 31)) *errCode |= ERR_PARAM_gColdStartAttempts;
471 if (__notInRange(clusterConfigPtr->gdActionPointOffset, 1, 63)) *errCode |= ERR_PARAM_gdActionPointOffset;
472 if (__notInRange(clusterConfigPtr->gdCASRxLowMax, 67, 99)) *errCode |= ERR_PARAM_gdCASRxLowMax;
473 if (clusterConfigPtr->gdDynamicSlotIdlePhase > 2) *errCode |= ERR_PARAM_gdDynamicSlotIdlePhase;
474 if (__notInRange(clusterConfigPtr->gdMinislot, 2, 63)) *errCode |= ERR_PARAM_gdMinislot;
475 if (__notInRange(clusterConfigPtr->gdMinislotActionPointOffset,
476 1, 31)) *errCode |= ERR_PARAM_gdMinislotActionPointOffset;
477 if (__notInRange(clusterConfigPtr->gdStaticSlot, 4, 661)) *errCode |= ERR_PARAM_gdStaticSlot;
478 if (__notInRange(clusterConfigPtr->gdTSSTransmitter, 3, 15)) *errCode |= ERR_PARAM_gdTSSTransmitter;
479 if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxIdle, 14, 59)) *errCode |= ERR_PARAM_gdWakeupSymbolRxIdle;
480 if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxLow, 11, 59)) *errCode |= ERR_PARAM_gdWakeupSymbolRxLow;
481 if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxWindow,
482 76, 301)) *errCode |= ERR_PARAM_gdWakeupSymbolRxWindow;
483 if (__notInRange(clusterConfigPtr->gdWakeupSymbolTxIdle, 45, 180)) *errCode |= ERR_PARAM_gdWakeupSymbolTxIdle;
484 if (__notInRange(clusterConfigPtr->gdWakeupSymbolTxLow, 15, 60)) *errCode |= ERR_PARAM_gdWakeupSymbolTxLow;
485 if (__notInRange(clusterConfigPtr->gListenNoise, 2, 16)) *errCode |= ERR_PARAM_gListenNoise;
486 if (__notInRange(clusterConfigPtr->gMacroPerCycle, 10, 16000)) *errCode |= ERR_PARAM_gMacroPerCycle;
487 if (__notInRange(clusterConfigPtr->gMaxWithoutClockCorrectionFatal,
488 clusterConfigPtr->gMaxWithoutClockCorrectionPassive, 15)) *errCode |= ERR_PARAM_gMaxWithoutClockCorrectionFatal;
489 if (__notInRange(clusterConfigPtr->gMaxWithoutClockCorrectionPassive,
490 1, 15)) *errCode |= ERR_PARAM_gMaxWithoutClockCorrectionPassive;
491 if (clusterConfigPtr->gNumberOfMinislots > 7986) *errCode |= ERR_PARAM_gNumberOfMinislots;
492 if (__notInRange(clusterConfigPtr->gNumberOfStaticSlots,
493 2, cStaticSlotIDMax)) *errCode |= ERR_PARAM_gNumberOfStaticSlots;
494 if (__notInRange(clusterConfigPtr->gOffsetCorrectionStart,
495 9, 15999)) *errCode |= ERR_PARAM_gOffsetCorrectionStart;
496 if (clusterConfigPtr->gPayloadLengthStatic > cPayloadLengthMax) *errCode |= ERR_PARAM_gPayloadLengthStatic;
497 if (__notInRange(clusterConfigPtr->gSyncNodeMax, 2, cSyncNodeMax)) *errCode |= ERR_PARAM_gSyncNodeMax;
498 if (__notInRange(clusterConfigPtr->gdNIT, 7, 0x3E7D)) *errCode |= ERR_PARAM_gdNIT;
499 if (clusterConfigPtr->gdSampleClockPeriod > 3) *errCode |= ERR_PARAM_gdSampleClockPeriod;
500 if (clusterConfigPtr->gNetworkManagementVectorLength > 12) *errCode |= ERR_PARAM_gNetworkManagementVectorLength;
502 return (*errCode == 0) ? E_OK : E_NOT_OK;
506 * @brief Copy node config parameters into FlexRay configuration registers.
508 * This function does not check values ranges. This is a responsibility of higher
509 * layers. Node configuration parameters are copied from data structure
510 * into right bit position in configuration registers.
512 * @param [in] nodeConfigPtr Address of structure with node configuration parameters
514 void Fr_config_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr) {
515 frayREG->SUCC1_UN.SUCC1_ST.hcse_B1 = nodeConfigPtr->pAllowHaltDueToClock;
516 frayREG->SUCC1_UN.SUCC1_ST.pta_B5 = nodeConfigPtr->pAllowPassiveToActive;
517 if (nodeConfigPtr->pChannels == FR_CHANNEL_AB) {
518 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 1;
519 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 1;
521 else if (nodeConfigPtr->pChannels == FR_CHANNEL_A) {
522 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 1;
523 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 0;
526 frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 = 0;
527 frayREG->SUCC1_UN.SUCC1_ST.cchb_B1 = 1;
529 frayREG->GTUC6_UN.GTUC6_ST.asr_B11 = nodeConfigPtr->pdAcceptedStartupRange;
530 frayREG->GTUC5_UN.GTUC5_ST.cdd_B5 = nodeConfigPtr->pClusterDriftDamping;
531 frayREG->GTUC5_UN.GTUC5_ST.dca_B8 = nodeConfigPtr->pDelayCompensationA;
532 frayREG->GTUC5_UN.GTUC5_ST.dcb_B8 = nodeConfigPtr->pDelayCompensationB;
533 frayREG->GTUC5_UN.GTUC5_ST.dec_B8 = nodeConfigPtr->pDecodingCorrection;
534 frayREG->SUCC2_UN.SUCC2_ST.lt_B21 = nodeConfigPtr->pdListenTimeout;
535 frayREG->GTUC6_UN.GTUC6_ST.mod_B11 = nodeConfigPtr->pdMaxDrift;
536 frayREG->GTUC11_UN.GTUC11_ST.eoc_B3 = nodeConfigPtr->pExternOffsetCorrection;
537 frayREG->GTUC11_UN.GTUC11_ST.erc_B3 = nodeConfigPtr->pExternRateCorrection;
538 frayREG->SUCC1_UN.SUCC1_ST.txst_B1 = nodeConfigPtr->pKeySlotUsedForStartup;
539 frayREG->SUCC1_UN.SUCC1_ST.txsy_B1 = nodeConfigPtr->pKeySlotUsedForSync;
540 frayREG->MHDC_UN.MHDC_ST.slt_B13 = nodeConfigPtr->pLatestTx;
541 frayREG->GTUC3_UN.GTUC3_ST.mioa_B7 = nodeConfigPtr->pMacroInitialOffsetA;
542 frayREG->GTUC3_UN.GTUC3_ST.miob_B7 = nodeConfigPtr->pMacroInitialOffsetB;
543 frayREG->GTUC3_UN.GTUC3_ST.uioa_B8 = nodeConfigPtr->pMicroInitialOffsetA;
544 frayREG->GTUC3_UN.GTUC3_ST.uiob_B8 = nodeConfigPtr->pMicroInitialOffsetB;
545 frayREG->GTUC1_UN.GTUC1_ST.ut_B20 = nodeConfigPtr->pMicroPerCycle;
546 frayREG->GTUC10_UN.GTUC10_ST.moc_B13 = nodeConfigPtr->pRateCorrectionOut;
547 frayREG->GTUC10_UN.GTUC10_ST.mrc_B11 = nodeConfigPtr->pOffsetCorrectionOut;
548 frayREG->SUCC1_UN.SUCC1_ST.tsm_B1 = nodeConfigPtr->pSingleSlotEnabled;
549 if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_A) {
550 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 0;
552 else if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_B) {
553 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 1;
555 frayREG->PRTC1_UN.PRTC1_ST.rwp_B6 = nodeConfigPtr->pWakeupPattern;
556 frayREG->PRTC1_UN.PRTC1_ST.brp_B2 = nodeConfigPtr->pSamplesPerMicrotick;
560 * @brief Check node configuration parameters.
562 * This function checks values of the node configuration parameters,
563 * if they are in ranges noted in FlexRay specification.
565 * @param [in] nodeConfigPtr Address of structure with node configuration parameters
566 * @param [out] errCode Address where error flags will be stored.
567 * We have 24 parameters to check. Every one of them has assigned its bit in this flag.
568 * Error flags are defined as macros ERR_PARAM_nameOfParameter.
569 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
571 Std_ReturnType Fr_check_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr, uint32_t* errCode) {
572 *errCode = ERR_PARAM_NO_ERROR;
574 if (nodeConfigPtr->pAllowPassiveToActive > 31) *errCode |= ERR_PARAM_pAllowPassiveToActive;
575 if (nodeConfigPtr->pChannels != FR_CHANNEL_A &&
576 nodeConfigPtr->pChannels != FR_CHANNEL_B &&
577 nodeConfigPtr->pChannels != FR_CHANNEL_AB ) *errCode |= ERR_PARAM_pChannels;
578 if (nodeConfigPtr->pdAcceptedStartupRange > 1875) *errCode |= ERR_PARAM_pdAcceptedStartupRange;
579 if (nodeConfigPtr->pClusterDriftDamping > 20) *errCode |= ERR_PARAM_pClusterDriftDamping;
580 if (nodeConfigPtr->pDelayCompensationA > 200) *errCode |= ERR_PARAM_pDelayCompensationA;
581 if (nodeConfigPtr->pDelayCompensationB > 200) *errCode |= ERR_PARAM_pDelayCompensationB;
582 if (__notInRange(nodeConfigPtr->pdListenTimeout, 1284, 1283846)) *errCode |= ERR_PARAM_pdListenTimeout;
583 if (__notInRange(nodeConfigPtr->pdMaxDrift, 2, 1923)) *errCode |= ERR_PARAM_pdMaxDrift;
584 if (nodeConfigPtr->pExternOffsetCorrection > 7) *errCode |= ERR_PARAM_pExternOffsetCorrection;
585 if (nodeConfigPtr->pExternRateCorrection > 7) *errCode |= ERR_PARAM_pExternRateCorrection;
586 if (nodeConfigPtr->pKeySlotUsedForStartup == TRUE &&
587 nodeConfigPtr->pKeySlotUsedForSync == FALSE) *errCode |= ERR_PARAM_pKeySlotUsedForSync
588 | ERR_PARAM_pKeySlotUsedForStartup; // If pKeySlotUsedForStartup is set to true then pKeySlotUsedForSync must also be set to true.
589 if (nodeConfigPtr->pLatestTx > 7980) *errCode |= ERR_PARAM_pLatestTx;
590 if (__notInRange(nodeConfigPtr->pMacroInitialOffsetA, 2, 68)) *errCode |= ERR_PARAM_pMacroInitialOffsetA;
591 if (__notInRange(nodeConfigPtr->pMacroInitialOffsetB, 2, 68)) *errCode |= ERR_PARAM_pMacroInitialOffsetB;
592 if (nodeConfigPtr->pMicroInitialOffsetA > 239) *errCode |= ERR_PARAM_pMicroInitialOffsetA;
593 if (nodeConfigPtr->pMicroInitialOffsetB > 239) *errCode |= ERR_PARAM_pMicroInitialOffsetB;
594 if (__notInRange(nodeConfigPtr->pMicroPerCycle, 640, 640000)) *errCode |= ERR_PARAM_pMicroPerCycle;
595 if (__notInRange(nodeConfigPtr->pRateCorrectionOut, 2, 1923)) *errCode |= ERR_PARAM_pRateCorrectionOut;
596 if (__notInRange(nodeConfigPtr->pOffsetCorrectionOut, 5, 0x3BA2)) *errCode |= ERR_PARAM_pOffsetCorrectionOut;
597 if (nodeConfigPtr->pWakeupChannel != FR_CHANNEL_A &&
598 nodeConfigPtr->pWakeupChannel != FR_CHANNEL_B ) *errCode |= ERR_PARAM_pWakeupChannel;
599 if (__notInRange(nodeConfigPtr->pWakeupPattern, 2, 63)) *errCode |= ERR_PARAM_pWakeupPattern;
600 if (nodeConfigPtr->pSamplesPerMicrotick > 3) *errCode |= ERR_PARAM_pSamplesPerMicrotick;
601 if (__notInRange(nodeConfigPtr->pDecodingCorrection, 0xF, 0x8F)) *errCode |= ERR_PARAM_pDecodingCorrection;
603 return (*errCode == 0) ? E_OK : E_NOT_OK;
607 * @brief Check Configuration parameters for all buffers
609 * This function checks configuration parameters.
611 * - All of them have to be RX
612 * - All of them have the same payload <= 256B
613 * - Same channels active
614 * - Same cycle counter filter
617 * - not reconfigurable
618 * - frame ID can be 0, which means that all messages not received by others buffers are received in FIFO.
619 * For dynamic segment buffers and static segment buffers:
620 * - frame ID must not be 0
622 * The sum of all configured payloads must be <= 8KB.
624 * @param [in] statBufCfgPtr Address of structure with static buffers configuration parameters
625 * @param [in] dynBufCfgPtr Address of structure with dynamic buffers configuration parameters
626 * @param [in] fifoBufCfgPtr Address of structure with fifo buffers configuration parameters
627 * @param [in] statBufCnt Number of static buffers to be configured
628 * @param [in] dynBufCnt Number of dynamic buffers to be configured
629 * @param [in] fifoBufCnt Number of fifo buffers to be configured
630 * @param [out] errCode Address where error flags will be stored.
631 * Flags are defined as ERR_PARAM_BUF.....
632 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
634 Std_ReturnType Fr_check_buffer_parameters(const Fr_TMS570LS_BufferConfigType* statBufCfgPtr, const Fr_TMS570LS_BufferConfigType* dynBufCfgPtr, const Fr_TMS570LS_BufferConfigType* fifoBufCfgPtr,
635 uint8_t statBufCnt, uint8_t dynBufCnt, uint8_t fifoBufCnt, uint32_t* errCode) {
636 uint32_t payloadTotal = 0;
637 *errCode = ERR_PARAM_NO_ERROR;
639 Fr_ChannelType fifoChannels;
640 uint8_t fifoCycleCounterFiltering;
643 /* Check FIFO buffer parameters */
644 if (fifoBufCnt != 0 && fifoBufCfgPtr != NULL) {
645 fifoPayload = fifoBufCfgPtr[0].maxPayload;
646 fifoChannels = fifoBufCfgPtr[0].channel;
647 fifoCycleCounterFiltering = fifoBufCfgPtr[0].cycleCounterFiltering;
648 if (fifoPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFFIFO_PAYLOAD_HIGH;
649 for (i = 0; i < fifoBufCnt; i++) {
650 if (fifoBufCfgPtr[i].isTx == TRUE) *errCode |= ERR_PARAM_BUFFIFO_NOT_RX;
651 if (fifoBufCfgPtr[i].maxPayload != fifoPayload) *errCode |= ERR_PARAM_BUFFIFO_PAYLOAD_DIFFERS;
652 if (fifoBufCfgPtr[i].channel != fifoChannels) *errCode |= ERR_PARAM_BUFFIFO_CHANNEL_DIFFERS;
653 if (fifoBufCfgPtr[i].cycleCounterFiltering != fifoCycleCounterFiltering) *errCode |= ERR_PARAM_BUFFIFO_CCFILTER_DIFFERS;
654 payloadTotal += fifoBufCfgPtr[i].maxPayload;
657 if (dynBufCfgPtr != NULL) {
658 for (i = 0; i < dynBufCnt; i++) {
659 if (dynBufCfgPtr[i].slotId == 0) *errCode |= ERR_PARAM_BUFDYN_FRAMEID_INVALID;
660 if (dynBufCfgPtr[i].maxPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFDYN_PAYLOAD_HIGH;
661 if (dynBufCfgPtr[i].channel == FR_CHANNEL_AB) *errCode |= ERR_PARAM_BUFDYN_CHANNELS;
662 payloadTotal += dynBufCfgPtr[i].maxPayload;
666 if (statBufCfgPtr != NULL) {
667 for (i = 0; i < statBufCnt; i++) {
668 if (statBufCfgPtr[i].slotId == 0) *errCode |= ERR_PARAM_BUFSTAT_FRAMEID_INVALID;
669 if (statBufCfgPtr[i].maxPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFSTAT_PAYLOAD_HIGH;
670 payloadTotal += statBufCfgPtr[i].maxPayload;
674 if (payloadTotal > 8192/2) *errCode |= ERR_PARAM_BUF_TOTAL_PAYLOAD_HIGH;
676 return (*errCode == 0) ? E_OK : E_NOT_OK;
680 * @brief Compute and set message RAM config parameters into FlexRay configuration registers.
682 * This function does not check values ranges. This is a responsibility of other functions.
683 * Message RAM configuration parameters are computed from data in the structure and
684 * written into right bit position in configuration registers.
686 * @param [in] msgRAMConfigPtr Address of structure with message RAM configuration parameters
687 * @return Number of configured buffers
689 uint8_t Fr_config_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr) {
690 /* If dynSegmentBufferCount is not 0 then first dynamic buffer = statSegmentBufferCount.
691 * If dynSegmentBufferCount is 0 then first dynamic buffer is 0x80 (see TMS570LS31x documentation)
693 if (msgRAMConfigPtr->dynSegmentBufferCount == 0) {
694 frayREG->MRC_UN.MRC_ST.fdb_B8 = 0x80;
697 frayREG->MRC_UN.MRC_ST.fdb_B8 = msgRAMConfigPtr->statSegmentBufferCount;
699 /* If fifoBufferCount is not 0 then first fifo buffer = statSegmentBufferCount + dynSegmentBufferCount
700 * If fifoBufferCount is 0 then first fifo buffer is 0x80 (see TMS570LS31x documentation)
702 if (msgRAMConfigPtr->fifoBufferCount == 0) {
703 frayREG->MRC_UN.MRC_ST.ffb_B8 = 0x80;
706 frayREG->MRC_UN.MRC_ST.ffb_B8 = msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount;
708 /* Last configured buffer = statSegmentBufferCount + dynSegmentBufferCount + fifoBufferCount - 1 */
709 frayREG->MRC_UN.MRC_ST.lcb_B8 = msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount - 1;
711 /* Secure buffers setting */
712 if (msgRAMConfigPtr->secureBuffers == FR_SB_RECONFIG_ENABLED) {
713 frayREG->MRC_UN.MRC_ST.sec_B2 = 0;
715 else if (msgRAMConfigPtr->secureBuffers == FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED) {
716 frayREG->MRC_UN.MRC_ST.sec_B2 = 1;
718 else if (msgRAMConfigPtr->secureBuffers == FR_SB_ALL_REC_DISABLED) {
719 frayREG->MRC_UN.MRC_ST.sec_B2 = 2;
722 frayREG->MRC_UN.MRC_ST.sec_B2 = 3;
725 /* Sync frame payload multiplex setting */
726 if (msgRAMConfigPtr->syncFramePayloadMultiplexEnabled == TRUE) {
727 frayREG->MRC_UN.MRC_ST.splm_B1 = 1;
730 frayREG->MRC_UN.MRC_ST.splm_B1 = 0;
733 return msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount;
736 #define __notInRange(val, min, max) (((val) < (min)) || ((val) > (max)))
739 * @brief Check message RAM configuration parameters.
741 * This function checks values of the message RAM configuration parameters.
742 * FlexRay implementation in TMS570 can have up to 128 buffers configured, so
743 * the sum of all values buffer count must not exceed this ceiling.
746 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
747 * @param [out] errCode Address where error flags will be stored.
748 * Error flags are defined as macros ERR_PARAM_nameOfParameter.
749 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
751 Std_ReturnType Fr_check_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr, uint32_t* errCode) {
752 *errCode = ERR_PARAM_NO_ERROR;
754 if (__notInRange(msgRAMConfigPtr->statSegmentBufferCount, 1, 127)) *errCode |= ERR_PARAM_statSegmentBufferCount;
755 if (msgRAMConfigPtr->dynSegmentBufferCount >= FR_MAX_BUFFERS_CNT) *errCode |= ERR_PARAM_dynSegmentBufferCount;
756 if (msgRAMConfigPtr->fifoBufferCount >= FR_MAX_BUFFERS_CNT) *errCode |= ERR_PARAM_fifoBufferCount;
757 if ((msgRAMConfigPtr->statSegmentBufferCount +
758 msgRAMConfigPtr->dynSegmentBufferCount +
759 msgRAMConfigPtr->fifoBufferCount) >= FR_MAX_BUFFERS_CNT) *errCode |= ERR_PARAM_maxBuffLimit;
761 return (*errCode == 0) ? E_OK : E_NOT_OK;
764 void Fr_Init(const Fr_ConfigType* Fr_ConfigPtr) {
768 if (Fr_ConfigPtr == NULL) {
771 if (Fr_DrvState != FR_ST_DRV_NOT_INITIALIZED) {
775 /* Save pointers for parameters indexed by CIDX indexes
776 * This array representation is used by Fr_ReadCCConfig function.
777 * Parameter thet are not configurable in tms570 FlexRay implementation
780 Fr_ConfigParPtrs[FR_CIDX_GDCYCLE] = 0;
781 Fr_ConfigParPtrs[FR_CIDX_PMICROPERCYCLE] = Fr_ConfigPtr->nodeConfiguration->pMicroPerCycle;
782 Fr_ConfigParPtrs[FR_CIDX_PDLISTENTIMEOUT] = Fr_ConfigPtr->clusterConfiguration->gMacroPerCycle;
783 Fr_ConfigParPtrs[FR_CIDX_GDMACROTICK] = 0;
784 Fr_ConfigParPtrs[FR_CIDX_GNUMBEROFMINISLOTS] = Fr_ConfigPtr->clusterConfiguration->gNumberOfMinislots;
785 Fr_ConfigParPtrs[FR_CIDX_GNUMBEROFSTATICSLOTS] = Fr_ConfigPtr->clusterConfiguration->gNumberOfStaticSlots;
786 Fr_ConfigParPtrs[FR_CIDX_GDNIT] = Fr_ConfigPtr->clusterConfiguration->gdNIT;
787 Fr_ConfigParPtrs[FR_CIDX_GDSTATICSLOT] = Fr_ConfigPtr->clusterConfiguration->gdNIT;
788 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXWINDOW] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolRxWindow;
789 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTID] = 0;
790 Fr_ConfigParPtrs[FR_CIDX_PLATESTTX] = Fr_ConfigPtr->nodeConfiguration->pLatestTx;
791 Fr_ConfigParPtrs[FR_CIDX_POFFSETCORRECTIONOUT] = 0;
792 Fr_ConfigParPtrs[FR_CIDX_POFFSETCORRECTIONSTART] = 0;
793 Fr_ConfigParPtrs[FR_CIDX_PRATECORRECTIONOUT] = Fr_ConfigPtr->nodeConfiguration->pRateCorrectionOut;
794 Fr_ConfigParPtrs[FR_CIDX_PSECONDKEYSLOTID] = 0;
795 Fr_ConfigParPtrs[FR_CIDX_PDACCEPTEDSTARTUPRANGE] = Fr_ConfigPtr->nodeConfiguration->pdAcceptedStartupRange;
796 Fr_ConfigParPtrs[FR_CIDX_GCOLDSTARTATTEMPTS] = Fr_ConfigPtr->clusterConfiguration->gColdStartAttempts;
797 Fr_ConfigParPtrs[FR_CIDX_GCYCLECOUNTMAX] = 0;
798 Fr_ConfigParPtrs[FR_CIDX_GLISTENNOISE] = Fr_ConfigPtr->clusterConfiguration->gListenNoise;
799 Fr_ConfigParPtrs[FR_CIDX_GMAXWITHOUTCLOCKCORRECTFATAL] = Fr_ConfigPtr->clusterConfiguration->gMaxWithoutClockCorrectionFatal;
800 Fr_ConfigParPtrs[FR_CIDX_GMAXWITHOUTCLOCKCORRECTPASSIVE] = Fr_ConfigPtr->clusterConfiguration->gMaxWithoutClockCorrectionPassive;
801 Fr_ConfigParPtrs[FR_CIDX_GNETWORKMANAGEMENTVECTORLENGTH] = Fr_ConfigPtr->clusterConfiguration->gNetworkManagementVectorLength;
802 Fr_ConfigParPtrs[FR_CIDX_GPAYLOADLENGTHSTATIC] = Fr_ConfigPtr->clusterConfiguration->gPayloadLengthStatic;
803 Fr_ConfigParPtrs[FR_CIDX_GSYNCFRAMEIDCOUNTMAX] = 0;
804 Fr_ConfigParPtrs[FR_CIDX_GDACTIONPOINTOFFSET] = Fr_ConfigPtr->clusterConfiguration->gdActionPointOffset;
805 Fr_ConfigParPtrs[FR_CIDX_GDBIT] = 0;
806 Fr_ConfigParPtrs[FR_CIDX_GDCASRXLOWMAX] = Fr_ConfigPtr->clusterConfiguration->gdCASRxLowMax;
807 Fr_ConfigParPtrs[FR_CIDX_GDDYNAMICSLOTIDLEPHASE] = Fr_ConfigPtr->clusterConfiguration->gdDynamicSlotIdlePhase;
808 Fr_ConfigParPtrs[FR_CIDX_GDMINISLOTACTIONPOINTOFFSET] = Fr_ConfigPtr->clusterConfiguration->gdMinislotActionPointOffset;
809 Fr_ConfigParPtrs[FR_CIDX_GDMINISLOT] = Fr_ConfigPtr->clusterConfiguration->gdMinislot;
810 Fr_ConfigParPtrs[FR_CIDX_GDSAMPLECLOCKPERIOD] = Fr_ConfigPtr->clusterConfiguration->gdSampleClockPeriod;
811 Fr_ConfigParPtrs[FR_CIDX_GDSYMBOLWINDOW] = 0;
812 Fr_ConfigParPtrs[FR_CIDX_GDSYMBOLWINDOWACTIONPOINTOFFSET] = 0;
813 Fr_ConfigParPtrs[FR_CIDX_GDTSSTRANSMITTER] = Fr_ConfigPtr->clusterConfiguration->gdTSSTransmitter;
814 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXIDLE] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolRxIdle;
815 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXLOW] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolRxLow;
816 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPTXACTIVE] = 0;
817 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPTXIDLE] = Fr_ConfigPtr->clusterConfiguration->gdWakeupSymbolTxIdle;
818 Fr_ConfigParPtrs[FR_CIDX_PALLOWPASSIVETOACTIVE] = Fr_ConfigPtr->nodeConfiguration->pAllowPassiveToActive;
819 Fr_ConfigParPtrs[FR_CIDX_PCHANNELS] = Fr_ConfigPtr->nodeConfiguration->pChannels;
820 Fr_ConfigParPtrs[FR_CIDX_PCLUSTERDRIFTDAMPING] = Fr_ConfigPtr->nodeConfiguration->pClusterDriftDamping;
821 Fr_ConfigParPtrs[FR_CIDX_PDECODINGCORRECTION] = 0;
822 Fr_ConfigParPtrs[FR_CIDX_PDELAYCOMPENSATIONA] = Fr_ConfigPtr->nodeConfiguration->pDelayCompensationA;
823 Fr_ConfigParPtrs[FR_CIDX_PDELAYCOMPENSATIONB] = Fr_ConfigPtr->nodeConfiguration->pDelayCompensationB;
824 Fr_ConfigParPtrs[FR_CIDX_PMACROINITIALOFFSETA] = Fr_ConfigPtr->nodeConfiguration->pMacroInitialOffsetA;
825 Fr_ConfigParPtrs[FR_CIDX_PMACROINITIALOFFSETB] = Fr_ConfigPtr->nodeConfiguration->pMacroInitialOffsetB;
826 Fr_ConfigParPtrs[FR_CIDX_PMICROINITIALOFFSETA] = Fr_ConfigPtr->nodeConfiguration->pMicroInitialOffsetA;
827 Fr_ConfigParPtrs[FR_CIDX_PMICROINITIALOFFSETB] = Fr_ConfigPtr->nodeConfiguration->pMicroInitialOffsetB;
828 Fr_ConfigParPtrs[FR_CIDX_PPAYLOADLENGTHDYNMAX] = 0;
829 Fr_ConfigParPtrs[FR_CIDX_PSAMPLESPERMICROTICK] = Fr_ConfigPtr->nodeConfiguration->pSamplesPerMicrotick;
830 Fr_ConfigParPtrs[FR_CIDX_PWAKEUPCHANNEL] = Fr_ConfigPtr->nodeConfiguration->pWakeupChannel;
831 Fr_ConfigParPtrs[FR_CIDX_PWAKEUPPATTERN] = Fr_ConfigPtr->nodeConfiguration->pWakeupPattern;
832 Fr_ConfigParPtrs[FR_CIDX_PDMICROTICK] = 0;
833 Fr_ConfigParPtrs[FR_CIDX_GDIGNOREAFTERTX] = 0;
834 Fr_ConfigParPtrs[FR_CIDX_PALLOWHALTDUETOCLOCK] = Fr_ConfigPtr->nodeConfiguration->pAllowHaltDueToClock;
835 Fr_ConfigParPtrs[FR_CIDX_PEXTERNALSYNC] = 0;
836 Fr_ConfigParPtrs[FR_CIDX_PFALLBACKINTERNAL] = 0;
837 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTONLYENABLED] = 0;
838 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSTARTUP] = Fr_ConfigPtr->nodeConfiguration->pKeySlotUsedForStartup;
839 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSYNC] = Fr_ConfigPtr->nodeConfiguration->pKeySlotUsedForSync;
840 Fr_ConfigParPtrs[FR_CIDX_PNMVECTOREARLYUPDATE] = 0;
841 Fr_ConfigParPtrs[FR_CIDX_PTWOKEYSLOTMODE] = 0;
843 /* Store whole configuration address
844 * This structured representation is used by other function in API.
846 Fr_Config = Fr_ConfigPtr;
848 /* Store pointers to structures with configuration parameters of buffers
849 * Reset configured flags for all buffers */
850 for (i = 0; i < Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount; ++i) { // Statis segment buffers
851 Fr_BuffersPtrs[i] = (Fr_TMS570LS_BufferConfigType*)&Fr_ConfigPtr->staticBufferConfigs[i];
852 Fr_BuffersConfigured[i] = FALSE;
854 for (i = 0; i < Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount; ++i) { // Dynamic segment buffers
855 Fr_BuffersPtrs[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount] = (Fr_TMS570LS_BufferConfigType*)&Fr_ConfigPtr->dynamicBufferConfigs[i];
856 Fr_BuffersConfigured[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount] = FALSE;
858 for (i = 0; i < Fr_ConfigPtr->msgRAMConfig->fifoBufferCount; ++i) { // Fifo buffrers
859 Fr_BuffersPtrs[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount] = (Fr_TMS570LS_BufferConfigType*)&Fr_ConfigPtr->fifoBufferConfigs[i];
860 Fr_BuffersConfigured[i + Fr_ConfigPtr->msgRAMConfig->statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig->dynSegmentBufferCount] = FALSE;
864 Fr_DrvState = FR_ST_DRV_INITIALIZED;
868 Std_ReturnType Fr_ControllerInit(uint8_t Fr_CtrlIdx) {
869 uint32_t errCode = ERR_PARAM_NO_ERROR;
871 uint8_t totalBufferCount;
874 if (Fr_DrvState != FR_ST_DRV_INITIALIZED) {
879 /* Switch CC into ‘POC:config’ (from any other POCState) */
880 if (Fr_POC_go_to_config() == E_NOT_OK) {
883 /* Check Cluster config parameters */
884 if (Fr_check_cluster_parameters(Fr_Config->clusterConfiguration, &errCode) == E_NOT_OK) {
885 return E_NOT_OK | errCode | FR_INIT_ERR_CLUSTER_CONFIG;
887 /* Check node config parameters */
888 if (Fr_check_node_parameters(Fr_Config->nodeConfiguration, &errCode) == E_NOT_OK) {
889 return E_NOT_OK | errCode | FR_INIT_ERR_NODE_CONFIG;
891 /* Check msgRAM config parameters */
892 if (Fr_check_msgRAM_parameters(Fr_Config->msgRAMConfig, &errCode) == E_NOT_OK) {
893 return E_NOT_OK | errCode | FR_INIT_ERR_MSGRAM_CONFIG;
895 /* Check buffers parameters */
896 if (Fr_check_buffer_parameters(Fr_Config->staticBufferConfigs, Fr_Config->dynamicBufferConfigs, Fr_Config->fifoBufferConfigs,
897 Fr_Config->msgRAMConfig->statSegmentBufferCount, Fr_Config->msgRAMConfig->dynSegmentBufferCount, Fr_Config->msgRAMConfig->fifoBufferCount, &errCode) == E_NOT_OK) {
898 return E_NOT_OK | errCode | FR_INIT_ERR_BUFFPARAM_CONFIG;
901 /* Clear message RAM */
902 if (Fr_clear_msg_RAM() == FAILURE) {
906 /* Configure all FlexRay cluster, node and msgRAM parameters */
907 Fr_config_cluster_parameters(Fr_Config->clusterConfiguration);
908 Fr_config_node_parameters(Fr_Config->nodeConfiguration);
910 // Wait until CLEAR_RAMS command is complete
911 while (frayREG->MHDS_UN.MHDS_ST.cram_B1 == 1)
914 totalBufferCount = Fr_config_msgRAM_parameters(Fr_Config->msgRAMConfig);
915 Fr_MsgRAMDataStartAddress = totalBufferCount*4U; // First data section after headers sections in message RAM.
916 Fr_MsgRAMDataOffset = Fr_MsgRAMDataStartAddress;
917 /* Configure all transmit/receive resources */
918 for (i = 0; i < totalBufferCount; i++) {
919 if (Fr_PrepareLPdu(Fr_CtrlIdx, Fr_BuffersPtrs[i]->slotId) == E_NOT_OK) {
920 return E_NOT_OK | FR_INIT_ERR_BUFF_CONFIG;
924 /* Switch POC to ready state */
925 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
929 Fr_DrvState = FR_ST_CTRL_INITIALIZED;
934 Std_ReturnType Fr_StartCommunication(uint8_t Fr_CtrlIdx) {
936 uint32_t state_value;
939 if (Fr_CtrlIdx != 0) {
942 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
945 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY && frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_HALT) {
949 // Node halted, switch to ready
950 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_HALT) {
951 if (Fr_POC_go_to_config() == E_NOT_OK) {
954 if (Fr_POC_go_to_config() == E_NOT_OK) {
957 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
962 // Node is configured as coldstart
963 if (Fr_Config->nodeConfiguration->pKeySlotUsedForStartup == TRUE) {
967 // Try to integrate into an existing network as following coldstarter
968 if (Fr_POC_go_to_startup() == E_NOT_OK) {
969 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_FOLLOW; // Switch to run state error
972 do { // Wait until NORMAL_ACTIVE state or timeout
973 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
975 } while ((state_value != FR_POCS_NORMAL_ACTIVE) && (counter < FR_FCS_LISTEN_TIMEOUT));
977 // No success in integration, try to initiate FlexRay network as leading coldstarter.
978 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_INTEGRATION_LISTEN){
979 csa = frayREG->CCSV_UN.CCSV_ST.rca_B5;
980 if (csa != 0) { // Some cold start attempts remaining
981 if (Fr_AllowColdstart(Fr_CtrlIdx) == E_NOT_OK) {
982 return E_NOT_OK | FR_STARTUP_ERR_CSINH_DIS; // Cold start inhibit disabled error
986 do { // Wait until NORMAL_ACTIVE or INTEGRATION_LISTEN state
987 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
988 } while ( (state_value != FR_POCS_NORMAL_ACTIVE) && (state_value != FR_POCS_INTEGRATION_LISTEN));
989 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_NORMAL_ACTIVE) // Success, break the start up loop
991 if (Fr_POC_go_to_ready_from_startup() == E_NOT_OK) { // No success. Switch back to READY state
992 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_READY;
996 // The node is not coldstarter, try to integrate into an existing network.
998 if(Fr_POC_go_to_startup() == E_NOT_OK) {
999 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_AS_NCOLD; // Switching to startup state as non-cold start node
1002 // Wait until NORMAL_ACTIVE
1004 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
1005 } while (state_value != FR_POCS_NORMAL_ACTIVE);
1011 Std_ReturnType Fr_AllowColdstart(uint8_t Fr_CtrlIdx) {
1012 #ifdef DET_ACTIVATED
1013 if (Fr_CtrlIdx != 0) {
1016 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1020 Fr_wait_for_POC_ready();
1021 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_ALLOW_COLDSTART;
1022 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1024 Fr_wait_for_POC_ready();
1028 Std_ReturnType Fr_AllSlots(uint8_t Fr_CtrlIdx) {
1029 #ifdef DET_ACTIVATED
1030 if (Fr_CtrlIdx != 0) {
1033 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1037 Fr_wait_for_POC_ready();
1038 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_ALL_SLOTS;
1039 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1041 Fr_wait_for_POC_ready();
1045 // TODO: Create functions to switch POC from HALT to Default_config->Config->Ready state, to be able start communicating again.
1046 Std_ReturnType Fr_HaltCommunication(uint8_t Fr_CtrlIdx) {
1047 #ifdef DET_ACTIVATED
1048 if (Fr_CtrlIdx != 0) {
1051 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1055 Fr_wait_for_POC_ready();
1056 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_HALT;
1057 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1059 Fr_wait_for_POC_ready();
1063 Std_ReturnType Fr_AbortCommunication(uint8_t Fr_CtrlIdx) {
1064 #ifdef DET_ACTIVATED
1065 if (Fr_CtrlIdx != 0) {
1068 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1072 Fr_wait_for_POC_ready();
1073 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_FREEZE;
1074 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1076 Fr_wait_for_POC_ready();
1080 Std_ReturnType Fr_SendWUP(uint8_t Fr_CtrlIdx) {
1081 #ifdef DET_ACTIVATED
1082 if (Fr_CtrlIdx != 0) {
1085 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1089 Fr_wait_for_POC_ready();
1090 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_WAKEUP;
1091 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
1093 Fr_wait_for_POC_ready();
1097 Std_ReturnType Fr_SetWakeupChannel(uint8_t Fr_CtrlIdx, Fr_ChannelType Fr_ChnlIdx) {
1098 Std_ReturnType retVal = E_OK;
1100 #ifdef DET_ACTIVATED
1101 if (Fr_CtrlIdx != 0) {
1104 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1107 if (Fr_ChnlIdx == FR_CHANNEL_AB) {
1110 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY) {
1114 if (Fr_POC_go_to_config() == E_NOT_OK) {
1117 if (Fr_ChnlIdx == FR_CHANNEL_A) {
1118 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 0;
1121 else if (Fr_ChnlIdx == FR_CHANNEL_B) {
1122 frayREG->SUCC1_UN.SUCC1_ST.wucs_B1 = 1;
1128 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
1135 Std_ReturnType Fr_GetPOCStatus(uint8_t Fr_CtrlIdx, Fr_POCStatusType* Fr_POCStatusPtr) {
1136 #ifdef DET_ACTIVATED
1137 if (Fr_CtrlIdx != 0) {
1140 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1143 if (Fr_POCStatusPtr == NULL) {
1147 /* Slot mode detection */
1148 switch (frayREG->CCSV_UN.CCSV_ST.slm_B2) {
1149 case 0x0: /* SINGLE */
1150 Fr_POCStatusPtr->SlotMode = FR_SLOTMODE_KEYSLOT;
1152 case 0x2: /* ALL PENDING */
1153 Fr_POCStatusPtr->SlotMode = FR_SLOTMODE_ALL_PENDING;
1156 Fr_POCStatusPtr->SlotMode = FR_SLOTMODE_ALL;
1161 /* Freeze request detection */
1162 Fr_POCStatusPtr->Freeze = (frayREG->CCSV_UN.CCSV_ST.fsi_B1 == 1) ? TRUE : FALSE;
1163 /* Halt request detection */
1164 Fr_POCStatusPtr->CHIHaltRequest = (frayREG->CCSV_UN.CCSV_ST.hrq_B1 == 1) ? TRUE : FALSE;
1165 /* Coldstart noise detection */
1166 Fr_POCStatusPtr->ColdstartNoise = (frayREG->CCSV_UN.CCSV_ST.csni_B1 == 1) ? TRUE : FALSE;
1167 /* Coldstart noise detection */
1168 Fr_POCStatusPtr->ColdstartNoise = (frayREG->CCSV_UN.CCSV_ST.csni_B1 == 1) ? TRUE : FALSE;
1169 /* Error mode detection */
1170 switch (frayREG->CCEV_UN.CCEV_ST.errm_B2) {
1171 case 0x0: /* ACTIVE */
1172 Fr_POCStatusPtr->ErrorMode = FR_ERRORMODE_ACTIVE;
1174 case 0x1: /* PASSIVE */
1175 Fr_POCStatusPtr->ErrorMode = FR_ERRORMODE_PASSIVE;
1177 case 0x2: /* COMM_HALT */
1178 Fr_POCStatusPtr->ErrorMode = FR_ERRORMODE_COMM_HALT;
1183 /* POC state detection */
1184 switch (frayREG->CCSV_UN.CCSV_ST.pocs_B6) {
1185 case FR_POCS_ABORT_STARTUP:
1186 case FR_POCS_COLDSTART_COLLISION_RESOLUTION:
1187 case FR_POCS_COLDSTART_CONSISTENCY_CHECK:
1188 case FR_POCS_COLDSTART_GAP:
1189 case FR_POCS_COLDSTART_JOIN:
1190 case FR_POCS_COLDSTART_LISTEN:
1191 case FR_POCS_INITIALIZE_SCHEDULE:
1192 case FR_POCS_INTEGRATION_COLDSTART_CHECK:
1193 case FR_POCS_INTEGRATION_CONSISTENCY_CHECK:
1194 case FR_POCS_INTEGRATION_LISTEN:
1195 case FR_POCS_STARTUP_PREPARE:
1196 Fr_POCStatusPtr->State = FR_POCSTATE_STARTUP;
1198 case FR_POCS_CONFIG:
1199 Fr_POCStatusPtr->State = FR_POCSTATE_CONFIG;
1201 case FR_POCS_DEFAULT_CONFIG:
1202 Fr_POCStatusPtr->State = FR_POCSTATE_DEFAULT_CONFIG;
1205 Fr_POCStatusPtr->State = FR_POCSTATE_HALT;
1207 case FR_POCS_LOOPBACK:
1208 Fr_POCStatusPtr->State = FR_POCSTATE_LOOPBACK;
1210 case FR_POCS_MONITOR_MODE:
1211 Fr_POCStatusPtr->State = FR_POCSTATE_MONITOR;
1213 case FR_POCS_NORMAL_ACTIVE:
1214 Fr_POCStatusPtr->State = FR_POCSTATE_NORMAL_ACTIVE;
1216 case FR_POCS_NORMAL_PASSIVE:
1217 Fr_POCStatusPtr->State = FR_POCSTATE_NORMAL_PASSIVE;
1220 Fr_POCStatusPtr->State = FR_POCSTATE_READY;
1222 case FR_POCS_WAKEUP_DETECT:
1223 case FR_POCS_WAKEUP_LISTEN:
1224 case FR_POCS_WAKEUP_SEND:
1225 case FR_POCS_WAKEUP_STANDBY:
1226 Fr_POCStatusPtr->State = FR_POCSTATE_WAKEUP;
1231 /* Wakeup substate detection */
1232 switch (frayREG->CCSV_UN.CCSV_ST.wsv_B3) {
1233 case FR_WSV_COLLISION_HEADER:
1234 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_COLLISION_HEADER;
1236 case FR_WSV_COLLISION_UNKNOWN:
1237 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_COLLISION_UNKNOWN;
1239 case FR_WSV_COLLISION_WUP:
1240 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_COLLISION_WUP;
1242 case FR_WSV_RECEIVED_HEADER:
1243 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_RECEIVED_HEADER;
1245 case FR_WSV_RECEIVED_WUP:
1246 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_RECEIVED_WUP;
1248 case FR_WSV_TRANSMITTED:
1249 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_TRANSMITTED;
1251 case FR_WSV_UNDEFINED:
1252 Fr_POCStatusPtr->WakeupStatus = FR_WAKEUP_UNDEFINED;
1257 /* Startup substate detection */
1258 switch (frayREG->CCSV_UN.CCSV_ST.pocs_B6) {
1259 case FR_POCS_ABORT_STARTUP:
1260 Fr_POCStatusPtr->StartupState = FR_STARTUP_ABORT;
1262 case FR_POCS_COLDSTART_COLLISION_RESOLUTION:
1263 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_COLLISION_RESOLUTION;
1265 case FR_POCS_COLDSTART_CONSISTENCY_CHECK:
1266 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_CONSISTENCY_CHECK;
1268 case FR_POCS_COLDSTART_GAP:
1269 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_GAP;
1271 case FR_POCS_COLDSTART_JOIN:
1272 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_JOIN;
1274 case FR_POCS_COLDSTART_LISTEN:
1275 Fr_POCStatusPtr->StartupState = FR_STARTUP_COLDSTART_LISTEN;
1277 case FR_POCS_INITIALIZE_SCHEDULE:
1278 Fr_POCStatusPtr->StartupState = FR_STARTUP_INITIALIZE_SCHEDULE;
1280 case FR_POCS_INTEGRATION_COLDSTART_CHECK:
1281 Fr_POCStatusPtr->StartupState = FR_STARTUP_INTEGRATION_COLDSTART_CHECK;
1283 case FR_POCS_INTEGRATION_CONSISTENCY_CHECK:
1284 Fr_POCStatusPtr->StartupState = FR_STARTUP_INTEGRATION_CONSISTENCY_CHECK;
1286 case FR_POCS_INTEGRATION_LISTEN:
1287 Fr_POCStatusPtr->StartupState = FR_STARTUP_INTEGRATION_LISTEN;
1289 case FR_POCS_STARTUP_PREPARE:
1290 Fr_POCStatusPtr->StartupState = FR_STARTUP_PREPARE;
1293 Fr_POCStatusPtr->StartupState = FR_STARTUP_UNDEFINED;
1299 Std_ReturnType Fr_TransmitTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, const uint8_t* Fr_LSduPtr, uint8_t Fr_LSduLength) {
1300 uint32_t byte, word, buffer, index, bufferIndex;
1301 #ifdef DET_ACTIVATED
1302 if (Fr_CtrlIdx != 0) {
1305 if (Fr_LPduIdx > cSlotIDMax) {
1308 if (Fr_LSduPtr == NULL) {
1311 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1316 /* Find the index of the buffer in configuration data array */
1317 for (bufferIndex = 0; bufferIndex < FR_MAX_BUFFERS_CNT; bufferIndex++) {
1318 if (Fr_BuffersPtrs[bufferIndex]->slotId == Fr_LPduIdx) {
1319 if (Fr_BuffersConfigured[bufferIndex] == TRUE && Fr_BuffersPtrs[bufferIndex]->isTx == TRUE) { // Buffer was configured already and is TX
1320 memset((void *)frayREG->WRDS, 0, sizeof(frayREG->WRDS));
1321 for (word = 0; word < (Fr_LSduLength+3)/4; word++) {
1323 for (byte = 0; byte < 4; byte++) {
1324 index = word*4+byte;
1325 if (index < Fr_LSduLength) {
1326 buffer |= Fr_LSduPtr[index] << byte*8;
1329 frayREG->WRDS[word] = buffer;
1331 Fr_buffer_transmit_data(bufferIndex);
1339 Std_ReturnType Fr_CancelTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
1342 #ifdef DET_ACTIVATED
1343 boolean_t canceled = FALSE;
1344 if (Fr_CtrlIdx != 0) {
1347 if (Fr_LPduIdx > cSlotIDMax) {
1350 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1353 if (Fr_Config->msgRAMConfig->secureBuffers != FR_SB_RECONFIG_ENABLED) {
1358 /* If bit IBCM.STXR in the input buffer command mask register is set (STXR = 1), the transmission request
1359 * flag TXR of the selected message buffer is automatically set after the message buffer has been updated.
1360 * If bit IBCM.STXR in the input buffer command mask register is reset (STXR = 0), the transmission request
1361 * flag TXR of the selected message buffer is reset. This can be used to stop transmission from message
1362 * buffers operated in continuous mode.
1366 * Write the same configuration into buffer headers with TXREQ disabled.
1369 for (i = 0; i < FR_MAX_BUFFERS_CNT; i++) {
1370 if (Fr_BuffersPtrs[i]->slotId == Fr_LPduIdx) { // Next occurence of the frame ID found, index retreived into i.
1371 if (Fr_BuffersConfigured[i] == TRUE) { // Buffer was already configured
1373 if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE ||
1374 Fr_Config->nodeConfiguration->pSingleSlotEnabled == TRUE
1376 continue; // The first buffer is used for synchronization and can not be reconfigured.
1381 if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE &&
1382 Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled == TRUE) {
1383 continue; // Sync frame payload multiplexing is enabled and the second buffer is used for synchronization and can not be reconfigured.
1386 mode = (Fr_BuffersPtrs[i]->singleTransmit == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
1387 mode |= (Fr_BuffersPtrs[i]->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
1388 mode |= (Fr_BuffersPtrs[i]->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
1389 mode |= (Fr_BuffersPtrs[i]->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
1390 mode |= (Fr_BuffersPtrs[i]->channel == FR_CHANNEL_A || Fr_BuffersPtrs[i]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
1391 mode |= (Fr_BuffersPtrs[i]->channel == FR_CHANNEL_B || Fr_BuffersPtrs[i]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
1392 mode |= (Fr_BuffersPtrs[i]->rejectNullFrames == TRUE) ? FRAY_BUF_REJECT_NULL_FRAMES : FRAY_BUF_ACCEPT_NULL_FRAMES;
1393 mode |= (Fr_BuffersPtrs[i]->rejectStaticSegment == TRUE) ? FRAY_BUF_REJECT_STATIC_SEGMENT : FRAY_BUF_ACCEPT_STATIC_SEGMENT;
1394 mode |= FRAY_BUF_TXREQ_DIS;
1395 if (Fr_BuffersPtrs[i]->isTx == TRUE) {
1396 Fr_config_buffer(i, mode, Fr_BuffersPtrs[i]->cycleCounterFiltering, Fr_BuffersPtrs[i]->slotId, Fr_BuffersPtrs[i]->maxPayload, Fr_MsgRAMDataPtrs[i]);
1397 #ifdef DET_ACTIVATED
1405 #ifdef DET_ACTIVATED
1406 return (canceled == TRUE) ? E_OK : E_NOT_OK;
1412 Std_ReturnType Fr_ReceiveRxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, uint8_t* Fr_LSduPtr, Fr_RxLPduStatusType* Fr_LPduStatusPtr, uint8_t* Fr_LSduLengthPtr) {
1413 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};
1414 uint32_t bufferIndex;
1416 #ifdef DET_ACTIVATED
1417 if (Fr_CtrlIdx != 0) {
1420 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1423 if (Fr_LPduIdx > cSlotIDMax) {
1426 if (Fr_LSduPtr == NULL) {
1429 if (Fr_LPduStatusPtr == NULL) {
1432 if (Fr_LSduLengthPtr == NULL) {
1436 /* Find the index of the buffer in configuration data array */
1437 *Fr_LSduLengthPtr = 0;
1438 *Fr_LPduStatusPtr = FR_NOT_RECEIVED;
1439 for (bufferIndex = 0; bufferIndex < FR_MAX_BUFFERS_CNT; bufferIndex++) {
1440 if (Fr_BuffersPtrs[bufferIndex]->slotId == Fr_LPduIdx) {
1441 if (Fr_BuffersConfigured[bufferIndex] == TRUE) { // Buffer was configured already
1443 * Determine if buffer is FIFO or standard static or dynamic buffer.
1445 * - Pop data and header into an output buffer.
1446 * - Detect if more data is available in the FIFO and set Fr_LPduStatusPtr.
1447 * - Store loaded payload from header of the output buffer.
1448 * - Copy data from the output buffer to the Fr_LSduPtr address.
1450 * - Check New Data flag, if no new data received, return.
1451 * - Load received data and header into the output buffer.
1452 * - Store loaded payload from header of the output buffer.
1453 * - Copy data from the output buffer to the Fr_LSduPtr address.
1455 // FIXME: Receiving for FID rejection filter other than zero is not working. Why?
1456 if (bufferIndex >= frayREG->MRC_UN.MRC_ST.ffb_B8 && frayREG->FSR_UN.FSR_ST.rfne_B1 == 1) { // This is RX FIFO buffer and it is not empty
1457 Fr_buffer_receive_data_header(frayREG->MRC_UN.MRC_ST.ffb_B8); // Consume first element from FIFO
1458 if (frayREG->FSR_UN.FSR_ST.rfne_B1 == 1) { // FIFO not empty after last pop
1459 *Fr_LPduStatusPtr = FR_RECEIVED_MORE_DATA_AVAILABLE;
1461 else { // FIFO empty after last pop
1462 *Fr_LPduStatusPtr = FR_RECEIVED;
1465 else { // Static/dynamic segment buffer
1466 if (*ndat[bufferIndex/32] & (0x1 << bufferIndex%32)) { // New data received
1467 Fr_buffer_receive_data_header(bufferIndex); // Read data and header into output buffer
1468 *Fr_LPduStatusPtr = FR_RECEIVED;
1470 else { // No new data received
1475 * Copy data from output register into address from parameter Fr_LSduPtr.
1476 * Data in the output register are 32b words,
1477 * Data in Fr_LSduPtr are 8b words.
1479 *Fr_LSduLengthPtr = frayREG->RDHS2_UN.RDHS2_ST.plr_B7*2; // Number of bytes copied into Fr_LSduPtr
1480 for (halfWord = 0; halfWord < frayREG->RDHS2_UN.RDHS2_ST.plr_B7; halfWord++) {
1481 if (halfWord%2 == 0) {
1482 Fr_LSduPtr[halfWord*2] = frayREG->RDDS[halfWord/2] & 0xFF;
1483 Fr_LSduPtr[halfWord*2+1] = (frayREG->RDDS[halfWord/2] & 0xFF00) >> 8;
1486 Fr_LSduPtr[halfWord*2] = (frayREG->RDDS[halfWord/2] & 0xFF0000) >> 16;
1487 Fr_LSduPtr[halfWord*2+1] = (frayREG->RDDS[halfWord/2] & 0xFF000000) >> 24;
1492 else { // Accessing buffer which was not yet configured.
1497 return E_NOT_OK; // No buffer with Fr_LPduIdx was found.
1500 Std_ReturnType Fr_CheckTxLPduStatus(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, Fr_TxLPduStatusType* Fr_TxLPduStatusPtr) {
1501 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};
1502 uint8_t bufferIndex;
1503 #ifdef DET_ACTIVATED
1504 if (Fr_CtrlIdx != 0) {
1507 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1510 if (Fr_LPduIdx > cSlotIDMax) {
1513 if (Fr_TxLPduStatusPtr == NULL) {
1517 for (bufferIndex = 0; bufferIndex < FR_MAX_BUFFERS_CNT; bufferIndex++) {
1518 if (Fr_BuffersPtrs[bufferIndex]->slotId == Fr_LPduIdx) {
1519 if (Fr_BuffersConfigured[bufferIndex] == TRUE) { // Buffer was configured already
1520 if (Fr_BuffersPtrs[bufferIndex]->isTx == TRUE) {
1521 if (*txrq[bufferIndex/32] & (0x1 << bufferIndex%32)) { // Transmit request is pending
1522 *Fr_TxLPduStatusPtr = FR_NOT_TRANSMITTED;
1525 *Fr_TxLPduStatusPtr = FR_TRANSMITTED;
1535 Std_ReturnType Fr_PrepareLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
1539 #ifdef DET_ACTIVATED
1540 if (Fr_CtrlIdx != 0) {
1543 if (Fr_DrvState != FR_ST_DRV_INITIALIZED) {
1546 if (Fr_LPduIdx > cSlotIDMax) {
1550 /* Find the index of the buffer in configuration data array */
1551 for (i = 0; i < FR_MAX_BUFFERS_CNT; i++) {
1552 if (Fr_BuffersPtrs[i]->slotId == Fr_LPduIdx) { // Next occurrence of the frame ID found, index retrieved into i.
1553 if (Fr_BuffersConfigured[i] == FALSE) { // Buffer was not yet configured
1554 mode = (Fr_BuffersPtrs[i]->msgBufferInterrupt == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
1555 mode |= (Fr_BuffersPtrs[i]->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
1556 mode |= (Fr_BuffersPtrs[i]->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
1557 mode |= (Fr_BuffersPtrs[i]->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
1558 mode |= (Fr_BuffersPtrs[i]->channel == FR_CHANNEL_A || Fr_BuffersPtrs[i]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
1559 mode |= (Fr_BuffersPtrs[i]->channel == FR_CHANNEL_B || Fr_BuffersPtrs[i]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
1560 mode |= (Fr_BuffersPtrs[i]->rejectNullFrames == TRUE) ? FRAY_BUF_REJECT_NULL_FRAMES : FRAY_BUF_ACCEPT_NULL_FRAMES;
1561 mode |= (Fr_BuffersPtrs[i]->rejectStaticSegment == TRUE) ? FRAY_BUF_REJECT_STATIC_SEGMENT : FRAY_BUF_ACCEPT_STATIC_SEGMENT;
1562 mode |= FRAY_BUF_TXREQ_DIS;
1563 if (i == 0 || (i == 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.
1564 if (Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSTARTUP] == 1) {
1565 mode |= FRAY_BUF_SFI_EN;
1567 if (Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSYNC] == 1) {
1568 mode |= FRAY_BUF_SYNC_EN;
1571 Fr_MsgRAMDataPtrs[i] = Fr_MsgRAMDataOffset;
1572 if (i >= frayREG->MRC_UN.MRC_ST.ffb_B8) { // This is RX FIFO buffer
1573 Fr_configure_fifo_buffer(i, mode, Fr_BuffersPtrs[i]->cycleCounterFiltering, Fr_BuffersPtrs[i]->slotId, Fr_BuffersPtrs[i]->maxPayload, Fr_MsgRAMDataPtrs[i]);
1575 else { // Static/dynamic segment buffer
1576 Fr_config_buffer(i, mode, Fr_BuffersPtrs[i]->cycleCounterFiltering, Fr_BuffersPtrs[i]->slotId, Fr_BuffersPtrs[i]->maxPayload, Fr_MsgRAMDataPtrs[i]);
1579 * Calculate new address.
1580 * Payload contains the number of two-bytes words, Fr_MsgRAMDataPtrs contains addresses of 4B words in message RAM, all msgRAM addresses have
1582 * Offset has to be divided by two each time because payload is in 2B words and msgRAM addresses are in 4B words.
1584 Fr_MsgRAMDataOffset += ((Fr_BuffersPtrs[i]->maxPayload)%2U == 0U ? (Fr_BuffersPtrs[i]->maxPayload) : ((Fr_BuffersPtrs[i]->maxPayload)+1U))/2;
1585 Fr_BuffersConfigured[i] = TRUE;
1592 Std_ReturnType Fr_ReconfigLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, uint16_t Fr_FrameId, Fr_ChannelType Fr_ChnlIdx, uint8_t Fr_CycleFiltering, uint8_t Fr_PayloadLength) {
1593 uint32_t bufferIndex;
1594 uint8_t lowest_index = 0;
1595 uint8_t highest_index = frayREG->MRC_UN.MRC_ST.ffb_B8;
1598 #ifdef DET_ACTIVATED
1599 boolean_t reconfigured = FALSE;
1600 if (Fr_CtrlIdx != 0) {
1603 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1607 if (Fr_Config->msgRAMConfig->secureBuffers == FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED) {
1608 lowest_index = frayREG->MRC_UN.MRC_ST.fdb_B8;
1610 else if (Fr_Config->msgRAMConfig->secureBuffers == FR_SB_RECONFIG_ENABLED) {
1611 if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync) {
1612 if (Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled) {
1624 return E_NOT_OK | ERR_PARAM_RECONFIG_NOT_ALLOWED;
1627 if (Fr_FrameId == 0) {
1628 return E_NOT_OK | ERR_PARAM_INVALID_FRAME_ID;
1630 if (Fr_FrameId > Fr_Config->clusterConfiguration->gNumberOfStaticSlots &&
1631 Fr_ChnlIdx == FR_CHANNEL_AB) {
1632 return E_NOT_OK | ERR_PARAM_INVALID_CHANNEL;
1635 for (bufferIndex = lowest_index; bufferIndex < highest_index; bufferIndex++) {
1636 if (Fr_BuffersPtrs[bufferIndex]->slotId == Fr_LPduIdx) {
1637 if (Fr_BuffersConfigured[bufferIndex] == TRUE) { // Buffer was configured already
1638 if (Fr_PayloadLength > Fr_BuffersPtrs[bufferIndex]->maxPayload) {
1639 return E_NOT_OK | ERR_PARAM_PAYLOAD_TOO_BIG;
1641 Fr_BuffersPtrs[bufferIndex]->channel = Fr_ChnlIdx;
1642 Fr_BuffersPtrs[bufferIndex]->cycleCounterFiltering = Fr_CycleFiltering;
1643 Fr_BuffersPtrs[bufferIndex]->maxPayload = Fr_PayloadLength;
1644 Fr_BuffersPtrs[bufferIndex]->slotId = Fr_FrameId;
1645 mode = (Fr_BuffersPtrs[bufferIndex]->msgBufferInterrupt == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
1646 mode |= (Fr_BuffersPtrs[bufferIndex]->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
1647 mode |= (Fr_BuffersPtrs[bufferIndex]->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
1648 mode |= (Fr_BuffersPtrs[bufferIndex]->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
1649 mode |= (Fr_BuffersPtrs[bufferIndex]->channel == FR_CHANNEL_A || Fr_BuffersPtrs[bufferIndex]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
1650 mode |= (Fr_BuffersPtrs[bufferIndex]->channel == FR_CHANNEL_B || Fr_BuffersPtrs[bufferIndex]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
1651 mode |= FRAY_BUF_TXREQ_DIS;
1652 Fr_config_buffer(bufferIndex, mode, Fr_BuffersPtrs[bufferIndex]->cycleCounterFiltering, Fr_BuffersPtrs[bufferIndex]->slotId, Fr_BuffersPtrs[bufferIndex]->maxPayload, Fr_MsgRAMDataPtrs[bufferIndex]);
1653 #ifdef DET_ACTIVATED
1654 reconfigured = TRUE;
1661 /* TODO: Implement */
1662 #ifdef DET_ACTIVATED
1663 if (reconfigured == FALSE)
1664 return E_NOT_OK | ERR_PARAM_NO_BUFFER_FOUND;
1669 Std_ReturnType Fr_DisableLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
1670 uint8_t bufferIndexLimit;
1673 #ifdef DET_ACTIVATED
1674 boolean_t disabled = FALSE;
1675 if (Fr_CtrlIdx != 0) {
1678 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1681 if (Fr_LPduIdx > cSlotIDMax) {
1684 if (Fr_Config->msgRAMConfig->secureBuffers != FR_SB_RECONFIG_ENABLED) {
1688 /* Determine reconfigurable buffers from the data in MRC.SET bits */
1689 switch (frayREG->MRC_UN.MRC_ST.sec_B2) {
1691 bufferIndexLimit = frayREG->MRC_UN.MRC_ST.ffb_B8;
1694 bufferIndexLimit = frayREG->MRC_UN.MRC_ST.fdb_B8;
1697 return E_OK; // No reconfiguration enabled
1700 /* Find the index of the buffer in configuration data array */
1701 for (i = 0; i < FR_MAX_BUFFERS_CNT; i++) {
1702 if (Fr_BuffersPtrs[i]->slotId == Fr_LPduIdx) { // Next occurrence of the frame ID found, index retrieved into i.
1703 if (Fr_BuffersConfigured[i] == TRUE) { // Buffer was not yet configured
1705 if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE ||
1706 Fr_Config->nodeConfiguration->pSingleSlotEnabled == TRUE
1708 continue; // The first buffer is used for synchronization and can not be reconfigured.
1713 if (Fr_Config->nodeConfiguration->pKeySlotUsedForSync == TRUE &&
1714 Fr_Config->msgRAMConfig->syncFramePayloadMultiplexEnabled == TRUE) {
1715 continue; // Sync frame payload multiplexing is enabled and the second buffer is used for synchronization and can not be reconfigured.
1718 if (i < bufferIndexLimit) { // Buffer is reconfigurable, reset its configuration registers.
1720 Fr_MsgRAMDataPtrs[i] = 0;
1721 Fr_BuffersConfigured[i] = FALSE;
1722 Fr_config_buffer(i, mode, Fr_BuffersPtrs[i]->cycleCounterFiltering, Fr_BuffersPtrs[i]->slotId, Fr_BuffersPtrs[i]->maxPayload, Fr_MsgRAMDataPtrs[i]);
1723 #ifdef DET_ACTIVATED
1730 #ifdef DET_ACTIVATED
1731 return (disabled == TRUE) ? E_OK : E_NOT_OK;
1737 Std_ReturnType Fr_GetGlobalTime(uint8_t Fr_CtrlIdx, uint8_t* Fr_CyclePtr, uint16_t* Fr_MacroTickPtr) {
1738 #ifdef DET_ACTIVATED
1739 if (Fr_CtrlIdx != 0) {
1742 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1745 if (Fr_CyclePtr == NULL) {
1748 if (Fr_MacroTickPtr == NULL) {
1752 uint32_t time = frayREG->MTCCV_UN.MTCCV_UL;
1753 *Fr_CyclePtr = __mfld2val(MTCCV_CCV_MSK, time);
1754 *Fr_MacroTickPtr = __mfld2val(MTCCV_MTV_MSK, time);
1758 static inline uint32_t swap32(uint32_t x)
1760 return (x & 0x000000ff) << 24 |
1761 (x & 0x0000ff00) << 8 |
1762 (x & 0x00ff0000) >> 8 |
1763 (x & 0xff000000) >> 24;
1766 Std_ReturnType Fr_GetNmVector(uint8_t Fr_CtrlIdx, uint8_t* Fr_NmVectorPtr) {
1767 #ifdef DET_ACTIVATED
1768 if (Fr_CtrlIdx != 0) {
1771 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1774 if (Fr_NmVectorPtr == NULL) {
1778 *((uint32_t*)(Fr_NmVectorPtr+0)) = swap32(frayREG->NMV1_UN.NMV1_UL);
1779 *((uint32_t*)(Fr_NmVectorPtr+4)) = swap32(frayREG->NMV2_UN.NMV2_UL);
1780 *((uint32_t*)(Fr_NmVectorPtr+8)) = swap32(frayREG->NMV3_UL);
1784 Std_ReturnType Fr_GetNumOfStartupFrames(uint8_t Fr_CtrlIdx, uint8_t* Fr_NumOfStartupFramesPtr) {
1785 /* TODO: Implement - can not find this information in the datasheet */
1789 Std_ReturnType Fr_GetChannelStatus(uint8_t Fr_CtrlIdx, uint16_t* Fr_ChannelAStatusPtr, uint16_t* Fr_ChannelBStatusPtr) {
1790 #ifdef DET_ACTIVATED
1791 if (Fr_CtrlIdx != 0) {
1794 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1797 if (Fr_ChannelAStatusPtr == NULL) {
1800 if (Fr_ChannelBStatusPtr == NULL) {
1804 *Fr_ChannelAStatusPtr = 0;
1805 *Fr_ChannelBStatusPtr = 0;
1807 *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.vfra_B1;
1808 *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.seda_B1 << 1;
1809 *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.ceda_B1 << 2;
1810 *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.cia_B1 << 3;
1811 *Fr_ChannelAStatusPtr |= frayREG->ACS_UN.ACS_ST.sbva_B1 << 4;
1812 *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.mtsa_B1 << 8;
1813 *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sesa_B1 << 9;
1814 *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbsa_B1 << 10;
1815 *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.tcsa_B1 << 11;
1816 *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sena_B1 << 12;
1817 *Fr_ChannelAStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbna_B1 << 13;
1819 *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.vfrb_B1;
1820 *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.sedb_B1 << 1;
1821 *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.cedb_B1 << 2;
1822 *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.cib_B1 << 3;
1823 *Fr_ChannelBStatusPtr |= frayREG->ACS_UN.ACS_ST.sbvb_B1 << 4;
1824 *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.mtsb_B1 << 8;
1825 *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sesb_B1 << 9;
1826 *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbsb_B1 << 10;
1827 *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.tcsb_B1 << 11;
1828 *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.senb_B1 << 12;
1829 *Fr_ChannelBStatusPtr |= frayREG->SWNIT_UN.SWNIT_ST.sbnb_B1 << 13;
1834 Std_ReturnType Fr_GetClockCorrection(uint8_t Fr_CtrlIdx, int16_t* Fr_RateCorrectionPtr, int32_t* Fr_OffsetCorrectionPtr) {
1835 #ifdef DET_ACTIVATED
1836 if (Fr_CtrlIdx != 0) {
1839 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1842 if (Fr_RateCorrectionPtr == NULL) {
1845 if (Fr_OffsetCorrectionPtr == NULL) {
1849 *Fr_RateCorrectionPtr = frayREG->RCV_UN.RCV_ST.rcv_B12;
1850 *Fr_OffsetCorrectionPtr = frayREG->OCV_UN.OCV_ST.ocv_B14;
1855 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) {
1859 #ifdef DET_ACTIVATED
1860 if (Fr_CtrlIdx != 0) {
1863 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1866 if (Fr_ChannelAEvenListPtr == NULL) {
1869 if (Fr_ChannelBEvenListPtr == NULL) {
1872 if (Fr_ChannelAOddListPtr == NULL) {
1875 if (Fr_ChannelBOddListPtr == NULL) {
1880 if (Fr_ListSize > FR_MAX_SYNC_FRAME_LIST_SIZE) { // Limit list size to 15
1881 Fr_ListSize = FR_MAX_SYNC_FRAME_LIST_SIZE;
1884 for (i = 0; i < Fr_ListSize; i++) {
1885 esid = frayREG->ESID_UL[i];
1886 osid = frayREG->OSID_UL[i];
1888 Fr_ChannelAEvenListPtr[i] = (__mfld2val(ESID_RXEA_MSK, esid) == 1) ? __mfld2val(ESID_EID_MSK, esid) : 0;
1889 Fr_ChannelBEvenListPtr[i] = (__mfld2val(ESID_RXEB_MSK, esid) == 1) ? __mfld2val(ESID_EID_MSK, esid) : 0;
1890 Fr_ChannelAOddListPtr[i] = (__mfld2val(OSID_RXOA_MSK, osid) == 1) ? __mfld2val(OSID_OID_MSK, osid) : 0;
1891 Fr_ChannelBOddListPtr[i] = (__mfld2val(OSID_RXOB_MSK, osid) == 1) ? __mfld2val(OSID_OID_MSK, osid) : 0;
1894 for (i = Fr_ListSize; i < 15; i++) {
1895 Fr_ChannelAEvenListPtr[i] = 0;
1896 Fr_ChannelBEvenListPtr[i] = 0;
1897 Fr_ChannelAOddListPtr[i] = 0;
1898 Fr_ChannelBOddListPtr[i] = 0;
1904 Std_ReturnType Fr_GetWakeupRxStatus(uint8_t Fr_CtrlIdx, uint8_t* Fr_WakeupRxStatusPtr) {
1905 #ifdef DET_ACTIVATED
1906 if (Fr_CtrlIdx != 0) {
1909 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1912 if (Fr_WakeupRxStatusPtr == NULL) {
1917 *Fr_WakeupRxStatusPtr = 0;
1918 *Fr_WakeupRxStatusPtr |= frayREG->SIR_UN.SIR_ST.wupa_B1;
1919 *Fr_WakeupRxStatusPtr |= frayREG->SIR_UN.SIR_ST.wupb_B1 << 1;
1921 frayREG->SIR_UN.SIR_ST.wupa_B1 = 1;
1922 frayREG->SIR_UN.SIR_ST.wupb_B1 = 1;
1926 Std_ReturnType Fr_SetAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, uint8_t Fr_Cycle, uint16_t Fr_Offset) {
1927 #ifdef DET_ACTIVATED
1928 if (Fr_CtrlIdx != 0) {
1931 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1934 if (Fr_AbsTimerIdx > 1) {
1937 if (Fr_Offset > Fr_Config->clusterConfiguration->gMacroPerCycle) {
1940 if (Fr_Cycle & 0x80) {
1944 if (Fr_AbsTimerIdx == 0) {
1945 frayREG->T0C_UN.T0C_ST.t0rc_B1 = 0;
1946 frayREG->T0C_UN.T0C_ST.t0ms_B1 = 1;
1947 frayREG->T0C_UN.T0C_ST.t0cc_B7 = Fr_Cycle;
1948 frayREG->T0C_UN.T0C_ST.t0mo_B14 = Fr_Offset;
1949 frayREG->SIR_UN.SIR_ST.ti0_B1 = 1; // Reset interrupt
1950 frayREG->T0C_UN.T0C_ST.t0rc_B1 = 1;
1952 else if (Fr_AbsTimerIdx == 1) {
1953 frayREG->T1C_UN.T1C_ST.t1rc_B1 = 0;
1954 frayREG->T1C_UN.T1C_ST.t1ms_B1 = 1;
1955 frayREG->T1C_UN.T1C_ST.t1mc_B14 = Fr_Cycle*Fr_Config->clusterConfiguration->gMacroPerCycle+Fr_Offset;
1956 frayREG->SIR_UN.SIR_ST.ti1_B1 = 1;// Reset interrupt
1957 frayREG->T1C_UN.T1C_ST.t1rc_B1 = 1;
1966 Std_ReturnType Fr_CancelAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
1967 #ifdef DET_ACTIVATED
1968 if (Fr_CtrlIdx != 0) {
1971 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1974 if (Fr_AbsTimerIdx > 1) {
1978 if (Fr_AbsTimerIdx == 0) {
1979 frayREG->T0C_UN.T0C_ST.t0rc_B1 = 0;
1981 else if (Fr_AbsTimerIdx == 1) {
1982 frayREG->T1C_UN.T1C_ST.t1rc_B1 = 0;
1990 Std_ReturnType Fr_EnableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
1991 #ifdef DET_ACTIVATED
1992 if (Fr_CtrlIdx != 0) {
1995 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
1998 if (Fr_AbsTimerIdx > 1) {
2002 frayREG->ILE_UN.ILE_ST.eint0_B1 = 1;
2003 if (Fr_AbsTimerIdx == 0) {
2004 frayREG->SIES_UN.SIES_ST.ti0e_B1 = 1;
2006 else if (Fr_AbsTimerIdx == 1) {
2007 frayREG->SIES_UN.SIES_ST.ti0e_B1 = 1;
2015 Std_ReturnType Fr_AckAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
2016 #ifdef DET_ACTIVATED
2017 if (Fr_CtrlIdx != 0) {
2020 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2023 if (Fr_AbsTimerIdx > 1) {
2027 if (Fr_AbsTimerIdx == 0) {
2028 frayREG->SIR_UN.SIR_ST.ti0_B1 = 1;
2030 else if (Fr_AbsTimerIdx == 1) {
2031 frayREG->SIR_UN.SIR_ST.ti1_B1 = 1;
2039 Std_ReturnType Fr_DisableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
2040 #ifdef DET_ACTIVATED
2041 if (Fr_CtrlIdx != 0) {
2044 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2047 if (Fr_AbsTimerIdx > 1) {
2051 if (Fr_AbsTimerIdx == 0) {
2052 frayREG->SIER_UN.SIER_ST.ti0e_B1 = 1;
2054 else if (Fr_AbsTimerIdx == 1) {
2055 frayREG->SIER_UN.SIER_ST.ti0e_B1 = 1;
2063 Std_ReturnType Fr_GetAbsoluteTimerIRQStatus(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, boolean_t* Fr_IRQStatusPtr) {
2064 #ifdef DET_ACTIVATED
2065 if (Fr_CtrlIdx != 0) {
2068 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2071 if (Fr_AbsTimerIdx > 1) {
2074 if (Fr_IRQStatusPtr == NULL) {
2078 if (Fr_AbsTimerIdx == 0) {
2079 *Fr_IRQStatusPtr = (frayREG->SIR_UN.SIR_ST.ti0_B1 == 1) ? TRUE : FALSE;
2081 else if (Fr_AbsTimerIdx == 1) {
2082 *Fr_IRQStatusPtr = (frayREG->SIR_UN.SIR_ST.ti1_B1 == 1) ? TRUE : FALSE;
2090 void Fr_GetVersionInfo(Std_VersionInfoType* VersioninfoPtr) {
2091 #ifdef DET_ACTIVATED
2092 if (VersioninfoPtr == NULL) {
2096 VersioninfoPtr->vendorID = Fr_versionInfo.vendorID;
2097 VersioninfoPtr->moduleID = Fr_versionInfo.moduleID;
2098 VersioninfoPtr->sw_major_version = Fr_versionInfo.sw_major_version;
2099 VersioninfoPtr->sw_minor_version= Fr_versionInfo.sw_minor_version;
2100 VersioninfoPtr->sw_patch_version= Fr_versionInfo.sw_patch_version;
2103 Std_ReturnType Fr_ReadCCConfig( uint8_t Fr_CtrlIdx, uint8_t Fr_ConfigParamIdx, uint32_t* Fr_ConfigParamValuePtr) {
2105 #ifdef DET_ACTIVATED
2106 if (Fr_CtrlIdx != 0) {
2109 if (Fr_ConfigParamIdx >= FR_CIDX_CNT) {
2112 if (Fr_ConfigParamValuePtr == NULL) {
2115 if (Fr_DrvState != FR_ST_CTRL_INITIALIZED) {
2120 *Fr_ConfigParamValuePtr = Fr_ConfigParPtrs[Fr_ConfigParamIdx];
2124 int Fr_spi_transfer(uint8_t port) {
2125 uint32_t commands[2];
2128 if (port > FRAY_NUM_PORTS) return -1;
2129 desc = hal_port_get_dsc(fray_port_names[port], -1);
2130 fray_spi_cmd_sh = fray_spi_cmd;
2131 commands[0] = (fray_spi_cmd_sh & 0xFF00) >> 8;
2132 commands[1] = (fray_spi_cmd_sh & 0xFF);
2134 fray_spi_resp[port] = desc->port_setfnc_ptr(desc->config, desc->numValues, commands);
2138 int Fr_spi_response(uint8_t port) {
2139 if (port > FRAY_NUM_PORTS) return -1;
2140 return fray_spi_resp[port];
2143 int Fr_spi_get_cmd(uint8_t port) {
2144 if (port > FRAY_NUM_PORTS) return -1;
2145 return fray_spi_cmd;