Author Topic: Kinetis K60 RS-485 receiving or sending but not both  (Read 10362 times)

Offline kingston

  • Newbie
  • *
  • Posts: 26
    • View Profile
Kinetis K60 RS-485 receiving or sending but not both
« on: March 12, 2013, 02:33:52 PM »
Hey all,

I currently have to program a test for the rs-485 interface on our hardware but can't get it to work properly.
After reading the Kinetis Demo document it looks like my hardware should support automatic switching between RX and TX but I can't get it to work...
In my current configuration I can only receive characters but it will never send.


The initialisation code is as follows:
Code: [Select]
extern QUEUE_HANDLE fnSetNewSerialMode485(unsigned char ucDriverMode) {
TTYTABLE tInterfaceParameters; // table for passing information to driver
tInterfaceParameters.Channel = 2; // set UART channel for serial use
tInterfaceParameters.ucSpeed = temp_pars->temp_parameters.ucSerialSpeed; // baud rate
tInterfaceParameters.Rx_tx_sizes.RxQueueSize = RX_BUFFER_SIZE; // input buffer size
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = TX_BUFFER_SIZE; // output buffer size
tInterfaceParameters.Task_to_wake = OWN_TASK; // wake self when messages have been received
tInterfaceParameters.Config = (CHAR_MODE | CHAR_8 | ECHO_RX_CHARS | SET_RS485_MODE | SET_RS485_NEG | NO_PARITY | ONE_STOP | NO_HANDSHAKE );

if ((SerialPort485ID = fnOpen(TYPE_TTY, FOR_I_O, &tInterfaceParameters))
!= 0) { // open or change the channel with defined configurations (initially inactive)
fnDriver(SerialPort485ID, (TX_ON | RX_ON ), 0); // enable rx and tx

}
return SerialPort485ID;
}

On receive my Tasks wakes up prints the received characters and should send a "Hello" with following function:
Code: [Select]
QUEUE_TRANSFER fnSend485Msg(unsigned char * cToSend) {
return (fnPrint((unsigned char *) cToSend, SerialPort485ID)); // send to UART2
}

I never receive the "Hello" on the pc-side. With another configuration (which i lost after playing around too much...) I received the "Hello" on the pc-side but couldn't receive on the K60. For me it looks like the control-lines aren't switching like they should but I even tried the example with manual switching of the lines and it doesn't work either.
Maybe someone has an idea what I'm doing wrong?

Offline kingston

  • Newbie
  • *
  • Posts: 26
    • View Profile
Re: Kinetis K60 RS-485 receiving or sending but not both
« Reply #1 on: March 13, 2013, 01:17:33 PM »
Ok looks like I found the problem:

For the initialisation of the UART the function fnConfigSCI() in kinetis.c gets called.
In the function there is only an if-statement which checks the RTS_CTS configuration:
Code: [Select]
if (pars->Config & RTS_CTS) {                                        // HW flow control defined so configure RTS/CTS pins
        fnControlLine(Channel, (CONFIG_RTS_PIN | CONFIG_CTS_PIN), 0);
    }

As you stated here http://www.utasker.com/forum/index.php?topic=692.msg3048#msg3048 "".. the serial interface must not be configured for RTS/CTS flow control operation" when the RTS is to control RS485."

I added a second if-statement to kinetis.c:
Code: [Select]
if (pars->Config & SET_RS485_MODE) {                                        // RS485-Mode defined so configure RTS Control
        fnControlLine(Channel, (SET_RS485_MODE | CONFIG_RTS_PIN), 0);
    }

Now the automatic switching works and I can communicate.

I hope this helps others with similiar problems.

The way I understand the code is that it could have never worked without the second if-statement because the RS458 settings are completely ignored.
Am I right or did I get something wrong? :)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Kinetis K60 RS-485 receiving or sending but not both
« Reply #2 on: March 17, 2013, 12:43:55 PM »
Hi

I just looked into this and found the following:

1) When the mode is set to RTS_CTS the RTS and CTS lines are set to their corresponding peripheral mode when the interface is opened. This is what you have seen, but when not using RTS_CTS mode (but using SET_RS485_MODE) this doesn't happen.
The reason for this is because the RS485 mode (based on RTS signal controlling the RS485 direction) doesn't need the CTS line to be configured.

2) SET_RS485_MODE is in fact not a mode configuration but instead is a configuration "command".
It is used in a similar way to enabling the receiver and/or transmitter:

fnDriver(SerialPortID, (TX_ON | RX_ON), 0);        // enable rx and tx
with
fnDriver(SerialPortID, (MODIFY_CONTROL | CONFIG_RTS_PIN | SET_RS485_MODE), 0);
or
fnDriver(SerialPortID, (MODIFY_CONTROL | CONFIG_RTS_PIN | SET_RS485_MODE | SET_RS485_NEG), 0);

That means that the command can be used after the interface has been opened to configure the RTS pin, set the RS485 mode and also set the polarity of the RTS control signal in this mode.

Your modification is essentially doing the same as the call above does, but within the open function.

See page 15 of the document: http://www.utasker.com/docs/uTasker/uTaskerUART.PDF which also illustrates the method.

Regards

Mark

P.S. I notice that you set ECHO_RX_CHARS but I am not sure that this is suitable for RS485 mode because the receiver will immediately send back each character when it is received (in its interrupt routine). If you receive data with no spaces between characters I could imaging that the echo will cause following characters to be lost since the RS485 direction will immediately be set to transmission for the character time.
If only 'typed' input is being received this probably wouldn't matter since the echo would be much faster than the next character reception.


« Last Edit: March 17, 2013, 12:48:04 PM by mark »

Offline kingston

  • Newbie
  • *
  • Posts: 26
    • View Profile
Re: Kinetis K60 RS-485 receiving or sending but not both
« Reply #3 on: March 18, 2013, 10:01:19 AM »
Thanks mark for your explanation!
I read the UART documentation but as stated on page 15
"Code 9 shows a method of controlling the RTS signal together with processors which do not have a HW setting to automatically control it"
So I thought it wasn't necessary for the K60.
I removed my changes in kinetis.c and tried the fnDriver function and it really does the same!

I'm really sorry for questioning your code but somehow I must have overread the right configuration commands ;)

Paul

P.S. The ECHO_RX_CHARS was only set for testing purposes it is gone now and everything works fine!
      Thank You!

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Kinetis K60 RS-485 receiving or sending but not both
« Reply #4 on: March 18, 2013, 11:17:35 AM »
Hi Paul

Thanks for the feedback - I think that I should change the remark in the document since it is doesn't look correct for the Kinetis (maybe it was the case for other processor types but I think that at least the pins should be configured explicitly).

Regards

Mark