*/
#include "pwm_at91.h"
+#include "hw/pwm_map.h"
#include "hw/hw_cpu.h"
#include <cfg/macros.h>
{
{//PWM Channel 0
.duty_zero = false,
+ .pol = false,
.pwm_pin = BV(PWM0),
.mode_reg = &PWM_CMR0,
.duty_reg = &PWM_CDTY0,
},
{//PWM Channel 1
.duty_zero = false,
+ .pol = false,
.pwm_pin = BV(PWM1),
.mode_reg = &PWM_CMR1,
.duty_reg = &PWM_CDTY1,
},
{//PWM Channel 2
.duty_zero = false,
+ .pol = false,
.pwm_pin = BV(PWM2),
.mode_reg = &PWM_CMR2,
.duty_reg = &PWM_CDTY2,
},
{//PWM Channel 3
.duty_zero = false,
+ .pol = false,
.pwm_pin = BV(PWM3),
.mode_reg = &PWM_CMR3,
.duty_reg = &PWM_CDTY3,
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
}
}
- PWM_ENA = BV(dev);
-
-// TRACEMSG("PWM ch[%d] period[%d]", dev, period);
+ TRACEMSG("PWM ch[%d] period[%ld]", dev, period);
}
/**
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);
}
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.
/*
* 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);
+ }
+
}
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.
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 */
#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);