mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-31 22:24:28 +00:00
uart: Support LP_UART port with UART driver on esp32c6
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/pcr_reg.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/lpperi_reg.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -79,9 +78,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
|
||||
return PCR_SDIO_SLAVE_CLK_EN;
|
||||
case PERIPH_REGDMA_MODULE:
|
||||
return PCR_REGDMA_CLK_EN;
|
||||
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
|
||||
case PERIPH_LP_I2C0_MODULE:
|
||||
return LPPERI_LP_EXT_I2C_CK_EN;
|
||||
// case PERIPH_RNG_MODULE:
|
||||
// return PCR_WIFI_CLK_RNG_EN;
|
||||
// case PERIPH_WIFI_MODULE:
|
||||
@@ -175,9 +171,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
|
||||
return PCR_SDIO_SLAVE_RST_EN;
|
||||
case PERIPH_REGDMA_MODULE:
|
||||
return PCR_REGDMA_RST_EN;
|
||||
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
|
||||
case PERIPH_LP_I2C0_MODULE:
|
||||
return LPPERI_LP_EXT_I2C_RESET_EN;
|
||||
// case PERIPH_RNG_MODULE:
|
||||
// return PCR_WIFI_CLK_RNG_EN;
|
||||
// case PERIPH_WIFI_MODULE:
|
||||
@@ -264,9 +257,6 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
|
||||
return PCR_SDIO_SLAVE_CONF_REG;
|
||||
case PERIPH_REGDMA_MODULE:
|
||||
return PCR_REGDMA_CONF_REG;
|
||||
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
|
||||
case PERIPH_LP_I2C0_MODULE:
|
||||
return LPPERI_CLK_EN_REG;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -333,9 +323,6 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
|
||||
return PCR_SDIO_SLAVE_CONF_REG;
|
||||
case PERIPH_REGDMA_MODULE:
|
||||
return PCR_REGDMA_CONF_REG;
|
||||
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
|
||||
case PERIPH_LP_I2C0_MODULE:
|
||||
return LPPERI_RESET_EN_REG;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -675,33 +674,6 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
PCR.i2c_sclk_conf.i2c_sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
#if SOC_LP_I2C_SUPPORTED
|
||||
/**
|
||||
* @brief Set LP I2C source clock
|
||||
*
|
||||
* @param hw Address offset of the LP I2C peripheral registers
|
||||
* @param src_clk Source clock for the LP I2C peripheral
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void lp_i2c_ll_set_source_clk(i2c_dev_t *hw, soc_periph_lp_i2c_clk_src_t src_clk)
|
||||
{
|
||||
(void)hw;
|
||||
// src_clk : (0) for LP_FAST_CLK (RTC Fast), (1) for XTAL_D2_CLK
|
||||
switch (src_clk) {
|
||||
case LP_I2C_SCLK_LP_FAST:
|
||||
LP_CLKRST.lpperi.lp_i2c_clk_sel = 0;
|
||||
break;
|
||||
case LP_I2C_SCLK_XTAL_D2:
|
||||
LP_CLKRST.lpperi.lp_i2c_clk_sel = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid source clock selected
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif /* SOC_LP_I2C_SUPPORTED */
|
||||
|
||||
/**
|
||||
* @brief Enable I2C peripheral controller clock
|
||||
*
|
||||
@@ -771,6 +743,7 @@ static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////Deprecated Functions//////////////////////////////////////////////////////////
|
||||
/////////////////////////////The following functions are only used by the legacy driver/////////////////////////////////
|
||||
/////////////////////////////They might be removed in the next major release (ESP-IDF 6.0)//////////////////////////////
|
||||
|
105
components/hal/esp32c6/include/hal/lp_periph_clk_ctrl_ll.h
Normal file
105
components/hal/esp32c6/include/hal/lp_periph_clk_ctrl_ll.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/lpperi_reg.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static uint32_t lp_periph_ll_get_clk_en_mask(lp_periph_module_t lp_periph)
|
||||
{
|
||||
switch (lp_periph) {
|
||||
case LP_PERIPH_I2C0_MODULE:
|
||||
return LPPERI_LP_EXT_I2C_CK_EN;
|
||||
case LP_PERIPH_UART0_MODULE:
|
||||
return LPPERI_LP_UART_CK_EN;
|
||||
default:
|
||||
// Unsupported LP peripherals
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t lp_periph_ll_get_rst_en_mask(lp_periph_module_t lp_periph)
|
||||
{
|
||||
switch (lp_periph) {
|
||||
case LP_PERIPH_I2C0_MODULE:
|
||||
return LPPERI_LP_EXT_I2C_RESET_EN;
|
||||
case LP_PERIPH_UART0_MODULE:
|
||||
return LPPERI_LP_UART_RESET_EN;
|
||||
default:
|
||||
// Unsupported LP peripherals
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_enable_clk_clear_rst(lp_periph_module_t lp_periph)
|
||||
{
|
||||
SET_PERI_REG_MASK(LPPERI_CLK_EN_REG, lp_periph_ll_get_clk_en_mask(lp_periph));
|
||||
CLEAR_PERI_REG_MASK(LPPERI_RESET_EN_REG, lp_periph_ll_get_rst_en_mask(lp_periph));
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_disable_clk_set_rst(lp_periph_module_t lp_periph)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, lp_periph_ll_get_clk_en_mask(lp_periph));
|
||||
SET_PERI_REG_MASK(LPPERI_RESET_EN_REG, lp_periph_ll_get_rst_en_mask(lp_periph));
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_reset(lp_periph_module_t lp_periph)
|
||||
{
|
||||
uint32_t bit_mask = lp_periph_ll_get_rst_en_mask(lp_periph);
|
||||
SET_PERI_REG_MASK(LPPERI_RESET_EN_REG, bit_mask);
|
||||
CLEAR_PERI_REG_MASK(LPPERI_RESET_EN_REG, bit_mask);
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_set_clk_src(lp_periph_module_t lp_periph, soc_module_clk_t clk_src)
|
||||
{
|
||||
uint32_t val;
|
||||
switch (lp_periph) {
|
||||
case LP_PERIPH_I2C0_MODULE:
|
||||
switch (clk_src) {
|
||||
case LP_I2C_SCLK_LP_FAST:
|
||||
val = 0;
|
||||
break;
|
||||
case LP_I2C_SCLK_XTAL_D2:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid LP_I2C clock source
|
||||
abort();
|
||||
}
|
||||
REG_SET_FIELD(LP_CLKRST_LPPERI_REG, LP_CLKRST_LP_I2C_CLK_SEL, val);
|
||||
break;
|
||||
case LP_PERIPH_UART0_MODULE:
|
||||
switch (clk_src) {
|
||||
case LP_UART_SCLK_LP_FAST:
|
||||
val = 0;
|
||||
break;
|
||||
case LP_UART_SCLK_XTAL_D2:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid LP_UART clock source
|
||||
abort();
|
||||
}
|
||||
REG_SET_FIELD(LP_CLKRST_LPPERI_REG, LP_CLKRST_LP_UART_CLK_SEL, val);
|
||||
break;
|
||||
default:
|
||||
// Unsupported LP peripherals
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -46,6 +46,17 @@ typedef enum {
|
||||
RTCIO_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */
|
||||
} rtcio_ll_out_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Select a RTC IOMUX function for the RTC IO
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param func Function to assign to the pin
|
||||
*/
|
||||
static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
|
||||
{
|
||||
LP_IO.gpio[rtcio_num].mcu_sel = func;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the rtcio function.
|
||||
*
|
||||
@@ -64,7 +75,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
|
||||
sel_mask |= BIT(rtcio_num);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel, sel_mask);
|
||||
//0:RTC FUNCTION 1,2,3:Reserved
|
||||
LP_IO.gpio[rtcio_num].mcu_sel = RTCIO_LL_PIN_FUNC;
|
||||
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
|
||||
} else if (func == RTCIO_FUNC_DIGITAL) {
|
||||
// Clear the bit to use digital GPIO module
|
||||
uint32_t sel_mask = HAL_FORCE_READ_U32_REG_FIELD(LP_AON.gpio_mux, gpio_mux_sel);
|
||||
|
@@ -12,9 +12,12 @@
|
||||
|
||||
#include "hal/misc.h"
|
||||
#include "hal/uart_types.h"
|
||||
#include "soc/uart_periph.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include "soc/lp_uart_reg.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -22,8 +25,11 @@ extern "C" {
|
||||
|
||||
// The default fifo depth
|
||||
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
|
||||
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
|
||||
|
||||
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
|
||||
|
||||
#define UART_LL_MIN_WAKEUP_THRESH (2)
|
||||
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
|
||||
@@ -77,6 +83,30 @@ typedef enum {
|
||||
UART_INTR_WAKEUP = (0x1 << 19),
|
||||
} uart_intr_t;
|
||||
|
||||
/****************************************** LP_UART Specific ********************************************/
|
||||
/**
|
||||
* @brief Get the LP_UART source clock.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param source_clk Current LP_UART clock source, one in soc_periph_lp_uart_clk_src_t.
|
||||
*/
|
||||
static inline void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk)
|
||||
{
|
||||
(void)hw;
|
||||
switch (LP_CLKRST.lpperi.lp_uart_clk_sel) {
|
||||
default:
|
||||
case 0:
|
||||
*source_clk = LP_UART_SCLK_LP_FAST;
|
||||
break;
|
||||
case 1:
|
||||
*source_clk = LP_UART_SCLK_XTAL_D2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// LP_UART clock control LL functions are located in lp_periph_clk_ctrl_ll.h
|
||||
|
||||
/*************************************** General LL functions ******************************************/
|
||||
/**
|
||||
* @brief Sync the update to UART core clock domain
|
||||
*
|
||||
@@ -100,7 +130,13 @@ static inline void uart_ll_update(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en)
|
||||
{
|
||||
UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en);
|
||||
if ((hw) != &LP_UART) {
|
||||
UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en);
|
||||
} else {
|
||||
// LP_UART reset shares the same register with other LP peripherals
|
||||
// Needs to be protected with a lock, therefore, it has its unique LL function, and must be called from lp_periph_ctrl.c
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +148,13 @@ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en)
|
||||
*/
|
||||
static inline void uart_ll_sclk_enable(uart_dev_t *hw)
|
||||
{
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1);
|
||||
if ((hw) != &LP_UART) {
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1);
|
||||
} else {
|
||||
// LP_UART clk_en shares the same register with other LP peripherals
|
||||
// Needs to be protected with a lock, therefore, it has its unique LL function, and must be called from lp_periph_ctrl.c
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,7 +166,13 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_sclk_disable(uart_dev_t *hw)
|
||||
{
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0);
|
||||
if ((hw) != &LP_UART) {
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0);
|
||||
} else {
|
||||
// LP_UART clk_en shares the same register with other LP peripherals
|
||||
// Needs to be protected with a lock, therefore, it has its unique LL function, and must be called from lp_periph_ctrl.c
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,19 +184,29 @@ static inline void uart_ll_sclk_disable(uart_dev_t *hw)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk)
|
||||
static inline void uart_ll_set_sclk(uart_dev_t *hw, soc_module_clk_t source_clk)
|
||||
{
|
||||
switch (source_clk) {
|
||||
default:
|
||||
if ((hw) != &LP_UART) {
|
||||
uint32_t sel_value = 0;
|
||||
switch (source_clk) {
|
||||
case UART_SCLK_PLL_F80M:
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 1);
|
||||
sel_value = 1;
|
||||
break;
|
||||
case UART_SCLK_RTC:
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 2);
|
||||
sel_value = 2;
|
||||
break;
|
||||
case UART_SCLK_XTAL:
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 3);
|
||||
sel_value = 3;
|
||||
break;
|
||||
default:
|
||||
// Invalid HP_UART clock source
|
||||
abort();
|
||||
}
|
||||
UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, sel_value);
|
||||
} else {
|
||||
// LP_UART clk_sel shares the same register with other LP peripherals
|
||||
// Needs to be protected with a lock, therefore, it has its unique LL function, and must be called from lp_periph_ctrl.c
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,9 +218,10 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk)
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
|
||||
static inline void uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *source_clk)
|
||||
{
|
||||
switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) {
|
||||
if ((hw) != &LP_UART) {
|
||||
switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) {
|
||||
default:
|
||||
case 1:
|
||||
*source_clk = UART_SCLK_PLL_F80M;
|
||||
@@ -173,6 +232,9 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk)
|
||||
case 3:
|
||||
*source_clk = UART_SCLK_XTAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
lp_uart_ll_get_sclk(hw, source_clk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +258,11 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t
|
||||
// an integer part and a fractional part.
|
||||
hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
|
||||
hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf;
|
||||
UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1);
|
||||
if ((hw) == &LP_UART) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1);
|
||||
} else {
|
||||
UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1);
|
||||
}
|
||||
#undef DIV_UP
|
||||
uart_ll_update(hw);
|
||||
}
|
||||
@@ -213,7 +279,13 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq)
|
||||
{
|
||||
typeof(hw->clkdiv_sync) div_reg;
|
||||
div_reg.val = hw->clkdiv_sync.val;
|
||||
return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1));
|
||||
int sclk_div;
|
||||
if ((hw) == &LP_UART) {
|
||||
sclk_div = HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1;
|
||||
} else {
|
||||
sclk_div = UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1;
|
||||
}
|
||||
return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * sclk_div);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -362,7 +434,7 @@ static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
{
|
||||
return hw->status.rxfifo_cnt;
|
||||
return (hw->status.rxfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -374,7 +446,9 @@ static inline uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw)
|
||||
{
|
||||
return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt;
|
||||
uint32_t total_fifo_len = ((hw) == &LP_UART) ? LP_UART_LL_FIFO_DEF_LEN : UART_LL_FIFO_DEF_LEN;
|
||||
uint32_t txfifo_len = (hw->status.txfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
return (total_fifo_len - txfifo_len);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -443,13 +517,13 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode
|
||||
* it will produce rxfifo_full_int_raw interrupt.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param full_thrhd The full threshold value of the rxfifo. `full_thrhd` should be less than `UART_LL_FIFO_DEF_LEN`.
|
||||
* @param full_thrhd The full threshold value of the rxfifo. `full_thrhd` should be less than `(LP_)UART_LL_FIFO_DEF_LEN`.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd)
|
||||
{
|
||||
hw->conf1.rxfifo_full_thrhd = full_thrhd;
|
||||
hw->conf1.rxfifo_full_thrhd = full_thrhd << UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -463,7 +537,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr
|
||||
*/
|
||||
static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd)
|
||||
{
|
||||
hw->conf1.txfifo_empty_thrhd = empty_thrhd;
|
||||
hw->conf1.txfifo_empty_thrhd = empty_thrhd << UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,7 +601,7 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_
|
||||
{
|
||||
//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set.
|
||||
if (flow_ctrl & UART_HW_FLOWCTRL_RTS) {
|
||||
hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs;
|
||||
hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs << UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
hw->hwfc_conf_sync.rx_flow_en = 1;
|
||||
} else {
|
||||
hw->hwfc_conf_sync.rx_flow_en = 0;
|
||||
@@ -573,8 +647,8 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t *
|
||||
if (sw_flow_ctrl_en) {
|
||||
hw->swfc_conf0_sync.xonoff_del = 1;
|
||||
hw->swfc_conf0_sync.sw_flow_con_en = 1;
|
||||
hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd;
|
||||
hw->swfc_conf1.xoff_threshold = flow_ctrl->xoff_thrd;
|
||||
hw->swfc_conf1.xon_threshold = (flow_ctrl->xon_thrd) << UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
hw->swfc_conf1.xoff_threshold = (flow_ctrl->xoff_thrd) << UART_LL_REG_FIELD_BIT_SHIFT(hw);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xon_char, flow_ctrl->xon_char);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char);
|
||||
} else {
|
||||
@@ -671,6 +745,10 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
|
||||
*/
|
||||
static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
{
|
||||
// This function is only for HP_UART use
|
||||
// LP_UART can only work in normal mode
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
hw->rs485_conf_sync.rs485_en = 0;
|
||||
hw->rs485_conf_sync.rs485tx_rx_en = 0;
|
||||
hw->rs485_conf_sync.rs485rxby_tx_en = 0;
|
||||
@@ -687,6 +765,10 @@ static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
{
|
||||
// This function is only for HP_UART use
|
||||
// LP_UART can only work in normal mode
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
// Application software control, remove echo
|
||||
hw->rs485_conf_sync.rs485rxby_tx_en = 1;
|
||||
hw->conf0_sync.irda_en = 0;
|
||||
@@ -707,6 +789,10 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
{
|
||||
// This function is only for HP_UART use
|
||||
// LP_UART can only work in normal mode
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
// Enable receiver, sw_rts = 1 generates low level on RTS pin
|
||||
hw->conf0_sync.sw_rts = 1;
|
||||
// Half duplex mode
|
||||
@@ -730,6 +816,10 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
{
|
||||
// This function is only for HP_UART use
|
||||
// LP_UART can only work in normal mode
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
hw->conf0_sync.irda_en = 0;
|
||||
// Enable full-duplex mode
|
||||
hw->rs485_conf_sync.rs485tx_rx_en = 1;
|
||||
@@ -751,6 +841,10 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
|
||||
{
|
||||
// This function is only for HP_UART use
|
||||
// LP_UART can only work in normal mode
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
hw->rs485_conf_sync.rs485_en = 0;
|
||||
hw->rs485_conf_sync.rs485tx_rx_en = 0;
|
||||
hw->rs485_conf_sync.rs485rxby_tx_en = 0;
|
||||
@@ -775,15 +869,19 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode)
|
||||
uart_ll_set_mode_normal(hw);
|
||||
break;
|
||||
case UART_MODE_RS485_COLLISION_DETECT:
|
||||
// Only HP_UART support this mode
|
||||
uart_ll_set_mode_collision_detect(hw);
|
||||
break;
|
||||
case UART_MODE_RS485_APP_CTRL:
|
||||
// Only HP_UART support this mode
|
||||
uart_ll_set_mode_rs485_app_ctrl(hw);
|
||||
break;
|
||||
case UART_MODE_RS485_HALF_DUPLEX:
|
||||
// Only HP_UART support this mode
|
||||
uart_ll_set_mode_rs485_half_duplex(hw);
|
||||
break;
|
||||
case UART_MODE_IRDA:
|
||||
// Only HP_UART support this mode
|
||||
uart_ll_set_mode_irda(hw);
|
||||
break;
|
||||
}
|
||||
@@ -838,7 +936,7 @@ static inline void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length_t *
|
||||
*/
|
||||
static inline bool uart_ll_is_tx_idle(uart_dev_t *hw)
|
||||
{
|
||||
return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0));
|
||||
return ((((hw->status.txfifo_cnt) >> UART_LL_REG_FIELD_BIT_SHIFT(hw)) == 0) && (hw->fsm_status.st_utx_out == 0));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -900,6 +998,9 @@ static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on)
|
||||
*/
|
||||
static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
{
|
||||
// LP_UART does not support UART_SIGNAL_IRDA_TX_INV and UART_SIGNAL_IRDA_RX_INV
|
||||
// lp_uart_dev_t has no these fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
typeof(hw->conf0_sync) conf0_reg;
|
||||
conf0_reg.val = hw->conf0_sync.val;
|
||||
conf0_reg.irda_tx_inv = (inv_mask & UART_SIGNAL_IRDA_TX_INV) ? 1 : 0;
|
||||
@@ -963,7 +1064,7 @@ static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||
{
|
||||
return UART_RX_TOUT_THRHD_V;
|
||||
return ((hw) == &LP_UART) ? LP_UART_RX_TOUT_THRHD_V : UART_RX_TOUT_THRHD_V;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -974,6 +1075,9 @@ static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable)
|
||||
{
|
||||
// LP_UART does not support autobaud
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
hw->conf0_sync.autobaud_en = enable ? 1 : 0;
|
||||
uart_ll_update(hw);
|
||||
}
|
||||
@@ -985,6 +1089,9 @@ static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw)
|
||||
{
|
||||
// LP_UART does not support this feature
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
return hw->rxd_cnt.rxd_edge_cnt;
|
||||
}
|
||||
|
||||
@@ -995,6 +1102,9 @@ static inline uint32_t uart_ll_get_rxd_edge_cnt(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw)
|
||||
{
|
||||
// LP_UART does not support this feature
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
return hw->pospulse.posedge_min_cnt;
|
||||
}
|
||||
|
||||
@@ -1005,6 +1115,9 @@ static inline uint32_t uart_ll_get_pos_pulse_cnt(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw)
|
||||
{
|
||||
// LP_UART does not support this feature
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
return hw->negpulse.negedge_min_cnt;
|
||||
}
|
||||
|
||||
@@ -1015,6 +1128,9 @@ static inline uint32_t uart_ll_get_neg_pulse_cnt(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw)
|
||||
{
|
||||
// LP_UART does not support this feature
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
return hw->highpulse.highpulse_min_cnt;
|
||||
}
|
||||
|
||||
@@ -1025,6 +1141,9 @@ static inline uint32_t uart_ll_get_high_pulse_cnt(uart_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw)
|
||||
{
|
||||
// LP_UART does not support this feature
|
||||
// lp_uart_dev_t has no following fields (reserved), but no harm since we map the LP_UART instance to the uart_dev_t struct
|
||||
|
||||
return hw->lowpulse.lowpulse_min_cnt;
|
||||
}
|
||||
|
||||
@@ -1037,9 +1156,11 @@ static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw)
|
||||
*/
|
||||
static inline void uart_ll_force_xoff(uart_port_t uart_num)
|
||||
{
|
||||
REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON);
|
||||
REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF);
|
||||
uart_ll_update(UART_LL_GET_HW(uart_num));
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart_num);
|
||||
hw->swfc_conf0_sync.force_xon = 0;
|
||||
hw->swfc_conf0_sync.sw_flow_con_en = 1;
|
||||
hw->swfc_conf0_sync.force_xoff = 1;
|
||||
uart_ll_update(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1051,10 +1172,12 @@ static inline void uart_ll_force_xoff(uart_port_t uart_num)
|
||||
*/
|
||||
static inline void uart_ll_force_xon(uart_port_t uart_num)
|
||||
{
|
||||
REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XOFF);
|
||||
REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON);
|
||||
REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XON);
|
||||
uart_ll_update(UART_LL_GET_HW(uart_num));
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart_num);
|
||||
hw->swfc_conf0_sync.force_xoff = 0;
|
||||
hw->swfc_conf0_sync.force_xon = 1;
|
||||
hw->swfc_conf0_sync.sw_flow_con_en = 0;
|
||||
hw->swfc_conf0_sync.force_xon = 0;
|
||||
uart_ll_update(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1066,7 +1189,8 @@ static inline void uart_ll_force_xon(uart_port_t uart_num)
|
||||
*/
|
||||
static inline uint32_t uart_ll_get_fsm_status(uart_port_t uart_num)
|
||||
{
|
||||
return REG_GET_FIELD(UART_FSM_STATUS_REG(uart_num), UART_ST_UTX_OUT);
|
||||
uart_dev_t *hw = UART_LL_GET_HW(uart_num);
|
||||
return hw->fsm_status.st_utx_out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user