mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
arch/arm/rtl8721dx: add shared Ameba UART driver.
Add a shared Ameba high-speed UART driver on top of the GPIO driver's common/ameba/ infrastructure, exposing UART0/UART1 through the NuttX serial upper half. - arch/arm/src/common/ameba/ameba_uart.c/.h: serial lower-half driver built on the SDK fwlib UART register layer (ROM symbol table). RX/TX dispatch through NuttX-native interrupts; TERMIOS get/set supported. The pins are muxed to the direction-specific UART crossbar function codes (TXD/RXD per controller) required by the amebadplus pinmux, and RX is pulled high through the SDK ROM. - arch/arm/src/common/ameba/Kconfig: AMEBA_UART option (selects SERIAL and ARCH_HAVE_SERIAL_TERMIOS) plus RX/TX buffer-size knobs. - arch/arm/src/rtl8721dx: wire ameba_uart.c into the Make/CMake builds and pull the fwlib ram_common UART table into the fwlib link set. - boards/arm/rtl8721dx/pke8721daf: board UART port table registering UART0 at /dev/ttyS1 (PB18/PB19, 115200), bring-up hook, and a uart NSH config with the serialrx/serialblaster examples. - Documentation: describe the driver and the uart board config. Verified on hardware (PKE8721DAF): pinmux routing, TX/RX and interrupt paths, and the TERMIOS ioctl path via loopback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: dechao_gong <dechao_gong@realsil.com.cn>
This commit is contained in:
parent
57c7e47a6b
commit
f8d6160022
15 changed files with 1066 additions and 2 deletions
|
|
@ -35,6 +35,8 @@ Supported in this NuttX port:
|
|||
* DHCP client (STA) and DHCP server (SoftAP)
|
||||
* GPIO pins exposed as ``/dev/gpioN`` character devices (input, output and
|
||||
interrupt), driven directly on the SDK fwlib register layer
|
||||
* General-purpose UARTs exposed as ``/dev/ttySN`` serial devices, driven
|
||||
directly on the SDK fwlib register layer
|
||||
|
||||
Buttons and LEDs
|
||||
================
|
||||
|
|
@ -78,6 +80,26 @@ Pins are encoded with the ``AMEBA_PA()`` / ``AMEBA_PB()`` helpers from
|
|||
``arch/arm/src/common/ameba/ameba_gpio.h`` (port A/B, pin 0-31), matching the
|
||||
Ameba SDK ``PinName`` layout.
|
||||
|
||||
uart
|
||||
----
|
||||
|
||||
Minimal NSH with the general-purpose UART driver and the ``serialrx`` /
|
||||
``serialblaster`` examples enabled (no Wi-Fi). The LOG-UART owns the console
|
||||
and ``/dev/ttyS0``, so the board registers UART0 from its table (see
|
||||
``boards/arm/rtl8721dx/pke8721daf/src/rtl8721dx_uart.c``) as ``/dev/ttyS1`` at
|
||||
115200 8N1. Edit that table -- controller, TX/RX pads and baud -- to match a
|
||||
board's wiring. The TX/RX pads use the same ``AMEBA_PA()`` / ``AMEBA_PB()``
|
||||
encoding as the GPIO table; the driver muxes them to the UART function and
|
||||
pulls RX high through the SDK ROM. Exercise the port with the examples (loop TX
|
||||
back to RX, or wire it to a host serial adapter)::
|
||||
|
||||
nsh> serialblaster # stream a test pattern out /dev/ttyS1
|
||||
nsh> serialrx # receive and dump bytes from /dev/ttyS1
|
||||
|
||||
The line format can be changed at runtime through ``tcsetattr()`` (the config
|
||||
enables ``CONFIG_SERIAL_TERMIOS``). UART2 is shared with Bluetooth and is not
|
||||
exposed by the driver.
|
||||
|
||||
Wi-Fi
|
||||
=====
|
||||
|
||||
|
|
|
|||
|
|
@ -22,4 +22,37 @@ config AMEBA_GPIO
|
|||
fwlib register layer and dispatches pin interrupts through the ROM
|
||||
GPIO interrupt handler.
|
||||
|
||||
config AMEBA_UART
|
||||
bool "UART"
|
||||
default n
|
||||
select SERIAL
|
||||
select ARCH_HAVE_SERIAL_TERMIOS
|
||||
---help---
|
||||
Expose the Ameba high-speed UARTs (UART0/UART1) through the NuttX
|
||||
serial upper half. The LOG-UART owns the console and /dev/ttyS0, so
|
||||
the board registers these general-purpose ports at /dev/ttyS1 and up
|
||||
in its bring-up code, giving the TX/RX pads and baud for each.
|
||||
|
||||
The driver (arch/arm/src/common/ameba/ameba_uart.c) sits on the SDK
|
||||
fwlib register layer and dispatches RX/TX through NuttX-native
|
||||
interrupts.
|
||||
|
||||
if AMEBA_UART
|
||||
|
||||
config AMEBA_UART_RXBUFSIZE
|
||||
int "UART receive buffer size"
|
||||
default 256
|
||||
---help---
|
||||
Size, in bytes, of the receive buffer allocated for each registered
|
||||
Ameba UART port.
|
||||
|
||||
config AMEBA_UART_TXBUFSIZE
|
||||
int "UART transmit buffer size"
|
||||
default 256
|
||||
---help---
|
||||
Size, in bytes, of the transmit buffer allocated for each registered
|
||||
Ameba UART port.
|
||||
|
||||
endif # AMEBA_UART
|
||||
|
||||
endmenu # Ameba Peripheral Support
|
||||
|
|
|
|||
|
|
@ -83,7 +83,9 @@ extern "C"
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEV_GPIO
|
||||
int ameba_gpio_register(int minor, uint8_t pin, enum gpio_pintype_e pintype);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
700
arch/arm/src/common/ameba/ameba_uart.c
Normal file
700
arch/arm/src/common/ameba/ameba_uart.c
Normal file
|
|
@ -0,0 +1,700 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/common/ameba/ameba_uart.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
/* NuttX serial lower half for the Realtek Ameba high-speed UARTs (UART0 and
|
||||
* UART1; UART2 is shared with Bluetooth and is not wired here). The
|
||||
* LOG-UART owns the console and /dev/ttyS0 (arch/.../ameba_loguart.c); this
|
||||
* driver registers the general-purpose UARTs from board bring-up, so they
|
||||
* appear as /dev/ttyS1 and up.
|
||||
*
|
||||
* The controller is programmed through the SDK fwlib UART API. NuttX runs
|
||||
* on the KM4 core in the SECURE state, so the fwlib routines resolve to the
|
||||
* secure register aliases via TrustZone_IsSecure() and reach the UART, the
|
||||
* PINMUX pad mux and the pull control without stall. Every symbol used here
|
||||
* (UART_Init, UART_SetBaud, UART_CharPut/Get, Pinmux_Config, PAD_PullCtrl,
|
||||
* RCC_PeriphClockCmd, ...) resolves to the on-chip ROM symbol table; the
|
||||
* fwlib data tables that ROM code indexes (UART_DEV_TABLE, APBPeriph_UARTx)
|
||||
* are compiled into libameba_fwlib.a (see AMEBA_FWLIB_SRCS). To keep the
|
||||
* vendor headers out of the NuttX include world, the few fwlib symbols and
|
||||
* the UART_InitTypeDef layout used here are declared locally below rather
|
||||
* than pulled in from <ameba_uart.h>.
|
||||
*
|
||||
* Interrupt dispatch stays NuttX-native: each UART's NVIC vector is owned by
|
||||
* NuttX (irq_attach), and the ISR drains RX / refills TX through the stock
|
||||
* uart_recvchars()/uart_xmitchars() upper-half helpers.
|
||||
*/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/serial/serial.h>
|
||||
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
# include <termios.h>
|
||||
#endif
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "ameba_uart.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Per-controller register base, peripheral clock mask and NuttX IRQ number.
|
||||
* The driver source is shared by every Ameba ARM chip; each chip's
|
||||
* <arch/irq.h> (pulled in by <nuttx/irq.h>) names its own vectors, so map
|
||||
* them onto chip-agnostic aliases here.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_CHIP_RTL8721DX)
|
||||
# define AMEBA_IRQ_UART0 RTL8721DX_IRQ_UART0
|
||||
# define AMEBA_IRQ_UART1 RTL8721DX_IRQ_UART1
|
||||
#else
|
||||
# error "Ameba UART: controller IRQ numbers not defined for this chip"
|
||||
#endif
|
||||
|
||||
#define AMEBA_UART0_BASE 0x4100c000ul
|
||||
#define AMEBA_UART1_BASE 0x4100d000ul
|
||||
|
||||
/* APBPeriph_UARTx / APBPeriph_UARTx_CLOCK (sysreg_lsys.h). */
|
||||
|
||||
#define AMEBA_APBPERIPH_UART0 (((uint32_t)1 << 30) | ((uint32_t)1 << 6))
|
||||
#define AMEBA_APBPERIPH_UART1 (((uint32_t)1 << 30) | ((uint32_t)1 << 7))
|
||||
|
||||
/* Pin mux function (ameba_pinmux.h) and pull control (ameba_gpio.h). RX is
|
||||
* held high while idle so a floating line is not read as a start bit.
|
||||
*
|
||||
* On this SoC (amebadplus) the pad mux is a crossbar: the generic
|
||||
* PINMUX_FUNCTION_UART code is not enough -- each pad must be routed with a
|
||||
* direction-specific function code so the crossbar knows which internal UART
|
||||
* signal to drive onto it (see the SDK's per-chip branch in the raw UART
|
||||
* example). The codes are indexed by controller in g_uart_txfid/rxfid.
|
||||
*/
|
||||
|
||||
#define AMEBA_PINMUX_UART0_TXD 19 /* PINMUX_FUNCTION_UART0_TXD */
|
||||
#define AMEBA_PINMUX_UART0_RXD 20 /* PINMUX_FUNCTION_UART0_RXD */
|
||||
#define AMEBA_PINMUX_UART1_TXD 23 /* PINMUX_FUNCTION_UART1_TXD */
|
||||
#define AMEBA_PINMUX_UART1_RXD 24 /* PINMUX_FUNCTION_UART1_RXD */
|
||||
#define AMEBA_GPIO_PUPD_UP 0x2 /* GPIO_PuPd_UP */
|
||||
|
||||
/* Mirror of the fwlib UART_InitTypeDef field values (ameba_uart.h). */
|
||||
|
||||
#define AMEBA_WLS_7BITS 0x0 /* RUART_WLS_7BITS */
|
||||
#define AMEBA_WLS_8BITS 0x1 /* RUART_WLS_8BITS */
|
||||
|
||||
#define AMEBA_STOP_BIT_1 0x0 /* RUART_STOP_BIT_1 */
|
||||
#define AMEBA_STOP_BIT_2 0x1 /* RUART_STOP_BIT_2 */
|
||||
|
||||
#define AMEBA_PARITY_DISABLE 0x0 /* RUART_PARITY_DISABLE */
|
||||
#define AMEBA_PARITY_ENABLE 0x1 /* RUART_PARITY_ENABLE */
|
||||
|
||||
#define AMEBA_ODD_PARITY 0x0 /* RUART_ODD_PARITY */
|
||||
#define AMEBA_EVEN_PARITY 0x1 /* RUART_EVEN_PARITY */
|
||||
|
||||
#define AMEBA_RX_FIFOTRIG_1 0x0 /* UART_RX_FIFOTRIG_LEVEL_1BYTES */
|
||||
|
||||
/* Interrupt enable register (IER) bits. */
|
||||
|
||||
#define AMEBA_UART_INT_ERBI ((uint32_t)1 << 0) /* Rx data available */
|
||||
#define AMEBA_UART_INT_ETBEI ((uint32_t)1 << 1) /* Tx FIFO empty */
|
||||
#define AMEBA_UART_INT_ETOI ((uint32_t)1 << 5) /* Rx timeout */
|
||||
|
||||
/* Line status register (LSR) bits. */
|
||||
|
||||
#define AMEBA_UART_LSR_TX_EMPTY ((uint32_t)1 << 5) /* Tx FIFO empty */
|
||||
|
||||
/* Second/third argument to fwlib "state" style APIs. */
|
||||
|
||||
#define AMEBA_DISABLE 0x0
|
||||
#define AMEBA_ENABLE 0x1
|
||||
|
||||
/* Number of general-purpose controllers this driver can address. */
|
||||
|
||||
#define AMEBA_NUART 2
|
||||
|
||||
/* Local parity encoding (priv->parity). */
|
||||
|
||||
#define AMEBA_PARITY_NONE 0
|
||||
#define AMEBA_PARITY_ODD 1
|
||||
#define AMEBA_PARITY_EVEN 2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Layout-compatible mirror of the fwlib UART_InitTypeDef (all u32, same
|
||||
* order); passed by address to UART_Init().
|
||||
*/
|
||||
|
||||
struct ameba_uart_init_s
|
||||
{
|
||||
uint32_t dmamodectrl; /* DmaModeCtrl */
|
||||
uint32_t wordlen; /* WordLen */
|
||||
uint32_t stopbit; /* StopBit */
|
||||
uint32_t parity; /* Parity */
|
||||
uint32_t paritytype; /* ParityType */
|
||||
uint32_t stickparity; /* StickParity */
|
||||
uint32_t flowcontrol; /* FlowControl */
|
||||
uint32_t rxfifotriglevel; /* RxFifoTrigLevel */
|
||||
uint32_t rxerreportctrl; /* RxErReportCtrl */
|
||||
uint32_t rxtimeoutcnt; /* RxTimeOutCnt */
|
||||
};
|
||||
|
||||
struct ameba_uart_dev_s
|
||||
{
|
||||
struct uart_dev_s dev; /* Serial upper-half device (must be first) */
|
||||
uintptr_t base; /* UART register base address */
|
||||
int irq; /* NuttX interrupt vector */
|
||||
uint32_t clk; /* APBPeriph mask for RCC_PeriphClockCmd() */
|
||||
uint32_t baud; /* Baud rate */
|
||||
uint8_t txpin; /* TX pad (AMEBA_PA()/AMEBA_PB() encoding) */
|
||||
uint8_t rxpin; /* RX pad (AMEBA_PA()/AMEBA_PB() encoding) */
|
||||
uint8_t txfid; /* Pin mux function code for the TX pad */
|
||||
uint8_t rxfid; /* Pin mux function code for the RX pad */
|
||||
uint8_t bits; /* Data bits (7 or 8) */
|
||||
uint8_t parity; /* AMEBA_PARITY_NONE / _ODD / _EVEN */
|
||||
bool stop2; /* True: 2 stop bits, false: 1 */
|
||||
bool txint; /* True while the TX interrupt is unmasked */
|
||||
spinlock_t lock; /* Serializes IER updates vs the ISR */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* SDK fwlib UART/pin/clock API (all resolve to the ROM symbol table). */
|
||||
|
||||
extern void RCC_PeriphClockCmd(uint32_t periph, uint32_t clock,
|
||||
uint8_t newstate);
|
||||
extern void Pinmux_Config(uint8_t pin, uint32_t func);
|
||||
extern void PAD_PullCtrl(uint8_t pin, uint8_t pull);
|
||||
extern void UART_DeInit(void *uartx);
|
||||
extern void UART_StructInit(struct ameba_uart_init_s *init);
|
||||
extern void UART_Init(void *uartx, struct ameba_uart_init_s *init);
|
||||
extern void UART_SetBaud(void *uartx, uint32_t baud);
|
||||
extern void UART_RxCmd(void *uartx, uint32_t newstate);
|
||||
extern uint32_t UART_Writable(void *uartx);
|
||||
extern uint32_t UART_Readable(void *uartx);
|
||||
extern void UART_CharPut(void *uartx, uint8_t txdata);
|
||||
extern void UART_CharGet(void *uartx, uint8_t *rxbyte);
|
||||
extern void UART_INTConfig(void *uartx, uint32_t uart_it, uint32_t newstate);
|
||||
extern uint32_t UART_LineStatusGet(void *uartx);
|
||||
|
||||
/* Serial lower-half operations. */
|
||||
|
||||
static int ameba_uart_setup(struct uart_dev_s *dev);
|
||||
static void ameba_uart_shutdown(struct uart_dev_s *dev);
|
||||
static int ameba_uart_attach(struct uart_dev_s *dev);
|
||||
static void ameba_uart_detach(struct uart_dev_s *dev);
|
||||
static int ameba_uart_ioctl(struct file *filep, int cmd,
|
||||
unsigned long arg);
|
||||
static int ameba_uart_receive(struct uart_dev_s *dev, unsigned int *status);
|
||||
static void ameba_uart_rxint(struct uart_dev_s *dev, bool enable);
|
||||
static bool ameba_uart_rxavailable(struct uart_dev_s *dev);
|
||||
static void ameba_uart_send(struct uart_dev_s *dev, int ch);
|
||||
static void ameba_uart_txint(struct uart_dev_s *dev, bool enable);
|
||||
static bool ameba_uart_txready(struct uart_dev_s *dev);
|
||||
static bool ameba_uart_txempty(struct uart_dev_s *dev);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct uart_ops_s g_ameba_uart_ops =
|
||||
{
|
||||
.setup = ameba_uart_setup,
|
||||
.shutdown = ameba_uart_shutdown,
|
||||
.attach = ameba_uart_attach,
|
||||
.detach = ameba_uart_detach,
|
||||
.ioctl = ameba_uart_ioctl,
|
||||
.receive = ameba_uart_receive,
|
||||
.rxint = ameba_uart_rxint,
|
||||
.rxavailable = ameba_uart_rxavailable,
|
||||
.send = ameba_uart_send,
|
||||
.txint = ameba_uart_txint,
|
||||
.txready = ameba_uart_txready,
|
||||
.txempty = ameba_uart_txempty,
|
||||
};
|
||||
|
||||
/* Per-controller register base, peripheral clock and IRQ, indexed by the
|
||||
* AMEBA_UART0/AMEBA_UART1 controller number.
|
||||
*/
|
||||
|
||||
static const uintptr_t g_uart_base[AMEBA_NUART] =
|
||||
{
|
||||
AMEBA_UART0_BASE,
|
||||
AMEBA_UART1_BASE,
|
||||
};
|
||||
|
||||
static const uint32_t g_uart_clk[AMEBA_NUART] =
|
||||
{
|
||||
AMEBA_APBPERIPH_UART0,
|
||||
AMEBA_APBPERIPH_UART1,
|
||||
};
|
||||
|
||||
static const int g_uart_irq[AMEBA_NUART] =
|
||||
{
|
||||
AMEBA_IRQ_UART0,
|
||||
AMEBA_IRQ_UART1,
|
||||
};
|
||||
|
||||
/* Direction-specific pad mux function codes, indexed by controller. */
|
||||
|
||||
static const uint8_t g_uart_txfid[AMEBA_NUART] =
|
||||
{
|
||||
AMEBA_PINMUX_UART0_TXD,
|
||||
AMEBA_PINMUX_UART1_TXD,
|
||||
};
|
||||
|
||||
static const uint8_t g_uart_rxfid[AMEBA_NUART] =
|
||||
{
|
||||
AMEBA_PINMUX_UART0_RXD,
|
||||
AMEBA_PINMUX_UART1_RXD,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_configure
|
||||
*
|
||||
* Description:
|
||||
* Gate the peripheral clock, route the TX/RX pads to the UART function and
|
||||
* program the line format and baud through fwlib UART_Init()/SetBaud(),
|
||||
* then enable the receiver. Called from setup() and on a termios change.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ameba_uart_configure(struct ameba_uart_dev_s *priv)
|
||||
{
|
||||
struct ameba_uart_init_s init;
|
||||
void *uartx = (void *)priv->base;
|
||||
|
||||
/* Gate on the UART peripheral clock (idempotent). */
|
||||
|
||||
RCC_PeriphClockCmd(priv->clk, priv->clk, AMEBA_ENABLE);
|
||||
|
||||
/* Route the pads to this controller's TX/RX signals through the crossbar;
|
||||
* hold RX high while idle.
|
||||
*/
|
||||
|
||||
Pinmux_Config(priv->txpin, priv->txfid);
|
||||
Pinmux_Config(priv->rxpin, priv->rxfid);
|
||||
PAD_PullCtrl(priv->rxpin, AMEBA_GPIO_PUPD_UP);
|
||||
|
||||
/* Start from the fwlib defaults, then apply the requested line format. */
|
||||
|
||||
UART_StructInit(&init);
|
||||
|
||||
init.wordlen = (priv->bits == 7) ?
|
||||
AMEBA_WLS_7BITS : AMEBA_WLS_8BITS;
|
||||
init.stopbit = priv->stop2 ? AMEBA_STOP_BIT_2 : AMEBA_STOP_BIT_1;
|
||||
init.flowcontrol = AMEBA_DISABLE;
|
||||
init.rxfifotriglevel = AMEBA_RX_FIFOTRIG_1;
|
||||
|
||||
if (priv->parity == AMEBA_PARITY_NONE)
|
||||
{
|
||||
init.parity = AMEBA_PARITY_DISABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
init.parity = AMEBA_PARITY_ENABLE;
|
||||
init.paritytype = (priv->parity == AMEBA_PARITY_ODD) ?
|
||||
AMEBA_ODD_PARITY : AMEBA_EVEN_PARITY;
|
||||
}
|
||||
|
||||
UART_Init(uartx, &init);
|
||||
UART_SetBaud(uartx, priv->baud);
|
||||
UART_RxCmd(uartx, AMEBA_ENABLE);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_interrupt
|
||||
*
|
||||
* Description:
|
||||
* Common UART interrupt handler. Drains the RX FIFO into the receive
|
||||
* buffer and, while the TX interrupt is unmasked, refills the TX FIFO from
|
||||
* the transmit buffer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int ameba_uart_interrupt(int irq, void *context, void *arg)
|
||||
{
|
||||
struct uart_dev_s *dev = (struct uart_dev_s *)arg;
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
void *uartx = (void *)priv->base;
|
||||
|
||||
UNUSED(irq);
|
||||
UNUSED(context);
|
||||
|
||||
/* Reading the line status register clears any latched RX error bits. */
|
||||
|
||||
UART_LineStatusGet(uartx);
|
||||
|
||||
if (UART_Readable(uartx))
|
||||
{
|
||||
uart_recvchars(dev);
|
||||
}
|
||||
|
||||
if (priv->txint && UART_Writable(uartx))
|
||||
{
|
||||
uart_xmitchars(dev);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_setup
|
||||
****************************************************************************/
|
||||
|
||||
static int ameba_uart_setup(struct uart_dev_s *dev)
|
||||
{
|
||||
ameba_uart_configure((struct ameba_uart_dev_s *)dev);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_shutdown
|
||||
****************************************************************************/
|
||||
|
||||
static void ameba_uart_shutdown(struct uart_dev_s *dev)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
ameba_uart_rxint(dev, false);
|
||||
ameba_uart_txint(dev, false);
|
||||
UART_DeInit((void *)priv->base);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_attach
|
||||
****************************************************************************/
|
||||
|
||||
static int ameba_uart_attach(struct uart_dev_s *dev)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
int ret;
|
||||
|
||||
ret = irq_attach(priv->irq, ameba_uart_interrupt, dev);
|
||||
if (ret == OK)
|
||||
{
|
||||
up_enable_irq(priv->irq);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_detach
|
||||
****************************************************************************/
|
||||
|
||||
static void ameba_uart_detach(struct uart_dev_s *dev)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
up_disable_irq(priv->irq);
|
||||
irq_detach(priv->irq);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_ioctl
|
||||
****************************************************************************/
|
||||
|
||||
static int ameba_uart_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
#ifdef CONFIG_SERIAL_TERMIOS
|
||||
struct inode *inode = filep->f_inode;
|
||||
struct uart_dev_s *dev = inode->i_private;
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case TCGETS:
|
||||
{
|
||||
struct termios *termiosp = (struct termios *)(uintptr_t)arg;
|
||||
tcflag_t ccflag;
|
||||
|
||||
if (termiosp == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ccflag = (priv->bits == 7) ? CS7 : CS8;
|
||||
if (priv->parity != AMEBA_PARITY_NONE)
|
||||
{
|
||||
ccflag |= PARENB;
|
||||
if (priv->parity == AMEBA_PARITY_ODD)
|
||||
{
|
||||
ccflag |= PARODD;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->stop2)
|
||||
{
|
||||
ccflag |= CSTOPB;
|
||||
}
|
||||
|
||||
termiosp->c_cflag = ccflag;
|
||||
cfsetispeed(termiosp, priv->baud);
|
||||
cfsetospeed(termiosp, priv->baud);
|
||||
return OK;
|
||||
}
|
||||
|
||||
case TCSETS:
|
||||
{
|
||||
struct termios *termiosp = (struct termios *)(uintptr_t)arg;
|
||||
irqstate_t flags;
|
||||
|
||||
if (termiosp == NULL)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
priv->bits = ((termiosp->c_cflag & CSIZE) == CS7) ? 7 : 8;
|
||||
priv->stop2 = (termiosp->c_cflag & CSTOPB) != 0;
|
||||
|
||||
if ((termiosp->c_cflag & PARENB) == 0)
|
||||
{
|
||||
priv->parity = AMEBA_PARITY_NONE;
|
||||
}
|
||||
else if ((termiosp->c_cflag & PARODD) != 0)
|
||||
{
|
||||
priv->parity = AMEBA_PARITY_ODD;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->parity = AMEBA_PARITY_EVEN;
|
||||
}
|
||||
|
||||
priv->baud = cfgetispeed(termiosp);
|
||||
|
||||
ameba_uart_configure(priv);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
#else
|
||||
UNUSED(filep);
|
||||
UNUSED(cmd);
|
||||
UNUSED(arg);
|
||||
return -ENOTTY;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_receive
|
||||
****************************************************************************/
|
||||
|
||||
static int ameba_uart_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
uint8_t rxbyte = 0;
|
||||
|
||||
*status = 0;
|
||||
UART_CharGet((void *)priv->base, &rxbyte);
|
||||
return rxbyte;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_rxint
|
||||
****************************************************************************/
|
||||
|
||||
static void ameba_uart_rxint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
/* Enable both the RX-trigger and RX-timeout sources so that bytes still
|
||||
* held below the FIFO trigger level are delivered promptly.
|
||||
*/
|
||||
|
||||
UART_INTConfig((void *)priv->base,
|
||||
AMEBA_UART_INT_ERBI | AMEBA_UART_INT_ETOI,
|
||||
enable ? AMEBA_ENABLE : AMEBA_DISABLE);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_rxavailable
|
||||
****************************************************************************/
|
||||
|
||||
static bool ameba_uart_rxavailable(struct uart_dev_s *dev)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
return UART_Readable((void *)priv->base) != 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_send
|
||||
****************************************************************************/
|
||||
|
||||
static void ameba_uart_send(struct uart_dev_s *dev, int ch)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
UART_CharPut((void *)priv->base, (uint8_t)ch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_txint
|
||||
*
|
||||
* Description:
|
||||
* Unmask/mask the TX-FIFO-empty interrupt. Enabling it while the FIFO is
|
||||
* already empty asserts the interrupt at once, so the ISR pumps the first
|
||||
* bytes; uart_xmitchars() re-disables it once the transmit buffer drains.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void ameba_uart_txint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&priv->lock);
|
||||
|
||||
priv->txint = enable;
|
||||
UART_INTConfig((void *)priv->base, AMEBA_UART_INT_ETBEI,
|
||||
enable ? AMEBA_ENABLE : AMEBA_DISABLE);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_txready
|
||||
****************************************************************************/
|
||||
|
||||
static bool ameba_uart_txready(struct uart_dev_s *dev)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
return UART_Writable((void *)priv->base) != 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_txempty
|
||||
****************************************************************************/
|
||||
|
||||
static bool ameba_uart_txempty(struct uart_dev_s *dev)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv = (struct ameba_uart_dev_s *)dev;
|
||||
|
||||
return (UART_LineStatusGet((void *)priv->base) &
|
||||
AMEBA_UART_LSR_TX_EMPTY) != 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_register
|
||||
*
|
||||
* Description:
|
||||
* See ameba_uart.h.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ameba_uart_register(const char *path, int uart, uint8_t txpin,
|
||||
uint8_t rxpin, uint32_t baud)
|
||||
{
|
||||
struct ameba_uart_dev_s *priv;
|
||||
char *rxbuffer;
|
||||
char *txbuffer;
|
||||
int ret;
|
||||
|
||||
if (uart < 0 || uart >= AMEBA_NUART || path == NULL || baud == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv = kmm_zalloc(sizeof(struct ameba_uart_dev_s));
|
||||
if (priv == NULL)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rxbuffer = kmm_malloc(CONFIG_AMEBA_UART_RXBUFSIZE);
|
||||
txbuffer = kmm_malloc(CONFIG_AMEBA_UART_TXBUFSIZE);
|
||||
if (rxbuffer == NULL || txbuffer == NULL)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
priv->base = g_uart_base[uart];
|
||||
priv->clk = g_uart_clk[uart];
|
||||
priv->irq = g_uart_irq[uart];
|
||||
priv->txpin = txpin;
|
||||
priv->rxpin = rxpin;
|
||||
priv->txfid = g_uart_txfid[uart];
|
||||
priv->rxfid = g_uart_rxfid[uart];
|
||||
priv->baud = baud;
|
||||
priv->bits = 8;
|
||||
priv->parity = AMEBA_PARITY_NONE;
|
||||
priv->stop2 = false;
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
priv->dev.recv.size = CONFIG_AMEBA_UART_RXBUFSIZE;
|
||||
priv->dev.recv.buffer = rxbuffer;
|
||||
priv->dev.xmit.size = CONFIG_AMEBA_UART_TXBUFSIZE;
|
||||
priv->dev.xmit.buffer = txbuffer;
|
||||
priv->dev.ops = &g_ameba_uart_ops;
|
||||
|
||||
ret = uart_register(path, &priv->dev);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: uart_register(%s) failed: %d\n", path, ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
errout:
|
||||
kmm_free(rxbuffer);
|
||||
kmm_free(txbuffer);
|
||||
kmm_free(priv);
|
||||
return ret;
|
||||
}
|
||||
90
arch/arm/src/common/ameba/ameba_uart.h
Normal file
90
arch/arm/src/common/ameba/ameba_uart.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/common/ameba/ameba_uart.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_COMMON_AMEBA_AMEBA_UART_H
|
||||
#define __ARCH_ARM_SRC_COMMON_AMEBA_AMEBA_UART_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* The Ameba high-speed UART controllers exposed to NuttX. UART2 is shared
|
||||
* with Bluetooth on this family and is not wired for general serial use, so
|
||||
* only UART0 and UART1 are registered by boards. TX/RX pins are given with
|
||||
* the same AMEBA_PA()/AMEBA_PB() PinName encoding used by the GPIO driver
|
||||
* (see ameba_gpio.h); any pad can be routed to a UART through the pin mux.
|
||||
*/
|
||||
|
||||
#define AMEBA_UART0 0
|
||||
#define AMEBA_UART1 1
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ameba_uart_register
|
||||
*
|
||||
* Description:
|
||||
* Configure one Ameba high-speed UART and register it with the NuttX
|
||||
* serial upper half at the given device path (e.g. "/dev/ttyS1"). The
|
||||
* LOG-UART console is owned separately (arch/.../ameba_loguart.c) and
|
||||
* already occupies /dev/ttyS0, so boards register the general-purpose
|
||||
* UARTs starting at /dev/ttyS1.
|
||||
*
|
||||
* Input Parameters:
|
||||
* path - The serial device path to register (e.g. "/dev/ttyS1").
|
||||
* uart - The controller index, AMEBA_UART0 or AMEBA_UART1.
|
||||
* txpin - The TX pad, encoded with AMEBA_PA()/AMEBA_PB().
|
||||
* rxpin - The RX pad, encoded with AMEBA_PA()/AMEBA_PB().
|
||||
* baud - The initial baud rate.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int ameba_uart_register(const char *path, int uart, uint8_t txpin,
|
||||
uint8_t rxpin, uint32_t baud);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_COMMON_AMEBA_AMEBA_UART_H */
|
||||
|
|
@ -44,6 +44,10 @@ if(CONFIG_AMEBA_GPIO)
|
|||
list(APPEND SRCS ${AMEBA_COMMON}/ameba_gpio.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_AMEBA_UART)
|
||||
list(APPEND SRCS ${AMEBA_COMMON}/ameba_uart.c)
|
||||
endif()
|
||||
|
||||
target_include_directories(arch PRIVATE ${AMEBA_COMMON})
|
||||
target_sources(arch PRIVATE ${SRCS})
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ ifeq ($(CONFIG_AMEBA_GPIO),y)
|
|||
CHIP_CSRCS += ameba_gpio.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AMEBA_UART),y)
|
||||
CHIP_CSRCS += ameba_uart.c
|
||||
endif
|
||||
|
||||
############################################################################
|
||||
# Realtek RTL8721Dx SDK integration
|
||||
#
|
||||
|
|
|
|||
|
|
@ -128,6 +128,15 @@ ifeq ($(CONFIG_AMEBA_GPIO),y)
|
|||
AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_gpio.c
|
||||
endif
|
||||
|
||||
# UART register layer. The UART driver (arch/.../common/ameba/ameba_uart.c)
|
||||
# calls the fwlib UART API, all of which resolves to the ROM symbol table; but
|
||||
# the ROM routines index the fwlib data tables (UART_DEV_TABLE, APBPeriph_UARTx)
|
||||
# which live in this RAM source and must be compiled in (--gc-sections drops
|
||||
# the unused DMA/monitor helpers).
|
||||
ifeq ($(CONFIG_AMEBA_UART),y)
|
||||
AMEBA_FWLIB_SRCS += $(AMEBA_SOC)/fwlib/ram_common/ameba_uart.c
|
||||
endif
|
||||
|
||||
# -Wno-int-conversion: the vendored SDK passes NULL to irq_register()'s u32
|
||||
# "Data" (interrupt context) argument in many places -- an intentional
|
||||
# NULL-as-context idiom. Silence -Wint-conversion for the SDK fwlib sources
|
||||
|
|
|
|||
55
boards/arm/rtl8721dx/pke8721daf/configs/uart/defconfig
Normal file
55
boards/arm/rtl8721dx/pke8721daf/configs/uart/defconfig
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# This file is autogenerated: PLEASE DO NOT EDIT IT.
|
||||
#
|
||||
# You can use "make menuconfig" to make any modifications to the installed .config file.
|
||||
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
|
||||
# modifications.
|
||||
#
|
||||
# CONFIG_DEBUG_WARN is not set
|
||||
CONFIG_AMEBA_UART=y
|
||||
CONFIG_ARCH="arm"
|
||||
CONFIG_ARCH_BOARD="pke8721daf"
|
||||
CONFIG_ARCH_BOARD_PKE8721DAF=y
|
||||
CONFIG_ARCH_CHIP="rtl8721dx"
|
||||
CONFIG_ARCH_CHIP_RTL8721DX=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=2048
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_ARMV8M_SYSTICK=y
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_ASSERTIONS=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_EXAMPLES_SERIALBLASTER=y
|
||||
CONFIG_EXAMPLES_SERIALBLASTER_DEVPATH="/dev/ttyS1"
|
||||
CONFIG_EXAMPLES_SERIALRX=y
|
||||
CONFIG_EXAMPLES_SERIALRX_DEVPATH="/dev/ttyS1"
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_TMPFS=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=4096
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_LIBC_MEMFD_ERROR=y
|
||||
CONFIG_MM_DEFAULT_ALIGNMENT=32
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_PREALLOC_TIMERS=4
|
||||
CONFIG_RAM_SIZE=294912
|
||||
CONFIG_RAM_START=0x20020000
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_RTL8721DX_FLASH_FS=y
|
||||
CONFIG_SCHED_HPWORK=y
|
||||
CONFIG_SCHED_HPWORKPRIORITY=192
|
||||
CONFIG_SCHED_LPWORK=y
|
||||
CONFIG_SERIAL_TERMIOS=y
|
||||
CONFIG_STACK_COLORATION=y
|
||||
CONFIG_START_DAY=16
|
||||
CONFIG_START_MONTH=6
|
||||
CONFIG_START_YEAR=2026
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_SYSTEM_NSH_STACKSIZE=2500
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_TIMER_ARCH=y
|
||||
CONFIG_USEC_PER_TICK=1000
|
||||
|
|
@ -26,10 +26,14 @@ if(CONFIG_AMEBA_GPIO)
|
|||
list(APPEND SRCS rtl8721dx_gpio.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_AMEBA_UART)
|
||||
list(APPEND SRCS rtl8721dx_uart.c)
|
||||
endif()
|
||||
|
||||
target_sources(board PRIVATE ${SRCS})
|
||||
|
||||
if(CONFIG_AMEBA_GPIO)
|
||||
# The board pin table pulls in the shared driver's public header from
|
||||
if(CONFIG_AMEBA_GPIO OR CONFIG_AMEBA_UART)
|
||||
# The board pin/UART tables pull in the shared driver's public headers from
|
||||
# arch/arm/src/common/ameba/, not on the default board include path.
|
||||
target_include_directories(board
|
||||
PRIVATE ${NUTTX_DIR}/arch/arm/src/common/ameba)
|
||||
|
|
|
|||
|
|
@ -33,4 +33,13 @@ CSRCS += rtl8721dx_gpio.c
|
|||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)common$(DELIM)ameba
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AMEBA_UART),y)
|
||||
CSRCS += rtl8721dx_uart.c
|
||||
|
||||
# The board UART table pulls in the shared driver's public header from
|
||||
# arch/arm/src/common/ameba/, which is not on the default board include path.
|
||||
|
||||
CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)arm$(DELIM)src$(DELIM)common$(DELIM)ameba
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
||||
|
|
|
|||
|
|
@ -118,6 +118,16 @@ int rtl8721dx_bringup(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AMEBA_UART
|
||||
/* Register the board's general-purpose UART ports at /dev/ttySN. */
|
||||
|
||||
ret = rtl8721dx_uart_initialize();
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: rtl8721dx_uart_initialize failed: %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Install the inter-core HW IPC-semaphore RTOS hooks LAST -- after all the
|
||||
* flash / WHC bring-up above, and just before this (board_late_initialize)
|
||||
* path returns and nx_start() hands off to the init task.
|
||||
|
|
|
|||
|
|
@ -81,6 +81,20 @@ int rtl8721dx_wifi_initialize(void);
|
|||
int rtl8721dx_gpio_initialize(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AMEBA_UART
|
||||
/****************************************************************************
|
||||
* Name: rtl8721dx_uart_initialize
|
||||
*
|
||||
* Description:
|
||||
* Register the board's general-purpose UART ports with the NuttX serial
|
||||
* upper half
|
||||
* (boards/arm/rtl8721dx/pke8721daf/src/rtl8721dx_uart.c).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rtl8721dx_uart_initialize(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_RTL8721DX_FLASH_FS
|
||||
/****************************************************************************
|
||||
* Name: ameba_flash_fs_initialize
|
||||
|
|
|
|||
105
boards/arm/rtl8721dx/pke8721daf/src/rtl8721dx_uart.c
Normal file
105
boards/arm/rtl8721dx/pke8721daf/src/rtl8721dx_uart.c
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/****************************************************************************
|
||||
* boards/arm/rtl8721dx/pke8721daf/src/rtl8721dx_uart.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "ameba_gpio.h"
|
||||
#include "ameba_uart.h"
|
||||
#include "rtl8721dx_pke8721daf.h"
|
||||
|
||||
#ifdef CONFIG_AMEBA_UART
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* One entry per general-purpose UART exposed to NuttX. The LOG-UART owns
|
||||
* the console and /dev/ttyS0, so these ports are registered starting at
|
||||
* /dev/ttyS1 in the order listed below. The TX/RX pads are examples used by
|
||||
* the `uart` config (examples/serialrx / serialblaster) -- any pad can be
|
||||
* routed to a UART through the pin mux, so adjust them to match your board's
|
||||
* wiring.
|
||||
*/
|
||||
|
||||
struct rtl8721dx_uart_s
|
||||
{
|
||||
const char *path; /* Device path (/dev/ttyS1, ...) */
|
||||
int uart; /* Controller index (AMEBA_UART0/AMEBA_UART1) */
|
||||
uint8_t txpin; /* TX pad (AMEBA_PA()/AMEBA_PB() encoding) */
|
||||
uint8_t rxpin; /* RX pad (AMEBA_PA()/AMEBA_PB() encoding) */
|
||||
uint32_t baud; /* Initial baud rate */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct rtl8721dx_uart_s g_uart_ports[] =
|
||||
{
|
||||
{
|
||||
"/dev/ttyS1", AMEBA_UART0, AMEBA_PB(18), AMEBA_PB(19), 115200
|
||||
},
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rtl8721dx_uart_initialize
|
||||
*
|
||||
* Description:
|
||||
* Register the board's general-purpose UART ports with the NuttX serial
|
||||
* upper half.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rtl8721dx_uart_initialize(void)
|
||||
{
|
||||
int ret;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nitems(g_uart_ports); i++)
|
||||
{
|
||||
ret = ameba_uart_register(g_uart_ports[i].path, g_uart_ports[i].uart,
|
||||
g_uart_ports[i].txpin, g_uart_ports[i].rxpin,
|
||||
g_uart_ports[i].baud);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR,
|
||||
"ERROR: ameba_uart_register(%s) failed: %d\n",
|
||||
g_uart_ports[i].path, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_AMEBA_UART */
|
||||
|
|
@ -278,10 +278,13 @@ static const char *g_white_prefix[] =
|
|||
"OSC2M_",
|
||||
"OSC4M_",
|
||||
"OSC131K_",
|
||||
"PAD_",
|
||||
"Pinmux_",
|
||||
"RCC_",
|
||||
"RTCIO_",
|
||||
"SYSCFG_",
|
||||
"SYSTIMER_",
|
||||
"UART_",
|
||||
"SystemCoreClock", /* SystemCoreClock, SystemCoreClockUpdate */
|
||||
"cmse_", /* ARM CMSE TrustZone intrinsics (arm_cmse.h) */
|
||||
"MQTTErrors", /* apps/tools/netutils/mqttc/MQTT-C/include/mqtt.h */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue