]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/drv/fr_tms570.c
Functin for data transmission implemented
[pes-rpp/rpp-lib.git] / rpp / src / drv / fr_tms570.c
1 /*
2  * fr_rms570.c
3  *
4  *  Created on: 9.7.2013
5  *      Author: michal
6  */
7
8 #include "drv/fr_tms570.h"
9 #include "sys/ti_drv_fray.h"
10 #include "drv/fray.h"
11 #include "binary.h"
12
13 Std_VersionInfoType Fr_versionInfo = {
14                 .vendorID = 0x00000001,
15                 .moduleID = 0x00000002,
16                 .sw_major_version = 0,
17                 .sw_minor_version = 1,
18                 .sw_patch_version = 0
19 };
20
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;
29 #ifdef DET_ACTIVATED
30         boolean_t Fr_Initialized = FALSE;
31 #endif
32
33 /** @fn wait_for_POC_ready(void)
34 *   @brief Wait until POC is not busy
35 */
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);
40 }
41
42 /**
43  * @brief Switch POC to config state from any other state
44  *
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
48  *
49  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
50  */
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)
56         return E_NOT_OK;
57     // Wait for PBSY bit to clear - POC not busy
58     Fr_wait_for_POC_ready();
59     return E_OK;
60 }
61
62 /**
63  * @brief Switch POC to clear_message_ram state from default_config and config state
64  *
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.
67  *
68  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
69  */
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) {
74         return E_NOT_OK;
75     }
76     Fr_wait_for_POC_ready();
77     return E_OK;
78 }
79
80 /**
81  * @brief Switch POC to ready state from config state
82  *
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
86  *
87  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
88  */
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){
93         // Unlock sequence
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;
97         // Unlock sequence
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;
101         // Unlock sequence
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;
105     }
106     // For CHA  network
107     else if(frayREG->SUCC1_UN.SUCC1_ST.ccha_B1){
108         // Unlock sequence
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;
112         // Unlock sequence
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;
116     }
117     // For CHB  network
118     else if (frayREG->SUCC1_UN.SUCC1_ST.cchb_B1){
119         // Unlock sequence
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;
123         // Unlock sequence
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;
127     }
128     else frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 = CMD_READY;
129
130     if (frayREG->SUCC1_UN.SUCC1_ST.cmd_B4 == CMD_command_not_accepted)
131         return E_NOT_OK;
132
133     while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01)
134             ; // Waiting for READY state
135     return E_OK;
136 }
137
138 /**
139  * @brief Switch POC to ready state from startup state
140  *
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
144  *
145  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
146  */
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)
151         return E_NOT_OK;
152     while ((frayREG->CCSV_UN.CCSV_UL & 0x0000003F) != 0x01); // Wait until POC is not in ready state
153         Fr_wait_for_POC_ready();
154     return E_OK;
155 }
156
157 /**
158  * @brief Switch POC to startup state from ready state
159  *
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
163  *
164  * @return E_OK: Call finished successfuly. E_NOT_OK: POC has not accepted command.
165  */
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)
170         return (E_NOT_OK);
171     Fr_wait_for_POC_ready();
172     return (E_OK);
173 }
174
175 /**
176  * @brief Copy cluster config parameters into FlexRay configuration registers.
177  *
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.
181  *
182  * @param [in] clusterConfigPtr Address of structure with cluster configuration parameters
183  */
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);
207
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);
211 }
212
213 #define __notInRange(val, min, max)     (((val) < (min)) || ((val) > (max)))
214
215 /**
216  * @brief Check cluster configuration parameters.
217  *
218  * This function checks values of the cluster configuration parameters,
219  * if they are in ranges noted in FlexRay specification.
220  *
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.
226  */
227 Std_ReturnType Fr_check_cluster_parameters(const Fr_TMS570LS_ClusterConfigType* clusterConfigPtr, uint32_t* errCode) {
228         *errCode = ERR_PARAM_NO_ERROR;
229
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;
261
262         return (*errCode == 0) ? E_OK : E_NOT_OK;
263 }
264
265 /**
266  * @brief Copy node config parameters into FlexRay configuration registers.
267  *
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.
271  *
272  * @param [in] nodeConfigPtr Address of structure with node configuration parameters
273  */
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);
280         }
281
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);
285         }
286         else {
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);
289         }
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);
310         }
311         else if (nodeConfigPtr->pWakeupChannel == FR_CHANNEL_B) {
312                 frayREG->SUCC1_UN.SUCC1_UL = __insval2mfld(SUCC1_WUCS_MSK, frayREG->SUCC1_UN.SUCC1_UL, 1);
313         }
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);
316
317 }
318
319 /**
320  * @brief Check node configuration parameters.
321  *
322  * This function checks values of the node configuration parameters,
323  * if they are in ranges noted in FlexRay specification.
324  *
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.
330  */
331 Std_ReturnType Fr_check_node_parameters(const Fr_TMS570LS_NodeConfigType* nodeConfigPtr, uint32_t* errCode) {
332         *errCode = ERR_PARAM_NO_ERROR;
333
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;
362
363         return (*errCode == 0) ? E_OK : E_NOT_OK;
364 }
365
366 /**
367  * @brief Check Configuration parameters for all buffers
368  *
369  * This function checks configuration parameters.
370  * For FIFO buffers:
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
375  *              - not coldstart
376  *              - not single/auto
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
381  *              - payload <= 256B
382  * The sum of all configured payloads must be <= 8KB.
383  *
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.
393  */
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;
398         uint8_t fifoPayload;
399         Fr_ChannelType fifoChannels;
400         uint8_t fifoCycleCounterFiltering;
401         uint8_t i;
402
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;
414         }
415
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;
421         }
422
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;
427         }
428
429         if (payloadTotal > 8192/2) *errCode |= ERR_PARAM_BUF_TOTAL_PAYLOAD_HIGH;
430
431         return (*errCode == 0) ? E_OK : E_NOT_OK;
432 }
433
434 /**
435  * @brief Compute and set message RAM config parameters into FlexRay configuration registers.
436  *
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.
440  *
441  * @param [in] msgRAMConfigPtr Address of structure with message RAM configuration parameters
442  * @return Number of configured buffers
443  */
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)
447          */
448         if (msgRAMConfigPtr->dynSegmentBufferCount == 0) {
449                 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FDB_MSK, frayREG->MRC_UN.MRC_UL, 0x80);
450         }
451         else {
452                 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FDB_MSK, frayREG->MRC_UN.MRC_UL, msgRAMConfigPtr->statSegmentBufferCount);
453         }
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)
456          */
457         if (msgRAMConfigPtr->fifoBufferCount == 0) {
458                 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FFB_MSK, frayREG->MRC_UN.MRC_UL, 0x80);
459         }
460         else {
461                 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_FFB_MSK, frayREG->MRC_UN.MRC_UL, msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount);
462         }
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);
465
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);
469         }
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);
472         }
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);
475         }
476         else {
477                 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SEC_MSK, frayREG->MRC_UN.MRC_UL, 3);
478         }
479
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);
483         }
484         else {
485                 frayREG->MRC_UN.MRC_UL = __insval2mfld(MRC_SPLM_MSK, frayREG->MRC_UN.MRC_UL, 0);
486         }
487
488         return msgRAMConfigPtr->statSegmentBufferCount + msgRAMConfigPtr->dynSegmentBufferCount + msgRAMConfigPtr->fifoBufferCount;
489 }
490
491 #define __notInRange(val, min, max)     (((val) < (min)) || ((val) > (max)))
492
493 /**
494  * @brief Check message RAM configuration parameters.
495  *
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.
499  *
500  *
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.
505  */
506 Std_ReturnType Fr_check_msgRAM_parameters(const Fr_TMS570LS_MsgRAMConfig* msgRAMConfigPtr, uint32_t* errCode) {
507         *errCode = ERR_PARAM_NO_ERROR;
508
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;
515
516         return (*errCode == 0) ? E_OK : E_NOT_OK;
517 }
518
519 void Fr_Init(const Fr_ConfigType* Fr_ConfigPtr) {
520         uint32_t i;
521
522 #ifdef DET_ACTIVATED
523         if (Fr_ConfigPtr == NULL) {
524                 return;
525         }
526 #endif
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
530          * are set as NULL.
531          */
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;
594
595         /* Store whole configuration address
596          * This structured representation is used by other function in API.
597          */
598         Fr_Config = Fr_ConfigPtr;
599
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;
605         }
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;
609         }
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;
613         }
614
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;
625
626 #ifdef DET_ACTIVATED
627         Fr_Initialized = TRUE;
628 #endif
629 }
630
631 Std_ReturnType Fr_ControllerInit(uint8_t Fr_CtrlIdx) {
632         uint32_t errCode = ERR_PARAM_NO_ERROR;
633         uint32_t i;
634         uint8_t totalBufferCount;
635
636         /* Switch CC into â€˜POC:config’ (from any other POCState) */
637         if (Fr_POC_go_to_config() == E_NOT_OK) {
638                 return E_NOT_OK;
639         }
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;
643         }
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;
647         }
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;
651         }
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;
656         }
657
658         /* Clear message RAM */
659         fray_clear_msg_ram();
660
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;
671                 }
672         }
673
674         /* Switch POC to ready state */
675         if (Fr_POC_go_to_ready_from_config() == E_NOT_OK) {
676                 return E_NOT_OK;
677         }
678         return E_OK;
679 }
680
681 Std_ReturnType Fr_StartCommunication(uint8_t Fr_CtrlIdx) {
682         uint32_t counter;
683         uint32_t state_value;
684         uint32_t csa;
685 #ifdef DET_ACTIVATED
686         if (Fr_CtrlIdx != 0) {
687                 return E_NOT_OK;
688         }
689         if (Fr_Initialized != TRUE) {
690                 return E_NOT_OK;
691         }
692         if (frayREG->CCSV_UN.CCSV_ST.pocs_B6 != FR_POCS_READY) {
693                 return E_NOT_OK;
694         }
695 #endif
696         // Node is configured as coldstart
697         if (Fr_Config->nodeConfiguration.pKeySlotUsedForStartup == TRUE) {
698         // Start up loop
699         while(1) {
700             counter = 0;
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
704             }
705
706             do {        // Wait until NORMAL_ACTIVE state or timeout
707                 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
708                 counter++;
709             } while ((state_value != FR_POCS_NORMAL_ACTIVE) && (counter < FR_FCS_LISTEN_TIMEOUT));
710
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
717                     }
718                 }
719             }
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
724                 break;
725             // fray_delay();
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;
728             }
729         }
730         }
731     // The node is not coldstarter, try to integrate into an existing network.
732     else {
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
735         }
736         else {
737             // Wait until NORMAL_ACTIVE
738             do {
739                 state_value = frayREG->CCSV_UN.CCSV_ST.pocs_B6;
740             } while (state_value != FR_POCS_NORMAL_ACTIVE);
741         }
742     }
743         return E_OK;
744 }
745
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)
750         return E_NOT_OK;
751     Fr_wait_for_POC_ready();
752     return E_OK;
753 }
754
755 Std_ReturnType Fr_AllSlots(uint8_t Fr_CtrlIdx) {
756         return E_OK;
757 }
758
759 Std_ReturnType Fr_HaltCommunication(uint8_t Fr_CtrlIdx) {
760         return E_OK;
761 }
762
763 Std_ReturnType Fr_AbortCommunication(uint8_t Fr_CtrlIdx) {
764         return E_OK;
765 }
766
767 Std_ReturnType Fr_SendWUP(uint8_t Fr_CtrlIdx) {
768         return E_OK;
769 }
770
771 Std_ReturnType Fr_SetWakeupChannel(uint8_t Fr_CtrlIdx, Fr_ChannelType Fr_ChnlIdx) {
772         return E_OK;
773 }
774
775 Std_ReturnType Fr_GetPOCStatus(uint8_t Fr_CtrlIdx, Fr_POCStatusType* Fr_POCStatusPtr) {
776         return E_OK;
777 }
778
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;
781
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++) {
787                                         buffer = 0;
788                                         for (byte = 0; byte < 4; byte++) {
789                                                 index = word*4+byte;
790                                                 if (index < Fr_LSduLength) {
791                                                         buffer |= Fr_LSduPtr[index] << byte*8;
792                                                 }
793                                         }
794                                         frayREG->WRDS[word] = buffer;
795                                 }
796                                 fray_buffer_transmit_data(bufferIndex);
797                                 return E_OK;
798                         }
799                 }
800         }
801         return E_NOT_OK;
802 }
803
804 Std_ReturnType Fr_CancelTxLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
805         return E_OK;
806 }
807
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) {
809         return E_OK;
810 }
811
812 Std_ReturnType Fr_CheckTxLPduStatus(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx, Fr_TxLPduStatusType* Fr_TxLPduStatusPtr) {
813         return E_OK;
814 }
815
816 Std_ReturnType Fr_PrepareLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
817         uint32_t i;
818         uint32_t mode;
819
820 #ifdef DET_ACTIVATED
821         if (Fr_CtrlIdx != 0) {
822                 return E_NOT_OK;
823         }
824         if (Fr_Initialized != TRUE) {
825                 return E_NOT_OK;
826         }
827         if (Fr_LPduIdx > cSlotIDMax) {
828                 return E_NOT_OK;
829         }
830 #endif
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]);
846                                 }
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]);
849                                 }
850                                 /*
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
853                                  * to be 4B alligned.
854                                  * Offset has to be divided by two each time because  payload is in 2B words and msgRAM addresses are in 4B words.
855                                  */
856                                 Fr_MsgRAMDataOffset += ((Fr_BuffersPtrs[i]->maxPayload)%2U == 0U ? (Fr_BuffersPtrs[i]->maxPayload) : ((Fr_BuffersPtrs[i]->maxPayload)+1U))/2;
857                                 Fr_BuffersConfigured[i] = TRUE;
858                         }
859                 }
860         }
861         return E_OK;
862 }
863
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 */
866         return E_OK;
867 }
868
869 Std_ReturnType Fr_DisableLPdu(uint8_t Fr_CtrlIdx, uint16_t Fr_LPduIdx) {
870         /* TODO: Implement */
871         return E_OK;
872 }
873
874 Std_ReturnType Fr_GetGlobalTime(uint8_t Fr_CtrlIdx, uint8_t* Fr_CyclePtr, uint16_t* Fr_MacroTickPtr) {
875         return E_OK;
876 }
877
878 Std_ReturnType Fr_GetNmVector(uint8_t Fr_CtrlIdx, uint8_t* Fr_NmVectorPtr) {
879         return E_OK;
880 }
881
882 Std_ReturnType Fr_GetNumOfStartupFrames(uint8_t Fr_CtrlIdx, uint8_t* Fr_NumOfStartupFramesPtr) {
883         return E_OK;
884 }
885
886 Std_ReturnType Fr_GetChannelStatus(uint8_t Fr_CtrlIdx, uint16_t* Fr_ChannelAStatusPtr, uint16_t* Fr_ChannelBStatusPtr) {
887         return E_OK;
888 }
889
890 Std_ReturnType Fr_GetClockCorrection(uint8_t Fr_CtrlIdx, int16_t* Fr_RateCorrectionPtr, int32_t* Fr_OffsetCorrectionPtr) {
891         return E_OK;
892 }
893
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) {
895         return E_OK;
896 }
897
898 Std_ReturnType Fr_GetWakeupRxStatus(uint8_t Fr_CtrlIdx, uint8_t* Fr_WakeupRxStatusPtr) {
899         return E_OK;
900 }
901
902 Std_ReturnType Fr_SetAbsoluteTimer(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, uint8_t Fr_Cycle, uint16_t Fr_Offset) {
903         return E_OK;
904 }
905
906 Std_ReturnType Fr_CancelAbsoluteTimer(uint8_t Fr_CtrlIdx,       uint8_t Fr_AbsTimerIdx) {
907         return E_OK;
908 }
909
910 Std_ReturnType Fr_EnableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
911         return E_OK;
912 }
913
914 Std_ReturnType Fr_AckAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
915         return E_OK;
916 }
917
918 Std_ReturnType Fr_DisableAbsoluteTimerIRQ(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx) {
919         return E_OK;
920 }
921
922 Std_ReturnType Fr_GetAbsoluteTimerIRQStatus(uint8_t Fr_CtrlIdx, uint8_t Fr_AbsTimerIdx, boolean_t* Fr_IRQStatusPtr) {
923         return E_OK;
924 }
925
926 void Fr_GetVersionInfo(Std_VersionInfoType* VersioninfoPtr) {
927 #ifdef DET_ACTIVATED
928         if (VersioninfoPtr == NULL) {
929                 return;
930         }
931 #endif
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;
937 }
938
939 Std_ReturnType Fr_ReadCCConfig( uint8_t Fr_CtrlIdx, uint8_t Fr_ConfigParamIdx, uint32_t* Fr_ConfigParamValuePtr) {
940 #ifdef DET_ACTIVATED
941         if (Fr_CtrlIdx != 0) {
942                 return E_NOT_OK;
943         }
944         if (Fr_ConfigParamIdx >= FR_CIDX_CNT) {
945                 return E_NOT_OK;
946         }
947         if (Fr_ConfigParamValuePtr >= NULL) {
948                 return E_NOT_OK;
949         }
950         if (Fr_Initialized != TRUE) {
951                 return E_NOT_OK;
952         }
953 #endif
954
955         Fr_ConfigParamValuePtr = (uint32_t*)Fr_ConfigParPtrs[Fr_ConfigParamIdx];
956         return E_OK;
957 }