FastPWM clone

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?

UserRevisionLine numberNew 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