Potmeter FastPWM.h

Dependencies:   mbed

Committer:
vd
Date:
Tue Sep 19 16:52:01 2017 +0000
Revision:
0:16be67f4d9ac
Potmeter FastPWM.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vd 0:16be67f4d9ac 1 //This should (hopefully) work on all STM targets which use TIM timers for PWM
vd 0:16be67f4d9ac 2
vd 0:16be67f4d9ac 3 #ifdef TARGET_STM
vd 0:16be67f4d9ac 4
vd 0:16be67f4d9ac 5 #include "FastPWM.h"
vd 0:16be67f4d9ac 6
vd 0:16be67f4d9ac 7 typedef __IO uint32_t* CHANNEL_P_T;
vd 0:16be67f4d9ac 8
vd 0:16be67f4d9ac 9 typedef struct {
vd 0:16be67f4d9ac 10 CHANNEL_P_T channel;
vd 0:16be67f4d9ac 11 uint32_t clk_prescaler;
vd 0:16be67f4d9ac 12 } fastpwm_struct;
vd 0:16be67f4d9ac 13
vd 0:16be67f4d9ac 14 #define PWM_CHANNEL ((((fastpwm_struct*)fast_obj)->channel))
vd 0:16be67f4d9ac 15 #define PWM_CLK_PRESCALER ((((fastpwm_struct*)fast_obj)->clk_prescaler))
vd 0:16be67f4d9ac 16 #define PWM_TIMER ((TIM_TypeDef*)_pwm.pwm)
vd 0:16be67f4d9ac 17
vd 0:16be67f4d9ac 18 #if defined(TARGET_STM32F0) || defined (TARGET_STM32F1) || defined (TARGET_STM32L1)
vd 0:16be67f4d9ac 19 extern __IO uint32_t* getChannel(TIM_TypeDef* pwm, PinName pin);
vd 0:16be67f4d9ac 20 #endif
vd 0:16be67f4d9ac 21
vd 0:16be67f4d9ac 22 void FastPWM::initFastPWM( void ) {
vd 0:16be67f4d9ac 23 fast_obj = new fastpwm_struct;
vd 0:16be67f4d9ac 24 #if defined(TARGET_STM32F0) || defined (TARGET_STM32F1) || defined (TARGET_STM32L1)
vd 0:16be67f4d9ac 25 PWM_CHANNEL = getChannel(PWM_TIMER, _pwm.pin);
vd 0:16be67f4d9ac 26 #else
vd 0:16be67f4d9ac 27 PWM_CHANNEL = (&PWM_TIMER->CCR1 + _pwm.channel - 1);
vd 0:16be67f4d9ac 28 #endif
vd 0:16be67f4d9ac 29
vd 0:16be67f4d9ac 30 // Depending on the timer and the internal bus it is connected to, each STM timer
vd 0:16be67f4d9ac 31 // can have a fixed prescaler from the clock, especially the faster devices.
vd 0:16be67f4d9ac 32 // In order not to have to hardcode this in, we use knowledge that mbed lib sets
vd 0:16be67f4d9ac 33 // default period to 20ms to reverse engineer the prescaler from this.
vd 0:16be67f4d9ac 34 uint32_t current_hz = SystemCoreClock / (PWM_TIMER->PSC + 1) / (PWM_TIMER->ARR+1);
vd 0:16be67f4d9ac 35 PWM_CLK_PRESCALER = (current_hz + 1) / 50; //50Hz is magic number it should be, +1 is to handle possible rounding errors in mbed setup
vd 0:16be67f4d9ac 36
vd 0:16be67f4d9ac 37 //Sanity check in case a target does something different
vd 0:16be67f4d9ac 38 if ( (PWM_CLK_PRESCALER == 0 ) || (PWM_CLK_PRESCALER > 16)) {
vd 0:16be67f4d9ac 39 PWM_CLK_PRESCALER = 1;
vd 0:16be67f4d9ac 40 }
vd 0:16be67f4d9ac 41
vd 0:16be67f4d9ac 42 //Enable PWM period syncing for glitch free result
vd 0:16be67f4d9ac 43 PWM_TIMER->CR1 |= TIM_CR1_ARPE;
vd 0:16be67f4d9ac 44
vd 0:16be67f4d9ac 45 bits = 16;
vd 0:16be67f4d9ac 46 }
vd 0:16be67f4d9ac 47
vd 0:16be67f4d9ac 48 void FastPWM::pulsewidth_ticks( uint32_t ticks ) {
vd 0:16be67f4d9ac 49 *PWM_CHANNEL = ticks;
vd 0:16be67f4d9ac 50 }
vd 0:16be67f4d9ac 51
vd 0:16be67f4d9ac 52 void FastPWM::period_ticks( uint32_t ticks ) {
vd 0:16be67f4d9ac 53 PWM_TIMER->ARR = ticks - 1;
vd 0:16be67f4d9ac 54 }
vd 0:16be67f4d9ac 55
vd 0:16be67f4d9ac 56 uint32_t FastPWM::getPeriod( void ) {
vd 0:16be67f4d9ac 57 return PWM_TIMER->ARR + 1;
vd 0:16be67f4d9ac 58 }
vd 0:16be67f4d9ac 59
vd 0:16be67f4d9ac 60 uint32_t FastPWM::setPrescaler(uint32_t reqScale) {
vd 0:16be67f4d9ac 61 if (reqScale == 0) {
vd 0:16be67f4d9ac 62 //Return prescaler
vd 0:16be67f4d9ac 63 return (PWM_TIMER->PSC + 1) * PWM_CLK_PRESCALER;
vd 0:16be67f4d9ac 64 }
vd 0:16be67f4d9ac 65 if (reqScale > (uint32_t)(PWM_CLK_PRESCALER<<16)) {
vd 0:16be67f4d9ac 66 reqScale = PWM_CLK_PRESCALER<<16;
vd 0:16be67f4d9ac 67 }
vd 0:16be67f4d9ac 68 //Else set prescaler, we have to substract one from reqScale since a 0 in PCVAL is prescaler of 1
vd 0:16be67f4d9ac 69 //Take into account PWM_CLK_PRESCALER, we need to make sure reqScale is always rounded up
vd 0:16be67f4d9ac 70 PWM_TIMER->PSC = (reqScale + PWM_CLK_PRESCALER - 1)/PWM_CLK_PRESCALER - 1;
vd 0:16be67f4d9ac 71
vd 0:16be67f4d9ac 72 return setPrescaler(0);
vd 0:16be67f4d9ac 73 }
vd 0:16be67f4d9ac 74
vd 0:16be67f4d9ac 75 #endif