mbed library sources. Supersedes mbed-src. GR-PEACH runs on RAM.
Fork of mbed-dev by
Revision 81:8b5f63428415, committed 2016-03-04
- Comitter:
- mbed_official
- Date:
- Fri Mar 04 11:30:11 2016 +0000
- Parent:
- 80:bdf1132a57cf
- Child:
- 82:98895dd43cc3
- Commit message:
- Synchronized with git revision 1020d7cb91f47e620cbf53b1c96328824512afc4
Full URL: https://github.com/mbedmicro/mbed/commit/1020d7cb91f47e620cbf53b1c96328824512afc4/
[LPC824] Fixed PwmOut SCT Bugs
Changed in this revision
targets/hal/TARGET_NXP/TARGET_LPC82X/pwmout_api.c | Show annotated file Show diff for this revision Revisions of this file |
--- a/targets/hal/TARGET_NXP/TARGET_LPC82X/pwmout_api.c Wed Mar 02 14:30:11 2016 +0000 +++ b/targets/hal/TARGET_NXP/TARGET_LPC82X/pwmout_api.c Fri Mar 04 11:30:11 2016 +0000 @@ -91,6 +91,7 @@ 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 @@ 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,32 @@ 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]) * value); - obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = t_on; + uint32_t t_on = (uint32_t)((float)(obj->pwm->MATCHREL[obj->pwm_ch * 2] + 1) * value); + if (t_on > 0) { // duty is not 0% + if (value != 1.0f) { // duty is not 100% + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = t_on - 1; + // unhalt the counter + obj->pwm->CTRL &= ~(1 << 2); + } else { // duty is 100% + // halt and clear the counter + obj->pwm->CTRL |= (1 << 2) | (1 << 3); + // output level tied to high + obj->pwm->OUTPUT |= (1 << obj->pwm_ch); + } + } else { // duty is 0% + // halt and clear the counter + obj->pwm->CTRL |= (1 << 2) | (1 << 3); + // output level tied to low + obj->pwm->OUTPUT &= ~(1 << obj->pwm_ch); + } } 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 +160,21 @@ // 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]; + // The period are off by one for MATCHREL, so +1 to get actual value + 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) { // PWM period is not 0 + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)((float)us * (float)v) - 1; + // unhalt the counter + obj->pwm->CTRL &= ~(1 << 2); + } else { // PWM period is 0 + // halt and clear the counter + obj->pwm->CTRL |= (1 << 2) | (1 << 3); + // output level tied to low + obj->pwm->OUTPUT &= ~(1 << obj->pwm_ch); + } } void pwmout_pulsewidth(pwmout_t* obj, float seconds) @@ -166,7 +189,15 @@ void pwmout_pulsewidth_us(pwmout_t* obj, int us) { - obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)us; + if (us > 0) { // PWM peried is not 0 + obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)us - 1; + obj->pwm->CTRL &= ~(1 << 2); + } else { //PWM period is 0 + // halt and clear the counter + obj->pwm->CTRL |= (1 << 2) | (1 << 3); + // output level tied to low + obj->pwm->OUTPUT &= ~(1 << obj->pwm_ch); + } } #endif