Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

UART interrupt

Altera_Forum
Honored Contributor II
1,316 Views

I'm in the process of converting an old NIOS II project over to eCos. The interrupts do not work when I use the eCos API. Here is the relevant code. 

 

#include <cyg/hal/system.h># include <cyg/kernel/kapi.h> unsigned char abycin; volatile unsigned int byrxptr = 0; unsigned int bywrptr = 0; cyg_uint32 uart_debug_isr(cyg_vector_t vector, cyg_addrword_t data) {     volatile int clr_int;    // Block this interrupt from occurring until this ISR completes.  cyg_interrupt_mask(vector);  // Tell the processor that we have received the interrupt.  cyg_interrupt_acknowledge(vector);  if (!(IORD_ALTERA_AVALON_UART_STATUS(UART_DEBUG_BASE) & 0x02))     {    abycin = IORD_ALTERA_AVALON_UART_RXDATA(UART_DEBUG_BASE);    if(byrxptr < (RXBUF_SIZE_DEBUG - 2)) byrxptr++;    else byrxptr = 0;  }  else clr_int = IORD_ALTERA_AVALON_UART_RXDATA(UART_DEBUG_BASE); // read UDR if framing error just to clear interrupt  // Allow this interrupt to occur again.  //cyg_interrupt_unmask (vector);  // Tell the kernel that chained interrupt processing is done.  //return CYG_ISR_HANDLED;  return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR; } void uart_debug_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) {  //printf("DSR\n");  //out_str("DSR\n");  cyg_interrupt_unmask(vector); } void out_str(char *s) {  unsigned char *c;    for(c = s;; c++)  {  if(*c == 0)    break;  out_char((unsigned char)*c);  } } void out_char(unsigned char c) {  while(!(IORD_ALTERA_AVALON_UART_STATUS(UART_DEBUG_BASE) & 0x40));  IOWR_ALTERA_AVALON_UART_TXDATA(UART_DEBUG_BASE, c); } void cyg_user_start(void) {  int divisor = 0;  int old = 0;  cyg_handle_t uart_debug_handle, timer_handle;  cyg_interrupt uart_debug_intr, timer_intr;  cyg_interrupt_create(UART_DEBUG_IRQ, 99, 0, &uart_debug_isr, &uart_debug_dsr, &uart_debug_handle, &uart_debug_intr);  cyg_interrupt_attach(uart_debug_handle);  cyg_interrupt_disable();  /* Other initialization tasks performed here */  cyg_interrupt_enable();  cyg_interrupt_unmask(UART_DEBUG_IRQ);  while(1)  {     while (bywrptr != byrxptr) // Check to see if any data has been received by the Uart     {        printf("bywrptr != byrxptr\n");        ProcessRxBuf(); // Process new data received from Uart      }      //while (rtdwrptr != rtdrxptr)        //MDP();  } } 

 

Is there something special that needs to be done in the nios2configtool to get interrupts to work?
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
587 Views

 

--- Quote Start ---  

originally posted by lee@Jan 2 2007, 11:54 AM 

i&#39;m in the process of converting an old nios ii project over to ecos.  the interrupts do not work when i use the ecos api.  here is the relevant code. 

 

#include <cyg/hal/system.h># include <cyg/kernel/kapi.h> unsigned char abycin; volatile unsigned int byrxptr = 0; unsigned int bywrptr = 0; cyg_uint32 uart_debug_isr(cyg_vector_t vector, cyg_addrword_t data) {     volatile int clr_int;    // block this interrupt from occurring until this isr completes.  cyg_interrupt_mask(vector);  // tell the processor that we have received the interrupt.  cyg_interrupt_acknowledge(vector);  if (!(iord_altera_avalon_uart_status(uart_debug_base) & 0x02))     {    abycin = iord_altera_avalon_uart_rxdata(uart_debug_base);    if(byrxptr < (rxbuf_size_debug - 2)) byrxptr++;    else byrxptr = 0;  }  else clr_int = iord_altera_avalon_uart_rxdata(uart_debug_base); // read udr if framing error just to clear interrupt  // allow this interrupt to occur again.  //cyg_interrupt_unmask (vector);  // tell the kernel that chained interrupt processing is done.  //return cyg_isr_handled;  return cyg_isr_handled | cyg_isr_call_dsr; } void uart_debug_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) {  //printf("dsr\n");  //out_str("dsr\n");  cyg_interrupt_unmask(vector); } void out_str(char *s) {  unsigned char *c;    for(c = s;; c++)  {  if(*c == 0)    break;  out_char((unsigned char)*c);  } } void out_char(unsigned char c) {  while(!(iord_altera_avalon_uart_status(uart_debug_base) & 0x40));  iowr_altera_avalon_uart_txdata(uart_debug_base, c); } void cyg_user_start(void) {  int divisor = 0;  int old = 0;  cyg_handle_t uart_debug_handle, timer_handle;  cyg_interrupt uart_debug_intr, timer_intr;  cyg_interrupt_create(uart_debug_irq, 99, 0, &uart_debug_isr, &uart_debug_dsr, &uart_debug_handle, &uart_debug_intr);  cyg_interrupt_attach(uart_debug_handle);  cyg_interrupt_disable();  /* other initialization tasks performed here */  cyg_interrupt_enable();  cyg_interrupt_unmask(uart_debug_irq);  while(1)  {     while (bywrptr != byrxptr) // check to see if any data has been received by the uart     {        printf("bywrptr != byrxptr\n");        processrxbuf(); // process new data received from uart      }      //while (rtdwrptr != rtdrxptr)        //mdp();  } } 

 

is there something special that needs to be done in the nios2configtool to get interrupts to work? 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=20322)</div> 

--- Quote End ---  

 

You&#39;re probably suffering from the fact that the eCos port already contains a driver for the UART and two drivers talking to one piece of hardware is never good
0 Kudos
Altera_Forum
Honored Contributor II
587 Views

Hey thanks, I&#39;ve got it working now using the cyg_io functions.

0 Kudos
Altera_Forum
Honored Contributor II
587 Views

Has anyone gotten multiple UARTs to work in a single system? 

 

My default debug/diagnostics UART works fine when mapped to "/dev/haldiag", but I have two other UARTs in the system which aren&#39;t working using the cyg_io functions. 

 

In the nios2configtool I have TTY mode channel# 0 mapped to "/dev/uart_rtd" and TTY mode channel# 1 mapped to "/dev/uart_radio". When I do the lookup for "/dev/tty0" I receive no error, but then the processor resets somewhere inside the cyg_io_read() function. 

 

Am I missing something? 

 

void cyg_user_start(void) {  cyg_io_handle_t uart_rtd_handle;  Cyg_ErrNo error;  char readbuf;  cyg_uint32 readbuf_size = 1;    cyg_io_init();  error = cyg_io_lookup("/dev/tty0", &uart_rtd_handle);  out_str("Error 1 = ");  out_hex(error);  while(!error)  {     error = cyg_io_read(uart_rtd_handle, (void *)&readbuf, &readbuf_size);     out_hex(readbuf);     out_char(&#39; &#39;);  } }
0 Kudos
Reply