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
Failed send and receive when using above bit flags, RTS is not pulled high for output enable
Pin tool routing
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
Solved! Go to Solution.
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.
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!
-----------------------------------------------------------------------------------------------------------------------
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.