Hi.
I'm trying to utilize the hardware RTS, by enabling the RS485 mode of serial ports - but I'm unable to get it working. (please see datasheet http://www.atmel.com/Images/doc11057.pdf page 810 and 839). I'm writing USART1->US_MR to achieve this.
Here is what I tried:
#include <RS485_non_blocking.h> // Lib by by Nick Gammon, v1.0
#define RTS 23 // Pin used for RTS, PA14/D23
size_t fWrite (const byte what) // The write function of the RS485 class
{
return Serial2.write (what);
}
RS485 myChannel (NULL, NULL, fWrite, 0); // RS485 class, by Nick Gammon. Basically a wrapper class that complements data, makes checksums and handles packages in both transmit and recieve.
void setup ()
{
Serial.begin (115200); // USB UART for Serial monitor
Serial2.begin (115200); // USART1 for, RS485 communication
myChannel.begin (); // Class initializer: mallocs buffer, resets control flags.
unsigned int test = USART1->US_MR; // Read USART mode register
Serial.print(test,BIN); //Reads out as 0000 0000 0000 0000 0000 1000 1100 0000, i.e. Normal mode, 8bit, 1 stop, async.
Serial.println();
USART1->US_MR |= 0x00000001; // Set the mode to 0x1 = RS485
test = USART1->US_MR; // Check that the register was written (it can be write protected)
Serial.print(test,BIN); //Reads out as 0000 0000 0000 0000 0000 1000 1100 0001, i.e. RS485 mode, 8bit, 1 stop, async.
Serial.println();
pinMode(RTS,OUTPUT);//RTS pin as output.
} // end of setup
const byte msg [5] = {0x01,0x01,0x01,0x01,0x01}; // Random message
void loop ()
{
myChannel.sendMsg (msg, sizeof (msg)); // Send message as package, implements Serial2.write() when data has been packed.
delay (100); // limit loop speed
} // end of loop
This however does not toggle the RTS pin (D23/PA14) belongning to Serial2 (the SAM3x USART1).
I can toggle the pin myself, by calling:
PIOA->PIO_SODR=1<<14; //RTS pin to HIGH
myChannel.sendMsg (msg, sizeof (msg)); // Send message as package, implements Serial2.write() when data has been packed.
// Serial2.flush(); //Doesn't work yet, still bytes left to send
while(USART1->US_CSR & US_CSR_TXEMPTY != US_CSR_TXEMPTY){}; //Wait for transmit buffer to empty. Also exits before transmit complete
delayMicroseconds(150); // My busywait hack to ensure complete transmission
PIOA->PIO_CODR=1<<14; //Clear RTS pin
But this is really not what I want, I would much prefer it to be handled in hardware (since RTS seems to be present, at least on USART0=Serial1 and USART1=Serial2). I realize a patch has been made to implement Serial.flush() properly, but I'm aiming to control it in hardware.
I have considered whether it's due to PIOA pin multiplexing, PA14 can also be function TK, but it seems the #define for both TK and RTS1 is the same.
Any help would be greatly appreciated.
BR
Hnygaard