LPC54114 RTS not toggling RS485 output enable

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

LPC54114 RTS not toggling RS485 output enable

Jump to solution
1,171 Views
mbressler
Contributor II

I've been working at getting the RTS pin on the LPC54114 to serve as hardware flow control for the RS485 driver's output enable (henceforth referred to as OE) and receiver enable (RE) pins. On the module, the OE and RE are tied together so that when you pull it HIGH, the transmitter is enabled, and when LOW the receiver is enable.

Despite my best efforts, I have not been able to get the flexcomm driver to handle this automatically and have had to resort to a function that wraps around the USART_WriteBlocking and uses GPIO to manually pull the RTS pin high before any send and then bring it back low once done.

I tried directly changing the OESEL and OEPOL bits by calling lots of variations of the below code either directly after the RESET_PeripheralReset call and after the USART_Init call in peripheral.c

USART2->CFG |= (1 << 20);‍
USART2->CFG |= (1 << 21);‍‍

Successful send and receive when using GPIO to toggle RTS

successful_logic_recording.PNG

Failed send and receive when using above bit flags, RTS is not pulled high for output enable

failed_logic_recording.PNG

Pin tool routing

routed_pins.PNG

Peripherals tool config

peripheral_config.PNG

/**
 * @file    LPC54114J256_RS485_RTS.cpp
 * @brief   Application entry point.
 */
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "LPC54114_cm4.h"
#include "fsl_debug_console.h"
#include "fsl_crc.h"

constexpr uint8_t buz[] = {0x53, 0x7F, 0x0D, 0x00, 0x04, 0x6A, 0x00, 0x02, 0x02, 0x01, 0x03, 0x9B, 0x0E};
constexpr uint8_t start_bit[] = {0xFF};

crc_config_t crc_config = {kCRC_Polynomial_CRC_CCITT, 0, 0, 0, 0, 0x1D0F};
uint8_t reply_buffer[128];



/*
 * @brief   Application entry point.
 */
int main(void) {
     // Init board hardware.
     BOARD_InitBootPins();
     BOARD_InitBootClocks();
     BOARD_InitBootPeripherals();
     BOARD_InitDebugConsole();

     printf("Hello World\n");

     USART_WriteBlocking(USART2, start_bit, 1);
     USART_WriteBlocking(USART2, buz, sizeof(buz));

     while (1) {
          USART_ReadBlocking(USART2, reply_buffer, 1);
          printf("0x%02X\n", reply_buffer[0]);
     }

     printf("Done\n");
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

/***********************************************************************************************************************
 * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
 * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
 **********************************************************************************************************************/

/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Peripherals v4.1
processor: LPC54114J256
package_id: LPC54114J256BD64
mcu_data: ksdk2_0
processor_version: 4.0.0
board: LPCXpresso54114
functionalGroups:
- name: BOARD_InitPeripherals
  called_from_default_init: true
  selectedCore: cm4
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/

/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
component:
- type: 'system'
- type_id: 'system_54b53072540eeeb8f8e9343e71f28176'
- global_system_definitions: []
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */

/***********************************************************************************************************************
 * Included files
 **********************************************************************************************************************/
#include "peripherals.h"

/***********************************************************************************************************************
 * BOARD_InitPeripherals functional group
 **********************************************************************************************************************/
/***********************************************************************************************************************
 * RS485 initialization code
 **********************************************************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
instance:
- name: 'RS485'
- type: 'flexcomm_usart'
- mode: 'polling'
- type_id: 'flexcomm_usart_fcc110cc6b16332e9dfd9e0df675e21f'
- functional_group: 'BOARD_InitPeripherals'
- peripheral: 'FLEXCOMM2'
- config_sets:
  - usartConfig_t:
    - usartConfig:
      - clockSource: 'FXCOMFunctionClock'
      - clockSourceFreq: 'GetFreq'
      - baudRate_Bps: '9600'
      - parityMode: 'kUSART_ParityDisabled'
      - stopBitCount: 'kUSART_OneStopBit'
      - bitCountPerChar: 'kUSART_8BitsPerChar'
      - loopback: 'false'
      - txWatermark: 'kUSART_TxFifo0'
      - rxWatermark: 'kUSART_RxFifo1'
      - enableRx: 'true'
      - enableTx: 'true'
    - quick_selection: 'QuickSelection5'
 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
const usart_config_t RS485_config = {
  .baudRate_Bps = 9600,
  .parityMode = kUSART_ParityDisabled,
  .stopBitCount = kUSART_OneStopBit,
  .bitCountPerChar = kUSART_8BitsPerChar,
  .loopback = false,
  .txWatermark = kUSART_TxFifo0,
  .rxWatermark = kUSART_RxFifo1,
  .enableRx = true,
  .enableTx = true
};

void RS485_init(void) {
  /* Reset FLEXCOMM device */
  RESET_PeripheralReset(kFC2_RST_SHIFT_RSTn);
  USART_Init(RS485_PERIPHERAL, &RS485_config, RS485_CLOCK_SOURCE);
}

/***********************************************************************************************************************
 * Initialization functions
 **********************************************************************************************************************/
void BOARD_InitPeripherals(void)
{
  /* Initialize components */
  RS485_init();
}

/***********************************************************************************************************************
 * BOARD_InitBootPeripherals function
 **********************************************************************************************************************/
void BOARD_InitBootPeripherals(void)
{
  BOARD_InitPeripherals();
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I've been told by higher ups that using GPIO to toggle RTS is a hack and not acceptable that they picked this chip because they believed it could handle 8 UARTs with automatic hardware flow control.

EDIT: Added screenshots of Pin tool and Peripherals tool

Labels (2)
1 Solution
858 Views
mbressler
Contributor II

So, consider this solved, it was a matter of placing the bit flags for the OESEL and OEPOL configuration after the USART_Init method and not before.

Turns out the USART_Init method sets the whole CFG register and not just the flags it's concerned with (=  vs |=), so I moved the

USART2->CFG |= (1 << 20) | (1 << 21);‍

to just after the USART_Init and it works now.

success_rs485_rts.png

View solution in original post

0 Kudos
Reply
2 Replies
858 Views
jeremyzhou
NXP Employee
NXP Employee

Hi ,

Good to hear the issue is sloved.:smileyhappy:
Have a great day,
TIC

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

859 Views
mbressler
Contributor II

So, consider this solved, it was a matter of placing the bit flags for the OESEL and OEPOL configuration after the USART_Init method and not before.

Turns out the USART_Init method sets the whole CFG register and not just the flags it's concerned with (=  vs |=), so I moved the

USART2->CFG |= (1 << 20) | (1 << 21);‍

to just after the USART_Init and it works now.

success_rs485_rts.png

0 Kudos
Reply