EmbDev.net

Forum: ARM programming with GCC/GNU tools TC capture problem with AT91SAM7S256


von Chris B. (chris301)


Rate this post
useful
not useful
Hello,

I’m having problems using the TC (Timer Counter) functionality on
AT91SAM7S256. In order to read in a PWM-signal, I want to use the
“capture” function of TC. As input pin, I want to use only TIOA and try
not to use TIOB, as I need this pin for other purposes.

I use the following code for initialisation and for interrupt handling:

Init:
//interrupts
AT91C_BASE_PIOA->PIO_PDR = PWM_input;
AT91C_BASE_PIOA->PIO_BSR = PWM_input;

AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC2);

AT91C_BASE_TCB->TCB_BCR = 0;

AT91C_BASE_TC2->TC_CMR =  AT91C_TC_CLKS_TIMER_DIV3_CLOCK |
AT91C_TC_ETRGEDG_NONE | AT91C_TC_LDRA_RISING | AT91C_TC_LDRB_FALLING;

AT91C_BASE_TC2->TC_RC = 0xFFFF;

//init interrupts: activate interrupt on load RA and RB
AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_TC2);
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC2] = (unsigned long)
interrupt_handler_TC2;
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC2] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL
| AT91C_AIC_PRIOR_LOWEST;
AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_TC2);
AT91C_BASE_TC2->TC_IER = AT91C_TC_LDRAS | AT91C_TC_LDRBS;

//start TC and interrupts
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_TC2);


Interrupt handler:
void interrupt_handler_TC2 (void)
{
  unsigned int TC_status;
  static unsigned int r_a;
  static unsigned int r_b;

  TC_status = AT91C_BASE_TC2->TC_SR;

  if ((TC_status & AT91C_TC_LDRAS) == AT91C_TC_LDRAS )
    r_a = AT91C_BASE_TC2->TC_RA;

  if ((TC_status & AT91C_TC_LDRBS) == AT91C_TC_LDRBS ){
    r_b = AT91C_BASE_TC2->TC_RB;
    PWM_ouput = r_b – r_a;
  }
}

So here’s my problem: first of all, I cannot read out the duty cycle of
my PWM-signal.
I verified with an oscilloscope that the PWM-signal is OK. Next, I found
out that the interrupts for “load ra” and “load rb” fire too often. I
would expect them to appear only at the edges of the PWM-signal, but
these two interrupts are in fact also triggered many many times when the
PWM-signal is on a perfect low-level.
For testing purposes, I set the interrupt to different sources, CPCS
(compare RC) and COVFS (overflow TC counter); both these interrupts
occur only when they should happen, in contradiction to “load ra” and
“load rb”.
Any idea why that happens? If you don’t want to write long answers but
have working code with capture-functions, it would be very helpful if
you could send me the appropriate sections.

Thanks,

chris

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.