[core] Refactor SerialClass as API library
This commit is contained in:
@@ -34,7 +34,7 @@ for f in family.inheritance:
|
||||
code = f"{f.code}_arduino"
|
||||
path = join("$CORES_DIR", f.name, "arduino")
|
||||
|
||||
found = found or env.AddCoreSources(queue, name=code, path=join(path, "src"))
|
||||
found = env.AddCoreSources(queue, name=code, path=join(path, "src")) or found
|
||||
env.AddArduinoLibraries(queue, name=code, path=join(path, "libraries"))
|
||||
|
||||
if f.short_name:
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-23. */
|
||||
|
||||
#include "Serial.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <uart_pub.h>
|
||||
|
||||
extern void bk_send_byte(uint8_t uport, uint8_t data);
|
||||
extern void uart_hw_set_change(uint8_t uport, bk_uart_config_t *uart_config);
|
||||
extern int uart_rx_callback_set(int uport, uart_callback callback, void *param);
|
||||
|
||||
} // extern "C"
|
||||
#include "SerialPrivate.h"
|
||||
|
||||
#if HAS_SERIAL1
|
||||
SerialClass Serial1(UART1_PORT);
|
||||
@@ -21,39 +9,22 @@ SerialClass Serial1(UART1_PORT);
|
||||
SerialClass Serial2(UART2_PORT);
|
||||
#endif
|
||||
|
||||
SerialClass::SerialClass(uint8_t port) {
|
||||
this->port = port;
|
||||
this->buf = NULL;
|
||||
}
|
||||
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT
|
||||
static uint8_t adrState = 0;
|
||||
static const uint8_t adrCmd[] = {0x01, 0xE0, 0xFC, 0x01, 0x00};
|
||||
|
||||
static void adrParse(uint8_t c) {
|
||||
// parse and respond to link check command (CMD_LinkCheck=0)
|
||||
adrState = (adrState + 1) * (c == adrCmd[adrState]);
|
||||
if (adrState == 5) {
|
||||
LT_I("Auto download mode: rebooting");
|
||||
LT.restart();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void callback(int port, void *param) {
|
||||
RingBuffer *buf = (RingBuffer *)param;
|
||||
int ch;
|
||||
while ((ch = uart_read_byte(port)) != -1) {
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT && defined(PIN_SERIAL1_RX)
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT && defined(LT_UART_ADR_PATTERN) && defined(PIN_SERIAL1_RX)
|
||||
// parse UART protocol commands on UART1
|
||||
if (port == UART1_PORT)
|
||||
adrParse(ch);
|
||||
SerialClass::adrParse(ch);
|
||||
#endif
|
||||
buf->store_char(ch);
|
||||
pBUF->store_char(ch);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialClass::begin(unsigned long baudrate, uint16_t config) {
|
||||
this->data = new SerialData();
|
||||
this->buf = &BUF;
|
||||
|
||||
uint8_t dataWidth = ((config & SERIAL_DATA_MASK) >> 8) - 1; // 0x100..0x400 -> 0..3
|
||||
uint8_t parity = 3 - (config & SERIAL_PARITY_MASK); // 0x3..0x1 -> 0..2
|
||||
uint8_t stopBits = (config & SERIAL_STOP_BIT_MASK) == SERIAL_STOP_BIT_2; // 0x10..0x30 -> 0..1
|
||||
@@ -66,14 +37,8 @@ void SerialClass::begin(unsigned long baudrate, uint16_t config) {
|
||||
.flow_control = FLOW_CTRL_DISABLED,
|
||||
};
|
||||
|
||||
if (this->buf) {
|
||||
this->buf->clear();
|
||||
} else {
|
||||
this->buf = new RingBuffer();
|
||||
}
|
||||
|
||||
uart_hw_set_change(port, &cfg);
|
||||
uart_rx_callback_set(port, callback, this->buf);
|
||||
uart_rx_callback_set(port, callback, &BUF);
|
||||
}
|
||||
|
||||
void SerialClass::end() {
|
||||
@@ -86,19 +51,8 @@ void SerialClass::end() {
|
||||
uart2_exit();
|
||||
break;
|
||||
}
|
||||
delete this->buf;
|
||||
}
|
||||
|
||||
int SerialClass::available() {
|
||||
return buf->available();
|
||||
}
|
||||
|
||||
int SerialClass::peek() {
|
||||
return buf->peek();
|
||||
}
|
||||
|
||||
int SerialClass::read() {
|
||||
return buf->read_char();
|
||||
this->buf = NULL;
|
||||
delete DATA;
|
||||
}
|
||||
|
||||
void SerialClass::flush() {
|
||||
|
||||
14
cores/beken-72xx/arduino/libraries/Serial/SerialPrivate.h
Normal file
14
cores/beken-72xx/arduino/libraries/Serial/SerialPrivate.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
typedef struct {
|
||||
RingBuffer buf;
|
||||
} SerialData;
|
||||
|
||||
#define DATA ((SerialData *)data)
|
||||
#define BUF (DATA->buf)
|
||||
#define pBUF ((RingBuffer *)param)
|
||||
@@ -14,3 +14,7 @@
|
||||
#error "No serial port is available"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Auto-download-reboot detection pattern
|
||||
// Link check command (CMD_LinkCheck=0)
|
||||
#define LT_UART_ADR_PATTERN 0x01, 0xE0, 0xFC, 0x01, 0x00
|
||||
|
||||
24
cores/beken-72xx/base/sdk_extern.h
Normal file
24
cores/beken-72xx/base/sdk_extern.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include <uart_pub.h>
|
||||
|
||||
// SDK
|
||||
extern uint8_t system_mac[];
|
||||
extern int uart_print_port;
|
||||
uint32_t wdt_ctrl(uint32_t cmd, void *param);
|
||||
void bk_send_byte(uint8_t uport, uint8_t data);
|
||||
void uart_hw_set_change(uint8_t uport, bk_uart_config_t *uart_config);
|
||||
int uart_rx_callback_set(int uport, uart_callback callback, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -19,9 +19,7 @@ extern "C" {
|
||||
#include <wdt_pub.h>
|
||||
#include <wlan_ui_pub.h>
|
||||
|
||||
extern uint8_t system_mac[];
|
||||
extern uint32_t wdt_ctrl(uint32_t cmd, void *param);
|
||||
extern int uart_print_port;
|
||||
#include <sdk_extern.h>
|
||||
|
||||
// conflict with stl_algobase.h
|
||||
#undef min
|
||||
|
||||
34
cores/common/arduino/libraries/api/Serial/Serial.cpp
Normal file
34
cores/common/arduino/libraries/api/Serial/Serial.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-23. */
|
||||
|
||||
#include "Serial.h"
|
||||
|
||||
SerialClass::SerialClass(uint32_t port) {
|
||||
this->port = port;
|
||||
this->buf = NULL;
|
||||
this->data = NULL;
|
||||
}
|
||||
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT && defined(LT_UART_ADR_PATTERN)
|
||||
static uint8_t adrState = 0;
|
||||
static uint8_t adrCmd[] = {LT_UART_ADR_PATTERN};
|
||||
|
||||
void SerialClass::adrParse(uint8_t c) {
|
||||
adrState = (adrState + 1) * (c == adrCmd[adrState]);
|
||||
if (adrState == sizeof(adrCmd) / sizeof(uint8_t)) {
|
||||
LT_I("Auto download mode: rebooting");
|
||||
LT.restartDownloadMode();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int SerialClass::available() {
|
||||
return this->buf && this->buf->available();
|
||||
}
|
||||
|
||||
int SerialClass::peek() {
|
||||
return this->buf ? this->buf->peek() : -1;
|
||||
}
|
||||
|
||||
int SerialClass::read() {
|
||||
return this->buf ? this->buf->read_char() : -1;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <api/ArduinoAPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <api/HardwareSerial.h>
|
||||
#include <api/RingBuffer.h>
|
||||
|
||||
@@ -10,11 +10,14 @@ using namespace arduino;
|
||||
|
||||
class SerialClass : public HardwareSerial {
|
||||
private:
|
||||
uint8_t port;
|
||||
uint32_t port;
|
||||
RingBuffer *buf;
|
||||
|
||||
public:
|
||||
SerialClass(uint8_t port);
|
||||
void *data;
|
||||
|
||||
public:
|
||||
SerialClass(uint32_t port);
|
||||
|
||||
inline void begin(unsigned long baudrate) {
|
||||
begin(baudrate, SERIAL_8N1);
|
||||
@@ -32,5 +35,12 @@ class SerialClass : public HardwareSerial {
|
||||
return !!buf;
|
||||
}
|
||||
|
||||
public:
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT
|
||||
static void adrParse(uint8_t c);
|
||||
#endif
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#define HAS_SERIAL_CLASS 1
|
||||
@@ -42,6 +42,7 @@ using std::min;
|
||||
#if defined(__cplusplus) && LT_ARD_HAS_SERIAL
|
||||
#include <Serial.h>
|
||||
|
||||
#if HAS_SERIAL_CLASS
|
||||
#if HAS_SERIAL0
|
||||
extern SerialClass Serial0;
|
||||
#endif
|
||||
@@ -51,6 +52,7 @@ extern SerialClass Serial1;
|
||||
#if HAS_SERIAL2
|
||||
extern SerialClass Serial2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SerialN(x) Serial##x
|
||||
#define SerialM(x) SerialN(x)
|
||||
|
||||
@@ -21,6 +21,8 @@ extern "C" {
|
||||
#define PIN_SWD (1 << 10)
|
||||
#define PIN_UART (1 << 11)
|
||||
|
||||
#define PIN_INVALID 255
|
||||
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief GPIO name in the family SDK.
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
|
||||
|
||||
#include "Serial.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
#if HAS_SERIAL0
|
||||
SerialClass Serial0(UART0_DEV, UART0_IRQ, PIN_SERIAL0_RX, PIN_SERIAL0_TX);
|
||||
#endif
|
||||
#if HAS_SERIAL1
|
||||
SerialClass Serial1(UART1_DEV, UART1_IRQ, PIN_SERIAL1_RX, PIN_SERIAL1_TX);
|
||||
#endif
|
||||
#if HAS_SERIAL2
|
||||
SerialClass Serial2(UART2_DEV, UART_LOG_IRQ, PIN_SERIAL2_RX, PIN_SERIAL2_TX);
|
||||
#endif
|
||||
|
||||
SerialClass::SerialClass(void *uart, uint8_t irq, pin_size_t rx, pin_size_t tx) {
|
||||
data.uart = uart;
|
||||
data.buf = NULL;
|
||||
this->irq = irq;
|
||||
this->rx = rx;
|
||||
this->tx = tx;
|
||||
}
|
||||
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT
|
||||
static uint8_t adrState = 0;
|
||||
|
||||
// clang-format off
|
||||
// Family ID, big-endian
|
||||
static const uint8_t adrCmd[] = {
|
||||
0x55, 0xAA,
|
||||
(FAMILY >> 24) & 0xFF,
|
||||
(FAMILY >> 16) & 0xFF,
|
||||
(FAMILY >> 8) & 0xFF,
|
||||
(FAMILY >> 0) & 0xFF
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
static void adrParse(uint8_t c) {
|
||||
adrState = (adrState + 1) * (c == adrCmd[adrState]);
|
||||
if (adrState == 6) {
|
||||
LT_I("Auto download mode: rebooting");
|
||||
LT.restartDownloadMode();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t callback(void *param) {
|
||||
SerialData *data = (SerialData *)param;
|
||||
UART_TypeDef *uart = (UART_TypeDef *)data->uart;
|
||||
|
||||
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(PIN_SERIAL2_RX)
|
||||
// parse UART protocol commands on UART2
|
||||
if (uart == UART2_DEV)
|
||||
adrParse(c);
|
||||
#endif
|
||||
data->buf->store_char(c);
|
||||
}
|
||||
|
||||
uart->DLH_INTCR = intcr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SerialClass::begin(unsigned long baudrate, uint16_t config) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
Pinmux_Config(pinInfo(this->rx)->gpio, PINMUX_FUNCTION_UART);
|
||||
Pinmux_Config(pinInfo(this->tx)->gpio, PINMUX_FUNCTION_UART);
|
||||
PAD_PullCtrl(pinInfo(this->rx)->gpio, GPIO_PuPd_UP);
|
||||
|
||||
UART_InitTypeDef cfg;
|
||||
UART_StructInit(&cfg);
|
||||
cfg.WordLen = dataWidth;
|
||||
cfg.Parity = parity;
|
||||
cfg.ParityType = parityType;
|
||||
cfg.StopBit = stopBits;
|
||||
UART_Init((UART_TypeDef *)data.uart, &cfg);
|
||||
UART_SetBaud((UART_TypeDef *)data.uart, baudrate);
|
||||
|
||||
if (data.buf) {
|
||||
data.buf->clear();
|
||||
} else {
|
||||
data.buf = new RingBuffer();
|
||||
}
|
||||
|
||||
VECTOR_IrqUnRegister(this->irq);
|
||||
VECTOR_IrqRegister(callback, this->irq, (uint32_t)&data, 10);
|
||||
VECTOR_IrqEn(this->irq, 10);
|
||||
|
||||
UART_RxCmd((UART_TypeDef *)data.uart, ENABLE);
|
||||
UART_INTConfig((UART_TypeDef *)data.uart, RUART_IER_ERBI, ENABLE);
|
||||
}
|
||||
|
||||
void SerialClass::end() {
|
||||
if (data.uart == UART2_DEV) {
|
||||
// restore command line mode
|
||||
DIAG_UartReInit((IRQ_FUN)UartLogIrqHandle);
|
||||
}
|
||||
delete data.buf;
|
||||
}
|
||||
|
||||
int SerialClass::available() {
|
||||
return data.buf->available();
|
||||
}
|
||||
|
||||
int SerialClass::peek() {
|
||||
return data.buf->peek();
|
||||
}
|
||||
|
||||
int SerialClass::read() {
|
||||
return data.buf->read_char();
|
||||
}
|
||||
|
||||
void SerialClass::flush() {
|
||||
UART_WaitBusy((UART_TypeDef *)data.uart, 10);
|
||||
}
|
||||
|
||||
size_t SerialClass::write(uint8_t c) {
|
||||
while (UART_Writable((UART_TypeDef *)data.uart) == 0) {}
|
||||
UART_CharPut((UART_TypeDef *)data.uart, c);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <api/ArduinoAPI.h>
|
||||
#include <api/HardwareSerial.h>
|
||||
#include <api/RingBuffer.h>
|
||||
|
||||
using namespace arduino;
|
||||
|
||||
typedef struct {
|
||||
void *uart; // UART_TypeDef
|
||||
RingBuffer *buf;
|
||||
} SerialData;
|
||||
|
||||
class SerialClass : public HardwareSerial {
|
||||
private:
|
||||
// data accessible to IRQ handler
|
||||
SerialData data;
|
||||
uint8_t irq; // IRQn
|
||||
pin_size_t rx;
|
||||
pin_size_t tx;
|
||||
|
||||
public:
|
||||
SerialClass(void *uart, uint8_t irq, pin_size_t rx, pin_size_t tx);
|
||||
|
||||
inline void begin(unsigned long baudrate) {
|
||||
begin(baudrate, SERIAL_8N1);
|
||||
}
|
||||
|
||||
void begin(unsigned long baudrate, uint16_t config);
|
||||
void end();
|
||||
int available();
|
||||
int peek();
|
||||
int read();
|
||||
void flush();
|
||||
size_t write(uint8_t c);
|
||||
|
||||
operator bool() {
|
||||
return !!data.buf;
|
||||
}
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
@@ -4,13 +4,5 @@
|
||||
|
||||
#define LT_ARD_HAS_WIFI 1
|
||||
#define LT_ARD_HAS_SOFTSERIAL 1
|
||||
#define LT_ARD_HAS_SERIAL 1
|
||||
|
||||
#define LT_ARD_MD5_POLARSSL 1
|
||||
|
||||
#define ARDUINO_AMEBA
|
||||
|
||||
// the SDK declares bool if not defined before
|
||||
// which conflicts with C++ built-in bool
|
||||
// so it's either -fpermissive or this:
|
||||
#define bool bool
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// the SDK declares bool if not defined before
|
||||
// which conflicts with C++ built-in bool
|
||||
// so it's either -fpermissive or this:
|
||||
#ifndef bool
|
||||
#define bool bool
|
||||
#endif
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
// for some reason, cmsis_os.c does not link properly when this method is inlined in core_cmFunc.h
|
||||
// (or I am too stupid to understand this)
|
||||
__attribute__((weak)) uint32_t __get_IPSR()
|
||||
{
|
||||
__attribute__((weak)) uint32_t __get_IPSR() {
|
||||
uint32_t result;
|
||||
asm volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||
asm volatile("MRS %0, ipsr" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
142
cores/realtek-ambz/arduino/libraries/Serial/Serial.cpp
Normal file
142
cores/realtek-ambz/arduino/libraries/Serial/Serial.cpp
Normal 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;
|
||||
}
|
||||
21
cores/realtek-ambz/arduino/libraries/Serial/SerialPrivate.h
Normal file
21
cores/realtek-ambz/arduino/libraries/Serial/SerialPrivate.h
Normal 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)
|
||||
7
cores/realtek-ambz/arduino/src/lt_defs.h
Normal file
7
cores/realtek-ambz/arduino/src/lt_defs.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -19,7 +19,7 @@ void putchar_(char c) {
|
||||
}
|
||||
|
||||
void putchar_p(char c, unsigned long port) {
|
||||
while (uart_dev[port]->lsr_b.txfifo_empty == 0) {}
|
||||
while ((uart_dev[port]->tflvr & 0x1F) > 15) {}
|
||||
uart_dev[port]->thr = c;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ Explicit is better than implicit.
|
||||
|
||||
### Other
|
||||
|
||||
- refactor `SerialClass` to have a shared header `Serial.h` in the common core (and `SerialData`, just like WiFi). Move ADR to common core
|
||||
- implement Wire on BK, refactor the API and class
|
||||
- watchdog API
|
||||
- `Preferences` library
|
||||
|
||||
Reference in New Issue
Block a user