8 #include "drv/fr_tms570.h"
9 #include "sys/ti_drv_fray.h"
13 Std_VersionInfoType Fr_versionInfo = {
14 .vendorID = 0x00000001,
15 .moduleID = 0x00000002,
16 .sw_major_version = 0,
17 .sw_minor_version = 1,
21 const uint32_t* Fr_ConfigParPtrs[FR_CIDX_CNT];
22 const Fr_ConfigType* Fr_Config;
23 const Fr_TMS570LS_BufferConfigType* Fr_BuffersPtrs[FR_MAX_BUFFERS_CNT]; /** < Array of address of configuration data to each buffer. */
24 boolean_t Fr_BuffersConfigured[FR_MAX_BUFFERS_CNT]; /**< Array of flags to determine if the buffer was or was not configured. */
25 int Fr_MsgRAMDataPtrs[FR_MAX_BUFFERS_CNT]; /**< Array of computed data pointers addresses for each buffer. */
26 uint32_t Fr_MsgRAMDataOffset; /**< Address of the next free position in message RAM, which can be assigned to configured buffer. Addresses 32b words. */
27 uint32_t Fr_MsgRAMDataStartAddress; /**< Address of the first free position in message RAM, which can be assigned to the first configured buffer. Addresses 32b words. */
28 Fr_POCStatusType Fr_POCStatus;
30 boolean_t Fr_Initialized = FALSE;
33 /** @fn wait_for_POC_ready(void)
34 * @brief Wait until POC is not busy
36 void Fr_wait_for_POC_ready() {
37 // Wait for PBSY bit to clear - POC not busy.
38 // 1: Signals that the POC is busy and cannot accept a command from the host. CMD(3-0) is locked against write accesses.
39 while(((frayREG->SUCC1_UN.SUCC1_UL) & 0x00000080) != 0);
43 * @brief Switch POC to config state from any other state
45 * After command to switch into config state is passed into CHI,
46 * the response is checked and if POC has reacted on the command,
47 * the function is waiting until POC is ready
49 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
51 Std_ReturnType Fr_POC_go_to_config() {
52 // write SUCC1 configuration
53 frayREG->SUCC1_UN.SUCC1_UL = 0x0F1FFB00 | CMD_CONFIG;
54 // Check if POC has accepted last command
55 if ((frayREG->SUCC1_UN.SUCC1_UL & 0xF) == 0x0)
57 // Wait for PBSY bit to clear - POC not busy
58 Fr_wait_for_POC_ready();
63 * @brief Switch POC to clear_message_ram state from default_config and config state
65 * Send command to POC to set all bits of message RAM to 0. Returns when cleaning is done,
66 * resulting in POC switch to origin state.
68 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
70 Std_ReturnType Fr_POC_go_to_clear_rams() {
71 Fr_wait_for_POC_ready();
72 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_CLEAR_RAMS;
73 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted) {
76 Fr_wait_for_POC_ready();
81 * @brief Switch POC to ready state from config state
83 * After command to switch into ready state is passed into CHI,
84 * the response is checked and if POC has reacted on the command,
85 * the function is waiting until POC is ready
87 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
89 Std_ReturnType Fr_POC_go_to_ready_from_config() {
90 Fr_wait_for_POC_ready();
91 // For CHA and CHB network
92 if (frayREG->SUCC1_UN.SUCC1_ST.ccha_B1 && frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
94 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
95 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
96 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
98 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
99 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
100 frayREG->SUCC1_UN.SUCC1_ST.mtsa_B1 = 1U;
102 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
103 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
104 frayREG->SUCC1_UN.SUCC1_ST.mtsb_B1 = 1U;
107 else if(frayREG->SUCC1_UN.SUCC1_ST.ccha_B1){
109 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
110 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
111 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
113 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
114 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
115 frayREG->SUCC1_UN.SUCC1_ST.mtsa_B1 = 1U;
118 else if (frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
120 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
121 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
122 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
124 frayREG->LCK_UN.LCK_ST.clk_B8 = 0xCE;
125 frayREG->LCK_UN.LCK_ST.clk_B8 = 0x31;
126 frayREG->SUCC1_UN.SUCC1_ST.mtsb_B1 = 1U;
128 else frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
130 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
133 while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01)
134 ; // Waiting for READY state
139 * @brief Switch POC to ready state from startup state
141 * After command to switch into ready state is passed into CHI,
142 * the response is checked and if POC has reacted on the command,
143 * the function is waiting until POC is ready
145 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
147 Std_ReturnType Fr_POC_go_to_ready_from_startup() {
148 Fr_wait_for_POC_ready();
149 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
150 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
152 while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01); // Wait until POC is not in ready state
153 Fr_wait_for_POC_ready();
158 * @brief Switch POC to startup state from ready state
160 * After command to switch into startup state is passed into CHI,
161 * the response is checked and if POC has reacted on the command,
162 * the function is waiting until POC is ready
164 * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
166 Std_ReturnType Fr_POC_go_to_startup() {
167 Fr_wait_for_POC_ready();
168 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_RUN;
169 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
171 Fr_wait_for_POC_ready();
176 * @brief Copy cluster config parameters into FlexRay configuration registers.
178 * This function does not check values ranges. This is a responsibility of higher
179 * layers. Cluster configuration parameters are copied from data structure
180 * into right bit position in configuration registers.
182 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
184 void Fr_config_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr) {
185 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CSA_MSK , frayREG->SUCC1_UN.SUCC1_UL, clusterConfigPtr->gColdStartAttempts);
186 frayREG->GTUC9_UN.GTUC9_UL = __insval2mfld(GTUC9_APO_MSK , frayREG->GTUC9_UN.GTUC9_UL, clusterConfigPtr->gdActionPointOffset);
187 frayREG->PRTC1_UN.PRTC1_UL = __insval2mfld(PRTC1_CASM_MSK, frayREG->PRTC1_UN.PRTC1_UL, clusterConfigPtr->gdCASRxLowMax);
188 frayREG->GTUC9_UN.GTUC9_UL = __insval2mfld(GTUC9_DSI_MSK , frayREG->GTUC9_UN.GTUC9_UL, clusterConfigPtr->gdDynamicSlotIdlePhase);
189 frayREG->GTUC8_UN.GTUC8_UL = __insval2mfld(GTUC8_MSL_MSK , frayREG->GTUC8_UN.GTUC8_UL, clusterConfigPtr->gdMinislot);
190 frayREG->GTUC9_UN.GTUC9_UL = __insval2mfld(GTUC9_MAPO_MSK, frayREG->GTUC9_UN.GTUC9_UL, clusterConfigPtr->gdMinislotActionPointOffset);
191 frayREG->GTUC7_UN.GTUC7_UL = __insval2mfld(GTUC7_SSL_MSK , frayREG->GTUC7_UN.GTUC7_UL, clusterConfigPtr->gdStaticSlot);
192 frayREG->PRTC1_UN.PRTC1_UL = __insval2mfld(PRTC1_TSST_MSK, frayREG->PRTC1_UN.PRTC1_UL, clusterConfigPtr->gdTSSTransmitter);
193 frayREG->PRTC2_UN.PRTC2_UL = __insval2mfld(PRTC2_RXI_MSK , frayREG->PRTC2_UN.PRTC2_UL, clusterConfigPtr->gdWakeupSymbolRxIdle);
194 frayREG->PRTC2_UN.PRTC2_UL = __insval2mfld(PRTC2_RXL_MSK , frayREG->PRTC2_UN.PRTC2_UL, clusterConfigPtr->gdWakeupSymbolRxLow);
195 frayREG->PRTC1_UN.PRTC1_UL = __insval2mfld(PRTC1_RXW_MSK , frayREG->PRTC1_UN.PRTC1_UL, clusterConfigPtr->gdWakeupSymbolRxWindow);
196 frayREG->PRTC2_UN.PRTC2_UL = __insval2mfld(PRTC2_TXI_MSK , frayREG->PRTC2_UN.PRTC2_UL, clusterConfigPtr->gdWakeupSymbolTxIdle);
197 frayREG->PRTC2_UN.PRTC2_UL = __insval2mfld(PRTC2_TXL_MSK , frayREG->PRTC2_UN.PRTC2_UL, clusterConfigPtr->gdWakeupSymbolTxLow);
198 frayREG->SUCC2_UN.SUCC2_UL = __insval2mfld(SUCC2_LTN_MSK , frayREG->SUCC2_UN.SUCC2_UL, clusterConfigPtr->gListenNoise);
199 frayREG->GTUC2_UN.GTUC2_UL = __insval2mfld(GTUC2_MPC_MSK , frayREG->GTUC2_UN.GTUC2_UL, clusterConfigPtr->gMacroPerCycle);
200 frayREG->SUCC3_UN.SUCC3_UL = __insval2mfld(SUCC3_WCF_MSK , frayREG->SUCC3_UN.SUCC3_UL, clusterConfigPtr->gMaxWithoutClockCorrectionFatal);
201 frayREG->SUCC3_UN.SUCC3_UL = __insval2mfld(SUCC3_WCP_MSK , frayREG->SUCC3_UN.SUCC3_UL, clusterConfigPtr->gMaxWithoutClockCorrectionPassive);
202 frayREG->GTUC8_UN.GTUC8_UL = __insval2mfld(GTUC8_NMS_MSK , frayREG->GTUC8_UN.GTUC8_UL, clusterConfigPtr->gNumberOfMinislots);
203 frayREG->GTUC7_UN.GTUC7_UL = __insval2mfld(GTUC7_NSS_MSK , frayREG->GTUC7_UN.GTUC7_UL, clusterConfigPtr->gNumberOfStaticSlots);
204 frayREG->GTUC4_UN.GTUC4_UL = __insval2mfld(GTUC4_OCS_MSK , frayREG->GTUC4_UN.GTUC4_UL, clusterConfigPtr->gOffsetCorrectionStart);
205 frayREG->MHDC_UN.MHDC_UL = __insval2mfld(MHDC_SFDL_MSK , frayREG->MHDC_UN.MHDC_UL , clusterConfigPtr->gPayloadLengthStatic);
206 frayREG->GTUC2_UN.GTUC2_UL = __insval2mfld(GTUC2_SNM_MSK , frayREG->GTUC2_UN.GTUC2_UL, clusterConfigPtr->gSyncNodeMax);
208 frayREG->GTUC4_UN.GTUC4_UL = __insval2mfld(GTUC4_NIT_MSK , frayREG->GTUC4_UN.GTUC4_UL, clusterConfigPtr->gdNIT);
209 frayREG->PRTC1_UN.PRTC1_UL = __insval2mfld(PRTC1_BRP_MSK , frayREG->PRTC1_UN.PRTC1_UL, clusterConfigPtr->gdSampleClockPeriod);
210 frayREG->NEMC_UN.NEMC_UL = __insval2mfld(NEMC_NML_MSK , frayREG->NEMC_UN.NEMC_UL , clusterConfigPtr->gNetworkManagementVectorLength);
213 #define __notInRange(val, min, max) (((val) < (min)) || ((val) > (max)))
216 * @brief Check cluster configuration parameters.
218 * This function checks values of the cluster configuration parameters,
219 * if they are in ranges noted in FlexRay specification.
221 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
222 * @param [out] errCode Address where error flags will be stored.
223 * We have 26 parameters to check. Every one of them has assigned its bit in this flag.
224 * Error flags are defined as macros ERR_PARAM_nameOfParameter.
225 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
227 Std_ReturnType Fr_check_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr, uint32_t* errCode) {
228 *errCode = ERR_PARAM_NO_ERROR;
230 if (__notInRange(clusterConfigPtr->gColdStartAttempts, 2, 31)) *errCode |= ERR_PARAM_gColdStartAttempts;
231 if (__notInRange(clusterConfigPtr->gdActionPointOffset, 1, 63)) *errCode |= ERR_PARAM_gdActionPointOffset;
232 if (__notInRange(clusterConfigPtr->gdCASRxLowMax, 67, 99)) *errCode |= ERR_PARAM_gdCASRxLowMax;
233 if (clusterConfigPtr->gdDynamicSlotIdlePhase > 2) *errCode |= ERR_PARAM_gdDynamicSlotIdlePhase;
234 if (__notInRange(clusterConfigPtr->gdMinislot, 2, 63)) *errCode |= ERR_PARAM_gdMinislot;
235 if (__notInRange(clusterConfigPtr->gdMinislotActionPointOffset,
236 1, 31)) *errCode |= ERR_PARAM_gdMinislotActionPointOffset;
237 if (__notInRange(clusterConfigPtr->gdStaticSlot, 4, 661)) *errCode |= ERR_PARAM_gdStaticSlot;
238 if (__notInRange(clusterConfigPtr->gdTSSTransmitter, 3, 15)) *errCode |= ERR_PARAM_gdTSSTransmitter;
239 if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxIdle, 14, 59)) *errCode |= ERR_PARAM_gdWakeupSymbolRxIdle;
240 if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxLow, 11, 59)) *errCode |= ERR_PARAM_gdWakeupSymbolRxLow;
241 if (__notInRange(clusterConfigPtr->gdWakeupSymbolRxWindow,
242 76, 301)) *errCode |= ERR_PARAM_gdWakeupSymbolRxWindow;
243 if (__notInRange(clusterConfigPtr->gdWakeupSymbolTxIdle, 45, 180)) *errCode |= ERR_PARAM_gdWakeupSymbolTxIdle;
244 if (__notInRange(clusterConfigPtr->gdWakeupSymbolTxLow, 15, 60)) *errCode |= ERR_PARAM_gdWakeupSymbolTxLow;
245 if (__notInRange(clusterConfigPtr->gListenNoise, 2, 16)) *errCode |= ERR_PARAM_gListenNoise;
246 if (__notInRange(clusterConfigPtr->gMacroPerCycle, 10, 16000)) *errCode |= ERR_PARAM_gMacroPerCycle;
247 if (__notInRange(clusterConfigPtr->gMaxWithoutClockCorrectionFatal,
248 clusterConfigPtr->gMaxWithoutClockCorrectionPassive, 15)) *errCode |= ERR_PARAM_gMaxWithoutClockCorrectionFatal;
249 if (__notInRange(clusterConfigPtr->gMaxWithoutClockCorrectionPassive,
250 1, 15)) *errCode |= ERR_PARAM_gMaxWithoutClockCorrectionPassive;
251 if (clusterConfigPtr->gNumberOfMinislots > 7986) *errCode |= ERR_PARAM_gNumberOfMinislots;
252 if (__notInRange(clusterConfigPtr->gNumberOfStaticSlots,
253 2, cStaticSlotIDMax)) *errCode |= ERR_PARAM_gNumberOfStaticSlots;
254 if (__notInRange(clusterConfigPtr->gOffsetCorrectionStart,
255 9, 15999)) *errCode |= ERR_PARAM_gOffsetCorrectionStart;
256 if (clusterConfigPtr->gPayloadLengthStatic > cPayloadLengthMax) *errCode |= ERR_PARAM_gPayloadLengthStatic;
257 if (__notInRange(clusterConfigPtr->gSyncNodeMax, 2, cSyncNodeMax)) *errCode |= ERR_PARAM_gSyncNodeMax;
258 if (__notInRange(clusterConfigPtr->gdNIT, 2, 805)) *errCode |= ERR_PARAM_gdNIT;
259 if (clusterConfigPtr->gdSampleClockPeriod > 2) *errCode |= ERR_PARAM_gdSampleClockPeriod;
260 if (clusterConfigPtr->gNetworkManagementVectorLength > 12) *errCode |= ERR_PARAM_gNetworkManagementVectorLength;
262 return (*errCode == 0) ? E_OK : E_NOT_OK;
266 * @brief Copy node config parameters into FlexRay configuration registers.
268 * This function does not check values ranges. This is a responsibility of higher
269 * layers. Node configuration parameters are copied from data structure
270 * into right bit position in configuration registers.
272 * @param [in] nodeConfigPtr Address of structure with node configuration parameters
274 void Fr_config_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr) {
275 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_HCSE_MSK, frayREG->SUCC1_UN.SUCC1_UL, nodeConfigPtr->pAllowHaltDueToClock);
276 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_PTA_MSK, frayREG->SUCC1_UN.SUCC1_UL, nodeConfigPtr->pAllowPassiveToActive);
277 if (nodeConfigPtr->pChannels == FR_CHANNEL_AB) {
278 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CCHA_MSK, frayREG->SUCC1_UN.SUCC1_UL, 1);
279 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CCHB_MSK, frayREG->SUCC1_UN.SUCC1_UL, 1);
282 else if (nodeConfigPtr->pChannels == FR_CHANNEL_A) {
283 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CCHA_MSK, frayREG->SUCC1_UN.SUCC1_UL, 1);
284 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CCHB_MSK, frayREG->SUCC1_UN.SUCC1_UL, 0);
287 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CCHA_MSK, frayREG->SUCC1_UN.SUCC1_UL, 0);
288 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_CCHB_MSK, frayREG->SUCC1_UN.SUCC1_UL, 1);
290 frayREG->GTUC6_UN.GTUC6_UL = __insval2mfld(GTUC6_ASR_MSK , frayREG->GTUC6_UN.GTUC6_UL , nodeConfigPtr->pdAcceptedStartupRange);
291 frayREG->GTUC5_UN.GTUC5_UL = __insval2mfld(GTUC5_CDD_MSK , frayREG->GTUC5_UN.GTUC5_UL , nodeConfigPtr->pClusterDriftDamping);
292 frayREG->GTUC5_UN.GTUC5_UL = __insval2mfld(GTUC5_DCA_MSK , frayREG->GTUC5_UN.GTUC5_UL , nodeConfigPtr->pDelayCompensationA);
293 frayREG->GTUC5_UN.GTUC5_UL = __insval2mfld(GTUC5_DCB_MSK , frayREG->GTUC5_UN.GTUC5_UL , nodeConfigPtr->pDelayCompensationB);
294 frayREG->SUCC2_UN.SUCC2_UL = __insval2mfld(SUCC2_LT_MSK , frayREG->SUCC2_UN.SUCC2_UL , nodeConfigPtr->pdListenTimeout);
295 frayREG->GTUC6_UN.GTUC6_UL = __insval2mfld(GTUC6_MOD_MSK , frayREG->GTUC6_UN.GTUC6_UL , nodeConfigPtr->pdMaxDrift);
296 frayREG->GTUC11_UN.GTUC11_UL = __insval2mfld(GTUC11_EOC_MSK, frayREG->GTUC11_UN.GTUC11_UL, nodeConfigPtr->pExternOffsetCorrection);
297 frayREG->GTUC11_UN.GTUC11_UL = __insval2mfld(GTUC11_ERC_MSK, frayREG->GTUC11_UN.GTUC11_UL, nodeConfigPtr->pExternRateCorrection);
298 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_TXST_MSK, frayREG->SUCC1_UN.SUCC1_UL , nodeConfigPtr->pKeySlotUsedForStartup);
299 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_TXSY_MSK, frayREG->SUCC1_UN.SUCC1_UL , nodeConfigPtr->pKeySlotUsedForSync);
300 frayREG->MHDC_UN.MHDC_UL = __insval2mfld(MHDC_SLT_MSK , frayREG->MHDC_UN.MHDC_UL , nodeConfigPtr->pLatestTx);
301 frayREG->GTUC3_UN.GTUC3_UL = __insval2mfld(GTUC3_MIOA_MSK, frayREG->GTUC3_UN.GTUC3_UL , nodeConfigPtr->pMacroInitialOffsetA);
302 frayREG->GTUC3_UN.GTUC3_UL = __insval2mfld(GTUC3_MIOB_MSK, frayREG->GTUC3_UN.GTUC3_UL , nodeConfigPtr->pMacroInitialOffsetB);
303 frayREG->GTUC3_UN.GTUC3_UL = __insval2mfld(GTUC3_UIOA_MSK, frayREG->GTUC3_UN.GTUC3_UL , nodeConfigPtr->pMicroInitialOffsetA);
304 frayREG->GTUC3_UN.GTUC3_UL = __insval2mfld(GTUC3_UIOB_MSK, frayREG->GTUC3_UN.GTUC3_UL , nodeConfigPtr->pMicroInitialOffsetB);
305 frayREG->GTUC1_UN.GTUC1_UL = __insval2mfld(GTUC1_UT_MSK , frayREG->GTUC1_UN.GTUC1_UL , nodeConfigPtr->pMicroPerCycle);
306 frayREG->GTUC10_UN.GTUC10_UL = __insval2mfld(GTUC10_MOC_MSK, frayREG->GTUC10_UN.GTUC10_UL, nodeConfigPtr->pRateCorrectionOut);
307 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_TSM_MSK , frayREG->SUCC1_UN.SUCC1_UL , nodeConfigPtr->pSingleSlotEnabled);
308 if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_A) {
309 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_WUCS_MSK, frayREG->SUCC1_UN.SUCC1_UL, 0);
311 else if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_B) {
312 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_WUCS_MSK, frayREG->SUCC1_UN.SUCC1_UL, 1);
314 frayREG->PRTC1_UN.PRTC1_UL = __insval2mfld(PRTC1_RWP_MSK, frayREG->PRTC1_UN.PRTC1_UL, nodeConfigPtr->pWakeupPattern);
315 frayREG->PRTC1_UN.PRTC1_UL = __insval2mfld(PRTC1_BRP_MSK, frayREG->PRTC1_UN.PRTC1_UL, nodeConfigPtr->pSamplesPerMicrotick);
320 * @brief Check node configuration parameters.
322 * This function checks values of the node configuration parameters,
323 * if they are in ranges noted in FlexRay specification.
325 * @param [in] nodeConfigPtr Address of structure with node configuration parameters
326 * @param [out] errCode Address where error flags will be stored.
327 * We have 24 parameters to check. Every one of them has assigned its bit in this flag.
328 * Error flags are defined as macros ERR_PARAM_nameOfParameter.
329 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
331 Std_ReturnType Fr_check_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr, uint32_t* errCode) {
332 *errCode = ERR_PARAM_NO_ERROR;
334 if (nodeConfigPtr->pAllowPassiveToActive > 31) *errCode |= ERR_PARAM_pAllowPassiveToActive;
335 if (nodeConfigPtr->pChannels != FR_CHANNEL_A &&
336 nodeConfigPtr->pChannels != FR_CHANNEL_B &&
337 nodeConfigPtr->pChannels != FR_CHANNEL_AB ) *errCode |= ERR_PARAM_pChannels;
338 if (nodeConfigPtr->pdAcceptedStartupRange > 1875) *errCode |= ERR_PARAM_pdAcceptedStartupRange;
339 if (nodeConfigPtr->pClusterDriftDamping > 20) *errCode |= ERR_PARAM_pClusterDriftDamping;
340 if (nodeConfigPtr->pDelayCompensationA > 200) *errCode |= ERR_PARAM_pDelayCompensationA;
341 if (nodeConfigPtr->pDelayCompensationB > 200) *errCode |= ERR_PARAM_pDelayCompensationB;
342 if (__notInRange(nodeConfigPtr->pdListenTimeout, 1284, 1283846)) *errCode |= ERR_PARAM_pdListenTimeout;
343 if (__notInRange(nodeConfigPtr->pdMaxDrift, 2, 1923)) *errCode |= ERR_PARAM_pdMaxDrift;
344 if (nodeConfigPtr->pExternOffsetCorrection > 7) *errCode |= ERR_PARAM_pExternOffsetCorrection;
345 if (nodeConfigPtr->pExternRateCorrection > 7) *errCode |= ERR_PARAM_pExternRateCorrection;
346 if (nodeConfigPtr->pKeySlotUsedForStartup == TRUE &&
347 nodeConfigPtr->pKeySlotUsedForSync == FALSE) *errCode |= ERR_PARAM_pKeySlotUsedForSync
348 | ERR_PARAM_pKeySlotUsedForStartup; // If pKeySlotUsedForStartup is set to true then pKeySlotUsedForSync must also be set to true.
349 if (nodeConfigPtr->pLatestTx > 7980) *errCode |= ERR_PARAM_pLatestTx;
350 if (__notInRange(nodeConfigPtr->pMacroInitialOffsetA, 2, 68)) *errCode |= ERR_PARAM_pMacroInitialOffsetA;
351 if (__notInRange(nodeConfigPtr->pMacroInitialOffsetB, 2, 68)) *errCode |= ERR_PARAM_pMacroInitialOffsetB;
352 if (nodeConfigPtr->pMicroInitialOffsetA > 239) *errCode |= ERR_PARAM_pMicroInitialOffsetA;
353 if (nodeConfigPtr->pMicroInitialOffsetB > 239) *errCode |= ERR_PARAM_pMicroInitialOffsetB;
354 if (__notInRange(nodeConfigPtr->pMicroPerCycle, 640, 640000)) *errCode |= ERR_PARAM_pMicroPerCycle;
355 if (__notInRange(nodeConfigPtr->pRateCorrectionOut, 2, 1923)) *errCode |= ERR_PARAM_pRateCorrectionOut;
356 if (nodeConfigPtr->pWakeupChannel != FR_CHANNEL_A &&
357 nodeConfigPtr->pWakeupChannel != FR_CHANNEL_B ) *errCode |= ERR_PARAM_pWakeupChannel;
358 if (__notInRange(nodeConfigPtr->pWakeupPattern, 2, 63)) *errCode |= ERR_PARAM_pWakeupPattern;
359 if (nodeConfigPtr->pSamplesPerMicrotick != 1 &&
360 nodeConfigPtr->pSamplesPerMicrotick != 2 &&
361 nodeConfigPtr->pSamplesPerMicrotick != 4 ) *errCode |= ERR_PARAM_pSamplesPerMicrotick;
363 return (*errCode == 0) ? E_OK : E_NOT_OK;
367 * @brief Check Configuration parameters for all buffers
369 * This function checks configuration parameters.
371 * - All of them have to be RX
372 * - All of them have the same payload <= 256B
373 * - Same channels active
374 * - Same cycle counter filter
377 * - not reconfigurable
378 * - frame ID can be 0, which means that all messages not received by others buffers are received in FIFO.
379 * For dynamic segment buffers and static segment buffers:
380 * - frame ID must not be 0
382 * The sum of all configured payloads must be <= 8KB.
384 * @param [in] statBufCfgPtr Address of structure with static buffers configuration parameters
385 * @param [in] dynBufCfgPtr Address of structure with dynamic buffers configuration parameters
386 * @param [in] fifoBufCfgPtr Address of structure with fifo buffers configuration parameters
387 * @param [in] statBufCnt Number of static buffers to be configured
388 * @param [in] dynBufCnt Number of dynamic buffers to be configured
389 * @param [in] fifoBufCnt Number of fifo buffers to be configured
390 * @param [out] errCode Address where error flags will be stored.
391 * Flags are defined as ERR_PARAM_BUF.....
392 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
394 Std_ReturnType Fr_check_buffer_parameters(const Fr_TMS570LS_BufferConfigType* statBufCfgPtr, const Fr_TMS570LS_BufferConfigType* dynBufCfgPtr, const Fr_TMS570LS_BufferConfigType* fifoBufCfgPtr,
395 uint8_t statBufCnt, uint8_t dynBufCnt, uint8_t fifoBufCnt, uint32_t* errCode) {
396 uint32_t payloadTotal = 0;
397 *errCode = ERR_PARAM_NO_ERROR;
399 Fr_ChannelType fifoChannels;
400 uint8_t fifoCycleCounterFiltering;
403 /* Check FIFO buffer parameters */
404 fifoPayload = fifoBufCfgPtr[0].maxPayload;
405 fifoChannels = fifoBufCfgPtr[0].channel;
406 fifoCycleCounterFiltering = fifoBufCfgPtr[0].cycleCounterFiltering;
407 if (fifoBufCnt != 0 && fifoPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFFIFO_PAYLOAD_HIGH;
408 for (i = 0; i < fifoBufCnt; i++) {
409 if (fifoBufCfgPtr[i].isTx == TRUE) *errCode |= ERR_PARAM_BUFFIFO_NOT_RX;
410 if (fifoBufCfgPtr[i].maxPayload != fifoPayload) *errCode |= ERR_PARAM_BUFFIFO_PAYLOAD_DIFFERS;
411 if (fifoBufCfgPtr[i].channel != fifoChannels) *errCode |= ERR_PARAM_BUFFIFO_CHANNEL_DIFFERS;
412 if (fifoBufCfgPtr[i].cycleCounterFiltering != fifoCycleCounterFiltering) *errCode |= ERR_PARAM_BUFFIFO_CCFILTER_DIFFERS;
413 payloadTotal += fifoBufCfgPtr[i].maxPayload;
416 for (i = 0; i < dynBufCnt; i++) {
417 if (dynBufCfgPtr[i].slotId == 0) *errCode |= ERR_PARAM_BUFDYN_FRAMEID_INVALID;
418 if (dynBufCfgPtr[i].maxPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFDYN_PAYLOAD_HIGH;
419 if (dynBufCfgPtr[i].channel == FR_CHANNEL_AB) *errCode |= ERR_PARAM_BUFDYN_CHANNELS;
420 payloadTotal += dynBufCfgPtr[i].maxPayload;
423 for (i = 0; i < statBufCnt; i++) {
424 if (statBufCfgPtr[i].slotId == 0) *errCode |= ERR_PARAM_BUFSTAT_FRAMEID_INVALID;
425 if (statBufCfgPtr[i].maxPayload > cPayloadLengthMax) *errCode |= ERR_PARAM_BUFSTAT_PAYLOAD_HIGH;
426 payloadTotal += statBufCfgPtr[i].maxPayload;
429 if (payloadTotal > 8192/2) *errCode |= ERR_PARAM_BUF_TOTAL_PAYLOAD_HIGH;
431 return (*errCode == 0) ? E_OK : E_NOT_OK;
435 * @brief Compute and set message RAM config parameters into FlexRay configuration registers.
437 * This function does not check values ranges. This is a responsibility of other functions.
438 * Message RAM configuration parameters are computed from data in the structure and
439 * written into right bit position in configuration registers.
441 * @param [in] msgRAMConfigPtr Address of structure with message RAM configuration parameters
442 * @return Number of configured buffers
444 uint8_t Fr_config_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr) {
445 /* If dynSegmentBufferCount is not 0 then first dynamic buffer = statSegmentBufferCount.
446 * If dynSegmentBufferCount is 0 then first dynamic buffer is 0x80 (see TMS570LS31x documentation)
448 if (msgRAMConfigPtr->dynSegmentBufferCount == 0) {
449 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FDB_MSK, frayREG->MRC_UN.MRC_UL, 0x80);
452 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FDB_MSK, frayREG->MRC_UN.MRC_UL, msgRAMConfigPtr->statSegmentBufferCount);
454 /* If fifoBufferCount is not 0 then first fifo buffer = statSegmentBufferCount + dynSegmentBufferCount
455 * If fifoBufferCount is 0 then first fifo buffer is 0x80 (see TMS570LS31x documentation)
457 if (msgRAMConfigPtr->fifoBufferCount == 0) {
458 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FFB_MSK, frayREG->MRC_UN.MRC_UL, 0x80);
461 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FFB_MSK, frayREG->MRC_UN.MRC_UL, msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount);
463 /* Last configured buffer = statSegmentBufferCount + dynSegmentBufferCount + fifoBufferCount - 1 */
464 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_LCB_MSK, frayREG->MRC_UN.MRC_UL, msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount - 1);
466 /* Secure buffers setting */
467 if (msgRAMConfigPtr->secureBuffers == FR_SB_RECONFIG_ENABLED) {
468 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SEC_MSK, frayREG->MRC_UN.MRC_UL, 0);
470 else if (msgRAMConfigPtr->secureBuffers == FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED) {
471 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SEC_MSK, frayREG->MRC_UN.MRC_UL, 1);
473 else if (msgRAMConfigPtr->secureBuffers == FR_SB_ALL_REC_DISABLED) {
474 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SEC_MSK, frayREG->MRC_UN.MRC_UL, 2);
477 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SEC_MSK, frayREG->MRC_UN.MRC_UL, 3);
480 /* Sync frame payload multiplex setting */
481 if (msgRAMConfigPtr->syncFramePayloadMultiplexEnabled == TRUE) {
482 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SPLM_MSK, frayREG->MRC_UN.MRC_UL, 1);
485 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SPLM_MSK, frayREG->MRC_UN.MRC_UL, 0);
488 return msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount;
491 #define __notInRange(val, min, max) (((val) < (min)) || ((val) > (max)))
494 * @brief Check message RAM configuration parameters.
496 * This function checks values of the message RAM configuration parameters.
497 * FlexRay implementation in TMS570 can have up to 128 buffers configured, so
498 * the sum of all values buffer count must not exceed this ceiling.
501 * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
502 * @param [out] errCode Address where error flags will be stored.
503 * Error flags are defined as macros ERR_PARAM_nameOfParameter.
504 * @return E_OK: Parameters are OK. E_NOT_OK: Some parameter is out of range.
506 Std_ReturnType Fr_check_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr, uint32_t* errCode) {
507 *errCode = ERR_PARAM_NO_ERROR;
509 if (__notInRange(msgRAMConfigPtr->statSegmentBufferCount, 1, 127)) *errCode |= ERR_PARAM_statSegmentBufferCount;
510 if (msgRAMConfigPtr->dynSegmentBufferCount >= FR_MAX_BUFFERS_CNT) *errCode |= ERR_PARAM_dynSegmentBufferCount;
511 if (msgRAMConfigPtr->fifoBufferCount >= FR_MAX_BUFFERS_CNT) *errCode |= ERR_PARAM_fifoBufferCount;
512 if ((msgRAMConfigPtr->statSegmentBufferCount +
513 msgRAMConfigPtr->dynSegmentBufferCount +
514 msgRAMConfigPtr->fifoBufferCount) >= FR_MAX_BUFFERS_CNT) *errCode |= ERR_PARAM_maxBuffLimit;
516 return (*errCode == 0) ? E_OK : E_NOT_OK;
519 void Fr_Init(const Fr_ConfigType* Fr_ConfigPtr) {
523 if (Fr_ConfigPtr == NULL) {
527 /* Save pointers for parameters indexed by CIDX indexes
528 * This array representation is used by Fr_ReadCCConfig function.
529 * Parameter thet are not configurable in tms570 FlexRay implementation
532 Fr_ConfigParPtrs[FR_CIDX_GDCYCLE] = NULL;
533 Fr_ConfigParPtrs[FR_CIDX_PMICROPERCYCLE] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pMicroPerCycle;
534 Fr_ConfigParPtrs[FR_CIDX_PDLISTENTIMEOUT] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gMacroPerCycle;
535 Fr_ConfigParPtrs[FR_CIDX_GDMACROTICK] = NULL;
536 Fr_ConfigParPtrs[FR_CIDX_GNUMBEROFMINISLOTS] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gNumberOfMinislots;
537 Fr_ConfigParPtrs[FR_CIDX_GNUMBEROFSTATICSLOTS] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gNumberOfStaticSlots;
538 Fr_ConfigParPtrs[FR_CIDX_GDNIT] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdNIT;
539 Fr_ConfigParPtrs[FR_CIDX_GDSTATICSLOT] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdNIT;
540 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXWINDOW] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdWakeupSymbolRxWindow;
541 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTID] = NULL;
542 Fr_ConfigParPtrs[FR_CIDX_PLATESTTX] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pLatestTx;
543 Fr_ConfigParPtrs[FR_CIDX_POFFSETCORRECTIONOUT] = NULL;
544 Fr_ConfigParPtrs[FR_CIDX_POFFSETCORRECTIONSTART] = NULL;
545 Fr_ConfigParPtrs[FR_CIDX_PRATECORRECTIONOUT] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pRateCorrectionOut;
546 Fr_ConfigParPtrs[FR_CIDX_PSECONDKEYSLOTID] = NULL;
547 Fr_ConfigParPtrs[FR_CIDX_PDACCEPTEDSTARTUPRANGE] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pdAcceptedStartupRange;
548 Fr_ConfigParPtrs[FR_CIDX_GCOLDSTARTATTEMPTS] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gColdStartAttempts;
549 Fr_ConfigParPtrs[FR_CIDX_GCYCLECOUNTMAX] = NULL;
550 Fr_ConfigParPtrs[FR_CIDX_GLISTENNOISE] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gListenNoise;
551 Fr_ConfigParPtrs[FR_CIDX_GMAXWITHOUTCLOCKCORRECTFATAL] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gMaxWithoutClockCorrectionFatal;
552 Fr_ConfigParPtrs[FR_CIDX_GMAXWITHOUTCLOCKCORRECTPASSIVE] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gMaxWithoutClockCorrectionPassive;
553 Fr_ConfigParPtrs[FR_CIDX_GNETWORKMANAGEMENTVECTORLENGTH] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gNetworkManagementVectorLength;
554 Fr_ConfigParPtrs[FR_CIDX_GPAYLOADLENGTHSTATIC] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gPayloadLengthStatic;
555 Fr_ConfigParPtrs[FR_CIDX_GSYNCFRAMEIDCOUNTMAX] = NULL;
556 Fr_ConfigParPtrs[FR_CIDX_GDACTIONPOINTOFFSET] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdActionPointOffset;
557 Fr_ConfigParPtrs[FR_CIDX_GDBIT] = NULL;
558 Fr_ConfigParPtrs[FR_CIDX_GDCASRXLOWMAX] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdCASRxLowMax;
559 Fr_ConfigParPtrs[FR_CIDX_GDDYNAMICSLOTIDLEPHASE] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdDynamicSlotIdlePhase;
560 Fr_ConfigParPtrs[FR_CIDX_GDMINISLOTACTIONPOINTOFFSET] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdMinislotActionPointOffset;
561 Fr_ConfigParPtrs[FR_CIDX_GDMINISLOT] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdMinislot;
562 Fr_ConfigParPtrs[FR_CIDX_GDSAMPLECLOCKPERIOD] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdSampleClockPeriod;
563 Fr_ConfigParPtrs[FR_CIDX_GDSYMBOLWINDOW] = NULL;
564 Fr_ConfigParPtrs[FR_CIDX_GDSYMBOLWINDOWACTIONPOINTOFFSET] = NULL;
565 Fr_ConfigParPtrs[FR_CIDX_GDTSSTRANSMITTER] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdTSSTransmitter;
566 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXIDLE] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdWakeupSymbolRxIdle;
567 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPRXLOW] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdWakeupSymbolRxLow;
568 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPTXACTIVE] = NULL;
569 Fr_ConfigParPtrs[FR_CIDX_GDWAKEUPTXIDLE] = (const uint32_t*)&Fr_ConfigPtr->clusterConfiguration.gdWakeupSymbolTxIdle;
570 Fr_ConfigParPtrs[FR_CIDX_PALLOWPASSIVETOACTIVE] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pAllowPassiveToActive;
571 Fr_ConfigParPtrs[FR_CIDX_PCHANNELS] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pChannels;
572 Fr_ConfigParPtrs[FR_CIDX_PCLUSTERDRIFTDAMPING] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pClusterDriftDamping;
573 Fr_ConfigParPtrs[FR_CIDX_PDECODINGCORRECTION] = NULL;
574 Fr_ConfigParPtrs[FR_CIDX_PDELAYCOMPENSATIONA] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pDelayCompensationA;
575 Fr_ConfigParPtrs[FR_CIDX_PDELAYCOMPENSATIONB] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pDelayCompensationB;
576 Fr_ConfigParPtrs[FR_CIDX_PMACROINITIALOFFSETA] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pMacroInitialOffsetA;
577 Fr_ConfigParPtrs[FR_CIDX_PMACROINITIALOFFSETB] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pMacroInitialOffsetB;
578 Fr_ConfigParPtrs[FR_CIDX_PMICROINITIALOFFSETA] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pMicroInitialOffsetA;
579 Fr_ConfigParPtrs[FR_CIDX_PMICROINITIALOFFSETB] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pMicroInitialOffsetB;
580 Fr_ConfigParPtrs[FR_CIDX_PPAYLOADLENGTHDYNMAX] = NULL;
581 Fr_ConfigParPtrs[FR_CIDX_PSAMPLESPERMICROTICK] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pSamplesPerMicrotick;
582 Fr_ConfigParPtrs[FR_CIDX_PWAKEUPCHANNEL] =(const uint32_t*) &Fr_ConfigPtr->nodeConfiguration.pWakeupChannel;
583 Fr_ConfigParPtrs[FR_CIDX_PWAKEUPPATTERN] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pWakeupPattern;
584 Fr_ConfigParPtrs[FR_CIDX_PDMICROTICK] = NULL;
585 Fr_ConfigParPtrs[FR_CIDX_GDIGNOREAFTERTX] = NULL;
586 Fr_ConfigParPtrs[FR_CIDX_PALLOWHALTDUETOCLOCK] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pAllowHaltDueToClock;
587 Fr_ConfigParPtrs[FR_CIDX_PEXTERNALSYNC] = NULL;
588 Fr_ConfigParPtrs[FR_CIDX_PFALLBACKINTERNAL] = NULL;
589 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTONLYENABLED] = NULL;
590 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSTARTUP] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pKeySlotUsedForStartup;
591 Fr_ConfigParPtrs[FR_CIDX_PKEYSLOTUSEDFORSYNC] = (const uint32_t*)&Fr_ConfigPtr->nodeConfiguration.pKeySlotUsedForSync;
592 Fr_ConfigParPtrs[FR_CIDX_PNMVECTOREARLYUPDATE] = NULL;
593 Fr_ConfigParPtrs[FR_CIDX_PTWOKEYSLOTMODE] = NULL;
595 /* Store whole configuration address
596 * This structured representation is used by other function in API.
598 Fr_Config = Fr_ConfigPtr;
600 /* Store pointers to structures with configuration parameters of buffers
601 * Reset configured flags for all buffers */
602 for (i = 0; i < Fr_ConfigPtr->msgRAMConfig.statSegmentBufferCount; ++i) { // Statis segment buffers
603 Fr_BuffersPtrs[i] = (const Fr_TMS570LS_BufferConfigType*)&Fr_ConfigPtr->staticBufferConfigs[i];
604 Fr_BuffersConfigured[i] = FALSE;
606 for (i = 0; i < Fr_ConfigPtr->msgRAMConfig.dynSegmentBufferCount; ++i) { // Dynamic segment buffers
607 Fr_BuffersPtrs[i + Fr_ConfigPtr->msgRAMConfig.statSegmentBufferCount] = (const Fr_TMS570LS_BufferConfigType*)&Fr_ConfigPtr->dynamicBufferConfigs[i];
608 Fr_BuffersConfigured[i + Fr_ConfigPtr->msgRAMConfig.statSegmentBufferCount] = FALSE;
610 for (i = 0; i < Fr_ConfigPtr->msgRAMConfig.fifoBufferCount; ++i) { // Fifo buffrers
611 Fr_BuffersPtrs[i + Fr_ConfigPtr->msgRAMConfig.statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig.dynSegmentBufferCount] = (const Fr_TMS570LS_BufferConfigType*)&Fr_ConfigPtr->fifoBufferConfigs[i];
612 Fr_BuffersConfigured[i + Fr_ConfigPtr->msgRAMConfig.statSegmentBufferCount + Fr_ConfigPtr->msgRAMConfig.dynSegmentBufferCount] = FALSE;
615 /* Set some default POC state values */
616 Fr_POCStatus.WakeupStatus = FR_WAKEUP_UNDEFINED;
617 Fr_POCStatus.State = FR_POCSTATE_DEFAULT_CONFIG;
618 Fr_POCStatus.StartupState = FR_STARTUP_UNDEFINED;
619 Fr_POCStatus.SlotMode = FR_SLOTMODE_ALL;
620 Fr_POCStatus.Freeze = FALSE;
621 Fr_POCStatus.ErrorMode = FR_ERRORMODE_ACTIVE;
622 Fr_POCStatus.ColdstartNoise = FALSE;
623 Fr_POCStatus.CHIReadyRequest = FALSE;
624 Fr_POCStatus.CHIHaltRequest = FALSE;
627 Fr_Initialized = TRUE;
631 Std_ReturnType Fr_ControllerInit(uint8_t Fr_CtrlIdx) {
632 uint32_t errCode = ERR_PARAM_NO_ERROR;
634 uint8_t totalBufferCount;
636 /* Switch CC into ‘POC:config’ (from any other POCState) */
637 if (Fr_POC_go_to_config() == E_NOT_OK) {
640 /* Check Cluster config parameters */
641 if (Fr_check_cluster_parameters(&Fr_Config->clusterConfiguration, &errCode) == E_NOT_OK) {
642 return E_NOT_OK | errCode | FR_INIT_ERR_CLUSTER_CONFIG;
644 /* Check node config parameters */
645 if (Fr_check_node_parameters(&Fr_Config->nodeConfiguration, &errCode) == E_NOT_OK) {
646 return E_NOT_OK | errCode | FR_INIT_ERR_NODE_CONFIG;
648 /* Check msgRAM config parameters */
649 if (Fr_check_msgRAM_parameters(&Fr_Config->msgRAMConfig, &errCode) == E_NOT_OK) {
650 return E_NOT_OK | errCode | FR_INIT_ERR_MSGRAM_CONFIG;
652 /* Check buffers parameters */
653 if (Fr_check_buffer_parameters(Fr_Config->staticBufferConfigs, Fr_Config->dynamicBufferConfigs, Fr_Config->fifoBufferConfigs,
654 Fr_Config->msgRAMConfig.statSegmentBufferCount, Fr_Config->msgRAMConfig.dynSegmentBufferCount, Fr_Config->msgRAMConfig.fifoBufferCount, &errCode) == E_NOT_OK) {
655 return E_NOT_OK | errCode | FR_INIT_ERR_BUFFPARAM_CONFIG;
658 /* Clear message RAM */
659 fray_clear_msg_ram();
661 /* Configure all FlexRay cluster, node and msgRAM parameters */
662 Fr_config_cluster_parameters(&Fr_Config->clusterConfiguration);
663 Fr_config_node_parameters(&Fr_Config->nodeConfiguration);
664 totalBufferCount = Fr_config_msgRAM_parameters(&Fr_Config->msgRAMConfig);
665 Fr_MsgRAMDataStartAddress = totalBufferCount*4U; // First data section after headers sections in message RAM.
666 Fr_MsgRAMDataOffset = Fr_MsgRAMDataStartAddress;
667 /* Configure all transmit/receive resources */
668 for (i = 0; i < totalBufferCount; i++) {
669 if (Fr_PrepareLPdu(Fr_CtrlIdx, Fr_BuffersPtrs[i]->slotId) == E_NOT_OK) {
670 return E_NOT_OK | FR_INIT_ERR_BUFF_CONFIG;
674 /* Switch POC to ready state */
675 if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
681 Std_ReturnType Fr_StartCommunication(uint8_t Fr_CtrlIdx) {
683 uint32_t state_value;
686 if (Fr_CtrlIdx != 0) {
689 if (Fr_Initialized != TRUE) {
692 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY) {
696 // Node is configured as coldstart
697 if (Fr_Config->nodeConfiguration.pKeySlotUsedForStartup == TRUE) {
701 // Try to integrate into an existing network as following coldstarter
702 if (Fr_POC_go_to_startup() == E_NOT_OK) {
703 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_FOLLOW; // Switch to run state error
706 do { // Wait until NORMAL_ACTIVE state or timeout
707 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
709 } while ((state_value != FR_POCS_NORMAL_ACTIVE) && (counter < FR_FCS_LISTEN_TIMEOUT));
711 // No success in integration, try to initiate FlexRay network as leading coldstarter.
712 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_INTEGRATION_LISTEN){
713 csa = frayREG->CCSV_UN.CCSV_ST.rca_B5;
714 if (csa != 0) { // Some cold start attempts remaining
715 if (Fr_AllowColdstart(Fr_CtrlIdx) == E_NOT_OK) {
716 return E_NOT_OK | FR_STARTUP_ERR_CSINH_DIS; // Cold start inhibit disabled error
720 do { // Wait until NORMAL_ACTIVE or INTEGRATION_LISTEN state
721 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
722 } while ( (state_value != FR_POCS_NORMAL_ACTIVE) && (state_value != FR_POCS_INTEGRATION_LISTEN));
723 if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 == FR_POCS_NORMAL_ACTIVE) // Success, break the start up loop
726 if (Fr_POC_go_to_ready_from_startup() == E_NOT_OK) { // No success. Switch back to READY state
727 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_READY;
731 // The node is not coldstarter, try to integrate into an existing network.
733 if(Fr_POC_go_to_startup() == E_NOT_OK) {
734 return E_NOT_OK | FR_STARTUP_ERR_SW_STUP_AS_NCOLD; // Switching to startup state as non-cold start node
737 // Wait until NORMAL_ACTIVE
739 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
740 } while (state_value != FR_POCS_NORMAL_ACTIVE);
746 Std_ReturnType Fr_AllowColdstart(uint8_t Fr_CtrlIdx) {
747 Fr_wait_for_POC_ready();
748 frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_ALLOW_COLDSTART;
749 if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
751 Fr_wait_for_POC_ready();
755 Std_ReturnType Fr_AllSlots(uint8_t Fr_CtrlIdx) {
759 Std_ReturnType Fr_HaltCommunication(uint8_t Fr_CtrlIdx) {
763 Std_ReturnType Fr_AbortCommunication(uint8_t Fr_CtrlIdx) {
767 Std_ReturnType Fr_SendWUP(uint8_t Fr_CtrlIdx) {
771 Std_ReturnType Fr_SetWakeupChannel(uint8_t Fr_CtrlIdx, Fr_ChannelType Fr_ChnlIdx) {
775 Std_ReturnType Fr_GetPOCStatus(uint8_t Fr_CtrlIdx, Fr_POCStatusType* Fr_POCStatusPtr) {
779 Std_ReturnType Fr_TransmitTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, const uint8_t* Fr_LSduPtr, uint8_t Fr_LSduLength) {
780 uint32_t byte, word, buffer, index, bufferIndex;
782 /* Find the index of the buffer in configuration data array */
783 for (bufferIndex = 0; bufferIndex < FR_MAX_BUFFERS_CNT; bufferIndex++) {
784 if (Fr_BuffersPtrs[bufferIndex]->slotId == Fr_LPduIdx) {
785 if (Fr_BuffersConfigured[bufferIndex] == TRUE) { // Buffer was configured already
786 for (word = 0; word < (Fr_LSduLength+3)/4; word++) {
788 for (byte = 0; byte < 4; byte++) {
790 if (index < Fr_LSduLength) {
791 buffer |= Fr_LSduPtr[index] << byte*8;
794 frayREG->WRDS[word] = buffer;
796 fray_buffer_transmit_data(bufferIndex);
804 Std_ReturnType Fr_CancelTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
808 Std_ReturnType Fr_ReceiveRxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, uint8_t* Fr_LSduPtr, Fr_RxLPduStatusType* Fr_LPduStatusPtr, uint8_t* Fr_LSduLengthPtr) {
812 Std_ReturnType Fr_CheckTxLPduStatus(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, Fr_TxLPduStatusType* Fr_TxLPduStatusPtr) {
816 Std_ReturnType Fr_PrepareLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
821 if (Fr_CtrlIdx != 0) {
824 if (Fr_Initialized != TRUE) {
827 if (Fr_LPduIdx > cSlotIDMax) {
831 /* Find the index of the buffer in configuration data array */
832 for (i = 0; i < FR_MAX_BUFFERS_CNT; i++) {
833 if (Fr_BuffersPtrs[i]->slotId == Fr_LPduIdx) { // Next occurence of the frame ID found, index retreived into i.
834 if (Fr_BuffersConfigured[i] == FALSE) { // Buffer was not yet configured
835 mode = (Fr_BuffersPtrs[i]->singleTransmit == TRUE) ? FRAY_BUF_MBI_EN : FRAY_BUF_MBI_DIS;
836 mode |= (Fr_BuffersPtrs[i]->singleTransmit == TRUE) ? FRAY_BUF_TX_MODE_SINGLE : FRAY_BUF_TX_MODE_CONTINUOUS;
837 mode |= (Fr_BuffersPtrs[i]->payloadPreambleIndicatorTr == TRUE) ? FRAY_BUF_NM_EN : FRAY_BUF_NM_DIS;
838 mode |= (Fr_BuffersPtrs[i]->isTx == TRUE) ? FRAY_BUF_TX : FRAY_BUF_RX;
839 mode |= (Fr_BuffersPtrs[i]->channel == FR_CHANNEL_A || Fr_BuffersPtrs[i]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHA_EN : FRAY_BUF_CHA_DIS;
840 mode |= (Fr_BuffersPtrs[i]->channel == FR_CHANNEL_B || Fr_BuffersPtrs[i]->channel == FR_CHANNEL_AB) ? FRAY_BUF_CHB_EN : FRAY_BUF_CHB_DIS;
841 mode |= (Fr_BuffersPtrs[i]->rejectNullFrames == TRUE) ? FRAY_BUF_REJECT_NULL_FRAMES : FRAY_BUF_ACCEPT_NULL_FRAMES;
842 mode |= (Fr_BuffersPtrs[i]->rejectStaticSegment == TRUE) ? FRAY_BUF_REJECT_STATIC_SEGMENT : FRAY_BUF_ACCEPT_STATIC_SEGMENT;
843 Fr_MsgRAMDataPtrs[i] = Fr_MsgRAMDataOffset;
844 if (i >= __mfld2val(MRC_FFB_MSK, frayREG->MRC_UN.MRC_UL)) { // This is RX FIFO buffer
845 fray_configure_fifo_buffer(i, mode, Fr_BuffersPtrs[i]->cycleCounterFiltering, Fr_BuffersPtrs[i]->slotId, Fr_BuffersPtrs[i]->maxPayload, Fr_MsgRAMDataPtrs[i]);
847 else { // Static/dynamic segment buffer
848 fray_config_buffer(i, mode, Fr_BuffersPtrs[i]->cycleCounterFiltering, Fr_BuffersPtrs[i]->slotId, Fr_BuffersPtrs[i]->maxPayload, Fr_MsgRAMDataPtrs[i]);
851 * Calculate new address.
852 * Payload contains the number of two-bytes words, Fr_MsgRAMDataPtrs contains addresses of 4B words in message RAM, all msgRAM addresses have
854 * Offset has to be divided by two each time because payload is in 2B words and msgRAM addresses are in 4B words.
856 Fr_MsgRAMDataOffset += ((Fr_BuffersPtrs[i]->maxPayload)%2U == 0U ? (Fr_BuffersPtrs[i]->maxPayload) : ((Fr_BuffersPtrs[i]->maxPayload)+1U))/2;
857 Fr_BuffersConfigured[i] = TRUE;
864 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) {
865 /* TODO: Implement */
869 Std_ReturnType Fr_DisableLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
870 /* TODO: Implement */
874 Std_ReturnType Fr_GetGlobalTime(uint8_t Fr_CtrlIdx, uint8_t* Fr_CyclePtr, uint16_t* Fr_MacroTickPtr) {
878 Std_ReturnType Fr_GetNmVector(uint8_t Fr_CtrlIdx, uint8_t* Fr_NmVectorPtr) {
882 Std_ReturnType Fr_GetNumOfStartupFrames(uint8_t Fr_CtrlIdx, uint8_t* Fr_NumOfStartupFramesPtr) {
886 Std_ReturnType Fr_GetChannelStatus(uint8_t Fr_CtrlIdx, uint16_t* Fr_ChannelAStatusPtr, uint16_t* Fr_ChannelBStatusPtr) {
890 Std_ReturnType Fr_GetClockCorrection(uint8_t Fr_CtrlIdx, int16_t* Fr_RateCorrectionPtr, int32_t* Fr_OffsetCorrectionPtr) {
894 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) {
898 Std_ReturnType Fr_GetWakeupRxStatus(uint8_t Fr_CtrlIdx, uint8_t* Fr_WakeupRxStatusPtr) {
902 Std_ReturnType Fr_SetAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, uint8_t Fr_Cycle, uint16_t Fr_Offset) {
906 Std_ReturnType Fr_CancelAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
910 Std_ReturnType Fr_EnableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
914 Std_ReturnType Fr_AckAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
918 Std_ReturnType Fr_DisableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
922 Std_ReturnType Fr_GetAbsoluteTimerIRQStatus(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, boolean_t* Fr_IRQStatusPtr) {
926 void Fr_GetVersionInfo(Std_VersionInfoType* VersioninfoPtr) {
928 if (VersioninfoPtr == NULL) {
932 VersioninfoPtr->vendorID = Fr_versionInfo.vendorID;
933 VersioninfoPtr->moduleID = Fr_versionInfo.moduleID;
934 VersioninfoPtr->sw_major_version = Fr_versionInfo.sw_major_version;
935 VersioninfoPtr->sw_minor_version= Fr_versionInfo.sw_minor_version;
936 VersioninfoPtr->sw_patch_version= Fr_versionInfo.sw_patch_version;
939 Std_ReturnType Fr_ReadCCConfig( uint8_t Fr_CtrlIdx, uint8_t Fr_ConfigParamIdx, uint32_t* Fr_ConfigParamValuePtr) {
941 if (Fr_CtrlIdx != 0) {
944 if (Fr_ConfigParamIdx >= FR_CIDX_CNT) {
947 if (Fr_ConfigParamValuePtr >= NULL) {
950 if (Fr_Initialized != TRUE) {
955 Fr_ConfigParamValuePtr = (uint32_t*)Fr_ConfigParPtrs[Fr_ConfigParamIdx];