pwm_at91.c
Go to the documentation of this file.00001
00041 #include "pwm_at91.h"
00042
00043 #include <hw/hw_cpu.h>
00044
00045 #include <cfg/macros.h>
00046 #include <cfg/debug.h>
00047 #include <io/arm.h>
00048
00049 #include "appconfig.h"
00050
00056 static PwmChannel pwm_map[PWM_CNT] =
00057 {
00058 {
00059 .duty_zero = false,
00060 .pwm_pin = BV(PWM0),
00061 .mode_reg = &PWM_CMR0,
00062 .duty_reg = &PWM_CDTY0,
00063 .period_reg = &PWM_CPRD0,
00064 .update_reg = &PWM_CUPD0,
00065 },
00066 {
00067 .duty_zero = false,
00068 .pwm_pin = BV(PWM1),
00069 .mode_reg = &PWM_CMR1,
00070 .duty_reg = &PWM_CDTY1,
00071 .period_reg = &PWM_CPRD1,
00072 .update_reg = &PWM_CUPD1,
00073 },
00074 {
00075 .duty_zero = false,
00076 .pwm_pin = BV(PWM2),
00077 .mode_reg = &PWM_CMR2,
00078 .duty_reg = &PWM_CDTY2,
00079 .period_reg = &PWM_CPRD2,
00080 .update_reg = &PWM_CUPD2,
00081 },
00082 {
00083 .duty_zero = false,
00084 .pwm_pin = BV(PWM3),
00085 .mode_reg = &PWM_CMR3,
00086 .duty_reg = &PWM_CDTY3,
00087 .period_reg = &PWM_CPRD3,
00088 .update_reg = &PWM_CUPD3,
00089 }
00090 };
00091
00092
00098 pwm_period_t pwm_hw_getPeriod(PwmDev dev)
00099 {
00100 return *pwm_map[dev].period_reg;
00101 }
00102
00108 void pwm_hw_setFrequency(PwmDev dev, uint32_t freq)
00109 {
00110 uint32_t period = 0;
00111
00112 for(int i = 0; i <= PWM_HW_MAX_PRESCALER_STEP; i++)
00113 {
00114 period = CLOCK_FREQ / (BV(i) * freq);
00115
00116 if ((period < PWM_HW_MAX_PERIOD) && (period != 0))
00117 {
00118
00119 *pwm_map[dev].mode_reg &= ~PWM_CPRE_MCK_MASK;
00120 *pwm_map[dev].mode_reg |= i;
00121
00122 *pwm_map[dev].period_reg = period;
00123 break;
00124 }
00125 }
00126
00127 PWM_ENA = BV(dev);
00128
00129
00130 }
00131
00137 void pwm_hw_setDutyUnlock(PwmDev dev, uint16_t duty)
00138 {
00139 ASSERT(duty <= (uint16_t)*pwm_map[dev].period_reg);
00140
00141
00142
00143
00144
00145
00146 if (!duty)
00147 {
00148 PWM_PIO_PER = pwm_map[dev].pwm_pin;
00149 pwm_map[dev].duty_zero = true;
00150 }
00151 else
00152 {
00153 ASSERT(PWM_CCNT0);
00154 PWM_PIO_PDR = pwm_map[dev].pwm_pin;
00155 *pwm_map[dev].update_reg = duty;
00156 pwm_map[dev].duty_zero = false;
00157 }
00158
00159
00160 }
00161
00162
00166 void pwm_hw_enable(PwmDev dev)
00167 {
00168 if (!pwm_map[dev].duty_zero)
00169 PWM_PIO_PDR = pwm_map[dev].pwm_pin;
00170 }
00171
00175 void pwm_hw_disable(PwmDev dev)
00176 {
00177 PWM_PIO_PER = pwm_map[dev].pwm_pin;
00178 }
00179
00180
00184 void pwm_hw_init(void)
00185 {
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 PWM_PIO_CODR = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00197 PWM_PIO_OER = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00198 PWM_PIO_PDR = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00199 PWM_PIO_ABSR = BV(PWM0) | BV(PWM1) | BV(PWM2) | BV(PWM3);
00200 PMC_PCER |= BV(PWMC_ID);
00201
00202
00203 PWM_DIS = 0xFFFFFFFF;
00204
00205 PWM_MR = 0;
00206
00207
00208
00209
00210
00211
00212
00213 for (int ch = 0; ch < PWM_CNT; ch++)
00214 *pwm_map[ch].mode_reg = 0;
00215 }
00216