Can a PE Serial component be set up for HalfDuplex single Tx pin

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

Can a PE Serial component be set up for HalfDuplex single Tx pin

Jump to solution
945 Views
neilhancock
Contributor IV

Can I set up a SerialComponent for RS485 HalfDuplex using a single Tx pin of a Uart.?

 

For a Cpu:MKL26Z128VFT4 part, I'm looking to use UART0 as HalfDuplex RS485. Uart0 as its low power.

From the manual registers I think this means setting

Uart0_S2: set LOOPS=RSRC=1

and then managing the single pin with

Uart0_C3:TXDIR 1 Tx Output else 0 Rx Input

I have tried using the PE AsynchroSerial  - and as noted in a previous post when I try and use the provided Loop command it has an error

Labels (1)
1 Solution
624 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Neil:

On a closer inspection, I realized that the Serial_LDD component does not support single-wire mode and this is confirmed by colleague Marek Neuzil in this thread: Single-wire UART on KL26Z ???

The error with AsynchroSerial component is indeed a bug already reported to the developers (ticket PEXMCU-3612). But even with no error, the loop mode actually refers to an internal loop or echo (LOOPS = 1, RSRC = 0), not to single-wire mode.

I think you can actually make single-wire work and your workaround is good (using UART0_PDD_SetLoopMode and UART0_PDD_SetTxPinDataDirection). Just make sure to change the pin direction before calling the SendBlock or ReceiveBlock methods.

As for the pin, you are right that the component requires the RX pin, but this is a minor issue. If you require the pin for another peripheral, you can enable "Pin Sharing" as shown below:

pastedImage_3.png

Then use the API ConnectPin() provided with the corresponding peripheral component. This API will be called only once, since the UART will not use the RX pin.

I hope my comments help.

Regards!

Jorge Gonzalez

View solution in original post

0 Kudos
5 Replies
624 Views
neilhancock
Contributor IV

THanks Jorge, I'm using the workaround as described

The ability to share the pin was what I was missing.

So I use asyncrhoSerial  and call it "AScust" and use a prefix for all my code calls "csm_"

I init  component asyncrhoSerial  from PE_low_level_init();

then call a local init performing

csm_init

void csm_init (){

  //AScust.c manages Bare metal standard

  // Uart0 - low power is initialized as Single Wire

  //Uart0_S2: set LOOPS=RSRC=1

  //Uart0_C3:TXDIR 1 Tx Output else 0 Rx Input

    UART0_PDD_SetLoopMode(ASLdd2_BP, UART0_PDD_LOOP_MODE_RX_TO_TX_PIN);

  UART0_PDD_SetTxPinDataDirection(ASLdd2_BP, 0);

}

then to receive - standard "listening state" using low power RS485 MAX3471

void csm_LineRxActive (){ //revert to receive after all data sent.

  //AScust_TurnTxOff();

  rs485RxEnN_ClrVal(NULL);

  rs485OutEn_ClrVal(NULL);

  UART0_PDD_SetTxPinDataDirection(ASLdd2_BP, 0);

}

and then when required to tx

void csm_LineTxOn(){ //Send enable

  //AScust_TurnTxOn();

  rs485RxEnN_SetVal(NULL); // doesn't matter but '1' good

  rs485OutEn_SetVal(NULL);

  UART0_PDD_SetTxPinDataDirection(ASLdd2_BP, UART0_C3_TXDIR_MASK);

}

to Tx RS485- which requires turning on the RS485 Out and sending the block

byte csm_SendBlock(byte *Ptr, word Size, word *pSnd) {

  csm_LineTxOn();

  if (ERR_OK !=  AScust_SendBlock(Ptr, Size, pSnd)) {

  //TODO error

  }

}

and then for handling the end of the buffer transmission

void csm_OnTxComplete() {

  csm_LineRxActive ();//Make ready to receive

}

which requires an entry in Events.c

/*

** ===================================================================

**     Event       :  AScust_OnTxComplete (module Events)

**

**     Component   :  AScust [AsynchroSerial]

**     Description :

**         This event indicates that the transmitter is finished

**         transmitting all data, preamble, and break characters and is

**         idle. It can be used to determine when it is safe to switch

**         a line driver (e.g. in RS-485 applications).

**         The event is available only when both <Interrupt

**         service/event> and <Transmitter> properties are enabled.

**     Parameters  : None

**     Returns     : Nothing

** ===================================================================

*/

void AScust_OnTxComplete(void){

  csm_OnTxComplete();

}

624 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Looks good Neil! :smileyhappy:

Thank you for sharing your code. This might be useful for others looking for the same functionality with Processor Expert.

Regards!

Jorge Gonzalez

0 Kudos
624 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Neil:

I checked your other thread. As noted by colleague Alice in your other thread (here: Failure with Serial_LDD:LoopMode ) it seems to be a bug with Asynchroserial component. As workaround you can use the Serial_LDD component alone.

The settings of an inherited component are often grayed out when the top component has control over those settings and not the user.

Regards!

Jorge Gonzalez

0 Kudos
624 Views
neilhancock
Contributor IV

Hello Jorge

Yes thanks for the note - I'm phrasing the issues I'm seeing as the user  - I'm not always sure what is related.

In this case, I'm trying to check if I am missing something with the PE components.

The hardware supports the ability to use a single pin Tx for both duplex Tx and Rx, and I've proved it works on real hardware with an RS485 interface.

The PE component appears to require the hardware Rx pin to be always assigned a real chip pin - no way to say that the Rx signal is assigned to the Tx pin for half-duplex mode.

The other thread (here: Failure with Serial_LDD:LoopMode ) is reporting a KDS300 PE script failure.

 

I have a workaround identified in hardware integration testing for both of these issues, but when I go to do real code, it looks like I will have to cut-and-slice the PE code to make it work for me. Bit of a bummer for all the hardwork that goes into the PE autogenerated framework - and since its a fudge, a work around, I probably won't publish it as open source as its harder to understand.

I've actually had some bigger issues with a KDS300 project corruption and having to restore it from a backup - but based on current discussion doesn't seem like there is much interest in KDS300 feedback,

On the whole KDS300 is 99.9% amazing, but like most software that 0.1% is challenging

Thanks again for the heads up.

0 Kudos
625 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Neil:

On a closer inspection, I realized that the Serial_LDD component does not support single-wire mode and this is confirmed by colleague Marek Neuzil in this thread: Single-wire UART on KL26Z ???

The error with AsynchroSerial component is indeed a bug already reported to the developers (ticket PEXMCU-3612). But even with no error, the loop mode actually refers to an internal loop or echo (LOOPS = 1, RSRC = 0), not to single-wire mode.

I think you can actually make single-wire work and your workaround is good (using UART0_PDD_SetLoopMode and UART0_PDD_SetTxPinDataDirection). Just make sure to change the pin direction before calling the SendBlock or ReceiveBlock methods.

As for the pin, you are right that the component requires the RX pin, but this is a minor issue. If you require the pin for another peripheral, you can enable "Pin Sharing" as shown below:

pastedImage_3.png

Then use the API ConnectPin() provided with the corresponding peripheral component. This API will be called only once, since the UART will not use the RX pin.

I hope my comments help.

Regards!

Jorge Gonzalez

0 Kudos