SAMD51 RS485 Hardware driven TE pin

The documentation from the datasheet is pretty thin but if you search all 11 times RS485 is found you will find that the SAMD51 has hardware support for controlling the TE (Transmit Enable) pin of the RS485 driver chip.

How do I set this up in the Arduino environment?

To use RS485 hardware support you need to set RXPO = 0x01 (Use SERCOM_PAD[1] for RxD)
and set TXPO = 0x03 for TxD on SERCOM_PAD[0] and TE on SERCOM_PAD[2].

RXPO is almost always 1, so how do I set TXPO?

I'm so close but haven't found anything in the code or the forums.

I found REG_SERCOMx_USART_CTRLA to read or write the whole 32 bit register. Is there a simpler way?



Hi pchidley,

The path of least resistance is to use the existing Serial1 port, disable it, make the necessary register alterations then re-enable it again.

The following code activates the TE (Tranmit Enable) on D10 (PA20) using an Adafruit Feather M4, with TX and RX on D1 and D0 respectively:

// Convert Serial1 for RS485 operation on the Adafruit Feather M4
void setup() {
  Serial1.begin(115200);                        // Initialise Serial1 (on SERCOM5)
  while (!Serial1);                             // Wait for the console to open
  SERCOM5->USART.CTRLA.bit.ENABLE = 0x0;        // Disable SERCOM5
  while (SERCOM5->USART.SYNCBUSY.bit.ENABLE);   // Wait for synchronization
  PORT->Group[g_APinDescription[10].ulPort].PINCFG[g_APinDescription[10].ulPin].bit.PMUXEN = 1;   // Enable the TE output on D10
  PORT->Group[g_APinDescription[10].ulPort].PMUX[g_APinDescription[10].ulPin >> 1].reg |= PORT_PMUX_PMUXE(2);
  SERCOM5->USART.CTRLA.bit.TXPO = 0x3;          // Set TXPO to 3 to activate the TE output
  SERCOM5->USART.CTRLC.bit.GTIME = 0x2;         // Set the RS485 guard time
  SERCOM5->USART.CTRLA.bit.ENABLE = 0x1;        // Enable SERCOM5
  while (SERCOM5->USART.SYNCBUSY.bit.ENABLE);   // Wait for synchronization

void loop() {
  Serial1.println("Test");                      // Send test message
  delay(1000);                                  // Wait for 1 second

Note that the SERCOM number and the TE output pin will depend on what board you're using.

Thanks Martin for the excellent answer.

Since my original hardware layout I found the section on IOSETS and discovered a couple of problems. MPLAB-X and Harmony Configurator did NOT indicate the pins I selected as a problem. Data sheet says otherwise.

I only understand a bit of your code. A bit above my hardware experience.
Especially "g_APinDescription[10].ulPort", where do you find info on this like this?

Thanks again.
Tested and works.

For those interested, Martin's solution for setting the registers works great.
I now have THREE additional RS485 ports with hardware control of the direction.

The IOSETS section of the data sheet leaves lots to be desired. IT IS POSSIBLE to have RX and TX pins in the same IOSET and the TE (transmit enable pin) on an alternate Sercom.2 pads.
E.G. Using PA22/PA23 for Sercom3.0 and Sercom3.1 works since TX and RX are in the same IOSET.
BUT I can then assign TE to PA18 Sercom3.2 which isn't in the same IOSET and isn't even in the same MUX group.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.