По даташиту вывод PB14 является PWM0 и TIOA1. Хочу сделать так: PWM0 генерит импульсы, а счетчик TC2 их считает, т.е тактовый сигнал для TC2 является TIOA1. На деле получил: PWM0 генерит пачку импульсов, но таймер не запускается. Если таймер тактировать от внутреннего генератора, то все ок. В чем я ошибаюсь? Исходники привожу:
// Обработчик прерывания от таймера2 по сравнению.
void timer2_handler(void)
{
volatile unsigned long dummy;
dummy = AT91C_BASE_TC2->TC_SR;
if(dummy&0x00000004)
{ BASE_PIO_LED->PIO_SODR = LED_B;// мыргаю, что мол закончил.
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;
}
}
static void configure_tc2(void)
{
volatile unsigned long dummy;
/* Enable periph clock for the PIO controller */
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC2);
/* Enable the periph */
/* Disable the clock and the interrupts */
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC2->TC_IDR = 0xFFFFFFFF;
/* Clear status bit */
dummy = AT91C_BASE_TC2->TC_SR;
AT91C_BASE_TCB2->TCB_BMR = 0x00000030;
/* Set the Mode of the Timer Counter */
AT91C_BASE_TC2->TC_CMR = 0x00008007;
AT91C_BASE_TC2->TC_RA = 15;
/* Enable interrupts */
/* Disable the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC2);
/* Save the interrupt handler routine pointer and the interrupt priority */
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned long) timer2_handler;
/* Store the Source Mode Register */
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC2] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;
/* Clear the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC2);
AT91C_BASE_TC2->TC_IER = AT91C_TC_CPAS;
/* Enable the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC2);
/* Clock is started */
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN;
/* Counter is reset and the clock is started */
AT91C_BASE_TC2->TC_CCR = AT91C_TC_SWTRG;
}
void pwmc_handler(void)
{ unsigned int i;
static unsigned int cnt = 0;
i = AT91C_BASE_PWMC->PWMC_ISR;
/* if (BASE_PIO_LED->PIO_ODSR & LED_B) {
BASE_PIO_LED->PIO_CODR = LED_B;
} else {
BASE_PIO_LED->PIO_SODR = LED_B;
}*/
if((++cnt)>=32768){
AT91C_BASE_PWMC->PWMC_IDR = 1;
AT91C_BASE_PWMC->PWMC_DIS = 1;
cnt = 0;
}
}
void configure_pwm(void)
{
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PWMC);
AT91C_BASE_PIOB->PIO_PDR = (1<<14); // config PB14
AT91C_BASE_PIOB->PIO_BSR = (1<<14);
AT91C_BASE_PWMC->PWMC_MR = 0;
AT91C_BASE_PWMC_CH0->PWMC_CMR = 0x00000400;
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 120;
AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 240;
/* Enable interrupts */
/* Disable the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_PWMC);
/* Save the interrupt handler routine pointer and the interrupt priority */
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PWMC] = (unsigned long) pwmc_handler;
/* Store the Source Mode Register */
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PWMC] = 0x00000026;
/* Clear the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_PWMC);
AT91C_BASE_PWMC->PWMC_IER = 1;
/* Enable the interrupt on the interrupt controller */
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_PWMC);
AT91C_BASE_PWMC->PWMC_ENA = 1;
}
int main()
{
/* === LED configuration (PIO in OUTPUT) === */
configure_leds();
configure_tc2();
configure_pwm();
__enable_interrupt();
while(1);
}