FASTPWM

Dependents:   OV7670_make

Committer:
Sissors
Date:
Thu Apr 16 19:23:53 2015 +0000
Revision:
22:db9c0cf445e2
Parent:
17:8378bc456f0d
Child:
24:1f451660d8c0
Fixed a bug for STM targets. The mbed library did not enable syncing of the period register, resulting in sometimes a smaller period being set than the current timer value -> it would first need to overflow before it worked properly. Which takes long o...

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 13:cdefd9d75b64 1 //This should (hopefully) work on all STM targets which use TIM timers for PWM
Sissors 13:cdefd9d75b64 2
Sissors 13:cdefd9d75b64 3 #ifdef TARGET_STM
Sissors 13:cdefd9d75b64 4
Sissors 13:cdefd9d75b64 5 #include "FastPWM.h"
Sissors 13:cdefd9d75b64 6
jocis 17:8378bc456f0d 7 #if defined TARGET_NUCLEO_F103RB
jocis 17:8378bc456f0d 8 typedef __IO uint16_t* CHANNEL_P_T;
jocis 17:8378bc456f0d 9 #else
jocis 17:8378bc456f0d 10 typedef __IO uint32_t* CHANNEL_P_T;
jocis 17:8378bc456f0d 11 #endif
jocis 17:8378bc456f0d 12
jocis 17:8378bc456f0d 13 #define PWM_CHANNEL (**(CHANNEL_P_T*)fast_obj)
Sissors 13:cdefd9d75b64 14 #define PWM_TIMER ((TIM_TypeDef*)_pwm.pwm)
Sissors 13:cdefd9d75b64 15
jocis 17:8378bc456f0d 16 extern CHANNEL_P_T getChannel(TIM_TypeDef* pwm, PinName pin);
Sissors 13:cdefd9d75b64 17
Sissors 13:cdefd9d75b64 18 void FastPWM::initFastPWM( void ) {
jocis 17:8378bc456f0d 19 fast_obj = new (CHANNEL_P_T);
jocis 17:8378bc456f0d 20 *(CHANNEL_P_T*)fast_obj = getChannel(PWM_TIMER, _pwm.pin);
jocis 17:8378bc456f0d 21
Sissors 22:db9c0cf445e2 22 //Enable PWM period syncing for glitch free result
Sissors 22:db9c0cf445e2 23 PWM_TIMER->CR1 |= TIM_CR1_ARPE;
Sissors 22:db9c0cf445e2 24
Sissors 13:cdefd9d75b64 25 bits = 16;
Sissors 13:cdefd9d75b64 26 }
Sissors 13:cdefd9d75b64 27
Sissors 13:cdefd9d75b64 28 void FastPWM::pulsewidth_ticks( uint32_t ticks ) {
Sissors 13:cdefd9d75b64 29 PWM_CHANNEL = ticks;
Sissors 13:cdefd9d75b64 30 }
Sissors 13:cdefd9d75b64 31
Sissors 13:cdefd9d75b64 32 void FastPWM::period_ticks( uint32_t ticks ) {
Sissors 13:cdefd9d75b64 33 PWM_TIMER->ARR = ticks - 1;
Sissors 13:cdefd9d75b64 34 }
Sissors 13:cdefd9d75b64 35
Sissors 13:cdefd9d75b64 36 uint32_t FastPWM::getPeriod( void ) {
Sissors 13:cdefd9d75b64 37 return PWM_TIMER->ARR + 1;
Sissors 13:cdefd9d75b64 38 }
Sissors 13:cdefd9d75b64 39
Sissors 13:cdefd9d75b64 40 uint32_t FastPWM::setPrescaler(uint32_t reqScale) {
Sissors 13:cdefd9d75b64 41 if (reqScale == 0)
Sissors 13:cdefd9d75b64 42 //Return prescaler
Sissors 13:cdefd9d75b64 43 return PWM_TIMER->PSC + 1;
Sissors 13:cdefd9d75b64 44 if (reqScale > (uint32_t)(1<<16))
Sissors 13:cdefd9d75b64 45 reqScale = 1<<16;
Sissors 13:cdefd9d75b64 46 //Else set prescaler, we have to substract one from reqScale since a 0 in PCVAL is prescaler of 1
Sissors 13:cdefd9d75b64 47 PWM_TIMER->PSC = reqScale - 1;
Sissors 13:cdefd9d75b64 48
Sissors 13:cdefd9d75b64 49 return reqScale;
Sissors 13:cdefd9d75b64 50 }
Sissors 13:cdefd9d75b64 51
Sissors 13:cdefd9d75b64 52 #endif