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++

NiosII UART HAL

Altera_Forum
Honored Contributor II
1,407 Views

Hello all, 

 

Has anyone messed with the NiosII UART HAL? I've had no problem using the UART in a polled mode but every attempt I've tried to use the UART with an ISR has just screwed up everything. 

 

I've tried modifying the SOPC design to enable hardware handshaking and then added the necessary pins in the Quartus II design but I've had no luck getting anything to work. Actually the last time I tried it I really screwed something up and had to uninstall NiosII and do a re-install in order to get anything to work. 

 

Thanks...
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
618 Views

the niosII uart hal does not support hardware handshake.  

Main problem is that it does not resets RTS if the circular receive buffer gets 

full.  

 

 

I modified altera_avalon_uart.c in the following way (perhaps not the best  

way but it seems to work): 

 

.. in altera_avalon_uart.h 

/* 

* ALT_AVALON_UART_BUF_LEN is the length of the circular buffers used to hold 

* pending transmit and receive data. This value must be a power of two. 

*/ 

# define ALT_AVALON_UART_BUF_LEN (64)# define ALT_AVALON_UART_RTS_LIMIT_OFF ((ALT_AVALON_UART_BUF_LEN*3)/4)# define ALT_AVALON_UART_RTS_LIMIT_ON ((ALT_AVALON_UART_BUF_LEN*2)/4) 

 

 

.. in altera_avalon_uart.c 

 

int alt_avalon_uart_read (alt_fd* fd, char* ptr, int len) 

.. 

.. 

/* 

* Ensure that interrupts are enabled, so that the circular buffer can 

* re-fill. 

*/ 

 

context = alt_irq_disable_all (); 

dev->ctrl |= ALTERA_AVALON_UART_CONTROL_RRDY_MSK; 

 

// !TF calculate number of bytes in buffer 

if(dev->rx_end>=dev->rx_start) { 

numbytes=dev->rx_end-dev->rx_start; 

else { 

numbytes=ALT_AVALON_UART_BUF_LEN-(dev->rx_start-dev->rx_end); 

// set RTS if RTS_ON LIMIT is reached 

if(numbytes<ALT_AVALON_UART_RTS_LIMIT_ON) { 

dev->ctrl |= ALTERA_AVALON_UART_CONTROL_RTS_MSK; 

// TF! 

 

 

 

IOWR_ALTERA_AVALON_UART_CONTROL(dev->base, dev->ctrl); 

alt_irq_enable_all (context); 

 

/* Return the number of bytes read */ 

 

return count; 

 

 

 

static void alt_avalon_uart_rxirq (alt_avalon_uart_dev* dev, 

alt_u32 status) 

.. 

.. 

.. 

/* 

* If the cicular buffer was full, disable interrupts. Interrupts will be 

* re-enabled when data is removed from the buffer. 

*/ 

 

// !TF calculate number of bytes in buffer 

if(dev->rx_end>=dev->rx_start) { 

numbytes=dev->rx_end-dev->rx_start; 

else { 

numbytes=ALT_AVALON_UART_BUF_LEN-(dev->rx_start-dev->rx_end); 

// clear RTS if RTS_OFF_LIMIT is reached 

if(numbytes>ALT_AVALON_UART_RTS_LIMIT_OFF) { 

dev->ctrl &= ~ALTERA_AVALON_UART_CONTROL_RTS_MSK; 

// TF! 

if (next == dev->rx_start) 

dev->ctrl &= ~ALTERA_AVALON_UART_CONTROL_RRDY_MSK; 

// !TF 

//dev->ctrl &= ~ALTERA_AVALON_UART_CONTROL_RTS_MSK; 

// TF! 

IOWR_ALTERA_AVALON_UART_CONTROL(dev->base, dev->ctrl);  

}  

 

 

 

 

 

//############################################################################  

 

int terminal_driver_set_flowcontrol(BYTE flowctrl) { 

 

alt_fd* fd;  

alt_avalon_uart_dev* dev; // pointer to uart device 

 

if(fdterm<0) return -1; 

 

// see alt_ioctrl.c 

fd = (fdterm < 0) ? NULL : &alt_fd_list[fdterm]; 

if (fd) { 

dev=(alt_avalon_uart_dev*)fd->dev; 

if(flowctrl) { 

dev->flags|=ALT_AVALON_UART_FC; 

else { 

dev->flags&=~ALT_AVALON_UART_FC; 

return 0; 

return -1;  

 

 

 

 

I open device uart in non blocking mode: 

 

static int fdterm; // FILEDESCRIPTOR RETURNED BY OPEN 

.. 

fdterm = open("/dev/uart1", O_RDWR | O_NONBLOCK | O_NOCTTY);  

.. 

 

 

reading is done by 

 

.. 

res=read(fdterm,uart1_tempbuff,sizeof(uart1_tempbuff)-1); 

if(res>0) { 

... we have received some bytes 

 

CTS can be set by function "terminal_driver_set_flowcontrol"
0 Kudos
Reply