1 /*
2  * Copyright 2021-2024 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8 *   @file       Emios_Pwm_Ip.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 
28 #if (EMIOS_PWM_IP_USED == STD_ON)
29 #include "Emios_Mcl_Ip.h"
30 #endif
31 
32 #include "SchM_Pwm.h"
33 
34 /*==================================================================================================
35 *                                 SOURCE FILE VERSION INFORMATION
36 ==================================================================================================*/
37 #define EMIOS_PWM_IP_VENDOR_ID_C                      43
38 #define EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C       4
39 #define EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C       7
40 #define EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION_C    0
41 #define EMIOS_PWM_IP_SW_MAJOR_VERSION_C               2
42 #define EMIOS_PWM_IP_SW_MINOR_VERSION_C               0
43 #define EMIOS_PWM_IP_SW_PATCH_VERSION_C               0
44 
45 /*==================================================================================================
46 *                                       FILE VERSION CHECKS
47 ==================================================================================================*/
48 #ifndef DISABLE_MCAL_INTERMODULE_ASR_CHECK
49 
50 #if (EMIOS_PWM_IP_USED == STD_ON)
51     /* Check if header file and Emios_Mcl_Ip.h are of the same AUTOSAR version */
52     #if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C != EMIOS_MCL_IP_AR_RELEASE_MAJOR_VERSION) || \
53          (EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C != EMIOS_MCL_IP_AR_RELEASE_MINOR_VERSION))
54         #error "AUTOSAR Version Numbers of Emios_Pwm_Ip.c and Emios_Mcl_Ip.h are different"
55     #endif
56 #endif
57 
58     /* Check if this source file and SchM_Pwm.h file are of the same Autosar version */
59     #if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C != SCHM_PWM_AR_RELEASE_MAJOR_VERSION) || \
60         (EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C != SCHM_PWM_AR_RELEASE_MINOR_VERSION))
61         #error "AutoSar Version Numbers of Emios_Pwm_Ip.c and SchM_Pwm.h are different"
62     #endif
63 #endif
64 
65 /* Check if source file and Emios_Pwm_Ip.h file are of the same vendor */
66 #if (EMIOS_PWM_IP_VENDOR_ID_C != EMIOS_PWM_IP_VENDOR_ID)
67     #error "Vendor IDs of Emios_Pwm_Ip.c and Emios_Pwm_Ip.h are different."
68 #endif
69 
70 /* Check if source file and Emios_Pwm_Ip.h file are of the same AUTOSAR version */
71 #if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C    != EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION) || \
72      (EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C    != EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION) || \
73      (EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION))
74     #error "AUTOSAR version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip.h are different."
75 #endif
76 
77 /* Check if source file and Emios_Pwm_Ip.h file are of the same Software version */
78 #if ((EMIOS_PWM_IP_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_SW_MAJOR_VERSION)  || \
79      (EMIOS_PWM_IP_SW_MINOR_VERSION_C != EMIOS_PWM_IP_SW_MINOR_VERSION)  || \
80      (EMIOS_PWM_IP_SW_PATCH_VERSION_C != EMIOS_PWM_IP_SW_PATCH_VERSION))
81     #error "Software version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip.h are different."
82 #endif
83 
84 /* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same vendor */
85 #if (EMIOS_PWM_IP_VENDOR_ID_C != EMIOS_PWM_IP_HWACCESS_VENDOR_ID)
86     #error "Vendor IDs of Emios_Pwm_Ip.c and Emios_Pwm_Ip_HwAccess.h are different."
87 #endif
88 
89 /* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same AUTOSAR version */
90 #if ((EMIOS_PWM_IP_AR_RELEASE_MAJOR_VERSION_C    != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_MAJOR_VERSION) || \
91      (EMIOS_PWM_IP_AR_RELEASE_MINOR_VERSION_C    != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_MINOR_VERSION) || \
92      (EMIOS_PWM_IP_AR_RELEASE_REVISION_VERSION_C != EMIOS_PWM_IP_HWACCESS_AR_RELEASE_REVISION_VERSION))
93     #error "AUTOSAR version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip_HwAccess.h are different."
94 #endif
95 
96 /* Check if source file and Emios_Pwm_Ip_HwAccess.h file are of the same Software version */
97 #if ((EMIOS_PWM_IP_SW_MAJOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_MAJOR_VERSION)  || \
98      (EMIOS_PWM_IP_SW_MINOR_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_MINOR_VERSION)  || \
99      (EMIOS_PWM_IP_SW_PATCH_VERSION_C != EMIOS_PWM_IP_HWACCESS_SW_PATCH_VERSION))
100     #error "Software version numbers of Emios_Pwm_Ip.c and Emios_Pwm_Ip_HwAccess.h are different."
101 #endif
102 
103 /*==================================================================================================
104 *                           LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
105 ==================================================================================================*/
106 
107 /*==================================================================================================
108 *                                          LOCAL MACROS
109 ==================================================================================================*/
110 
111 /*==================================================================================================
112 *                                         LOCAL CONSTANTS
113 ==================================================================================================*/
114 
115 /*==================================================================================================
116 *                                         LOCAL VARIABLES
117 ==================================================================================================*/
118 
119 /*==================================================================================================
120 *                                        GLOBAL CONSTANTS
121 ==================================================================================================*/
122 
123 /*==================================================================================================
124 *                                        GLOBAL VARIABLES
125 ==================================================================================================*/
126 #if (EMIOS_PWM_IP_USED == STD_ON)
127 
128 #define PWM_START_SEC_CONST_UNSPECIFIED
129 #include "Pwm_MemMap.h"
130 
131 /** @brief Array with Base addresses for Emios instances available on platform */
132 Emios_Pwm_Ip_HwAddrType *const Emios_Pwm_Ip_aBasePtr[EMIOS_PWM_IP_INSTANCE_COUNT] = IP_eMIOS_BASE_PTRS;
133 
134 #define PWM_STOP_SEC_CONST_UNSPECIFIED
135 #include "Pwm_MemMap.h"
136 
137 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
138 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
139     #define PWM_START_SEC_VAR_INIT_32_NO_CACHEABLE
140 #else
141     #define PWM_START_SEC_VAR_INIT_32
142 #endif
143 #include "Pwm_MemMap.h"
144 
145 /* Array with available pwm modes for each Emios Channel */
146 static uint32 Emios_Pwm_Ip_aChannelModes[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_MODES] = EMIOS_PWM_IP_CHANNEL_MODES;
147 
148 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
149     #define PWM_STOP_SEC_VAR_INIT_32_NO_CACHEABLE
150 #else
151     #define PWM_STOP_SEC_VAR_INIT_32
152 #endif
153 #include "Pwm_MemMap.h"
154 #endif
155 
156 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
157     #define PWM_START_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
158 #else
159     #define PWM_START_SEC_VAR_INIT_UNSPECIFIED
160 #endif
161 #include "Pwm_MemMap.h"
162 
163 /* Array with initial pwm modes for each Emios Channel */
164 static Emios_Pwm_Ip_PwmModeType Emios_Pwm_Ip_aInitialModes[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8] = EMIOS_PWM_IP_INITIAL_MODES;
165 
166 /* Array with current pwm modes for each Emios Channel */
167 Emios_Pwm_Ip_PwmModeType Emios_Pwm_Ip_aCurrentModes[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8] = EMIOS_PWM_IP_INITIAL_MODES;
168 
169 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
170     #define PWM_STOP_SEC_VAR_INIT_UNSPECIFIED_NO_CACHEABLE
171 #else
172     #define PWM_STOP_SEC_VAR_INIT_UNSPECIFIED
173 #endif
174 #include "Pwm_MemMap.h"
175 
176 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
177     #define PWM_START_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
178 #else
179     #define PWM_START_SEC_VAR_CLEARED_UNSPECIFIED
180 #endif
181 #include "Pwm_MemMap.h"
182 
183 /** @brief Array with notification handlers for all configurable channels */
184 Emios_Pwm_Ip_NotificationType const *Emios_Pwm_Ip_aNotificationPtr[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
185 
186 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
187     #define PWM_STOP_SEC_VAR_CLEARED_UNSPECIFIED_NO_CACHEABLE
188 #else
189     #define PWM_STOP_SEC_VAR_CLEARED_UNSPECIFIED
190 #endif
191 #include "Pwm_MemMap.h"
192 
193 #ifdef EMIOS_PWM_IP_TIMER_WIDTH_24BITS
194 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
195     #define PWM_START_SEC_VAR_CLEARED_32_NO_CACHEABLE
196 #else
197     #define PWM_START_SEC_VAR_CLEARED_32
198 #endif
199 #else
200 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
201     #define PWM_START_SEC_VAR_CLEARED_16_NO_CACHEABLE
202 #else
203     #define PWM_START_SEC_VAR_CLEARED_16
204 #endif
205 #endif
206 #include "Pwm_MemMap.h"
207 /** @brief Array with period for each channels */
208 Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_aPeriod[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
209 
210 #if (defined(EMIOS_PWM_IP_MODE_OPWM_USED) || defined(EMIOS_PWM_IP_MODE_OPWMB_USED) || defined(EMIOS_PWM_IP_MODE_OPWMT_USED))
211 /** @brief Array to store register A value for each channels */
212 static Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_aRegA[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
213 #endif
214 
215 /** @brief Array with duty cycle for all channels */
216 Emios_Pwm_Ip_DutyType Emios_Pwm_Ip_aDutyCycle[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
217 #ifdef EMIOS_PWM_IP_TIMER_WIDTH_24BITS
218 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
219     #define PWM_STOP_SEC_VAR_CLEARED_32_NO_CACHEABLE
220 #else
221     #define PWM_STOP_SEC_VAR_CLEARED_32
222 #endif
223 #else
224 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
225     #define PWM_STOP_SEC_VAR_CLEARED_16_NO_CACHEABLE
226 #else
227     #define PWM_STOP_SEC_VAR_CLEARED_16
228 #endif
229 #endif
230 #include "Pwm_MemMap.h"
231 
232 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
233     #define PWM_START_SEC_VAR_CLEARED_8_NO_CACHEABLE
234 #else
235     #define PWM_START_SEC_VAR_CLEARED_8
236 #endif
237 #include "Pwm_MemMap.h"
238 
239 /** @brief Arrays to check the condition whether Channel can be enale notification or not */
240 static uint8 Emios_Pwm_Ip_aNotif[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
241 
242 /** @brief Arrays to check the state of Channel in the notification or not */
243 uint8 Emios_Pwm_Ip_aCheckEnableNotif[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
244 
245 #if (defined(EMIOS_PWM_IP_MODE_OPWFM_USED) || defined(EMIOS_PWM_IP_MODE_DAOC_USED))
246 /** @brief Arrays with the polarity of channels */
247 static uint8 Emios_Pwm_Ip_aPolarity[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
248 #endif
249 
250 /** @brief Arrays to check the state of Channel is initial state or uninitialized state or idle state */
251 uint8 Emios_Pwm_Ip_aCheckState[EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8];
252 
253 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
254     #define PWM_STOP_SEC_VAR_CLEARED_8_NO_CACHEABLE
255 #else
256     #define PWM_STOP_SEC_VAR_CLEARED_8
257 #endif
258 #include "Pwm_MemMap.h"
259 
260 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
261     #define PWM_START_SEC_VAR_INIT_8_NO_CACHEABLE
262 #else
263     #define PWM_START_SEC_VAR_INIT_8
264 #endif
265 #include "Pwm_MemMap.h"
266 
267 /* Arrays to store the channel logic Index State */
268 uint8 eMios_Pwm_Ip_IndexInChState[EMIOS_PWM_IP_INSTANCE_COUNT][EMIOS_PWM_IP_CHANNEL_COUNT] = EMIOS_PWM_IP_USED_CHANNELS;
269 
270 #if (EMIOS_PWM_IP_NO_CACHE_NEEDED == STD_ON)
271     #define PWM_STOP_SEC_VAR_INIT_8_NO_CACHEABLE
272 #else
273     #define PWM_STOP_SEC_VAR_INIT_8
274 #endif
275 #include "Pwm_MemMap.h"
276 /*==================================================================================================
277 *                                    LOCAL FUNCTION PROTOTYPES
278 ==================================================================================================*/
279 
280 /*==================================================================================================
281 *                                         LOCAL FUNCTIONS
282 ==================================================================================================*/
283 #define PWM_START_SEC_CODE
284 #include "Pwm_MemMap.h"
285 
286 #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
287 /*FUNCTION**********************************************************************
288  *
289  * Function Name : Emios_Pwm_Ip_SetOutputToNormalOpwfm
290  * Description   : Set the polarity and Mode for current Channel as normal for OPWFM mode.
291  *
292  *END**************************************************************************/
Emios_Pwm_Ip_SetOutputToNormalOpwfm(uint8 Instance,uint8 Channel,uint16 DutyPercent,Emios_Pwm_Ip_PolarityType Polarity,Emios_Pwm_Ip_PwmModeType Mode)293 static inline void Emios_Pwm_Ip_SetOutputToNormalOpwfm(uint8 Instance,
294                                                        uint8 Channel,
295                                                        uint16 DutyPercent,
296                                                        Emios_Pwm_Ip_PolarityType Polarity,
297                                                        Emios_Pwm_Ip_PwmModeType  Mode
298                                                       )
299 {
300     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
301 
302     if(0x0U == DutyPercent)
303     {
304        Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW);
305     }
306     else
307     {
308        Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH);
309     }
310 
311     Emios_Pwm_Ip_SetPwmMode(Base, Channel, Mode);
312 
313     if(0x8000U == DutyPercent)
314     {
315        Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW);
316     }
317     else
318     {
319         /* Do nothing */
320     }
321 }
322 #endif
323 
324 #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
325 /*FUNCTION**********************************************************************
326  *
327  * Function Name : Emios_Pwm_Ip_SetOutputToNormalOpwm
328  * Description   : Set the polarity and Mode for current Channel as normal for OPWM mode.
329  *
330  *END**************************************************************************/
Emios_Pwm_Ip_SetOutputToNormalOpwm(uint8 Instance,uint8 Channel,uint16 DutyPercent,Emios_Pwm_Ip_PolarityType Polarity,Emios_Pwm_Ip_PwmModeType Mode)331 static inline void Emios_Pwm_Ip_SetOutputToNormalOpwm(uint8 Instance,
332                                                       uint8 Channel,
333                                                       uint16 DutyPercent,
334                                                       Emios_Pwm_Ip_PolarityType Polarity,
335                                                       Emios_Pwm_Ip_PwmModeType  Mode
336                                                      )
337 {
338     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
339 
340     if (0x8000U == DutyPercent)
341     {
342         /* To avoid spike pulse
343         If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
344         after that, EDPOL bit is restored valid value */
345         Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH);
346     }
347     else
348     {
349         Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW);
350     }
351 
352     Emios_Pwm_Ip_SetPwmMode(Base, Channel, Mode);
353 
354     if (0x8000U == DutyPercent)
355     {
356         /* Configure output pin polarity */
357         Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW);
358     }
359     else
360     {
361         /* Do nothing */
362     }
363 
364     Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, Polarity);
365 }
366 #endif
367 
368 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
369 /*---------------------Validation API------------------------*/
370 
371 /*FUNCTION**********************************************************************
372  *
373  * Function Name : Emios_Pwm_Ip_ValidateMode
374  * Description   : Validate a eMIOS Mode can run on the Channel or not.
375  *END**************************************************************************/
Emios_Pwm_Ip_ValidateMode(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_PwmType Mode)376 static inline boolean Emios_Pwm_Ip_ValidateMode(uint8  Instance,
377                                                 uint8  Channel,
378                                                 Emios_Pwm_Ip_PwmType Mode
379                                                )
380 {
381     boolean Ret = FALSE;
382     if((uint8)Mode < (uint8)EMIOS_PWM_IP_MODES)
383     {
384         Ret = (((Emios_Pwm_Ip_aChannelModes[Instance][(uint8)Mode] >> Channel) & 0x01UL) == 1UL) ? TRUE : FALSE;
385     }
386     else
387     {
388         /* Avoid compiler warning */
389         (void) Instance;
390         (void) Channel;
391         (void) Mode;
392     }
393     return Ret;
394 }
395 
396 #endif
397 
398 /*FUNCTION**********************************************************************
399  *
400  * Function Name : Emios_Pwm_Ip_GetCounterBusPeriod
401  * Description   : Return the period for Channel using an external counter bus.
402  * Only used for channels in OPWMB/OPWMCB/OPWMT modes
403  *
404  *END**************************************************************************/
Emios_Pwm_Ip_GetCounterBusPeriod(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_CounterBusSourceType CounterBus)405 static inline Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_GetCounterBusPeriod(uint8 Instance,
406                                                                        uint8 Channel,
407                                                                        Emios_Pwm_Ip_CounterBusSourceType CounterBus
408                                                                       )
409 {
410 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
411     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
412     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
413 #endif
414 
415     Emios_Pwm_Ip_PeriodType ChPeriod = 0U;
416     uint8 MasterBusCh = Emios_Pwm_Ip_GetTimebaseChannel(Channel, CounterBus);
417 
418 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
419     /* The used channel in internal counter or undefined mode. */
420     DevAssert(0xFFU != MasterBusCh);
421 #endif
422 
423     if(MasterBusCh < EMIOS_PWM_IP_CHANNEL_COUNT)
424     {
425         ChPeriod = Emios_Mcl_Ip_GetCounterBusPeriod(Instance, MasterBusCh);
426     }
427     else
428     {
429         /* Do nothing */
430     }
431 
432     return ChPeriod;
433 }
434 
435 /*FUNCTION**********************************************************************
436  *
437  * Function Name : Emios_Pwm_Ip_GetCounterBusMode
438  * Description   : Return the counter bus Mode for Channel using an external counter bus.
439  * Only used for channels in OPWMB/OPWMCB/OPWMT modes
440  *
441  *END**************************************************************************/
Emios_Pwm_Ip_GetCounterBusMode(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_CounterBusSourceType CounterBus)442 static inline Emios_Pwm_Ip_MasterBusModeType Emios_Pwm_Ip_GetCounterBusMode(uint8 Instance,
443                                                                             uint8 Channel,
444                                                                             Emios_Pwm_Ip_CounterBusSourceType CounterBus
445                                                                            )
446 {
447 
448     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
449     Emios_Pwm_Ip_MasterBusModeType CounterBusMode;
450     switch (CounterBus)
451     {
452         case EMIOS_PWM_IP_BUS_A:
453             CounterBusMode = (Emios_Pwm_Ip_MasterBusModeType)Emios_Pwm_Ip_GetChannelPwmMode(Base, EMIOS_PWM_IP_COUNTER_BUS_A);
454             break;
455         case EMIOS_PWM_IP_BUS_BCDE:
456             CounterBusMode = (Emios_Pwm_Ip_MasterBusModeType)Emios_Pwm_Ip_GetChannelPwmMode(Base, (Channel & (uint8)EMIOS_PWM_IP_COUNTER_BUS_BCDE));
457             break;
458         case EMIOS_PWM_IP_BUS_F:
459             CounterBusMode = (Emios_Pwm_Ip_MasterBusModeType)Emios_Pwm_Ip_GetChannelPwmMode(Base, EMIOS_PWM_IP_COUNTER_BUS_F);
460             break;
461         default:
462             /* internal counter bus */
463             CounterBusMode = EMIOS_PWM_IP_NODEFINE_COUNTER;
464             break;
465     }
466 
467     return CounterBusMode;
468 }
469 #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
470 /*FUNCTION**********************************************************************
471  *
472  * Function Name : Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmbMode
473  * Description   : Initial Output Pulse Width and Frequency Modulation Buffered Mode - OPWFMB Mode.
474  * This Mode provides waveforms with variable duty cycle and frequency. The internal Channel counter
475  * is automatically selected as the time Base when this Mode is selected.
476  *END**************************************************************************/
Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmbMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)477 static void Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmbMode(uint8 Instance,
478                                                        Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
479                                                       )
480 {
481 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
482     DevAssert(NULL_PTR != UserChCfg);
483     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
484     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
485     /* Check Selected Channel is set for OPWFMB */
486     DevAssert((UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWFMB_FLAG) ||
487               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWFMB_FLAG_BOTH));
488     /* Check that Channel has internal counter for this Mode */
489     DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWFMB));
490     /* Validate parametter */
491     DevAssert(EMIOS_PWM_IP_MIN_CNT_VAL < UserChCfg->PeriodCount);
492     DevAssert(UserChCfg->DutyCycle <= UserChCfg->PeriodCount);
493 #endif
494 
495     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
496 
497     /* Configure OPWFMB special parameters */
498     /* Configure Counter Bus used by this Channel */
499     Emios_Pwm_Ip_SetCounterBus(Base, UserChCfg->ChannelId, UserChCfg->Timebase);
500     /* Configure DutyCycle in reg A */
501     Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, UserChCfg->DutyCycle);
502     /* Configure Period in reg B */
503     Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, UserChCfg->PeriodCount);
504 
505     Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->PeriodCount;
506 
507     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
508     {   /* 100% DutyCycle is desired. */
509         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
510         /* To avoid spike pulse
511         If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
512         after that, EDPOL bit is restored valid value */
513         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
514     }
515     else if(0U == UserChCfg->DutyCycle)
516     {
517         /* 0% DutyCycle is desired. */
518         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
519         /* Configure output pin polarity */
520         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
521     }
522     else
523     {
524         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)0U;
525     }
526     /* Transition from GPIO Mode to OPWFMB Mode */
527     Emios_Pwm_Ip_SetPwmMode(Base, UserChCfg->ChannelId, UserChCfg->Mode);
528     /* Configure output pin polarity */
529     Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
530     /* Stores the inital duty cycle in ticks */
531     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->DutyCycle;
532 }
533 #endif /* EMIOS_PWM_IP_MODE_OPWFMB_USED */
534 
535 #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
536 /*FUNCTION**********************************************************************
537  *
538  * Function Name : Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmMode
539  * Description   : Initial Output Pulse Width and Frequency Modulation Mode - OPWFM Mode.
540  * This Mode provides waveforms with variable duty cycle and frequency. The internal Channel counter
541  * is automatically selected as the time Base when this Mode is selected.
542  *END**************************************************************************/
Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)543 static void Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmMode(uint8 Instance,
544                                                       Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
545                                                      )
546 {
547 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
548     DevAssert(NULL_PTR != UserChCfg);
549     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
550     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
551     /* Check Selected Channel is set for OPWFM*/
552     DevAssert((UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG) ||
553               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG_BOTH) ||
554               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG) ||
555               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG_BOTH));
556     /* Check that Channel has internal counter for this Mode */
557     DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWFM));
558     /* Validate parametter */
559     DevAssert(EMIOS_PWM_IP_MIN_CNT_VAL < UserChCfg->PeriodCount);
560     DevAssert(UserChCfg->DutyCycle <= UserChCfg->PeriodCount);
561 #endif
562 
563     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
564 
565     /* Configure OPWFM special parameters */
566     /* Configure Counter Bus used by this Channel */
567     Emios_Pwm_Ip_SetCounterBus(Base, UserChCfg->ChannelId, UserChCfg->Timebase);
568     /* Configure DutyCycle in reg A */
569     Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, UserChCfg->DutyCycle);
570     /* Configure Period in reg B */
571     Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, UserChCfg->PeriodCount);
572 
573     Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->PeriodCount;
574 
575     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
576     {   /* 100% DutyCycle is desired. */
577         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
578         /* To avoid spike pulse
579         If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
580         after that, EDPOL bit is restored valid value */
581         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
582     }
583     else if(0U == UserChCfg->DutyCycle)
584     {
585         /* 0% DutyCycle is desired. */
586         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
587         /* Configure output pin polarity */
588         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW );
589     }
590     else
591     {
592         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)0U;
593         /* Configure output pin polarity */
594         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
595     }
596 
597     /* Transition from GPIO Mode to OPWFM Mode */
598     Emios_Pwm_Ip_SetPwmMode(Base, UserChCfg->ChannelId, UserChCfg->Mode);
599 
600     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
601     {
602         /* Configure output pin polarity */
603         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW );
604     }
605 
606     /* Stores the inital duty cycle in ticks */
607     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->DutyCycle;
608     Emios_Pwm_Ip_aPolarity[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH)? 1U : 0U;
609 }
610 #endif /* EMIOS_PWM_IP_MODE_OPWFM_USED */
611 
612 #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
613 /*FUNCTION**********************************************************************
614  *
615  * Function Name : Emios_Pwm_Ip_SetDutyCycleOpwfmb
616  * Description   : Set new duty cycle for the Channel in OPWFMB Mode
617  * This function will check the specific duty cycle and set new duty cycle for
618  * this Channel
619  *
620  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleOpwfmb(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)621 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwfmb(uint8  Instance,
622                                                                       uint8  Channel,
623                                                                       Emios_Pwm_Ip_DutyType NewDutyCycle
624                                                                      )
625 {
626 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
627     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
628     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
629 #endif
630     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
631     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
632 
633     /* OPWFMB Mode */
634     if ((NewDutyCycle > Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) && ((Emios_Pwm_Ip_PeriodType)0U != Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]))
635     {   /* Duty cycle value should not be greater than the Channel Period. */
636         Ret = EMIOS_PWM_IP_STATUS_ERROR;
637     }
638     else if ((Emios_Pwm_Ip_PeriodType)0U == Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
639     {
640         /* Disable and clear interrupt flag */
641         Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
642         Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
643         /* If new period is 0, set duty cycle to 0 */
644         Emios_Pwm_Ip_SetUCRegA(Base, Channel, (Emios_Pwm_Ip_PeriodType)0U);
645         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
646     }
647     else
648     {
649         if(NewDutyCycle == 0U)
650         {
651             /* Disable and clear interrupt flag */
652             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
653             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
654             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
655         }
656         else if (NewDutyCycle == Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
657         {
658             /* Disable and clear interrupt flag */
659             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
660             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
661             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
662         }
663         else
664         {
665             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)0U;
666             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, (Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == 0U)? FALSE : TRUE);
667         }
668 
669         Emios_Pwm_Ip_SetUCRegA(Base, Channel, NewDutyCycle);
670     }
671 
672     /* Stores the new duty cycle in ticks */
673     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = NewDutyCycle;
674 
675     return Ret;
676 }
677 #endif
678 
679 #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
680 /*FUNCTION**********************************************************************
681  *
682  * Function Name : Emios_Pwm_Ip_SetDutyCycleOpwfm
683  * Description   : Set new duty cycle for the Channel in OPWFM Mode
684  * This function will check the specific duty cycle and set new duty cycle for
685  * this Channel
686  *
687  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleOpwfm(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)688 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwfm(uint8  Instance,
689                                                                      uint8  Channel,
690                                                                      Emios_Pwm_Ip_DutyType NewDutyCycle
691                                                                     )
692 {
693 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
694     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
695     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
696 #endif
697     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
698     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
699 
700     /* OPWFM Mode */
701     if ((NewDutyCycle > Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) && ((Emios_Pwm_Ip_PeriodType)0U != Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]))
702     {   /* Duty cycle value should not be greater than the Channel Period. */
703         Ret = EMIOS_PWM_IP_STATUS_ERROR;
704     }
705     else if ((Emios_Pwm_Ip_PeriodType)0U == Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
706     {
707         /* Disable and clear interrupt flag */
708         Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
709         Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
710         /* If new period is 0, set duty cycle to 0 */
711         Emios_Pwm_Ip_SetUCRegA(Base, Channel, (Emios_Pwm_Ip_PeriodType)0U);
712         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
713         /* Set polarity when channels is in active state */
714         if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
715         {
716             /* Reverse output pin polarity */
717             Emios_Pwm_Ip_SetEdgePolarity(Base, Channel,(Emios_Pwm_Ip_aPolarity[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == (uint16)1U) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW );
718         }
719     }
720     else
721     {
722         if(NewDutyCycle == 0U)
723         {
724             /* Disable and clear interrupt flag */
725             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
726             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
727             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
728             /* Set polarity when channels is in active state */
729             if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
730             {
731                 /* Reverse output pin polarity */
732                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel,(Emios_Pwm_Ip_aPolarity[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == (uint16)1U) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW );
733             }
734         }
735         else if (NewDutyCycle == Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
736         {
737             /* Disable and clear interrupt flag */
738             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
739             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
740             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
741             /* Set polarity when channels is in active state */
742             if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
743             {
744                 /* Reverse output pin polarity */
745                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel,(Emios_Pwm_Ip_aPolarity[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == (uint16)1U) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW );
746             }
747         }
748         else
749         {
750             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)0U;
751             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, (Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == 0U)? FALSE : TRUE);
752             /* Set polarity when channels is in active state */
753             if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
754             {
755                 /* Configure output pin polarity */
756                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel,(Emios_Pwm_Ip_aPolarity[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == (uint16)1U) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
757             }
758         }
759 
760         Emios_Pwm_Ip_SetUCRegA(Base, Channel, NewDutyCycle);
761     }
762 
763     /* Stores the new duty cycle in ticks */
764     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = NewDutyCycle;
765 
766     return Ret;
767 }
768 #endif
769 
770 #if (defined EMIOS_PWM_IP_MODE_OPWMCB_USED)
771 /*FUNCTION**********************************************************************
772  *
773  * Function Name : Emios_Pwm_Ip_InitDeadTimeMode
774  * Description   : Initial Center Aligned Output Pulse Width Modulation with Dead Time Insertion (Buffered Mode - OPWMCB, Nonbuffered Mode - OPWMC).
775  * This operation Mode generates a center aligned PWM with dead time insertion to the leading or trailing edge.
776  * Allow smooth output signal generation when changing duty cycle and deadtime values.
777  *
778  * The time Base selected for a Channel configured to OPWMCB or OPWMC Mode should be a Channel configured to MCB or MC Up/Down Mode.
779  * It is recommended to start the Channel time Base after the OPWMCB or OPWMC Mode is entered
780  * in order to avoid missing A matches at the very first duty cycle.
781  *
782  * The internal counter runs in the internal prescaler ratio, while the selected time Base
783  * may be running in a different prescaler ratio.
784  *
785  *END**************************************************************************/
Emios_Pwm_Ip_InitDeadTimeMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)786 static void Emios_Pwm_Ip_InitDeadTimeMode(uint8 Instance,
787                                           Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
788                                          )
789 {
790 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
791     DevAssert(NULL_PTR != UserChCfg);
792     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
793     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
794     /* Check Selected Channel is set for OPWMCB or OPWMC*/
795     DevAssert((UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
796               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
797               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
798               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH));
799     /* Check selected Channel supports OPWMCB or OPWMC Mode */
800     DevAssert((TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWMCB)) ||
801               (TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWMC)));
802     /* Check selected counter bus is configured in MCB or MC Up-Down Mode */
803     DevAssert((EMIOS_PWM_IP_MCB_UP_DOWN_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) ||
804               (EMIOS_PWM_IP_MC_UP_DOWN_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)));
805     /* Validate OPWMCB or OPWMC parametter */
806     DevAssert(((2U * Emios_Pwm_Ip_GetCounterBusPeriod(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) - 2U) >= UserChCfg->DutyCycle);
807 #endif
808 
809     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
810     Emios_Pwm_Ip_PeriodType DutyCycle = 0U;
811 
812     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
813     {   /* 100% DutyCycle is desired. */
814         if((UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
815            (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
816            (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
817            (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH))
818         {
819             DutyCycle = 1U;
820         }
821         else
822         {
823             /* Do nothing */
824         }
825         /* To avoid spike pulse
826         If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
827         after that, EDPOL bit is restored valid value */
828         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
829         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
830     }
831     else if((0U == UserChCfg->DutyCycle) || (1U == UserChCfg->DutyCycle))
832     {
833         /* 0% DutyCycle is desired. */
834         DutyCycle = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, UserChCfg->ChannelId, UserChCfg->Timebase) + (uint8)1U;
835         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
836         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
837     }
838     else
839     {
840         DutyCycle = (UserChCfg->DutyCycle) >> (uint8)1U;
841         DutyCycle = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, UserChCfg->ChannelId, UserChCfg->Timebase) - DutyCycle;
842         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)0U;
843         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
844     }
845 
846     /* Configure OPWMCB or OPWMC special parameters */
847     /* Configure Counter Bus used by this Channel */
848     Emios_Pwm_Ip_SetCounterBus(Base, UserChCfg->ChannelId, UserChCfg->Timebase);
849     /* Configure DutyCycle in reg A */
850     Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, DutyCycle);
851     /* Configure DeadTime in reg B */
852     Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, UserChCfg->DeadTime);
853     /* Transition from GPIO Mode to OPWMCB or OPWMC Mode */
854     Emios_Pwm_Ip_SetPwmMode(Base, UserChCfg->ChannelId, UserChCfg->Mode);
855     /* Configure output pin polarity */
856     Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
857     /* Stores the inital duty cycle in ticks */
858     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->DutyCycle;
859 }
860 #endif
861 
862 #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED
863 /*FUNCTION**********************************************************************
864  *
865  * Function Name : Emios_Pwm_Ip_SetDutyCycleOpwmcb
866  * Description   : Set new duty cycle for the Channel in OPWMCB Mode
867  * This function will check the specific duty cycle and set new duty cycle for
868  * this Channel
869  *
870  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleOpwmcb(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)871 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwmcb(uint8  Instance,
872                                                                       uint8  Channel,
873                                                                       Emios_Pwm_Ip_DutyType NewDutyCycle
874                                                                      )
875 {
876 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
877     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
878     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
879 #endif
880     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
881     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
882     Emios_Pwm_Ip_PeriodType ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel));
883     /* Get the value of channel Index */
884     uint8 ChannelIdx = Emios_Pwm_Ip_GetChannelIndex(Instance, Channel);
885 
886     if (ChannelIdx < EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8)
887     {
888         /* OPWMCB Mode */
889         if(NewDutyCycle > ((ChPeriod * 2U) - 2U))
890         { /* Duty cycle value should not be greater than the Channel Period. */
891             Ret = EMIOS_PWM_IP_STATUS_ERROR;
892         }
893         else if(0U == NewDutyCycle)
894         {
895             /* Disable and clear interrupt flag */
896             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
897             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
898 
899             Emios_Pwm_Ip_SetUCRegA(Base, Channel, ChPeriod + 1U);
900             Emios_Pwm_Ip_aNotif[ChannelIdx] = (uint8)1U;
901             /* This statement is required to avoid limitation of 0% duty cycle (if call 100% to 0%) */
902             if(1U == Emios_Pwm_Ip_GetUCRegA(Base, Channel))
903             {
904                 if((Emios_Pwm_Ip_aInitialModes[ChannelIdx] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
905                    (Emios_Pwm_Ip_aInitialModes[ChannelIdx] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH))
906                 {
907                     Emios_Pwm_Ip_SetForceMatchB(Base, Channel, TRUE);
908                 }
909                 else
910                 {
911                     Emios_Pwm_Ip_SetForceMatchA(Base, Channel, TRUE);
912                 }
913             }
914         }
915         else if(NewDutyCycle == ((ChPeriod * 2U) - 2U))
916         {
917             /* Disable and clear interrupt flag */
918             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
919             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
920 
921             Emios_Pwm_Ip_SetUCRegA(Base, Channel, 1U);
922             Emios_Pwm_Ip_aNotif[ChannelIdx] = (uint8)1U;
923         }
924         else
925         {
926             Emios_Pwm_Ip_SetUCRegA(Base, Channel, (Emios_Pwm_Ip_PeriodType)(ChPeriod - (NewDutyCycle >> 1U)));
927             Emios_Pwm_Ip_aNotif[ChannelIdx] = (uint8)0U;
928             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, (Emios_Pwm_Ip_aCheckEnableNotif[ChannelIdx] == 0U)? FALSE : TRUE);
929         }
930 
931         /* Stores the new duty cycle in ticks */
932         Emios_Pwm_Ip_aDutyCycle[ChannelIdx] = NewDutyCycle;
933     }
934     else
935     {
936         /* Do nothing */
937     }
938 
939     return Ret;
940 }
941 #endif
942 
943 
944 #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
945 /*FUNCTION**********************************************************************
946  *
947  * Function Name : Emios_Pwm_Ip_InitEdgePlacementOpwmMode
948  * Description   : Initial Output Pulse Width Modulation (OPWM).
949  * OPWM Mode is used to generate pulses with programmable leading and trailing edge placement.
950  * An external counter driven in MC Up Mode must be selected from one of the counter buses.
951  * UserChCfg defines the first edge and the second edge. The output signal polarity is defined
952  * by OutputPolarity in UserChCfg.
953  *
954  *END**************************************************************************/
Emios_Pwm_Ip_InitEdgePlacementOpwmMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)955 static void Emios_Pwm_Ip_InitEdgePlacementOpwmMode(uint8 Instance,
956                                                    Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
957                                                   )
958 {
959 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
960     DevAssert(NULL_PTR != UserChCfg);
961     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
962     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
963     /* Check Selected Channel is set for OPWM */
964     DevAssert((UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG) ||
965               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH) ||
966               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG) ||
967               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH));
968     /* Check selected Channel supports OPWM */
969     DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWM));
970     /* Check selected counter bus is configured in MCB Up-Down Mode */
971     DevAssert((EMIOS_PWM_IP_MC_UP_COUNTER_START == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) ||
972               (EMIOS_PWM_IP_MC_UP_COUNTER_END == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)));
973     /* Validate OPWM parametter */
974     /* Phase Shift and DutyCycle cannot be bigger than the counter bus period */
975     DevAssert((Emios_Pwm_Ip_GetCounterBusPeriod(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) >= (UserChCfg->PhaseShift + UserChCfg->DutyCycle));
976     DevAssert(EMIOS_PWM_IP_MAX_CNT_VAL >= (uint32)((uint32)UserChCfg->PhaseShift + (uint32)UserChCfg->DutyCycle));
977 #endif
978 
979     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
980 
981     Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->PhaseShift;
982 
983     /* Configure Counter Bus used by this Channel */
984     Emios_Pwm_Ip_SetCounterBus(Base, UserChCfg->ChannelId, UserChCfg->Timebase);
985     /* Configure Phase Shift in reg A */
986     Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, UserChCfg->PhaseShift + (Emios_Pwm_Ip_PeriodType)1U);
987     /* Configure Trailing edge in reg B */
988     Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, UserChCfg->PhaseShift + UserChCfg->DutyCycle);
989 
990     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
991     {   /* 100% DutyCycle is desired. */
992         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
993         /* Write the same nonzero value to AS1 and BS1 */
994         Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, UserChCfg->PhaseShift + UserChCfg->DutyCycle);
995 
996         /* To avoid spike pulse
997         If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
998         after that, EDPOL bit is restored valid value */
999         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
1000     }
1001     else if((0U == UserChCfg->DutyCycle) || (1U == UserChCfg->DutyCycle))
1002     {
1003         /* 0% DutyCycle is desired. */
1004         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
1005         /* Write 0 to AS1 */
1006         Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, (Emios_Pwm_Ip_PeriodType)0U);
1007         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW );
1008     }
1009     else
1010     {
1011         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)0U;
1012         /* Configure output pin polarity */
1013         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1014     }
1015 
1016     /* Transition from GPIO Mode to OPWM Mode */
1017     Emios_Pwm_Ip_SetPwmMode(Base, UserChCfg->ChannelId, UserChCfg->Mode);
1018 
1019     /* Configure output pin polarity */
1020     Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1021 
1022     /* Stores the inital duty cycle in ticks */
1023     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->DutyCycle;
1024 }
1025 #endif
1026 
1027 #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
1028 /*FUNCTION**********************************************************************
1029  *
1030  * Function Name : Emios_Pwm_Ip_InitEdgePlacementOpwmbMode
1031  * Description   : Initial Output Pulse Width Modulation Buffered (OPWMB).
1032  * OPWMB Mode is used to generate pulses with programmable leading and trailing edge placement.
1033  * An external counter driven in MCB Up Mode must be selected from one of the counter buses.
1034  * UserChCfg defines the first edge and the second edge. The output signal polarity is defined
1035  * by OutputPolarity in UserChCfg.
1036  *
1037  *END**************************************************************************/
Emios_Pwm_Ip_InitEdgePlacementOpwmbMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)1038 static void Emios_Pwm_Ip_InitEdgePlacementOpwmbMode(uint8 Instance,
1039                                                     Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
1040                                                    )
1041 {
1042 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1043     DevAssert(NULL_PTR != UserChCfg);
1044     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1045     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
1046     /* Check Selected Channel is set for OPWMB */
1047     DevAssert((UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMB_FLAG) ||
1048               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH));
1049     /* Check selected Channel supports OPWMB Mode */
1050     DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWMB));
1051     /* Check selected counter bus is configured in MCB Up-Down Mode */
1052     DevAssert(EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase));
1053     /* Validate OPWMB parametter */
1054     /* Phase Shift and DutyCycle cannot be bigger than the counter bus period */
1055     DevAssert((Emios_Pwm_Ip_GetCounterBusPeriod(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) >= (UserChCfg->PhaseShift + UserChCfg->DutyCycle));
1056     DevAssert(EMIOS_PWM_IP_MAX_CNT_VAL >= (uint32)((uint32)UserChCfg->PhaseShift + (uint32)UserChCfg->DutyCycle));
1057 #endif
1058 
1059     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1060 
1061     Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->PhaseShift;
1062 
1063     /* Configure Counter Bus used by this Channel */
1064     Emios_Pwm_Ip_SetCounterBus(Base, UserChCfg->ChannelId, UserChCfg->Timebase);
1065     /* Configure Phase Shift in reg A */
1066     Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, UserChCfg->PhaseShift);
1067     /* Configure Trailing edge in reg B */
1068     Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, UserChCfg->PhaseShift + UserChCfg->DutyCycle);
1069 
1070     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
1071     {   /* 100% DutyCycle is desired. */
1072         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
1073         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1074     }
1075     else if((0U == UserChCfg->DutyCycle) || (1U == UserChCfg->DutyCycle))
1076     {
1077         /* 0% DutyCycle is desired. */
1078         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
1079         /* To avoid spike pulse
1080         If duty cycle = 0%, when enter Mode, EDPOL bit get complement of polarity
1081         after that, EDPOL bit is restored valid value */
1082         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
1083     }
1084     else
1085     {
1086         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)0U;
1087     }
1088     /* Transition from GPIO Mode to OPWMB Mode */
1089     Emios_Pwm_Ip_SetPwmMode(Base, UserChCfg->ChannelId, UserChCfg->Mode);
1090     /* Configure output pin polarity */
1091     Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1092     /* Stores the inital duty cycle in ticks */
1093     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->DutyCycle;
1094 }
1095 #endif
1096 
1097 #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
1098 /*FUNCTION**********************************************************************
1099  *
1100  * Function Name : Emios_Pwm_Ip_SetDutyCycleOpwmb
1101  * Description   : Set new duty cycle for the Channel in OPWMB Mode
1102  * This function will check the specific duty cycle and set new duty cycle for
1103  * this Channel
1104  *
1105  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleOpwmb(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)1106 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwmb(uint8  Instance,
1107                                                                      uint8  Channel,
1108                                                                      Emios_Pwm_Ip_DutyType NewDutyCycle
1109                                                                     )
1110 {
1111 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1112     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1113     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1114 #endif
1115     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1116     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
1117     Emios_Pwm_Ip_PeriodType ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel));
1118 
1119     /* OPWMB Mode */
1120     if ((NewDutyCycle + Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) > ChPeriod)
1121     { /* New duty cycle puts trailing edge outside of counter bus period. */
1122         Ret = EMIOS_PWM_IP_STATUS_ERROR;
1123     }
1124     else
1125     {
1126         if(NewDutyCycle == 0U)
1127         {
1128             /* Disable and clear interrupt flag */
1129             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1130             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1131             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
1132         }
1133         else if (NewDutyCycle == ChPeriod)
1134         {
1135             /* Disable and clear interrupt flag */
1136             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1137             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1138             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
1139         }
1140         else
1141         {
1142             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)0U;
1143             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, (Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == 0U)? FALSE : TRUE);
1144         }
1145         Emios_Pwm_Ip_SetUCRegB(Base, Channel, (NewDutyCycle + Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
1146     }
1147 
1148     /* Stores the new duty cycle in ticks */
1149     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = NewDutyCycle;
1150 
1151     return Ret;
1152 }
1153 #endif
1154 
1155 #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
1156 /*FUNCTION**********************************************************************
1157  *
1158  * Function Name : Emios_Pwm_Ip_SetDutyCycleOpwm
1159  * Description   : Set new duty cycle for the Channel in OPWM Mode
1160  * This function will check the specific duty cycle and set new duty cycle for
1161  * this Channel
1162  *
1163  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleOpwm(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)1164 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwm(uint8  Instance,
1165                                                                     uint8  Channel,
1166                                                                     Emios_Pwm_Ip_DutyType NewDutyCycle
1167                                                                    )
1168 {
1169 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1170     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1171     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1172 #endif
1173     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1174     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
1175     Emios_Pwm_Ip_PeriodType ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel));
1176 
1177     /* OPWM Mode */
1178     if ((NewDutyCycle + Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) > ChPeriod)
1179     { /* New duty cycle puts trailing edge outside of counter bus period. */
1180         Ret = EMIOS_PWM_IP_STATUS_ERROR;
1181     }
1182     else
1183     {
1184         if(NewDutyCycle == 0U)
1185         {
1186             /* Disable and clear interrupt flag */
1187             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1188             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1189             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
1190             Emios_Pwm_Ip_SetUCRegA(Base, Channel, (NewDutyCycle + Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
1191         }
1192         else if (NewDutyCycle == ChPeriod)
1193         {
1194             /* Disable and clear interrupt flag */
1195             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1196             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1197             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
1198             Emios_Pwm_Ip_SetUCRegA(Base, Channel, (NewDutyCycle + Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
1199         }
1200         else
1201         {
1202             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)0U;
1203             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, (Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == 0U)? FALSE : TRUE);
1204             Emios_Pwm_Ip_SetUCRegA(Base, Channel, (Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) + (Emios_Pwm_Ip_PeriodType)1U);
1205         }
1206         Emios_Pwm_Ip_SetUCRegB(Base, Channel, (NewDutyCycle + Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
1207     }
1208 
1209     /* Stores the new duty cycle in ticks */
1210     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = NewDutyCycle;
1211 
1212     return Ret;
1213 }
1214 #endif
1215 
1216 #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
1217 /*FUNCTION**********************************************************************
1218  *
1219  * Function Name : Emios_Pwm_Ip_InitTriggerMode
1220  * Description   : Initial Output Pulse Width Modulation with Trigger (OPWMT) Mode
1221  * OPWMT Mode is intended to support the generation of Pulse Width Modulation signals where
1222  * the period is not modified while the signal is being output, but where the duty cycle will
1223  * be varied and must not create glitches. The Mode is intended to be used in conjunction with
1224  * other channels executing in the same Mode and sharing a common timebase. It will support each
1225  * Channel with a fixed PWM leading edge position with respect to the other channels and the
1226  * ability to generate a trigger signal at any point in the period that can be output from
1227  * the module to initiate activity in other parts of the SoC such as starting ADC conversions.
1228  *
1229  * An external counter driven in either MC Up or MCB Up Mode must be selected from one of the counter buses.
1230  *
1231  * The leading edge can be configured with any value within the range of the selected time Base. Note that registers
1232  * loaded with 0x0 will not produce matches if the timebase is driven by a Channel in MCB Mode.
1233  *
1234  *END**************************************************************************/
Emios_Pwm_Ip_InitTriggerMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)1235 static void Emios_Pwm_Ip_InitTriggerMode(uint8 Instance,
1236                                          Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
1237                                         )
1238 {
1239 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1240     DevAssert(NULL_PTR != UserChCfg);
1241     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1242     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
1243     /* Check Selected Channel is set for OPWMT */
1244     DevAssert(UserChCfg->Mode == EMIOS_PWM_IP_MODE_OPWMT);
1245     /* Check selected Channel supports OPWMT Mode */
1246     DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_OPWMT));
1247     /* Check selected counter bus is configured in MCB Up Mode or MC Up Mode */
1248     DevAssert((EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) ||
1249               (EMIOS_PWM_IP_MC_UP_COUNTER_START == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)) ||
1250               (EMIOS_PWM_IP_MC_UP_COUNTER_END == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase)));
1251 #endif
1252 
1253     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1254     Emios_Pwm_Ip_PeriodType CounterBusPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, UserChCfg->ChannelId, UserChCfg->Timebase);
1255     Emios_Pwm_Ip_DutyType TrailingEdge = 0x0000U;
1256     uint8 CounterStart = 0U;
1257 
1258 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1259     /* Validate OPWMT parameters */
1260     /* Phase Shift must be in the counter bus period range. */
1261     DevAssert(CounterBusPeriod >= UserChCfg->PhaseShift);
1262     /* If 100% duty cycle must be implemented the maximum counter value for the time Base is 0xFFFE */
1263     DevAssert(EMIOS_PWM_IP_MAX_CNT_VAL > CounterBusPeriod);
1264     /* Duty cycle must not exceed the counter bus period. If 100% duty is desired dutycycle must be counterbus period +1U */
1265     DevAssert((CounterBusPeriod + 1U) >= UserChCfg->DutyCycle);
1266     /* Trigger point must be inside the counter bus period */
1267     DevAssert(CounterBusPeriod >= UserChCfg->TriggerPosition);
1268 #endif
1269 
1270     if (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, UserChCfg->ChannelId, UserChCfg->Timebase))
1271     {
1272         CounterStart = 1U;
1273     }
1274     else
1275     {
1276         CounterStart = 0U;
1277     }
1278 
1279     if (CounterBusPeriod == UserChCfg->DutyCycle)
1280     {   /* 100% DutyCycle is desired. Trailing edge must be placed outside counter bus period. */
1281         TrailingEdge = UserChCfg->DutyCycle + 1U;
1282         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
1283     }
1284     else if ((0U == UserChCfg->DutyCycle) || (0U == CounterBusPeriod))
1285     {
1286         TrailingEdge = UserChCfg->PhaseShift;
1287         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)1U;
1288     }
1289     else
1290     { /* Calculate trailing edge postion. Wrap-around if DutyCycle extends the signal past the counterbus period. */
1291         TrailingEdge = (UserChCfg->PhaseShift + UserChCfg->DutyCycle) % CounterBusPeriod;
1292         Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (uint8)0U;
1293     }
1294 
1295     Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->PhaseShift + CounterStart;
1296 
1297     /* Configure Counter Bus used by this Channel */
1298     Emios_Pwm_Ip_SetCounterBus(Base, UserChCfg->ChannelId, UserChCfg->Timebase);
1299     /* Configure Leading Edge in reg A */
1300     Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, (UserChCfg->PhaseShift + CounterStart));
1301     /* Configure Trailing Edge in reg B */
1302     Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, (TrailingEdge + CounterStart));
1303     /* Configure Triggerpoint in reg ALTA */
1304     Emios_Pwm_Ip_SetTrigger(Base, UserChCfg->ChannelId, (UserChCfg->TriggerPosition + CounterStart));
1305     /* To avoid spike pulse
1306     If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
1307     after that, EDPOL bit is restored valid value */
1308     if (CounterBusPeriod == UserChCfg->DutyCycle)
1309     {
1310          Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
1311     }
1312     else
1313     {
1314         Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1315     }
1316     /* Transition from GPIO Mode to OPWMT Mode */
1317     Emios_Pwm_Ip_SetPwmMode(Base, UserChCfg->ChannelId, UserChCfg->Mode);
1318     /* Configure output pin polarity */
1319     Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1320     /* Stores the inital duty cycle in ticks */
1321     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->DutyCycle;
1322 }
1323 
1324 /*FUNCTION**********************************************************************
1325  *
1326  * Function Name : Emios_Pwm_Ip_SetDutyCycleOpwmt
1327  * Description   : Set new duty cycle for the Channel in OPWMT Mode
1328  * This function will check the specific duty cycle and set new duty cycle for
1329  * this Channel
1330  *
1331  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleOpwmt(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)1332 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleOpwmt(uint8  Instance,
1333                                                                      uint8  Channel,
1334                                                                      Emios_Pwm_Ip_DutyType NewDutyCycle
1335                                                                     )
1336 {
1337 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1338     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1339     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1340 #endif
1341     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1342     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
1343     Emios_Pwm_Ip_PeriodType ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel));
1344 
1345     /* OPWMT Mode */
1346     if (NewDutyCycle > ChPeriod)
1347     { /* Duty cycle value should not be greater than the Channel Period. */
1348         Ret = EMIOS_PWM_IP_STATUS_ERROR;
1349     }
1350     else
1351     {
1352         if (ChPeriod == NewDutyCycle)
1353         {   /* 100% DutyCycle is desired. Trailing edge must be placed outside counter bus period. */
1354             /* Disable and clear interrupt flag */
1355             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1356             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1357 
1358             Emios_Pwm_Ip_SetUCRegB(Base, Channel, (NewDutyCycle + 1U));
1359             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
1360         }
1361         else if(0U == NewDutyCycle)
1362         {
1363             /* 0% DutyCycle is desired. */
1364             /* Disable and clear interrupt flag */
1365             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1366             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1367 
1368             Emios_Pwm_Ip_SetUCRegB(Base, Channel, Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]);
1369             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
1370         }
1371         else
1372         { /* Calculate trailing edge postion. Wrap-around if DutyCycle extends the signal past the counterbus period. */
1373             Emios_Pwm_Ip_SetUCRegB(Base, Channel, (Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] + NewDutyCycle) % ChPeriod);
1374             Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)0U;
1375             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, (Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == 0U)? FALSE : TRUE);
1376         }
1377     }
1378 
1379     /* Stores the new duty cycle in ticks */
1380     Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = NewDutyCycle;
1381 
1382     return Ret;
1383 }
1384 #endif /* EMIOS_PWM_IP_MODE_OPWMT_USED */
1385 
1386 #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
Emios_Pwm_Ip_InitDCModeWithDuty(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)1387 static inline void Emios_Pwm_Ip_InitDCModeWithDuty(uint8 Instance,
1388                                                    Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
1389                                                   )
1390 {
1391 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1392     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]);
1393 #endif
1394     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1395     Emios_Pwm_Ip_PeriodType DaocRegA = 0U;
1396     Emios_Pwm_Ip_PeriodType CounterMax = Emios_Pwm_Ip_GetUCRegA(Base, Emios_Pwm_Ip_GetMasterBusChannel(Instance, UserChCfg->ChannelId));
1397     uint8 ChannelIndex = Emios_Pwm_Ip_GetChannelIndex(Instance, UserChCfg->ChannelId);
1398 
1399     if (ChannelIndex < EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8)
1400     {
1401         if(0U == UserChCfg->DutyCycle)
1402         {
1403             DaocRegA = 1U;
1404             Emios_Pwm_Ip_aDutyCycle[ChannelIndex] = 0U;
1405 
1406             Emios_Pwm_Ip_SetForceMatchB(Base, UserChCfg->ChannelId, TRUE);
1407             /* Configure Leading Edge in reg A */
1408             Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, DaocRegA);
1409             /* Configure Trailing Edge in reg B */
1410             Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, (UserChCfg->DutyCycle + 1U));
1411 
1412             Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1413 
1414             Emios_Pwm_Ip_aNotif[ChannelIndex] = (uint8)1U;
1415 
1416         }
1417         else if(UserChCfg->DutyCycle == UserChCfg->PeriodCount)
1418         {
1419             DaocRegA = (Emios_Pwm_Ip_aPeriod[ChannelIndex] + Emios_Pwm_Ip_GetUCRegA(Base, UserChCfg->ChannelId)) % CounterMax;
1420 
1421             Emios_Pwm_Ip_aDutyCycle[ChannelIndex] = 0U;
1422 
1423             Emios_Pwm_Ip_SetForceMatchA(Base, UserChCfg->ChannelId, TRUE);
1424             /* Configure Leading Edge in reg A */
1425             Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, (DaocRegA == 0U)? CounterMax : DaocRegA);
1426             /* Configure Trailing Edge in reg B */
1427             Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, (DaocRegA == 0U)? CounterMax : DaocRegA);
1428             /* Invert the EDGE POLARITY in control register */
1429             Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH);
1430 
1431             Emios_Pwm_Ip_aNotif[ChannelIndex] = (uint8)1U;
1432         }
1433         else
1434         {
1435             DaocRegA = 1U;
1436             Emios_Pwm_Ip_aDutyCycle[ChannelIndex] = UserChCfg->DutyCycle;
1437 
1438             /* Configure Leading Edge in reg A */
1439             Emios_Pwm_Ip_SetUCRegA(Base, UserChCfg->ChannelId, DaocRegA);
1440             /* Configure Trailing Edge in reg B */
1441             Emios_Pwm_Ip_SetUCRegB(Base, UserChCfg->ChannelId, (UserChCfg->DutyCycle + 1U));
1442 
1443             Emios_Pwm_Ip_SetEdgePolarity(Base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1444 
1445             Emios_Pwm_Ip_aNotif[ChannelIndex] = (uint8)0U;
1446         }
1447     }
1448     else
1449     {
1450         /* Do nothing */
1451     }
1452 }
1453 
1454 /*FUNCTION**********************************************************************
1455  *
1456  * Function Name : Emios_Pwm_Ip_InitDoubleCompareMode
1457  * Description   : Initial Double Action Output Compare (DAOC) Mode.
1458  * This mode provides waveforms with variable duty cycle and frequency.
1459  * In DAOC mode, at the end of period, the A register and B register need re-calculated to
1460  * enable next match A. This calculation and first pulse must be done by software.
1461  * Calculate the duty tick follow period and Duty cycle
1462  * Always enable interrupt. Because in this mode, the A register and B register is re-calculated
1463  * with period and duty at the end of period by software.
1464  *
1465  *END**************************************************************************/
Emios_Pwm_Ip_InitDoubleCompareMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)1466 static void Emios_Pwm_Ip_InitDoubleCompareMode(uint8 Instance,
1467                                                Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
1468                                               )
1469 {
1470 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1471     DevAssert(NULL_PTR != UserChCfg);
1472     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1473     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > UserChCfg->ChannelId);
1474     /* Check Selected channel is set for DAOC mode */
1475     DevAssert((UserChCfg->Mode == EMIOS_PWM_IP_MODE_DAOC_FLAG) ||
1476               (UserChCfg->Mode == EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH));
1477     /* Check selected Channel supports DAOC Mode */
1478     DevAssert(TRUE == Emios_Pwm_Ip_ValidateMode(Instance, UserChCfg->ChannelId, EMIOS_PWM_IP_HW_MODE_DAOC));
1479     /* Validate DAOC parametter */
1480     DevAssert(EMIOS_PWM_IP_MIN_CNT_VAL < UserChCfg->PeriodCount);
1481     DevAssert(UserChCfg->DutyCycle <= UserChCfg->PeriodCount);
1482 #endif
1483 
1484     Emios_Pwm_Ip_HwAddrType *const base = Emios_Pwm_Ip_aBasePtr[Instance];
1485     Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = UserChCfg->PeriodCount;
1486     Emios_Pwm_Ip_aPolarity[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = (UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH)? 1U : 0U;
1487 
1488     /* FLAG event enabled */
1489     Emios_Pwm_Ip_SetInterruptRequest(base, UserChCfg->ChannelId, TRUE);
1490     /* Configure Counter Bus used by this channel */
1491     Emios_Pwm_Ip_SetCounterBus(base, UserChCfg->ChannelId, UserChCfg->Timebase);
1492 
1493     if (UserChCfg->PeriodCount == UserChCfg->DutyCycle)
1494     {
1495         Emios_Pwm_Ip_SetEdgePolarity(base, UserChCfg->ChannelId,(UserChCfg->OutputPolarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
1496     }
1497     else
1498     {
1499         Emios_Pwm_Ip_SetEdgePolarity(base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1500     }
1501     /* Transition from GPIO mode to DAOC mode */
1502     Emios_Pwm_Ip_SetPwmMode(base, UserChCfg->ChannelId, UserChCfg->Mode);
1503     /* Configure output pin polarity */
1504     Emios_Pwm_Ip_SetEdgePolarity(base, UserChCfg->ChannelId, UserChCfg->OutputPolarity);
1505     /* With Duty cycle 0% */
1506     Emios_Pwm_Ip_InitDCModeWithDuty(Instance, UserChCfg);
1507 
1508 }
1509 
1510 /*FUNCTION**********************************************************************
1511  *
1512  * Function Name : Emios_Pwm_Ip_SetDutyCycleDaoc
1513  * Description   : Set new duty cycle for the Channel in DAOC Mode
1514  * This function will check the specific duty cycle and set new duty cycle for
1515  * this Channel
1516  *
1517  *END**************************************************************************/
Emios_Pwm_Ip_SetDutyCycleDaoc(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)1518 static inline Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycleDaoc(uint8  Instance,
1519                                                                     uint8  Channel,
1520                                                                     Emios_Pwm_Ip_DutyType NewDutyCycle
1521                                                                    )
1522 {
1523 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1524     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1525     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1526 #endif
1527     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1528     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
1529     Emios_Pwm_Ip_PeriodType DaocRegA = 0U;
1530     Emios_Pwm_Ip_PeriodType CounterMax = Emios_Pwm_Ip_GetUCRegA(Base, Emios_Pwm_Ip_GetMasterBusChannel(Instance, Channel));
1531     /* Get the value of channel Index */
1532     uint8 ChannelIdx = Emios_Pwm_Ip_GetChannelIndex(Instance, Channel);
1533 
1534     if (ChannelIdx < EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8)
1535     {
1536         /* DAOC Mode */
1537         if ((NewDutyCycle > Emios_Pwm_Ip_aPeriod[ChannelIdx]) && ((Emios_Pwm_Ip_PeriodType)0U != Emios_Pwm_Ip_aPeriod[ChannelIdx]))
1538         {   /* Duty cycle value should not be greater than the Channel Period. */
1539             Ret = EMIOS_PWM_IP_STATUS_ERROR;
1540         }
1541         else if (((Emios_Pwm_Ip_PeriodType)0U == Emios_Pwm_Ip_aPeriod[ChannelIdx]) || ((Emios_Pwm_Ip_DutyType)0U == NewDutyCycle))
1542         {
1543             /* Disable and clear interrupt flag */
1544             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1545             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1546 
1547             /* If new period is 0, set duty cycle to 0 */
1548             Emios_Pwm_Ip_aDutyCycle[ChannelIdx] = 0U;
1549 
1550             Emios_Pwm_Ip_SetForceMatchB(Base, Channel, TRUE);
1551             /* Configure Leading Edge in reg A */
1552             Emios_Pwm_Ip_SetUCRegA(Base, Channel, 1U);
1553             /* Configure Trailing Edge in reg B */
1554             Emios_Pwm_Ip_SetUCRegB(Base, Channel, (NewDutyCycle + 1U));
1555             /* Set polarity when channels is in active state */
1556             if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[ChannelIdx])
1557             {
1558                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, (Emios_Pwm_Ip_aPolarity[ChannelIdx] == 1U)? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW);
1559             }
1560 
1561             Emios_Pwm_Ip_aNotif[ChannelIdx] = (uint8)1U;
1562         }
1563         else if(NewDutyCycle == Emios_Pwm_Ip_aPeriod[ChannelIdx])
1564         {
1565             /* Disable and clear interrupt flag */
1566             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
1567             Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
1568 
1569             Emios_Pwm_Ip_aDutyCycle[ChannelIdx] = 0U;
1570             DaocRegA = (Emios_Pwm_Ip_aPeriod[ChannelIdx] + Emios_Pwm_Ip_GetUCRegA(Base, Channel)) % CounterMax;
1571 
1572             Emios_Pwm_Ip_SetForceMatchA(Base, Channel, TRUE);
1573             /* Configure Leading Edge in reg A */
1574             Emios_Pwm_Ip_SetUCRegA(Base, Channel, (DaocRegA == 0U)? CounterMax : DaocRegA);
1575             /* Configure Trailing Edge in reg B */
1576             Emios_Pwm_Ip_SetUCRegB(Base, Channel, (DaocRegA == 0U)? CounterMax : DaocRegA);
1577             /* Set polarity when channels is in active state */
1578             /* Invert the EDGE POLARITY in control register */
1579             if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[ChannelIdx])
1580             {
1581                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel,(Emios_Pwm_Ip_aPolarity[ChannelIdx] == 1U)? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH);
1582             }
1583 
1584             Emios_Pwm_Ip_aNotif[ChannelIdx] = (uint8)1U;
1585         }
1586         else
1587         {
1588             /* FLAG event enabled. The Daoc Mode requires interrupt to calculate the next match value*/
1589             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, TRUE);
1590 
1591             Emios_Pwm_Ip_aDutyCycle[ChannelIdx] = NewDutyCycle;
1592             /* Configure Leading Edge in reg A */
1593             Emios_Pwm_Ip_SetUCRegA(Base, Channel, 1U);
1594             /* Configure Trailing Edge in reg B */
1595             Emios_Pwm_Ip_SetUCRegB(Base, Channel, NewDutyCycle + 1U);
1596             /* Set polarity when channels is in active state */
1597             if (EMIOS_PWM_IP_MODE_GPO != Emios_Pwm_Ip_aCurrentModes[ChannelIdx])
1598             {
1599                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, (Emios_Pwm_Ip_aPolarity[ChannelIdx] == 1U)? EMIOS_PWM_IP_ACTIVE_HIGH : EMIOS_PWM_IP_ACTIVE_LOW);
1600             }
1601 
1602             Emios_Pwm_Ip_aNotif[ChannelIdx] = (uint8)0U;
1603 
1604         }
1605     }
1606 
1607     return Ret;
1608 }
1609 #endif /* EMIOS_PWM_IP_MODE_DAOC_USED */
1610 
Emios_Pwm_Ip_InitOutputIrqAndMode(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)1611 static inline void Emios_Pwm_Ip_InitOutputIrqAndMode(uint8                                   Instance,
1612                                                      Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
1613                                                     )
1614 {
1615     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1616 
1617     if (EMIOS_PWM_IP_OUTPUT_DISABLE_NONE != UserChCfg->OutputDisableSource)
1618     {
1619         Emios_Pwm_Ip_SetOutDisable(Base, UserChCfg->ChannelId, TRUE);
1620         Emios_Pwm_Ip_SetOutDisableSource(Base, UserChCfg->ChannelId, UserChCfg->OutputDisableSource);
1621     }
1622 
1623     /* Configure Interrupt/DMA request */
1624     if (EMIOS_PWM_IP_NOTIFICATION_DISABLED != UserChCfg->IrqMode)
1625     {
1626         if (EMIOS_PWM_IP_INTERRUPT_REQUEST == UserChCfg->IrqMode)
1627         {
1628             /* Register the notification structure */
1629             Emios_Pwm_Ip_aNotificationPtr[eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]] = &(UserChCfg->UserCallback);
1630         }
1631         else
1632         {
1633             Emios_Pwm_Ip_SetDMARequest(Base, UserChCfg->ChannelId, TRUE);
1634         }
1635     }
1636 
1637     /* Configure CounterBus, DutyCycle, period, trigger, phase shift for selected Mode */
1638     switch (UserChCfg->Mode)
1639     {
1640         #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
1641         case EMIOS_PWM_IP_MODE_OPWFMB_FLAG:
1642         case EMIOS_PWM_IP_MODE_OPWFMB_FLAG_BOTH:
1643             /* OPWFMB Mode initialization */
1644             Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmbMode(Instance, UserChCfg);
1645             break;
1646         #endif
1647         #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
1648         case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG:
1649         case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG_BOTH:
1650         case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG:
1651         case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
1652             /* OPWFM Mode initialization */
1653             Emios_Pwm_Ip_InitPeriodDutyCycleOpwfmMode(Instance, UserChCfg);
1654             break;
1655         #endif
1656         #if (defined EMIOS_PWM_IP_MODE_OPWMCB_USED)
1657         #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED
1658         case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG:
1659         case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH:
1660         case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG:
1661         case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH:
1662         #endif
1663             /* OPWMCB,OPWMC Mode initialization */
1664             Emios_Pwm_Ip_InitDeadTimeMode(Instance, UserChCfg);
1665             break;
1666         #endif /* defined EMIOS_PWM_IP_MODE_OPWMCB_USED) || (defined EMIOS_PWM_IP_MODE_OPWMC_USED */
1667         #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
1668         case EMIOS_PWM_IP_MODE_OPWMB_FLAG:
1669         case EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH:
1670             /* OPWMB Mode initialization */
1671             Emios_Pwm_Ip_InitEdgePlacementOpwmbMode(Instance, UserChCfg);
1672             break;
1673         #endif
1674         #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
1675         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG:
1676         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH:
1677         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG:
1678         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
1679             /* OPWM Mode initialization */
1680             Emios_Pwm_Ip_InitEdgePlacementOpwmMode(Instance, UserChCfg);
1681             break;
1682         #endif
1683         #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
1684         case EMIOS_PWM_IP_MODE_OPWMT:
1685             /* OPWMT Mode initialization */
1686             Emios_Pwm_Ip_InitTriggerMode(Instance, UserChCfg);
1687             break;
1688         #endif
1689         #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
1690         case EMIOS_PWM_IP_MODE_DAOC_FLAG:
1691         case EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH:
1692             /* DAOC Mode initialization */
1693             Emios_Pwm_Ip_InitDoubleCompareMode(Instance, UserChCfg);
1694             break;
1695         #endif
1696         default:
1697             /* Nothing to do. All Pwm Mode are already treated. */
1698             break;
1699     }
1700 }
1701 /*==================================================================================================
1702 *                                        GLOBAL FUNCTIONS
1703 ==================================================================================================*/
1704 
1705 /**
1706  *
1707  * Function Name : Emios_Pwm_Ip_InitChannel
1708  * Description   : Initialize PWM Mode.
1709  * Select main Mode
1710  *     - EMIOS OPWFMB
1711  *       Initialize Output Pulse Width and Frequency Modulation Buffered (OPWFMB) Mode.
1712  *       This Mode provides waveforms with variable duty cycle and frequency. The internal Channel counter
1713  *       is automatically selected as the time Base when this Mode is selected.
1714  *
1715  *     - EMIOS OPWMB
1716  *       Initialize Output Pulse Width Modulation Buffered (OPWMB) Mode.
1717  *       OPWMB Mode is used to generate pulses with programmable leading and trailing edge placement.
1718  *       An external counter driven in MCB Up Mode must be selected from one of the counter buses.
1719  *       UserChCfg defines the first edge and the second edge. The output signal polarity is defined
1720  *       by OutputPolarity in UserChCfg.
1721  *
1722  *     - EMIOS OPWMCB
1723  *       Initialize Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode.
1724  *       This operation Mode generates a center aligned PWM with dead time insertion to the leading or trailing edge.
1725  *       Allow smooth output signal generation when changing duty cycle and deadtime values.
1726  *
1727  *     - EMIOS OPWMT
1728  *       Initialize Output Pulse Width Modulation with Trigger (OPWMT) Mode
1729  *       OPWMT Mode is intended to support the generation of Pulse Width Modulation signals where
1730  *       the period is not modified while the signal is being output, but where the duty cycle will
1731  *       be varied and must not create glitches. The Mode is intended to be used in conjunction with
1732  *       other channels executing in the same Mode and sharing a common timebase. It will support each
1733  *       Channel with a fixed PWM leading edge position with respect to the other channels and the
1734  *       ability to generate a trigger signal at any point in the period that can be output from
1735  *       the module to initiate activity in other parts of the SoC such as starting ADC conversions.
1736  *
1737  * @implements Emios_Pwm_Ip_InitChannel_Activity
1738  **/
Emios_Pwm_Ip_InitChannel(uint8 Instance,Emios_Pwm_Ip_ChannelConfigType const * UserChCfg)1739 void Emios_Pwm_Ip_InitChannel(uint8 Instance,
1740                               Emios_Pwm_Ip_ChannelConfigType const *UserChCfg
1741                              )
1742 {
1743 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1744     DevAssert(NULL_PTR != UserChCfg);
1745     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1746     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][UserChCfg->ChannelId]);
1747 
1748     /* Check that a valid notification structure is defined for interrupt Mode */
1749     if (EMIOS_PWM_IP_INTERRUPT_REQUEST == UserChCfg->IrqMode)
1750     {
1751         DevAssert(NULL_PTR != UserChCfg->UserCallback.CbFunction);
1752     }
1753 #endif
1754 
1755     uint8 ChannelIndex = UserChCfg->ChannelId;
1756     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1757     /* Get timbase channel */
1758     uint8 TimbaseCh = Emios_Pwm_Ip_GetTimebaseChannel(UserChCfg->ChannelId, UserChCfg->Timebase);
1759 
1760     /* Disable Channel pre-scaler (reset default) */
1761     Emios_Pwm_Ip_aBasePtr[Instance]->CH.UC[UserChCfg->ChannelId].C = 0UL;
1762 
1763     /* Enable the Output Update for Channel */
1764     Emios_Pwm_Ip_SetOutputUpdate(Base, UserChCfg->ChannelId, TRUE);
1765 
1766 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1767     /* Configure debug freeze enable */
1768     if ((FALSE == Emios_Pwm_Ip_GetDebugMode(Base)) &&
1769         (TRUE == UserChCfg->DebugMode))
1770     {
1771         DevAssert(FALSE);
1772     }
1773     else
1774     {
1775 #endif
1776         Emios_Pwm_Ip_SetFreezeEnable(Base, UserChCfg->ChannelId, UserChCfg->DebugMode);
1777 
1778 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1779     }
1780 #endif
1781 
1782     /* Configure output disable feature */
1783     /* Configure Interrupt/DMA request */
1784     /* Configure counterBus, dutyCycle, period, trigger, phase shift for selected mode */
1785     Emios_Pwm_Ip_InitOutputIrqAndMode(Instance, UserChCfg);
1786 
1787     /* Set the prescaler source */
1788     Emios_Pwm_Ip_SetPrescalerSource(Base, UserChCfg->ChannelId, UserChCfg->InternalPsSrc);
1789 
1790     /* Configure internal prescaler */
1791     Emios_Pwm_Ip_SetExtendedPrescaler(Base, UserChCfg->ChannelId, UserChCfg->InternalPs);
1792     Emios_Pwm_Ip_SetPrescalerEnable(Base, UserChCfg->ChannelId, TRUE);
1793     /* Stores the inital modes of Channel. */
1794     Emios_Pwm_Ip_aInitialModes[eMios_Pwm_Ip_IndexInChState[Instance][ChannelIndex]] = UserChCfg->Mode;
1795     /* Stores the current modes of Channel. */
1796     Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][ChannelIndex]] = UserChCfg->Mode;
1797     /* Confirm the Channel is active*/
1798     Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][ChannelIndex]] = (uint8)1U;
1799     /* If the counter buses to be used by the Unified Channel. */
1800     if (TimbaseCh < EMIOS_PWM_IP_CHANNEL_COUNT)
1801     {
1802         /* Confirm the timebase channel is active */
1803         /* Each channel that uses the master bus the Emios_Pwm_Ip_aCheckState variable will increment. */
1804         Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][TimbaseCh]] += (uint8)1U;
1805     }
1806     else
1807     {
1808         /* The internal counter to be used by the Unified Channel */
1809         (void)TimbaseCh;
1810     }
1811 }
1812 
1813 /**
1814  *
1815  * Function Name : Emios_Pwm_Ip_DeInitChannel
1816  * Description   : Reset eMIOS Channel to GPIO Mode (reset default)
1817  *
1818  * @implements Emios_Pwm_Ip_DeInitChannel_Activity
1819  **/
Emios_Pwm_Ip_DeInitChannel(uint8 Instance,uint8 Channel)1820 void Emios_Pwm_Ip_DeInitChannel(uint8 Instance,
1821                                 uint8 Channel
1822                                )
1823 {
1824 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1825     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1826     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1827     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
1828 #endif
1829     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1830     /* Get Bus Select value */
1831     Emios_Pwm_Ip_CounterBusSourceType CounterBus = Emios_Pwm_Ip_GetCounterBus(Base, Channel);
1832     /* Get timbase channel */
1833     uint8 TimbaseCh = Emios_Pwm_Ip_GetTimebaseChannel(Channel, CounterBus);
1834     /* Get the value of channel Index */
1835     uint8 ChannelIdx = Emios_Pwm_Ip_GetChannelIndex(Instance, Channel);
1836     /* Clear control register 2 and stop clock for Channel */
1837     Base->CH.UC[Channel].C2 = 0UL;
1838 #if (defined(EMIOS_PWM_IP_AUTOSAR_MODE_IS_USED) && (STD_ON == EMIOS_PWM_IP_AUTOSAR_MODE_IS_USED))
1839     /* Clear control register for Channel */
1840     /* If this channel is working on ASR mode, do not touch Polarity and Mode bits in control register to prevent spike */
1841     Base->CH.UC[Channel].C &= (eMIOS_C_MODE_MASK | eMIOS_C_EDPOL_MASK);
1842 #else
1843     Base->CH.UC[Channel].C = 0UL;
1844     /* Clear An and Bn registers */
1845     Emios_Pwm_Ip_SetUCRegA(Base, Channel, 0U);
1846     Emios_Pwm_Ip_SetUCRegB(Base, Channel, 0U);
1847 #endif
1848 
1849     if (ChannelIdx < EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8)
1850     {
1851         /* Clear ALTAn if in PWM Trigger Mode */
1852 #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
1853         if (Emios_Pwm_Ip_aCurrentModes[ChannelIdx] == EMIOS_PWM_IP_MODE_OPWMT)
1854         {
1855             Emios_Pwm_Ip_SetTrigger(Base, Channel, 0U);
1856         }
1857 #endif
1858         Emios_Pwm_Ip_aCheckEnableNotif[ChannelIdx] = (uint8)0U;
1859 
1860         /* Confirm the Channel is inactive*/
1861         Emios_Pwm_Ip_aCheckState[ChannelIdx] = (uint8)0U;
1862     }
1863 
1864     /* If the counter buses to be used by the Unified Channel. */
1865     if ((EMIOS_PWM_IP_BUS_INTERNAL != CounterBus) && (TimbaseCh < EMIOS_PWM_IP_CHANNEL_COUNT))
1866     {
1867         if((uint8)0U != Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][TimbaseCh]])
1868         {
1869             /* Confirm the timebase channel is inactive if Emios_Pwm_Ip_aCheckState is 0U*/
1870             /* Decrement Emios_Pwm_Ip_aCheckState variable for each channel that uses the master bus, make sure the master bus is not marked inactive when there are still active channels. */
1871             Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][TimbaseCh]] = Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][TimbaseCh]] - (uint8)1U;
1872         }
1873     }
1874     else
1875     {
1876         /* The internal counter to be used by the Unified Channel */
1877         (void)TimbaseCh;
1878     }
1879 }
1880 
1881 /**
1882  *
1883  * Function Name : Emios_Pwm_Ip_ForceMatchLeadingEdge
1884  * Description   : Force the output flip-flop to the level corresponding to a match on Leading edge
1885  *      In Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode
1886  *      FORCMA has different behaviors depending upon the selected dead time
1887  *      insertion Mode, lead or trail. In lead dead time insertion FORCMA force a transition
1888  *      in the output flipflop to the opposite of EDPOL. In trail dead time insertion the
1889  *      output flip-flop is forced to the value of EDPOL bit.
1890  *      FORCMA bit set does not set the internal time-Base to 0x1 as a regular A1 match.
1891  *
1892  * @implements Emios_Pwm_Ip_ForceMatchLeadingEdge_Activity
1893  **/
Emios_Pwm_Ip_ForceMatchLeadingEdge(uint8 Instance,uint8 Channel,boolean Enable)1894 void Emios_Pwm_Ip_ForceMatchLeadingEdge(uint8 Instance,
1895                                         uint8 Channel,
1896                                         boolean Enable
1897                                        )
1898 {
1899 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1900     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1901     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1902 #endif
1903     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1904 
1905     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_14();
1906     /* Force Match A bit */
1907     Emios_Pwm_Ip_SetForceMatchA(Base, Channel, Enable);
1908     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_14();
1909 }
1910 
1911 /**
1912  *
1913  * Function Name : Emios_Pwm_Ip_ForceMatchTrailingEdge
1914  * Description   : Force the output flipflop to the level corresponding to a match on Trailing edge
1915  *
1916  * In Center Aligned Output Pulse Width Modulation with Dead Time Insertion Buffered (OPWMCB) Mode
1917  *       If FORCMB bit is set, the output flip-flop value depends upon the selected dead time
1918  *       insertion Mode. In lead dead time insertion FORCMB forces the output flip-flop to transition to EDPOL
1919  *       bit value. In trail dead time insertion the output flip-flop is forced to the opposite of EDPOL bit value.
1920  *
1921  * @implements Emios_Pwm_Ip_ForceMatchTrailingEdge_Activity
1922  **/
Emios_Pwm_Ip_ForceMatchTrailingEdge(uint8 Instance,uint8 Channel,boolean Enable)1923 void Emios_Pwm_Ip_ForceMatchTrailingEdge(uint8 Instance,
1924                                          uint8 Channel,
1925                                          boolean Enable
1926                                         )
1927 {
1928 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1929     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1930     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1931 #endif
1932 
1933     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1934     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_15();
1935     /* Force Match B bit */
1936     Emios_Pwm_Ip_SetForceMatchB(Base, Channel, Enable);
1937     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_15();
1938 }
1939 
1940 /**
1941  *
1942  * Function Name : Emios_Pwm_Ip_GetPeriod
1943  * Description   : Get period of waveforms in PWM Mode.
1944  *
1945  * @implements Emios_Pwm_Ip_GetPeriod_Activity
1946  **/
Emios_Pwm_Ip_GetPeriod(uint8 Instance,uint8 Channel)1947 Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_GetPeriod(uint8 Instance,
1948                                                uint8 Channel
1949                                               )
1950 {
1951 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
1952     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
1953     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
1954     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
1955 #endif
1956     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
1957     Emios_Pwm_Ip_PwmModeType ChMode;
1958     Emios_Pwm_Ip_PeriodType ChPeriod = 0x00U;
1959     /* Channels shall be reactivated from idle state. */
1960     if ((uint8)2U == Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
1961     {
1962         ChMode = Emios_Pwm_Ip_aInitialModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
1963     }
1964     else
1965     {
1966         ChMode =  Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
1967     }
1968 
1969     switch (ChMode)
1970     {
1971 #if ((defined EMIOS_PWM_IP_MODE_OPWFMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWFM_USED) || (defined EMIOS_PWM_IP_MODE_DAOC_USED))
1972         #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
1973         case EMIOS_PWM_IP_MODE_OPWFMB_FLAG:
1974         case EMIOS_PWM_IP_MODE_OPWFMB_FLAG_BOTH:
1975         #endif
1976         #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
1977         case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG:
1978         case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG_BOTH:
1979         case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG:
1980         case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
1981         #endif
1982         #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
1983         case EMIOS_PWM_IP_MODE_DAOC_FLAG:
1984         case EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH:
1985         #endif
1986         /* Channel Mode is OPWFMB, OPWFM or DAOC Mode */
1987         ChPeriod = Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
1988 
1989         /* Prevent compiler warning */
1990         (void)Base;
1991             break;
1992 #endif
1993 
1994 #if (defined EMIOS_PWM_IP_MODE_OPWMCB_USED)
1995         #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED
1996         case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG:
1997         case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH:
1998         case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG:
1999         case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH:
2000         #endif
2001         /* Get the value AS1 in regA register in counter bus */
2002         ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel));
2003         /* The counter period is: (2 x AS1) - 2. */
2004         ChPeriod = (0U != ChPeriod) ? ((ChPeriod << 1U) - 2U) : 0U;
2005             break;
2006 #endif
2007 #if ((defined EMIOS_PWM_IP_MODE_OPWM_USED) || (defined EMIOS_PWM_IP_MODE_OPWMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWMT_USED))
2008         #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
2009         case EMIOS_PWM_IP_MODE_OPWMB_FLAG:
2010         case EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH:
2011         #endif
2012         #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
2013         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG:
2014         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH:
2015         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG:
2016         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
2017         #endif
2018         #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
2019         case EMIOS_PWM_IP_MODE_OPWMT:
2020         #endif
2021         ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel));
2022             break;
2023 #endif
2024         default:
2025         /* GPO or undefined Mode */
2026         ChPeriod = 0U;
2027         /* Prevent compiler warning */
2028         (void)Base;
2029             break;
2030     }
2031 
2032     return ChPeriod;
2033 }
2034 
2035 /**
2036  *
2037  * Function Name : Emios_Pwm_Ip_SetPeriod
2038  * Description   : Setup period of waveforms in OPWFMB Mode.
2039  * With PWM Mode, the OPWFMB(Output Pulse Width and Frequency Modulation Buffered) and the OPWFM(Output Pulse Width and Frequency Modulation) can set
2040  * period. All other PWM modes can not, because OPWFMB Mode using internal counter. All other
2041  * modes use external timebase and their period is timebase period.
2042  *
2043  * @implements Emios_Pwm_Ip_SetPeriod_Activity
2044  **/
Emios_Pwm_Ip_SetPeriod(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_PeriodType NewPeriod)2045 void Emios_Pwm_Ip_SetPeriod(uint8 Instance,
2046                             uint8 Channel,
2047                             Emios_Pwm_Ip_PeriodType NewPeriod
2048                            )
2049 {
2050 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2051     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2052     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2053     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2054 #endif
2055 
2056     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2057 
2058 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2059     /* Check Channel Mode is OPWFMB, OPWFM, DAOC or GPO Mode */
2060     DevAssert(
2061 #if ((defined EMIOS_PWM_IP_MODE_OPWFMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWFM_USED) || (defined EMIOS_PWM_IP_MODE_DAOC_USED))
2062               (EMIOS_PWM_IP_MODE_OPWFMB_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2063               (EMIOS_PWM_IP_MODE_OPWFMB_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2064               (EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2065               (EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2066               (EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2067               (EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2068               (EMIOS_PWM_IP_MODE_DAOC_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2069               (EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2070 #endif
2071               (EMIOS_PWM_IP_MODE_GPO == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
2072 
2073 #endif
2074 
2075     /* If new period is 0, No change the period */
2076     if((Emios_Pwm_Ip_PeriodType)0U == NewPeriod)
2077     {
2078         /* Do Nothing */
2079     }
2080     else
2081     {
2082         /* Set new period */
2083         Emios_Pwm_Ip_SetUCRegB(Base, Channel, NewPeriod);
2084     }
2085     /* Store new period */
2086     Emios_Pwm_Ip_aPeriod[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = NewPeriod;
2087 }
2088 
2089 /**
2090  *
2091  * Function Name : Emios_Pwm_Ip_GetDutyCycle
2092  * Description   : Get duty cycle of waveforms in PWM Mode. Duty cycle is signal active time in a period.
2093  *
2094  * @implements Emios_Pwm_Ip_GetDutyCycle_Activity
2095  **/
Emios_Pwm_Ip_GetDutyCycle(uint8 Instance,uint8 Channel)2096 Emios_Pwm_Ip_DutyType Emios_Pwm_Ip_GetDutyCycle(uint8 Instance,
2097                                                 uint8 Channel
2098                                                )
2099 {
2100 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2101     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2102     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2103     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2104 #endif
2105 
2106     Emios_Pwm_Ip_DutyType DutyCycle = Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
2107 
2108     return DutyCycle;
2109 }
2110 
2111 /**
2112  *
2113  * Function Name : Emios_Pwm_Ip_SetDutyCycle
2114  * Description   : Setup duty cycle of waveforms in OPWFMB, OPWFM Mode.
2115  * Duty cycle should be not greater period value. When set duty cycle value greater period value
2116  * (and do not over 24 bits counter register) 100% duty cycle signal generated.
2117  *
2118  * @implements Emios_Pwm_Ip_SetDutyCycle_Activity
2119  **/
Emios_Pwm_Ip_SetDutyCycle(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType NewDutyCycle)2120 Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetDutyCycle(uint8 Instance,
2121                                                   uint8 Channel,
2122                                                   Emios_Pwm_Ip_DutyType NewDutyCycle
2123                                                  )
2124 {
2125 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2126     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2127     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2128     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2129 #endif
2130 
2131     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
2132     Emios_Pwm_Ip_PwmModeType ChMode;
2133     /* Channels shall be reactivated from idle state. */
2134     ChMode = ((uint8)2U == Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ? Emios_Pwm_Ip_aInitialModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] : \
2135                                                                                                        Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
2136 
2137     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_16();
2138 
2139     switch (ChMode)
2140     {
2141         #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
2142         case EMIOS_PWM_IP_MODE_OPWFMB_FLAG:
2143         case EMIOS_PWM_IP_MODE_OPWFMB_FLAG_BOTH:
2144             /* OPWFMB Mode */
2145             Ret = Emios_Pwm_Ip_SetDutyCycleOpwfmb(Instance, Channel, NewDutyCycle);
2146             break;
2147         #endif
2148         #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
2149         case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG:
2150         case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG_BOTH:
2151         case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG:
2152         case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
2153             /* OPWFM Mode */
2154             Ret = Emios_Pwm_Ip_SetDutyCycleOpwfm(Instance, Channel, NewDutyCycle);
2155             break;
2156         #endif
2157         #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED
2158         case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG:
2159         case EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH:
2160         case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG:
2161         case EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH:
2162             /* OPWMCB Mode */
2163             Ret = Emios_Pwm_Ip_SetDutyCycleOpwmcb(Instance, Channel, NewDutyCycle);
2164             break;
2165         #endif
2166         #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
2167         case EMIOS_PWM_IP_MODE_OPWMB_FLAG:
2168         case EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH:
2169             /* OPWMB Mode */
2170             Ret = Emios_Pwm_Ip_SetDutyCycleOpwmb(Instance, Channel, NewDutyCycle);
2171             break;
2172         #endif
2173         #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
2174         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG:
2175         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
2176         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG:
2177         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH:
2178             /* OPWM Mode */
2179             Ret = Emios_Pwm_Ip_SetDutyCycleOpwm(Instance, Channel, NewDutyCycle);
2180             break;
2181         #endif
2182         #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
2183         case EMIOS_PWM_IP_MODE_DAOC_FLAG:
2184         case EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH:
2185             /* DAOC Mode */
2186             Ret = Emios_Pwm_Ip_SetDutyCycleDaoc(Instance, Channel, NewDutyCycle);
2187             break;
2188         #endif
2189         #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
2190         case EMIOS_PWM_IP_MODE_OPWMT:
2191             /* OPWMT Mode */
2192             Ret = Emios_Pwm_Ip_SetDutyCycleOpwmt(Instance, Channel, NewDutyCycle);
2193             break;
2194         #endif
2195         default:
2196             /* GPO or undefined Mode */
2197             Ret = EMIOS_PWM_IP_STATUS_WRONG_MODE;
2198             break;
2199     }
2200 
2201     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_16();
2202 
2203     return Ret;
2204 }
2205 
2206 /**
2207  *
2208  * Function Name : Emios_Pwm_Ip_GetPhaseShift
2209  * Description   : Get Leading edge position of waveforms in OPWMB & OPWMT Mode.
2210  *
2211  * @implements Emios_Pwm_Ip_GetPhaseShift_Activity
2212  **/
Emios_Pwm_Ip_GetPhaseShift(uint8 Instance,uint8 Channel)2213 Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_GetPhaseShift(uint8 Instance,
2214                                                    uint8 Channel
2215                                                   )
2216 {
2217 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2218     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2219     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2220     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2221 #endif
2222 
2223     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2224 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2225 #if ((defined EMIOS_PWM_IP_MODE_OPWM_USED) || (defined EMIOS_PWM_IP_MODE_OPWMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWMT_USED))
2226     DevAssert((EMIOS_PWM_IP_MODE_OPWMB_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2227               (EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2228               (EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2229               (EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2230               (EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2231               (EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2232               (EMIOS_PWM_IP_MODE_OPWMT == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
2233 #endif
2234 #endif
2235 
2236     return Emios_Pwm_Ip_GetUCRegA(Base, Channel);
2237 }
2238 
2239 /**
2240  *
2241  * Function Name : Emios_Pwm_Ip_SetPhaseShift
2242  * Description   : Set Leading edge position of waveforms in OPWMB, OPWM & OPWMT Mode.
2243  * DutyCycle will be kept the same value.
2244  *
2245  * @implements Emios_Pwm_Ip_SetPhaseShift_Activity
2246  **/
Emios_Pwm_Ip_SetPhaseShift(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_DutyType PhaseShift)2247 Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_SetPhaseShift(uint8 Instance,
2248                                                    uint8 Channel,
2249                                                    Emios_Pwm_Ip_DutyType PhaseShift
2250                                                   )
2251 {
2252 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2253     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2254     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2255     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2256 #endif
2257 
2258     Emios_Pwm_Ip_StatusType Status = EMIOS_PWM_IP_STATUS_SUCCESS;
2259     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2260     Emios_Pwm_Ip_CounterBusSourceType CounterBus = Emios_Pwm_Ip_GetCounterBus(Base, Channel);
2261     Emios_Pwm_Ip_PeriodType ChPeriod = 0U;
2262     Emios_Pwm_Ip_DutyType DutyCycle = 0U;
2263 #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
2264     uint8  CounterStart = 0U;
2265 #endif
2266 
2267 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2268 #if ((defined EMIOS_PWM_IP_MODE_OPWM_USED) || (defined EMIOS_PWM_IP_MODE_OPWMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWMT_USED))
2269     DevAssert((EMIOS_PWM_IP_MODE_OPWMB_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2270               (EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2271               (EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2272               (EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2273               (EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2274               (EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]) ||
2275               (EMIOS_PWM_IP_MODE_OPWMT == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]));
2276 #endif
2277 #endif
2278 
2279     ChPeriod = Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, CounterBus);
2280     DutyCycle = Emios_Pwm_Ip_aDutyCycle[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
2281 #if ((defined EMIOS_PWM_IP_MODE_OPWM_USED) || (defined EMIOS_PWM_IP_MODE_OPWMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWMT_USED))
2282     /* Check that phase shift can be applied to the selected Channel */
2283     switch (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
2284     {
2285 #if ((defined EMIOS_PWM_IP_MODE_OPWM_USED) || (defined EMIOS_PWM_IP_MODE_OPWMB_USED))
2286 #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
2287         case EMIOS_PWM_IP_MODE_OPWMB_FLAG:
2288         case EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH:
2289 #endif
2290 #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
2291         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG:
2292         case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH:
2293         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG:
2294         case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
2295 #endif
2296             Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = PhaseShift;
2297             if ((PhaseShift + DutyCycle) > ChPeriod)
2298             {
2299                 Status = EMIOS_PWM_IP_STATUS_ERROR;
2300             }
2301             else
2302             {
2303                 /* Set the new phase shift */
2304                 Emios_Pwm_Ip_SetUCRegA(Base, Channel, Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]);
2305                 /* Move trailing edge to keep the same duty cycle */
2306                 Emios_Pwm_Ip_SetUCRegB(Base, Channel, (Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] + DutyCycle));
2307             }
2308             break;
2309 #endif
2310 #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
2311         case EMIOS_PWM_IP_MODE_OPWMT:
2312             CounterStart = (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, Channel, CounterBus)) ? 0x01U : 0x00U;
2313 
2314             Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = PhaseShift + CounterStart;
2315             if (PhaseShift > ChPeriod)
2316             {
2317                 Status = EMIOS_PWM_IP_STATUS_ERROR;
2318             }
2319             else
2320             {
2321                 /* Set the new phase shift */
2322                 Emios_Pwm_Ip_SetUCRegA(Base, Channel, Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]]);
2323                 /* Move trailing edge to keep the same duty cycle */
2324                 Emios_Pwm_Ip_SetUCRegB(Base, Channel, (Emios_Pwm_Ip_aRegA[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] + DutyCycle));
2325             }
2326             break;
2327 #endif
2328         default:
2329             Status = EMIOS_PWM_IP_STATUS_ERROR;
2330             break;
2331     }
2332 #else
2333     /* Prevent CWE */
2334     (void)ChPeriod;
2335     (void)DutyCycle;
2336     (void)PhaseShift;
2337 #endif
2338 
2339     return Status;
2340 }
2341 
2342 /**
2343  *
2344  * Function Name : Emios_Pwm_Ip_GetDeadTime
2345  * Description   : Get Dead time value of waveforms in OPWMCB Mode.
2346  *
2347  * @implements Emios_Pwm_Ip_GetDeadTime_Activity
2348  **/
Emios_Pwm_Ip_GetDeadTime(uint8 Instance,uint8 Channel)2349 Emios_Pwm_Ip_PeriodType Emios_Pwm_Ip_GetDeadTime(uint8 Instance,
2350                                                  uint8 Channel
2351                                                 )
2352 {
2353 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2354     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2355     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2356     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2357 #endif
2358 
2359     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2360 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2361 #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED
2362     DevAssert((Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
2363               (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
2364               (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
2365               (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH));
2366 #endif
2367 #endif
2368     /* Get the configured dead time */
2369     return Emios_Pwm_Ip_GetUCRegB(Base, Channel);
2370 }
2371 
2372 /**
2373  *
2374  * Function Name : Emios_Pwm_Ip_SetDeadTime
2375  * Description   : Set Dead time value of waveforms in OPWMCB Mode. New dead time should
2376  * be no greater than 0xFFFFFF (24 bits).
2377  *
2378  * @implements Emios_Pwm_Ip_SetDeadTime_Activity
2379  **/
Emios_Pwm_Ip_SetDeadTime(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_PeriodType NewDeadTime)2380 void Emios_Pwm_Ip_SetDeadTime(uint8 Instance,
2381                               uint8 Channel,
2382                               Emios_Pwm_Ip_PeriodType NewDeadTime
2383                              )
2384 {
2385 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2386     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2387     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2388     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2389 #endif
2390     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2391 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2392 #if (defined EMIOS_PWM_IP_MODE_OPWMCB_USED)
2393     DevAssert((Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
2394               (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH) ||
2395               (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
2396               (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH));
2397 #endif
2398 #endif
2399 
2400     /* Set the new dead time */
2401     Emios_Pwm_Ip_SetUCRegB(Base, Channel, NewDeadTime);
2402 }
2403 
2404 /**
2405  *
2406  * Function Name : Emios_Pwm_Ip_GetTriggerPlacement
2407  * Description   : Get Trigger placement value in OPWMT Mode
2408  *
2409  * @implements Emios_Pwm_Ip_GetTriggerPlacement_Activity
2410  **/
Emios_Pwm_Ip_GetTriggerPlacement(uint8 Instance,uint8 Channel)2411 uint32 Emios_Pwm_Ip_GetTriggerPlacement(uint8 Instance,
2412                                         uint8 Channel
2413                                        )
2414 {
2415 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2416     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2417     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2418     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2419 #endif
2420     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2421     uint8 CounterStart                        = 0U;
2422 
2423 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2424 #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
2425     DevAssert(Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMT);
2426 #endif
2427 #endif
2428 
2429     if (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel)))
2430     {
2431         CounterStart = 1U;
2432     }
2433     else
2434     {
2435         CounterStart = 0U;
2436     }
2437 
2438     /* Get the configured trigger */
2439     return (Emios_Pwm_Ip_GetTrigger(Base, Channel) - (Emios_Pwm_Ip_PeriodType)CounterStart);
2440 }
2441 
2442 /**
2443  *
2444  * Function Name : Emios_Pwm_Ip_SetTriggerPlacement
2445  * Description   : Set Trigger placement value in OPWMT Mode. New trigger placement
2446  * should be no larger than 0xFFFFFF(24 bits).
2447  *
2448  * @implements Emios_Pwm_Ip_SetTriggerPlacement_Activity
2449  **/
Emios_Pwm_Ip_SetTriggerPlacement(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_PeriodType NewTriggerPlacement)2450 void Emios_Pwm_Ip_SetTriggerPlacement(uint8 Instance,
2451                                       uint8 Channel,
2452                                       Emios_Pwm_Ip_PeriodType NewTriggerPlacement
2453                                      )
2454 {
2455 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2456     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2457     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2458     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2459 #endif
2460 
2461     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2462     uint8 CounterStart = 0U;
2463 
2464 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2465 #ifdef EMIOS_PWM_IP_MODE_OPWMT_USED
2466     DevAssert(Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] == EMIOS_PWM_IP_MODE_OPWMT);
2467 #endif
2468     /* Check selected counter bus is configured in MCB Up Mode or MC Up Mode */
2469     DevAssert((EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel))) ||
2470               (EMIOS_PWM_IP_MC_UP_COUNTER_START == Emios_Pwm_Ip_GetCounterBusMode(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel))) ||
2471               (EMIOS_PWM_IP_MC_UP_COUNTER_END == Emios_Pwm_Ip_GetCounterBusMode(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel)))
2472              );
2473     DevAssert((Emios_Pwm_Ip_GetCounterBusPeriod(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel))) > NewTriggerPlacement);
2474 #endif
2475 
2476     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_17();
2477     if (EMIOS_PWM_IP_MCB_UP_COUNTER == Emios_Pwm_Ip_GetCounterBusMode(Instance, Channel, Emios_Pwm_Ip_GetCounterBus(Base, Channel)))
2478     {
2479         CounterStart = 1U;
2480     }
2481     else
2482     {
2483         CounterStart = 0U;
2484     }
2485     /* Set the new trigger value */
2486     Emios_Pwm_Ip_SetTrigger(Base, Channel, (Emios_Pwm_Ip_PeriodType)(NewTriggerPlacement + CounterStart));
2487     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_17();
2488 }
2489 
2490 /**
2491  *
2492  * Function Name : Emios_Pwm_Ip_ChannelEnterDebugMode
2493  * Description   : To set a Channel enters freeze state, should be setting
2494  * Emios_Pwm_Ip_AllowEnterDebugMode first.
2495  *
2496  * @implements Emios_Pwm_Ip_ChannelEnterDebugMode_Activity
2497  **/
Emios_Pwm_Ip_ChannelEnterDebugMode(uint8 Instance,uint8 Channel)2498 Emios_Pwm_Ip_StatusType Emios_Pwm_Ip_ChannelEnterDebugMode(uint8 Instance,
2499                                                            uint8 Channel
2500                                                           )
2501 {
2502 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2503     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2504     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2505 #endif
2506     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2507     Emios_Pwm_Ip_StatusType Ret = EMIOS_PWM_IP_STATUS_SUCCESS;
2508 
2509     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_18();
2510     if (Emios_Pwm_Ip_GetDebugMode(Base) == TRUE)
2511     {
2512         Emios_Pwm_Ip_SetFreezeEnable(Base, Channel, TRUE);
2513     }
2514     else
2515     {
2516         Ret = EMIOS_PWM_IP_STATUS_GLOBAL_FREEZE_DISABLED;
2517     }
2518     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_18();
2519     return Ret;
2520 }
2521 
2522 /**
2523  *
2524  * Function Name : Emios_Pwm_Ip_ChannelStopDebugMode
2525  * Description   : Release a Channel from freeze state
2526  *
2527  * @implements Emios_Pwm_Ip_ChannelStopDebugMode_Activity
2528  **/
Emios_Pwm_Ip_ChannelStopDebugMode(uint8 Instance,uint8 Channel)2529 void Emios_Pwm_Ip_ChannelStopDebugMode(uint8 Instance,
2530                                        uint8 Channel
2531                                       )
2532 {
2533 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2534     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2535     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2536 #endif
2537     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2538 
2539     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_19();
2540     Emios_Pwm_Ip_SetFreezeEnable(Base, Channel, FALSE);
2541     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_19();
2542 }
2543 
2544 /**
2545 *
2546 * Function Name : Emios_Pwm_Ip_GetFlagRequest
2547 * Description   : Configure what the FLAG event should do. Generate Interrupt request,
2548 *                 Generate DMA request or do nothing.
2549 *
2550 * @implements Emios_Pwm_Ip_GetFlagRequest_Activity
2551 **/
Emios_Pwm_Ip_GetFlagRequest(uint8 Instance,uint8 Channel)2552 Emios_Pwm_Ip_InterruptType Emios_Pwm_Ip_GetFlagRequest(uint8 Instance,
2553                                                        uint8 Channel
2554                                                       )
2555 {
2556 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2557     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2558     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2559 #endif
2560     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2561     Emios_Pwm_Ip_InterruptType EventType = EMIOS_PWM_IP_NOTIFICATION_DISABLED;
2562 
2563     if (Emios_Pwm_Ip_GetInterruptRequest(Base, Channel) == TRUE)
2564     {
2565         if (Emios_Pwm_Ip_GetDMARequest(Base, Channel) == TRUE)
2566         {
2567             EventType = EMIOS_PWM_IP_DMA_REQUEST;
2568         }
2569         else
2570         {
2571             EventType = EMIOS_PWM_IP_INTERRUPT_REQUEST;
2572         }
2573     }
2574 
2575     return EventType;
2576 }
2577 
2578 /**
2579 *
2580 * Function Name : Emios_Pwm_Ip_SetFlagRequest
2581 * Description   : Configure what the FLAG event should do. Generate Interrupt request,
2582 *                 Generate DMA request or do nothing.
2583 *
2584 * @implements Emios_Pwm_Ip_SetFlagRequest_Activity
2585 **/
Emios_Pwm_Ip_SetFlagRequest(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_InterruptType Event)2586 void Emios_Pwm_Ip_SetFlagRequest(uint8 Instance,
2587                                  uint8 Channel,
2588                                  Emios_Pwm_Ip_InterruptType Event
2589                                 )
2590 {
2591 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2592     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2593     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2594     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2595 #endif
2596     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2597 
2598     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_20();
2599     /* Clear Interrupt flag */
2600     Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
2601 
2602     switch (Event)
2603     {
2604     case EMIOS_PWM_IP_INTERRUPT_REQUEST:
2605         if ((uint8)0U == Emios_Pwm_Ip_aNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
2606         {
2607             Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, TRUE);
2608             Emios_Pwm_Ip_SetDMARequest(Base, Channel, FALSE);
2609             Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
2610         }
2611         break;
2612     case EMIOS_PWM_IP_DMA_REQUEST:
2613         Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, TRUE);
2614         Emios_Pwm_Ip_SetDMARequest(Base, Channel, TRUE);
2615         Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)1U;
2616         break;
2617     case EMIOS_PWM_IP_NOTIFICATION_DISABLED:
2618         Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
2619         Emios_Pwm_Ip_SetDMARequest(Base, Channel, FALSE);
2620         Emios_Pwm_Ip_aCheckEnableNotif[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)0U;
2621         break;
2622     default:
2623         /* Nothig to do. All cases are treated.*/
2624         break;
2625     }
2626     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_20();
2627 }
2628 
2629 /**
2630 *
2631 * Function Name : Emios_Pwm_Ip_GetOutputState
2632 * Description   : Get the Unified Channel output pin logic level
2633 *
2634 * @implements Emios_Pwm_Ip_GetOutputState_Activity
2635 **/
Emios_Pwm_Ip_GetOutputState(uint8 Instance,uint8 Channel)2636 Emios_Pwm_Ip_OutputStateType Emios_Pwm_Ip_GetOutputState(uint8 Instance,
2637                                                          uint8 Channel
2638                                                         )
2639 {
2640 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2641     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2642     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2643 #endif
2644     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2645 
2646     return (Emios_Pwm_Ip_GetOutputPinState(Base, Channel) == FALSE)? EMIOS_PWM_IP_OUTPUT_STATE_LOW : EMIOS_PWM_IP_OUTPUT_STATE_HIGH;
2647 }
2648 
2649 /**
2650 *
2651 * Function Name : Emios_Pwm_Ip_SetOutputState
2652 * Description   : Set the state of output pin
2653 *
2654 * @implements Emios_Pwm_Ip_SetOutputState_Activity
2655 **/
Emios_Pwm_Ip_SetOutputState(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_OutputStateType OutputState)2656 void Emios_Pwm_Ip_SetOutputState(uint8 Instance,
2657                                  uint8 Channel,
2658                                  Emios_Pwm_Ip_OutputStateType OutputState
2659                                 )
2660 {
2661 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2662     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2663     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2664     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2665 #endif
2666     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2667     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_21();
2668     /* Set output pin polarity */
2669     if (EMIOS_PWM_IP_OUTPUT_STATE_LOW == OutputState)
2670     {
2671         Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, (Emios_Pwm_Ip_PolarityType)EMIOS_PWM_IP_ACTIVE_LOW);
2672     }
2673     else
2674     {
2675         Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, (Emios_Pwm_Ip_PolarityType)EMIOS_PWM_IP_ACTIVE_HIGH);
2676     }
2677     /* Enter GPIO output Mode */
2678     Emios_Pwm_Ip_SetPwmMode(Base, Channel, (Emios_Pwm_Ip_PwmModeType)EMIOS_PWM_IP_MODE_GPO);
2679     /* Stored the current Mode */
2680     Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (Emios_Pwm_Ip_PwmModeType)EMIOS_PWM_IP_MODE_GPO;
2681     /* Disable Channel interrupts */
2682     Emios_Pwm_Ip_SetInterruptRequest(Base, Channel, FALSE);
2683     /* Clear pending interrupt flag for the Channel */
2684     Emios_Pwm_Ip_ClearFlagEvent(Base, Channel);
2685     /* Confirm the Channel is idle state */
2686     Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = (uint8)2U;
2687     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_21();
2688 }
2689 
2690 /**
2691 *
2692 * Function Name : Emios_Pwm_Ip_SetOutputToNormal
2693 * Description   : Set the polarity and Mode for current Channel as normal
2694 *
2695 * @implements Emios_Pwm_Ip_SetOutputToNormal_Activity
2696 **/
Emios_Pwm_Ip_SetOutputToNormal(uint8 Instance,uint8 Channel,uint16 DutyPercent,Emios_Pwm_Ip_PolarityType Polarity,Emios_Pwm_Ip_PwmModeType Mode)2697 void Emios_Pwm_Ip_SetOutputToNormal(uint8 Instance,
2698                                     uint8 Channel,
2699                                     uint16 DutyPercent,
2700                                     Emios_Pwm_Ip_PolarityType Polarity,
2701                                     Emios_Pwm_Ip_PwmModeType  Mode
2702                                    )
2703 {
2704 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2705     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2706     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2707     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2708 #endif
2709     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2710 
2711     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_22();
2712     if (EMIOS_PWM_IP_MODE_GPO == Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]])
2713     {
2714 #if ((defined EMIOS_PWM_IP_MODE_OPWFMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWFM_USED) || \
2715      (defined EMIOS_PWM_IP_MODE_OPWMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWM_USED) || \
2716      (defined EMIOS_PWM_IP_MODE_DAOC_USED))
2717         switch (Mode)
2718         {
2719 #ifdef EMIOS_PWM_IP_MODE_OPWFMB_USED
2720             case EMIOS_PWM_IP_MODE_OPWFMB_FLAG:
2721             case EMIOS_PWM_IP_MODE_OPWFMB_FLAG_BOTH:
2722                 Emios_Pwm_Ip_SetPwmMode(Base, Channel, Mode);
2723                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel,(Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH );
2724                 break;
2725 #endif
2726 #ifdef EMIOS_PWM_IP_MODE_OPWFM_USED
2727             case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG:
2728             case EMIOS_PWM_IP_MODE_OPWFM_IMMEDIATE_UPDATE_FLAG_BOTH:
2729             case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG:
2730             case EMIOS_PWM_IP_MODE_OPWFM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
2731                 Emios_Pwm_Ip_SetOutputToNormalOpwfm(Instance, Channel, DutyPercent, Polarity, Mode);
2732                 break;
2733 #endif
2734 #ifdef EMIOS_PWM_IP_MODE_OPWMB_USED
2735             case EMIOS_PWM_IP_MODE_OPWMB_FLAG:
2736             case EMIOS_PWM_IP_MODE_OPWMB_FLAG_BOTH:
2737                 Emios_Pwm_Ip_SetPwmMode(Base, Channel, Mode);
2738                 Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, Polarity);
2739                 break;
2740 #endif
2741 #ifdef EMIOS_PWM_IP_MODE_OPWM_USED
2742             case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG:
2743             case EMIOS_PWM_IP_MODE_OPWM_IMMEDIATE_UPDATE_FLAG_BOTH:
2744             case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG:
2745             case EMIOS_PWM_IP_MODE_OPWM_NEXT_PERIOD_UPDATE_FLAG_BOTH:
2746                 Emios_Pwm_Ip_SetOutputToNormalOpwm(Instance, Channel, DutyPercent, Polarity, Mode);
2747                 break;
2748 #endif
2749 #ifdef EMIOS_PWM_IP_MODE_DAOC_USED
2750             case EMIOS_PWM_IP_MODE_DAOC_FLAG:
2751             case EMIOS_PWM_IP_MODE_DAOC_FLAG_BOTH:
2752                 if(0x8000U == DutyPercent)
2753                 {
2754                     Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH);
2755                 }
2756                 else
2757                 {
2758                     Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, Polarity);
2759                 }
2760                 Emios_Pwm_Ip_SetPwmMode(Base, Channel, Mode);
2761                 Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]] = Mode;
2762                 break;
2763 #endif
2764             default:
2765                 /* To avoid spike pulse
2766                 If duty cycle = 100%, when enter Mode, EDPOL bit get complement of polarity
2767                 after that, EDPOL bit is restored valid value */
2768 
2769 #endif
2770                 if(0x8000U == DutyPercent)
2771                 {
2772                     Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, (Polarity == EMIOS_PWM_IP_ACTIVE_HIGH) ? EMIOS_PWM_IP_ACTIVE_LOW : EMIOS_PWM_IP_ACTIVE_HIGH);
2773                     Emios_Pwm_Ip_SetEdgePolarity(Base, Channel, Polarity);
2774                 }
2775                 else
2776                 {
2777                     Emios_Pwm_Ip_SetPwmModePol(Base, Channel, Mode, Polarity);
2778                 }
2779 #if ((defined EMIOS_PWM_IP_MODE_OPWFMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWFM_USED) || \
2780      (defined EMIOS_PWM_IP_MODE_OPWMB_USED) || (defined EMIOS_PWM_IP_MODE_OPWM_USED) || \
2781      (defined EMIOS_PWM_IP_MODE_DAOC_USED))
2782                 break;
2783         }
2784 #endif
2785     }
2786     else
2787     {
2788         /*Do Nothing*/
2789         (void)Polarity;
2790         (void)Mode;
2791         (void)DutyPercent;
2792     }
2793     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_22();
2794 }
2795 
2796 /**
2797 *
2798 * Function Name : Emios_Pwm_Ip_GetChannelMode
2799 * Description   : Get Mode of operation of the Unified Channel
2800 *
2801 * @implements Emios_Pwm_Ip_GetChannelMode_Activity
2802 **/
Emios_Pwm_Ip_GetChannelMode(uint8 Instance,uint8 Channel)2803 Emios_Pwm_Ip_PwmModeType Emios_Pwm_Ip_GetChannelMode(uint8 Instance,
2804                                                      uint8 Channel
2805                                                     )
2806 {
2807 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2808     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2809     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2810     DevAssert(EMIOS_PWM_IP_NUM_OF_CHANNELS_USED_U8 > eMios_Pwm_Ip_IndexInChState[Instance][Channel]);
2811 #endif
2812 
2813     Emios_Pwm_Ip_PwmModeType ChannelMode = Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][Channel]];
2814 
2815     return ChannelMode;
2816 }
2817 
2818 /**
2819 *
2820 * Function Name : Emios_Pwm_Ip_GetMasterBusChannel
2821 * Description   : Get master bus Channel
2822 *
2823 * @implements Emios_Pwm_Ip_GetMasterBusChannel_Activity
2824 **/
Emios_Pwm_Ip_GetMasterBusChannel(uint8 Instance,uint8 Channel)2825 uint8 Emios_Pwm_Ip_GetMasterBusChannel(uint8 Instance,
2826                                        uint8 Channel
2827                                       )
2828 {
2829 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2830     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2831     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2832 #endif
2833     const Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2834 
2835     uint8 ChannelMaster = Channel;
2836 
2837     Emios_Pwm_Ip_CounterBusSourceType CounterBus = Emios_Pwm_Ip_GetCounterBus(Base, Channel);
2838 
2839     switch (CounterBus)
2840     {
2841         case EMIOS_PWM_IP_BUS_A:
2842             ChannelMaster = 23U;
2843             break;
2844         case EMIOS_PWM_IP_BUS_F:
2845             ChannelMaster = 22U;
2846             break;
2847         case EMIOS_PWM_IP_BUS_BCDE:
2848             ChannelMaster = (uint8)((Channel >> 3U) * 8U);
2849             break;
2850         default:
2851             /* Internal bus is used */
2852             ChannelMaster = Channel;
2853             break;
2854     }
2855     return ChannelMaster;
2856 }
2857 
2858 /**
2859 *
2860 * Function Name : Emios_Pwm_Ip_SetPreEnableClock
2861 * Description   : Set Prescaler Enable bit.
2862 *
2863 * @implements Emios_Pwm_Ip_SetPreEnableClock_Activity
2864 **/
Emios_Pwm_Ip_SetPreEnableClock(uint8 Instance,uint8 Channel,boolean Value)2865 void Emios_Pwm_Ip_SetPreEnableClock(uint8 Instance,
2866                                     uint8 Channel,
2867                                     boolean Value
2868                                    )
2869 {
2870 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2871     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2872     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2873 #endif
2874     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2875 
2876     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_23();
2877     /* Set Prescaler Enable bit. */
2878     Emios_Pwm_Ip_SetPrescalerEnable(Base, Channel, Value);
2879     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_23();
2880 }
2881 
2882 /**
2883 *
2884 * Function Name : Emios_Pwm_Ip_SetBusSelected
2885 * Description   : Set Bus Select bits.
2886 *
2887 * @implements Emios_Pwm_Ip_SetBusSelected_Activity
2888 **/
Emios_Pwm_Ip_SetBusSelected(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_CounterBusSourceType Value)2889 void Emios_Pwm_Ip_SetBusSelected(uint8 Instance,
2890                                  uint8 Channel,
2891                                  Emios_Pwm_Ip_CounterBusSourceType Value
2892                                 )
2893 {
2894 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2895     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2896     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2897 #endif
2898     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2899     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_24();
2900     /* Set Bus Select bits.*/
2901     Emios_Pwm_Ip_SetCounterBus(Base, Channel, Value);
2902     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_24();
2903 }
2904 
2905 /**
2906 *
2907 * Function Name : Emios_Pwm_Ip_SetClockPs
2908 * Description   : This function set the value of the prescaler on eMios channels
2909 *
2910 * @implements Emios_Pwm_Ip_SetClockPs_Activity
2911 **/
Emios_Pwm_Ip_SetClockPs(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_InternalClkPsType Value)2912 void Emios_Pwm_Ip_SetClockPs(uint8 Instance,
2913                              uint8 Channel,
2914                              Emios_Pwm_Ip_InternalClkPsType Value
2915                             )
2916 {
2917 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2918     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2919     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
2920 #endif
2921     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2922     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_25();
2923     /* Stop eMios Channel - this will stop the internal counter */
2924     Emios_Pwm_Ip_SetPrescalerEnable(Base, Channel, FALSE);
2925     /*Set Extended Prescaler bits */
2926     Emios_Pwm_Ip_SetExtendedPrescaler(Base, Channel, Value);
2927     /* Re-start eMios Channel */
2928     Emios_Pwm_Ip_SetPrescalerEnable(Base, Channel, TRUE);
2929     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_25();
2930 }
2931 
2932 /**
2933 *
2934 * Function Name : Emios_Pwm_Ip_ComparatorTransferEnable
2935 * Description   : The function shall enable the output update for the corresponding Channel.
2936 *
2937 * @implements Emios_Pwm_Ip_ComparatorTransferEnable_Activity
2938 **/
Emios_Pwm_Ip_ComparatorTransferEnable(uint8 Instance,uint32 ChannelMask)2939 void Emios_Pwm_Ip_ComparatorTransferEnable(uint8 Instance, uint32 ChannelMask)
2940 {
2941 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2942     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2943 #endif
2944 
2945     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_26();
2946 
2947     /* Enable the output update for the corresponding Channel.*/
2948     Emios_Mcl_Ip_ComparatorTransferEnable(Instance, ChannelMask);
2949 
2950     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_26();
2951 }
2952 
2953 /**
2954 *
2955 * Function Name : Emios_Pwm_Ip_ComparatorTransferDisable
2956 * Description   : The function shall disable the output update for the corresponding Channel.
2957 *
2958 * @implements Emios_Pwm_Ip_ComparatorTransferDisable_Activity
2959 **/
Emios_Pwm_Ip_ComparatorTransferDisable(uint8 Instance,uint32 ChannelMask)2960 void Emios_Pwm_Ip_ComparatorTransferDisable(uint8 Instance, uint32 ChannelMask)
2961 {
2962 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2963     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2964 #endif
2965 
2966     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_27();
2967 
2968     /* Disable the output update for the corresponding Channel.*/
2969     Emios_Mcl_Ip_ComparatorTransferDisable(Instance, ChannelMask);
2970 
2971     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_27();
2972 }
2973 
2974 /**
2975 *
2976 * Function Name : Emios_Pwm_Ip_SyncUpdate
2977 * Description   : This function updates the duty cycle and-or period for the specified PWM Channel.
2978 *                 The value written does not take effect until calling SyncUpdate API.
2979 *
2980 * @implements Emios_Pwm_Ip_SyncUpdate_Activity
2981 **/
Emios_Pwm_Ip_SyncUpdate(uint8 Instance)2982 void Emios_Pwm_Ip_SyncUpdate(uint8 Instance)
2983 {
2984 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
2985     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
2986 #endif
2987     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
2988 
2989     /* Read OUDIS register */
2990     uint32 OudisRegVal = (uint32)Emios_Pwm_Ip_GetOutputUpdateInstance(Base);
2991     /* the mask of channels */
2992     uint32 ChannelMask = (uint32)0U;
2993 
2994     uint8  OudisDisable = 0U;
2995     uint8  ChannelId;
2996 
2997     SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_28();
2998 
2999     /* Loop all channels available on each Emios Instance */
3000     for (ChannelId = 0U; ChannelId < EMIOS_PWM_IP_CHANNEL_COUNT; ChannelId++)
3001     {
3002         OudisDisable = (uint8)((OudisRegVal & (uint32)((uint32)1U << ChannelId)) >> ChannelId);
3003 
3004         if (((uint8)0U != Emios_Pwm_Ip_aCheckState[eMios_Pwm_Ip_IndexInChState[Instance][ChannelId]]) && ((uint8)1U == OudisDisable))
3005         {
3006 #ifdef EMIOS_PWM_IP_MODE_OPWMCB_USED
3007             /* This statement is required to avoid limitation of 0% duty cycle (if call 100% to 0%) */
3008             if(1U == Emios_Pwm_Ip_GetUCRegA(Base, ChannelId))
3009             {
3010                 if((Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][ChannelId]] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG) ||
3011                    (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][ChannelId]] == EMIOS_PWM_IP_MODE_OPWMCB_TRAIL_EDGE_FLAG_BOTH))
3012                 {
3013                     /* Enable the output update for the corresponding Channel.*/
3014                     Emios_Mcl_Ip_ComparatorTransferEnable(Instance, (uint32)((uint32)1U << ChannelId));
3015 
3016                     Emios_Pwm_Ip_SetForceMatchB(Base, ChannelId, TRUE);
3017                 }
3018                 else if ((Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][ChannelId]] == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG) ||
3019                          (Emios_Pwm_Ip_aCurrentModes[eMios_Pwm_Ip_IndexInChState[Instance][ChannelId]] == EMIOS_PWM_IP_MODE_OPWMCB_LEAD_EDGE_FLAG_BOTH))
3020                 {
3021                     /* Enable the output update for the corresponding Channel.*/
3022                     Emios_Mcl_Ip_ComparatorTransferEnable(Instance, (uint32)((uint32)1U << ChannelId));
3023 
3024                     Emios_Pwm_Ip_SetForceMatchA(Base, ChannelId, TRUE);
3025                 }
3026                 else
3027                 {
3028                     /* Do Nothing */
3029                 }
3030             }
3031 #endif
3032             /* Update OUDIS register value for synchronization */
3033             ChannelMask |= (uint32)((uint32)1U << ChannelId);
3034         }
3035     }
3036     /* Write OUDIS register */
3037     Emios_Mcl_Ip_ComparatorTransferEnable(Instance, ChannelMask);
3038 
3039     SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_28();
3040 }
3041 
3042 /**
3043 *
3044 * Function Name : Emios_Pwm_Ip_UpdateUCRegA
3045 * Description   : This function updates the value of UCRegA. It may be used to
3046 *                 change duty cycle or phase shift with minimum overhead.
3047 *
3048 * @implements Emios_Pwm_Ip_UpdateUCRegA_Activity
3049 **/
Emios_Pwm_Ip_UpdateUCRegA(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_PeriodType Value)3050 void Emios_Pwm_Ip_UpdateUCRegA(uint8 Instance, uint8 Channel, Emios_Pwm_Ip_PeriodType Value)
3051 {
3052 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
3053     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
3054     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
3055 #endif
3056 
3057     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
3058     Emios_Pwm_Ip_SetUCRegA(Base, Channel, Value);
3059 }
3060 
3061 /**
3062 *
3063 * Function Name : Emios_Pwm_Ip_UpdateUCRegB
3064 * Description   : This function updates the value of UCRegB. It may be used to
3065 *                 change duty cycle, phase shift or inserted dead time buffer
3066 *                 with minimum overhead.
3067 *
3068 * @implements Emios_Pwm_Ip_UpdateUCRegB_Activity
3069 **/
Emios_Pwm_Ip_UpdateUCRegB(uint8 Instance,uint8 Channel,Emios_Pwm_Ip_PeriodType Value)3070 void Emios_Pwm_Ip_UpdateUCRegB(uint8 Instance, uint8 Channel, Emios_Pwm_Ip_PeriodType Value)
3071 {
3072 #if (EMIOS_PWM_IP_DEV_ERROR_DETECT == STD_ON)
3073     DevAssert(EMIOS_PWM_IP_INSTANCE_COUNT > Instance);
3074     DevAssert(EMIOS_PWM_IP_CHANNEL_COUNT > Channel);
3075 #endif
3076 
3077     Emios_Pwm_Ip_HwAddrType *const Base = Emios_Pwm_Ip_aBasePtr[Instance];
3078     Emios_Pwm_Ip_SetUCRegB(Base, Channel, Value);
3079 }
3080 
3081 #define PWM_STOP_SEC_CODE
3082 #include "Pwm_MemMap.h"
3083 
3084 
3085 #endif /* EMIOS_PWM_IP_USED == STD_ON */
3086 #ifdef __cplusplus
3087 }
3088 #endif
3089 
3090 /** @} */
3091