1 /*
2  * Copyright 2020-2023 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8 *   @file       Emios_Pwm_Ip_Irq.c
9 *
10 *   @addtogroup emios_pwm_ip Emios Pwm IPL
11 *   @{
12 */
13 
14 #ifdef __cplusplus
15 extern "C"{
16 #endif
17 
18 
19 /*==================================================================================================
20 *                                          INCLUDE FILES
21 * 1) system and project includes
22 * 2) needed interfaces from external units
23 * 3) internal and external interfaces from this unit
24 ==================================================================================================*/
25 #include "Emios_Pwm_Ip.h"
26 #include "Emios_Pwm_Ip_HwAccess.h"
27 #include "Emios_Pwm_Ip_Irq.h"
28 
29 /*==================================================================================================
30 *                                 SOURCE FILE VERSION INFORMATION
31 ==================================================================================================*/
32 #define EMIOS_PWM_IP_IRQ_VENDOR_ID_C                      43
33 #define EMIOS_PWM_IP_IRQ_AR_RELEASE_MAJOR_VERSION_C       4
34 #define EMIOS_PWM_IP_IRQ_AR_RELEASE_MINOR_VERSION_C       7
35 #define EMIOS_PWM_IP_IRQ_AR_RELEASE_REVISION_VERSION_C    0
36 #define EMIOS_PWM_IP_IRQ_SW_MAJOR_VERSION_C               3
37 #define EMIOS_PWM_IP_IRQ_SW_MINOR_VERSION_C               0
38 #define EMIOS_PWM_IP_IRQ_SW_PATCH_VERSION_C               0
39 
40 /*==================================================================================================
41 *                                       FILE VERSION CHECKS
42 ==================================================================================================*/
43 /* Check if source file and Emios_Pwm_Ip.h file are of the same vendor */
44 #if (EMIOS_PWM_IP_IRQ_VENDOR_ID_C != EMIOS_PWM_IP_VENDOR_ID)
45     #error "Vendor IDs of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip.h are different."
46 #endif
47 
48 /* Check if source file and Emios_Pwm_Ip.h file are of the same AUTOSAR version */
49 #if ((EMIOS_PWM_IP_IRQ_AR_RELEASE_MAJOR_VERSION_C    != EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION) || \
50      (EMIOS_PWM_IP_IRQ_AR_RELEASE_MINOR_VERSION_C    != EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION) || \
51      (EMIOS_PWM_IP_IRQ_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION))
52     #error "AUTOSAR version numbers of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip.h are different."
53 #endif
54 
55 /* Check if source file and Emios_Pwm_Ip.h file are of the same Software version */
56 #if ((EMIOS_PWM_IP_IRQ_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_SW_MAJOR_VERSION)  || \
57      (EMIOS_PWM_IP_IRQ_SW_MINOR_VERSION_C != EMIOS_PWM_IP_SW_MINOR_VERSION)  || \
58      (EMIOS_PWM_IP_IRQ_SW_PATCH_VERSION_C != EMIOS_PWM_IP_SW_PATCH_VERSION))
59     #error "Software version numbers of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip.h are different."
60 #endif
61 
62 /* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same vendor */
63 #if (EMIOS_PWM_IP_IRQ_VENDOR_ID_C != EMIOS_PWM_IP_HWACCESS_VENDOR_ID)
64     #error "Vendor IDs of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip_HwAccess.h are different."
65 #endif
66 
67 /* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same AUTOSAR version */
68 #if ((EMIOS_PWM_IP_IRQ_AR_RELEASE_MAJOR_VERSION_C    != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_MAJOR_VERSION) || \
69      (EMIOS_PWM_IP_IRQ_AR_RELEASE_MINOR_VERSION_C    != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_MINOR_VERSION) || \
70      (EMIOS_PWM_IP_IRQ_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_REVISION_VERSION))
71     #error "AUTOSAR version numbers of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip_HwAccess.h are different."
72 #endif
73 
74 /* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same Software version */
75 #if ((EMIOS_PWM_IP_IRQ_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_MAJOR_VERSION)  || \
76      (EMIOS_PWM_IP_IRQ_SW_MINOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_MINOR_VERSION)  || \
77      (EMIOS_PWM_IP_IRQ_SW_PATCH_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_PATCH_VERSION))
78     #error "Software version numbers of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip_HwAccess.h are different."
79 #endif
80 
81 /* Check if source file and Emios_Pwm_Ip_Irq.h file are of the same vendor */
82 #if (EMIOS_PWM_IP_IRQ_VENDOR_ID_C != EMIOS_PWM_IP_IRQ_VENDOR_ID)
83     #error "Vendor IDs of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip_Irq.h are different."
84 #endif
85 
86 /* Check if source file and Emios_Pwm_Ip_Irq.h file are of the same AUTOSAR version */
87 #if ((EMIOS_PWM_IP_IRQ_AR_RELEASE_MAJOR_VERSION_C    != EMIOS_PWM_IP_IRQ_AR_RELEASE_MAJOR_VERSION) || \
88      (EMIOS_PWM_IP_IRQ_AR_RELEASE_MINOR_VERSION_C    != EMIOS_PWM_IP_IRQ_AR_RELEASE_MINOR_VERSION) || \
89      (EMIOS_PWM_IP_IRQ_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_IRQ_AR_RELEASE_REVISION_VERSION))
90     #error "AUTOSAR version numbers of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip_Irq.h are different."
91 #endif
92 
93 /* Check if source file and Emios_Pwm_Ip_Irq.h file are of the same Software version */
94 #if ((EMIOS_PWM_IP_IRQ_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_IRQ_SW_MAJOR_VERSION)  || \
95      (EMIOS_PWM_IP_IRQ_SW_MINOR_VERSION_C != EMIOS_PWM_IP_IRQ_SW_MINOR_VERSION)  || \
96      (EMIOS_PWM_IP_IRQ_SW_PATCH_VERSION_C != EMIOS_PWM_IP_IRQ_SW_PATCH_VERSION))
97     #error "Software version numbers of Emios_Pwm_Ip_Irq.c and Emios_Pwm_Ip_Irq.h are different."
98 #endif
99 
100 /*==================================================================================================
101 *                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
102 ==================================================================================================*/
103 
104 
105 /*==================================================================================================
106 *                                       LOCAL MACROS
107 ==================================================================================================*/
108 
109 
110 /*==================================================================================================
111 *                                      LOCAL CONSTANTS
112 ==================================================================================================*/
113 
114 
115 /*==================================================================================================
116 *                                      LOCAL VARIABLES
117 ==================================================================================================*/
118 
119 
120 /*==================================================================================================
121 *                                      GLOBAL CONSTANTS
122 ==================================================================================================*/
123 
124 
125 /*==================================================================================================
126 *                                      GLOBAL VARIABLES
127 ==================================================================================================*/
128 #if (EMIOS_PWM_IP_USED == STD_ON)
129 #define PWM_START_SEC_CONST_UNSPECIFIED
130 #include "Pwm_MemMap.h"
131 
132 /** @brief Array with base addresses for Emios instances available on platform */
133 extern Emios_Pwm_Ip_HwAddrType *const Emios_Pwm_Ip_aBasePtr[EMIOS_PWM_IP_INSTANCE_COUNT];
134 
135 #define PWM_STOP_SEC_CONST_UNSPECIFIED
136 #include "Pwm_MemMap.h"
137 
138 #define PWM_START_SEC_VAR_CLEARED_UNSPECIFIED
139 #include "Pwm_MemMap.h"
140 
141 /** @brief Array with notification handlers for all configurable channels */
142 extern Emios_Pwm_Ip_NotificationType const *Emios_Pwm_Ip_aNotificationPtr[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED];
143 
144 #define PWM_STOP_SEC_VAR_CLEARED_UNSPECIFIED
145 #include "Pwm_MemMap.h"
146 
147 #define PWM_START_SEC_VAR_INIT_UNSPECIFIED
148 #include "Pwm_MemMap.h"
149 
150 /* Array with current pwm modes for each Emios Channel */
151 extern Emios_Pwm_Ip_PwmModeType Emios_Pwm_Ip_aCurrentModes[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED];
152 
153 #define PWM_STOP_SEC_VAR_INIT_UNSPECIFIED
154 #include "Pwm_MemMap.h"
155 
156 #ifdef EMIOS_PWM_IP_TIMER_WIDTH_24BITS
157 #define PWM_START_SEC_VAR_CLEARED_32
158 #include "Pwm_MemMap.h"
159 #else
160 #define PWM_START_SEC_VAR_CLEARED_16
161 #include "Pwm_MemMap.h"
162 #endif
163 
164 /** @brief Array with period for all channels */
165 extern Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_aPeriod[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED];
166 
167 /** @brief Array with duty cycle for all channels */
168 extern Emios_Pwm_Ip_DutyType Emios_Pwm_Ip_aDutyCycle[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED];
169 #ifdef EMIOS_PWM_IP_TIMER_WIDTH_24BITS
170 #define PWM_STOP_SEC_VAR_CLEARED_32
171 #include "Pwm_MemMap.h"
172 #else
173 #define PWM_STOP_SEC_VAR_CLEARED_16
174 #include "Pwm_MemMap.h"
175 #endif
176 
177 #define PWM_START_SEC_VAR_CLEARED_8
178 #include "Pwm_MemMap.h"
179 
180 /* Arrays to store the channel logic Index State */
181 extern uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT];
182 
183 /** @brief Arrays to check the state of Channel is initial state or uninitialized state or idle state */
184 extern uint8 Emios_Pwm_Ip_aCheckState[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED];
185 
186 /** @brief Arrays to check the state of Channel in the notification or not */
187 extern uint8 Emios_Pwm_Ip_aCheckEnableNotif[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED];
188 
189 #define PWM_STOP_SEC_VAR_CLEARED_8
190 #include "Pwm_MemMap.h"
191 /*==================================================================================================
192 *                                   LOCAL FUNCTION PROTOTYPES
193 ==================================================================================================*/
194 
195 
196 /*==================================================================================================
197 *                                       LOCAL FUNCTIONS
198 ==================================================================================================*/
199 
200 
201 /*==================================================================================================
202 *                                       GLOBAL FUNCTIONS
203 ==================================================================================================*/
204 #define PWM_START_SEC_CODE
205 #include "Pwm_MemMap.h"
206 #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
Emios_Pwm_Ip_IrqDaocHandler(uint8 Instance,uint8 Channel)207 static void Emios_Pwm_Ip_IrqDaocHandler(uint8 Instance, uint8 Channel)
208 {
209     Emios_Pwm_Ip_DutyType DaocDuty = 0U;
210     Emios_Pwm_Ip_DutyType DaocRegA = 0U;
211     Emios_Pwm_Ip_PeriodType DaocRegB = 0U;
212     Emios_Pwm_Ip_DutyType CounterMax = Emios_Pwm_Ip_GetUCRegA(Emios_Pwm_Ip_aBasePtr[Instance], Emios_Pwm_Ip_GetMasterBusChannel(Instance, Channel));
213 
214     Emios_Pwm_Ip_PolarityType Polarity = Emios_Pwm_Ip_GetEdgePolarity(Emios_Pwm_Ip_aBasePtr[Instance], Channel);
215     boolean OutputPin = Emios_Pwm_Ip_GetOutputPinState(Emios_Pwm_Ip_aBasePtr[Instance], Channel);
216 
217     if (EMIOS_PWM_IP_MODE_DAOC_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
218     {
219         DaocDuty = Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] - Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
220         DaocRegA = ((DaocDuty + Emios_Pwm_Ip_GetUCRegB(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) % CounterMax);
221 
222         Emios_Pwm_Ip_SetUCRegA(Emios_Pwm_Ip_aBasePtr[Instance], Channel, (DaocRegA == 0U)? CounterMax : DaocRegA);
223 
224         DaocRegB = (Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] + Emios_Pwm_Ip_GetUCRegB(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) % CounterMax;
225         Emios_Pwm_Ip_SetUCRegB(Emios_Pwm_Ip_aBasePtr[Instance], Channel, (DaocRegB == 0U)? CounterMax : DaocRegB);
226 
227     }
228     else if (EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
229     {
230         if (((EMIOS_PWM_IP_ACTIVE_HIGH == Polarity) && (FALSE == OutputPin)) ||
231             ((EMIOS_PWM_IP_ACTIVE_LOW == Polarity) && (TRUE == OutputPin)))
232         {
233             DaocRegA = (Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] + Emios_Pwm_Ip_GetUCRegA(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) % CounterMax;
234             Emios_Pwm_Ip_SetUCRegA(Emios_Pwm_Ip_aBasePtr[Instance], Channel, (DaocRegA == 0U)? CounterMax : DaocRegA);
235         }
236         else
237         {
238             DaocRegB = (Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] + Emios_Pwm_Ip_GetUCRegA(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) % CounterMax;
239             Emios_Pwm_Ip_SetUCRegB(Emios_Pwm_Ip_aBasePtr[Instance], Channel, (DaocRegB == 0U)? CounterMax : DaocRegB);
240         }
241     }
242     else
243     {
244         /* Do nothing */
245     }
246     (void)DaocDuty;
247     (void)DaocRegA;
248     (void)DaocRegB;
249     (void)Polarity;
250     (void)OutputPin;
251 }
252 #endif
253 /**
254 * @brief          Interrupt handler for Emios Pwm channels.
255 * @details        Interrupt handler that clears the flags and calls the user notification function.
256 *
257 * @param[in]      Instance    Emios Instance id on which the interrupt occured.
258 * @param[in]      Channel     Channel id within the emios Instance that triggered the interrupt.
259 * @implements Emios_Pwm_Ip_IrqHandler_Activity
260 */
Emios_Pwm_Ip_IrqHandler(uint8 Instance,uint8 Channel)261 void Emios_Pwm_Ip_IrqHandler(uint8 Instance, uint8 Channel)
262 {
263     /* Check the state of Channel is uninitialized state */
264     if ((0U == Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) &&
265         ((TRUE == Emios_Pwm_Ip_GetOverRunFlag(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) ||
266         (TRUE == Emios_Pwm_Ip_GetOverFlagEvent(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) ||
267         (TRUE == Emios_Pwm_Ip_GetOverFlowFlag(Emios_Pwm_Ip_aBasePtr[Instance], Channel))))
268     {
269         /* Clear Interrupt flag */
270         Emios_Pwm_Ip_ClearFlagEvent(Emios_Pwm_Ip_aBasePtr[Instance], Channel);
271     }
272     else
273     {
274         /*Interrupt Flag and Interrupt Enable is set*/
275         if ((TRUE == Emios_Pwm_Ip_GetInterruptRequest(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) &&
276             ((TRUE == Emios_Pwm_Ip_GetOverRunFlag(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) ||
277             (TRUE == Emios_Pwm_Ip_GetOverFlagEvent(Emios_Pwm_Ip_aBasePtr[Instance], Channel)) ||
278             (TRUE == Emios_Pwm_Ip_GetOverFlowFlag(Emios_Pwm_Ip_aBasePtr[Instance], Channel))))
279         {
280 #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
281             Emios_Pwm_Ip_IrqDaocHandler(Instance, Channel);
282 #endif
283             /* Clear Interrupt flag */
284             Emios_Pwm_Ip_ClearFlagEvent(Emios_Pwm_Ip_aBasePtr[Instance], Channel);
285 
286             if ((NULL_PTR != Emios_Pwm_Ip_aNotificationPtr[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]->CbFunction) &&
287                 (1U == Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]))
288             {
289                 /* Call the user notification callback with the provided parameter */
290                 (Emios_Pwm_Ip_aNotificationPtr[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]->CbFunction)(Emios_Pwm_Ip_aNotificationPtr[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]->CbParameter);
291             }
292         }
293     }
294 }
295 
296 #define PWM_STOP_SEC_CODE
297 #include "Pwm_MemMap.h"
298 
299 #endif /* EMIOS_PWM_IP_USED == STD_ON */
300 #ifdef __cplusplus
301 }
302 #endif
303 
304 /** @} */
305