• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

ARM7TDMI interrupt question

Status
Not open for further replies.

tresca

Member
playing with an arm dev board, and trying to get edge triggered interupts to work. Im able to get one pin to work, but my question is

is it possible to have individual edge triggers for each io pin ?

looking through the datasheet, there doesnt seem to be anything and the AIC seems to consider all the io pins as one group.

So if there are any arm users here, who could answer.

If no, thanks.
If yes, how can you do it ?

im using crossworks compiler.
 

DirtyLude

Well-Known Member
We have no idea what ARM7 chip you are using.

The only one I know right now is SAM7. Only one pin can use the Fast Interrupt, but other GPIO pins can use regular edge triggered interrupts. You set the trigger type using the AIC Source Mode register 0 thru 31 and set the vector in the corresponding vector register.

EDIT: If it is a SAM7, or equivalent lookup for another ARM7 chip, you might be confused because it looks like there's just one source mode register and vector register, but there's actually 32 of them and they are numbered. AIC_SMR0 thru AIC_SMR31
 
Last edited:

tresca

Member
I thought all ARM7 were essentially the same. The architecture and what not maybe just minor sutle differences. And yes I am using the sam7 (AT91SAM7S64).

I was wondering what that 32 source modes were for.

Then, is it possible to have all 4 interrupts(edge hi, edge low, level high, level low for one pin by assigning them to different source modes ?

I'm still trying to understand the crossworks compiler and this arm7.
 

DirtyLude

Well-Known Member
The peripherals are all different on each manufacturer. The interrupt controller is a peripheral.

I haven't used external triggered interrupts other than the FIQ. From what I'm reading, no, you can only configure an i/o line for one interrupt mode. Each source mode register is for a specific I/O line. For external interrupts you have to enable it with the PIO controller interrupt enable.
 

tresca

Member
To clear an interrupt, it says write to the AIC_ICCR (interupt clear control register), and I have cleared it, but i cant seem to return to main function. Is there another way.

ill post my code a bit later if i cant figure this out.

thanks
 

DirtyLude

Well-Known Member
I use Crossworks, but I use the GCC isr routines. If you want to use the Crossworks routines, you can lookup in the help 'Programmable interrupt handling'. They provide several functions for setup and handling. You can just check the help index fo ctl_set_isr and work out from there.
 

tresca

Member
I need some guidance.

What I want to do: Each time I press button1, it interrupts, and led1 is toggled.

What it does: As soon as I run the program and immediately after global interrupts are enabled, it jumps to the ISR and when it leaves the ISR, it goes right back in, and continues to do this.

Code:
#include <targets/AT91SAM7.h>
#include <targets/AT91SAM7S64.h>
#include <ctl_api.h>

#define B1 (1 << 19)
#define B2 (1 << 20)
#define MASK 0X1;

static CTL_ISR_FN_t isrButton1;
static CTL_ISR_FN_t isrButton2;
int x=0;

void isrSet()
{
    isrButton1();


}

void isr1Init(CTL_ISR_FN_t isr)
{
 isrButton1 = isr;

  // Setup PIO
  PIOA_ODR = B1 |B2;
  PIOA_PER = B1|B2;
  PIOA_MDDR = ~(B1|B2);
  PIOA_MDER = B1|B2;
  PIOA_IER = B1|B2;
  ctl_set_isr(PIOA_ID, 0, CTL_ISR_TRIGGER_LOW_LEVEL, isrSet, 0);
  ctl_unmask_isr(PIOA_ID);


}

void setLed(void)
{
    x++;
  int temp=PIOA_PDSR&1;
  if(temp)
  {
    PIOA_CODR=1;
    PIOA_SODR=2;
  }
  else
  {
    PIOA_CODR=2;
    PIOA_SODR=1;
  }
  temp=AIC_FVR;
  AIC_ICCR=1<<PIOA_ID;
  AIC_EOICR=1<<PIOA_ID;

}




int main()
{
  
    int x=0;
    int y=0;
    unsigned char led=0;
   // isrButton2=clearLed;
    ctl_board_init(); //init the board
    isr1Init(setLed);
    //isr2Init(clearLed);
    ctl_global_interrupts_enable();
    ctl_board_set_leds(8);

   
    
    while(1)
    {
        
        //binCount();
        //scaleUp();
        //scaleDown();
        
        //scale();
        
          
         
        
    }


 
  return 0;
}



}
How can I get out of an interrupt ?
 
Last edited:

tresca

Member
I should mention that I have an IAR JLINK and I am using the AT01SAM7S-EK developer board if that matters
 

tresca

Member
Just changed my setIsr a bit

Code:
void setLed(void)
{

    x++;
  int temp=PIOA_PDSR&1;
  if(temp)
  {
    PIOA_CODR=1;
    PIOA_SODR=2;
  }
  else
  {
    PIOA_CODR=2;
    PIOA_SODR=1;
  }
  temp=AIC_FVR;
  AIC_ICCR=PIOA_ID;
  AIC_EOICR=PIOA_ID;



}
If i run the program in full (no breakpoints), it appears not to work. I press the button and nothing, wait a few seconds and then press it again, nothing (all 4 leds are lit up).

If i use break points and put a breakpoint inside the the setIsr(), then it works.
I run the program, press the button, goes into the isr, led turns on/off, resume the program, press the button and the led turns on/off.

When i remove the breakpoint, and then press the button, both leds turn on.

I dont get why it works if i step through it, but does not when I run the program fully.
 

DirtyLude

Well-Known Member
Well, I'm hindered here by the fact that I don't actually use the CTL library or the Crossworks register definitions. I use the free GCC ones as there is more code out there that uses them, so it's easier to convert.

I have to go pick up the kids, but one thing I notice is that you have not enabled the PIO peripheral clock. One annoying thing on the ARM is you need to enable clocks for peripherals you are going to use. For PIO, you can output without the clock enabled, but you need to enable the clock to input.

Code:
  //Turn on the peripheral clock.  Without this on, inputs do not actually register in the PDSR register
  volatile AT91PS_PMC	pPMC = AT91C_BASE_PMC;			// pointer to PMC data structure
  pPMC->PMC_PCER = (1<<AT91C_ID_PIOA);				// enable PIOA peripheral clock
I'll take a look at the code better later tonight.
 
Last edited:

tresca

Member
I tried to get gnuArm to work, but so many things i had to get and link up that i finally gave up and am trying out the crossworks compiler since it too uses gcc.

where did you get the arm gcc library and at91 register definitions ?

id like to go with that approach
 

DirtyLude

Well-Known Member
Download the sample code from Atmel and the James (Jim) Lynch tutorials. The AT91SAM7S256.h is in there along with isrsupport.c

The tutorial has an external interrupt example, but its the FIQ.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top