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