00001
00040 #include "pwm_at91.h"
00041 #include "hw/pwm_map.h"
00042 #include "hw/hw_cpu.h"
00043 #include "cfg/cfg_pwm.h"
00044
00045
00046 #define LOG_LEVEL PWM_LOG_LEVEL
00047 #define LOG_FORMAT PWM_LOG_FORMAT
00048 #include <cfg/log.h>
00049
00050 #include <cfg/macros.h>
00051 #include <cfg/debug.h>
00052
00053 #include <io/arm.h>
00054
00055
00061 static PwmChannel pwm_map[PWM_CNT] =
00062 {
00063 {
00064 .duty_zero = false,
00065 .pol = false,
00066 .pwm_pin = BV(PWM0),
00067 .mode_reg = &PWM_CMR0,
00068 .duty_reg = &PWM_CDTY0,
00069 .period_reg = &PWM_CPRD0,
00070 .update_reg = &PWM_CUPD0,
00071 },
00072 {
00073 .duty_zero = false,
00074 .pol = false,
00075 .pwm_pin = BV(PWM1),
00076 .mode_reg = &PWM_CMR1,
00077 .duty_reg = &PWM_CDTY1,
00078 .period_reg = &PWM_CPRD1,
00079 .update_reg = &PWM_CUPD1,
00080 },
00081 {
00082 .duty_zero = false,
00083 .pol = false,
00084 .pwm_pin = BV(PWM2),
00085 .mode_reg = &PWM_CMR2,
00086 .duty_reg = &PWM_CDTY2,
00087 .period_reg = &PWM_CPRD2,
00088 .update_reg = &PWM_CUPD2,
00089 },
00090 {
00091 .duty_zero = false,
00092 .pol = false,
00093 .pwm_pin = BV(PWM3),
00094 .mode_reg = &PWM_CMR3,
00095 .duty_reg = &PWM_CDTY3,
00096 .period_reg = &PWM_CPRD3,
00097 .update_reg = &PWM_CUPD3,
00098 }
00099 };
00100
00101
00107 pwm_period_t pwm_hw_getPeriod(PwmDev dev)
00108 {
00109 return *pwm_map[dev].period_reg;
00110 }
00111
00117 void pwm_hw_setFrequency(PwmDev dev, uint32_t freq)
00118 {
00119 uint32_t period = 0;
00120
00121 for(int i = 0; i <= PWM_HW_MAX_PRESCALER_STEP; i++)
00122 {
00123 period = CLOCK_FREQ / (BV(i) * freq);
00124
00125 if ((period < PWM_HW_MAX_PERIOD) && (period != 0))
00126 {
00127
00128 *pwm_map[dev].mode_reg &= ~PWM_CPRE_MCK_MASK;
00129 *pwm_map[dev].mode_reg |= i;
00130
00131 *pwm_map[dev].period_reg = period;
00132 break;
00133 }
00134 }
00135
00136 LOG_INFO("PWM ch[%d] period[%ld]\n", dev, period);
00137 }
00138
00144 void pwm_hw_setDutyUnlock(PwmDev dev, uint16_t duty)
00145 {
00146 ASSERT(duty <= (uint16_t)*pwm_map[dev].period_reg);
00147
00148
00149
00150
00151
00152
00153 if (!duty)
00154 {
00155 PWM_PIO_PER = pwm_map[dev].pwm_pin;
00156 pwm_map[dev].duty_zero = true;
00157 }
00158 else
00159 {
00160 ASSERT(PWM_CCNT0);
00161
00162
00163
00164
00165 if (pwm_map[dev].pol)
00166 {
00167 duty = (uint16_t)*pwm_map[dev].period_reg - duty;
00168 LOG_INFO("Inverted duty[%d], pol[%d]\n", duty, pwm_map[dev].pol);
00169 }
00170
00171 PWM_PIO_PDR = pwm_map[dev].pwm_pin;
00172 *pwm_map[dev].update_reg = duty;
00173 pwm_map[dev].duty_zero = false;
00174 }
00175
00176 PWM_ENA = BV(dev);
00177
00178 LOG_INFO("PWM ch[%d] duty[%d], period[%ld]\n", dev, duty, *pwm_map[dev].period_reg);
00179 }
00180
00181
00185 void pwm_hw_enable(PwmDev dev)
00186 {
00187 if (!pwm_map[dev].duty_zero)
00188 PWM_PIO_PDR = pwm_map[dev].pwm_pin;
00189 }
00190
00194 void pwm_hw_disable(PwmDev dev)
00195 {
00196 PWM_PIO_PER = pwm_map[dev].pwm_pin;
00197 }
00198
00202 void pwm_hw_setPolarity(PwmDev dev, bool pol)
00203 {
00204 pwm_map[dev].pol = pol;
00205 LOG_INFO("Set pol[%d]\n", pwm_map[dev].pol);
00206 }
00207
00211 void pwm_hw_init(void)
00212 {
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 PWM_PIO_CODR = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00224 PWM_PIO_OER = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00225 PWM_PIO_PDR = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00226 PWM_PIO_ABSR = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00227 PMC_PCER |= BV(PWMC_ID);
00228
00229
00230 PWM_DIS = 0xFFFFFFFF;
00231
00232 PWM_MR = 0;
00233
00234
00235
00236
00237
00238
00239
00240 for (int ch = 0; ch < PWM_CNT; ch++)
00241 {
00242 *pwm_map[ch].mode_reg = 0;
00243 *pwm_map[ch].mode_reg = BV(PWM_CPOL);
00244 }
00245
00246 }
00247