AnsweredAssumed Answered

LPC54114 RTS not toggling RS485 output enable

Question asked by Marc Bressler on Jul 2, 2018
Latest reply on Jul 3, 2018 by jeremyzhou

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 send and receive when toggling RTS via GPIO

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

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

Pin tool routing

Pin tool view

Peripherals tool config

Peripherals tool config

/**
* @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

Outcomes