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