[En-Nut-Discussion] PIO Interrupt freeze

Pawel Czarnecki apcom at tlen.pl
Sat Mar 20 09:36:23 CET 2010


Shame, shame, shame.... sorry for that junk mail...
I thinking about this problem 2 days and have no idea... mental block...

If input pin will be changed in PortAInt() handler, just after read
PIO_ISR we lost all next interrupts. Case closed.

best regards
Pawel




>    To show the problem I wrote simple application for AT91SAM7X256.
> This is PIOA interrupt handler and one thread that printing information
> when interrupt arrive. To generate interrupt I connect GND to PA27.
> Of course one connect-disconnect generate several interrupts. In main
> I print information what is interrupt configuration. After a few
> connect-disconnect GND from PA27 interrupt does not generate anymore.
> Application work good, because interrupt config is still reported.
> I saw this problem on my own board but I test this on olimex
> SAM7-EX256 and result is similar.
> Can anyone tell me what I doing wrong?
>
> best regards
> Pawel
>
>
> //---------------------------------------------------------------------------
> /*
> * main.c
> *
> */
>
> #include <stdio.h>
> #include <stdint.h>
> #include <io.h>
>
> #include <dev/usartat91.h>
> #include <dev/irqreg.h>
>
> #include <sys/version.h>
> #include <sys/event.h>
> #include <sys/heap.h>
> #include <sys/thread.h>
> #include <sys/timer.h>
>
> //---------------------------------------------------------------------------
> void UartInit(void){
>   NutRegisterDevice(&devUsartAt910, 0, 0);
>   freopen("uart0", "w", stdout);
>
>   unsigned int Bd = 115200,
>            Parity = 0,  // 0 (no), 1 (odd) or 2 (even).
>            DataBits = 8, StopBits = 1, Timeout = NUT_WAIT_INFINITE;
>
>   _ioctl(_fileno(stdout), UART_SETREADTIMEOUT, &Timeout);
>   _ioctl(_fileno(stdout), UART_SETDATABITS, &DataBits);
>   _ioctl(_fileno(stdout), UART_SETSTOPBITS, &StopBits);
>   _ioctl(_fileno(stdout), UART_SETPARITY, &Parity);
>   _ioctl(_fileno(stdout), UART_SETSPEED, &Bd);
>
>   printf("Nut/OS %s\n", NutVersionString());
>   printf("Clock: %ld Hz\n", NutGetCpuClock());
>   printf("Heap Available: %lu bytes free\n", 
> (uint32_t)(NutHeapAvailable()));
>   printf("Compile: "__DATE__" "__TIME__"\n");
> }
> //---------------------------------------------------------------------------
> volatile uint32_t PortAIsr=0;
> HANDLE PortAIntEvent;
> #define PIOA_INT_BIT  27
>
> //---------------------------------------------------------------------------
> void PortAInt(void *arg){
>   PortAIsr |= (inr(PIOA_BASE + PIO_ISR_OFF)) & (inr(PIOA_BASE + 
> PIO_IMR_OFF));
>   if(PortAIsr) NutEventPostFromIrq(&PortAIntEvent);
> }
> //---------------------------------------------------------------------------
> THREAD(PortAIntTh, arg){
>   for(;;){
>      NutEventWait(&PortAIntEvent, NUT_WAIT_INFINITE);
>      PortAIsr = 0;
>      printf("Th WakeUp\n");
>   }
> }
> //---------------------------------------------------------------------------
> void PortAIntInit(void){
>   NutThreadCreate("PortAIntTh", PortAIntTh, 0, 1024);
>
>   outr(PIOA_BASE+PIO_ODR_OFF, (1<<PIOA_INT_BIT)); // Output Disable 
> Register
>   outr(PIOA_BASE+PIO_PUER_OFF,(1<<PIOA_INT_BIT)); // PIO Pull Up Enable 
> Register
>   outr(PIOA_BASE+PIO_IFER_OFF,(1<<PIOA_INT_BIT)); // Input Filter Enable 
> Register
>   outr(PIOA_BASE+PIO_IER_OFF, (1<<PIOA_INT_BIT)); // PIO Controller 
> Interrupt Enable Register
>   outr(PIOA_BASE+PIO_PER_OFF, (1<<PIOA_INT_BIT)); // PIO Controller PIO 
> Enable Register
>
>   NutRegisterIrqHandler(&sig_PIOA, PortAInt, 0);
>
>   outr(PMC_PCER, 1<<PIOA_ID);  // PMC Peripheral Clock Enable Register
>   outr(AIC_IECR, 1<<PIOA_ID);  // AIC Interrupt Enable Command Register
>   inr(PIOA_BASE+PIO_ISR_OFF);  // Read PIO Status Reg
>   outr(AIC_ICCR, 1<<PIOA_ID);  // Clear interrupt
> }
> //---------------------------------------------------------------------------
> int main(void){
>
>   UartInit();
>
>   PortAIntInit();
>   uint32_t reg;
>
>   for(;;){
>      NutSleep(5000);
>      reg = inr(PMC_PCSR);
>      printf("Clock on PIOA    = %ld (PMC_PCSR=0x%08lx)\n", 
> (reg>>PIOA_ID)&1, reg);
>      reg = inr(AIC_IMR);
>      printf("PIOA int enable  = %ld (AIC_IMR =0x%08lx)\n", 
> (reg>>PIOA_ID)&1, reg);
>      reg = inr(PIOA_BASE+PIO_PSR_OFF);
>      printf("PIO Stat Reg     = %ld (PIOA_PSR=0x%08lx)\n", 
> (reg>>PIOA_INT_BIT)&1, reg);
>      reg = inr(PIOA_BASE+PIO_OSR_OFF);
>      printf("PIO Out Stat Reg = %ld (PIOA_OSR=0x%08lx)\n", 
> (reg>>PIOA_INT_BIT)&1, reg);
>      reg = inr(PIOA_BASE+PIO_IMR_OFF);
>      printf("PIO Ctrl Int     = %ld (PIOA_IMR=0x%08lx)\n", 
> (reg>>PIOA_INT_BIT)&1, reg);
>      printf("sig_PIOA handler = 0x%08lx\n", 
> (uint32_t)sig_PIOA.ir_handler);
>      printf("PIOA Int svr     = 0x%08lx\n", 
> (uint32_t)inr(AIC_SVR(PIOA_ID)));
>
>      NutEventPost(&PortAIntEvent);
>   }
>   return 0;
> }
> //---------------------------------------------------------------------------
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion 




More information about the En-Nut-Discussion mailing list