Remove too specific ASSERT.
[bertos.git] / bertos / cpu / arm / drv / pwm_at91.c
index 9bba617d1c8285cb69095e29fe24f1fbd215a7d2..a716a7d43e56a2ed353c712bb30b250a4c45d4a7 100644 (file)
  * \brief PWM hardware-specific implementation
  *
  * \version $Id$
- *
  * \author Daniele Basile <asterix@develer.com>
  */
 
 #include "pwm_at91.h"
-#include "hw_cpu.h"
+#include "hw/pwm_map.h"
+#include <hw/hw_cpufreq.h>
+#include "cfg/cfg_pwm.h"
 
-#include "appconfig.h"
+// Define logging setting (for cfg/log.h module).
+#define LOG_LEVEL         PWM_LOG_LEVEL
+#define LOG_FORMAT        PWM_LOG_FORMAT
+#include <cfg/log.h>
 
 #include <cfg/macros.h>
 #include <cfg/debug.h>
@@ -58,6 +62,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,
@@ -66,6 +71,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,
@@ -74,6 +80,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,
@@ -82,6 +89,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,
@@ -112,8 +120,8 @@ 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);
+               period = CPU_FREQ / (BV(i) * freq);
+//             LOG_INFO("period[%ld], prescale[%d]\n", period, i);
                if ((period < PWM_HW_MAX_PERIOD) && (period != 0))
                {
                        //Clean previous channel prescaler, and set new
@@ -125,9 +133,7 @@ void pwm_hw_setFrequency(PwmDev dev, uint32_t freq)
                }
        }
 
-       PWM_ENA = BV(dev);
-
-//     TRACEMSG("PWM ch[%d] period[%d]", dev, period);
+       LOG_INFO("PWM ch[%d] period[%ld]\n", dev, period);
 }
 
 /**
@@ -151,13 +157,24 @@ 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;
+                               LOG_INFO("Inverted duty[%d], pol[%d]\n", 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;
        }
 
-//     TRACEMSG("PWM ch[%d] duty[%d], period[%ld]", dev, duty, *pwm_map[dev].period_reg);
+       PWM_ENA = BV(dev);
+
+       LOG_INFO("PWM ch[%d] duty[%d], period[%ld]\n", dev, duty, *pwm_map[dev].period_reg);
 }
 
 
@@ -178,6 +195,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;
+               LOG_INFO("Set pol[%d]\n", pwm_map[dev].pol);
+}
 
 /**
  * Init pwm.
@@ -208,10 +233,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);
+       }
+
 }