interrupt programming in C...first time coding...please help

All design tool related questions: compiler, assembler, linker. Embedded programming questions: assembler, C code.

Moderator: nferre

seenu461
Posts: 7
Joined: Sat Jan 16, 2010 7:32 am

interrupt programming in C...first time coding...please help

Tue Apr 06, 2010 9:07 am

Hi,
I am beginner working with ATMEL microcontroller programming. i am working on ARM9 board from kwikbyte, which has AT91RM9200 controller on it.

I am trying to work with interrupts, all i am trying to do is execute an ISR block when push button switch is pressed. I am able to pull the necessary registers from the header file and use it my code...but it not working the way i expected.

The following program suppose to print 4 command on the board terminal when it is executed.
statements:
1.PIO Status is IRQ enabled
2.PIO Peripheral B is selected
3.main loop execution
4.interrupt working

Push button is connected to PA25 pin on the board and pin is mulitplex with 2 functions...one of the function is IRQ2...which needs to be selected for the interrupt generation. statement 1 should be printed after checking the status of the pin...it should be zero when peripheral is active...but it is not printing....

when the program is executed...it directly prints statements 2, 3 and seems like it stays in infinite loop...but it doesnt execute ISR block when push button is pressed...I am not sure where i am making the mistake and even i am not able to get resources to understand...please help me ...any help is appreciated...

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <time.h>
#include "AT91RM9200.h"

/* ********************** LOCAL DEFINES ****************************** */

#define GPIO_PUSH_BUTTON_MASK (AT91C_PIO_PA25)

static int memMapFile;
static AT91PS_SYS at91SysCtrlr;
void ext_IRQ0_handler(void);


/* ************************ UTILITY FUNCTIONS ******************************* */

static int OpenSystemController(void)
{
if ((memMapFile = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
{
printf("ERROR: Unable to open /dev/mem\n");
return (errno);
}

at91SysCtrlr = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, memMapFile, (unsigned)AT91C_BASE_SYS);

if (at91SysCtrlr == MAP_FAILED)
{
printf("ERROR: Unable to mmap the system controller\n");
close (memMapFile);
memMapFile = -1;
return (errno);
}

at91SysCtrlr->PMC_PCER = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PMC_IER = GPIO_PUSH_BUTTON_MASK;

//button-switch connected to IRQ1 - PA26

at91SysCtrlr->PIOA_PPUER = ~GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_PDR = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_IFER = ~GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_IER = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_BSR = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_ODR =GPIO_PUSH_BUTTON_MASK;


while(!(at91SysCtrlr->PIOA_PSR)) // PSR shdnt be 1;
{
printf("PIO Status is IRQ enabled\n");
break;
}

while((at91SysCtrlr->PIOA_ABSR)) // ABSR shd be 1;
{
printf("PIO Peripheral B is selected\n");
break;
}

/* do not worry about sync */
return (0);
}


/* ************************ MAIN LOOPS ******************************* */


int main(int argc, char **argv)
{
unsigned ledIndex;
int var;

if (OpenSystemController())
{
printf("Unable to map hardware resources\n");
return (-1);
}

at91SysCtrlr->AIC_SMR[0x1A]=0x00000067;
at91SysCtrlr->AIC_SVR[0x1A]=(unsigned int)&ext_IRQ0_handler;
at91SysCtrlr->AIC_IMR=0x02000000;
at91SysCtrlr->AIC_IECR=0x02000000;

printf("main loop execution\n");

while (1);

return (0); /* never get here */
}

void ext_IRQ0_handler(void)
{
at91SysCtrlr->AIC_IDCR=0xFFFFFFFF;
at91SysCtrlr->AIC_ICCR=0x02000000;
printf("interrupt working\n");
asm("mrs r7,CPSR");
asm("bic r7,r7,#0x80");
asm("msr CPSR,r7");
printf("interrupt working\n");
at91SysCtrlr->AIC_EOICR=0x0;
}
seenu461
Posts: 7
Joined: Sat Jan 16, 2010 7:32 am

Re: interrupt programming in C...first time coding...please help

Tue Apr 06, 2010 10:09 pm

Please help me....
dfridley
Posts: 90
Joined: Thu Feb 25, 2010 5:02 pm

Re: interrupt programming in C...first time coding...please help

Wed Apr 07, 2010 4:02 am

Hello,

One quick comment...

Looks like your switch (PA25) is on IRQ2 but you are setting up IRQ0 in the AIC.
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.
seenu461
Posts: 7
Joined: Sat Jan 16, 2010 7:32 am

Re: interrupt programming in C...first time coding...please help

Thu Apr 08, 2010 4:16 pm

First of all thank you for replying....
And regarding the issue

at91SysCtrlr->AIC_SVR[0x1A]=(unsigned int)&ext_IRQ0_handler;


I believe IRQ0 handler is user defined...i even changed that to IRQ2...it not working....

I am trying to read PSR register value which shouldnt be one for selecting IRQ2

while(!(at91SysCtrlr->PIOA_PSR)) // PSR shdnt be 1;
{
printf("PIO Status is IRQ enabled\n");
break;
}

according to this....

PIO: AT91_REG PIO_PSR PIO Status Register

* PIOD AT91C_PIOD_PSR 0xFFFFFA08
* PIOC AT91C_PIOC_PSR 0xFFFFF808
* PIOB AT91C_PIOB_PSR 0xFFFFF608
* PIOA AT91C_PIOA_PSR 0xFFFFF408


This register indicates which pins are enabled for PIO control. This register is updated when PIO lines are enabled or dis-abled.The register reads as follows:
1 = PIO is active on the corresponding line (peripheral is inactive).
0 = PIO is inactive on the corresponding line (peripheral is active).

since that statement is not printing while execution...that is the first problem need to be sorted out...i couldnt understand how to use the register other than that...please let me know if am doing mistake in the procedure....Thank you
dfridley
Posts: 90
Joined: Thu Feb 25, 2010 5:02 pm

Re: interrupt programming in C...first time coding...please help

Thu Apr 08, 2010 8:21 pm

To clarify...
seenu461 wrote: And regarding the issue

at91SysCtrlr->AIC_SVR[0x1A]=(unsigned int)&ext_IRQ0_handler;

I believe IRQ0 handler is user defined...i even changed that to IRQ2...it not working....
It doesn't matter what you call your handler function it could be myisr_button_handler(). But you need to setup the correct SMR (AIC_SMR[0x1B]) and load your handler address into the SVR for the IRQ you want to service. AIC_SVR[0x1A] is for IRQ1 this needs to be AIC_SVR[0x1B] because PIO_PA25 uses IRQ2 not IRQ1.

see your definition.

Code: Select all

#define GPIO_PUSH_BUTTON_MASK (AT91C_PIO_PA25)
seenu461 wrote: while(!(at91SysCtrlr->PIOA_PSR)) // PSR shdnt be 1;
{
printf("PIO Status is IRQ enabled\n");
break;
}
You are incorrectly checking the entire register.
To check a single bit perform a bitwise AND with the bit(s) you are interested in.
For example:

Code: Select all

// See if the Push Button is set up to use a peripherial
// by testing the bit associated with the Push Button
// 0 = peripheral selected, otherwise = I/O selected.
if( !(at91SysCtrlr->PIOA_PSR & GPIO_PUSH_BUTTON_MASK) )
{
    printf( "Push Button is IRQ enabled\n" );
}
EDIT (fyi): You might also have to update the other AIC registers to properly handle IRQ2, I didn't look these up but I suspect these are setup for IRQ0. Review the data sheet for these registers.
seenu461 wrote:

Code: Select all

at91SysCtrlr->AIC_IMR=0x02000000;
at91SysCtrlr->AIC_IECR=0x02000000;

--- snip ---

void ext_IRQ0_handler(void)
{
    at91SysCtrlr->AIC_IDCR=0xFFFFFFFF;
    at91SysCtrlr->AIC_ICCR=0x02000000;
--- snip---
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.
seenu461
Posts: 7
Joined: Sat Jan 16, 2010 7:32 am

Re: interrupt programming in C...first time coding...please help

Fri Apr 09, 2010 3:22 am

Thanks a lot dfridley....
i changed the registers values accordingly....and after modifications the program is like this ...

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/shm.h>

#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <strings.h>
#include <string.h>
#include <time.h>

#include "AT91RM9200.h"

/* ********************** LOCAL DEFINES ****************************** */

#define GPIO_LED_MASK (AT91C_PIO_PC20)
#define GPIO_PUSH_BUTTON_MASK (AT91C_PIO_PA25)

static int memMapFile;
static AT91PS_SYS at91SysCtrlr;
void ext_IRQ2_handler(void);


/* ************************ UTILITY FUNCTIONS ******************************* */

static int OpenSystemController(void)
{
if ((memMapFile = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
{
printf("ERROR: Unable to open /dev/mem\n");
return (errno);
}

at91SysCtrlr = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED, memMapFile, (unsigned)AT91C_BASE_SYS);

if (at91SysCtrlr == MAP_FAILED)
{
printf("ERROR: Unable to mmap the system controller\n");
close (memMapFile);
memMapFile = -1;
return (errno);
}

/* set LED signals for output */
/* set digital output ports init value = all on (active low) */

at91SysCtrlr->PIOC_PPUDR = GPIO_LED_MASK;
at91SysCtrlr->PIOC_PER = GPIO_LED_MASK;
at91SysCtrlr->PIOC_OER = GPIO_LED_MASK;
at91SysCtrlr->PMC_PCER = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PMC_IER = GPIO_PUSH_BUTTON_MASK;

//button-switch connected to IRQ1 - PA26

at91SysCtrlr->PIOA_PPUER = ~GPIO_PUSH_BUTTON_MASK;

at91SysCtrlr->PIOA_PDR = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_IFER = ~GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_IER = GPIO_PUSH_BUTTON_MASK;

//at91SysCtrlr->PIOA_MDDR = GPIO_PUSH_BUTTON_MASK;
// at91SysCtrlr->PIOA_OWDR = GPIO_PUSH_BUTTON_MASK;
at91SysCtrlr->PIOA_BSR = GPIO_PUSH_BUTTON_MASK;

at91SysCtrlr->PIOA_ODR =GPIO_PUSH_BUTTON_MASK;


while(!(at91SysCtrlr->PIOA_PSR & GPIO_PUSH_BUTTON_MASK)) // PSR shdnt be 1;
{

printf("PIO Status is IRQ enabled\n");
break;

}
while((at91SysCtrlr->PIOA_ABSR)) // ABSR shd be 1;
{
printf("PIO Peripheral B is selected\n");
break;
}

/* do not worry about sync */
return (0);
}


/* ************************ MAIN LOOPS ******************************* */


int main(int argc, char **argv)
{
unsigned ledIndex;
int var;

if (OpenSystemController())
{
printf("Unable to map hardware resources\n");
return (-1);
}
//at91SysCtrlr->PIOA_IER = GPIO_PUSH_BUTTON_MASK;
//at91SysCtrlr->PIOA_MDDR = GPIO_PUSH_BUTTON_MASK;
//at91SysCtrlr->PIOA_OWDR = GPIO_PUSH_BUTTON_MASK;
//at91SysCtrlr->PIOA_ABSR = GPIO_PUSH_BUTTON_MASK;

//at91SysCtrlr->AIC_SMR[0x1A]=0x00000007;
at91SysCtrlr->AIC_IDCR=0x08000000;
at91SysCtrlr->AIC_SMR[0x1B]=0x00000067;
at91SysCtrlr->AIC_SVR[0x1B]=(unsigned int)&ext_IRQ2_handler;
at91SysCtrlr->AIC_IMR=0x08000000;
at91SysCtrlr->AIC_ICCR=0x08000000;
at91SysCtrlr->AIC_IECR=0x08000000;

printf("main loop execution\n");


while (1);
return (0); /* never get here */
}

void ext_IRQ2_handler(void)
{
at91SysCtrlr->AIC_IDCR=0xFFFFFFFF;
at91SysCtrlr->AIC_ICCR=0x08000000;
printf("interrupt working\n");
asm("mrs r7,CPSR");
asm("bic r7,r7,#0x80");
asm("msr CPSR,r7");

printf("interrupt working\n");

at91SysCtrlr->AIC_EOICR=0x0;
}


Now it prints the first statement...but when button is pressed it generates an error message in the terminal...

error message:
[254085.910000] irq 34032, desc: c032a38c, depth: 0, count: 0, unhandled: 0
[254085.910000] ->handle_irq(): c0067398, handle_bad_irq+0x0/0x284
[254085.910000] ->chip(): 00000000, 0x0
[254085.910000] ->action(): 00000000

And one again thanks a lot for ur assistance...it is helping me a lot...
dfridley
Posts: 90
Joined: Thu Feb 25, 2010 5:02 pm

Re: interrupt programming in C...first time coding...please help

Fri Apr 09, 2010 2:12 pm

Hello seenu461,

I'm sorry I don't have the time to debug your program for you.

Maybe someone else can help you with debugging this.

I would recommend you get familiar with your debugger, read the manuals and look at the Atmel sample code. This is the best way to learn the ins and outs of microcontroller programming...
Duane P. Fridley, IEEE CSDP
Viable Bytes, Inc.
seenu461
Posts: 7
Joined: Sat Jan 16, 2010 7:32 am

Re: interrupt programming in C...first time coding...please help

Sat Apr 10, 2010 7:28 am

Hi dfridley
Thanks a lot for your time...i really appreciate that....
sureshkvl
Posts: 2
Joined: Sat Sep 04, 2010 2:21 pm

Re: interrupt programming in C...first time coding...please help

Sat Sep 04, 2010 2:54 pm

Hi seenu,
Have you solved it.
I am also using the kwikbyte kb9202c board and facing the same problem.
Also i require some helps to access the PIOs (specifically D24,D25,D26,D27)
Please help me.

thanks
suresh
sureshkumarr.s@gmail.com

Return to “Development Tools”

Who is online

Users browsing this forum: No registered users and 1 guest