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