risc-v/esp32c3: Add basic UART support for console
This commit is contained in:
parent
b11a5ca8b2
commit
998f7e5d4c
@ -75,6 +75,16 @@ config ESP32C3_ESP32C3XXX
|
||||
|
||||
menu "ESP32-C3 Peripheral Support"
|
||||
|
||||
config ESP32C3_UART0
|
||||
bool "UART0"
|
||||
default y
|
||||
select UART0_SERIALDRIVER
|
||||
|
||||
config ESP32C3_UART1
|
||||
bool "UART1"
|
||||
default n
|
||||
select UART1_SERIALDRIVER
|
||||
|
||||
endmenu
|
||||
|
||||
endif # ARCH_CHIP_ESP32C3
|
||||
|
@ -51,3 +51,4 @@ endif
|
||||
|
||||
CHIP_CSRCS = esp32c3_allocateheap.c esp32c3_start.c esp32c3_idle.c
|
||||
CHIP_CSRCS += esp32c3_irq.c esp32c3_timerisr.c
|
||||
CHIP_CSRCS += esp32c3_serial.c esp32c3_lowputc.c
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <arch/irq.h>
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_arch.h"
|
||||
#include "esp32c3_rom.h"
|
||||
#include "chip.h"
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/esp32c3/esp32c3_rom.h
|
||||
* arch/risc-v/src/esp32c3/esp32c3_config.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
@ -18,19 +18,46 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_ROM_H
|
||||
#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_ROM_H
|
||||
#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_CONFIG_H
|
||||
#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_CONFIG_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/chip/chip.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ets_printf
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
int ets_printf(const char *fmt, ...);
|
||||
/* UARTs ********************************************************************/
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_ROM_H */
|
||||
/* Are any UARTs enabled? */
|
||||
|
||||
#undef HAVE_UART_DEVICE
|
||||
#if defined(CONFIG_ESP32C3_UART0) || defined(CONFIG_ESP32C3_UART1)
|
||||
# define HAVE_UART_DEVICE 1 /* Flag to indicate a UART has been selected */
|
||||
#endif
|
||||
|
||||
/* Serial Console ***********************************************************/
|
||||
|
||||
/* Is there a serial console? There should be no more than one defined. It
|
||||
* could be on any UARTn. n E {0,1}
|
||||
*/
|
||||
|
||||
#undef HAVE_SERIAL_CONSOLE
|
||||
#if defined(CONFIG_UART0_SERIAL_CONSOLE) && defined(CONFIG_ESP32C3_UART0)
|
||||
# undef CONFIG_UART1_SERIAL_CONSOLE
|
||||
# define HAVE_SERIAL_CONSOLE 1
|
||||
#elif defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_ESP32C3_UART1)
|
||||
# undef CONFIG_UART0_SERIAL_CONSOLE
|
||||
# define HAVE_SERIAL_CONSOLE 1
|
||||
#else
|
||||
# undef CONFIG_UART0_SERIAL_CONSOLE
|
||||
# undef CONFIG_UART1_SERIAL_CONSOLE
|
||||
#endif
|
||||
|
||||
#endif /* __ARCH_XTENSA_SRC_ESP32C3_ESP32C3_CONFIG_H */
|
394
arch/risc-v/src/esp32c3/esp32c3_lowputc.c
Normal file
394
arch/risc-v/src/esp32c3/esp32c3_lowputc.c
Normal file
@ -0,0 +1,394 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/esp32c3/esp32c3_lowputc.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 <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "hardware/esp32c3_uart.h"
|
||||
#include "riscv_arch.h"
|
||||
#include "chip.h"
|
||||
#include "esp32c3_lowputc.h"
|
||||
#include "esp32c3_config.h"
|
||||
#include "hardware/esp32c3_soc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
# if defined(CONFIG_UART0_SERIAL_CONSOLE)
|
||||
|
||||
static const struct esp32c3_uart_s g_console_config =
|
||||
{
|
||||
.base = REG_UART_BASE(0),
|
||||
.id = 0,
|
||||
.irq = -1, /* TODO */
|
||||
.baud = CONFIG_UART0_BAUD,
|
||||
.bits = CONFIG_UART0_BITS,
|
||||
.parity = CONFIG_UART0_PARITY,
|
||||
.stop_b2 = CONFIG_UART0_2STOP,
|
||||
.int_pri = 1
|
||||
};
|
||||
|
||||
# elif defined(CONFIG_UART1_SERIAL_CONSOLE)
|
||||
|
||||
static const struct esp32c3_uart_s g_uart1_config =
|
||||
{
|
||||
.base = REG_UART_BASE(1),
|
||||
.id = 1,
|
||||
.irq = -1, /* TODO */
|
||||
.baud = CONFIG_UART1_BAUD,
|
||||
.bits = CONFIG_UART1_BITS,
|
||||
.parity = CONFIG_UART1_PARITY,
|
||||
.stop_b2 = CONFIG_UART1_2STOP,
|
||||
.int_pri = 1
|
||||
};
|
||||
#endif /* CONFIG_UART0_SERIAL_CONSOLE */
|
||||
#endif /* HAVE_SERIAL_CONSOLE */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_reset_core
|
||||
* Reset both TX and RX core
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_reset_core(const struct esp32c3_uart_s *conf)
|
||||
{
|
||||
uint32_t set_bit = 1 << UART_RST_CORE_S;
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_RST_CORE_M, set_bit);
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_RST_CORE_M, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_enable_sclk
|
||||
* Enable clock for whole core
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_enable_sclk(const struct esp32c3_uart_s *conf)
|
||||
{
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_SCLK_EN_M,
|
||||
1 << UART_SCLK_EN_S);
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_RX_SCLK_EN_M,
|
||||
1 << UART_RX_SCLK_EN_S);
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_TX_SCLK_EN_M,
|
||||
1 << UART_TX_SCLK_EN_S);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_disable_sclk
|
||||
* Disable clock for whole core
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_disable_sclk(const struct esp32c3_uart_s *conf)
|
||||
{
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_SCLK_EN_M, 0);
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_RX_SCLK_EN_M, 0);
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_TX_SCLK_EN_M, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_set_sclk
|
||||
* Set a source clock for UART
|
||||
* APB_CLK = 1 80 MHz
|
||||
* CLK_8 = 2 8 MHz
|
||||
* XTAL_CLK = 3
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_set_sclk(const struct esp32c3_uart_s *conf, enum
|
||||
uart_sclk source)
|
||||
{
|
||||
uint32_t clk = (uint32_t)source << UART_SCLK_SEL_S;
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_SCLK_SEL_M, clk);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_get_sclk
|
||||
* Get the source clock for UART
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t esp32c3_lowputc_get_sclk(const struct esp32c3_uart_s * conf)
|
||||
{
|
||||
uint32_t clk_conf_reg;
|
||||
uint32_t ret = -ENODATA;
|
||||
clk_conf_reg = getreg32(UART_CLK_CONF_REG(conf->id));
|
||||
clk_conf_reg &= UART_SCLK_SEL_M;
|
||||
clk_conf_reg >>= UART_SCLK_SEL_S;
|
||||
switch (clk_conf_reg)
|
||||
{
|
||||
case 1:
|
||||
ret = APB_CLK_FREQ;
|
||||
break;
|
||||
case 2:
|
||||
ret = RTC_CLK_FREQ;
|
||||
break;
|
||||
case 3:
|
||||
ret = XTAL_CLK_FREQ;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_baud
|
||||
* Set the baud rate
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_baud(const struct esp32c3_uart_s * conf)
|
||||
{
|
||||
const int sclk_div = 1;
|
||||
uint32_t sclk_freq = esp32c3_lowputc_get_sclk(conf);
|
||||
uint32_t clk_div = ((sclk_freq) << 4) / conf->baud;
|
||||
uint32_t int_part = clk_div >> 4;
|
||||
uint32_t frag_part = clk_div & 0xf;
|
||||
|
||||
/* The baud rate configuration register is divided into
|
||||
* an integer part and a fractional part.
|
||||
*/
|
||||
|
||||
modifyreg32(UART_CLKDIV_REG(conf->id), UART_CLKDIV_M, int_part);
|
||||
modifyreg32(UART_CLKDIV_REG(conf->id), UART_CLKDIV_FRAG_M,
|
||||
frag_part << UART_CLKDIV_FRAG_S);
|
||||
modifyreg32(UART_CLK_CONF_REG(conf->id), UART_SCLK_DIV_NUM_M,
|
||||
(sclk_div - 1) << UART_SCLK_DIV_NUM_S);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_normal_mode
|
||||
* Set the UART to operate in normal mode
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_normal_mode(const struct esp32c3_uart_s * conf)
|
||||
{
|
||||
/* Disable RS485 mode */
|
||||
|
||||
modifyreg32(UART_RS485_CONF_REG(conf->id), UART_RS485_EN_M, 0);
|
||||
modifyreg32(UART_RS485_CONF_REG(conf->id), UART_RS485TX_RX_EN_M, 0);
|
||||
modifyreg32(UART_RS485_CONF_REG(conf->id), UART_RS485RXBY_TX_EN_M, 0);
|
||||
|
||||
/* Disable IRDA mode */
|
||||
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_IRDA_EN_M, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_parity
|
||||
* Set the parity
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_parity(const struct esp32c3_uart_s * conf)
|
||||
{
|
||||
if (conf->parity == UART_PARITY_DISABLE)
|
||||
{
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_PARITY_EN_M, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_PARITY_M,
|
||||
((conf->parity & 0x1) << UART_PARITY_S));
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_PARITY_EN_M,
|
||||
1 << UART_PARITY_EN_S);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_data_length
|
||||
* Set the data length
|
||||
****************************************************************************/
|
||||
|
||||
int esp32c3_lowputc_data_length(const struct esp32c3_uart_s * conf)
|
||||
{
|
||||
int ret = OK;
|
||||
uint32_t length = (conf->bits - 5);
|
||||
|
||||
/* If it is the allowed range */
|
||||
|
||||
if (length >= UART_DATA_5_BITS && length <= UART_DATA_8_BITS)
|
||||
{
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_BIT_NUM_M,
|
||||
length << UART_BIT_NUM_S);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_stop_length
|
||||
* Set the stop length
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_stop_length(const struct esp32c3_uart_s * conf)
|
||||
{
|
||||
if (conf->stop_b2 == 0)
|
||||
{
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_STOP_BIT_NUM_M,
|
||||
UART_STOP_BITS_1 << UART_STOP_BIT_NUM_S);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifyreg32(UART_CONF0_REG(conf->id), UART_STOP_BIT_NUM_M,
|
||||
UART_STOP_BITS_2 << UART_STOP_BIT_NUM_S);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_set_tx_idle_time
|
||||
* Set the idle time between transfers
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_set_tx_idle_time(const struct esp32c3_uart_s *
|
||||
conf, uint32_t time)
|
||||
{
|
||||
time = time << UART_TX_IDLE_NUM_S;
|
||||
time = time & UART_TX_IDLE_NUM_M; /* Just in case value overloads */
|
||||
modifyreg32(UART_IDLE_CONF_REG(conf->id), UART_TX_IDLE_NUM_M,
|
||||
time);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_send_byte
|
||||
* Send one byte
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_send_byte(const struct esp32c3_uart_s * conf,
|
||||
char byte)
|
||||
{
|
||||
putreg32((uint32_t) byte, UART_FIFO_REG(conf->id));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_is_tx_fifo_full
|
||||
* Verifies if TX FIFO is full
|
||||
****************************************************************************/
|
||||
|
||||
bool esp32c3_lowputc_is_tx_fifo_full(const struct esp32c3_uart_s *
|
||||
conf)
|
||||
{
|
||||
uint32_t reg;
|
||||
reg = getreg32(UART_STATUS_REG(conf->id));
|
||||
reg = reg >> UART_TXFIFO_CNT_S;
|
||||
reg = reg & UART_TXFIFO_CNT_V;
|
||||
if (reg < (UART_TX_FIFO_SIZE -1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_lowputc
|
||||
*
|
||||
* Description:
|
||||
* Output one byte on the serial console
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_lowputc(char ch)
|
||||
{
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
|
||||
/* Wait until the TX FIFO has space to insert new char */
|
||||
|
||||
while (esp32c3_lowputc_is_tx_fifo_full(&g_console_config));
|
||||
|
||||
/* Then send the character */
|
||||
|
||||
esp32c3_lowputc_send_byte(&g_console_config, ch);
|
||||
|
||||
#endif /* HAVE_CONSOLE */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowsetup
|
||||
*
|
||||
* Description:
|
||||
* This performs basic initialization of the UART used for the serial
|
||||
* console. Its purpose is to get the console output available as soon
|
||||
* as possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowsetup(void)
|
||||
{
|
||||
/* Enable and configure the selected console device */
|
||||
|
||||
#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG)
|
||||
|
||||
/* Configure Clock */
|
||||
|
||||
/* esp32c3_lowputc_set_sclk(&g_console_config, APB_CLK); */
|
||||
|
||||
/* Configure the UART Baud Rate */
|
||||
|
||||
/* esp32c3_lowputc_baud(&g_console_config); */
|
||||
|
||||
/* Set a mode */
|
||||
|
||||
esp32c3_lowputc_normal_mode(&g_console_config);
|
||||
|
||||
/* Parity */
|
||||
|
||||
esp32c3_lowputc_parity(&g_console_config);
|
||||
|
||||
/* Data Frame size */
|
||||
|
||||
esp32c3_lowputc_data_length(&g_console_config);
|
||||
|
||||
/* Stop bit */
|
||||
|
||||
esp32c3_lowputc_stop_length(&g_console_config);
|
||||
|
||||
/* No Tx idle interval */
|
||||
|
||||
esp32c3_lowputc_set_tx_idle_time(&g_console_config, 0);
|
||||
|
||||
/* Enable cores */
|
||||
|
||||
esp32c3_lowputc_enable_sclk(&g_console_config);
|
||||
|
||||
#endif /* HAVE_SERIAL_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */
|
||||
}
|
207
arch/risc-v/src/esp32c3/esp32c3_lowputc.h
Normal file
207
arch/risc-v/src/esp32c3/esp32c3_lowputc.h
Normal file
@ -0,0 +1,207 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/esp32c3/esp32c3_lowputc.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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "hardware/esp32c3_uart.h"
|
||||
#include "chip.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
enum uart_sclk
|
||||
{
|
||||
APB_CLK = 1, /* 80 MHz */
|
||||
CLK_8, /* 8 MHz */
|
||||
XTAL_CLK
|
||||
};
|
||||
|
||||
enum uart_parity
|
||||
{
|
||||
UART_PARITY_DISABLE,
|
||||
UART_PARITY_ODD,
|
||||
UART_PARITY_EVEN
|
||||
};
|
||||
|
||||
enum uart_data_length
|
||||
{
|
||||
UART_DATA_5_BITS,
|
||||
UART_DATA_6_BITS,
|
||||
UART_DATA_7_BITS,
|
||||
UART_DATA_8_BITS
|
||||
};
|
||||
|
||||
enum uart_stop_length
|
||||
{
|
||||
UART_STOP_BITS_1 = 0x1, /* stop bit: 1 bit */
|
||||
UART_STOP_BITS_2 = 0x3, /* stop bit: 2bits */
|
||||
};
|
||||
|
||||
/* Default FIFOs size */
|
||||
|
||||
#define UART_TX_FIFO_SIZE 128
|
||||
#define UART_RX_FIFO_SIZE 128
|
||||
|
||||
/* Struct used to store uart driver information and to
|
||||
* manipulate uart driver
|
||||
*/
|
||||
|
||||
struct esp32c3_uart_s
|
||||
{
|
||||
uint32_t base; /* Base address of UART registers */
|
||||
uint8_t periph; /* UART peripheral ID */
|
||||
int cpuint; /* CPU interrupt assigned to this UART */
|
||||
uint8_t id; /* UART ID */
|
||||
uint8_t irq; /* IRQ associated with this UART */
|
||||
uint32_t baud; /* Configured baud rate */
|
||||
uint8_t bits;
|
||||
uint8_t parity; /* 0=no parity, 1=odd parity, 2=even parity */
|
||||
uint8_t stop_b2; /* Use 2 stop bits? 0 no, others yes */
|
||||
uint8_t int_pri; /* UART Interrupt Priority */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_reset_core
|
||||
* Reset both TX and RX core
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_reset_core(const struct esp32c3_uart_s *conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_enable_sclk
|
||||
* Enable clock for whole core
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_enable_sclk(const struct esp32c3_uart_s *conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_disable_sclk
|
||||
* Disable clock for whole core
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_disable_sclk(const struct esp32c3_uart_s *conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_set_sclk
|
||||
* Set a source clock for UART
|
||||
* APB_CLK = 1 80 MHz
|
||||
* CLK_8 = 2 8 MHz
|
||||
* XTAL_CLK = 3
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_set_sclk(const struct esp32c3_uart_s *conf, enum
|
||||
uart_sclk source);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_get_sclk
|
||||
* Get the source clock for UART
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t esp32c3_lowputc_get_sclk(const struct esp32c3_uart_s *conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_baud
|
||||
* Set the baud rate
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_baud(const struct esp32c3_uart_s * conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_normal_mode
|
||||
* Set the UART to operate in normal mode
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_normal_mode(const struct esp32c3_uart_s * conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_parity
|
||||
* Set the parity
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_parity(const struct esp32c3_uart_s * conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_data_length
|
||||
* Set the data length
|
||||
****************************************************************************/
|
||||
|
||||
int esp32c3_lowputc_data_length(const struct esp32c3_uart_s * conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_stop_length
|
||||
* Set the stop length
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_stop_length(const struct esp32c3_uart_s * conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_set_tx_idle_time
|
||||
* Set the idle time between transfers
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_set_tx_idle_time(const struct esp32c3_uart_s *
|
||||
conf, uint32_t time);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_send_byte
|
||||
* Send one byte
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowputc_send_byte(const struct esp32c3_uart_s * conf,
|
||||
char byte);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowputc_is_tx_fifo_full
|
||||
* Send one byte
|
||||
****************************************************************************/
|
||||
|
||||
bool esp32c3_lowputc_is_tx_fifo_full(const struct esp32c3_uart_s *
|
||||
conf);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_lowsetup
|
||||
*
|
||||
* Description:
|
||||
* This performs basic initialization of the UART used for the serial
|
||||
* console. Its purpose is to get the console output available as soon
|
||||
* as possible.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void esp32c3_lowsetup(void);
|
696
arch/risc-v/src/esp32c3/esp32c3_serial.c
Normal file
696
arch/risc-v/src/esp32c3/esp32c3_serial.c
Normal file
@ -0,0 +1,696 @@
|
||||
/****************************************************************************
|
||||
* arch/risc-v/src/esp32c3/esp32c3_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 <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/serial/serial.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "hardware/esp32c3_uart.h"
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_arch.h"
|
||||
#include "chip.h"
|
||||
#include "esp32c3_lowputc.h"
|
||||
#include "esp32c3_config.h"
|
||||
#include "esp32c3_irq.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* The console is enabled, and it's not the syslog device,
|
||||
* so, it should be a serial device.
|
||||
*/
|
||||
|
||||
#ifdef USE_SERIALDRIVER
|
||||
|
||||
/* Which UART with be tty0/console and which tty1? */
|
||||
|
||||
/* First pick the console and ttys0.
|
||||
* Console can be UART0 or UART1, but will always be ttys0.
|
||||
*/
|
||||
|
||||
/* In case a UART was assigned to be
|
||||
* the console and the corresponding peripheral was also selected.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
# if defined(CONFIG_UART0_SERIAL_CONSOLE)
|
||||
# define CONSOLE_DEV g_uart0_dev /* UART0 is console */
|
||||
# define TTYS0_DEV g_uart0_dev /* UART0 is ttyS0 */
|
||||
# define UART0_ASSIGNED 1
|
||||
# elif defined(CONFIG_UART1_SERIAL_CONSOLE)
|
||||
# define CONSOLE_DEV g_uart1_dev /* UART1 is console */
|
||||
# define TTYS0_DEV g_uart1_dev /* UART1 is ttyS0 */
|
||||
# define UART1_ASSIGNED 1
|
||||
# endif /* CONFIG_UART0_SERIAL_CONSOLE */
|
||||
#else /* No console */
|
||||
# undef CONSOLE_DEV
|
||||
# if defined(CONFIG_ESP32C3_UART0)
|
||||
# define TTYS0_DEV g_uart0_dev /* UART0 is ttyS0 */
|
||||
# define UART0_ASSIGNED 1
|
||||
# elif defined(CONFIG_ESP32C3_UART1)
|
||||
# define TTYS0_DEV g_uart1_dev /* UART1 is ttyS0 */
|
||||
# define UART1_ASSIGNED 1
|
||||
# endif
|
||||
#endif /* HAVE_SERIAL_CONSOLE */
|
||||
|
||||
/* Pick ttys1 */
|
||||
|
||||
#if defined(CONFIG_ESP32C3_UART0) && !defined(UART0_ASSIGNED)
|
||||
# define TTYS1_DEV g_uart0_dev /* UART0 is ttyS1 */
|
||||
# define UART0_ASSIGNED 1
|
||||
#elif defined(CONFIG_ESP32C3_UART1) && !defined(UART1_ASSIGNED)
|
||||
# define TTYS1_DEV g_uart1_dev /* UART1 is ttyS1 */
|
||||
# define UART1_ASSIGNED 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UART_DEVICE
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Serial driver methods */
|
||||
|
||||
static int esp32c3_setup(struct uart_dev_s *dev);
|
||||
static void esp32c3_shutdown(struct uart_dev_s *dev);
|
||||
static int esp32c3_attach(struct uart_dev_s *dev);
|
||||
static void esp32c3_detach(struct uart_dev_s *dev);
|
||||
static void esp32c3_txint(struct uart_dev_s *dev, bool enable);
|
||||
static void esp32c3_rxint(struct uart_dev_s *dev, bool enable);
|
||||
static bool esp32c3_rxavailable(struct uart_dev_s *dev);
|
||||
static bool esp32c3_txready(struct uart_dev_s *dev);
|
||||
static bool esp32c3_txempty(struct uart_dev_s *dev);
|
||||
static void esp32c3_send(struct uart_dev_s *dev, int ch);
|
||||
static int esp32c3_receive(struct uart_dev_s *dev, unsigned int *status);
|
||||
static int esp32c3_ioctl(struct file *filep, int cmd, unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Operations */
|
||||
|
||||
static struct uart_ops_s g_uart_ops =
|
||||
{
|
||||
.setup = esp32c3_setup,
|
||||
.shutdown = esp32c3_shutdown,
|
||||
.attach = esp32c3_attach,
|
||||
.detach = esp32c3_detach,
|
||||
.txint = esp32c3_txint,
|
||||
.rxint = esp32c3_rxint,
|
||||
.rxavailable = esp32c3_rxavailable,
|
||||
.txready = esp32c3_txready,
|
||||
.txempty = esp32c3_txempty,
|
||||
.send = esp32c3_send,
|
||||
.receive = esp32c3_receive,
|
||||
.ioctl = esp32c3_ioctl,
|
||||
#ifdef CONFIG_SERIAL_IFLOWCONTROL
|
||||
.rxflowcontrol = NULL,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* UART 0 */
|
||||
|
||||
#ifdef CONFIG_ESP32C3_UART0
|
||||
|
||||
static char g_uart0_rxbuffer[CONFIG_UART0_RXBUFSIZE];
|
||||
static char g_uart0_txbuffer[CONFIG_UART0_TXBUFSIZE];
|
||||
|
||||
static struct esp32c3_uart_s g_uart0_config =
|
||||
{
|
||||
.base = REG_UART_BASE(0),
|
||||
.periph = ESP32C3_PERIPH_UART0,
|
||||
.id = 0,
|
||||
.irq = ESP32C3_IRQ_UART0,
|
||||
.baud = CONFIG_UART0_BAUD,
|
||||
.bits = CONFIG_UART0_BITS,
|
||||
.parity = CONFIG_UART0_PARITY,
|
||||
.stop_b2 = CONFIG_UART0_2STOP,
|
||||
.int_pri = 1
|
||||
};
|
||||
|
||||
/* Fill only the requested fields */
|
||||
|
||||
static uart_dev_t g_uart0_dev =
|
||||
{
|
||||
#ifdef CONFIG_UART0_SERIAL_CONSOLE
|
||||
.isconsole = true,
|
||||
#else
|
||||
.isconsole = false,
|
||||
#endif
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_UART0_TXBUFSIZE,
|
||||
.buffer = g_uart0_txbuffer,
|
||||
},
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_UART0_RXBUFSIZE,
|
||||
.buffer = g_uart0_rxbuffer,
|
||||
},
|
||||
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_uart0_config
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* UART 1 */
|
||||
|
||||
#ifdef CONFIG_ESP32C3_UART1
|
||||
|
||||
static char g_uart1_rxbuffer[CONFIG_UART1_RXBUFSIZE];
|
||||
static char g_uart1_txbuffer[CONFIG_UART1_TXBUFSIZE];
|
||||
|
||||
static struct esp32c3_uart_s g_uart1_config =
|
||||
{
|
||||
.base = REG_UART_BASE(1),
|
||||
.periph = ESP32C3_PERIPH_UART1,
|
||||
.id = 1,
|
||||
.irq = ESP32C3_IRQ_UART1,
|
||||
.baud = CONFIG_UART1_BAUD,
|
||||
.bits = CONFIG_UART1_BITS,
|
||||
.parity = CONFIG_UART1_PARITY,
|
||||
.stop_b2 = CONFIG_UART1_2STOP,
|
||||
.int_pri = 1
|
||||
};
|
||||
|
||||
/* Fill only the requested fields */
|
||||
|
||||
static uart_dev_t g_uart1_dev =
|
||||
{
|
||||
#ifdef CONFIG_UART1_SERIAL_CONSOLE
|
||||
.isconsole = true,
|
||||
#else
|
||||
.isconsole = false,
|
||||
#endif
|
||||
.xmit =
|
||||
{
|
||||
.size = CONFIG_UART1_TXBUFSIZE,
|
||||
.buffer = g_uart1_txbuffer,
|
||||
},
|
||||
.recv =
|
||||
{
|
||||
.size = CONFIG_UART1_RXBUFSIZE,
|
||||
.buffer = g_uart1_rxbuffer,
|
||||
},
|
||||
|
||||
.ops = &g_uart_ops,
|
||||
.priv = &g_uart1_config
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: uart_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 uart_handler(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
struct uart_dev_s *dev = (struct uart_dev_s *)arg;
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
uint32_t tx_mask = UART_TXFIFO_EMPTY_INT_ST_M | UART_TX_DONE_INT_ST_M;
|
||||
uint32_t rx_mask = UART_RXFIFO_TOUT_INT_ST_M | UART_RXFIFO_FULL_INT_ST_M;
|
||||
uint32_t int_status;
|
||||
|
||||
int_status = getreg32(UART_INT_ST_REG(priv->id));
|
||||
|
||||
/* Tx fifo empty interrupt or UART tx done int */
|
||||
|
||||
if (int_status & tx_mask)
|
||||
{
|
||||
uart_xmitchars(dev);
|
||||
modifyreg32(UART_INT_CLR_REG(priv->id), tx_mask, tx_mask);
|
||||
}
|
||||
|
||||
/* Rx fifo timeout interrupt or rx fifo full interrupt */
|
||||
|
||||
if (int_status & rx_mask)
|
||||
{
|
||||
uart_recvchars(dev);
|
||||
modifyreg32(UART_INT_CLR_REG(priv->id), rx_mask, rx_mask);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the UART baud, bits, parity, fifos, etc. This method is
|
||||
* called the first time that the serial port is opened.
|
||||
* For the serial console, this will occur very early in initialization,
|
||||
* for other serial ports this will occur when the port is first opened.
|
||||
* This setup does not include attaching or enabling interrupts.
|
||||
* That portion of the UART setup is performed when the attach() method
|
||||
* is called.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int esp32c3_setup(struct uart_dev_s *dev)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the UART. This method is called when the serial port is closed.
|
||||
* This method reverses the operation the setup method. NOTE that the serial
|
||||
* console is never shutdown.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void esp32c3_shutdown(struct uart_dev_s *dev)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_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 when 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() methods
|
||||
* are called.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int esp32c3_attach(struct uart_dev_s *dev)
|
||||
{
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
int ret;
|
||||
|
||||
/* Try to attach the IRQ to a CPU int */
|
||||
|
||||
priv->cpuint = esp32c3_request_irq(priv->periph, priv->int_pri,
|
||||
ESP32C3_INT_LEVEL);
|
||||
if (priv->cpuint < 0)
|
||||
{
|
||||
return priv->cpuint;
|
||||
}
|
||||
|
||||
/* Attach and enable the IRQ */
|
||||
|
||||
ret = irq_attach(priv->irq, uart_handler, dev);
|
||||
if (ret == OK)
|
||||
{
|
||||
up_enable_irq(priv->cpuint);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32_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 esp32c3_detach(struct uart_dev_s *dev)
|
||||
{
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
|
||||
up_disable_irq(priv->cpuint);
|
||||
irq_detach(priv->irq);
|
||||
esp32c3_free_cpuint(priv->periph);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_txint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable TX interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void esp32c3_txint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
irqstate_t flags;
|
||||
uint32_t ints_mask = UART_TXFIFO_EMPTY_INT_ENA_M | UART_TX_DONE_INT_ENA_M;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Set to receive an interrupt when the TX holding register register
|
||||
* is empty
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
modifyreg32(UART_INT_ENA_REG(priv->id), ints_mask, ints_mask);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the TX interrupt */
|
||||
|
||||
modifyreg32(UART_INT_ENA_REG(priv->id), ints_mask, 0);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_rxint
|
||||
*
|
||||
* Description:
|
||||
* Call to enable or disable RXRDY interrupts
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void esp32c3_rxint(struct uart_dev_s *dev, bool enable)
|
||||
{
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
irqstate_t flags;
|
||||
uint32_t ints_mask = UART_RXFIFO_TOUT_INT_ENA_M |
|
||||
UART_RXFIFO_FULL_INT_ENA_M;
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Receive an interrupt when their is anything in the Rx data register
|
||||
* (or an Rx timeout occurs).
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
modifyreg32(UART_INT_ENA_REG(priv->id), ints_mask, ints_mask);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the RX interrupts */
|
||||
|
||||
modifyreg32(UART_INT_ENA_REG(priv->id), ints_mask, 0);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_rxavailable
|
||||
*
|
||||
* Description:
|
||||
* Return true if the receive holding register is not empty
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool esp32c3_rxavailable(struct uart_dev_s *dev)
|
||||
{
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
uint32_t status_reg;
|
||||
uint32_t bytes;
|
||||
|
||||
status_reg = getreg32(UART_STATUS_REG(priv->id));
|
||||
bytes = status_reg & UART_RXFIFO_CNT_M;
|
||||
|
||||
return (bytes > 0) ? true : false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_txready
|
||||
*
|
||||
* Description:
|
||||
* Return true if the tranmsit hardware is ready to send another byte. This
|
||||
* is used to determine if send() method can be called.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool esp32c3_txready(struct uart_dev_s *dev)
|
||||
{
|
||||
return (esp32c3_lowputc_is_tx_fifo_full(dev->priv)) ? false : true;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_txempty
|
||||
*
|
||||
* Description:
|
||||
* Return true if all characters have been sent. If for example, the UART
|
||||
* hardware implements FIFOs, then this would mean the transmit FIFO is
|
||||
* empty. This method is called when the driver needs to make sure that
|
||||
* all characters are "drained" from the TX hardware.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static bool esp32c3_txempty(struct uart_dev_s *dev)
|
||||
{
|
||||
uint32_t reg;
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
|
||||
reg = getreg32(UART_INT_RAW_REG(priv->id));
|
||||
reg = reg & UART_TXFIFO_EMPTY_INT_RAW_M;
|
||||
|
||||
return (reg > 0) ? true : false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the UART. This method is called when the serial port is closed.
|
||||
* This method reverses the operation the setup method. NOTE that the serial
|
||||
* console is never shutdown.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void esp32c3_send(struct uart_dev_s *dev, int ch)
|
||||
{
|
||||
/* Then send the character */
|
||||
|
||||
esp32c3_lowputc_send_byte(dev->priv, ch);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: esp32c3_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 esp32c3_receive(struct uart_dev_s *dev, unsigned int *status)
|
||||
{
|
||||
uint32_t rx_fifo;
|
||||
struct esp32c3_uart_s *priv = dev->priv;
|
||||
|
||||
rx_fifo = getreg32(UART_FIFO_REG(priv->id));
|
||||
rx_fifo = rx_fifo & UART_RXFIFO_RD_BYTE_M;
|
||||
|
||||
return (int)rx_fifo;
|
||||
}
|
||||
|
||||
static int esp32c3_ioctl(struct file *filep, int cmd, unsigned long arg)
|
||||
{
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef USE_EARLYSERIALINIT
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_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 up_serialinit. NOTE: This function depends on GPIO pin
|
||||
* configuration performed in up_consoleinit() and main clock
|
||||
* initialization performed in up_clkinitialize().
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* TODO */
|
||||
|
||||
void up_earlyserialinit(void)
|
||||
{
|
||||
/* I've been looking at others chips/arches and I noticed
|
||||
* that <chips>_lowsetup performs almost the same of this func and it's
|
||||
* called earlier than this one in <chip>_start
|
||||
* So, I am not sure what to do here
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* USE_EARLYSERIALINIT */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_serialinit
|
||||
*
|
||||
* Description:
|
||||
* Register serial console and serial ports. This assumes
|
||||
* that up_earlyserialinit was called previously.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* TODO */
|
||||
|
||||
void up_serialinit(void)
|
||||
{
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
uart_register("/dev/console", &CONSOLE_DEV);
|
||||
#endif
|
||||
|
||||
/* At least one UART char driver will logically be registered */
|
||||
|
||||
uart_register("/dev/ttyS0", &TTYS0_DEV);
|
||||
|
||||
#ifdef TTYS1_DEV
|
||||
uart_register("/dev/ttyS1", &TTYS1_DEV);
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_putc
|
||||
*
|
||||
* Description:
|
||||
* Provide priority, low-level access to support OS debug writes
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* TODO - To finish later with interrupt */
|
||||
|
||||
int up_putc(int ch)
|
||||
{
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
|
||||
/* TODO disable uart ints */
|
||||
|
||||
/* Check for LF */
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
/* Add CR */
|
||||
|
||||
up_lowputc('\r');
|
||||
}
|
||||
|
||||
up_lowputc(ch);
|
||||
|
||||
/* TODO restore ints */
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
||||
#else /* HAVE_UART_DEVICE */
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_earlyserialinit, up_serialinit, and up_putc
|
||||
*
|
||||
* Description:
|
||||
* stubs that may be needed. These stubs will 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_earlyserialinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
void up_serialinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int up_putc(int ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
|
||||
#endif /* HAVE_UART_DEVICE */
|
||||
#else /* USE_SERIALDRIVER */
|
||||
|
||||
/* 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 up_earlyserialinit(), up_serialinit(), and
|
||||
* up_putc().
|
||||
*/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_putc
|
||||
*
|
||||
* Description:
|
||||
* Provide priority, low-level access to support OS debug writes
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* TODO - Finish it disabling interrupt and restoring it later */
|
||||
|
||||
int up_putc(int ch)
|
||||
{
|
||||
#ifdef HAVE_SERIAL_CONSOLE
|
||||
/* Check for LF */
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
/* Add CR */
|
||||
|
||||
up_lowputc('\r');
|
||||
}
|
||||
|
||||
up_lowputc(ch);
|
||||
#endif
|
||||
return ch;
|
||||
}
|
||||
|
||||
#endif /* USE_SERIALDRIVER */
|
@ -32,13 +32,14 @@
|
||||
#include "chip.h"
|
||||
#include "esp32c3.h"
|
||||
#include "esp32c3_irq.h"
|
||||
#include "esp32c3_lowputc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
# define showprogress(c) ets_printf("%c", c)
|
||||
# define showprogress(c) up_lowputc(c)
|
||||
#else
|
||||
# define showprogress(c)
|
||||
#endif
|
||||
@ -65,6 +66,10 @@ void __esp32c3_start(void)
|
||||
{
|
||||
uint32_t *dest;
|
||||
|
||||
/* Configure the UART so we can get debug output */
|
||||
|
||||
esp32c3_lowsetup();
|
||||
|
||||
showprogress('A');
|
||||
|
||||
/* Clear .bss. We'll do this inline (vs. calling memset) just to be
|
||||
@ -82,7 +87,5 @@ void __esp32c3_start(void)
|
||||
|
||||
nx_start();
|
||||
|
||||
/* Shouldn't get here */
|
||||
|
||||
for (; ; );
|
||||
}
|
||||
|
@ -73,6 +73,8 @@
|
||||
#define DR_REG_APB_SARADC_BASE 0x60040000
|
||||
#define DR_REG_AES_XTS_BASE 0x600CC000
|
||||
|
||||
/* Registers Operation */
|
||||
|
||||
#define REG_UHCI_BASE(i) (DR_REG_UHCI0_BASE - (i) * 0x8000)
|
||||
#define REG_UART_BASE( i ) (DR_REG_UART_BASE + (i) * 0x10000 + \
|
||||
( (i) > 1 ? 0xe000 : 0 ) )
|
||||
|
2185
arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h
Normal file
2185
arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user