Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

UART ISR

Has Anyone implemented ISRs with AVALON UART?

I'm trying to implement an ISR using the RRDY Interrupt bit in the STATUS register

but it seems not work... has anyone an idea?

i past and copy the functions:

-- ISR instantiation --

void init_seriale_ext (void)

{

// Dichiarazione delle Variabili Interne //

// Recast the _edge_capture pointer to match the alt_irq_register()

// function prototype.

void* serial_rcv_exception_ptr = (void*) &_serial_rcv_exception;

// Register the interrupt handler. //

alt_irq_register(SERIALE_EXT_IRQ, serial_rcv_exception_ptr, handle_seriale_ext_interrupt);

} // END init_seriale_ext() //

-- ISR ROUTINE --

void handle_seriale_ext_interrupt (void *context, alt_u32 id)

{

// It is important to keep this volatile,

// to avoid compiler optimization issues.

volatile int* serial_rcv_exception_ptr = (volatile int*) context;

// Store the value in the Serial exception register in *context. //

*serial_rcv_exception_ptr = IORD_ALTERA_AVALON_UART_STATUS(SERIALE_EXT_BASE);

// Reset the Serial exception register. //

IOWR_ALTERA_AVALON_UART_STATUS(SERIALE_EXT_BASE, (*serial_rcv_exception_ptr & 0xFF7F));

// richiamo la funzione che gestisce la ricezione di un pacchetto

serial_protocol_ext(IORD_ALTERA_AVALON_UART_RXDATA(SERIALE_EXT_BASE));

} // END handle_serial_ext_interrupt //

No errors were found in compilation, but it doesn't jump to the ISR function when I send anythink

using the UART.

Help...

shadowice

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If you look in the directory altera\kits\nios2\components\altera_avalon_uart there is a driver for the UART, both interrupt driven and non-interrupt driven. I suspect that your problem is that the UART driver is automatically installed on your system, so it is handling the ISR. You will be able to tell by looking in alt_sys_init.c, but you should probably read chapter 4 and 5 of the Nios II Software Developers Handook to understand what alt_sys_init.c is first.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by rugbybloke@Sep 2 2005, 10:02 AM

    if you look in the directory altera\kits\nios2\components\altera_avalon_uart there is a driver for the uart, both interrupt driven and non-interrupt driven. i suspect that your problem is that the uart driver is automatically installed on your system, so it is handling the isr. you will be able to tell by looking in alt_sys_init.c, but you should probably read chapter 4 and 5 of the nios ii software developers handook to understand what alt_sys_init.c is first.

    --- Quote End ---

    I have looked into the codes you say,

    but i want to use as less as possible nios II API because I want to

    understand what I'm doing so I've registered by hand the IRQ

    associated to the IRQ mapped to the UART in the Hardware Platform.

    As I can read on datasheet i can see that

    " The UART core outputs a single IRQ signal to the Avalon interface, which

    can connect to any master peripheral in the system, such as a Nios II

    processor. The master peripheral must read the status register to

    determine the cause of the interrupt.

    Every interrupt condition has an associated bit in the status register

    and an interrupt-enable bit in the control register. When any of the

    interrupt conditions occur, the associated status bit is set to 1 and

    remains set until it is explicitly acknowledged. The IRQ output is asserted

    when any of the status bits are set while the corresponding interruptenable

    bit is 1. A master peripheral can acknowledge the IRQ by clearing

    the status register.

    At reset, all interrupt-enable bits are set to 0; therefore, the core cannot

    assert an IRQ until a master peripheral sets one or more of the interruptenable

    bits to 1.

    All possible interrupt conditions are listed with their associated status

    and control (interrupt-enable) bits in Table 6–5 on page 6–16 and

    Table 6–6 on page 6–18. Details of each interrupt condition are provided

    in the status bit descriptions. "

    so the IRQ should be setted automatically by the CPU and the only think

    I have to do is to register the irq to a custom IRQ handler function. There

    is an example on the datasheet for the PIOs Peripheral.

    I've looked into my alt_sys_init.c and I've found these:

    void alt_sys_init( void )

    {

    ALTERA_AVALON_TIMER_INIT( TIMER, timer );

    ALTERA_AVALON_JTAG_UART_INIT( JTAG_UART_0, jtag_uart_0 );

    ALTERA_AVALON_SYSID_INIT( SYSID, sysid );

    ALTERA_AVALON_CFI_FLASH_INIT( EXT_FLASH, ext_flash );

    ALTERA_AVALON_LAN91C111_INIT( LAN91C111, lan91c111 );

    ALTERA_AVALON_LCD_16207_INIT( LCD, lcd );

    ALTERA_AVALON_UART_INIT( SERIALE_INT, seriale_int );

    ALTERA_AVALON_UART_INIT( SERIALE_EXT, seriale_ext );

    ALTERA_AVALON_UART_INIT( SERIALE_FUT, seriale_fut );

    }

    yes I&#39;ve 3 UARTS.... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/sad.gif ....

    now if I recall the API, (but I wish that there is another method) how I have to do ???

    there is any kind of example?

    shadowice
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    ALTERA_AVALON_UART_INIT( SERIALE_INT, seriale_int );

    ALTERA_AVALON_UART_INIT( SERIALE_EXT, seriale_ext );

    ALTERA_AVALON_UART_INIT( SERIALE_FUT, seriale_fut );[/b]

    --- Quote End ---

    Your problem is exactly as I diagnosed the lines above are initialising the driver for each of your UARTs so when the interrupt goes off for one of your UARTs the driver interrupt handler get&#39;s called and your ISR does not get a look in. There is no easy method to turn off the drivers at present you will have to remove the _INIT and _INSTANCE macros from alt_sys_init.c. The problem is that this is an auto generated file which will be re-generated under your feet.

    You would be much better off using the provided driver and if you don&#39;t understand it step through it. Otherwise you will have to start from the alt_main entry point example which hands you complete control of the machine, with no drivers etc. This does have drawbacks though which are coverred in the manual.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by rugbybloke@Sep 2 2005, 11:24 AM

    <div class='quotetop'>quote

    --- quote end ---

    --- quote start ---

    altera_avalon_uart_init( seriale_int, seriale_int );

    altera_avalon_uart_init( seriale_ext, seriale_ext );

    altera_avalon_uart_init( seriale_fut, seriale_fut );

    --- Quote End ---

    Your problem is exactly as I diagnosed the lines above are initialising the driver for each of your UARTs so when the interrupt goes off for one of your UARTs the driver interrupt handler get&#39;s called and your ISR does not get a look in. There is no easy method to turn off the drivers at present you will have to remove the _INIT and _INSTANCE macros from alt_sys_init.c. The problem is that this is an auto generated file which will be re-generated under your feet.

    You would be much better off using the provided driver and if you don&#39;t understand it step through it. Otherwise you will have to start from the alt_main entry point example which hands you complete control of the machine, with no drivers etc. This does have drawbacks though which are coverred in the manual.[/b]

    --- Quote End ---

    so there is no simply way to drive UART using low level functions such as

    for the PIO component.

    I have to understand how drive the ISR function using its APIs.... but

    the only think I don&#39;t understand is HOW recall the IRQ using the auto

    generated function by NIOS-II IDE.

    thank you

    shadowice
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Now SEEMS!! to be functioning...

    http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/laugh.gif

    I have noted that the IRQ call is not flushed after the ISR execution... http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/mad.gif

    In order to explain to the community I cut and paste the simple code I have created

    for my UART "SERIALE_EXT" peripheral

    I hope It will be usefull:

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    # include <stdio.h># include "altera_avalon_uart_regs.h"# include "altera_avalon_uart.h"# include "sys/alt_irq.h"# include "system.h"

    // Register the istance into the CPU //

    ALTERA_AVALON_UART_INSTANCE( SERIALE_EXT, seriale_ext );

    void handle_seriale_ext_interrupt (void *context, alt_u32 id);

    int _serial_rcv_exception;

    // ************************************************************************** //

    // ************************************************************************** //

    // MAIN Function //

    int main (void)

    {

    // Initialize the IRQ on the UART selected //

    ALTERA_AVALON_UART_INIT ( SERIALE_EXT, seriale_ext );

    // Recast the _edge_capture pointer to match the alt_irq_register()

    // function prototype.

    void* serial_rcv_exception_ptr = (void*) &_serial_rcv_exception;

    // Register the interrupt handler. //

    alt_irq_register(SERIALE_EXT_IRQ, serial_rcv_exception_ptr, handle_seriale_ext_interrupt);

    } // END MAIN //

    // ************************************************************************** //

    // ************************************************************************** //

    // UART ISR Handling //

    void handle_seriale_ext_interrupt (void *context, alt_u32 id)

    {

    // Cast context to _edge_capture&#39;s type.

    // It is important to keep this volatile,

    // to avoid compiler optimization issues.

    volatile int* serial_rcv_exception_ptr = (volatile int*) context;

    // Store the value in the Serial exception register in *context. //

    *serial_rcv_exception_ptr = IORD_ALTERA_AVALON_UART_STATUS(SERIALE_EXT_BASE);

    // Reset the Serial exception register. //

    IOWR_ALTERA_AVALON_UART_STATUS(SERIALE_EXT_BASE, (*serial_rcv_exception_ptr & 0xFF7F));

    // Print a simple message on the STDOUT peripheral //

    printf("\rISR HAS BEEN\nEXECUTED!!!");

    } // END handle_serial_ext_interrupt //

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    bye,

    shadowice
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    the command:

    IOWR_ALTERA_AVALON_UART_STATUS(SERIALE_EXT_BASE, (*serial_rcv_exception_ptr & 0xFF7F))

    is ignored, the register is not resetted...

    why?

    shadowice
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    the only method to flush that bit is to read the UART TX content...

    The ISR recalls forever if this operation is not executed

    shadowice