[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