1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @file Mru_Ip.c
9 *
10 *
11 * @brief MRU low-level driver implementations.
12 * @details MRU low-level driver implementations.
13 *
14 * @addtogroup MRU_IP_DRIVER Mru Ip Driver
15 * @{
16 */
17
18 #ifdef __cplusplus
19 extern "C"
20 {
21 #endif
22
23 /*==================================================================================================
24 * INCLUDE FILES
25 * 1) system and project includes
26 * 2) needed interfaces from external units
27 * 3) internal and external interfaces from this unit
28 ==================================================================================================*/
29 #include "Mcal.h"
30 #include "Mru_Ip.h"
31 #if (STD_ON == MRU_IP_DEV_ERROR_DETECT)
32 #include "Devassert.h"
33 #endif
34
35 /*==================================================================================================
36 * SOURCE FILE VERSION INFORMATION
37 ==================================================================================================*/
38 #define MRU_IP_VENDOR_ID_C 43
39 #define MRU_IP_AR_RELEASE_MAJOR_VERSION_C 4
40 #define MRU_IP_AR_RELEASE_MINOR_VERSION_C 7
41 #define MRU_IP_AR_RELEASE_REVISION_VERSION_C 0
42 #define MRU_IP_SW_MAJOR_VERSION_C 0
43 #define MRU_IP_SW_MINOR_VERSION_C 9
44 #define MRU_IP_SW_PATCH_VERSION_C 0
45 /*==================================================================================================
46 * FILE VERSION CHECKS
47 ==================================================================================================*/
48 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
49 /* Check if current file and Mcal header file are of the same Autosar version */
50 #if ((MRU_IP_AR_RELEASE_MAJOR_VERSION_C != MCAL_AR_RELEASE_MAJOR_VERSION) || \
51 (MRU_IP_AR_RELEASE_MINOR_VERSION_C != MCAL_AR_RELEASE_MINOR_VERSION))
52 #error "AutoSar Version Numbers of Mru_Ip.c and Mcal.h are different"
53 #endif
54 #endif
55
56 /* Check if Mru_Ip.h and Mru_Ip.c are of the same vendor */
57 #if (MRU_IP_VENDOR_ID != MRU_IP_VENDOR_ID_C)
58 #error "Mru_Ip.h and Mru_Ip.c have different vendor ids"
59 #endif
60 /* Check if Mru_Ip.h file and Mru_Ip.c file are of the same Autosar version */
61 #if ((MRU_IP_AR_RELEASE_MAJOR_VERSION != MRU_IP_AR_RELEASE_MAJOR_VERSION_C) || \
62 (MRU_IP_AR_RELEASE_MINOR_VERSION != MRU_IP_AR_RELEASE_MINOR_VERSION_C) || \
63 (MRU_IP_AR_RELEASE_REVISION_VERSION != MRU_IP_AR_RELEASE_REVISION_VERSION_C))
64 #error "AutoSar Version Numbers of Mru_Ip.h and Mru_Ip.c are different"
65 #endif
66 #if ((MRU_IP_SW_MAJOR_VERSION != MRU_IP_SW_MAJOR_VERSION_C) || \
67 (MRU_IP_SW_MINOR_VERSION != MRU_IP_SW_MINOR_VERSION_C) || \
68 (MRU_IP_SW_PATCH_VERSION != MRU_IP_SW_PATCH_VERSION_C))
69 #error "Software Version Numbers of Mru_Ip.h and Mru_Ip.c are different"
70 #endif
71 /*==================================================================================================
72 * LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
73 ==================================================================================================*/
74 /*==================================================================================================
75 * LOCAL MACROS
76 ==================================================================================================*/
77 #define MRU_IP_CH_CFG0_CHE_MASK (0x1U)
78 #define MRU_IP_CH_CFG0_IE_MASK (0x4U)
79 #define MRU_IP_CH_MBSTAT_MBS0_MASK (0x10000U)
80 #define MRU_IP_CH_CFG1_MBIC0_MASK (0x10000U)
81 #define MRU_IP_CH_CFG1_MBIC0_SHIFT (16U)
82 #define MRU_IP_NOTIFY_CH1_IS_MASK (0x1U)
83 /*==================================================================================================
84 * LOCAL CONSTANTS
85 ==================================================================================================*/
86 /*==================================================================================================
87 * LOCAL VARIABLES
88 ==================================================================================================*/
89 /*==================================================================================================
90 * GLOBAL CONSTANTS
91 ==================================================================================================*/
92 /*==================================================================================================
93 GLOBAL VARIABLES
94 ==================================================================================================*/
95 #define PLATFORM_START_SEC_VAR_CLEARED_UNSPECIFIED
96 #include "Platform_MemMap.h"
97
98 Mru_Ip_StateStructureType Mru_Ip_axStateStructure[MRU_IP_NUMBER_OF_INSTANCES];
99
100 Mru_Ip_StateStructureType* Mru_Ip_apxStateStructureArray[MRU_IP_NUMBER_OF_INSTANCES];
101
102 #define PLATFORM_STOP_SEC_VAR_CLEARED_UNSPECIFIED
103 #include "Platform_MemMap.h"
104 /*==================================================================================================
105 * LOCAL FUNCTION PROTOTYPES
106 ==================================================================================================*/
107 #define PLATFORM_START_SEC_CODE
108 #include "Platform_MemMap.h"
109
110 /*==================================================================================================
111 * LOCAL FUNCTIONS
112 ==================================================================================================*/
113 /**
114 * @brief This function is called by MRU ISRs.
115 * @details This function will process MRU interrupts.
116 *
117 * @param[in] InstanceId Instance Id of the hardware unit.
118 * @param[in] IntGroupId Interrupt group Id of the hardware unit.
119 *
120 * @implementsMru_Ip_IrqHandlerReceiveMb_Activity
121 */
122 static void Mru_Ip_IrqHandlerReceiveMb(const Mru_Ip_ChannelCfgType * ChannelConfig, uint8 IntGroupId);
123 /*================================================================================================*/
Mru_Ip_Init(const Mru_Ip_ConfigType * HWUnitConfigPtr)124 void Mru_Ip_Init(const Mru_Ip_ConfigType *HWUnitConfigPtr)
125 {
126 Mru_Ip_StateStructureType* State;
127 uint8 InstanceId = 0u;
128 uint8 CfgIndex = 0u;
129
130 #if (MRU_IP_DEV_ERROR_DETECT == STD_ON)
131 DevAssert(NULL_PTR != HWUnitConfigPtr);
132 #endif
133 InstanceId = HWUnitConfigPtr->InstanceId;
134 State = Mru_Ip_apxStateStructureArray[InstanceId];
135 #if (MRU_IP_DEV_ERROR_DETECT == STD_ON)
136 DevAssert(NULL_PTR == State);
137 #endif
138 Mru_Ip_apxStateStructureArray[InstanceId] = &Mru_Ip_axStateStructure[HWUnitConfigPtr->StateIndex];
139 State = Mru_Ip_apxStateStructureArray[InstanceId];
140 State->HWUnitConfig = HWUnitConfigPtr;
141
142 for(CfgIndex = 0u; CfgIndex < HWUnitConfigPtr->NumChannel; CfgIndex++)
143 {
144 if(NULL_PTR != HWUnitConfigPtr->ChannelCfg[CfgIndex].MBLinkReceiveChCfg)
145 {
146 /* Enables the channel configuration before writing to registers */
147 *HWUnitConfigPtr->ChannelCfg[CfgIndex].ChCFG0Add = MRU_IP_CH_CFG0_CHE_MASK;
148 /* Update channel CFG1 */
149 *HWUnitConfigPtr->ChannelCfg[CfgIndex].ChCFG1Add = HWUnitConfigPtr->ChannelCfg[CfgIndex].ChCFG1;
150 /* Update channel CFG0 */
151 *HWUnitConfigPtr->ChannelCfg[CfgIndex].ChCFG0Add = HWUnitConfigPtr->ChannelCfg[CfgIndex].ChCFG0 | MRU_IP_CH_CFG0_CHE_MASK;
152 }
153 }
154 }
155 /*================================================================================================*/
Mru_Ip_Transmit(const Mru_Ip_TransmitChannelType * TransmitChCfgPtr,const uint32 * TxBufferPtr)156 Mru_Ip_StatusType Mru_Ip_Transmit( const Mru_Ip_TransmitChannelType *TransmitChCfgPtr,
157 const uint32 *TxBufferPtr
158 )
159 {
160 uint8 BufferIndex = 0u;
161 Mru_Ip_StatusType Status = MRU_IP_STATUS_SUCCESS;
162
163 #if (MRU_IP_DEV_ERROR_DETECT == STD_ON)
164 DevAssert(NULL_PTR != TransmitChCfgPtr);
165 DevAssert(NULL_PTR != TxBufferPtr);
166 #endif
167
168 /* Check flag of last transmission MailBox, new data will be only wrote to Maiboxes if flag is cleared by receiver */
169 if(((*TransmitChCfgPtr->ChMBSTATAdd >> TransmitChCfgPtr->LastTxMBIndex) & MRU_IP_CH_MBSTAT_MBS0_MASK) == 0U)
170 {
171 /* Write data from Tx buffer to mailboxes */
172 for(BufferIndex = 0u; BufferIndex < TransmitChCfgPtr->NumTxMB; BufferIndex++)
173 {
174 *TransmitChCfgPtr->MBAddList[BufferIndex] = TxBufferPtr[BufferIndex];
175 }
176 }
177 else
178 {
179 Status = MRU_IP_STATUS_FAIL;
180 }
181
182 return Status;
183 }
184
185 /**
186 * @brief This function is called by MRU ISRs.
187 * @details This function will process MRU interrupts.
188 *
189 * @param[in] InstanceId Instance Id of the hardware unit.
190 * @param[in] IntGroupId Interrupt group Id of the hardware unit.
191 *
192 * @implements Mru_Ip_IrqHandler_Activity
193 */
Mru_Ip_IrqHandler(uint8 InstanceId,uint8 IntGroupId)194 void Mru_Ip_IrqHandler(uint8 InstanceId, uint8 IntGroupId)
195 {
196 const Mru_Ip_StateStructureType* State = Mru_Ip_apxStateStructureArray[InstanceId];
197 uint8 ChannelIdx = 0u;
198 uint32 NotifyStatus = 0u;
199 const Mru_Ip_ChannelCfgType * ChannelConfig = NULL_PTR;
200
201 /* Processing channels notification */
202 NotifyStatus = *State->HWUnitConfig->NOTIFYAdd[IntGroupId];
203 for(ChannelIdx = 0u; ChannelIdx < State->HWUnitConfig->NumChannel; ChannelIdx++)
204 {
205 if((NotifyStatus & MRU_IP_NOTIFY_CH1_IS_MASK) != 0u)
206 {
207 ChannelConfig = &State->HWUnitConfig->ChannelCfg[ChannelIdx];
208 if((*ChannelConfig->ChCFG0Add & MRU_IP_CH_CFG0_IE_MASK) != 0u)
209 {
210 /* Receive mail box */
211 Mru_Ip_IrqHandlerReceiveMb(ChannelConfig, IntGroupId);
212 }
213 else
214 {
215 /* Channel enable interrupt flag is not set, nothing to do */
216 }
217 }
218 else
219 {
220 /* Channel status flag is not set, nothing to do */
221 }
222 NotifyStatus = NotifyStatus >> 1u;
223 }
224 }
225
226 /**
227 * @brief This function is called by MRU ISRs.
228 * @details This function will process MRU interrupts.
229 *
230 * @param[in] InstanceId Instance Id of the hardware unit.
231 * @param[in] IntGroupId Interrupt group Id of the hardware unit.
232 *
233 * @implementsMru_Ip_IrqHandlerReceiveMb_Activity
234 */
Mru_Ip_IrqHandlerReceiveMb(const Mru_Ip_ChannelCfgType * ChannelConfig,uint8 IntGroupId)235 static void Mru_Ip_IrqHandlerReceiveMb(const Mru_Ip_ChannelCfgType * ChannelConfig, uint8 IntGroupId)
236 {
237 const Mru_Ip_MBLinkReceiveChannelType (* MBLinkReceiveChConfig)[2U];
238 volatile uint32 * ChMBSTATAddr;
239 uint32 MBStatus = 0u;
240 uint32 ChCFG1 = 0u;
241 uint32 MBIdx = 0u;
242 uint8 BufferIdx = 0u;
243 uint32 IntGroupCfg = ((uint32)IntGroupId) << MRU_IP_CH_CFG1_MBIC0_SHIFT;
244 const Mru_Ip_ReceiveChannelType * ReceiveChConfig = NULL_PTR;
245
246 MBLinkReceiveChConfig = ChannelConfig->MBLinkReceiveChCfg;
247 if(MBLinkReceiveChConfig != NULL_PTR)
248 {
249 ChMBSTATAddr = ChannelConfig->ChMBSTATAdd;
250 MBStatus = *ChMBSTATAddr;
251 ChCFG1 = *ChannelConfig->ChCFG1Add;
252 for(MBIdx = 0u; MBIdx < ChannelConfig->NumMailbox; MBIdx++)
253 {
254 if(((ChCFG1 & MRU_IP_CH_CFG1_MBIC0_MASK) == IntGroupCfg) && ((MBStatus & MRU_IP_CH_MBSTAT_MBS0_MASK) != 0u))
255 {
256 ReceiveChConfig = MBLinkReceiveChConfig[MBIdx][IntGroupId].ReceiveChCfg;
257 if(ReceiveChConfig != NULL_PTR)
258 {
259 /* Copy data to RxBuffer */
260 for(BufferIdx = 0u; BufferIdx < ReceiveChConfig->NumRxMB; BufferIdx++)
261 {
262 ReceiveChConfig->RxBuffer[BufferIdx] = *ReceiveChConfig->MBAddList[BufferIdx];
263 }
264 /* To support unidirectional communication, transmitter core will check Mailbox flag of Receiver MRU is cleared for triggering next transmit session.
265 Mailbox flag should be clear after copy data to buffer and before call notification */
266 *ChMBSTATAddr = (uint32)(MRU_IP_CH_MBSTAT_MBS0_MASK << MBIdx);
267 /* Call notification function */
268 if(NULL_PTR != ReceiveChConfig->ReceiveNotification)
269 {
270 ReceiveChConfig->ReceiveNotification(ReceiveChConfig->ChannelId,
271 ReceiveChConfig->RxBuffer,
272 ReceiveChConfig->NumRxMB
273 );
274 }
275 }
276 else
277 {
278 /* the mailbox was not configured using current interrupt group, nothing to do */
279 }
280 }
281 else
282 {
283 /* Mailbox status flag for current interrupt group is not set, nothing to do */
284 }
285 MBStatus = MBStatus >> 1u;
286 ChCFG1 = ChCFG1 >> 1u;
287 }
288 }
289 else
290 {
291 /* the channel was not used by the driver, nothing to do */
292 }
293 }
294
295 #define PLATFORM_STOP_SEC_CODE
296 #include "Platform_MemMap.h"
297
298 #ifdef __cplusplus
299 }
300 #endif
301
302 /** @} */
303