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