Hi,
Teensyduino supports the transmitterEnable(pin) on all UARTs for use in applications where you need to signal that Transmission is ongoing. A typical case are RS485 chips but also applies to tri-state buffers.
Teensyduino implements this in software so you can use any pin as TxEnable.
There have been some recent reports in the forum of people having issues with the timing of TxEnable and subsequent communication problems (myself included).
See here https://forum.pjrc.com/threads/5706...erial-when-using-Transmit-Enable-pin?p=215480 and here https://forum.pjrc.com/threads/56281-Troubles-with-RS485-between-2-teensy
From my thorough investigation so far, one of the solutions is to have Teensy processor manage the Tx Enable pin natively in Hardware. This is something the processor can do with proper UART configuration, which I'll describe below.
This seems to work correctly and overcome the problems described when using the software implemented transmitterEnable.
The processor manages TxEnable by configuring the UARTx_MODEM register with the TXRTSE flag. This modifies the RTS pin to work as a TX Enable.
There is one constraint to using hardware-managed TXEnable:
you are limited on the pins that can be used for this (which are the UART hardware RTS pins)
NOTE: Even though we are re-purposing the UART hardware RTS pin, RTS flow control can still be used because, once again, RTS support is implemented by Teensyduino in software (bit banged), so you can assign the RTS function to any other pin. This means that if you need traditional RTS functionality it is still available, even if using this TxEnable approach.
Therefore, here is how to enable processor(hardware)-managed TxEnable for RS485 and other transceivers in Teensy 3.2(for other models, refer to the datasheet)
For Serial1:
For Serial2:
For Serial3:
That's it.
Best Regards
Pedro
Teensyduino supports the transmitterEnable(pin) on all UARTs for use in applications where you need to signal that Transmission is ongoing. A typical case are RS485 chips but also applies to tri-state buffers.
Teensyduino implements this in software so you can use any pin as TxEnable.
There have been some recent reports in the forum of people having issues with the timing of TxEnable and subsequent communication problems (myself included).
See here https://forum.pjrc.com/threads/5706...erial-when-using-Transmit-Enable-pin?p=215480 and here https://forum.pjrc.com/threads/56281-Troubles-with-RS485-between-2-teensy
From my thorough investigation so far, one of the solutions is to have Teensy processor manage the Tx Enable pin natively in Hardware. This is something the processor can do with proper UART configuration, which I'll describe below.
This seems to work correctly and overcome the problems described when using the software implemented transmitterEnable.
The processor manages TxEnable by configuring the UARTx_MODEM register with the TXRTSE flag. This modifies the RTS pin to work as a TX Enable.
There is one constraint to using hardware-managed TXEnable:
you are limited on the pins that can be used for this (which are the UART hardware RTS pins)
- For Serial 1: can be pins 6 or pin 19 (there may be another pin according to the datasheet but not sure)
- For Serial2: pin 22 only
- For Serial 3: pin 2 only
NOTE: Even though we are re-purposing the UART hardware RTS pin, RTS flow control can still be used because, once again, RTS support is implemented by Teensyduino in software (bit banged), so you can assign the RTS function to any other pin. This means that if you need traditional RTS functionality it is still available, even if using this TxEnable approach.
Therefore, here is how to enable processor(hardware)-managed TxEnable for RS485 and other transceivers in Teensy 3.2(for other models, refer to the datasheet)
For Serial1:
Code:
Serial1.begin(....)
/* Activation of TxEnable*/
// uncomment ONE of the lines below depending on which pin you want to use for TxEnable on Serial 1 (6 or 19)
//CORE_PIN6_CONFIG = PORT_PCR_MUX(3);
//CORE_PIN19_CONFIG = PORT_PCR_MUX(3);
UART0_MODEM |= (UART_MODEM_TXRTSE | UART_MODEM_TXRTSPOL);
[COLOR="#FF0000"]// DON'T issue the Serial1.transmitterEnable(x) instruction as that would turn on the software managed TxEnable and duplicate the functionality (causing malfunction probably)[/COLOR]
// now use the UART normally.
// no need to wait for Serial1.flush(). everything is managed by the processor and library
Serial1.write('a');
Serial1.write('b');
...
For Serial2:
Code:
Serial2.begin(....)
/* Activation of TxEnable*/
// Serial 2 can only use pin 22 for hardware managed TXEnable
CORE_PIN22_CONFIG = PORT_PCR_MUX(3);
UART1_MODEM |= (UART_MODEM_TXRTSE | UART_MODEM_TXRTSPOL);
[COLOR="#FF0000"]// DON'T issue the Serial2.transmitterEnable(x) instruction as that would turn on the software managed TxEnable and duplicate the functionality (causing malfunction probably)[/COLOR]
// now use the UART normally.
// no need to wait for Serial2.flush(). everything is managed by the processor and library
Serial2.write('a');
Serial2.write('b');
...
For Serial3:
Code:
Serial3.begin(....)
/* Activation of TxEnable*/
// uncomment ONE of the lines below depending on which pin you want to use for TxEnable on Serial 1 (6 or 19)
CORE_PIN2_CONFIG = PORT_PCR_MUX(3);
UART2_MODEM |= (UART_MODEM_TXRTSE | UART_MODEM_TXRTSPOL);
[COLOR="#FF0000"]// DON'T issue the Serial3.transmitterEnable(x) instruction as that would turn on the software managed TxEnable and duplicate the functionality (causing malfunction probably)[/COLOR]
// now use the UART normally.
// no need to wait for Serial3.flush(). everything is managed by the processor and library
Serial3.write('a');
Serial3.write('b');
...
That's it.
Best Regards
Pedro