From: asterix Date: Thu, 29 May 2008 13:29:27 +0000 (+0000) Subject: Add function to change and manage polarity of pwm wave form. X-Git-Tag: 2.0.0~530 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=6286e79f3da8091ec8da66469488a11035cada11;p=bertos.git Add function to change and manage polarity of pwm wave form. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1404 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/cpu/arm/drv/pwm_at91.c b/bertos/cpu/arm/drv/pwm_at91.c index 01324110..76a53d39 100644 --- a/bertos/cpu/arm/drv/pwm_at91.c +++ b/bertos/cpu/arm/drv/pwm_at91.c @@ -39,6 +39,7 @@ */ #include "pwm_at91.h" +#include "hw/pwm_map.h" #include "hw/hw_cpu.h" #include @@ -56,6 +57,7 @@ static PwmChannel pwm_map[PWM_CNT] = { {//PWM Channel 0 .duty_zero = false, + .pol = false, .pwm_pin = BV(PWM0), .mode_reg = &PWM_CMR0, .duty_reg = &PWM_CDTY0, @@ -64,6 +66,7 @@ static PwmChannel pwm_map[PWM_CNT] = }, {//PWM Channel 1 .duty_zero = false, + .pol = false, .pwm_pin = BV(PWM1), .mode_reg = &PWM_CMR1, .duty_reg = &PWM_CDTY1, @@ -72,6 +75,7 @@ static PwmChannel pwm_map[PWM_CNT] = }, {//PWM Channel 2 .duty_zero = false, + .pol = false, .pwm_pin = BV(PWM2), .mode_reg = &PWM_CMR2, .duty_reg = &PWM_CDTY2, @@ -80,6 +84,7 @@ static PwmChannel pwm_map[PWM_CNT] = }, {//PWM Channel 3 .duty_zero = false, + .pol = false, .pwm_pin = BV(PWM3), .mode_reg = &PWM_CMR3, .duty_reg = &PWM_CDTY3, @@ -111,7 +116,7 @@ void pwm_hw_setFrequency(PwmDev dev, uint32_t freq) for(int i = 0; i <= PWM_HW_MAX_PRESCALER_STEP; i++) { period = CLOCK_FREQ / (BV(i) * freq); -// TRACEMSG("period[%d], prescale[%d]", period, i); +// TRACEMSG("period[%ld], prescale[%d]", period, i); if ((period < PWM_HW_MAX_PERIOD) && (period != 0)) { //Clean previous channel prescaler, and set new @@ -123,9 +128,7 @@ void pwm_hw_setFrequency(PwmDev dev, uint32_t freq) } } - PWM_ENA = BV(dev); - -// TRACEMSG("PWM ch[%d] period[%d]", dev, period); + TRACEMSG("PWM ch[%d] period[%ld]", dev, period); } /** @@ -150,11 +153,23 @@ void pwm_hw_setDutyUnlock(PwmDev dev, uint16_t duty) else { ASSERT(PWM_CCNT0); + /* + * If polarity flag is true we must invert + * PWM polarity. + */ + if (pwm_map[dev].pol) + { + duty = (uint16_t)*pwm_map[dev].period_reg - duty; +// TRACEMSG("Inverted duty[%d], pol[%d]", duty, pwm_map[dev].pol); + } + PWM_PIO_PDR = pwm_map[dev].pwm_pin; *pwm_map[dev].update_reg = duty; pwm_map[dev].duty_zero = false; } + PWM_ENA = BV(dev); + // TRACEMSG("PWM ch[%d] duty[%d], period[%ld]", dev, duty, *pwm_map[dev].period_reg); } @@ -176,6 +191,14 @@ void pwm_hw_disable(PwmDev dev) PWM_PIO_PER = pwm_map[dev].pwm_pin; } +/** + * Set PWM polarity to select pwm channel + */ +void pwm_hw_setPolarity(PwmDev dev, bool pol) +{ + pwm_map[dev].pol = pol; +// TRACEMSG("Set pol[%d]", pwm_map[dev].pol); +} /** * Init pwm. @@ -206,10 +229,14 @@ void pwm_hw_init(void) /* * Set pwm mode: * - set period alidned to left - * - set output waveform to low level + * - set output waveform to start at high level * - allow duty cycle modify at next period event */ for (int ch = 0; ch < PWM_CNT; ch++) + { *pwm_map[ch].mode_reg = 0; + *pwm_map[ch].mode_reg = BV(PWM_CPOL); + } + } diff --git a/bertos/cpu/arm/drv/pwm_at91.h b/bertos/cpu/arm/drv/pwm_at91.h index e86f5235..c8b0fd47 100644 --- a/bertos/cpu/arm/drv/pwm_at91.h +++ b/bertos/cpu/arm/drv/pwm_at91.h @@ -63,6 +63,7 @@ typedef uint16_t pwm_period_t; typedef struct PwmChannel { bool duty_zero; ///< True if duty cyle is zero, false otherwise. + bool pol; ///< PWM polarty flag. int pwm_pin; ///< PWM pin. reg32_t *mode_reg; ///< PWM mode register. reg32_t *duty_reg; ///< PWM duty cycle register. @@ -77,6 +78,7 @@ void pwm_hw_setFrequency(PwmDev dev, uint32_t freq); void pwm_hw_setDutyUnlock(PwmDev dev, uint16_t duty); void pwm_hw_disable(PwmDev dev); void pwm_hw_enable(PwmDev dev); +void pwm_hw_setPolarity(PwmDev dev, bool pol); pwm_period_t pwm_hw_getPeriod(PwmDev dev); #endif /* DRV_ADC_AT91_H */ diff --git a/bertos/drv/pwm.c b/bertos/drv/pwm.c index ef18612e..021d2437 100644 --- a/bertos/drv/pwm.c +++ b/bertos/drv/pwm.c @@ -57,7 +57,7 @@ void pwm_setDuty(PwmDev dev, pwm_duty_t duty) pwm_period_t period = 0; pwm_duty_t real_duty = 0; - duty = MIN(duty, (pwm_duty_t)PWM_MAX_DUTY); + duty = MIN(duty, PWM_MAX_DUTY); period = pwm_hw_getPeriod(dev); diff --git a/bertos/drv/pwm.h b/bertos/drv/pwm.h index f60986eb..db9b3a2c 100644 --- a/bertos/drv/pwm.h +++ b/bertos/drv/pwm.h @@ -42,15 +42,30 @@ #define DRV_PWM_H #include "hw/pwm_map.h" +#include CPU_HEADER(pwm) + #include #define PWM_MAX_DUTY ((pwm_duty_t)0xFFFF) #define PWM_MAX_PERIOD 0xFFFF #define PWM_MAX_PERIOD_LOG2 16 +/** + * PWM type define. + */ typedef uint16_t pwm_duty_t; typedef uint32_t pwm_freq_t; + + +/** + * Set PWM polarity of pwm \p dev. + */ +INLINE void pwm_setPolarity(PwmDev dev, bool pol) +{ + pwm_hw_setPolarity(dev, pol); +} + void pwm_setDuty(PwmDev dev, pwm_duty_t duty); void pwm_setFrequency(PwmDev dev, pwm_freq_t freq); void pwm_enable(PwmDev dev, bool state);