[core] Refactor SerialClass as API library

This commit is contained in:
Kuba Szczodrzyński
2023-05-24 11:55:07 +02:00
parent b073290989
commit 3836ad20b7
22 changed files with 296 additions and 268 deletions

View File

@@ -0,0 +1,142 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#include "SerialPrivate.h"
#if HAS_SERIAL0
SerialClass Serial0(0);
#endif
#if HAS_SERIAL1
SerialClass Serial1(1);
#endif
#if HAS_SERIAL2
SerialClass Serial2(2);
#endif
static UART_TypeDef *PORT_UART[3] = {UART0_DEV, UART1_DEV, UART2_DEV};
static const IRQn PORT_IRQ[3] = {UART0_IRQ, UART1_IRQ, UART_LOG_IRQ};
static const pin_size_t PORT_RX[3] = {
#ifdef PIN_SERIAL0_RX
PIN_SERIAL0_RX,
#else
PIN_INVALID,
#endif
#ifdef PIN_SERIAL1_RX
PIN_SERIAL1_RX,
#else
PIN_INVALID,
#endif
#ifdef PIN_SERIAL2_RX
PIN_SERIAL2_RX,
#else
PIN_INVALID,
#endif
};
static const pin_size_t PORT_TX[3] = {
#ifdef PIN_SERIAL0_TX
PIN_SERIAL0_TX,
#else
PIN_INVALID,
#endif
#ifdef PIN_SERIAL1_TX
PIN_SERIAL1_TX,
#else
PIN_INVALID,
#endif
#ifdef PIN_SERIAL2_TX
PIN_SERIAL2_TX,
#else
PIN_INVALID,
#endif
};
static uint32_t callback(void *param) {
UART_TypeDef *uart = pdUART;
uint32_t intcr = uart->DLH_INTCR;
uart->DLH_INTCR = 0;
uint8_t c;
while (UART_Readable(uart)) {
UART_CharGet(uart, &c);
#if LT_AUTO_DOWNLOAD_REBOOT && defined(LT_UART_ADR_PATTERN) && defined(PIN_SERIAL2_RX)
// parse UART protocol commands on UART2
if (uart == UART2_DEV)
SerialClass::adrParse(c);
#endif
pdBUF.store_char(c);
}
uart->DLH_INTCR = intcr;
return 0;
}
void SerialClass::begin(unsigned long baudrate, uint16_t config) {
this->data = new SerialData();
this->buf = &BUF;
DATA->uart = PORT_UART[this->port];
DATA->irq = PORT_IRQ[this->port];
DATA->rx = PORT_RX[this->port];
DATA->tx = PORT_TX[this->port];
// RUART_WLS_7BITS / RUART_WLS_8BITS
uint8_t dataWidth = (config & SERIAL_DATA_MASK) == SERIAL_DATA_8;
// RUART_PARITY_DISABLE / RUART_PARITY_ENABLE
uint8_t parity = (config & SERIAL_PARITY_MASK) != SERIAL_PARITY_NONE;
// RUART_ODD_PARITY / RUART_EVEN_PARITY
uint8_t parityType = (config & SERIAL_PARITY_MASK) == SERIAL_PARITY_EVEN;
// RUART_STOP_BIT_1 / RUART_STOP_BIT_2
uint8_t stopBits = (config & SERIAL_STOP_BIT_MASK) == SERIAL_STOP_BIT_2;
switch ((uint32_t)DATA->uart) {
case UART0_REG_BASE:
RCC_PeriphClockCmd(APBPeriph_UART0, APBPeriph_UART0_CLOCK, ENABLE);
break;
case UART1_REG_BASE:
RCC_PeriphClockCmd(APBPeriph_UART1, APBPeriph_UART1_CLOCK, ENABLE);
break;
}
if (DATA->tx != PIN_INVALID) {
Pinmux_Config(DATA->tx, PINMUX_FUNCTION_UART);
}
if (DATA->rx != PIN_INVALID) {
Pinmux_Config(DATA->rx, PINMUX_FUNCTION_UART);
PAD_PullCtrl(DATA->rx, GPIO_PuPd_UP);
}
UART_InitTypeDef cfg;
UART_StructInit(&cfg);
cfg.WordLen = dataWidth;
cfg.Parity = parity;
cfg.ParityType = parityType;
cfg.StopBit = stopBits;
UART_Init(UART, &cfg);
UART_SetBaud(UART, baudrate);
if (DATA->rx != PIN_INVALID) {
VECTOR_IrqUnRegister(DATA->irq);
VECTOR_IrqRegister(callback, DATA->irq, (uint32_t)&data, 10);
VECTOR_IrqEn(DATA->irq, 10);
UART_RxCmd(UART, ENABLE);
UART_INTConfig(UART, RUART_IER_ERBI, ENABLE);
}
}
void SerialClass::end() {
if (UART == UART2_DEV) {
// restore command line mode
DIAG_UartReInit((IRQ_FUN)UartLogIrqHandle);
}
this->buf = NULL;
delete DATA;
}
void SerialClass::flush() {
UART_WaitBusy(UART, 10);
}
size_t SerialClass::write(uint8_t c) {
while (UART_Writable(UART) == 0) {}
UART_CharPut(UART, c);
return 1;
}

View File

@@ -0,0 +1,21 @@
/* Copyright (c) Kuba Szczodrzyński 2023-05-23. */
#pragma once
#include <Arduino.h>
#include <sdk_private.h>
typedef struct {
UART_TypeDef *uart;
IRQn irq;
pin_size_t rx;
pin_size_t tx;
RingBuffer buf;
} SerialData;
#define DATA ((SerialData *)data)
#define pDATA ((SerialData *)param)
#define BUF (DATA->buf)
#define pdBUF (pDATA->buf)
#define UART (DATA->uart)
#define pdUART (pDATA->uart)

View File

@@ -0,0 +1,7 @@
#pragma once
#error "Don't include this file directly"
#define LT_ARD_HAS_SERIAL 1
#define LT_ARD_MD5_POLARSSL 1

View File

@@ -16,3 +16,13 @@
#error "No serial port is available"
#endif
#endif
// clang-format off
// Auto-download-reboot detection pattern
// Family ID, big-endian
#define LT_UART_ADR_PATTERN 0x55, 0xAA, \
(FAMILY >> 24) & 0xFF, \
(FAMILY >> 16) & 0xFF, \
(FAMILY >> 8) & 0xFF, \
(FAMILY >> 0) & 0xFF
// clang-format on

View File

@@ -2,12 +2,15 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c
extern void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70!
int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c
void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70!
#ifdef __cplusplus
} // extern "C"