- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...Link Copied
1 Reply
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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"
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page