UART RS485 transmit / receive

Peter.zupancic

Joined Dec 22, 2021
7
Hi, if anyone would help me I would be glad. What I want is to transmit and receive data via RS485. Here I’m having problem because drive of UART (SC16…) are not prepared for RS485 communication, from datasheet as I understand I need to somehow enable auto RTS mode, so pin will set DE & RE to HIGH when transmiting and to LOW when receiving. I found some register but dont know how to use it. In attachment I add schematic, also for UART I’m using drivers: https://github.com/nopnop2002/SC16IS752/blob/master/Arduino & ESP8266/SC16IS752.cpp

Any idea?

Attachments

• 794.6 KB Views: 8

Ian0

Joined Aug 7, 2020
5,131
Before you transmit anything, first you have to make sure that the bus is not busy, because RS485 doesn't do collision detection. So all that is necessary is to set DE/RE high as soon as the bus is clear and then start transmitting. As soon as the transmission has stopped (there will be a flag in the UART that says when it has returned to an IDLE state) set DE/RE back to low, because you must not leave the transmitter enabled when it is not transmitting because it will jam the bus.

Peter.zupancic

Joined Dec 22, 2021
7
But this should be on SW side or can HW do it with auto RST pin as it says in datasheet?

Peter.zupancic

Joined Dec 22, 2021
7
Also can I help somehow with voltmeter for example to debug easier? For example if is transmiting RTS should be high meaning 3.3V on pin? And on receiving should have 0V?

Ian0

Joined Aug 7, 2020
5,131
There are many different schemes that determine when a device can transmit on an RS485 line, all sorts of token-passing schemes, different idle-time requirements etc. depending on the application. I don't see how it could be done automatically.
The only RTS I see on the diagram is part of the debug connector and does not seem to be at all related to the RS485.
The only RS485 signal other than TXD and RXD is the R/T (receive/transmit)

nsaspook

Joined Aug 27, 2009
9,729
It seems to be pretty simple, Turn off SC16ISxxx hardware flow control for the UARTx and enable AUTO-RTS to use the SC16ISxxx RTS pin for half-duplex DE/RE direction switching on the driver chip.

Peter.zupancic

Joined Dec 22, 2021
7
What are register in this case? I dont know what or how to use it from datasheet.

nsaspook

Joined Aug 27, 2009
9,729
Extra Features Control Register (EFCR):
BIT 4 RTSCON Enable the transmitter to control the RTS pin. 0: transmitter does not control RTS pin 1: transmitter controls RTS pin

Enhanced Features Register (EFR)
BIT 7 EFR[7] CTS flow control enable. logic 0 = CTS flow control is disabled (normal default condition) logic 1 = CTS flow control is enabled. Transmission will stop when a HIGH signal is detected on the CTS pin.
BIT 6 EFR[6] RTS flow control enable. logic 0 = RTS flow control is disabled (normal default condition) logic 1 = RTS flow control is enabled. The RTS pin goes HIGH when the receiver FIFO halt trigger level TCR[3:0] is reached, and goes LOW when the receiver FIFO resume transmission trigger level TCR[7:4] is reached.

https://www.nxp.com/docs/en/data-sheet/SC16IS752_SC16IS762.pdf
9.1 Auto RS-485 RTS control Normally the RTS pin is controlled by MCR bit 1, or if hardware flow control is enabled, the logic state of the RTS pin is controlled by the hardware flow control circuitry. EFCR register bit 4 will take the precedence over the other two modes; once this bit is set, the transmitter will control the state of the RTS pin. The transmitter automatically asserts the RTS pin (logic 0) once the host writes data to the transmit FIFO, and de-asserts RTS pin (logic 1) once the last bit of the data has been transmitted. To use the auto RS-485 RTS mode the software would have to disable the hardware flow control function.

nsaspook

Joined Aug 27, 2009
9,729
Modify (add a line) this routine to set bit 4 when the tx_enable is true might work.
C:
void SC16IS752::EnableTransmit(uint8_t channel, uint8_t tx_enable)
{
uint8_t temp_efcr;
temp_efcr = ReadRegister(channel, SC16IS750_REG_EFCR);
if ( tx_enable == 0) {
temp_efcr |= 0x04;
} else {
temp_efcr &= 0xFB; // true
}
WriteRegister(channel, SC16IS750_REG_EFCR,temp_efcr);

return;
}
temp_efcr |= 0x10; // set bit 4 to high for auto RS-485 RTS direction control

Peter.zupancic

Joined Dec 22, 2021
7
Should I just call somewhere function EnableTransmit and should work? Lot od functions here are not in use, dont know why.

nsaspook

Joined Aug 27, 2009
9,729
Should I just call somewhere function EnableTransmit and should work? Lot od functions here are not in use, dont know why.
I can't do it for you. It's time for you to look at the code, functions and to understand what to do now.

Peter.zupancic

Joined Dec 22, 2021
7
For ecample;
BIT 4 RTSCON Enable the transmitter to control the RTS pin. 0: transmitter does not control RTS pin 1: transmitter controls RTS pin

How would I write it?
temp_lcr &= 0x4 ; ? Meaning bit 4?
WriteRegister(channel, SC16IS750_REG_EFCR, temp_lcr);

I dont know how to use those registers, I understand need to change bit 4 to 1 but where I define value 1?