EmbDev.net

Forum: ARM programming with GCC/GNU tools GCC 4.2.2 and interrupt


von Jonathan D. (dumarjo)


Rate this post
useful
not useful
Hi all,

I just try to use the serial port interrupt in received mode. I think I
have set correctly my vector interrupt but when the interrupt routine is
executed i never get back in my program, probably I jump in a exception
vector. I post here the relevant code.

Let me know if you fond something wrong with it.

#define MCK             47923200   //!< MCK (PLLRC div by 2)
#define INTFUNC _attribute_ ((interrupt("IRQ")))

void uart1_init(long BaudRate, int interrupt)
{
  UART1_PERCLOCK_Init(); // Initialisation du periph clock

  *AT91C_PIOA_PDR =   AT91C_PA5_RXD1 |        /* Enable RxD0 Pin */
              AT91C_PA6_TXD1;         /* Enalbe TxD0 Pin */

  *AT91C_US1_CR = AT91C_US_RSTRX |          /* Reset Receiver      */
                    AT91C_US_RSTTX |          /* Reset Transmitter   */
                    AT91C_US_RXDIS |          /* Receiver Disable    */
                    AT91C_US_TXDIS;           /* Transmitter Disable */

  *AT91C_US1_MR = AT91C_US_USMODE_NORMAL |  /* Normal Mode */
                    AT91C_US_CLKS_CLOCK    |  /* Clock = MCK */
                    AT91C_US_CHRL_8_BITS   |  /* 8-bit Data  */
                    AT91C_US_PAR_NONE      |  /* No Parity   */
                    AT91C_US_NBSTOP_1_BIT;    /* 1 Stop Bit  */

    *AT91C_US1_BRGR = (MCK  16  BaudRate);  /* Baud Rate Divisor */

    *AT91C_US1_IER = AT91C_US_RXRDY;//interrupt mask
    if(interrupt)
      usrt1_init_interrupt();//permettre les interruptions


  *AT91C_US1_CR =   AT91C_US_RXEN  |          /* Receiver Enable     */
                    AT91C_US_TXEN;            /* Transmitter Enable  */
}

void usrt1_init_interrupt(void)
{
  unsigned int mask ;

  mask = (0x1 << AT91C_ID_US1);
    //* Disable the interrupt on the interrupt controller
    *AT91C_AIC_IDCR = mask ;
    //* Save the interrupt handler routine pointer and the interrupt
priority
    AT91C_AIC_SVR[AT91C_ID_US1] = (unsigned int) Usart_c_irq_handler ;
    //* Store the Source Mode Register
    AT91C_AIC_SMR[AT91C_ID_US1] = (AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL |
USART_INTERRUPT_LEVEL);
    //* Clear the interrupt on the interrupt controller
    *AT91C_AIC_ICCR = mask ;

    *AT91C_AIC_IECR = (0x1 << AT91C_ID_US1);//Enable interrupt

}

void INTFUNC Usart_c_irq_handler(void)
{

  //usart0_putchar('B');
  unsigned int status;
  unsigned int val;

  //* get Usart status register
  status = *AT91C_US1_CSR;
  if ( status & AT91C_US_RXRDY)
  {
    //* Get byte and send
    //usart0_putchar(*AT91C_US1_RHR);
  }

  if ( status & AT91C_US_OVRE)
  {
    //* clear US_RXRDY
     val = *AT91C_US1_RHR;
  }

  //* Check error
  if ( status & AT91C_US_PARE)
  {
  }

  if ( status & AT91C_US_FRAME)
  {
  }

  //* Reset the satus bit
   *AT91C_US1_CSR = AT91C_US_RSTSTA;
  // usart0_putchar('C');

}

MAKEFILE

The isr routine is compiled in arm mode.

When I uncomment the usart0_putchar call, I see in my debug terminal BC
and after that, the watchdog reset the controller.

Is there something worng with this code ?

Jonathan

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Do you have another interrupt working, i.e. some "systick" from a ISR
driven by a timer ("normal" Timer not the PIT)? It might be a good idea
to do this first before you search for problems in your UART setup/code.
Does your startup-code include an assembler-wrapper for ARM-IRQs, if yes
there might be a "side-effect" with compiler-generated code for
attributes.

von Jonathan D. (dumarjo)


Rate this post
useful
not useful
Martin Thomas wrote:
> Do you have another interrupt working, i.e. some "systick" from a ISR
> driven by a timer ("normal" Timer not the PIT)?

I have the USB interrupt working but this one use the NAKED attribut
also the timer with NAKED attribute.

I've try that too for the Uart, but this is not help.


>It might be a good idea
> to do this first before you search for problems in your UART setup/code.
> Does your startup-code include an assembler-wrapper for ARM-IRQs, if yes
> there might be a "side-effect" with compiler-generated code for
> attributes.

I will look at it. I will also try to use only arm code without any
thumb instruction. Juste to see if this change something

I let you know my progress

Jonathan

von Martin T. (mthomas) (Moderator)


Rate this post
useful
not useful
Jonathan Dumaresq wrote:
> Martin Thomas wrote:
>> Do you have another interrupt working, i.e. some "systick" from a ISR
>> driven by a timer ("normal" Timer not the PIT)?
>
> I have the USB interrupt working but this one use the NAKED attribut
> also the timer with NAKED attribute.
>
> I've try that too for the Uart, but this is not help.

Do not mix "attribute(interrupt)", "attribute(naked)"+macros and
IRQ-assembler-wrapper. If the "attribute interrupt" does now work for
the USB ISRs it will most certainly not work for this handler too. Stay
with one approach. If in doubt look into the disassembly, there are just
a few assembler instructions you need to understand, not the complete
instruction-set. I suggest to use an assembler-wrapper for IRQ as
demonstrated in several examples from Atmel. This will avoid
"vendor"-extensions.

von Jonathan D. (dumarjo)


Attached files:

Rate this post
useful
not useful
Martin Thomas wrote:
> Jonathan Dumaresq wrote:
>> Martin Thomas wrote:
>>> Do you have another interrupt working, i.e. some "systick" from a ISR
>>> driven by a timer ("normal" Timer not the PIT)?
>>
>> I have the USB interrupt working but this one use the NAKED attribut
>> also the timer with NAKED attribute.
>>
>> I've try that too for the Uart, but this is not help.
>
> Do not mix "attribute(interrupt)", "attribute(naked)"+macros and
> IRQ-assembler-wrapper. If the "attribute interrupt" does now work for
> the USB ISRs it will most certainly not work for this handler too. Stay
> with one approach. If in doubt look into the disassembly, there are just
> a few assembler instructions you need to understand, not the complete
> instruction-set. I suggest to use an assembler-wrapper for IRQ as
> demonstrated in several examples from Atmel. This will avoid
> "vendor"-extensions.

Hi I have a small sample program that only set the interrupt on USART1
and user DBGU to output some status.

And I only enter 1 time in the interrupt. The interrupt is never fired
after.

I attached the project in a zip file. If someone can put an eye on it to
tell me where is the problem that sould be good

regards

Jonathan

von Jonathan D. (dumarjo)


Rate this post
useful
not useful
found it

I have to put
AT91C_BASE_AIC->AIC_EOICR = 0;

at the end of the usart interrupt

Jonathan

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.