File indexing completed on 2025-05-11 08:23:00
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_pwm.h"
0010
0011
0012 #ifndef FSL_COMPONENT_ID
0013 #define FSL_COMPONENT_ID "platform.drivers.pwm"
0014 #endif
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 static uint32_t PWM_GetInstance(PWM_Type *base);
0027
0028
0029
0030
0031
0032 static PWM_Type *const s_pwmBases[] = PWM_BASE_PTRS;
0033
0034 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0035
0036 static const clock_ip_name_t s_pwmClocks[][FSL_FEATURE_PWM_SUBMODULE_COUNT] = PWM_CLOCKS;
0037 #endif
0038
0039
0040 static uint8_t s_pwmGetPwmDutyCycle[FSL_FEATURE_PWM_SUBMODULE_COUNT][PWM_SUBMODULE_CHANNEL] = {{0}};
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 static inline uint16_t PWM_GetComplementU16(uint16_t value)
0055 {
0056 return (~value + 1U);
0057 }
0058
0059 static inline uint16_t dutyCycleToReloadValue(uint8_t dutyCyclePercent)
0060 {
0061
0062 return ((65535U * dutyCyclePercent) + 50U) / 100U;
0063 }
0064
0065 static uint32_t PWM_GetInstance(PWM_Type *base)
0066 {
0067 uint32_t instance;
0068
0069
0070 for (instance = 0; instance < ARRAY_SIZE(s_pwmBases); instance++)
0071 {
0072 if (s_pwmBases[instance] == base)
0073 {
0074 break;
0075 }
0076 }
0077
0078 assert(instance < ARRAY_SIZE(s_pwmBases));
0079
0080 return instance;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 status_t PWM_Init(PWM_Type *base, pwm_submodule_t subModule, const pwm_config_t *config)
0095 {
0096 assert(config);
0097
0098 uint16_t reg;
0099
0100
0101 if ((config->clockSource == kPWM_Submodule0Clock) && (subModule == kPWM_Module_0))
0102 {
0103 return kStatus_Fail;
0104 }
0105
0106
0107 if ((config->reloadSelect == kPWM_MasterReload) && (subModule == kPWM_Module_0))
0108 {
0109 return kStatus_Fail;
0110 }
0111
0112 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0113
0114 CLOCK_EnableClock(s_pwmClocks[PWM_GetInstance(base)][subModule]);
0115 #endif
0116
0117
0118 base->FSTS |= PWM_FSTS_FFLAG_MASK;
0119
0120 reg = base->SM[subModule].CTRL2;
0121
0122
0123
0124
0125 reg &=
0126 ~(uint16_t)(PWM_CTRL2_CLK_SEL_MASK | PWM_CTRL2_FORCE_SEL_MASK | PWM_CTRL2_INIT_SEL_MASK | PWM_CTRL2_INDEP_MASK |
0127 #if !defined(FSL_FEATURE_PWM_HAS_NO_WAITEN) || (!FSL_FEATURE_PWM_HAS_NO_WAITEN)
0128 PWM_CTRL2_WAITEN_MASK |
0129 #endif
0130 PWM_CTRL2_DBGEN_MASK | PWM_CTRL2_RELOAD_SEL_MASK);
0131 reg |= (PWM_CTRL2_CLK_SEL(config->clockSource) | PWM_CTRL2_FORCE_SEL(config->forceTrigger) |
0132 PWM_CTRL2_INIT_SEL(config->initializationControl) | PWM_CTRL2_DBGEN(config->enableDebugMode) |
0133 #if !defined(FSL_FEATURE_PWM_HAS_NO_WAITEN) || (!FSL_FEATURE_PWM_HAS_NO_WAITEN)
0134 PWM_CTRL2_WAITEN(config->enableWait) |
0135 #endif
0136 PWM_CTRL2_RELOAD_SEL(config->reloadSelect));
0137
0138
0139 switch (config->pairOperation)
0140 {
0141 case kPWM_Independent:
0142 reg |= PWM_CTRL2_INDEP_MASK;
0143 break;
0144 case kPWM_ComplementaryPwmA:
0145 base->MCTRL &= ~((uint16_t)1U << (PWM_MCTRL_IPOL_SHIFT + (uint16_t)subModule));
0146 break;
0147 case kPWM_ComplementaryPwmB:
0148 base->MCTRL |= ((uint16_t)1U << (PWM_MCTRL_IPOL_SHIFT + (uint16_t)subModule));
0149 break;
0150 default:
0151 assert(false);
0152 break;
0153 }
0154 base->SM[subModule].CTRL2 = reg;
0155
0156 reg = base->SM[subModule].CTRL;
0157
0158
0159 reg &= ~(uint16_t)(PWM_CTRL_PRSC_MASK | PWM_CTRL_LDFQ_MASK | PWM_CTRL_LDMOD_MASK);
0160 reg |= (PWM_CTRL_PRSC(config->prescale) | PWM_CTRL_LDFQ(config->reloadFrequency));
0161
0162
0163 switch (config->reloadLogic)
0164 {
0165 case kPWM_ReloadImmediate:
0166 reg |= PWM_CTRL_LDMOD_MASK;
0167 break;
0168 case kPWM_ReloadPwmHalfCycle:
0169 reg |= PWM_CTRL_HALF_MASK;
0170 reg &= (uint16_t)(~PWM_CTRL_FULL_MASK);
0171 break;
0172 case kPWM_ReloadPwmFullCycle:
0173 reg &= (uint16_t)(~PWM_CTRL_HALF_MASK);
0174 reg |= PWM_CTRL_FULL_MASK;
0175 break;
0176 case kPWM_ReloadPwmHalfAndFullCycle:
0177 reg |= PWM_CTRL_HALF_MASK;
0178 reg |= PWM_CTRL_FULL_MASK;
0179 break;
0180 default:
0181 assert(false);
0182 break;
0183 }
0184 base->SM[subModule].CTRL = reg;
0185
0186
0187 base->MASK &= ~(uint16_t)(PWM_MASK_MASKX_MASK | PWM_MASK_MASKA_MASK | PWM_MASK_MASKB_MASK);
0188
0189 base->DTSRCSEL = 0U;
0190
0191
0192 if (config->forceTrigger == kPWM_Force_Local)
0193 {
0194 base->SM[subModule].CTRL2 |= PWM_CTRL2_FORCE(1U);
0195 }
0196
0197 return kStatus_Success;
0198 }
0199
0200
0201
0202
0203
0204
0205
0206 void PWM_Deinit(PWM_Type *base, pwm_submodule_t subModule)
0207 {
0208
0209 base->MCTRL &= ~((uint16_t)1U << (PWM_MCTRL_RUN_SHIFT + (uint16_t)subModule));
0210
0211 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0212
0213 CLOCK_DisableClock(s_pwmClocks[PWM_GetInstance(base)][subModule]);
0214 #endif
0215 }
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 void PWM_GetDefaultConfig(pwm_config_t *config)
0236 {
0237 assert(config);
0238
0239
0240 (void)memset(config, 0, sizeof(*config));
0241
0242
0243 config->enableDebugMode = false;
0244
0245 #if !defined(FSL_FEATURE_PWM_HAS_NO_WAITEN) || (!FSL_FEATURE_PWM_HAS_NO_WAITEN)
0246 config->enableWait = false;
0247 #endif
0248
0249 config->reloadSelect = kPWM_LocalReload;
0250
0251 config->clockSource = kPWM_BusClock;
0252
0253 config->prescale = kPWM_Prescale_Divide_1;
0254
0255 config->initializationControl = kPWM_Initialize_LocalSync;
0256
0257 config->forceTrigger = kPWM_Force_Local;
0258
0259
0260
0261 config->reloadFrequency = kPWM_LoadEveryOportunity;
0262
0263 config->reloadLogic = kPWM_ReloadImmediate;
0264
0265 config->pairOperation = kPWM_Independent;
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 status_t PWM_SetupPwm(PWM_Type *base,
0288 pwm_submodule_t subModule,
0289 const pwm_signal_param_t *chnlParams,
0290 uint8_t numOfChnls,
0291 pwm_mode_t mode,
0292 uint32_t pwmFreq_Hz,
0293 uint32_t srcClock_Hz)
0294 {
0295 assert(chnlParams);
0296 assert(pwmFreq_Hz);
0297 assert(numOfChnls);
0298 assert(srcClock_Hz);
0299
0300 uint32_t pwmClock;
0301 uint16_t pulseCnt = 0, pwmHighPulse = 0;
0302 uint16_t modulo = 0;
0303 uint8_t i, polarityShift = 0, outputEnableShift = 0;
0304
0305 for (i = 0; i < numOfChnls; i++)
0306 {
0307 if (chnlParams[i].pwmChannel == kPWM_PwmX)
0308 {
0309
0310 return kStatus_Fail;
0311 }
0312 }
0313
0314
0315 pwmClock = (srcClock_Hz / (1UL << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT)));
0316 pulseCnt = (uint16_t)(pwmClock / pwmFreq_Hz);
0317
0318
0319 for (i = 0; i < numOfChnls; i++)
0320 {
0321
0322 pwmHighPulse = (pulseCnt * chnlParams->dutyCyclePercent) / 100U;
0323
0324
0325 switch (mode)
0326 {
0327 case kPWM_SignedCenterAligned:
0328
0329 if (i == 0U)
0330 {
0331 modulo = (pulseCnt >> 1U);
0332
0333 base->SM[subModule].INIT = PWM_GetComplementU16(modulo);
0334
0335 base->SM[subModule].VAL0 = 0;
0336
0337
0338 base->SM[subModule].VAL1 = modulo - 1U;
0339 }
0340
0341
0342 if (chnlParams->pwmChannel == kPWM_PwmA)
0343 {
0344 base->SM[subModule].VAL2 = PWM_GetComplementU16(pwmHighPulse / 2U);
0345 base->SM[subModule].VAL3 = (pwmHighPulse / 2U);
0346 }
0347 else
0348 {
0349 base->SM[subModule].VAL4 = PWM_GetComplementU16(pwmHighPulse / 2U);
0350 base->SM[subModule].VAL5 = (pwmHighPulse / 2U);
0351 }
0352 break;
0353 case kPWM_CenterAligned:
0354
0355
0356 if (i == 0U)
0357 {
0358 base->SM[subModule].INIT = 0;
0359
0360 base->SM[subModule].VAL0 = (pulseCnt / 2U);
0361
0362
0363 base->SM[subModule].VAL1 = pulseCnt - 1U;
0364 }
0365
0366
0367 if (chnlParams->pwmChannel == kPWM_PwmA)
0368 {
0369 base->SM[subModule].VAL2 = ((pulseCnt - pwmHighPulse) / 2U);
0370 base->SM[subModule].VAL3 = ((pulseCnt + pwmHighPulse) / 2U);
0371 }
0372 else
0373 {
0374 base->SM[subModule].VAL4 = ((pulseCnt - pwmHighPulse) / 2U);
0375 base->SM[subModule].VAL5 = ((pulseCnt + pwmHighPulse) / 2U);
0376 }
0377 break;
0378 case kPWM_SignedEdgeAligned:
0379
0380 if (i == 0U)
0381 {
0382 modulo = (pulseCnt >> 1U);
0383
0384 base->SM[subModule].INIT = PWM_GetComplementU16(modulo);
0385
0386 base->SM[subModule].VAL0 = 0;
0387
0388
0389 base->SM[subModule].VAL1 = modulo - 1U;
0390 }
0391
0392
0393 if (chnlParams->pwmChannel == kPWM_PwmA)
0394 {
0395 base->SM[subModule].VAL2 = PWM_GetComplementU16(modulo);
0396 base->SM[subModule].VAL3 = PWM_GetComplementU16(modulo) + pwmHighPulse;
0397 }
0398 else
0399 {
0400 base->SM[subModule].VAL4 = PWM_GetComplementU16(modulo);
0401 base->SM[subModule].VAL5 = PWM_GetComplementU16(modulo) + pwmHighPulse;
0402 }
0403 break;
0404 case kPWM_EdgeAligned:
0405
0406
0407 if (i == 0U)
0408 {
0409 base->SM[subModule].INIT = 0;
0410
0411 base->SM[subModule].VAL0 = (pulseCnt / 2U);
0412
0413
0414 base->SM[subModule].VAL1 = pulseCnt - 1U;
0415 }
0416
0417
0418 if (chnlParams->pwmChannel == kPWM_PwmA)
0419 {
0420 base->SM[subModule].VAL2 = 0;
0421 base->SM[subModule].VAL3 = pwmHighPulse;
0422 }
0423 else
0424 {
0425 base->SM[subModule].VAL4 = 0;
0426 base->SM[subModule].VAL5 = pwmHighPulse;
0427 }
0428 break;
0429 default:
0430 assert(false);
0431 break;
0432 }
0433
0434
0435
0436 if (chnlParams->pwmChannel == kPWM_PwmA)
0437 {
0438 polarityShift = PWM_OCTRL_POLA_SHIFT;
0439 outputEnableShift = PWM_OUTEN_PWMA_EN_SHIFT;
0440 base->SM[subModule].DTCNT0 = PWM_DTCNT0_DTCNT0(chnlParams->deadtimeValue);
0441 }
0442 else
0443 {
0444 polarityShift = PWM_OCTRL_POLB_SHIFT;
0445 outputEnableShift = PWM_OUTEN_PWMB_EN_SHIFT;
0446 base->SM[subModule].DTCNT1 = PWM_DTCNT1_DTCNT1(chnlParams->deadtimeValue);
0447 }
0448
0449
0450 switch (chnlParams->pwmChannel)
0451 {
0452 case kPWM_PwmA:
0453 base->SM[subModule].OCTRL &= ~((uint16_t)PWM_OCTRL_PWMAFS_MASK);
0454 base->SM[subModule].OCTRL |= (((uint16_t)(chnlParams->faultState) << (uint16_t)PWM_OCTRL_PWMAFS_SHIFT) &
0455 (uint16_t)PWM_OCTRL_PWMAFS_MASK);
0456 break;
0457 case kPWM_PwmB:
0458 base->SM[subModule].OCTRL &= ~((uint16_t)PWM_OCTRL_PWMBFS_MASK);
0459 base->SM[subModule].OCTRL |= (((uint16_t)(chnlParams->faultState) << (uint16_t)PWM_OCTRL_PWMBFS_SHIFT) &
0460 (uint16_t)PWM_OCTRL_PWMBFS_MASK);
0461 break;
0462 default:
0463 assert(false);
0464 break;
0465 }
0466
0467
0468 if ((bool)chnlParams->level == kPWM_HighTrue)
0469 {
0470 base->SM[subModule].OCTRL &= ~((uint16_t)1U << (uint16_t)polarityShift);
0471 }
0472 else
0473 {
0474 base->SM[subModule].OCTRL |= ((uint16_t)1U << (uint16_t)polarityShift);
0475 }
0476 if (chnlParams->pwmchannelenable)
0477 {
0478
0479 base->OUTEN |= ((uint16_t)1U << ((uint16_t)outputEnableShift + (uint16_t)subModule));
0480 }
0481
0482
0483 s_pwmGetPwmDutyCycle[subModule][chnlParams->pwmChannel] = chnlParams->dutyCyclePercent;
0484
0485
0486 chnlParams++;
0487 }
0488
0489 return kStatus_Success;
0490 }
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506 status_t PWM_SetupPwmPhaseShift(PWM_Type *base,
0507 pwm_submodule_t subModule,
0508 pwm_channels_t pwmChannel,
0509 uint32_t pwmFreq_Hz,
0510 uint32_t srcClock_Hz,
0511 uint8_t shiftvalue,
0512 bool doSync)
0513 {
0514 assert(pwmFreq_Hz != 0U);
0515 assert(srcClock_Hz != 0U);
0516 assert(shiftvalue <= 50U);
0517
0518 uint32_t pwmClock;
0519 uint16_t pulseCnt = 0, pwmHighPulse = 0;
0520 uint16_t modulo = 0;
0521 uint16_t shift = 0;
0522
0523 if (pwmChannel != kPWM_PwmX)
0524 {
0525
0526 pwmClock = (srcClock_Hz / (1UL << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT)));
0527 pulseCnt = (uint16_t)(pwmClock / pwmFreq_Hz);
0528
0529
0530 if (0U != (base->MCTRL & PWM_MCTRL_LDOK(1UL << (uint8_t)subModule)))
0531 {
0532 base->MCTRL |= PWM_MCTRL_CLDOK(1UL << (uint8_t)subModule);
0533 }
0534
0535 modulo = (pulseCnt >> 1U);
0536
0537 base->SM[subModule].INIT = PWM_GetComplementU16(modulo);
0538
0539 base->SM[subModule].VAL0 = 0;
0540
0541
0542 base->SM[subModule].VAL1 = modulo - 1U;
0543
0544
0545 base->SM[subModule].CTRL |= PWM_CTRL_LDMOD_MASK;
0546
0547
0548 shift = (pulseCnt * shiftvalue) / 100U;
0549
0550
0551 pwmHighPulse = pulseCnt / 2U;
0552
0553 if (pwmChannel == kPWM_PwmA)
0554 {
0555 base->SM[subModule].VAL2 = PWM_GetComplementU16(modulo) + shift;
0556 base->SM[subModule].VAL3 = PWM_GetComplementU16(modulo) + pwmHighPulse + shift - 1U;
0557 }
0558 else if (pwmChannel == kPWM_PwmB)
0559 {
0560 base->SM[subModule].VAL4 = PWM_GetComplementU16(modulo) + shift;
0561 base->SM[subModule].VAL5 = PWM_GetComplementU16(modulo) + pwmHighPulse + shift - 1U;
0562 }
0563 else
0564 {
0565 return kStatus_Fail;
0566 }
0567
0568 if (doSync)
0569 {
0570
0571 base->MCTRL |= PWM_MCTRL_LDOK(1UL << (uint8_t)subModule);
0572 }
0573 }
0574 else
0575 {
0576 return kStatus_Fail;
0577 }
0578
0579 return kStatus_Success;
0580 }
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597 void PWM_UpdatePwmDutycycle(PWM_Type *base,
0598 pwm_submodule_t subModule,
0599 pwm_channels_t pwmSignal,
0600 pwm_mode_t currPwmMode,
0601 uint8_t dutyCyclePercent)
0602 {
0603 assert(dutyCyclePercent <= 100U);
0604 assert(pwmSignal != kPWM_PwmX);
0605 uint16_t reloadValue = dutyCycleToReloadValue(dutyCyclePercent);
0606
0607 PWM_UpdatePwmDutycycleHighAccuracy(base, subModule, pwmSignal, currPwmMode, reloadValue);
0608 }
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625 void PWM_UpdatePwmDutycycleHighAccuracy(
0626 PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmSignal, pwm_mode_t currPwmMode, uint16_t dutyCycle)
0627 {
0628 assert(pwmSignal != kPWM_PwmX);
0629 uint16_t pulseCnt = 0, pwmHighPulse = 0;
0630 uint16_t modulo = 0;
0631
0632 switch (currPwmMode)
0633 {
0634 case kPWM_SignedCenterAligned:
0635 modulo = base->SM[subModule].VAL1 + 1U;
0636 pulseCnt = modulo * 2U;
0637
0638 pwmHighPulse = (pulseCnt * dutyCycle) / 65535U;
0639
0640
0641 if (pwmSignal == kPWM_PwmA)
0642 {
0643 base->SM[subModule].VAL2 = PWM_GetComplementU16(pwmHighPulse / 2U);
0644 base->SM[subModule].VAL3 = (pwmHighPulse / 2U);
0645 }
0646 else if (pwmSignal == kPWM_PwmB)
0647 {
0648 base->SM[subModule].VAL4 = PWM_GetComplementU16(pwmHighPulse / 2U);
0649 base->SM[subModule].VAL5 = (pwmHighPulse / 2U);
0650 }
0651 else
0652 {
0653 assert(false);
0654 }
0655 break;
0656 case kPWM_CenterAligned:
0657 pulseCnt = base->SM[subModule].VAL1 + 1U;
0658
0659 pwmHighPulse = (pulseCnt * dutyCycle) / 65535U;
0660
0661
0662 if (pwmSignal == kPWM_PwmA)
0663 {
0664 base->SM[subModule].VAL2 = ((pulseCnt - pwmHighPulse) / 2U);
0665 base->SM[subModule].VAL3 = ((pulseCnt + pwmHighPulse) / 2U);
0666 }
0667 else if (pwmSignal == kPWM_PwmB)
0668 {
0669 base->SM[subModule].VAL4 = ((pulseCnt - pwmHighPulse) / 2U);
0670 base->SM[subModule].VAL5 = ((pulseCnt + pwmHighPulse) / 2U);
0671 }
0672 else
0673 {
0674 assert(false);
0675 }
0676 break;
0677 case kPWM_SignedEdgeAligned:
0678 modulo = base->SM[subModule].VAL1 + 1U;
0679 pulseCnt = modulo * 2U;
0680
0681 pwmHighPulse = (pulseCnt * dutyCycle) / 65535U;
0682
0683
0684 if (pwmSignal == kPWM_PwmA)
0685 {
0686 base->SM[subModule].VAL2 = PWM_GetComplementU16(modulo);
0687 base->SM[subModule].VAL3 = PWM_GetComplementU16(modulo) + pwmHighPulse;
0688 }
0689 else if (pwmSignal == kPWM_PwmB)
0690 {
0691 base->SM[subModule].VAL4 = PWM_GetComplementU16(modulo);
0692 base->SM[subModule].VAL5 = PWM_GetComplementU16(modulo) + pwmHighPulse;
0693 }
0694 else
0695 {
0696 assert(false);
0697 }
0698 break;
0699 case kPWM_EdgeAligned:
0700 pulseCnt = base->SM[subModule].VAL1 + 1U;
0701
0702 pwmHighPulse = (pulseCnt * dutyCycle) / 65535U;
0703
0704
0705 if (pwmSignal == kPWM_PwmA)
0706 {
0707 base->SM[subModule].VAL2 = 0;
0708 base->SM[subModule].VAL3 = pwmHighPulse;
0709 }
0710 else if (pwmSignal == kPWM_PwmB)
0711 {
0712 base->SM[subModule].VAL4 = 0;
0713 base->SM[subModule].VAL5 = pwmHighPulse;
0714 }
0715 else
0716 {
0717 assert(false);
0718 }
0719 break;
0720 default:
0721 assert(false);
0722 break;
0723 }
0724 if (kPWM_PwmX != pwmSignal)
0725 {
0726
0727 s_pwmGetPwmDutyCycle[subModule][pwmSignal] = (uint8_t)(dutyCycle / 65535U);
0728 }
0729 }
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742 void PWM_SetupInputCapture(PWM_Type *base,
0743 pwm_submodule_t subModule,
0744 pwm_channels_t pwmChannel,
0745 const pwm_input_capture_param_t *inputCaptureParams)
0746 {
0747 uint16_t reg = 0;
0748 switch (pwmChannel)
0749 {
0750 case kPWM_PwmA:
0751
0752 reg = (PWM_CAPTCTRLA_INP_SELA(inputCaptureParams->captureInputSel) |
0753 PWM_CAPTCTRLA_EDGA0(inputCaptureParams->edge0) | PWM_CAPTCTRLA_EDGA1(inputCaptureParams->edge1) |
0754 PWM_CAPTCTRLA_ONESHOTA(inputCaptureParams->enableOneShotCapture) |
0755 PWM_CAPTCTRLA_CFAWM(inputCaptureParams->fifoWatermark));
0756
0757 if (inputCaptureParams->captureInputSel)
0758 {
0759 reg |= PWM_CAPTCTRLA_EDGCNTA_EN_MASK;
0760 }
0761
0762 reg |= PWM_CAPTCTRLA_ARMA_MASK;
0763
0764 base->SM[subModule].CAPTCTRLA = reg;
0765
0766
0767 base->SM[subModule].CAPTCOMPA = PWM_CAPTCOMPA_EDGCMPA(inputCaptureParams->edgeCompareValue);
0768
0769 base->OUTEN &= ~((uint16_t)1U << (PWM_OUTEN_PWMA_EN_SHIFT + (uint16_t)subModule));
0770 break;
0771 case kPWM_PwmB:
0772
0773 reg = (PWM_CAPTCTRLB_INP_SELB(inputCaptureParams->captureInputSel) |
0774 PWM_CAPTCTRLB_EDGB0(inputCaptureParams->edge0) | PWM_CAPTCTRLB_EDGB1(inputCaptureParams->edge1) |
0775 PWM_CAPTCTRLB_ONESHOTB(inputCaptureParams->enableOneShotCapture) |
0776 PWM_CAPTCTRLB_CFBWM(inputCaptureParams->fifoWatermark));
0777
0778 if (inputCaptureParams->captureInputSel)
0779 {
0780 reg |= PWM_CAPTCTRLB_EDGCNTB_EN_MASK;
0781 }
0782
0783 reg |= PWM_CAPTCTRLB_ARMB_MASK;
0784
0785 base->SM[subModule].CAPTCTRLB = reg;
0786
0787
0788 base->SM[subModule].CAPTCOMPB = PWM_CAPTCOMPB_EDGCMPB(inputCaptureParams->edgeCompareValue);
0789
0790 base->OUTEN &= ~((uint16_t)1U << (PWM_OUTEN_PWMB_EN_SHIFT + (uint16_t)subModule));
0791 break;
0792 case kPWM_PwmX:
0793 reg = (PWM_CAPTCTRLX_INP_SELX(inputCaptureParams->captureInputSel) |
0794 PWM_CAPTCTRLX_EDGX0(inputCaptureParams->edge0) | PWM_CAPTCTRLX_EDGX1(inputCaptureParams->edge1) |
0795 PWM_CAPTCTRLX_ONESHOTX(inputCaptureParams->enableOneShotCapture) |
0796 PWM_CAPTCTRLX_CFXWM(inputCaptureParams->fifoWatermark));
0797
0798 if (inputCaptureParams->captureInputSel)
0799 {
0800 reg |= PWM_CAPTCTRLX_EDGCNTX_EN_MASK;
0801 }
0802
0803 reg |= PWM_CAPTCTRLX_ARMX_MASK;
0804
0805 base->SM[subModule].CAPTCTRLX = reg;
0806
0807
0808 base->SM[subModule].CAPTCOMPX = PWM_CAPTCOMPX_EDGCMPX(inputCaptureParams->edgeCompareValue);
0809
0810 base->OUTEN &= ~((uint16_t)1U << (PWM_OUTEN_PWMX_EN_SHIFT + (uint16_t)subModule));
0811 break;
0812 default:
0813 assert(false);
0814 break;
0815 }
0816 }
0817
0818
0819
0820
0821
0822
0823
0824 void PWM_SetupFaultInputFilter(PWM_Type *base, const pwm_fault_input_filter_param_t *faultInputFilterParams)
0825 {
0826 assert(NULL != faultInputFilterParams);
0827
0828
0829 if (0U != (base->FFILT & PWM_FFILT_FILT_PER_MASK))
0830 {
0831 base->FFILT &= ~(uint16_t)(PWM_FFILT_FILT_PER_MASK);
0832 }
0833
0834 base->FFILT = (uint16_t)(PWM_FFILT_FILT_PER(faultInputFilterParams->faultFilterPeriod) |
0835 PWM_FFILT_FILT_CNT(faultInputFilterParams->faultFilterCount) |
0836 PWM_FFILT_GSTR(faultInputFilterParams->faultGlitchStretch ? 1U : 0U));
0837 }
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848 void PWM_SetupFaults(PWM_Type *base, pwm_fault_input_t faultNum, const pwm_fault_param_t *faultParams)
0849 {
0850 assert(faultParams);
0851 uint16_t reg;
0852
0853 reg = base->FCTRL;
0854
0855 if (faultParams->faultLevel)
0856 {
0857 reg |= ((uint16_t)1U << (PWM_FCTRL_FLVL_SHIFT + (uint16_t)faultNum));
0858 }
0859 else
0860 {
0861 reg &= ~((uint16_t)1U << (PWM_FCTRL_FLVL_SHIFT + (uint16_t)faultNum));
0862 }
0863
0864 if ((uint16_t)faultParams->faultClearingMode != 0U)
0865 {
0866
0867 reg &= ~((uint16_t)1U << (PWM_FCTRL_FAUTO_SHIFT + (uint16_t)faultNum));
0868 if (faultParams->faultClearingMode == kPWM_ManualSafety)
0869 {
0870
0871 reg |= ((uint16_t)1U << (PWM_FCTRL_FSAFE_SHIFT + (uint16_t)faultNum));
0872 }
0873 else
0874 {
0875
0876 reg &= ~((uint16_t)1U << (PWM_FCTRL_FSAFE_SHIFT + (uint16_t)faultNum));
0877 }
0878 }
0879 else
0880 {
0881
0882 reg |= ((uint16_t)1U << (PWM_FCTRL_FAUTO_SHIFT + (uint16_t)faultNum));
0883 }
0884 base->FCTRL = reg;
0885
0886
0887 if (faultParams->enableCombinationalPath)
0888 {
0889
0890 base->FCTRL2 &= ~((uint16_t)1U << (uint16_t)faultNum);
0891 }
0892 else
0893 {
0894
0895 base->FCTRL2 |= ((uint16_t)1U << (uint16_t)faultNum);
0896 }
0897
0898
0899 reg = base->FSTS;
0900 reg &= ~(((uint16_t)1U << (PWM_FSTS_FFULL_SHIFT + (uint16_t)faultNum)) |
0901 ((uint16_t)1U << (PWM_FSTS_FHALF_SHIFT + (uint16_t)faultNum)));
0902
0903 switch (faultParams->recoverMode)
0904 {
0905 case kPWM_NoRecovery:
0906 break;
0907 case kPWM_RecoverHalfCycle:
0908 reg |= ((uint16_t)1U << (PWM_FSTS_FHALF_SHIFT + (uint16_t)faultNum));
0909 break;
0910 case kPWM_RecoverFullCycle:
0911 reg |= ((uint16_t)1U << (PWM_FSTS_FFULL_SHIFT + (uint16_t)faultNum));
0912 break;
0913 case kPWM_RecoverHalfAndFullCycle:
0914 reg |= ((uint16_t)1U << (PWM_FSTS_FHALF_SHIFT + (uint16_t)faultNum));
0915 reg |= ((uint16_t)1U << (PWM_FSTS_FFULL_SHIFT + (uint16_t)faultNum));
0916 break;
0917 default:
0918 assert(false);
0919 break;
0920 }
0921 base->FSTS = reg;
0922 }
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936 void PWM_FaultDefaultConfig(pwm_fault_param_t *config)
0937 {
0938 assert(config);
0939
0940
0941 (void)memset(config, 0, sizeof(*config));
0942
0943
0944 config->faultClearingMode = kPWM_Automatic;
0945
0946 config->faultLevel = false;
0947
0948 config->enableCombinationalPath = true;
0949
0950 config->recoverMode = kPWM_NoRecovery;
0951 }
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964 void PWM_SetupForceSignal(PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmChannel, pwm_force_signal_t mode)
0965
0966 {
0967 uint16_t shift;
0968 uint16_t reg;
0969
0970
0971 shift = ((uint16_t)subModule * 4U) + ((uint16_t)pwmChannel * 2U);
0972
0973
0974 reg = base->DTSRCSEL;
0975 reg &= ~((uint16_t)0x3U << shift);
0976 reg |= (uint16_t)((uint16_t)mode << shift);
0977 base->DTSRCSEL = reg;
0978 }
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988 void PWM_EnableInterrupts(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask)
0989 {
0990
0991 base->SM[subModule].INTEN |= ((uint16_t)mask & 0xFFFFU);
0992
0993 base->FCTRL |= ((uint16_t)(mask >> 16U) & PWM_FCTRL_FIE_MASK);
0994 }
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004 void PWM_DisableInterrupts(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask)
1005 {
1006 base->SM[subModule].INTEN &= ~((uint16_t)mask & 0xFFFFU);
1007 base->FCTRL &= ~((uint16_t)(mask >> 16U) & PWM_FCTRL_FIE_MASK);
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019 uint32_t PWM_GetEnabledInterrupts(PWM_Type *base, pwm_submodule_t subModule)
1020 {
1021 uint32_t enabledInterrupts;
1022
1023 enabledInterrupts = base->SM[subModule].INTEN;
1024 enabledInterrupts |= (((uint32_t)base->FCTRL & PWM_FCTRL_FIE_MASK) << 16UL);
1025 return enabledInterrupts;
1026 }
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037 uint32_t PWM_GetStatusFlags(PWM_Type *base, pwm_submodule_t subModule)
1038 {
1039 uint32_t statusFlags;
1040
1041 statusFlags = base->SM[subModule].STS;
1042 statusFlags |= (((uint32_t)base->FSTS & PWM_FSTS_FFLAG_MASK) << 16UL);
1043
1044 return statusFlags;
1045 }
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055 void PWM_ClearStatusFlags(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask)
1056 {
1057 uint16_t reg;
1058
1059 base->SM[subModule].STS = ((uint16_t)mask & 0xFFFFU);
1060 reg = base->FSTS;
1061
1062
1063
1064 reg &= ~(uint16_t)(PWM_FSTS_FFLAG_MASK);
1065 reg |= (uint16_t)((mask >> 16U) & PWM_FSTS_FFLAG_MASK);
1066 base->FSTS = reg;
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 status_t PWM_SetOutputToIdle(PWM_Type *base, pwm_channels_t pwmChannel, pwm_submodule_t subModule, bool idleStatus)
1082 {
1083 uint16_t valOn = 0, valOff = 0;
1084 uint16_t ldmod;
1085
1086
1087 if (0U != (base->MCTRL & PWM_MCTRL_LDOK(1UL << (uint8_t)subModule)))
1088 {
1089 base->MCTRL |= PWM_MCTRL_CLDOK(1UL << (uint8_t)subModule);
1090 }
1091
1092 valOff = base->SM[subModule].INIT;
1093 valOn = base->SM[subModule].VAL1 + 0x1U;
1094
1095 if ((valOff + 1U) == valOn)
1096 {
1097 return kStatus_Fail;
1098 }
1099
1100
1101 if (kPWM_PwmA == pwmChannel)
1102 {
1103 if (0U != (base->SM[subModule].OCTRL & PWM_OCTRL_POLA_MASK))
1104 {
1105 if (!idleStatus)
1106 {
1107 valOn = base->SM[subModule].INIT;
1108 valOff = base->SM[subModule].VAL1 + 0x1U;
1109 }
1110 }
1111 else
1112 {
1113 if (idleStatus)
1114 {
1115 valOn = base->SM[subModule].INIT;
1116 valOff = base->SM[subModule].VAL1 + 0x1U;
1117 }
1118 }
1119 base->SM[subModule].VAL2 = valOn;
1120 base->SM[subModule].VAL3 = valOff;
1121 }
1122 else if (kPWM_PwmB == pwmChannel)
1123 {
1124 if (0U != (base->SM[subModule].OCTRL & PWM_OCTRL_POLB_MASK))
1125 {
1126 if (!idleStatus)
1127 {
1128 valOn = base->SM[subModule].INIT;
1129 valOff = base->SM[subModule].VAL1 + 0x1U;
1130 }
1131 }
1132 else
1133 {
1134 if (idleStatus)
1135 {
1136 valOn = base->SM[subModule].INIT;
1137 valOff = base->SM[subModule].VAL1 + 0x1U;
1138 }
1139 }
1140 base->SM[subModule].VAL4 = valOn;
1141 base->SM[subModule].VAL5 = valOff;
1142 }
1143 else
1144 {
1145 return kStatus_Fail;
1146 }
1147
1148
1149 ldmod = base->SM[subModule].CTRL;
1150
1151 base->SM[subModule].CTRL |= PWM_CTRL_LDMOD_MASK;
1152
1153 base->MCTRL |= PWM_MCTRL_LDOK(1UL << (uint8_t)subModule);
1154
1155 base->SM[subModule].CTRL = ldmod;
1156
1157
1158 s_pwmGetPwmDutyCycle[subModule][pwmChannel] = 0x0U;
1159
1160 return kStatus_Success;
1161 }
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172 uint8_t PWM_GetPwmChannelState(PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmChannel)
1173 {
1174 return s_pwmGetPwmDutyCycle[subModule][pwmChannel];
1175 }
1176
1177
1178
1179
1180
1181
1182
1183
1184 void PWM_SetClockMode(PWM_Type *base, pwm_submodule_t subModule, pwm_clock_prescale_t prescaler)
1185 {
1186 uint16_t reg = base->SM[subModule].CTRL;
1187
1188
1189 if (0U != (base->MCTRL & PWM_MCTRL_LDOK(1UL << (uint8_t)subModule)))
1190 {
1191 base->MCTRL |= PWM_MCTRL_CLDOK(1UL << (uint8_t)subModule);
1192 }
1193
1194 reg &= ~(uint16_t)PWM_CTRL_PRSC_MASK;
1195 reg |= PWM_CTRL_PRSC(prescaler);
1196 base->SM[subModule].CTRL = reg;
1197
1198 base->SM[subModule].CTRL |= PWM_CTRL_LDMOD_MASK;
1199
1200 base->MCTRL |= PWM_MCTRL_LDOK(1UL << (uint8_t)subModule);
1201
1202 base->SM[subModule].CTRL = reg;
1203 }
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214 void PWM_SetPwmForceOutputToZero(PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmChannel, bool forcetozero)
1215 {
1216 uint16_t reg = base->SM[subModule].CTRL2;
1217 uint16_t mask;
1218
1219 if (kPWM_PwmA == pwmChannel)
1220 {
1221 mask = PWM_MASK_MASKA(0x01UL << (uint8_t)subModule);
1222 }
1223 else if (kPWM_PwmB == pwmChannel)
1224 {
1225 mask = PWM_MASK_MASKB(0x01UL << (uint8_t)subModule);
1226 }
1227 else
1228 {
1229 mask = PWM_MASK_MASKX(0x01UL << (uint8_t)subModule);
1230 }
1231
1232 if (forcetozero)
1233 {
1234
1235 base->MASK |= mask;
1236 }
1237 else
1238 {
1239
1240 base->MASK &= ~mask;
1241 }
1242
1243
1244 base->SM[subModule].CTRL2 &= ~(uint16_t)PWM_CTRL2_FORCE_SEL_MASK;
1245
1246 base->SM[subModule].CTRL2 |= PWM_CTRL2_FORCE_MASK;
1247
1248 base->SM[subModule].CTRL2 = reg;
1249 }
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 void PWM_SetChannelOutput(PWM_Type *base,
1260 pwm_submodule_t subModule,
1261 pwm_channels_t pwmChannel,
1262 pwm_output_state_t outputstate)
1263 {
1264 uint16_t mask, swcout, sourceShift;
1265 uint16_t reg = base->SM[subModule].CTRL2;
1266
1267 if (kPWM_PwmA == pwmChannel)
1268 {
1269 mask = PWM_MASK_MASKA(0x01UL << (uint8_t)subModule);
1270 swcout = (uint16_t)PWM_SWCOUT_SM0OUT23_MASK << ((uint8_t)subModule * 2U);
1271 sourceShift = PWM_DTSRCSEL_SM0SEL23_SHIFT + ((uint16_t)subModule * 4U);
1272 }
1273 else if (kPWM_PwmB == pwmChannel)
1274 {
1275 mask = PWM_MASK_MASKB(0x01UL << (uint8_t)subModule);
1276 swcout = (uint16_t)PWM_SWCOUT_SM0OUT45_MASK << ((uint8_t)subModule * 2U);
1277 sourceShift = PWM_DTSRCSEL_SM0SEL45_SHIFT + ((uint16_t)subModule * 4U);
1278 }
1279 else
1280 {
1281 mask = PWM_MASK_MASKX(0x01UL << (uint8_t)subModule);
1282 swcout = 0U;
1283 sourceShift = 0U;
1284 }
1285
1286 if (kPWM_MaskState == outputstate)
1287 {
1288
1289 base->MASK |= mask;
1290 }
1291 else
1292 {
1293
1294 base->MASK &= ~mask;
1295
1296 if (kPWM_PwmX != pwmChannel)
1297 {
1298 if (kPWM_HighState == outputstate)
1299 {
1300 base->SWCOUT |= swcout;
1301 base->DTSRCSEL =
1302 (base->DTSRCSEL & ~(uint16_t)(0x3UL << sourceShift)) | (uint16_t)(0x2UL << sourceShift);
1303 }
1304 else if (kPWM_LowState == outputstate)
1305 {
1306 base->SWCOUT &= ~swcout;
1307 base->DTSRCSEL =
1308 (base->DTSRCSEL & ~(uint16_t)(0x3UL << sourceShift)) | (uint16_t)(0x2UL << sourceShift);
1309 }
1310 else if (kPWM_NormalState == outputstate)
1311 {
1312 base->DTSRCSEL &= ~(uint16_t)(0x3UL << sourceShift);
1313 }
1314 else
1315 {
1316 base->DTSRCSEL =
1317 (base->DTSRCSEL & ~(uint16_t)(0x3UL << sourceShift)) | (uint16_t)(0x1UL << sourceShift);
1318 }
1319 }
1320 }
1321
1322
1323 base->SM[subModule].CTRL2 &= ~(uint16_t)PWM_CTRL2_FORCE_SEL_MASK;
1324
1325 base->SM[subModule].CTRL2 |= PWM_CTRL2_FORCE_MASK;
1326
1327 base->SM[subModule].CTRL2 = reg;
1328 }