[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