FastPWM clone

Committer:
blaze
Date:
Wed Oct 30 03:00:00 2019 +0000
Revision:
35:d6c2b73d71f5
Parent:
23:ed690a19dc55
Replace new/delete with malloc/free for void *. Deleting void pointer is undefined behavior in C++.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 23:ed690a19dc55 1 #if defined(TARGET_LPC11UXX) || defined(TARGET_LPC11XX_11CXX)
Sissors 4:a7b9f778c4b4 2
Sissors 4:a7b9f778c4b4 3 #include "FastPWM.h"
Sissors 4:a7b9f778c4b4 4
Sissors 12:4600daab8a83 5 #define PWM_MR (*(((fastpwm_struct*)fast_obj)->MR))
Sissors 12:4600daab8a83 6 #define PWM_TIMER (((fastpwm_struct*)fast_obj)->timer)
Sissors 12:4600daab8a83 7
Sissors 23:ed690a19dc55 8 typedef struct {
Sissors 23:ed690a19dc55 9 uint8_t timer;
Sissors 23:ed690a19dc55 10 uint8_t mr;
Sissors 23:ed690a19dc55 11 } timer_mr;
Sissors 23:ed690a19dc55 12
Sissors 23:ed690a19dc55 13 #ifdef TARGET_LPC11UXX
Sissors 12:4600daab8a83 14 typedef struct {
Sissors 12:4600daab8a83 15 __IO uint32_t *MR;
Sissors 12:4600daab8a83 16 LPC_CTxxBx_Type *timer;
Sissors 12:4600daab8a83 17 } fastpwm_struct;
Sissors 12:4600daab8a83 18
Sissors 4:a7b9f778c4b4 19 static timer_mr pwm_timer_map[11] = {
Sissors 4:a7b9f778c4b4 20 {0, 0}, {0, 1}, {0, 2},
Sissors 4:a7b9f778c4b4 21 {1, 0}, {1, 1},
Sissors 4:a7b9f778c4b4 22 {2, 0}, {2, 1}, {2, 2},
Sissors 4:a7b9f778c4b4 23 {3, 0}, {3, 1}, {3, 2},
Sissors 4:a7b9f778c4b4 24 };
Sissors 23:ed690a19dc55 25
Sissors 4:a7b9f778c4b4 26 static LPC_CTxxBx_Type *Timers[4] = {
Sissors 4:a7b9f778c4b4 27 LPC_CT16B0, LPC_CT16B1,
Sissors 4:a7b9f778c4b4 28 LPC_CT32B0, LPC_CT32B1
Sissors 4:a7b9f778c4b4 29 };
Sissors 23:ed690a19dc55 30 #else //LPC11XX
Sissors 23:ed690a19dc55 31 typedef struct {
Sissors 23:ed690a19dc55 32 __IO uint32_t *MR;
Sissors 23:ed690a19dc55 33 LPC_TMR_TypeDef *timer;
Sissors 23:ed690a19dc55 34 } fastpwm_struct;
Sissors 23:ed690a19dc55 35
Sissors 23:ed690a19dc55 36 static timer_mr pwm_timer_map[5] = {
Sissors 23:ed690a19dc55 37 {0, 0}, /* CT16B0, MR0 */
Sissors 23:ed690a19dc55 38 {0, 1}, /* CT16B0, MR1 */
Sissors 23:ed690a19dc55 39
Sissors 23:ed690a19dc55 40 {1, 0}, /* CT16B1, MR0 */
Sissors 23:ed690a19dc55 41 {1, 1}, /* CT16B1, MR1 */
Sissors 23:ed690a19dc55 42
Sissors 23:ed690a19dc55 43 {2, 2}, /* CT32B0, MR2 */
Sissors 23:ed690a19dc55 44 };
Sissors 23:ed690a19dc55 45
Sissors 23:ed690a19dc55 46 static LPC_TMR_TypeDef *Timers[3] = {
Sissors 23:ed690a19dc55 47 LPC_TMR16B0, LPC_TMR16B1,
Sissors 23:ed690a19dc55 48 LPC_TMR32B0
Sissors 23:ed690a19dc55 49 };
Sissors 23:ed690a19dc55 50 #endif
Sissors 4:a7b9f778c4b4 51
Sissors 4:a7b9f778c4b4 52
Sissors 4:a7b9f778c4b4 53 void FastPWM::initFastPWM( void ) {
blaze 35:d6c2b73d71f5 54 fast_obj = malloc(sizeof(fastpwm_struct));
Sissors 12:4600daab8a83 55 timer_mr tid = pwm_timer_map[_pwm.pwm];
Sissors 12:4600daab8a83 56 PWM_TIMER = Timers[tid.timer];
Sissors 12:4600daab8a83 57 (((fastpwm_struct*)fast_obj)->MR) = &PWM_TIMER->MR[tid.mr];
Sissors 4:a7b9f778c4b4 58
Sissors 4:a7b9f778c4b4 59 if (tid.timer < 2)
Sissors 4:a7b9f778c4b4 60 //16-bit timer
Sissors 4:a7b9f778c4b4 61 bits = 16;
Sissors 4:a7b9f778c4b4 62 else
Sissors 4:a7b9f778c4b4 63 //32-bit timer
Sissors 7:1b5df740bcd7 64 bits = 32;
Sissors 4:a7b9f778c4b4 65 }
Sissors 4:a7b9f778c4b4 66
Sissors 4:a7b9f778c4b4 67 void FastPWM::pulsewidth_ticks( uint32_t ticks ) {
Sissors 7:1b5df740bcd7 68 if (ticks)
Sissors 12:4600daab8a83 69 PWM_MR = PWM_TIMER->MR3 - ticks; //They inverted PWM on the 11u24
Sissors 7:1b5df740bcd7 70 else
Sissors 12:4600daab8a83 71 PWM_MR = 0xFFFFFFFF; //If MR3 = ticks 1 clock cycle wide errors appear, this prevents that (unless MR3 = max).
Sissors 4:a7b9f778c4b4 72 }
Sissors 4:a7b9f778c4b4 73
Sissors 12:4600daab8a83 74 void FastPWM::period_ticks( uint32_t ticks ) {
Sissors 12:4600daab8a83 75 PWM_TIMER->TCR = 0x02;
Sissors 12:4600daab8a83 76 PWM_TIMER->MR3 = ticks;
Sissors 12:4600daab8a83 77 PWM_TIMER->TCR = 0x01;
Sissors 4:a7b9f778c4b4 78 }
Sissors 4:a7b9f778c4b4 79
Sissors 4:a7b9f778c4b4 80 uint32_t FastPWM::getPeriod( void ) {
Sissors 12:4600daab8a83 81 return PWM_TIMER->MR3;
Sissors 4:a7b9f778c4b4 82 }
Sissors 4:a7b9f778c4b4 83
Sissors 4:a7b9f778c4b4 84 uint32_t FastPWM::setPrescaler(uint32_t reqScale) {
Sissors 4:a7b9f778c4b4 85 //If 32-bit, disable auto-scaling, return 1
Sissors 4:a7b9f778c4b4 86 if (bits == 32) {
Sissors 4:a7b9f778c4b4 87 dynamicPrescaler = false;
Sissors 4:a7b9f778c4b4 88 return 1;
Sissors 4:a7b9f778c4b4 89 }
Sissors 4:a7b9f778c4b4 90
Sissors 4:a7b9f778c4b4 91 //Else 16-bit timer:
Sissors 4:a7b9f778c4b4 92 if (reqScale == 0)
Sissors 4:a7b9f778c4b4 93 //Return prescaler
Sissors 12:4600daab8a83 94 return PWM_TIMER->PR + 1;
Sissors 4:a7b9f778c4b4 95 if (reqScale > (uint32_t)(1<<16))
Sissors 4:a7b9f778c4b4 96 reqScale = 1<<16;
Sissors 4:a7b9f778c4b4 97 //Else set prescaler, we have to substract one from reqScale since a 0 in PCVAL is prescaler of 1
Sissors 12:4600daab8a83 98 PWM_TIMER->PR = reqScale - 1;
Sissors 4:a7b9f778c4b4 99
Sissors 4:a7b9f778c4b4 100 return reqScale;
Sissors 4:a7b9f778c4b4 101 }
Sissors 4:a7b9f778c4b4 102
Sissors 4:a7b9f778c4b4 103 #endif