//Sets up PWM output //use_accelerator pwm should generally not be turned on un void act_driver_init() { //sets up driver pins if (use_normal_pwm) { PIO_Configure(&pwm0_pin, 1); } else { PIO_Configure(&pwm2_pin, 1); } PIO_Configure(&pwm1_pin, 1); // Enable PWMC peripheral clock AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PWMC; // Power up PWM Controller. if (use_normal_pwm) { AT91C_BASE_PWMC->PWMC_DIS = AT91C_PWMC_CHID0; //disable channel 0 - ACT_DRIVER_CHANNEL_CLOCKWISE } else { AT91C_BASE_PWMC->PWMC_DIS = AT91C_PWMC_CHID2; // disable channel 2 - ACT_DRIVER_ALTERNATE_PWM } AT91C_BASE_PWMC->PWMC_DIS = AT91C_PWMC_CHID1; //disable channel 1 - ACT_DRIVER_CHANNEL_ANTICLOCKWISE AT91C_BASE_PWMC->PWMC_MR = 0; // Clear mode register. if (use_normal_pwm) { AT91C_BASE_PWMC->PWMC_CH[0].PWMC_CMR = 0x00 | AT91C_PWMC_CPOL; // use board frequency and polarity 0. AT91C_BASE_PWMC->PWMC_CH[0].PWMC_CPRDR = FULL_DUTY_PERIOD; //set the period set_pwm_duty_percent(/*channel*/ACT_DRIVER_CHANNEL_CLOCKWISE,0); } else { AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CMR = 0x00 | AT91C_PWMC_CPOL; // MCK and polarity 0. AT91C_BASE_PWMC->PWMC_CH[2].PWMC_CPRDR = FULL_DUTY_PERIOD; //set the period set_pwm_duty_percent(/*channel*/ACT_DRIVER_CHANNEL_ALTERNATE,0); } AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CMR = 0x00 | AT91C_PWMC_CPOL; // MCK and polarity 0. AT91C_BASE_PWMC->PWMC_CH[1].PWMC_CPRDR = FULL_DUTY_PERIOD; //set the period set_pwm_duty_percent(/*channel*/ACT_DRIVER_CHANNEL_ANTICLOCKWISE,0); if (use_normal_pwm) { AT91C_BASE_PWMC->PWMC_ENA = AT91C_PWMC_CHID0; // Enable channel 0. } else { AT91C_BASE_PWMC->PWMC_ENA = AT91C_PWMC_CHID2; // Enable channel 2 } AT91C_BASE_PWMC->PWMC_ENA = AT91C_PWMC_CHID1; // Enable channel 1 }
/* drive the actuator at a percentage duty cycle; use negative numbers for reverse direction The steering actuator overcurrents power supplies at 50% duty cycle, and the brake actuator claimed that it should not be driven over 25% duty cycle in its spec sheet */ void act_driver_drive(int percent) { if (percent > MAX_DUTY_PERCENT) { percent = MAX_DUTY_PERCENT; } if (percent < -MAX_DUTY_PERCENT) { percent = -MAX_DUTY_PERCENT; } if (percent > 0) { if (use_normal_pwm) { set_pwm_duty_percent(ACT_DRIVER_CHANNEL_CLOCKWISE,percent); } else { set_pwm_duty_percent(ACT_DRIVER_CHANNEL_ALTERNATE,percent); } set_pwm_duty_percent(ACT_DRIVER_CHANNEL_ANTICLOCKWISE,0); } else { if (use_normal_pwm) { set_pwm_duty_percent(ACT_DRIVER_CHANNEL_CLOCKWISE,0); } else { set_pwm_duty_percent(ACT_DRIVER_CHANNEL_ALTERNATE,0); } set_pwm_duty_percent(ACT_DRIVER_CHANNEL_ANTICLOCKWISE,-percent); } /* Mat 21/07/2012 - need to somehow make pwm a hard 0 when percent is set to 0. might be best to disable, and renable once it's non-zero or could alternately try pulling both channels high instead of pulling them both low */ }