Question

Hello I am learning how to use the Uart by using interrupts in Nios and I am not sure how to start. I have made it in polling, but I am not sure how to start using interrupts.

Any help would be appreciated

Here is my code

#include <stdio.h>                    // for NULL
#include <sys/alt_irq.h>              // for irq support function
#include "system.h"                   // for QSYS defines
#include "nios_std_types.h"           // for standard embedded types

#define JTAG_DATA_REG_OFFSET          0
#define JTAG_CNTRL_REG_OFFSET         1


#define JTAG_UART_WSPACE_MASK         0xFFFF0000
#define JTAG_UART_RV_BIT_MASK         0x00008000
#define JTAG_UART_DATA_MASK           0x000000FF

volatile uint32* uartDataRegPtr  = (uint32*)JTAG_UART_0_BASE;
volatile uint32* uartCntrlRegPtr = ((uint32*)JTAG_UART_0_BASE +
                                             JTAG_CNTRL_REG_OFFSET);
void uart_SendByte (uint8 byte);
void uart_SendString (uint8 * msg);
//uint32 uart_checkRecvBuffer (uint8 *byte);

uint32 done = FALSE;

void uart_SendString (uint8 * msg)
{
    int i = 0;
    while(msg[i] != '\0')
    {
        uart_SendByte(msg[i]);
        i++;
    }
} /* uart_SendString */

void uart_SendByte (uint8 byte)
{
    uint32 WSPACE_Temp = *uartCntrlRegPtr;

    while((WSPACE_Temp & JTAG_UART_WSPACE_MASK) == 0 )
    {
        WSPACE_Temp = *uartCntrlRegPtr;
    }

    *uartDataRegPtr = byte;

} /* uart_SendByte */

uint32 uart_checkRecvBuffer (uint8 *byte)
{
    uint32 return_value;
    uint32 DataReg = *uartDataRegPtr;

    *byte = (uint8)(DataReg & JTAG_UART_DATA_MASK);
    return_value = DataReg & JTAG_UART_RV_BIT_MASK;


    return_value = return_value >> 15;
    return return_value;



} /* uart_checkRecvBuffer */

void uart_RecvBufferIsr (void* context)
{


} /* uart_RecvBufferIsr */



int main(void)
{
  uint8* test_msg = (uint8*)"This is a test message.\n";

  //alt_ic_isr_register (  ); // used for 2nd part when interrupts are enabled

  uart_SendString (test_msg);

  uart_SendString ((uint8*)"Enter a '.' to exist the program\n\n");

  while (!done)
  {
      uint8 character_from_uart;
      if (uart_checkRecvBuffer(&character_from_uart))
      {
          uart_SendByte(character_from_uart);
      }

    // do nothing
  } /* while */

  uart_SendString((uint8*)"\n\nDetected '.'.\n");
  uart_SendString((uint8*)"Program existing....\n");
  return 0;

} /* main */

I am suppose to use the uart_RecvBufferIsr instead of uart_checkRecvBuffer. How can tackle this situation?

Was it helpful?

Solution

You will need to register your interrupt handler by using alt_ic_isr_register(), which will then be called when an interrupt is raised. Details can be found (including some sample code) in this NIOS II PDF document from Altera.

As far as modifying your code to use the interrupt, here is what I would do:

Remove uart_checkRecvBuffer();

Change uart_RecvBufferIsr() to something like (sorry no compiler here so can't check syntax/functioning):

volatile uint32 recv_flag = 0;
volatile uint8  recv_char;
void uart_RecvBufferIsr(void *context)
{
    uint32 DataReg = *uartDataRegPtr;

    recv_char = (uint8)(DataReg & JTAG_UART_DATA_MASK);
    recv_flag = (DataReg & JTAG_UART_RV_BIT_MASK) >> 15;
}

The moral of the story with the code above is that you should keep your interrupts as short as possible and let anything that is not strictly necessary to be done outside (perhaps by simplifying the logic I used with the recv_char and recv_flag).

And then change your loop to something like:

while (!done)
{
    if (recv_flag)
    {
        uart_SendByte(recv_byte);
        recv_flag = 0;
    }
}

Note that there could be issues with what I've done depending on the speed of your port - if characters are received too quickly for the "while" loop above to process them, you would be losing some characters.

Finally, note that I declared some variables as "volatile" to prevent the compiler from keeping them in registers for example in the while loop.

But hopefully this will get you going.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top