Forum Discussion
Altera_Forum
Honored Contributor
14 years agoThis is an old post but I thought I'd post my solution to this RS-485 issue in case someone else finds it useful.
I ended up modifying the altera_avalon_uart driver so that it could use the PIO to toggle the direction of the RS-485 transceiver. To do this I modified the uart write function, which I call co_avalon_rs485_write here, such that at the very beginning I put IOWR_ALTERA_AVALON_PIO_DATA(GENERAL_PIO_BASE, 0x1); to enable writes. Then just before the "return (len - count)" call I turn it back off. However it was also necessary to make sure the shift register had drained before toggling this bit back so what I have is, /* If in blocking mode, wait for data to be sent out before puting * the rs-485 transceiver into receive mode. */ if (!(flags & O_NONBLOCK)) { /* wait for circular transmit buffer to drain to transmitter * shift register */ while ((sp->tx_start != sp->tx_end)){ /* interrupts here drain tx_buffer until tx_start=tx_end */ } /* setup to monitor status register */ base = sp->base; status = IORD_CO_AVALON_RS485_STATUS(base); /* wait for transmitter shift register to drain */ while(!(status & CO_AVALON_RS485_STATUS_TMT_MSK)) { status = IORD_CO_AVALON_RS485_STATUS(base); } } /* put rs-485 transceiver into receive mode */ IOWR_ALTERA_AVALON_PIO_DATA(GENERAL_PIO_BASE, 0x0); /* return the number of bytes written */ return (len - count);