Author Topic: UART Tx/Rx in different pins for KL03  (Read 4014 times)

Offline Raffaele

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
UART Tx/Rx in different pins for KL03
« on: January 09, 2020, 12:24:09 AM »
Hi,
is it possible to set up the LPUART Tx and Rx on two different pins in the KL03? I tried something like the following code, I can transfer but not receive. I don't know if my receive routine is correct:


Code: [Select]
#include "config.h"

#define SET_UART_PORT() _CONFIG_PERIPHERAL(B, 3,  (PB_3_LPUART0_TX | UART_PULL_UPS ));\
_CONFIG_PERIPHERAL(B, 1,  (PB_1_LPUART0_RX | UART_PULL_UPS ));


#define SERIAL_INTERFACE

static int iState = 0;

static void fn_process_data() {
         unsigned char ucInputByte;
while (fnRead( SerialPortID, &ucInputByte, 1) != 0) {
while (ucInputByte--) {
fnDebugMsg("\r\n");
fnDebugDec(ucInputByte, 0);
}
}
}


extern void fnTaskMyUartToSPI(TTASKTABLE *ptrTaskTable) {
switch (iState) {

case 0 :

SET_UART_PORT();

TTYTABLE tInterfaceParameters; // table for passing information to driver
QUEUE_HANDLE SerialPortID; // UART handle to be obtained during open
tInterfaceParameters.Channel = 0; // set UART channel for serial use
tInterfaceParameters.ucSpeed = SERIAL_BAUD_115200;
tInterfaceParameters.Rx_tx_sizes.RxQueueSize = 256; // input buffer size
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = 512; // output buffer size
tInterfaceParameters.Task_to_wake = TASK_MY_UART_TO_SPI; // wake task on rx
#ifdef SUPPORT_FLOW_HIGH_LOW
tInterfaceParameters.ucFlowHighWater = 80; // set the flow control high in %
    tInterfaceParameters.ucFlowLowWater = 20; // set the flow control low in %
#endif
tInterfaceParameters.Config = (CHAR_8 + NO_PARITY + ONE_STOP +  CHAR_MODE);

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

DebugHandle = SerialPortID;

iState = 1;
break;


case 1 :
fn_process_data();
break;
}
}

« Last Edit: January 09, 2020, 06:44:56 AM by Raffaele »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: UART Tx/Rx in different pins for KL03
« Reply #1 on: January 09, 2020, 12:59:58 AM »
Hi

The default ports for the KL03 UART0 are
_CONFIG_PERIPHERAL(B, 1, (PB_1_UART0_TX | UART_PULL_UPS));   // UART0_TX on PB1 (alt. function 2)
_CONFIG_PERIPHERAL(B, 2, (PB_2_UART0_RX | UART_PULL_UPS));   // UART0_RX on PB2 (alt. function 2)

It is possible to configure other pins instead but the Kinetis user's manual states that no peripheral should be connected to more that one pin at the same time since undefined behavior may result.
I suspect that configuring two pins for Tx may allow the output to appear on both but if two Rx pins are configured there are likely to cause conflicts and so not work.

Regards

Mark

Offline Raffaele

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Re: UART Tx/Rx in different pins for KL03
« Reply #2 on: January 09, 2020, 01:15:06 AM »
thanks Mark,

I'm not trying to configure two Rx or two Tx pins. Still one Tx and one Rx but not on the default ports. Would that work?
I am not sure if I properly defined the function that is activated when bytes are received. As reported in my first part, I wake my own task Task_to_wake = MY_UART_TASK that calls a function that should read the UART.

I also tried to read the UART, using fnRead(SerialPortIDRx, rxMsg, 1); periodically instead of waiting for data but it looks like there are no bytes in on the UART. It could also be that I am not enabling some necessary defines or configs
« Last Edit: January 09, 2020, 06:47:19 AM by Raffaele »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: UART Tx/Rx in different pins for KL03
« Reply #3 on: January 09, 2020, 10:35:15 PM »
Raffaele

This is the set of pin options for LPUART1 that can be selected:


            #if defined LPUART0_ON_A
            _CONFIG_PERIPHERAL(A, 4, (PA_4_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PA4 (alt. function 4)
            #elif defined LPUART0_ON_B_HIGH
            _CONFIG_PERIPHERAL(B, 4, (PB_4_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB4 (alt. function 3)
            #elif defined LPUART0_ON_B_ALT
            _CONFIG_PERIPHERAL(B, 1, (PB_1_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB1 (alt. function 3)
            #else
            _CONFIG_PERIPHERAL(B, 2, (PB_2_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB2 (alt. function 2)
            #endif


            #if defined LPUART0_ON_A
            _CONFIG_PERIPHERAL(A, 3, (PA_3_LPUART0_TX | UART_PULL_UPS)); // LPUART0_TX on PA3 (alt. function 4)
            #elif defined LPUART0_ON_B_HIGH
            _CONFIG_PERIPHERAL(B, 3, (PB_3_LPUART0_TX | UART_PULL_UPS)); // LPUART0_TX on PB2 (alt. function 3)
            #elif defined LPUART0_ON_B_ALT
            _CONFIG_PERIPHERAL(B, 2, (PB_2_LPUART0_TX | UART_PULL_UPS)); // LPUART0_TX on PB2 (alt. function 3)
            #else
            _CONFIG_PERIPHERAL(B, 1, (PB_1_LPUART0_TX | UART_PULL_UPS)); // LPUART0_TX on PB1 (alt. function 2)
            #endif


What you presumably require is
_CONFIG_PERIPHERAL(B, 3, (PB_3_LPUART0_TX | UART_PULL_UPS)); // LPUART0_TX on PB2 (alt. function 3)
and
_CONFIG_PERIPHERAL(B, 1, (PB_1_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB1 (alt. function 3)
 which is not a pair as defined above but could be added as follows:

            #if defined LPUART0_ON_A
            _CONFIG_PERIPHERAL(A, 4, (PA_4_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PA4 (alt. function 4)
            #elif defined LPUART0_ON_B_HIGH && !defined LPUART_OPTION_1
            _CONFIG_PERIPHERAL(B, 4, (PB_4_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB4 (alt. function 3)
            #elif defined LPUART0_ON_B_ALT
            _CONFIG_PERIPHERAL(B, 1, (PB_1_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB1 (alt. function 3)
            #else
            _CONFIG_PERIPHERAL(B, 2, (PB_2_LPUART0_RX | UART_PULL_UPS)); // LPUART0_RX on PB2 (alt. function 2)
            #endif


and selected with:
#define LPUART0_ON_B_HIGH
#define LPUART0_ON_B_ALT
#define LPUART_OPTION_1


If you think that there is a problem with the code performing reception try using the
#define HELLO_WORLD
configuration to verify the operation - it will print a "Hello, World" message and then respond to input and should prove the operation and configuration on the HW before using different code.

Regards

Mark


Offline Raffaele

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Re: UART Tx/Rx in different pins for KL03
« Reply #4 on: January 10, 2020, 06:34:56 PM »
Hi Mark,

I was able to make it work, my code works now as far as I keep the HELLO_WORLD activated
« Last Edit: January 10, 2020, 10:14:32 PM by Raffaele »

Offline Raffaele

  • Jr. Member
  • **
  • Posts: 65
    • View Profile
Re: UART Tx/Rx in different pins for KL03
« Reply #5 on: January 11, 2020, 12:23:10 AM »
Hey Mark,
 
I see how the APPLICATION TASK uses the QUEUE_HANDLE fnSetNewSerialMode(unsigned char ucDriverMode) to set up the UART and if I change the task to wake in this function to TASK_MY_UART I can use my task upon receiving UART data.

However, all this works only if I keep HELLO_WORLD active.
I tried to have the same configs of hello_world and replicate a similar TTYTABLE with tInterfaceParameters.Task_to_wake = TASK_MY_UART  in my task, commented the HELLO_WORLD, but it doesn't work.

Any ideas why?

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: UART Tx/Rx in different pins for KL03
« Reply #6 on: January 11, 2020, 03:16:24 PM »
Raffaele

If
#define SERIAL_INTERFACE                                                 // enable serial interface driver
is defined and the same code is used I would expect identical behavior.

Regards

Mark