0

first code:

//------------------------------------------------------------------------------
/// Interrupt handlers for TC interrupts. Toggles the state of LEDs
//------------------------------------------------------------------------------
char token = 0;
void TC0_IrqHandler(void) {
    volatile unsigned int dummy;
    dummy = AT91C_BASE_TC0->TC_SR;  
    if(token == 1) {
        PIO_Clear(&leds[0]);
        PIO_Set(&leds[1]);
        token = 0;
        }
    else {
        PIO_Set(&leds[0]);
        PIO_Clear(&leds[1]);
        token = 1;
        }
    }
//------------------------------------------------------------------------------
/// Configure Timer Counter 0 to generate an interrupt every 250ms.
//------------------------------------------------------------------------------
void ConfigureTc(void) {
    unsigned int div;
    unsigned int tcclks;
    AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;       // Enable peripheral clock
    TC_FindMckDivisor(1, BOARD_MCK, &div, &tcclks);     // Configure TC for a 4Hz frequency and trigger on RC compare
    TC_Configure(AT91C_BASE_TC0, tcclks | AT91C_TC_CPCTRG);
    AT91C_BASE_TC0->TC_RC = (BOARD_MCK / div) / 1;      // timerFreq / desiredFreq
    IRQ_ConfigureIT(AT91C_ID_TC0, 0, TC0_IrqHandler);   // Configure and enable interrupt on RC compare
    AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
    IRQ_EnableIT(AT91C_ID_TC0);
    printf(" -- timer has started \n\r");
    TC_Start(AT91C_BASE_TC0);
    }

it's just interrupt timer and it's event (handler) but when I run some

while(1) {
  // action

after ConfigureTc() it both cycle and interrupt timer are freezes... Why could that be? Should I add another timer and avoid while(1) ?

while(1) {
  printf("hello");
  }

-- this breaks (freeze) loops (yes, if I don't use timer it works as it must)

cnd
  • 32,616
  • 62
  • 183
  • 313
  • Is the timer interrupt handler entered - if you put a breakpoint on the handler, is it hit at all? What do you mean by 'freezes' - if you break execution, where is it and what is it doing? – Martin James Sep 13 '12 at 11:10
  • without while(1) it executes fine, strange but it doesn't exit from main function, freezes means timer stop processing and while(1) loop too. – cnd Sep 13 '12 at 11:22
  • 2
    Does `IRQ_ConfigureIT()` take care of wrapping the call to `TC0_IrqHandler()` into proper context save-restore code? I mean, if `TC0_IrqHandler()` is executed directly in response to timer IRQs, it's going to trash some registers in the code that `TC0_IrqHandler()` preempts/interrupts. – Alexey Frunze Sep 13 '12 at 11:32
  • Do you mean while() must be in the same ... code context? where do I call IRQ_ConfigureIT ? – cnd Sep 13 '12 at 11:51
  • 1
    @AlexeyFrunze - good point - I kinda assumed that it did, but maybe not... Maybe, then, also needs some 'interrupt' attribute/pragma? – Martin James Sep 13 '12 at 12:45
  • 1
    What I mean is, does `IRQ_ConfigureIT()` work with a regular C function or does it need a special function (perhaps defined as an `interrupt` function or implemented (partially) in assembly) that saves and restores registers that it uses internally. – Alexey Frunze Sep 13 '12 at 12:46
  • 1
    Usually, if the structure of the interrupt handler is bad, it gets entered once and that's it. Your 'symptoms' are not clear. Unless code in the while() loop explicitly or implicitly disables the timer interrupt or all interrupts, I would expect the handler to get called at least once. To be clear, if you remove the while(1) loop, does the LED flash reliably at the expected rate? Also, I assume you're not running on any kind of OS? – Martin James Sep 13 '12 at 12:55
  • Based on what I've found online, regular C functions are OK with `IRQ_ConfigureIT()`. We need to see more code as it's unclear what else can be the problem. – Alexey Frunze Sep 13 '12 at 12:57
  • Another point - does the wrapper generated by IRQ_ConfigureIT() clear any and all bits in the timer and/or interrupt-controller to acknowledge/reset the interrupt? – Martin James Sep 13 '12 at 13:03
  • @Martin James yes. bootstrap -> my application. and yes without while leds flash fine, after all... with very simple loop while + printf nothing breaks to... Something in my while breaks it. – cnd Sep 13 '12 at 13:06
  • Hmm.. you don't say what the 'a' and 'C' vars are or where declared. When it's 'frozen', what is is doing? You have a debugger, surely? Stop the execution and check to ensure that the uC is not just looping round some abort handler with interrupts disabled - that's where most of my code ends up :( – Martin James Sep 13 '12 at 19:31

1 Answers1

1

I'll venture an actual answer here. IME, 99% of the time my boards 'go out' with no response on any input and no 'heartbeat' LED-flash from the low-priority 'blinky' thread, the CPU has flown off to a prefetch or data abort handler. These handlers are entered by interrupt and most library-defined default handlers do not re-enable interrupts, so stuffing the entire system. Often, they're just endless loops and, with interrupts disabled, that's the end of the story:(

I have changed my default handlers to output suitable 'CRITICAL ERROR' messages to the UART, (by polling it - the OS/interrupts are stuft!).

Martin James
  • 24,453
  • 3
  • 36
  • 60
  • Solved mistake. some poi_configure that were runes before loops were the reason of it. Thank for all people who were trying to help! – cnd Sep 14 '12 at 05:32