Add function to change and manage polarity of pwm wave form.
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Thu, 29 May 2008 13:29:27 +0000 (13:29 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Thu, 29 May 2008 13:29:27 +0000 (13:29 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1404 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/arm/drv/pwm_at91.c
bertos/cpu/arm/drv/pwm_at91.h
bertos/drv/pwm.c
bertos/drv/pwm.h

index 013241103939e0aef1224da4f2736c6f7fcf3ab5..76a53d398482aa88e0a4dee9a57dc7279235d84c 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 #include "pwm_at91.h"
+#include "hw/pwm_map.h"
 #include "hw/hw_cpu.h"
 
 #include <cfg/macros.h>
@@ -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);
+       }
+
 }
 
index e86f523537b15f330d349f7f8d3b11246fb8c4d5..c8b0fd473d7494053e858ca46c66f5d9f061796f 100644 (file)
@@ -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 */
index ef18612e7541d028c5d31da0680b0ca74f2241bd..021d2437c79e4f7f1e9b44cc74f7de1ff628e77a 100644 (file)
@@ -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);
 
index f60986eb374b6a44d0d2c44d1d53f6a4e7db1f42..db9b3a2cae7c2e6137e8a6f05056e33db8d1561c 100644 (file)
 #define DRV_PWM_H
 
 #include "hw/pwm_map.h"
+#include CPU_HEADER(pwm)
+
 #include <cfg/compiler.h>
 
 #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);