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