|
(I'm quite new to ARM , as I come straight from the AVR). I've been trying for days to set up a timer which should generate a pulse. In my example, the pulse is 230 ticks out of 1920 ticks and I'm setting MCK to 59904000, thus the pulse should be approximately 31200 Hz.
In my program, I have two LEDs blinking in an infinite loop, to make sure the MCU is running.
The first thing I do is to set up my LEDs, then to call setupTimers, before I go into my LED-blink-while-loop.
My code is probably missing something obvious. I've been through the entire chapter 33 in the datasheet; also tried out whatever I could find with Google, but I'm still stuck.
I've chosen timers instead of PWM, as I need to count the pulses I'm creating. Here's what I expect from my code: * Set TIOA1 high for 230 ticks then set TIOA1 low for 1690 ticks : repeat * When reaching n ticks, trigger an interrupt (n is not determined yet) * TC2 should increment its counter when TIOA1 goes high
What happens is: When I measure on TIOA1 I get no change. I've reduced the code here to make it easier t overview (it's also attached).
[code] #define LENGTH 1920 #define PULSE_END 230 #define PULSE_INT (230+96)
void setupTimers() { AT91PS_PIO pPIO; AT91PS_PMC pPMC; AT91PS_AIC pAIC; AT91PS_TCB pTCB; AT91PS_TC pTC1; AT91PS_TC pTC2; AT91PS_SYS pSYS;
pPIO = AT91C_BASE_PIOA; pPMC = AT91C_BASE_PMC; pAIC = AT91C_BASE_AIC; pTCB = AT91C_BASE_TCB; pTC1 = AT91C_BASE_TC1; pTC2 = AT91C_BASE_TC2; pSYS = AT91C_BASE_SYS;
pPMC->PMC_PCER = (1 << AT91C_ID_PIOA); /* enable the clock of the PIO */ pSYS->RSTC_RMR |= 0xA5000001; /* enable user reset */
pPIO->PIO_PER = AT91C_PA15_TIOA1 | AT91C_PA26_TIOA2; /* enable pins for output */ pPIO->PIO_OER = AT91C_PA15_TIOA1 | AT91C_PA26_TIOA2; /* configure as outputs */ pPIO->PIO_PPUDR = AT91C_PA15_TIOA1 | AT91C_PA26_TIOA2; /* disable pull-up resistor for outputs */ pPIO->PIO_SODR = AT91C_PA15_TIOA1 | AT91C_PA26_TIOA2; /* set output pin high */
/* (at this point, it's possible to manually turn on/off PA15 and PA26) */
pPMC->PMC_PCER = (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); /* turn on timer1 and timer2 */
pTCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; /* we will not use external signals */
// Timer 1: register C = length and pulse start (set), register A = pulse end (toggles), register B = interrupt start pTC1->TC_IDR = 0xffffffff; /* disable interrupts */ (void) pTC1->TC_SR; /* clear status bit */ pTC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_LDRA_RISING | AT91C_TC_LDRB_FALLING | AT91C_TC_BURST_NONE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CPCTRG | AT91C_TC_WAVE | AT91C_TC_ACPA_TOGGLE | AT91C_TC_ACPC_SET; pTC1->TC_RC = LENGTH - 1; /* length in timer ticks */ pTC1->TC_RA = PULSE_END; /* end pulse here */ pTC1->TC_RB = PULSE_INT; /* trigger interrupt here */
#if 0 /* set up interrupt (code disabled until pulse works) */ pAIC->AIC_IDCR = (1 << AT91C_ID_TC1); pAIC->AIC_SVR[AT91C_ID_TC1] = (unsigned int)pulse_interrupt; pAIC->AIC_SMR[AT91C_ID_TC1] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL_SENSITIVE | PULSE_INTERRUPT_LEVEL; pAIC->AIC_ICCR = (1 << AT91C_ID_TC1); pAIC->AIC_IECR = (1 << AT91C_ID_TC1);
pTC1->TC_IER = (1 << AT91C_ID_TC1); #endif
pPIO->PIO_ASR = (AT91C_PA15_TIOA1); pPIO->PIO_BSR = 0; pPIO->PIO_PDR = (AT91C_PA15_TIOA1 | 0);
pTC1->TC_CCR = AT91C_TC_CLKEN; /* enable Timer/Counter 1 */
// (Do the same thing with TC2 + AT91C_PA26_TIOA2.)
}
int main() { setupTimers(); while(1) { } return(0); }
[/code]
| Attachments: |
File comment: Complete test-project (for SAM7-P256 + ARM-USB-TINY-H)
TimerTest.zip [36.54 KiB]
Downloaded 51 times
|
|