doc: renamed project

This commit is contained in:
SylvanArnold
2025-04-29 13:52:54 +02:00
committed by Sylvan Arnold
parent 244e516bd8
commit 32618389d1
985 changed files with 1 additions and 1 deletions

View File

@@ -0,0 +1,679 @@
/*
* Copyright (c) 2020-2023, Erich Styger
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "McuUart485.h"
#if McuUart485_CONFIG_USE_RS_485
#include "McuShell.h"
#include "McuRTOS.h"
#include "McuUtility.h"
#include "McuLog.h"
#include "McuGPIO.h"
#include <ctype.h> /* for isprint() */
#if McuLib_CONFIG_CPU_IS_ESP32
#include "esp_system.h"
#include "driver/uart.h"
#endif
#if !McuUart485_CONFIG_USE_HW_OE_RTS
static McuGPIO_Handle_t RS485_TxEn; /* LOW: Rx, HIGH: Tx */
void McuUart485_GPIO_RxEnable(void) {
McuGPIO_SetLow(RS485_TxEn);
#if McuLib_CONFIG_CPU_IS_RPxxxx
uart_get_hw(McuUart485_CONFIG_UART_DEVICE)->cr |= UART_UARTCR_RXE_BITS; /* enable receiver for half duplex communication */
#endif
}
void McuUart485_GPIO_TxEnable(void) {
#if McuLib_CONFIG_CPU_IS_RPxxxx
uart_get_hw(McuUart485_CONFIG_UART_DEVICE)->cr &= ~UART_UARTCR_RXE_BITS; /* disable receiver for half duplex communication */
#endif
McuGPIO_SetHigh(RS485_TxEn);
}
static void McuUart485_GPIO_Deinit(void) {
RS485_TxEn = McuGPIO_DeinitGPIO(RS485_TxEn);
}
static void McuUart485_GPIO_Init(void) {
McuGPIO_Config_t config;
McuGPIO_GetDefaultConfig(&config);
#if McuLib_CONFIG_CPU_IS_ESP32
config.hw.pin = McuUart485_CONFIG_TX_EN_GPIO;
#elif McuLib_CONFIG_CPU_IS_RPxxxx
config.hw.pin = McuUart485_CONFIG_TX_EN_PIN;
#else
config.hw.gpio = McuUart485_CONFIG_TX_EN_GPIO;
config.hw.port = McuUart485_CONFIG_TX_EN_PORT;
config.hw.pin = McuUart485_CONFIG_TX_EN_PIN;
#endif
config.isInput = false;
config.isHighOnInit = false; /* Tx disabled */
RS485_TxEn = McuGPIO_InitGPIO(&config);
McuUart485_GPIO_RxEnable();
}
#endif /* McuUart485_CONFIG_USE_HW_OE_RTS */
/* -------------------------------------------------------------------------------------- */
static QueueHandle_t RS485UartRxQueue; /* queue of the received bytes */
#if !McuUart485_CONFIG_USE_MODBUS /* shell response queue only used in non-Modbus mode */
static QueueHandle_t RS485UartResponseQueue; /* queue for the OK or NOK response */
#endif
#if McuUart485_CONFIG_USE_LOGGER
static bool McuUart485_doLogging = false; /* if logging is turned on or off */
#endif
void McuUart485_ClearRxQueue(void) {
xQueueReset(RS485UartRxQueue);
}
#if !McuUart485_CONFIG_USE_MODBUS
void McuUart485_ClearResponseQueue(void) {
xQueueReset(RS485UartResponseQueue);
}
#endif
uint8_t McuUart485_GetRxQueueByte(unsigned char *data, TickType_t ticksToWait) {
if (xQueueReceive(RS485UartRxQueue, data, ticksToWait)==pdPASS ) {
return ERR_OK;
} else {
return ERR_FAILED;
}
}
uint8_t McuUart485_GetRxQueueChar(void) {
uint8_t ch;
if (xQueueReceive(RS485UartRxQueue, &ch, 0)==pdPASS ) {
/* return received character */
} else {
ch = '\0'; /* nothing received */
}
return ch;
}
#if !McuUart485_CONFIG_USE_MODBUS
uint8_t McuUart485_GetResponseQueueChar(void) {
uint8_t ch;
if (xQueueReceive(RS485UartResponseQueue, &ch, 0)==pdPASS ) {
/* return received character */
} else {
ch = '\0'; /* nothing received */
}
return ch;
}
#endif
/* -------------------------------------------------------------------------------------- */
#if McuLib_CONFIG_CPU_IS_ESP32
#define RS485_ESP_BUF_SIZE (4*1024) /* buffer for the UART task. The UART driver uses twice of this */
#if 0 /* not used */
void RS485_SendStr(char *str) {
size_t len = strlen(str);
uart_write_bytes(McuUart485_CONFIG_UART_DEVICE, str, len);
}
void RS485_SendChar(char ch) {
uart_write_bytes(McuUart485_CONFIG_UART_DEVICE, &ch, 1);
}
#endif
/* On the ESP32 we are using a task. On other architectures this would be handled by an interrupt */
static void rs485uart_task(void *arg) {
static unsigned char data[RS485_ESP_BUF_SIZE]; /* Rx buffer for UART */
unsigned char prevChar = '\n';
bool responseLine = false;
BaseType_t res;
McuLog_trace("UART start receive loop.\r\n");
for(;;) {
/* Read data from UART */
int len = uart_read_bytes(McuUart485_CONFIG_UART_DEVICE, data, sizeof(data)-1, pdMS_TO_TICKS(100));
#if 0 /* for debugging only */
if (len>0) {
data[len] = '\0';
McuLog_trace("rx: %d", len);
}
#endif
/* send to Rx Queue */
for(int i=0; i<len; i++) { /* handle received bytes */
if (prevChar=='\n' && data[i]=='@') { /* do we have potentially a response for us on the bus? */
responseLine = true;
}
if (responseLine) {
res = xQueueSend(RS485UartResponseQueue, &data[i], pdMS_TO_TICKS(10));
if (res!=pdPASS) {
McuLog_error("failed sending data to response queue");
}
}
prevChar = data[i];
if (responseLine && data[i]=='\n') { /* end of line while on response line */
responseLine = false;
}
res = xQueueSend(RS485UartRxQueue, &data[i], pdMS_TO_TICKS(20));
if (res!=pdPASS) {
McuLog_error("failed sending data to rx queue");
}
}
} /* for */
}
#endif /* McuLib_CONFIG_CPU_IS_ESP32 */
/*********************************************************************************************************/
/* Shell interface */
/*********************************************************************************************************/
void McuUart485_SendBlock(unsigned char *data, size_t dataSize) {
#if McuLib_CONFIG_CPU_IS_ESP32
uart_write_bytes(McuUart485_CONFIG_UART_DEVICE, data, dataSize);
#else
#if !McuUart485_CONFIG_USE_HW_OE_RTS
McuUart485_GPIO_TxEnable();
#endif
McuUart485_CONFIG_UART_WRITE_BLOCKING(McuUart485_CONFIG_UART_DEVICE, data, dataSize);
#if !McuUart485_CONFIG_USE_HW_OE_RTS
#if McuLib_CONFIG_CPU_IS_RPxxxx
uart_tx_wait_blocking(McuUart485_CONFIG_UART_DEVICE); /* wait until all bytes are sent */
#endif
McuUart485_GPIO_RxEnable();
#endif
#endif
}
void McuUart485_SendString(unsigned char *str) {
McuUart485_SendBlock(str, strlen((char*)str));
}
static void McuUart485_SendChar(unsigned char ch) {
static unsigned char McuUart485_SendCharbuf[McuShell_DEFAULT_SHELL_BUFFER_SIZE] = ""; /* only sending after a '\n', to send things as a block for faster transmission */
static size_t index = 0;
McuUart485_SendCharbuf[index++] = ch;
if (ch=='\n' || index==sizeof(McuUart485_SendCharbuf)-1) {
McuUart485_SendCharbuf[index] = '\0'; /* terminate buffer */
McuUart485_SendString(McuUart485_SendCharbuf);
McuUart485_SendCharbuf[0] = '\0';
index = 0;
}
}
static void McuUart485_ReadChar(uint8_t *c) {
uint8_t ch;
if (xQueueReceive(RS485UartRxQueue, &ch, 0)==pdPASS ) {
*c = ch; /* return received character */
} else {
*c = '\0'; /* nothing received */
}
}
static bool McuUart485_CharPresent(void) {
return uxQueueMessagesWaiting(RS485UartRxQueue)!=0;
}
McuShell_ConstStdIOType McuUart485_stdio = {
.stdIn = (McuShell_StdIO_In_FctType)McuUart485_ReadChar,
.stdOut = (McuShell_StdIO_OutErr_FctType)McuUart485_SendChar,
.stdErr = (McuShell_StdIO_OutErr_FctType)McuUart485_SendChar,
.keyPressed = McuUart485_CharPresent, /* if input is not empty */
#if McuShell_CONFIG_ECHO_ENABLED
.echoEnabled = false,
#endif
};
uint8_t McuUart485_DefaultShellBuffer[McuShell_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */
/*********************************************************************************************************/
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC || McuLib_CONFIG_CPU_IS_RPxxxx
void McuUart485_CONFIG_UART_IRQ_HANDLER(void) {
uint8_t data;
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC /* no flags for RPxxxx */
uint32_t flags;
#endif
BaseType_t xHigherPriorityTaskWoken1 = false, xHigherPriorityTaskWoken2 = false;
#if !McuUart485_CONFIG_USE_MODBUS
static unsigned char prevChar = '\n';
static bool responseLine = false;
#endif
uint8_t count;
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC /* no flags for RPxxxx */
flags = McuUart485_CONFIG_UART_GET_FLAGS(McuUart485_CONFIG_UART_DEVICE);
#endif
#if McuUart485_CONFIG_HAS_FIFO
if (flags&kUART_RxFifoOverflowFlag) {
count = 0; /* statement to allow debugger to set a breakpoint here */
}
#endif
/* new data arrived. */
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC /* no flags for RPxxxx */
if (flags&McuUart485_CONFIG_UART_HW_RX_READY_FLAGS) {
#elif McuLib_CONFIG_CPU_IS_RPxxxx
while (uart_is_readable(McuUart485_CONFIG_UART_DEVICE)) { /* check if we have data available */
#endif
#if McuUart485_CONFIG_HAS_FIFO
count = McuUart485_CONFIG_UART_DEVICE->RCFIFO;
#else
count = 1;
#endif
while(count!=0) {
data = McuUart485_CONFIG_UART_READ_BYTE(McuUart485_CONFIG_UART_DEVICE);
#if !McuUart485_CONFIG_USE_MODBUS
if (data!=0) { /* data==0 could happen especially after power-up, ignore it if we are in shell/non-Modbus mode */
#endif
#if !McuUart485_CONFIG_USE_MODBUS
/* only store into RS485UartResponseQueue if we have a line starting with '@' */
if (prevChar=='\n' && data=='@') {
responseLine = true;
}
if (responseLine) {
(void)xQueueSendFromISR(RS485UartResponseQueue, &data, &xHigherPriorityTaskWoken1);
}
prevChar = data;
if (responseLine && data=='\n') { /* end of line while on response line */
responseLine = false;
}
#endif
(void)xQueueSendFromISR(RS485UartRxQueue, &data, &xHigherPriorityTaskWoken2);
#if McuUart485_CONFIG_USE_LOGGER
if (McuUart485_doLogging) {
extern uint8_t McuRTT_SendChar(uint8_t ch);
unsigned char buf[3];
buf[0] = '\0';
McuUtility_strcatNum8Hex(buf, sizeof(buf), data);
(void)McuUart485_CONFIG_LOGGER_CALLBACK_NAME(buf[0]);
(void)McuUart485_CONFIG_LOGGER_CALLBACK_NAME(buf[1]);
if (isprint(data)) {
(void)McuUart485_CONFIG_LOGGER_CALLBACK_NAME((unsigned char)' ');
(void)McuUart485_CONFIG_LOGGER_CALLBACK_NAME(data);
}
(void)McuUart485_CONFIG_LOGGER_CALLBACK_NAME((unsigned char)'\n');
}
#endif
#if !McuUart485_CONFIG_USE_MODBUS
} /* if data != 0 */
#endif
count--;
} /* while count != 0 */
}
#if McuLib_CONFIG_CPU_IS_KINETIS
flags |= kUART_RxOverrunFlag|kUART_RxFifoOverflowFlag; /* always clear these flags, as they might been set? Not clearing them will not generate future interrupts */
#endif
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC /* no clearing needed for RPxxxx */
McuUart485_CONFIG_CLEAR_STATUS_FLAGS(McuUart485_CONFIG_UART_DEVICE, flags);
#endif
if (xHigherPriorityTaskWoken1 != pdFALSE || xHigherPriorityTaskWoken2 != pdFALSE) {
vPortYieldFromISR();
}
#if McuLib_CONFIG_CORTEX_M==4
__DSB(); /* ARM Cortex-M4 errata Notice 838869: dsb required because "Store immediate overlapping exception return operation might vector to incorrect interrupt" */
#endif
}
#endif
static void InitUart(void) {
#if !McuUart485_CONFIG_USE_HW_OE_RTS
McuUart485_GPIO_Init();
#endif
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC
/* NOTE: Muxing of the UART pins needs to be done in the Pins tool! */
McuUart485_CONFIG_UART_CONFIG_STRUCT config;
status_t res;
McuUart485_CONFIG_UART_SET_UART_CLOCK();
McuUart485_CONFIG_UART_GET_DEFAULT_CONFIG(&config);
config.baudRate_Bps = McuUart485_CONFIG_UART_BAUDRATE;
config.parityMode = McuUart485_CONFIG_UART_PARITY;
config.enableRx = true;
config.enableTx = true;
#if McuLib_CONFIG_CPU_IS_KINETIS
config.enableRxRTS = true; /* using RTS pin to control the transceiver */
config.enableTxCTS = false;
#endif
/* Initialize the USART with configuration. */
res = McuUart485_CONFIG_UART_INIT(McuUart485_CONFIG_UART_DEVICE, &config, CLOCK_GetFreq(McuUart485_CONFIG_UART_GET_CLOCK_FREQ_SELECT));
if (res!=kStatus_Success) {
McuLog_fatal("failed initializing UART");
for(;;) {}
}
#if McuUart485_CONFIG_USE_HW_OE_RTS
#if McuLib_CONFIG_CPU_IS_KINETIS /* Kinetis K22FN512 */
McuUart485_CONFIG_UART_DEVICE->MODEM |= UART_MODEM_TXRTSPOL(1); /* TXRTSPOL: 1: transmitter RTS polarity is active high */
McuUart485_CONFIG_UART_DEVICE->MODEM |= UART_MODEM_TXRTSE(1); /* TXRTSE: Transmitter request-to-send enable, 1: RTS asserted before start bit is transmitted and deasserted after stop bit */
#elif McuLib_CONFIG_CPU_IS_LPC /* LPC845 or LPC55S69 */
McuUart485_CONFIG_UART_DEVICE->CFG |= USART_CFG_OESEL(1); /* if enabled, use RTS signal for RS-485 transceiver */
McuUart485_CONFIG_UART_DEVICE->CFG |= USART_CFG_OEPOL(1); /* 1: the output enable signal is high active */
McuUart485_CONFIG_UART_DEVICE->CFG |= USART_CFG_OETA(1); /* output enable turnaround time: if set, the output enable signal remains asserted for 1 char time after the end of the last bit */
#endif
#endif
#if McuUart485_CONFIG_HAS_FIFO
UART_EnableRxFIFO(McuUart485_CONFIG_UART_DEVICE, true); /* enable UART Rx FIFO */
#endif
McuUart485_CONFIG_UART_ENABLE_INTERRUPTS(McuUart485_CONFIG_UART_DEVICE,
McuUart485_CONFIG_UART_ENABLE_INTERRUPT_FLAGS
);
NVIC_SetPriority(McuUart485_CONFIG_UART_IRQ_NUMBER, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); /* required as we are using FreeRTOS API calls */
EnableIRQ(McuUart485_CONFIG_UART_IRQ_NUMBER);
#elif McuLib_CONFIG_CPU_IS_ESP32
// Timeout threshold for UART = number of symbols (~10 tics) with unchanged state on receive pin
#define UART_CONFIG_READ_TOUT (3) // 3.5T * 8 = 28 ticks, TOUT=3 -> ~24..33 ticks
uart_config_t uart_config = {
.baud_rate = McuUart485_CONFIG_UART_BAUDRATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, /* UART_HW_FLOWCTRL_CTS */ /*UART_HW_FLOWCTRL_RTS,*/ /* UART_HW_FLOWCTRL_CTS_RTS, */
.rx_flow_ctrl_thresh = 122,
.source_clk = UART_SCLK_APB,
};
McuLog_trace("UART set pins, mode and install driver.");
/* Install UART driver (we don't need an event queue here) */
ESP_ERROR_CHECK(uart_driver_install(
McuUart485_CONFIG_UART_DEVICE, /* usart device */
RS485_ESP_BUF_SIZE*2, /* RX Buffer */
RS485_ESP_BUF_SIZE*2, /* TX Buffer */
0, /* event queue size */
NULL, /* event queue handle */
0 /* interrupt alloc flags */
)
);
/* Configure UART parameters */
ESP_ERROR_CHECK(uart_param_config(McuUart485_CONFIG_UART_DEVICE, &uart_config));
/* RE (Receiver Enable, IO23) shall be HIGH during Tx, RE (Low Active, IO26) shall be LOW during Tx */
ESP_ERROR_CHECK(uart_set_pin(McuUart485_CONFIG_UART_DEVICE,
McuUart485_CONFIG_TXD_PIN, /* TX pin */
McuUart485_CONFIG_RXD_PIN, /* RX pin */
McuUart485_CONFIG_RTS_PIN, /* RTS pin */
UART_PIN_NO_CHANGE /* CTS pin */
));
/* Set RS485 half duplex mode */
ESP_ERROR_CHECK(uart_set_mode(McuUart485_CONFIG_UART_DEVICE, UART_MODE_RS485_HALF_DUPLEX));
// Set read timeout of UART TOUT feature
ESP_ERROR_CHECK(uart_set_rx_timeout(McuUart485_CONFIG_UART_DEVICE, UART_CONFIG_READ_TOUT));
#elif McuLib_CONFIG_CPU_IS_RPxxxx
uart_init(McuUart485_CONFIG_UART_DEVICE, McuUart485_CONFIG_UART_BAUDRATE);
gpio_set_function(McuUart485_CONFIG_TXD_PIN, GPIO_FUNC_UART);
gpio_set_function(McuUart485_CONFIG_RXD_PIN, GPIO_FUNC_UART);
uart_set_fifo_enabled(McuUart485_CONFIG_UART_DEVICE, false);
uart_set_format(McuUart485_CONFIG_UART_DEVICE, 8, 1, McuUart485_CONFIG_UART_PARITY);
uart_set_hw_flow(McuUart485_CONFIG_UART_DEVICE, false, false); /* disable flow control, cannot use CTS/RTS */
uart_set_translate_crlf(McuUart485_CONFIG_UART_DEVICE, false); /* do not translate */
/* setup interrupt */
int UART_IRQ = McuUart485_CONFIG_UART_DEVICE == uart0 ? UART0_IRQ : UART1_IRQ; /* find out which UART is used */
irq_set_exclusive_handler(UART_IRQ, McuUart485_CONFIG_UART_IRQ_HANDLER /* on_uart_rx*/); /* setup IRQ handler */
irq_set_enabled(UART_IRQ, true); /* enable interrupt */
irq_set_priority(UART_IRQ, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); /* required as we are using FreeRTOS API calls */
uart_set_irq_enables(McuUart485_CONFIG_UART_DEVICE, true, false); /* enable UART interrupt output, Rx only */
#else
#error "need to initialize UART!"
#endif
}
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC
static void DecodeUARTFlags(uint32_t flags, const McuShell_StdIOType *io) {
#if McuLib_CONFIG_CPU_IS_KINETIS
if (flags&kUART_TxDataRegEmptyFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_TxDataRegEmptyFlag\r\n", io->stdOut);
}
if (flags&kUART_TransmissionCompleteFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_TransmissionCompleteFlag\r\n", io->stdOut);
}
if (flags&kUART_RxDataRegFullFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxDataRegFullFlag\r\n", io->stdOut);
}
if (flags&kUART_IdleLineFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_IdleLineFlag\r\n", io->stdOut);
}
if (flags&kUART_RxOverrunFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxOverrunFlag\r\n", io->stdOut);
}
if (flags&kUART_NoiseErrorFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_NoiseErrorFlag\r\n", io->stdOut);
}
if (flags&kUART_FramingErrorFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_FramingErrorFlag\r\n", io->stdOut);
}
if (flags&kUART_ParityErrorFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_ParityErrorFlag\r\n", io->stdOut);
}
#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT
if (flags&kUART_LinBreakFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_LinBreakFlag\r\n", io->stdOut);
}
#endif
if (flags&kUART_RxActiveEdgeFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxActiveEdgeFlag\r\n", io->stdOut);
}
if (flags&kUART_RxActiveFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxActiveFlag\r\n", io->stdOut);
}
#if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS
if (flags&kUART_NoiseErrorInRxDataRegFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_NoiseErrorInRxDataRegFlag\r\n", io->stdOut);
}
if (flags&kUART_ParityErrorInRxDataRegFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_ParityErrorInRxDataRegFlag\r\n", io->stdOut);
}
#endif
#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO
if (flags&kUART_TxFifoEmptyFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_TxFifoEmptyFlag\r\n", io->stdOut);
}
if (flags&kUART_RxFifoEmptyFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxFifoEmptyFlag\r\n", io->stdOut);
}
if (flags&kUART_TxFifoOverflowFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_TxFifoOverflowFlag\r\n", io->stdOut);
}
if (flags&kUART_RxFifoOverflowFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxFifoOverflowFlag\r\n", io->stdOut);
}
if (flags&kUART_RxFifoOverflowFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUART_RxFifoOverflowFlag\r\n", io->stdOut);
}
#endif
#elif McuLib_CONFIG_CPU_IS_LPC && McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC845
if (flags&kUSART_RxReady) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_RxReady\r\n", io->stdOut);
}
if (flags&kUSART_RxIdleFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_RxIdleFlag\r\n", io->stdOut);
}
if (flags&kUSART_TxReady) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_TxReady\r\n", io->stdOut);
}
if (flags&kUSART_TxIdleFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_TxIdleFlag\r\n", io->stdOut);
}
if (flags&kUSART_CtsState) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_CtsState\r\n", io->stdOut);
}
if (flags&kUSART_DeltaCtsFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_DeltaCtsFlag\r\n", io->stdOut);
}
if (flags&kUSART_TxDisableFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_TxDisableFlag\r\n", io->stdOut);
}
if (flags&kUSART_HardwareOverrunFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_HardwareOverrunFlag\r\n", io->stdOut);
}
if (flags&kUSART_RxBreakFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_RxBreakFlag\r\n", io->stdOut);
}
if (flags&kUSART_RxStartFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_RxStartFlag\r\n", io->stdOut);
}
if (flags&kUSART_FramErrorFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_FramErrorFlag\r\n", io->stdOut);
}
if (flags&kUSART_ParityErrorFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_ParityErrorFlag\r\n", io->stdOut);
}
if (flags&kUSART_RxNoiseFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_RxNoiseFlag\r\n", io->stdOut);
}
#if defined(FSL_FEATURE_USART_HAS_ABERR_CHECK) && FSL_FEATURE_USART_HAS_ABERR_CHECK
if (flags&kUSART_AutoBaudErrorFlag) {
McuShell_SendStatusStr((unsigned char*)"", (unsigned char*)"kUSART_AutoBaudErrorFlag\r\n", io->stdOut);
}
#endif
#endif
}
#endif
static uint8_t PrintStatus(const McuShell_StdIOType *io) {
uint8_t buf[96];
McuShell_SendStatusStr((unsigned char*)"McuUart485", (unsigned char*)"RS-485 UART settings\r\n", io->stdOut);
#if McuUart485_CONFIG_USE_LOGGER
McuShell_SendStatusStr((unsigned char*)" logging", McuUart485_doLogging?(unsigned char*)"on\r\n":(unsigned char*)"off\r\n", io->stdOut);
#endif
McuShell_SendStatusStr((unsigned char*)" HW TxEn", McuUart485_CONFIG_USE_HW_OE_RTS?(unsigned char*)"yes\r\n":(unsigned char*)"no\r\n", io->stdOut);
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC
uint32_t flags;
#if !McuUart485_CONFIG_USE_HW_OE_RTS
McuGPIO_GetPinStatusString(RS485_TxEn, buf, sizeof(buf));
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"\r\n");
McuShell_SendStatusStr((unsigned char*)" TxEn", buf, io->stdOut);
#endif
flags = McuUart485_CONFIG_UART_GET_FLAGS(McuUart485_CONFIG_UART_DEVICE);
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"0x");
McuUtility_strcatNum32Hex(buf, sizeof(buf), flags);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"\r\n");
McuShell_SendStatusStr((unsigned char*)" flags", buf, io->stdOut);
DecodeUARTFlags(flags, io) ;
#endif
McuUtility_Num32uToStr(buf, sizeof(buf), McuUart485_CONFIG_UART_BAUDRATE);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"\r\n");
McuShell_SendStatusStr((unsigned char*)" baud", buf, io->stdOut);
#if McuLib_CONFIG_CPU_IS_ESP32
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"buffer: ");
McuUtility_strcatNum32u(buf, sizeof(buf), RS485_ESP_BUF_SIZE);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)" bytes\r\n");
McuShell_SendStatusStr((unsigned char*)" uart", buf, io->stdOut);
#endif
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"Rx: ");
McuUtility_strcatNum32u(buf, sizeof(buf), McuUart485_CONFIG_UART_RX_QUEUE_LENGTH);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)", Response: ");
McuUtility_strcatNum32u(buf, sizeof(buf), McuUart485_CONFIG_UART_RESPONSE_QUEUE_LENGTH);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)"\r\n");
McuShell_SendStatusStr((unsigned char*)" queues", buf, io->stdOut);
return ERR_OK;
}
static uint8_t PrintHelp(const McuShell_StdIOType *io) {
McuShell_SendHelpStr((unsigned char*)"McuUart485", (unsigned char*)"Group of RS-485 commands\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut);
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC
McuShell_SendHelpStr((unsigned char*)" clear <flags>", (unsigned char*)"Clear UART ISR flags\r\n", io->stdOut);
#endif
McuShell_SendHelpStr((unsigned char*)" log on|off", (unsigned char*)"Turn logging on or off\r\n", io->stdOut);
return ERR_OK;
}
uint8_t McuUart485_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) {
if (McuUtility_strcmp((char*)cmd, McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, "McuUart485 help")==0) {
*handled = true;
return PrintHelp(io);
} else if ((McuUtility_strcmp((char*)cmd, McuShell_CMD_STATUS)==0) || (McuUtility_strcmp((char*)cmd, "McuUart485 status")==0)) {
*handled = true;
return PrintStatus(io);
#if McuLib_CONFIG_CPU_IS_KINETIS || McuLib_CONFIG_CPU_IS_LPC
} else if (McuUtility_strncmp((char*)cmd, "McuUart485 clear ", sizeof("McuUart485 clear ")-1)==0) {
int32_t flags;
#if McuLib_CONFIG_CPU_IS_KINETIS
status_t status;
#endif
const unsigned char *p;
*handled = true;
p = cmd + sizeof("McuUart485 clear ")-1;
if (McuUtility_xatoi(&p, &flags)==ERR_OK) {
#if McuLib_CONFIG_CPU_IS_KINETIS
status = McuUart485_CONFIG_CLEAR_STATUS_FLAGS(McuUart485_CONFIG_UART_DEVICE, flags);
McuShell_SendStr((unsigned char*)"status: ", io->stdOut);
McuShell_SendNum32u(status, io->stdOut);
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
#elif McuLib_CONFIG_CPU_IS_LPC
McuUart485_CONFIG_CLEAR_STATUS_FLAGS(McuUart485_CONFIG_UART_DEVICE, flags);
#endif
return ERR_OK;
}
return ERR_FAILED;
#endif
#if McuUart485_CONFIG_USE_LOGGER
} else if (McuUtility_strcmp((char*)cmd, "McuUart485 log on")==0) {
*handled = TRUE;
McuUart485_doLogging = true;
return ERR_OK;
} else if (McuUtility_strcmp((char*)cmd, "McuUart485 log off")==0) {
*handled = TRUE;
McuUart485_doLogging = false;
return ERR_OK;
#endif
}
return ERR_OK;
}
void McuUart485_Deinit(void) {
vQueueDelete(RS485UartRxQueue);
RS485UartRxQueue = NULL;
#if !McuUart485_CONFIG_USE_MODBUS
vQueueDelete(RS485UartResponseQueue);
RS485UartResponseQueue = NULL;
#endif
#if !McuUart485_CONFIG_USE_HW_OE_RTS
McuUart485_GPIO_Deinit();
#endif
}
void McuUart485_Init(void) {
InitUart();
RS485UartRxQueue = xQueueCreate(McuUart485_CONFIG_UART_RX_QUEUE_LENGTH, sizeof(uint8_t));
if (RS485UartRxQueue==NULL) {
McuLog_fatal("failed creating RS-485 Rx queue");
for(;;){} /* out of memory? */
}
vQueueAddToRegistry(RS485UartRxQueue, "RS485UartRxQueue");
#if !McuUart485_CONFIG_USE_MODBUS
RS485UartResponseQueue = xQueueCreate(McuUart485_CONFIG_UART_RESPONSE_QUEUE_LENGTH, sizeof(uint8_t));
if (RS485UartResponseQueue==NULL) {
McuLog_fatal("failed creating RS-485 response queue");
for(;;){} /* out of memory? */
}
vQueueAddToRegistry(RS485UartResponseQueue, "RS485UartResponseQueue");
#endif
#if McuLib_CONFIG_CPU_IS_ESP32
BaseType_t res;
res = xTaskCreate(rs485uart_task, "rs485uart", (4*1024)/sizeof(StackType_t), NULL, tskIDLE_PRIORITY+3, NULL);
if (res==pdPASS) {
McuLog_trace("created rs485-uart task");
} else {
McuLog_fatal("failed creating res485-uart task!");
}
#endif
}
#endif /* #ifdef McuUart485_CONFIG_UART_DEVICE */