mirror of https://github.com/ARMmbed/mbed-os.git
[LPC824] Fixed PwmOut SCT Bugs
* Fixed period & pulse-width off-by-one errors * Fixed 0% and 100% duty cycle outputpull/1585/head
parent
aa4fddcddc
commit
6ab159af26
|
@ -91,6 +91,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm->CTRL &= ~(0x7F << 5);
|
||||
pwm->CTRL |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);
|
||||
|
||||
// Set event number
|
||||
pwm->OUT[sct_n].SET = (1 << ((sct_n * 2) + 0));
|
||||
pwm->OUT[sct_n].CLR = (1 << ((sct_n * 2) + 1));
|
||||
|
||||
|
@ -99,10 +100,6 @@ void pwmout_init(pwmout_t* obj, PinName pin)
|
|||
pwm->EVENT[(sct_n * 2) + 1].CTRL = (1 << 12) | ((sct_n * 2) + 1);
|
||||
pwm->EVENT[(sct_n * 2) + 1].STATE = 0xFFFFFFFF;
|
||||
|
||||
// unhalt the counter:
|
||||
// - clearing bit 2 of the CTRL register
|
||||
pwm->CTRL &= ~(1 << 2);
|
||||
|
||||
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||
pwmout_period_ms(obj, 20);
|
||||
pwmout_write (obj, 0);
|
||||
|
@ -120,16 +117,27 @@ void pwmout_write(pwmout_t* obj, float value)
|
|||
if (value < 0.0f) {
|
||||
value = 0.0;
|
||||
} else if (value > 1.0f) {
|
||||
value = 1.0;
|
||||
value = 1.0f;
|
||||
}
|
||||
uint32_t t_on = (uint32_t)((float)(obj->pwm->MATCHREL[obj->pwm_ch * 2] + 1) * value);
|
||||
if (t_on > 0) {
|
||||
if (value != 1.0f) {
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = t_on - 1;
|
||||
obj->pwm->CTRL &= ~(1 << 2);
|
||||
} else {
|
||||
obj->pwm->CTRL |= (1 << 2) | (1 << 3);
|
||||
obj->pwm->OUTPUT |= (1 << obj->pwm_ch);
|
||||
}
|
||||
} else {
|
||||
obj->pwm->CTRL |= (1 << 2) | (1 << 3);
|
||||
obj->pwm->OUTPUT &= ~(1 << obj->pwm_ch);
|
||||
}
|
||||
uint32_t t_on = (uint32_t)((float)(obj->pwm->MATCHREL[obj->pwm_ch * 2]) * value);
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = t_on;
|
||||
}
|
||||
|
||||
float pwmout_read(pwmout_t* obj)
|
||||
{
|
||||
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0];
|
||||
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1];
|
||||
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] + 1;
|
||||
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] + 1;
|
||||
float v = (float)t_on/(float)t_off;
|
||||
return (v > 1.0f) ? (1.0f) : (v);
|
||||
}
|
||||
|
@ -147,11 +155,17 @@ void pwmout_period_ms(pwmout_t* obj, int ms)
|
|||
// Set the PWM period, keeping the duty cycle the same.
|
||||
void pwmout_period_us(pwmout_t* obj, int us)
|
||||
{
|
||||
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0];
|
||||
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1];
|
||||
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] + 1;
|
||||
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] + 1;
|
||||
float v = (float)t_on/(float)t_off;
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] = (uint32_t)us;
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)((float)us * (float)v);
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] = (uint32_t)us - 1;
|
||||
if (us > 0) {
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)((float)us * (float)v) - 1;
|
||||
obj->pwm->CTRL &= ~(1 << 2);
|
||||
} else {
|
||||
obj->pwm->CTRL |= (1 << 2) | (1 << 3);
|
||||
obj->pwm->OUTPUT &= ~(1 << obj->pwm_ch);
|
||||
}
|
||||
}
|
||||
|
||||
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
|
||||
|
@ -166,7 +180,13 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
|
|||
|
||||
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
|
||||
{
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)us;
|
||||
if (us > 0) {
|
||||
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)us - 1;
|
||||
obj->pwm->CTRL &= ~(1 << 2);
|
||||
} else {
|
||||
obj->pwm->CTRL |= (1 << 2) | (1 << 3);
|
||||
obj->pwm->OUTPUT &= ~(1 << obj->pwm_ch);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue