Forum Discussion
Altera_Forum
Honored Contributor
21 years agoNiosII UART HAL
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 e...
Altera_Forum
Honored Contributor
21 years agothe 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"