support uart1-uart3 for k210 on Nuttx

This commit is contained in:
wgzAIIT 2022-09-27 20:54:22 +08:00
parent 3bec8f496a
commit 281389af1c
13 changed files with 8683 additions and 119 deletions

View File

@ -79,6 +79,26 @@ extern "C"
#define EXTERN extern #define EXTERN extern
#endif #endif
#define GPIO_CAN_RXD 18
#define GPIO_CAN_TXD 19
#define GPIO_EC200T_RXD 21
#define GPIO_EC200T_TXD 20
#define GPIO_CH376T_RXD 22
#define GPIO_CH376T_TXD 23
#define FPOA_USART1_RX K210_IO_FUNC_UART1_RX
#define FPOA_USART1_TX K210_IO_FUNC_UART1_TX
#define FPOA_USART2_RX K210_IO_FUNC_UART2_RX
#define FPOA_USART2_TX K210_IO_FUNC_UART2_TX
#define FPOA_USART3_RX K210_IO_FUNC_UART3_RX
#define FPOA_USART3_TX K210_IO_FUNC_UART3_TX
/**************************************************************************** /****************************************************************************
* Public Function Prototypes * Public Function Prototypes
****************************************************************************/ ****************************************************************************/

View File

@ -36,6 +36,8 @@
#include "k210.h" #include "k210.h"
#include "k210_clockconfig.h" #include "k210_clockconfig.h"
#include "xidatong-riscv64.h" #include "xidatong-riscv64.h"
#include <arch/board/board.h>
#include "k210_sysctl.h"
#ifdef CONFIG_BSP_USING_CH438 #ifdef CONFIG_BSP_USING_CH438
# include "k210_ch438.h" # include "k210_ch438.h"
@ -85,5 +87,31 @@ int k210_bringup(void)
} }
#endif #endif
#ifdef CONFIG_K210_16550_UART1
sysctl_clock_enable(SYSCTL_CLOCK_UART1);
sysctl_reset(SYSCTL_RESET_UART1);
fpioa_set_function(GPIO_CAN_RXD, FPOA_USART1_RX);
fpioa_set_function(GPIO_CAN_TXD, FPOA_USART1_TX);
#endif
#ifdef CONFIG_K210_16550_UART2
sysctl_clock_enable(SYSCTL_CLOCK_UART2);
sysctl_reset(SYSCTL_RESET_UART2);
fpioa_set_function(GPIO_EC200T_RXD, FPOA_USART2_RX);
fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX);
#endif
#ifdef CONFIG_K210_16550_UART3
sysctl_clock_enable(SYSCTL_CLOCK_UART3);
sysctl_reset(SYSCTL_RESET_UART3);
fpioa_set_function(GPIO_CH376T_RXD, FPOA_USART3_RX);
fpioa_set_function(GPIO_CH376T_TXD, FPOA_USART3_TX);
#endif
#ifdef CONFIG_BSP_USING_ENET
k210_sysctl_init();
board_enet_initialize();
#endif
return ret; return ret;
} }

View File

@ -0,0 +1,49 @@
/****************************************************************************
* arch/risc-v/include/k210/irq.h
*
* 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_RISCV_INCLUDE_K210_IRQ_H
#define __ARCH_RISCV_INCLUDE_K210_IRQ_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <arch/irq.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Map RISC-V exception code to NuttX IRQ */
#ifdef CONFIG_K210_WITH_QEMU
#define K210_IRQ_UART0 (RISCV_IRQ_MEXT + 4)
#else
#define K210_IRQ_UART0 (RISCV_IRQ_MEXT + 33)
#define K210_IRQ_UART1 (RISCV_IRQ_MEXT + 11)
#define K210_IRQ_UART2 (RISCV_IRQ_MEXT + 12)
#define K210_IRQ_UART3 (RISCV_IRQ_MEXT + 13)
#endif
/* Total number of IRQs */
#define NR_IRQS (64 + 16 +16)
#endif /* __ARCH_RISCV_INCLUDE_K210_IRQ_H */

View File

@ -40,6 +40,273 @@ config K210_LCD_BACKLIGHT
endmenu endmenu
menuconfig K210_16550_UART
bool "K210 16550 UART Chip support"
select ARCH_HAVE_SERIAL_TERMIOS
default n
if K210_16550_UART
config K210_16550_SERIAL_DISABLE_REORDERING
bool "Disable reordering of ttySx devices."
default n
---help---
NuttX per default reorders the serial ports (/dev/ttySx) so that the
console is always on /dev/ttyS0. If more than one UART is in use this
can, however, have the side-effect that all port mappings
(hardware USART1 -> /dev/ttyS0) change if the console is moved to another
UART. This option disables that re-ordering for 16550 UARTs.
config K210_16550_UART1
bool "K210 16550 UART1"
default n
if K210_16550_UART1
config K210_16550_UART1_BASE
hex "K210 16550 UART1 base address"
default 0x50210000
config K210_16550_UART1_CLOCK
int "K210 16550 UART1 clock"
default 195000000
config K210_16550_UART1_IRQ
int "K210 16550 UART1 IRQ number"
default 38
config K210_16550_UART1_BAUD
int "K210 16550 UART1 BAUD"
default 115200
config K210_16550_UART1_PARITY
int "K210 16550 UART1 parity"
default 0
range 0 2
---help---
K210 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None
config K210_16550_UART1_BITS
int "K210 16550 UART1 number of bits"
default 8
---help---
K210 16550 UART1 number of bits. Default: 8
config K210_16550_UART1_2STOP
int "K210 16550 UART1 two stop bits"
default 0
---help---
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
config K210_16550_UART1_RXBUFSIZE
int "K210 16550 UART1 Rx buffer size"
default 256
---help---
K210 16550 UART1 Rx buffer size. Default: 128
config K210_16550_UART1_TXBUFSIZE
int "K210 16550 UART1 Tx buffer size"
default 256
---help---
K210 16550 UART1 Tx buffer size. Default: 128
config K210_16550_UART1_IFLOWCONTROL
bool "K210 16550 UART1 RTS flow control"
default n
select SERIAL_IFLOWCONTROL
---help---
Enable K210 16550 UART1 RTS flow control
config K210_16550_UART1_OFLOWCONTROL
bool "K210 16550 UART1 CTS flow control"
default n
select SERIAL_OFLOWCONTROL
---help---
Enable K210 16550 UART1 CTS flow control
endif # K210_16550_UART1
config K210_16550_UART2
bool "K210 16550 UART2"
default n
if K210_16550_UART2
config K210_16550_UART2_BASE
hex "K210 16550 UART2 base address"
default 0x50220000
config K210_16550_UART2_CLOCK
int "K210 16550 UART2 clock"
default 195000000
config K210_16550_UART2_IRQ
int "K210 16550 UART2 IRQ number"
default 39
config K210_16550_UART2_BAUD
int "K210 16550 UART2 BAUD"
default 115200
config K210_16550_UART2_PARITY
int "K210 16550 UART2 parity"
default 0
range 0 2
---help---
K210 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None
config K210_16550_UART2_BITS
int "K210 16550 UART2 number of bits"
default 8
---help---
K210 16550 UART2 number of bits. Default: 8
config K210_16550_UART2_2STOP
int "K210 16550 UART2 two stop bits"
default 0
---help---
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
config K210_16550_UART2_RXBUFSIZE
int "K210 16550 UART2 Rx buffer size"
default 256
---help---
K210 16550 UART2 Rx buffer size. Default: 128
config K210_16550_UART2_TXBUFSIZE
int "K210 16550 UART2 Tx buffer size"
default 256
---help---
K210 16550 UART2 Tx buffer size. Default: 128
config K210_16550_UART2_IFLOWCONTROL
bool "K210 16550 UART2 RTS flow control"
default n
select SERIAL_IFLOWCONTROL
---help---
Enable K210 16550 UART2 RTS flow control
config K210_16550_UART2_OFLOWCONTROL
bool "K210 16550 UART2 CTS flow control"
default n
select SERIAL_OFLOWCONTROL
---help---
Enable K210 16550 UART2 CTS flow control
endif # K210_16550_UART2
config K210_16550_UART3
bool "K210 16550 UART3"
default n
if K210_16550_UART3
config K210_16550_UART3_BASE
hex "K210 16550 UART3 base address"
default 0x50230000
config K210_16550_UART3_CLOCK
int "K210 16550 UART3 clock"
default 195000000
config K210_16550_UART3_IRQ
int "K210 16550 UART3 IRQ number"
default 40
config K210_16550_UART3_BAUD
int "K210 16550 UART3 BAUD"
default 115200
config K210_16550_UART3_PARITY
int "K210 16550 UART3 parity"
default 0
range 0 2
---help---
K210 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None
config K210_16550_UART3_BITS
int "K210 16550 UART3 number of bits"
default 8
---help---
K210 16550 UART3 number of bits. Default: 8
config K210_16550_UART3_2STOP
int "K210 16550 UART3 two stop bits"
default 0
---help---
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
config K210_16550_UART3_RXBUFSIZE
int "K210 16550 UART3 Rx buffer size"
default 256
---help---
K210 16550 UART3 Rx buffer size. Default: 128
config K210_16550_UART3_TXBUFSIZE
int "K210 16550 UART3 Tx buffer size"
default 256
---help---
K210 16550 UART3 Tx buffer size. Default: 128
config K210_16550_UART3_IFLOWCONTROL
bool "K210 16550 UART3 RTS flow control"
default n
select SERIAL_IFLOWCONTROL
---help---
Enable K210 16550 UART3 RTS flow control
config K210_16550_UART3_OFLOWCONTROL
bool "K210 16550 UART3 CTS flow control"
default n
select SERIAL_OFLOWCONTROL
---help---
Enable K210 16550 UART3 CTS flow control
endif # K210_16550_UART3
config K210_16550_SUPRESS_CONFIG
bool "Suppress K210 16550 configuration"
default n
config K210_16550_SUPRESS_INITIAL_CONFIG
bool "Suppress initial K210 16550 configuration"
depends on !K210_16550_SUPRESS_CONFIG
default y
---help---
This option is useful, for example, if you are using a bootloader
that configures the K210_16550_UART. In that case, you may want to
just leave the existing console configuration in place. Default: n
config SERIAL_UART_ARCH_MMIO
bool "Platform access register through the memory mapping"
default y
config SERIAL_UART_ARCH_IOCTL
bool "Platform has own custom IOCTL"
default n
config K210_16550_REGINCR
int "Address increment between K210 16550 registers"
default 4
---help---
The address increment between K210 16550 registers. Options are 1, 2, or 4.
Default: 1
config K210_16550_REGWIDTH
int "Bit width of K210 16550 registers"
default 32
---help---
The bit width of registers. Options are 8, 16, or 32. Default: 32
config K210_16550_ADDRWIDTH
int "Address width of K210 16550 registers"
default 32
---help---
The bit width of registers. Options are 0, 8, 16, or 32.
Default: 32
Note: 0 means auto detect address size (uintptr_t)
endif
menu "K210 Others" menu "K210 Others"
config K210_WITH_QEMU config K210_WITH_QEMU

View File

@ -55,9 +55,9 @@ endif
# Specify our C code within this directory to be included # Specify our C code within this directory to be included
CHIP_CSRCS = k210_allocateheap.c k210_clockconfig.c CHIP_CSRCS = k210_allocateheap.c k210_clockconfig.c
CHIP_CSRCS += k210_irq.c k210_irq_dispatch.c k210_systemreset.c CHIP_CSRCS += k210_irq.c k210_irq_dispatch.c k210_systemreset.c
CHIP_CSRCS += k210_lowputc.c k210_serial.c k210_fpioa.c CHIP_CSRCS += k210_lowputc.c k210_serial.c k210_fpioa.c fpioa.c
CHIP_CSRCS += k210_start.c k210_timerisr.c k210_gpiohs.c k210_gpio.c CHIP_CSRCS += k210_start.c k210_timerisr.c k210_gpiohs.c k210_gpio.c
CHIP_CSRCS += k210_sysctl.c CHIP_CSRCS += k210_sysctl.c k210_uart_16550.c
ifeq ($(CONFIG_BUILD_PROTECTED),y) ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -128,8 +128,6 @@ void k210_clockconfig(void)
{ {
/* PLL0 selected */ /* PLL0 selected */
g_cpu_clock = k210_get_pll0clk() / 2; g_cpu_clock = k210_get_pll0clk() / 2;
syslog(LOG_NOTICE, "g_cpu clock = %d sel %#x\r\n", g_cpu_clock, clksel0);
} }
else else
{ {
@ -142,12 +140,18 @@ void k210_clockconfig(void)
void k210_sysctl_init(void) void k210_sysctl_init(void)
{ {
// sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL);
// sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL);
// sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL); sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL);
sysctl_clock_set_threshold(SYSCTL_THRESHOLD_APB1, 2); sysctl_clock_set_threshold(SYSCTL_THRESHOLD_APB1, 2);
// sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18);
// sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18);
// sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18);
// for IO-27/28
sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33);
// for IO-20~23
sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33);
} }

View File

@ -47,55 +47,21 @@ int k210_fpioa_get_io_by_function(uint8_t function)
{ {
int index = 0; int index = 0;
uint32_t RegValue = 0x0000; uint32_t RegValue = 0x0000;
uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE;
for (index = 0; index < K210_IO_NUMBER; index++) for (index = 0; index < K210_IO_NUMBER; index++)
{ {
RegValue = getreg32(&fpioa[index]); RegValue = getreg32(&fpioa_base[index]);
if ((RegValue & 0xFF) == function) if ((RegValue & 0xFF) == function)
return index; return index;
} }
return -1; return -1;
} }
int fpioa_set_io_pull(int number, fpioa_pull_t pull)
{
/* Check parameters */
if (number < 0 || number >= K210_IO_NUMBER || pull >= FPIOA_PULL_MAX)
return -1;
/* read register */
uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE;
fpioa_io_config_t cfg = *(fpioa_io_config_t *)(&fpioa[number]);
uint32_t ioflags = 0x0000;
switch (pull)
{
case FPIOA_PULL_NONE:
cfg.pu = 0;
cfg.pd = 0;
break;
case FPIOA_PULL_DOWN:
cfg.pu = 0;
cfg.pd = 1;
break;
case FPIOA_PULL_UP:
cfg.pu = 1;
cfg.pd = 0;
break;
default:
break;
}
/* write register */
ioflags = *(uint32_t*)(&cfg);
putreg32(ioflags, &fpioa[number]);
return 0;
}
void k210_fpioa_config(uint32_t io, uint32_t ioflags) void k210_fpioa_config(uint32_t io, uint32_t ioflags)
{ {
uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE;
DEBUGASSERT(io < K210_IO_NUMBER); DEBUGASSERT(io < K210_IO_NUMBER);
putreg32(ioflags, &fpioa[io]); putreg32(ioflags, &fpioa_base[io]);
} }

View File

@ -22,7 +22,7 @@
* @file k210_fpioa.h * @file k210_fpioa.h
* @brief nuttx source code * @brief nuttx source code
* https://github.com/apache/incubator-nuttx.git * https://github.com/apache/incubator-nuttx.git
* @version 10.3.0 * @version 10.3.0
* @author AIIT XUOS Lab * @author AIIT XUOS Lab
* @date 2022-03-23 * @date 2022-03-23
*/ */
@ -35,6 +35,7 @@
****************************************************************************/ ****************************************************************************/
#include <stdint.h> #include <stdint.h>
#include "fpioa.h"
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
@ -44,48 +45,263 @@
#define K210_GPIOHS_MAX_PINNO 32 #define K210_GPIOHS_MAX_PINNO 32
#define K210_GPIO_MAX_PINNO 8 #define K210_GPIO_MAX_PINNO 8
#define K210_IO_FUNC_UARTHS_RX 18 /* UART High speed Receiver */ #define K210_IO_FUNC_JTAG_TCLK 0 /* JTAG Test Clock */
#define K210_IO_FUNC_UARTHS_TX 19 /* UART High speed Transmitter */ #define K210_IO_FUNC_JTAG_TDI 1 /* JTAG Test Data In */
#define K210_IO_FUNC_GPIOHS0 24 /* GPIO High speed 0 */ #define K210_IO_FUNC_JTAG_TMS 2 /* JTAG Test Mode Select */
#define K210_IO_FUNC_GPIOHS1 25 /* GPIO High speed 1 */ #define K210_IO_FUNC_JTAG_TDO 3 /* JTAG Test Data Out */
#define K210_IO_FUNC_GPIOHS2 26 /* GPIO High speed 2 */ #define K210_IO_FUNC_SPI0_D0 4 /* SPI0 Data 0 */
#define K210_IO_FUNC_GPIOHS3 27 /* GPIO High speed 3 */ #define K210_IO_FUNC_SPI0_D1 5 /* SPI0 Data 1 */
#define K210_IO_FUNC_GPIOHS4 28 /* GPIO High speed 4 */ #define K210_IO_FUNC_SPI0_D2 6 /* SPI0 Data 2 */
#define K210_IO_FUNC_GPIOHS5 29 /* GPIO High speed 5 */ #define K210_IO_FUNC_SPI0_D3 7 /* SPI0 Data 3 */
#define K210_IO_FUNC_GPIOHS6 30 /* GPIO High speed 6 */ #define K210_IO_FUNC_SPI0_D4 8 /* SPI0 Data 4 */
#define K210_IO_FUNC_GPIOHS7 31 /* GPIO High speed 7 */ #define K210_IO_FUNC_SPI0_D5 9 /* SPI0 Data 5 */
#define K210_IO_FUNC_GPIOHS8 32 /* GPIO High speed 8 */ #define K210_IO_FUNC_SPI0_D6 10 /* SPI0 Data 6 */
#define K210_IO_FUNC_GPIOHS9 33 /* GPIO High speed 9 */ #define K210_IO_FUNC_SPI0_D7 11 /* SPI0 Data 7 */
#define K210_IO_FUNC_GPIOHS10 34 /* GPIO High speed 10 */ #define K210_IO_FUNC_SPI0_SS0 12 /* SPI0 Chip Select 0 */
#define K210_IO_FUNC_GPIOHS11 35 /* GPIO High speed 11 */ #define K210_IO_FUNC_SPI0_SS1 13 /* SPI0 Chip Select 1 */
#define K210_IO_FUNC_GPIOHS12 36 /* GPIO High speed 12 */ #define K210_IO_FUNC_SPI0_SS2 14 /* SPI0 Chip Select 2 */
#define K210_IO_FUNC_GPIOHS13 37 /* GPIO High speed 13 */ #define K210_IO_FUNC_SPI0_SS3 15 /* SPI0 Chip Select 3 */
#define K210_IO_FUNC_GPIOHS14 38 /* GPIO High speed 14 */ #define K210_IO_FUNC_SPI0_ARB 16 /* SPI0 Arbitration */
#define K210_IO_FUNC_GPIOHS15 39 /* GPIO High speed 15 */ #define K210_IO_FUNC_SPI0_SCLK 17 /* SPI0 Serial Clock */
#define K210_IO_FUNC_GPIOHS16 40 /* GPIO High speed 16 */ #define K210_IO_FUNC_UARTHS_RX 18 /* UART High speed Receiver */
#define K210_IO_FUNC_GPIOHS17 41 /* GPIO High speed 17 */ #define K210_IO_FUNC_UARTHS_TX 19 /* UART High speed Transmitter */
#define K210_IO_FUNC_GPIOHS18 42 /* GPIO High speed 18 */ #define K210_IO_FUNC_RESV6 20 /* Reserved function */
#define K210_IO_FUNC_GPIOHS19 43 /* GPIO High speed 19 */ #define K210_IO_FUNC_RESV7 21 /* Reserved function */
#define K210_IO_FUNC_GPIOHS20 44 /* GPIO High speed 20 */ #define K210_IO_FUNC_CLK_SPI1 22 /* Clock SPI1 */
#define K210_IO_FUNC_GPIOHS21 45 /* GPIO High speed 21 */ #define K210_IO_FUNC_CLK_I2C1 23 /* Clock I2C1 */
#define K210_IO_FUNC_GPIOHS22 46 /* GPIO High speed 22 */ #define K210_IO_FUNC_GPIOHS0 24 /* GPIO High speed 0 */
#define K210_IO_FUNC_GPIOHS23 47 /* GPIO High speed 23 */ #define K210_IO_FUNC_GPIOHS1 25 /* GPIO High speed 1 */
#define K210_IO_FUNC_GPIOHS24 48 /* GPIO High speed 24 */ #define K210_IO_FUNC_GPIOHS2 26 /* GPIO High speed 2 */
#define K210_IO_FUNC_GPIOHS25 49 /* GPIO High speed 25 */ #define K210_IO_FUNC_GPIOHS3 27 /* GPIO High speed 3 */
#define K210_IO_FUNC_GPIOHS26 50 /* GPIO High speed 26 */ #define K210_IO_FUNC_GPIOHS4 28 /* GPIO High speed 4 */
#define K210_IO_FUNC_GPIOHS27 51 /* GPIO High speed 27 */ #define K210_IO_FUNC_GPIOHS5 29 /* GPIO High speed 5 */
#define K210_IO_FUNC_GPIOHS28 52 /* GPIO High speed 28 */ #define K210_IO_FUNC_GPIOHS6 30 /* GPIO High speed 6 */
#define K210_IO_FUNC_GPIOHS29 53 /* GPIO High speed 29 */ #define K210_IO_FUNC_GPIOHS7 31 /* GPIO High speed 7 */
#define K210_IO_FUNC_GPIOHS30 54 /* GPIO High speed 30 */ #define K210_IO_FUNC_GPIOHS8 32 /* GPIO High speed 8 */
#define K210_IO_FUNC_GPIOHS31 55 /* GPIO High speed 31 */ #define K210_IO_FUNC_GPIOHS9 33 /* GPIO High speed 9 */
#define K210_IO_FUNC_GPIO0 56 /* GPIO pin 0 */ #define K210_IO_FUNC_GPIOHS10 34 /* GPIO High speed 10 */
#define K210_IO_FUNC_GPIO1 57 /* GPIO pin 1 */ #define K210_IO_FUNC_GPIOHS11 35 /* GPIO High speed 11 */
#define K210_IO_FUNC_GPIO2 58 /* GPIO pin 2 */ #define K210_IO_FUNC_GPIOHS12 36 /* GPIO High speed 12 */
#define K210_IO_FUNC_GPIO3 59 /* GPIO pin 3 */ #define K210_IO_FUNC_GPIOHS13 37 /* GPIO High speed 13 */
#define K210_IO_FUNC_GPIO4 60 /* GPIO pin 4 */ #define K210_IO_FUNC_GPIOHS14 38 /* GPIO High speed 14 */
#define K210_IO_FUNC_GPIO5 61 /* GPIO pin 5 */ #define K210_IO_FUNC_GPIOHS15 39 /* GPIO High speed 15 */
#define K210_IO_FUNC_GPIO6 62 /* GPIO pin 6 */ #define K210_IO_FUNC_GPIOHS16 40 /* GPIO High speed 16 */
#define K210_IO_FUNC_GPIO7 63 /* GPIO pin 7 */ #define K210_IO_FUNC_GPIOHS17 41 /* GPIO High speed 17 */
#define K210_IO_FUNC_GPIOHS18 42 /* GPIO High speed 18 */
#define K210_IO_FUNC_GPIOHS19 43 /* GPIO High speed 19 */
#define K210_IO_FUNC_GPIOHS20 44 /* GPIO High speed 20 */
#define K210_IO_FUNC_GPIOHS21 45 /* GPIO High speed 21 */
#define K210_IO_FUNC_GPIOHS22 46 /* GPIO High speed 22 */
#define K210_IO_FUNC_GPIOHS23 47 /* GPIO High speed 23 */
#define K210_IO_FUNC_GPIOHS24 48 /* GPIO High speed 24 */
#define K210_IO_FUNC_GPIOHS25 49 /* GPIO High speed 25 */
#define K210_IO_FUNC_GPIOHS26 50 /* GPIO High speed 26 */
#define K210_IO_FUNC_GPIOHS27 51 /* GPIO High speed 27 */
#define K210_IO_FUNC_GPIOHS28 52 /* GPIO High speed 28 */
#define K210_IO_FUNC_GPIOHS29 53 /* GPIO High speed 29 */
#define K210_IO_FUNC_GPIOHS30 54 /* GPIO High speed 30 */
#define K210_IO_FUNC_GPIOHS31 55 /* GPIO High speed 31 */
#define K210_IO_FUNC_GPIO0 56 /* GPIO pin 0 */
#define K210_IO_FUNC_GPIO1 57 /* GPIO pin 1 */
#define K210_IO_FUNC_GPIO2 58 /* GPIO pin 2 */
#define K210_IO_FUNC_GPIO3 59 /* GPIO pin 3 */
#define K210_IO_FUNC_GPIO4 60 /* GPIO pin 4 */
#define K210_IO_FUNC_GPIO5 61 /* GPIO pin 5 */
#define K210_IO_FUNC_GPIO6 62 /* GPIO pin 6 */
#define K210_IO_FUNC_GPIO7 63 /* GPIO pin 7 */
#define K210_IO_FUNC_UART1_RX 64 /* UART1 Receiver */
#define K210_IO_FUNC_UART1_TX 65 /* UART1 Transmitter */
#define K210_IO_FUNC_UART2_RX 66 /* UART2 Receiver */
#define K210_IO_FUNC_UART2_TX 67 /* UART2 Transmitter */
#define K210_IO_FUNC_UART3_RX 68 /* UART3 Receiver */
#define K210_IO_FUNC_UART3_TX 69 /* UART3 Transmitter */
#define K210_IO_FUNC_SPI1_D0 70 /* SPI1 Data 0 */
#define K210_IO_FUNC_SPI1_D1 71 /* SPI1 Data 1 */
#define K210_IO_FUNC_SPI1_D2 72 /* SPI1 Data 2 */
#define K210_IO_FUNC_SPI1_D3 73 /* SPI1 Data 3 */
#define K210_IO_FUNC_SPI1_D4 74 /* SPI1 Data 4 */
#define K210_IO_FUNC_SPI1_D5 75 /* SPI1 Data 5 */
#define K210_IO_FUNC_SPI1_D6 76 /* SPI1 Data 6 */
#define K210_IO_FUNC_SPI1_D7 77 /* SPI1 Data 7 */
#define K210_IO_FUNC_SPI1_SS0 78 /* SPI1 Chip Select 0 */
#define K210_IO_FUNC_SPI1_SS1 79 /* SPI1 Chip Select 1 */
#define K210_IO_FUNC_SPI1_SS2 80 /* SPI1 Chip Select 2 */
#define K210_IO_FUNC_SPI1_SS3 81 /* SPI1 Chip Select 3 */
#define K210_IO_FUNC_SPI1_ARB 82 /* SPI1 Arbitration */
#define K210_IO_FUNC_SPI1_SCLK 83 /* SPI1 Serial Clock */
#define K210_IO_FUNC_SPI_SLAVE_D0 84 /* SPI Slave Data 0 */
#define K210_IO_FUNC_SPI_SLAVE_SS 85 /* SPI Slave Select */
#define K210_IO_FUNC_SPI_SLAVE_SCLK 86 /* SPI Slave Serial Clock */
#define K210_IO_FUNC_I2S0_MCLK 87 /* I2S0 Master Clock */
#define K210_IO_FUNC_I2S0_SCLK 88 /* I2S0 Serial Clock(BCLK) */
#define K210_IO_FUNC_I2S0_WS 89 /* I2S0 Word Select(LRCLK) */
#define K210_IO_FUNC_I2S0_IN_D0 90 /* I2S0 Serial Data Input 0 */
#define K210_IO_FUNC_I2S0_IN_D1 91 /* I2S0 Serial Data Input 1 */
#define K210_IO_FUNC_I2S0_IN_D2 92 /* I2S0 Serial Data Input 2 */
#define K210_IO_FUNC_I2S0_IN_D3 93 /* I2S0 Serial Data Input 3 */
#define K210_IO_FUNC_I2S0_OUT_D0 94 /* I2S0 Serial Data Output 0 */
#define K210_IO_FUNC_I2S0_OUT_D1 95 /* I2S0 Serial Data Output 1 */
#define K210_IO_FUNC_I2S0_OUT_D2 96 /* I2S0 Serial Data Output 2 */
#define K210_IO_FUNC_I2S0_OUT_D3 97 /* I2S0 Serial Data Output 3 */
#define K210_IO_FUNC_I2S1_MCLK 98 /* I2S1 Master Clock */
#define K210_IO_FUNC_I2S1_SCLK 99 /* I2S1 Serial Clock(BCLK) */
#define K210_IO_FUNC_I2S1_WS 100 /* I2S1 Word Select(LRCLK) */
#define K210_IO_FUNC_I2S1_IN_D0 101 /* I2S1 Serial Data Input 0 */
#define K210_IO_FUNC_I2S1_IN_D1 102 /* I2S1 Serial Data Input 1 */
#define K210_IO_FUNC_I2S1_IN_D2 103 /* I2S1 Serial Data Input 2 */
#define K210_IO_FUNC_I2S1_IN_D3 104 /* I2S1 Serial Data Input 3 */
#define K210_IO_FUNC_I2S1_OUT_D0 105 /* I2S1 Serial Data Output 0 */
#define K210_IO_FUNC_I2S1_OUT_D1 106 /* I2S1 Serial Data Output 1 */
#define K210_IO_FUNC_I2S1_OUT_D2 107 /* I2S1 Serial Data Output 2 */
#define K210_IO_FUNC_I2S1_OUT_D3 108 /* I2S1 Serial Data Output 3 */
#define K210_IO_FUNC_I2S2_MCLK 109 /* I2S2 Master Clock */
#define K210_IO_FUNC_I2S2_SCLK 110 /* I2S2 Serial Clock(BCLK) */
#define K210_IO_FUNC_I2S2_WS 111 /* I2S2 Word Select(LRCLK) */
#define K210_IO_FUNC_I2S2_IN_D0 112 /* I2S2 Serial Data Input 0 */
#define K210_IO_FUNC_I2S2_IN_D1 113 /* I2S2 Serial Data Input 1 */
#define K210_IO_FUNC_I2S2_IN_D2 114 /* I2S2 Serial Data Input 2 */
#define K210_IO_FUNC_I2S2_IN_D3 115 /* I2S2 Serial Data Input 3 */
#define K210_IO_FUNC_I2S2_OUT_D0 116 /* I2S2 Serial Data Output 0 */
#define K210_IO_FUNC_I2S2_OUT_D1 117 /* I2S2 Serial Data Output 1 */
#define K210_IO_FUNC_I2S2_OUT_D2 118 /* I2S2 Serial Data Output 2 */
#define K210_IO_FUNC_I2S2_OUT_D3 119 /* I2S2 Serial Data Output 3 */
#define K210_IO_FUNC_RESV0 120 /* Reserved function */
#define K210_IO_FUNC_RESV1 121 /* Reserved function */
#define K210_IO_FUNC_RESV2 122 /* Reserved function */
#define K210_IO_FUNC_RESV3 123 /* Reserved function */
#define K210_IO_FUNC_RESV4 124 /* Reserved function */
#define K210_IO_FUNC_RESV5 125 /* Reserved function */
#define K210_IO_FUNC_I2C0_SCLK 126 /* I2C0 Serial Clock */
#define K210_IO_FUNC_I2C0_SDA 127 /* I2C0 Serial Data */
#define K210_IO_FUNC_I2C1_SCLK 128 /* I2C1 Serial Clock */
#define K210_IO_FUNC_I2C1_SDA 129 /* I2C1 Serial Data */
#define K210_IO_FUNC_I2C2_SCLK 130 /* I2C2 Serial Clock */
#define K210_IO_FUNC_I2C2_SDA 131 /* I2C2 Serial Data */
#define K210_IO_FUNC_CMOS_XCLK 132 /* DVP System Clock */
#define K210_IO_FUNC_CMOS_RST 133 /* DVP System Reset */
#define K210_IO_FUNC_CMOS_PWDN 134 /* DVP Power Down Mode */
#define K210_IO_FUNC_CMOS_VSYNC 135 /* DVP Vertical Sync */
#define K210_IO_FUNC_CMOS_HREF 136 /* DVP Horizontal Reference output */
#define K210_IO_FUNC_CMOS_PCLK 137 /* Pixel Clock */
#define K210_IO_FUNC_CMOS_D0 138 /* Data Bit 0 */
#define K210_IO_FUNC_CMOS_D1 139 /* Data Bit 1 */
#define K210_IO_FUNC_CMOS_D2 140 /* Data Bit 2 */
#define K210_IO_FUNC_CMOS_D3 141 /* Data Bit 3 */
#define K210_IO_FUNC_CMOS_D4 142 /* Data Bit 4 */
#define K210_IO_FUNC_CMOS_D5 143 /* Data Bit 5 */
#define K210_IO_FUNC_CMOS_D6 144 /* Data Bit 6 */
#define K210_IO_FUNC_CMOS_D7 145 /* Data Bit 7 */
#define K210_IO_FUNC_SCCB_SCLK 146 /* SCCB Serial Clock */
#define K210_IO_FUNC_SCCB_SDA 147 /* SCCB Serial Data */
#define K210_IO_FUNC_UART1_CTS 148 /* UART1 Clear To Send */
#define K210_IO_FUNC_UART1_DSR 149 /* UART1 Data Set Ready */
#define K210_IO_FUNC_UART1_DCD 150 /* UART1 Data Carrier Detect */
#define K210_IO_FUNC_UART1_RI 151 /* UART1 Ring Indicator */
#define K210_IO_FUNC_UART1_SIR_IN 152 /* UART1 Serial Infrared Input */
#define K210_IO_FUNC_UART1_DTR 153 /* UART1 Data Terminal Ready */
#define K210_IO_FUNC_UART1_RTS 154 /* UART1 Request To Send */
#define K210_IO_FUNC_UART1_OUT2 155 /* UART1 User-designated Output 2 */
#define K210_IO_FUNC_UART1_OUT1 156 /* UART1 User-designated Output 1 */
#define K210_IO_FUNC_UART1_SIR_OUT 157 /* UART1 Serial Infrared Output */
#define K210_IO_FUNC_UART1_BAUD 158 /* UART1 Transmit Clock Output */
#define K210_IO_FUNC_UART1_RE 159 /* UART1 Receiver Output Enable */
#define K210_IO_FUNC_UART1_DE 160 /* UART1 Driver Output Enable */
#define K210_IO_FUNC_UART1_RS485_EN 161 /* UART1 RS485 Enable */
#define K210_IO_FUNC_UART2_CTS 162 /* UART2 Clear To Send */
#define K210_IO_FUNC_UART2_DSR 163 /* UART2 Data Set Ready */
#define K210_IO_FUNC_UART2_DCD 164 /* UART2 Data Carrier Detect */
#define K210_IO_FUNC_UART2_RI 165 /* UART2 Ring Indicator */
#define K210_IO_FUNC_UART2_SIR_IN 166 /* UART2 Serial Infrared Input */
#define K210_IO_FUNC_UART2_DTR 167 /* UART2 Data Terminal Ready */
#define K210_IO_FUNC_UART2_RTS 168 /* UART2 Request To Send */
#define K210_IO_FUNC_UART2_OUT2 169 /* UART2 User-designated Output 2 */
#define K210_IO_FUNC_UART2_OUT1 170 /* UART2 User-designated Output 1 */
#define K210_IO_FUNC_UART2_SIR_OUT 171 /* UART2 Serial Infrared Output */
#define K210_IO_FUNC_UART2_BAUD 172 /* UART2 Transmit Clock Output */
#define K210_IO_FUNC_UART2_RE 173 /* UART2 Receiver Output Enable */
#define K210_IO_FUNC_UART2_DE 174 /* UART2 Driver Output Enable */
#define K210_IO_FUNC_UART2_RS485_EN 175 /* UART2 RS485 Enable */
#define K210_IO_FUNC_UART3_CTS 176 /* UART3 Clear To Send */
#define K210_IO_FUNC_UART3_DSR 177 /* UART3 Data Set Ready */
#define K210_IO_FUNC_UART3_DCD 178 /* UART3 Data Carrier Detect */
#define K210_IO_FUNC_UART3_RI 179 /* UART3 Ring Indicator */
#define K210_IO_FUNC_UART3_SIR_IN 180 /* UART3 Serial Infrared Input */
#define K210_IO_FUNC_UART3_DTR 181 /* UART3 Data Terminal Ready */
#define K210_IO_FUNC_UART3_RTS 182 /* UART3 Request To Send */
#define K210_IO_FUNC_UART3_OUT2 183 /* UART3 User-designated Output 2 */
#define K210_IO_FUNC_UART3_OUT1 184 /* UART3 User-designated Output 1 */
#define K210_IO_FUNC_UART3_SIR_OUT 185 /* UART3 Serial Infrared Output */
#define K210_IO_FUNC_UART3_BAUD 186 /* UART3 Transmit Clock Output */
#define K210_IO_FUNC_UART3_RE 187 /* UART3 Receiver Output Enable */
#define K210_IO_FUNC_UART3_DE 188 /* UART3 Driver Output Enable */
#define K210_IO_FUNC_UART3_RS485_EN 189 /* UART3 RS485 Enable */
#define K210_IO_FUNC_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */
#define K210_IO_FUNC_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */
#define K210_IO_FUNC_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */
#define K210_IO_FUNC_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */
#define K210_IO_FUNC_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */
#define K210_IO_FUNC_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */
#define K210_IO_FUNC_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */
#define K210_IO_FUNC_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */
#define K210_IO_FUNC_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */
#define K210_IO_FUNC_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */
#define K210_IO_FUNC_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */
#define K210_IO_FUNC_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */
#define K210_IO_FUNC_CLK_SPI2 202 /* Clock SPI2 */
#define K210_IO_FUNC_CLK_I2C2 203 /* Clock I2C2 */
#define K210_IO_FUNC_INTERNAL0 204 /* Internal function signal 0 */
#define K210_IO_FUNC_INTERNAL1 205 /* Internal function signal 1 */
#define K210_IO_FUNC_INTERNAL2 206 /* Internal function signal 2 */
#define K210_IO_FUNC_INTERNAL3 207 /* Internal function signal 3 */
#define K210_IO_FUNC_INTERNAL4 208 /* Internal function signal 4 */
#define K210_IO_FUNC_INTERNAL5 209 /* Internal function signal 5 */
#define K210_IO_FUNC_INTERNAL6 210 /* Internal function signal 6 */
#define K210_IO_FUNC_INTERNAL7 211 /* Internal function signal 7 */
#define K210_IO_FUNC_INTERNAL8 212 /* Internal function signal 8 */
#define K210_IO_FUNC_INTERNAL9 213 /* Internal function signal 9 */
#define K210_IO_FUNC_INTERNAL10 214 /* Internal function signal 10 */
#define K210_IO_FUNC_INTERNAL11 215 /* Internal function signal 11 */
#define K210_IO_FUNC_INTERNAL12 216 /* Internal function signal 12 */
#define K210_IO_FUNC_INTERNAL13 217 /* Internal function signal 13 */
#define K210_IO_FUNC_INTERNAL14 218 /* Internal function signal 14 */
#define K210_IO_FUNC_INTERNAL15 219 /* Internal function signal 15 */
#define K210_IO_FUNC_INTERNAL16 220 /* Internal function signal 16 */
#define K210_IO_FUNC_INTERNAL17 221 /* Internal function signal 17 */
#define K210_IO_FUNC_CONSTANT 222 /* Constant function */
#define K210_IO_FUNC_INTERNAL18 223 /* Internal function signal 18 */
#define K210_IO_FUNC_DEBUG0 224 /* Debug function 0 */
#define K210_IO_FUNC_DEBUG1 225 /* Debug function 1 */
#define K210_IO_FUNC_DEBUG2 226 /* Debug function 2 */
#define K210_IO_FUNC_DEBUG3 227 /* Debug function 3 */
#define K210_IO_FUNC_DEBUG4 228 /* Debug function 4 */
#define K210_IO_FUNC_DEBUG5 229 /* Debug function 5 */
#define K210_IO_FUNC_DEBUG6 230 /* Debug function 6 */
#define K210_IO_FUNC_DEBUG7 231 /* Debug function 7 */
#define K210_IO_FUNC_DEBUG8 232 /* Debug function 8 */
#define K210_IO_FUNC_DEBUG9 233 /* Debug function 9 */
#define K210_IO_FUNC_DEBUG10 234 /* Debug function 10 */
#define K210_IO_FUNC_DEBUG11 235 /* Debug function 11 */
#define K210_IO_FUNC_DEBUG12 236 /* Debug function 12 */
#define K210_IO_FUNC_DEBUG13 237 /* Debug function 13 */
#define K210_IO_FUNC_DEBUG14 238 /* Debug function 14 */
#define K210_IO_FUNC_DEBUG15 239 /* Debug function 15 */
#define K210_IO_FUNC_DEBUG16 240 /* Debug function 16 */
#define K210_IO_FUNC_DEBUG17 241 /* Debug function 17 */
#define K210_IO_FUNC_DEBUG18 242 /* Debug function 18 */
#define K210_IO_FUNC_DEBUG19 243 /* Debug function 19 */
#define K210_IO_FUNC_DEBUG20 244 /* Debug function 20 */
#define K210_IO_FUNC_DEBUG21 245 /* Debug function 21 */
#define K210_IO_FUNC_DEBUG22 246 /* Debug function 22 */
#define K210_IO_FUNC_DEBUG23 247 /* Debug function 23 */
#define K210_IO_FUNC_DEBUG24 248 /* Debug function 24 */
#define K210_IO_FUNC_DEBUG25 249 /* Debug function 25 */
#define K210_IO_FUNC_DEBUG26 250 /* Debug function 26 */
#define K210_IO_FUNC_DEBUG27 251 /* Debug function 27 */
#define K210_IO_FUNC_DEBUG28 252 /* Debug function 28 */
#define K210_IO_FUNC_DEBUG29 253 /* Debug function 29 */
#define K210_IO_FUNC_DEBUG30 254 /* Debug function 30 */
#define K210_IO_FUNC_DEBUG31 255 /* Debug function 31 */
#define K210_IO_FUNC_MAX 256 /* Function numbers */
#define K210_IO_DS(x) (x << 8) /* Driving Selector */ #define K210_IO_DS(x) (x << 8) /* Driving Selector */
@ -102,34 +318,6 @@
#define K210_IOFLAG_GPIOHS (K210_IO_DS(0xf) | K210_IO_OUTPUT_ENABLE | \ #define K210_IOFLAG_GPIOHS (K210_IO_DS(0xf) | K210_IO_OUTPUT_ENABLE | \
K210_IO_INPUT_ENABLE | K210_IO_ST) K210_IO_INPUT_ENABLE | K210_IO_ST)
typedef struct _fpioa_io_config
{
uint32_t ch_sel : 8; /* Channel select from 256 input. */
uint32_t ds : 4; /* Driving selector. */
uint32_t oe_en : 1; /* Static output enable, will AND with OE_INV. */
uint32_t oe_inv : 1; /* Invert output enable. */
uint32_t do_sel : 1; /* Data output select: 0 for DO, 1 for OE. */
uint32_t do_inv : 1; /* Invert the result of data output select (DO_SEL). */
uint32_t pu : 1; /* Pull up enable. 0 for nothing, 1 for pull up. */
uint32_t pd : 1; /* Pull down enable. 0 for nothing, 1 for pull down. */
uint32_t resv0 : 1; /* Reserved bits. */
uint32_t sl : 1; /* Slew rate control enable. */
uint32_t ie_en : 1; /* Static input enable, will AND with IE_INV. */
uint32_t ie_inv : 1; /* Invert input enable. */
uint32_t di_inv : 1; /* Invert Data input. */
uint32_t st : 1; /* Schmitt trigger. */
uint32_t resv1 : 7; /* Reserved bits. */
uint32_t pad_di : 1; /* Read current IO's data input. */
} __attribute__((packed, aligned(4))) fpioa_io_config_t;
typedef enum _fpioa_pull
{
FPIOA_PULL_NONE, /* No Pull */
FPIOA_PULL_DOWN, /* Pull Down */
FPIOA_PULL_UP, /* Pull Up */
FPIOA_PULL_MAX /* Count of pull settings */
} fpioa_pull_t;
/**************************************************************************** /****************************************************************************
* Public Functions Prototypes * Public Functions Prototypes

View File

@ -0,0 +1,733 @@
/****************************************************************************
* arch/risc-v/src/k210/k210_serial.c
*
* 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/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/serial/serial.h>
#include <arch/board/board.h>
#include "riscv_internal.h"
#include "k210_config.h"
#include "chip.h"
#include "k210.h"
#include "k210_uart_16550.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* If we are not using the serial driver for the console, then we still must
* provide some minimal implementation of up_putc.
*/
#ifdef USE_SERIALDRIVER
/* Which UART with be tty0/console and which tty1? The console will always
* be ttyS0. If there is no console then will use the lowest numbered UART.
*/
#ifdef HAVE_SERIAL_CONSOLE
# if defined(CONFIG_UART0_SERIAL_CONSOLE)
# define CONSOLE_DEV g_uart0port /* UART0 is console */
# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */
# undef TTYS1_DEV /* No ttyS1 */
# define SERIAL_CONSOLE 1
# else
# error "I'm confused... Do we have a serial console or not?"
# endif
#else
# undef CONSOLE_DEV /* No console */
# undef CONFIG_UART0_SERIAL_CONSOLE
# if defined(CONFIG_K210_UART0)
# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */
# undef TTYS1_DEV /* No ttyS1 */
# define SERIAL_CONSOLE 1
# else
# undef TTYS0_DEV
# undef TTYS1_DEV
# endif
#endif
/* Common initialization logic will not not know that the all of the UARTs
* have been disabled. So, as a result, we may still have to provide
* stub implementations of riscv_earlyserialinit(), riscv_serialinit(), and
* up_putc().
*/
#ifdef HAVE_UART_DEVICE
/****************************************************************************
* Private Types
****************************************************************************/
struct up_dev_s
{
uintptr_t uartbase; /* Base address of UART registers */
uint32_t baud; /* Configured baud */
uint8_t irq; /* IRQ associated with this UART */
uint8_t im; /* Interrupt mask state */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Low-level helpers */
static uint32_t up_serialin(struct up_dev_s *priv, int offset);
static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value);
static void up_restoreuartint(struct up_dev_s *priv, uint8_t im);
static void up_disableuartint(struct up_dev_s *priv, uint8_t *im);
/* Serial driver methods */
static int up_setup(struct uart_dev_s *dev);
static void up_shutdown(struct uart_dev_s *dev);
static int up_attach(struct uart_dev_s *dev);
static void up_detach(struct uart_dev_s *dev);
static int up_interrupt(int irq, void *context, void *arg);
static int up_ioctl(struct file *filep, int cmd, unsigned long arg);
static int up_receive(struct uart_dev_s *dev, unsigned int *status);
static void up_rxint(struct uart_dev_s *dev, bool enable);
static bool up_rxavailable(struct uart_dev_s *dev);
static void up_send(struct uart_dev_s *dev, int ch);
static void up_txint(struct uart_dev_s *dev, bool enable);
static bool up_txready(struct uart_dev_s *dev);
static bool up_txempty(struct uart_dev_s *dev);
/****************************************************************************
* Private Data
****************************************************************************/
static const struct uart_ops_s g_uart_ops =
{
.setup = up_setup,
.shutdown = up_shutdown,
.attach = up_attach,
.detach = up_detach,
.ioctl = up_ioctl,
.receive = up_receive,
.rxint = up_rxint,
.rxavailable = up_rxavailable,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.rxflowcontrol = NULL,
#endif
.send = up_send,
.txint = up_txint,
.txready = up_txready,
.txempty = up_txempty,
};
/* I/O buffers */
#ifdef CONFIG_K210_UART0
static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE];
static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE];
static uint32_t g_rxdata;
#endif
#ifdef CONFIG_K210_UART0
static struct up_dev_s g_uart0priv =
{
.uartbase = K210_UART0_BASE,
.baud = CONFIG_UART0_BAUD,
.irq = K210_IRQ_UART0,
};
static uart_dev_t g_uart0port =
{
#if SERIAL_CONSOLE == 1
.isconsole = 1,
#endif
.recv =
{
.size = CONFIG_UART0_RXBUFSIZE,
.buffer = g_uart0rxbuffer,
},
.xmit =
{
.size = CONFIG_UART0_TXBUFSIZE,
.buffer = g_uart0txbuffer,
},
.ops = &g_uart_ops,
.priv = &g_uart0priv,
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: up_serialin
****************************************************************************/
static uint32_t up_serialin(struct up_dev_s *priv, int offset)
{
return getreg32(priv->uartbase + offset);
}
/****************************************************************************
* Name: up_serialout
****************************************************************************/
static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value)
{
putreg32(value, priv->uartbase + offset);
}
/****************************************************************************
* Name: up_restoreuartint
****************************************************************************/
static void up_restoreuartint(struct up_dev_s *priv, uint8_t im)
{
irqstate_t flags = enter_critical_section();
priv->im = im;
up_serialout(priv, UART_IE_OFFSET, im);
leave_critical_section(flags);
}
/****************************************************************************
* Name: up_disableuartint
****************************************************************************/
static void up_disableuartint(struct up_dev_s *priv, uint8_t *im)
{
irqstate_t flags = enter_critical_section();
/* Return the current interrupt mask value */
if (im)
{
*im = priv->im;
}
/* Disable all interrupts */
priv->im = 0;
up_serialout(priv, UART_IE_OFFSET, 0);
leave_critical_section(flags);
}
/****************************************************************************
* Name: up_setup
*
* Description:
* Configure the UART baud, bits, parity, etc. This method is called the
* first time that the serial port is opened.
*
****************************************************************************/
static int up_setup(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
#if 0 /* TODO: Setup divisor */
#endif
/* Enable RX */
up_serialout(priv, UART_RXCTL_OFFSET, 1);
/* Set TX watermark level to 1 and enable TX */
up_serialout(priv, UART_TXCTL_OFFSET, 1 << 16 | 1);
return OK;
}
/****************************************************************************
* Name: up_shutdown
*
* Description:
* Disable the UART. This method is called when the serial
* port is closed
*
****************************************************************************/
static void up_shutdown(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* Disable interrupts */
up_disableuartint(priv, NULL);
}
/****************************************************************************
* Name: up_attach
*
* Description:
* Configure the UART to operation in interrupt driven mode. This method is
* called when the serial port is opened. Normally, this is just after the
* the setup() method is called, however, the serial console may operate in
* a non-interrupt driven mode during the boot phase.
*
* RX and TX interrupts are not enabled by the attach method (unless the
* hardware supports multiple levels of interrupt enabling). The RX and TX
* interrupts are not enabled until the txint() and rxint() are called.
*
****************************************************************************/
static int up_attach(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
int ret;
/* Initialize interrupt generation on the peripheral */
up_serialout(priv, UART_IE_OFFSET, UART_IE_TXWM | UART_IE_RXWM);
ret = irq_attach(priv->irq, up_interrupt, dev);
if (ret == OK)
{
/* Enable the interrupt (RX and TX interrupts are still disabled
* in the UART
*/
up_enable_irq(priv->irq);
}
return ret;
}
/****************************************************************************
* Name: up_detach
*
* Description:
* Detach UART interrupts. This method is called when the serial port is
* closed normally just before the shutdown method is called. The exception
* is the serial console which is never shutdown.
*
****************************************************************************/
static void up_detach(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* Disable interrupts */
up_disable_irq(priv->irq);
/* Detach from the interrupt */
irq_detach(priv->irq);
}
/****************************************************************************
* Name: up_interrupt
*
* Description:
* This is the UART interrupt handler. It will be invoked when an
* interrupt received on the 'irq' It should call uart_transmitchars or
* uart_receivechar to perform the appropriate data transfers. The
* interrupt handling logic must be able to map the 'irq' number into the
* appropriate uart_dev_s structure in order to call these functions.
*
****************************************************************************/
static int up_interrupt(int irq, void *context, void *arg)
{
struct uart_dev_s *dev = (struct uart_dev_s *)arg;
struct up_dev_s *priv;
uint32_t status;
int passes;
DEBUGASSERT(dev != NULL && dev->priv != NULL);
priv = (struct up_dev_s *)dev->priv;
/* Loop until there are no characters to be transferred or,
* until we have been looping for a long time.
*/
for (passes = 0; passes < 256; passes++)
{
/* Retrieve interrupt pending status */
status = up_serialin(priv, UART_IP_OFFSET);
if (status == 0)
{
break;
}
if (status & UART_IP_RXWM)
{
/* Process incoming bytes */
uart_recvchars(dev);
}
if (status & UART_IP_TXWM)
{
/* Process outgoing bytes */
uart_xmitchars(dev);
}
}
return OK;
}
/****************************************************************************
* Name: up_ioctl
*
* Description:
* All ioctl calls will be routed through this method
*
****************************************************************************/
static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
{
return -ENOTTY;
}
/****************************************************************************
* Name: up_receive
*
* Description:
* Called (usually) from the interrupt level to receive one
* character from the UART. Error bits associated with the
* receipt are provided in the return 'status'.
*
****************************************************************************/
static int up_receive(struct uart_dev_s *dev, unsigned int *status)
{
/* Return status information */
if (status)
{
*status = 0; /* We are not yet tracking serial errors */
}
/* Return cached data */
return g_rxdata;
}
/****************************************************************************
* Name: up_rxint
*
* Description:
* Call to enable or disable RX interrupts
*
****************************************************************************/
static void up_rxint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
irqstate_t flags = enter_critical_section();
if (enable)
{
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
priv->im |= UART_IE_RXWM;
#endif
}
else
{
priv->im &= ~UART_IE_RXWM;
}
up_serialout(priv, UART_IE_OFFSET, priv->im);
leave_critical_section(flags);
}
/****************************************************************************
* Name: up_rxavailable
*
* Description:
* Return true if the receive register is not empty
*
****************************************************************************/
static bool up_rxavailable(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* Return true is data is available in the receive data buffer */
uint32_t rxdata = up_serialin(priv, UART_RXDATA_OFFSET);
/* NOTE: In K210, actual data is also retrieved */
g_rxdata = rxdata & 0xff;
return (rxdata & UART_RX_EMPTY) == 0;
}
/****************************************************************************
* Name: up_send
*
* Description:
* This method will send one byte on the UART.
*
****************************************************************************/
static void up_send(struct uart_dev_s *dev, int ch)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
up_serialout(priv, UART_TXDATA_OFFSET, (uint32_t)ch);
}
/****************************************************************************
* Name: up_txint
*
* Description:
* Call to enable or disable TX interrupts
*
****************************************************************************/
static void up_txint(struct uart_dev_s *dev, bool enable)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
irqstate_t flags;
flags = enter_critical_section();
if (enable)
{
/* Enable the TX interrupt */
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
priv->im |= UART_IE_TXWM;
up_serialout(priv, UART_IE_OFFSET, priv->im);
/* Fake a TX interrupt here by just calling uart_xmitchars() with
* interrupts disabled (note this may recurse).
*/
uart_xmitchars(dev);
#endif
}
else
{
/* Disable the TX interrupt */
priv->im &= ~UART_IE_TXWM;
up_serialout(priv, UART_IE_OFFSET, priv->im);
}
leave_critical_section(flags);
}
/****************************************************************************
* Name: up_txready
*
* Description:
* Return true if the tranmsit data register is not full
*
****************************************************************************/
static bool up_txready(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* Return TRUE if the TX FIFO is not full */
return (up_serialin(priv, UART_TXDATA_OFFSET) & UART_TX_FULL) == 0;
}
/****************************************************************************
* Name: up_txempty
*
* Description:
* Return true if the tranmsit data register is empty
*
****************************************************************************/
static bool up_txempty(struct uart_dev_s *dev)
{
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
/* Return TRUE if the TX wartermak is pending */
return (up_serialin(priv, UART_IP_OFFSET) & UART_IP_TXWM) == 1;
}
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef USE_EARLYSERIALINIT
/****************************************************************************
* Name: riscv_earlyserialinit
*
* Description:
* Performs the low level UART initialization early in debug so that the
* serial console will be available during bootup. This must be called
* before riscv_serialinit. NOTE: This function depends on GPIO pin
* configuration performed in up_consoleinit() and main clock
* initialization performed in up_clkinitialize().
*
****************************************************************************/
void riscv_earlyserialinit(void)
{
/* Disable interrupts from all UARTS. The console is enabled in
* k210_consoleinit().
*/
up_disableuartint(TTYS0_DEV.priv, NULL);
#ifdef TTYS1_DEV
up_disableuartint(TTYS1_DEV.priv, NULL);
#endif
/* Configuration whichever one is the console */
#ifdef HAVE_SERIAL_CONSOLE
CONSOLE_DEV.isconsole = true;
up_setup(&CONSOLE_DEV);
#endif
}
#endif
/****************************************************************************
* Name: riscv_serialinit
*
* Description:
* Register serial console and serial ports. This assumes
* that riscv_earlyserialinit was called previously.
*
****************************************************************************/
void riscv_serialinit(void)
{
/* Register the console */
#ifdef HAVE_SERIAL_CONSOLE
uart_register("/dev/console", &CONSOLE_DEV);
#endif
/* Register all UARTs */
uart_register("/dev/ttyS0", &TTYS0_DEV);
#ifdef CONFIG_K210_16550_UART
/* Register UART1-UART3 */
k210_uart_16550_register();
#endif
}
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes
*
****************************************************************************/
int up_putc(int ch)
{
#ifdef HAVE_SERIAL_CONSOLE
struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv;
uint8_t imr;
up_disableuartint(priv, &imr);
/* Check for LF */
if (ch == '\n')
{
/* Add CR */
riscv_lowputc('\r');
}
riscv_lowputc(ch);
up_restoreuartint(priv, imr);
#endif
return ch;
}
/****************************************************************************
* Name: riscv_earlyserialinit, riscv_serialinit, and up_putc
*
* Description:
* stubs that may be needed. These stubs would be used if all UARTs are
* disabled. In that case, the logic in common/up_initialize() is not
* smart enough to know that there are not UARTs and will still expect
* these interfaces to be provided.
*
****************************************************************************/
#else /* HAVE_UART_DEVICE */
void riscv_earlyserialinit(void)
{
}
void riscv_serialinit(void)
{
}
int up_putc(int ch)
{
return ch;
}
#endif /* HAVE_UART_DEVICE */
#else /* USE_SERIALDRIVER */
/****************************************************************************
* Name: up_putc
*
* Description:
* Provide priority, low-level access to support OS debug writes
*
****************************************************************************/
int up_putc(int ch)
{
#ifdef HAVE_SERIAL_CONSOLE
/* Check for LF */
if (ch == '\n')
{
/* Add CR */
riscv_lowputc('\r');
}
riscv_lowputc(ch);
#endif
return ch;
}
#endif /* USE_SERIALDRIVER */

View File

@ -0,0 +1,340 @@
/****************************************************************************
* include/nuttx/serial/uart_16550.h
* Serial driver for 16550 UART
*
* 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 __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H
#define __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_K210_16550_UART
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* CONFIGURATION ************************************************************/
/* Are any UARTs enabled? */
#undef HAVE_UART
#if defined(CONFIG_K210_16550_UART1) || defined(CONFIG_K210_16550_UART2) || defined(CONFIG_K210_16550_UART3)
# define HAVE_UART 1
#endif
/* We need to be told the address increment between registers and the
* register bit width.
*/
#ifndef CONFIG_K210_16550_REGINCR
# error "CONFIG_K210_16550_REGINCR not defined"
#endif
#if CONFIG_K210_16550_REGINCR != 1 && CONFIG_K210_16550_REGINCR != 2 && CONFIG_K210_16550_REGINCR != 4
# error "CONFIG_K210_16550_REGINCR not supported"
#endif
#ifndef CONFIG_K210_16550_REGWIDTH
# error "CONFIG_K210_16550_REGWIDTH not defined"
#endif
#if CONFIG_K210_16550_REGWIDTH != 8 && CONFIG_K210_16550_REGWIDTH != 16 && CONFIG_K210_16550_REGWIDTH != 32
# error "CONFIG_K210_16550_REGWIDTH not supported"
#endif
#ifndef CONFIG_K210_16550_ADDRWIDTH
# error "CONFIG_K210_16550_ADDRWIDTH not defined"
#endif
#if CONFIG_K210_16550_ADDRWIDTH != 0 && CONFIG_K210_16550_ADDRWIDTH != 8 && \
CONFIG_K210_16550_ADDRWIDTH != 16 && CONFIG_K210_16550_ADDRWIDTH != 32 && \
CONFIG_K210_16550_ADDRWIDTH != 64
# error "CONFIG_K210_16550_ADDRWIDTH not supported"
#endif
/* If a UART is enabled, then its base address, clock, and IRQ
* must also be provided
*/
#ifdef CONFIG_K210_16550_UART1
# ifndef CONFIG_K210_16550_UART1_BASE
# error "CONFIG_K210_16550_UART1_BASE not provided"
# undef CONFIG_K210_16550_UART1
# endif
# ifndef CONFIG_K210_16550_UART1_CLOCK
# error "CONFIG_K210_16550_UART1_CLOCK not provided"
# undef CONFIG_K210_16550_UART1
# endif
# ifndef CONFIG_K210_16550_UART1_IRQ
# error "CONFIG_K210_16550_UART1_IRQ not provided"
# undef CONFIG_K210_16550_UART1
# endif
#endif
#ifdef CONFIG_K210_16550_UART2
# ifndef CONFIG_K210_16550_UART2_BASE
# error "CONFIG_K210_16550_UART2_BASE not provided"
# undef CONFIG_K210_16550_UART2
# endif
# ifndef CONFIG_K210_16550_UART2_CLOCK
# error "CONFIG_K210_16550_UART2_CLOCK not provided"
# undef CONFIG_K210_16550_UART2
# endif
# ifndef CONFIG_K210_16550_UART2_IRQ
# error "CONFIG_K210_16550_UART2_IRQ not provided"
# undef CONFIG_K210_16550_UART2
# endif
#endif
#ifdef CONFIG_K210_16550_UART3
# ifndef CONFIG_K210_16550_UART3_BASE
# error "CONFIG_K210_16550_UART3_BASE not provided"
# undef CONFIG_K210_16550_UART3
# endif
# ifndef CONFIG_K210_16550_UART3_CLOCK
# error "CONFIG_K210_16550_UART3_CLOCK not provided"
# undef CONFIG_K210_16550_UART3
# endif
# ifndef CONFIG_K210_16550_UART3_IRQ
# error "CONFIG_K210_16550_UART3_IRQ not provided"
# undef CONFIG_K210_16550_UART3
# endif
#endif
/* Is there a serial console? There should be at most one defined.
* It could be on any UARTn, n=0,1,2,3
*/
/* Register offsets *********************************************************/
#define UART_RBR_INCR 0 /* (DLAB =0) Receiver Buffer Register */
#define UART_THR_INCR 0 /* (DLAB =0) Transmit Holding Register */
#define UART_DLL_INCR 0 /* (DLAB =1) Divisor Latch LSB */
#define UART_DLM_INCR 1 /* (DLAB =1) Divisor Latch MSB */
#define UART_IER_INCR 1 /* (DLAB =0) Interrupt Enable Register */
#define UART_IIR_INCR 2 /* Interrupt ID Register */
#define UART_FCR_INCR 2 /* FIFO Control Register */
#define UART_LCR_INCR 3 /* Line Control Register */
#define UART_MCR_INCR 4 /* Modem Control Register */
#define UART_LSR_INCR 5 /* Line Status Register */
#define UART_MSR_INCR 6 /* Modem Status Register */
#define UART_SCR_INCR 7 /* Scratch Pad Register */
#define UART_SRT_INCR 39 /* Receive Fifo Trigger Register*/
#define UART_DLF_INCR 48 /* Divisor factor Register*/
#define UART_CPR_INCR 61 /* Component Register */
#define UART_RBR_OFFSET (CONFIG_K210_16550_REGINCR*UART_RBR_INCR)
#define UART_THR_OFFSET (CONFIG_K210_16550_REGINCR*UART_THR_INCR)
#define UART_DLL_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLL_INCR)
#define UART_DLM_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLM_INCR)
#define UART_IER_OFFSET (CONFIG_K210_16550_REGINCR*UART_IER_INCR)
#define UART_IIR_OFFSET (CONFIG_K210_16550_REGINCR*UART_IIR_INCR)
#define UART_FCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_FCR_INCR)
#define UART_LCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_LCR_INCR)
#define UART_MCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_MCR_INCR)
#define UART_LSR_OFFSET (CONFIG_K210_16550_REGINCR*UART_LSR_INCR)
#define UART_MSR_OFFSET (CONFIG_K210_16550_REGINCR*UART_MSR_INCR)
#define UART_SCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_SCR_INCR)
#define UART_SRT_OFFSET (CONFIG_K210_16550_REGINCR*UART_SRT_INCR)
#define UART_DLF_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLF_INCR)
#define UART_CPR_OFFSET (CONFIG_K210_16550_REGINCR*UART_CPR_INCR)
/* Register bit definitions *************************************************/
/* RBR (DLAB =0) Receiver Buffer Register */
#define UART_RBR_MASK (0xff) /* Bits 0-7: Oldest received byte in RX FIFO */
/* Bits 8-31: Reserved */
/* THR (DLAB =0) Transmit Holding Register */
#define UART_THR_MASK (0xff) /* Bits 0-7: Adds byte to TX FIFO */
/* Bits 8-31: Reserved */
/* DLL (DLAB =1) Divisor Latch LSB */
#define UART_DLL_MASK (0xff) /* Bits 0-7: DLL */
/* Bits 8-31: Reserved */
/* DLM (DLAB =1) Divisor Latch MSB */
#define UART_DLM_MASK (0xff) /* Bits 0-7: DLM */
/* Bits 8-31: Reserved */
/* IER (DLAB =0) Interrupt Enable Register */
#define UART_IER_ERBFI (1 << 0) /* Bit 0: Enable received data available interrupt */
#define UART_IER_ETBEI (1 << 1) /* Bit 1: Enable THR empty interrupt */
#define UART_IER_ELSI (1 << 2) /* Bit 2: Enable receiver line status interrupt */
#define UART_IER_EDSSI (1 << 3) /* Bit 3: Enable MODEM status interrupt */
/* Bits 4-7: Reserved */
#define UART_IER_ALLIE (0x0f)
/* IIR Interrupt ID Register */
#define UART_IIR_INTSTATUS (1 << 0) /* Bit 0: Interrupt status (active low) */
#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */
#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT)
# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Status */
# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THR Empty Interrupt */
# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* Receive Data Available (RDA) */
# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* Receiver Line Status (RLS) */
# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* Character Time-out Indicator (CTI) */
/* Bits 4-5: Reserved */
#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: RCVR FIFO interrupt */
#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT)
/* FCR FIFO Control Register */
#define UART_FCR_FIFOEN (1 << 0) /* Bit 0: Enable FIFOs */
#define UART_FCR_RXRST (1 << 1) /* Bit 1: RX FIFO Reset */
#define UART_FCR_TXRST (1 << 2) /* Bit 2: TX FIFO Reset */
#define UART_FCR_DMAMODE (1 << 3) /* Bit 3: DMA Mode Select */
/* Bits 4-5: Reserved */
#define UART_FCR_RXTRIGGER_SHIFT (6) /* Bits 6-7: RX Trigger Level */
#define UART_FCR_RXTRIGGER_MASK (3 << UART_FCR_RXTRIGGER_SHIFT)
# define UART_FCR_RXTRIGGER_1 (0 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 0 (1 character) */
# define UART_FCR_RXTRIGGER_4 (1 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 1 (4 characters) */
# define UART_FCR_RXTRIGGER_8 (2 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 2 (8 characters) */
# define UART_FCR_RXTRIGGER_14 (3 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 3 (14 characters) */
/* LCR Line Control Register */
#define UART_LCR_WLS_SHIFT (0) /* Bit 0-1: Word Length Select */
#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT)
# define UART_LCR_WLS_5BIT (0 << UART_LCR_WLS_SHIFT)
# define UART_LCR_WLS_6BIT (1 << UART_LCR_WLS_SHIFT)
# define UART_LCR_WLS_7BIT (2 << UART_LCR_WLS_SHIFT)
# define UART_LCR_WLS_8BIT (3 << UART_LCR_WLS_SHIFT)
#define UART_LCR_STB (1 << 2) /* Bit 2: Number of Stop Bits */
#define UART_LCR_PEN (1 << 3) /* Bit 3: Parity Enable */
#define UART_LCR_EPS (1 << 4) /* Bit 4: Even Parity Select */
#define UART_LCR_STICKY (1 << 5) /* Bit 5: Stick Parity */
#define UART_LCR_BRK (1 << 6) /* Bit 6: Break Control */
#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit (DLAB) */
/* MCR Modem Control Register */
#define UART_MCR_DTR (1 << 0) /* Bit 0: DTR Control Source for DTR output */
#define UART_MCR_RTS (1 << 1) /* Bit 1: Control Source for RTS output */
#define UART_MCR_OUT1 (1 << 2) /* Bit 2: Auxiliary user-defined output 1 */
#define UART_MCR_OUT2 (1 << 3) /* Bit 3: Auxiliary user-defined output 2 */
#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */
#define UART_MCR_AFCE (1 << 5) /* Bit 5: Auto Flow Control Enable */
/* Bit 6-7: Reserved */
/* LSR Line Status Register */
#define UART_LSR_DR (1 << 0) /* Bit 0: Data Ready */
#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */
#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */
#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */
#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */
#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */
#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */
#define UART_LSR_RXFE (1 << 7) /* Bit 7: Error in RX FIFO (RXFE) */
#define UART_INTERRUPT_SEND 0x02U
#define UART_INTERRUPT_RECEIVE 0x04U
#define UART_INTERRUPT_CHARACTER_TIMEOUT 0x0CU
/* SCR Scratch Pad Register */
#define UART_SCR_MASK (0xff) /* Bits 0-7: SCR data */
/****************************************************************************
* Public Types
****************************************************************************/
#if CONFIG_K210_16550_REGWIDTH == 8
typedef uint8_t uart_datawidth_t;
#elif CONFIG_K210_16550_REGWIDTH == 16
typedef uint16_t uart_datawidth_t;
#elif CONFIG_K210_16550_REGWIDTH == 32
typedef uint32_t uart_datawidth_t;
#endif
#if CONFIG_K210_16550_ADDRWIDTH == 0
typedef uintptr_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 8
typedef uint8_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 16
typedef uint16_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 32
typedef uint32_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 64
typedef uint64_t uart_addrwidth_t;
#endif
struct k210_16550_s
{
uart_addrwidth_t uartbase; /* Base address of UART registers */
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
uint32_t baud; /* Configured baud */
uint32_t uartclk; /* UART clock frequency */
#endif
uart_datawidth_t ier; /* Saved IER value */
uint8_t irq; /* IRQ associated with this UART */
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (7 or 8) */
int stopbits2; /* true: Configure with 2 stop bits instead of 1 */
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
bool flow; /* flow control (RTS/CTS) enabled */
#endif
#endif
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Public Functions Definitions
****************************************************************************/
/****************************************************************************
* Name: uart_getreg(), uart_putreg(), uart_ioctl()
*
* Description:
* These functions must be provided by the processor-specific code in order
* to correctly access 16550 registers
* uart_ioctl() is optional to provide custom IOCTLs
*
****************************************************************************/
#ifndef CONFIG_SERIAL_UART_ARCH_MMIO
uart_datawidth_t uart_getreg(uart_addrwidth_t base, unsigned int offset);
void uart_putreg(uart_addrwidth_t base,
unsigned int offset,
uart_datawidth_t value);
#endif
struct file; /* Forward reference */
int uart_ioctl(struct file *filep, int cmd, unsigned long arg);
void k210_uart_16550_register(void);
#endif /* CONFIG_K210_16550_UART */
#endif /* __INCLUDE_NUTTX_SERIAL_UART_16550_H */