Chciałbym ostrzec użytkowników Niosa w FPGA Altery przed błędem w obsłudze przerwania od odbiornika w ichnim UARTcie...
Błąd siedzi sobie tam w bibliotece i nie bardzo jest jak mu zapobiedz. Otóż obsługa przerwania budzi task czekający na zdarzenie od portu szeregowego ZANIM sprawdzony zostanie status błędu przystości lub status błędu ramki... W przypadku błędu taki znak jest usuwany z bufora kołowego i nigdzie nie ma informacji o żadnym błędzie (handler przerwania po prostu robi pusty "return;") ale task jest już obudzony wcześniejszym zawołaniem funkcji systemowej ALT_FLAG_POST...
Tu jest ich obsługa przerwania od odbiornika RX:
static void alt_avalon_uart_rxirq (alt_avalon_uart_dev* dev, alt_u32 status) { alt_u32 next;
/* * In a multi-threaded environment, set the read event flag to indicate * that there is data ready. This is only done if the circular buffer was * previously empty. */
if (dev->rx_end == dev->rx_start) { ALT_FLAG_POST (dev->events, ALT_UART_READ_RDY, OS_FLAG_SET); } /***** TUTAJ BUDZĄ TASK UŚPIONY NA FLADZE ALT_UART_READ_RDY ****/
/* Determine which slot to use next in the circular buffer */
next = (dev->rx_end + 1) & ALT_AVALON_UART_BUF_MSK;
/* Transfer data from the device to the circular buffer */
dev->rx_buf[dev->rx_end] = IORD_ALTERA_AVALON_UART_RXDATA(dev->base);
/* If there was an error, discard the data */
if (status & (ALTERA_AVALON_UART_STATUS_PE_MSK | ALTERA_AVALON_UART_STATUS_FE_MSK)) { return; } /*** TUTAJ KOŃCZĄ OBSŁUGĘ PRZERWANIA BEZ WSTAWIENIA ZNAKU DO BUFORA ***/
dev->rx_end = next;
next = (dev->rx_end + 1) & ALT_AVALON_UART_BUF_MSK;
/* * If the cicular buffer was full, disable interrupts. Interrupts will be * re-enabled when data is removed from the buffer. */
if (next == dev->rx_start) { dev->ctrl &= ~ALTERA_AVALON_UART_CONTROL_RRDY_MSK; IOWR_ALTERA_AVALON_UART_CONTROL(dev->base, dev->ctrl); } }
Bardziej szczegółowy opis moich zmagań z wyprodukowaniem prostej funkcji "ReadUARTwithTimeout" w tym środowisku zamieszczam tutaj: