yes
Device/FastPWM_KSDK.cpp@0:c60399891edd, 2022-05-08 (annotated)
- Committer:
- braichi13
- Date:
- Sun May 08 14:39:57 2022 +0000
- Revision:
- 0:c60399891edd
Yes
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
braichi13 | 0:c60399891edd | 1 | #if defined(TARGET_KPSDK_MCUS) |
braichi13 | 0:c60399891edd | 2 | |
braichi13 | 0:c60399891edd | 3 | #include "FastPWM.h" |
braichi13 | 0:c60399891edd | 4 | #include "fsl_ftm.h" |
braichi13 | 0:c60399891edd | 5 | |
braichi13 | 0:c60399891edd | 6 | |
braichi13 | 0:c60399891edd | 7 | #define PWM_CNV (*(((fastpwm_struct*)fast_obj)->CnV)) |
braichi13 | 0:c60399891edd | 8 | #define PWM_MOD (*(((fastpwm_struct*)fast_obj)->MOD)) |
braichi13 | 0:c60399891edd | 9 | #define PWM_SC (*(((fastpwm_struct*)fast_obj)->SC)) |
braichi13 | 0:c60399891edd | 10 | #define PWM_SYNC (*(((fastpwm_struct*)fast_obj)->SYNC)) |
braichi13 | 0:c60399891edd | 11 | |
braichi13 | 0:c60399891edd | 12 | typedef struct { |
braichi13 | 0:c60399891edd | 13 | __IO uint32_t *CnV; |
braichi13 | 0:c60399891edd | 14 | __IO uint32_t *MOD; |
braichi13 | 0:c60399891edd | 15 | __IO uint32_t *SC; |
braichi13 | 0:c60399891edd | 16 | __IO uint32_t *SYNC; |
braichi13 | 0:c60399891edd | 17 | } fastpwm_struct; |
braichi13 | 0:c60399891edd | 18 | |
braichi13 | 0:c60399891edd | 19 | static uint32_t pwm_prescaler; |
braichi13 | 0:c60399891edd | 20 | static FTM_Type *const ftm_addrs[] = FTM_BASE_PTRS; |
braichi13 | 0:c60399891edd | 21 | |
braichi13 | 0:c60399891edd | 22 | void FastPWM::initFastPWM( void ) { |
braichi13 | 0:c60399891edd | 23 | fast_obj = new fastpwm_struct; |
braichi13 | 0:c60399891edd | 24 | bits = 16; |
braichi13 | 0:c60399891edd | 25 | |
braichi13 | 0:c60399891edd | 26 | pwm_prescaler = SystemCoreClock / CLOCK_GetFreq(kCLOCK_BusClk);; |
braichi13 | 0:c60399891edd | 27 | |
braichi13 | 0:c60399891edd | 28 | unsigned int ch_n = (_pwm.pwm_name & 0xF); |
braichi13 | 0:c60399891edd | 29 | FTM_Type *ftm = ftm_addrs[_pwm.pwm_name >> TPM_SHIFT]; |
braichi13 | 0:c60399891edd | 30 | |
braichi13 | 0:c60399891edd | 31 | ((fastpwm_struct*)fast_obj)->CnV = &ftm->CONTROLS[ch_n].CnV; |
braichi13 | 0:c60399891edd | 32 | ((fastpwm_struct*)fast_obj)->MOD = &ftm->MOD; |
braichi13 | 0:c60399891edd | 33 | ((fastpwm_struct*)fast_obj)->SC = &ftm->SC; |
braichi13 | 0:c60399891edd | 34 | ((fastpwm_struct*)fast_obj)->SYNC = &ftm->SYNC; |
braichi13 | 0:c60399891edd | 35 | |
braichi13 | 0:c60399891edd | 36 | //Do not clear counter when writing new value, set end of period as loading value |
braichi13 | 0:c60399891edd | 37 | ftm->SYNCONF &= ~FTM_SYNCONF_SWRSTCNT_MASK; |
braichi13 | 0:c60399891edd | 38 | ftm->SYNC |= FTM_SYNC_CNTMAX_MASK; |
braichi13 | 0:c60399891edd | 39 | } |
braichi13 | 0:c60399891edd | 40 | |
braichi13 | 0:c60399891edd | 41 | void FastPWM::pulsewidth_ticks( uint32_t ticks ) { |
braichi13 | 0:c60399891edd | 42 | PWM_CNV = ticks; |
braichi13 | 0:c60399891edd | 43 | PWM_SYNC |= FTM_SYNC_SWSYNC_MASK; |
braichi13 | 0:c60399891edd | 44 | } |
braichi13 | 0:c60399891edd | 45 | |
braichi13 | 0:c60399891edd | 46 | void FastPWM::period_ticks( uint32_t ticks ) { |
braichi13 | 0:c60399891edd | 47 | PWM_MOD = ticks - 1; |
braichi13 | 0:c60399891edd | 48 | PWM_SYNC |= FTM_SYNC_SWSYNC_MASK; |
braichi13 | 0:c60399891edd | 49 | } |
braichi13 | 0:c60399891edd | 50 | |
braichi13 | 0:c60399891edd | 51 | uint32_t FastPWM::getPeriod( void ) { |
braichi13 | 0:c60399891edd | 52 | return PWM_MOD + 1; |
braichi13 | 0:c60399891edd | 53 | } |
braichi13 | 0:c60399891edd | 54 | |
braichi13 | 0:c60399891edd | 55 | uint32_t FastPWM::setPrescaler(uint32_t reqScale) { |
braichi13 | 0:c60399891edd | 56 | |
braichi13 | 0:c60399891edd | 57 | uint32_t prescalers[] = {1, 2, 4, 8, 16, 32, 64, 128}; |
braichi13 | 0:c60399891edd | 58 | |
braichi13 | 0:c60399891edd | 59 | for (int i = 0; i<8; i++) |
braichi13 | 0:c60399891edd | 60 | prescalers[i] = prescalers[i] * pwm_prescaler; |
braichi13 | 0:c60399891edd | 61 | |
braichi13 | 0:c60399891edd | 62 | //If prescaler is 0, return current one |
braichi13 | 0:c60399891edd | 63 | if (reqScale == 0) |
braichi13 | 0:c60399891edd | 64 | return (prescalers[(PWM_SC) & 0x07]); |
braichi13 | 0:c60399891edd | 65 | |
braichi13 | 0:c60399891edd | 66 | uint32_t retval = 0; |
braichi13 | 0:c60399891edd | 67 | char bin; |
braichi13 | 0:c60399891edd | 68 | |
braichi13 | 0:c60399891edd | 69 | for (bin = 0; bin<8; bin++) { |
braichi13 | 0:c60399891edd | 70 | retval = prescalers[bin]; |
braichi13 | 0:c60399891edd | 71 | if (retval >= reqScale) |
braichi13 | 0:c60399891edd | 72 | break; |
braichi13 | 0:c60399891edd | 73 | } |
braichi13 | 0:c60399891edd | 74 | if (bin == 8) |
braichi13 | 0:c60399891edd | 75 | bin = 7; |
braichi13 | 0:c60399891edd | 76 | |
braichi13 | 0:c60399891edd | 77 | //Clear lower 5 bits, write new value: |
braichi13 | 0:c60399891edd | 78 | char clockbits = PWM_SC & (3<<3); |
braichi13 | 0:c60399891edd | 79 | |
braichi13 | 0:c60399891edd | 80 | //For some reason clearing them takes some effort |
braichi13 | 0:c60399891edd | 81 | while ((PWM_SC & 0x1F) != 0) |
braichi13 | 0:c60399891edd | 82 | PWM_SC &= ~0x1F; |
braichi13 | 0:c60399891edd | 83 | |
braichi13 | 0:c60399891edd | 84 | |
braichi13 | 0:c60399891edd | 85 | PWM_SC = bin + clockbits; |
braichi13 | 0:c60399891edd | 86 | return retval; |
braichi13 | 0:c60399891edd | 87 | } |
braichi13 | 0:c60399891edd | 88 | #endif |