[En-Nut-Discussion] PIO Interrupt freeze

Paweł Czarnecki apcom at tlen.pl
Fri Mar 19 16:07:07 CET 2010


    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;
}
//---------------------------------------------------------------------------




More information about the En-Nut-Discussion mailing list