UART Flow control, K64

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

UART Flow control, K64

2,236 Views
roymessinger
Contributor V

From looking at various posts, I've understood there is no HW flow support for UART. I'm working with KSDK 2.1 (I've read no support for earlier versions).

Nevertheless, in MK64F12.h there's:

/* @brief Hardware flow control (RTS, CTS) is supported. */
#define FSL_FEATURE_UART_HAS_MODEM_SUPPORT (1)

1. So, does it mean there is HW Flow support?

2. How do I use it?

I  connected TX_Enable to pin 71, PTC1 (UART1_RTS), still I do not get any uart interrupt... (Where as in FRDM board all is ok). I defined this pin to be a UART1_RTS functionality)

Any idea?

Update:

See more info below. It seems the RTS is high (even though I tried changing its polarity), and by that avoiding data from being received by the chip. Mystery....

Roy

pastedImage_1.png

0 Kudos
11 Replies

1,352 Views
Robin_Shen
NXP TechSupport
NXP TechSupport

Hi

If your project works flawlessly on the FRDM board but not with my custom board. Are there any difference between FRDM board and the custom board?

Have you check the mask of the MCU on your custom board?

MASK K64.png

For the 1N83J mask, e4647: UART: Flow control timing issue can result in loss of characters if FIFO is not enabled

e4647 1N83J.png

About the Hardware flow control, you can refer the uart_txrts_test() in attached "uart_flow_control_tests.c"file.

Best Regards,

Robin

 

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

1,352 Views
roymessinger
Contributor V

Thankd Robin & Mark. Once I've swapped between R188 and R189 like a typical RS485 half duplex comm. it all went fine and all is working.

Thanks for the test file. I will keep it... ;-) 

Roy

0 Kudos

1,352 Views
mjbcswitzerland
Specialist V

Hi

The K64 has a modem register which controls some part of RTS/CTS HW flow control automatically.
Eg. Set TXCTSE in UARTx_MODEM register and it will only send when the CTS input is asserted.
You can control the RTS output with the RXRTSE bit in the same register.

Some background:
http://www.utasker.com/docs/uTasker/uTaskerUART.PDF

I do it in the uTasker project with:

tInterfaceParameters.Config |= RTS_CTS;                              // enable RTS/CTS operation (HW flow control)

if ((SerialPortID = fnOpen(TYPE_TTY, ucDriverMode, &tInterfaceParameters)) != NO_ID_ALLOCATED) { // open or change the channel with defined configurations (initially inactive)
    fnDriver(SerialPortID, (TX_ON | RX_ON), 0);                      // enable rx and tx
    if ((tInterfaceParameters.Config & RTS_CTS) != 0) {              // if HW flow control is being used
        fnDriver(SerialPortID, (MODIFY_INTERRUPT | ENABLE_CTS_CHANGE), 0); // activate CTS operation when working with HW flow control
        fnDriver(SerialPortID, (MODIFY_CONTROL | SET_RTS), 0);       // activate RTS line when working with HW flow control
    }
}

Regards

Mark


Professional support for Kinetis: http://www.utasker.com/index.html
Remote desktop one-on-one coaching: http://www.utasker.com/services.html
Getting started to expert videos: https://www.youtube.com/results?search_query=utasker+shorts

0 Kudos

1,352 Views
roymessinger
Contributor V

Thanks,

I'm using the RTS only (you can have a look at my elec. scheme above). so I wanted to configure the TXRTSE register.

If I'm writing straight to the registers:

UART1->S1 & UART_MODEM_TXRTSPOL(1); //setting it as active high
UART1->S1 & UART_MODEM_TXRTSE(1);

1. Is this the correct way to do it?

2. If so, when I connect a scope, I see the RTS line is getting high right pass this line:

PORT_SetPinMux(PORTC, PIN1_IDX, kPORT_MuxAlt3); /* PORTC1 (pin 71) is configured as UART1_RTS_b */

which is strange by itself (why does setting this pin as a RTS asserted it to '1'?),

and also, it stays there as '1' for good (why did my previous lines did not changed it back to '0'?)

Roy

0 Kudos

1,352 Views
mjbcswitzerland
Specialist V

Hi

I think that the subject is in fact RS485 mode rather than HW flow control since you are using the RTS to control the transceiver's drive. This is described in Chapter 8 of the document that I linked to.
The code to do it is very simple since this is automatically controlled by the UART.

_CONFIG_PERIPHERAL(C, 1, (PC_1_UART1_RTS));
UART1_MODEM = (UART_MODEM_TXRTSE | UART_MODEM_TXRTSPOL);

Regards

Mark


Professional support for Kinetis: http://www.utasker.com/index.html
Remote desktop one-on-one coaching: http://www.utasker.com/services.html
Getting started to expert videos: https://www.youtube.com/results?search_query=utasker+shorts

0 Kudos

1,352 Views
roymessinger
Contributor V

Ok, a newbie question here... When you write:

UART1_MODEM = (UART_MODEM_TXRTSE | UART_MODEM_TXRTSPOL);

Don't you need to pass a parameter to the UART_MODEM_TXRTSE and UART_MODEM_TXRTSPOL?

as writte in the h file:

#define UART_MODEM_TXRTSE(x)                     (((uint8_t)(((uint8_t)(x)) << UART_MODEM_TXRTSE_SHIFT)) & UART_MODEM_TXRTSE_MASK)

?

0 Kudos

1,352 Views
mjbcswitzerland
Specialist V

Roy

It depends on how the macros are defined. I use

#define UART_MODEM_TXRTSE          0x02    // transmit request-to-send enable
#define UART_MODEM_TXRTSPOL        0x04    // transmit request-to-send polarity

In your case

#define UART_MODEM_TXRTSE(x)                     (((uint8_t)(((uint8_t)(x)) << UART_MODEM_TXRTSE_SHIFT)) & UART_MODEM_TXRTSE_MASK)

where supposedly UART_MODEM_TXRTSE_SHIFT is 1 and UART_MODEM_TXRTSE_MASK is 0x02, and you MUST use a value of x of 1 otherwise it will fail...

Your framework uses a certain philosophy which is possible over-complicated in this case and more prone to error since you also need to know what width the mask is and what 1, 0, etc. actually mean.

At the end of the day
UART1_MODEM = 0x06;

is what you want, sogar dann wenn die Macros versuchen "Knüppel zwischen die Beine werfen"..... [assuming you are of German tongue]

Regards

Mark

0 Kudos

1,352 Views
roymessinger
Contributor V

Thanks, Mark.

As I'm not working with uTasker I'm afraid your answer (UART1_MODEM ) is less good for me... And my project works flawlessly on the FRDM board but not with my custom board, which is pretty annoying.

Anyway, still I cannot communicate. As I've written earlier, the RTS line stays high indefinitely avoiding data from being received (it locks the transceiver on driver mode).

Roy

0 Kudos

1,352 Views
mjbcswitzerland
Specialist V

Roy

UART1_MODEM is not 'uTasker' - it is a physical register in the K64:

pastedImage_1.png

Using your headers it is probably

UART1->MODEM

Regards

Mark

0 Kudos

1,352 Views
roymessinger
Contributor V

Mark,

Sorry for my latest post, too tired yesterday, wrote some nonsense... Deleted it.

Anyway,

I wrote:

UART1->MODEM | UART_MODEM_TXRTSPOL(1) ;

UART1->MODEM |  UART_MODEM_TXRTSE(1);

This seems to work untill the data start passing. Once the first packet of data is passed (and I see it as the correct data), alot of garbage data is passing without stopping, and the RTS line keeps set and reset continously.

This phenomenon was shown also when I implemented the RTS by myself (without using the TXRTSE registers). The scope shows the RTS line goes up and down endlessly. If I disconnect the USB (I use USB to RS485 dongle, to a transceiver on my board:MAX3362EKA) it doesn't stop and keeps passing data.

pastedImage_1.jpg

Roy

0 Kudos

1,352 Views
mjbcswitzerland
Specialist V

Roy

UART1->S1 & UART_MODEM_TXRTSPOL(1) | UART_MODEM_TXRTSE(1);

This code looks to have nothing to do with setting the mode.
Why are you using the status register rather than the MODEM register?
If this is the real code it is just reading the status register and masking it with 0x06 which doesn't write anything to any register.

1. Write the value directly in the MODEM register in the register view and test the operation first so that you have a working reference.
2. Then write code to set the bits correctly. If you are having problem with the macros in your framework you can also simply do:
*(unsigned char *)0x4006b00d = 0x06;

Regards

Mark

0 Kudos