mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(cordic): Add hal layer support for cordic
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
idf_build_get_property(target IDF_TARGET)
|
||||||
|
if(${target} STREQUAL "linux")
|
||||||
|
return() # This component is not supported by the POSIX/Linux simulator
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(includes)
|
||||||
|
|
||||||
|
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/include")
|
||||||
|
list(APPEND includes "${target}/include")
|
||||||
|
endif()
|
||||||
|
list(APPEND includes "include")
|
||||||
|
|
||||||
|
set(srcs)
|
||||||
|
|
||||||
|
# Cordic related source files
|
||||||
|
if(CONFIG_SOC_CORDIC_SUPPORTED)
|
||||||
|
list(APPEND srcs "cordic_hal.c" "${target}/cordic_periph.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
idf_component_register(SRCS ${srcs}
|
||||||
|
INCLUDE_DIRS ${includes}
|
||||||
|
REQUIRES soc hal)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# `esp_hal_cordic`
|
||||||
|
|
||||||
|
⚠️ This HAL component is still under heavy development at the moment, so we don't guarantee the stability and backward-compatibility among versions.
|
||||||
|
|
||||||
|
The `esp_hal_cordic` component provides a **Hardware Abstraction Layer** of cordic for all targets supported by ESP-IDF.
|
||||||
|
|
||||||
|
In a broad sense, the HAL layer consists of two sub-layers: HAL (upper) and Low-Level(bottom). The HAL layer defines the steps and data that is required to operate a peripheral (e.g. initialization, parameter settings). The low-level is a translation layer above the register files under the `soc` component, it only covers general conceptions to register configurations.
|
||||||
|
|
||||||
|
The functions in this file mainly provide hardware abstraction for IDF peripheral drivers. For advanced developers, the HAL layer functions can also be directly used to assist in implementing their own drivers. However, it needs to be mentioned again that the interfaces here do not guarantee stability.
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "hal/cordic_hal.h"
|
||||||
|
#include "hal/cordic_ll.h"
|
||||||
|
|
||||||
|
// Function pointer arrays for setting arguments
|
||||||
|
// Index: [format][argument_count]
|
||||||
|
// format: 0 = Q15, 1 = Q31
|
||||||
|
// argument_count: 0 = one_arg, 1 = two_args
|
||||||
|
const cordic_hal_set_argument_func_t cordic_hal_set_argument_funcs[ESP_CORDIC_IQ_SIZE_MAX][2] = {
|
||||||
|
[ESP_CORDIC_FORMAT_Q15] = {
|
||||||
|
[0] = cordic_hal_set_argument_q15_one_arg,
|
||||||
|
[1] = cordic_hal_set_argument_q15_two_args,
|
||||||
|
},
|
||||||
|
[ESP_CORDIC_FORMAT_Q31] = {
|
||||||
|
[0] = cordic_hal_set_argument_q31_one_arg,
|
||||||
|
[1] = cordic_hal_set_argument_q31_two_args,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function pointer array for getting results
|
||||||
|
// Index: [format]
|
||||||
|
// format: 0 = Q15, 1 = Q31
|
||||||
|
const cordic_hal_get_result_func_t cordic_hal_get_result_funcs[ESP_CORDIC_IQ_SIZE_MAX] = {
|
||||||
|
[ESP_CORDIC_FORMAT_Q15] = cordic_hal_get_result_q15,
|
||||||
|
[ESP_CORDIC_FORMAT_Q31] = cordic_hal_get_result_q31,
|
||||||
|
};
|
||||||
|
|
||||||
|
void cordic_hal_init(cordic_hal_context_t *hal)
|
||||||
|
{
|
||||||
|
hal->dev = CORDIC_LL_GET_HW();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cordic_hal_deinit(cordic_hal_context_t *hal)
|
||||||
|
{
|
||||||
|
hal->dev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cordic_hal_set_argument_q15_two_args(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index)
|
||||||
|
{
|
||||||
|
// Pack two 16-bit values into one 32-bit register
|
||||||
|
cordic_ll_set_calculate_argument_1(hal->dev, (uint32_t)(input_buffer->p_data_arg2[index] << 16) | input_buffer->p_data_arg1[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Q15 format with one argument
|
||||||
|
void cordic_hal_set_argument_q15_one_arg(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index)
|
||||||
|
{
|
||||||
|
cordic_ll_set_calculate_argument_1(hal->dev, input_buffer->p_data_arg1[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cordic_hal_set_argument_q31_two_args(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index)
|
||||||
|
{
|
||||||
|
// Set two separate 32-bit registers
|
||||||
|
cordic_ll_set_calculate_argument_1(hal->dev, input_buffer->p_data_arg1[index]);
|
||||||
|
cordic_ll_set_calculate_argument_2(hal->dev, input_buffer->p_data_arg2[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cordic_hal_set_argument_q31_one_arg(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index)
|
||||||
|
{
|
||||||
|
cordic_ll_set_calculate_argument_1(hal->dev, input_buffer->p_data_arg1[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cordic_hal_get_result_q15(cordic_hal_context_t *hal, cordic_output_buffer_desc_t *output_buffer, size_t index)
|
||||||
|
{
|
||||||
|
// For Q15_SIZE: extract two 16-bit values from one 32-bit register
|
||||||
|
uint32_t res = cordic_ll_get_calculate_result_1(hal->dev);
|
||||||
|
output_buffer->p_data_res1[index] = (res & 0x0000FFFF);
|
||||||
|
if (output_buffer->p_data_res2 != NULL) {
|
||||||
|
output_buffer->p_data_res2[index] = (res >> 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cordic_hal_get_result_q31(cordic_hal_context_t *hal, cordic_output_buffer_desc_t *output_buffer, size_t index)
|
||||||
|
{
|
||||||
|
// For Q31_SIZE: get two separate 32-bit results
|
||||||
|
uint32_t res = cordic_ll_get_calculate_result_1(hal->dev);
|
||||||
|
output_buffer->p_data_res1[index] = res;
|
||||||
|
if (output_buffer->p_data_res2 != NULL) {
|
||||||
|
uint32_t res2 = cordic_ll_get_calculate_result_2(hal->dev);
|
||||||
|
output_buffer->p_data_res2[index] = res2;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "hal/cordic_hal.h"
|
||||||
|
#include "hal/cordic_ll.h"
|
||||||
|
|
||||||
|
// algorithm allowable scale, format [min, max]
|
||||||
|
uint16_t cordic_hal_algorithm_allowable_scale[ESP_CORDIC_FUNC_MAX][2] = {
|
||||||
|
{0, 0},
|
||||||
|
{0, 0},
|
||||||
|
{0, 15},
|
||||||
|
{0, 15},
|
||||||
|
{0, 15},
|
||||||
|
{1, 1},
|
||||||
|
{1, 1},
|
||||||
|
{1, 1},
|
||||||
|
{1, 1},
|
||||||
|
{0, 4},
|
||||||
|
};
|
||||||
@@ -0,0 +1,301 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "hal/misc.h"
|
||||||
|
#include "hal/assert.h"
|
||||||
|
#include "soc/cordic_struct.h"
|
||||||
|
#include "hal/cordic_types.h"
|
||||||
|
#include "soc/hp_sys_clkrst_struct.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CORDIC_LL_GET_HW() (&CORDIC)
|
||||||
|
#define CORDIC_LL_PRECISION_MAX (0xF)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CORDIC operation mode
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
CORDIC_LL_MODE_REG = 0, ///< Register mode: data is transferred via registers
|
||||||
|
CORDIC_LL_MODE_DMA, ///< DMA mode: data is transferred via DMA
|
||||||
|
} cordic_ll_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the hardware clock for CORDIC module
|
||||||
|
*
|
||||||
|
* @param enable True to enable; false to disable
|
||||||
|
*/
|
||||||
|
static inline void cordic_ll_enable_bus_clock(bool enable)
|
||||||
|
{
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_apb_clk_en = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable the CORDIC module clock
|
||||||
|
*
|
||||||
|
* @param enable True to enable; false to disable
|
||||||
|
*/
|
||||||
|
static inline void cordic_ll_enable_clock(bool enable)
|
||||||
|
{
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_clk_en = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the CORDIC module
|
||||||
|
*/
|
||||||
|
static inline void cordic_ll_reset_module_register(void)
|
||||||
|
{
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_apb_rst_en = 1;
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_apb_rst_en = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the clock source for CORDIC module
|
||||||
|
*
|
||||||
|
* @param source Clock source to use (XTAL, RC_FAST, or PLL_F160M)
|
||||||
|
*/
|
||||||
|
static inline void cordic_ll_set_clock_source(cordic_clock_source_t source)
|
||||||
|
{
|
||||||
|
switch (source) {
|
||||||
|
case CORDIC_CLK_SRC_XTAL:
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_clk_src_sel = 0;
|
||||||
|
break;
|
||||||
|
case CORDIC_CLK_SRC_RC_FAST:
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_clk_src_sel = 1;
|
||||||
|
break;
|
||||||
|
case CORDIC_CLK_SRC_PLL_F160M:
|
||||||
|
HP_SYS_CLKRST.cordic_ctrl0.reg_cordic_clk_src_sel = 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false && "unsupported cordic clock source");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the calculation function type (e.g., cosine, sine, arctan)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param function Function type to calculate
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_function(cordic_dev_t *hw, cordic_func_t function)
|
||||||
|
{
|
||||||
|
switch (function) {
|
||||||
|
case ESP_CORDIC_FUNC_COS:
|
||||||
|
hw->csr_cfg.func = 0;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_SIN:
|
||||||
|
hw->csr_cfg.func = 1;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_PHASE:
|
||||||
|
hw->csr_cfg.func = 2;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_MODULUS:
|
||||||
|
hw->csr_cfg.func = 3;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_ARCTAN:
|
||||||
|
hw->csr_cfg.func = 4;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_COSH:
|
||||||
|
hw->csr_cfg.func = 5;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_SINH:
|
||||||
|
hw->csr_cfg.func = 6;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_ARCHTANH:
|
||||||
|
hw->csr_cfg.func = 7;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_LOGE:
|
||||||
|
hw->csr_cfg.func = 8;
|
||||||
|
break;
|
||||||
|
case ESP_CORDIC_FUNC_SQUARE_ROOT:
|
||||||
|
hw->csr_cfg.func = 9;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the calculation mode (register mode or DMA mode)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param mode Operation mode (REG_MODE or DMA_MODE)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_mode(cordic_dev_t *hw, cordic_ll_mode_t mode)
|
||||||
|
{
|
||||||
|
if (mode == CORDIC_LL_MODE_REG) {
|
||||||
|
hw->csr_cfg.work_mode = 0;
|
||||||
|
} else if (mode == CORDIC_LL_MODE_DMA) {
|
||||||
|
hw->csr_cfg.work_mode = 1;
|
||||||
|
} else {
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the calculation precision (iteration count)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param precision Precision value (number of iterations)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_precision(cordic_dev_t *hw, uint16_t precision)
|
||||||
|
{
|
||||||
|
hw->csr_cfg.press = precision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the input data scale factor
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param scale Scale factor for input data (range depends on function type)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_scale(cordic_dev_t *hw, uint16_t scale)
|
||||||
|
{
|
||||||
|
hw->csr_cfg.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the number of result outputs (one or two)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param number Number of result outputs (ONE_NUM or TWO_NUM)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_result_number(cordic_dev_t *hw, uint8_t number)
|
||||||
|
{
|
||||||
|
hw->csr_cfg.res_num = number - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the number of input arguments (one or two)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param number Number of input arguments (ONE_NUM or TWO_NUM)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_argument_number(cordic_dev_t *hw, uint8_t number)
|
||||||
|
{
|
||||||
|
hw->csr_cfg.arg_num = number - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the result data format size (Q15 or Q31)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param size Result data format (Q15_SIZE or Q31_SIZE)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_result_format(cordic_dev_t *hw, cordic_iq_format_t format)
|
||||||
|
{
|
||||||
|
if (format == ESP_CORDIC_FORMAT_Q15) {
|
||||||
|
hw->csr_cfg.res_size = 0;
|
||||||
|
} else {
|
||||||
|
hw->csr_cfg.res_size = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the argument data format size (Q15 or Q31)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param size Argument data format (Q15_SIZE or Q31_SIZE)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_argument_format(cordic_dev_t *hw, cordic_iq_format_t format)
|
||||||
|
{
|
||||||
|
if (format == ESP_CORDIC_FORMAT_Q15) {
|
||||||
|
hw->csr_cfg.arg_size = 0;
|
||||||
|
} else {
|
||||||
|
hw->csr_cfg.arg_size = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the first input argument value
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param arg First argument value in fixed-point format
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_argument_1(cordic_dev_t *hw, uint32_t arg)
|
||||||
|
{
|
||||||
|
hw->arg1.arg1_data = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the second input argument value (for two-argument functions)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @param arg Second argument value in fixed-point format
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_set_calculate_argument_2(cordic_dev_t *hw, uint32_t arg)
|
||||||
|
{
|
||||||
|
hw->arg2.arg2_data = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Start the CORDIC calculation
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline void cordic_ll_start_calculate(cordic_dev_t *hw)
|
||||||
|
{
|
||||||
|
hw->csr_cfg.update_flag = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the first calculation result
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @return First result value in fixed-point format
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t cordic_ll_get_calculate_result_1(cordic_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->res1.res1_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the second calculation result (for functions with two outputs)
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @return Second result value in fixed-point format
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline uint32_t cordic_ll_get_calculate_result_2(cordic_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->res2.res2_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the calculation result is ready
|
||||||
|
*
|
||||||
|
* @param hw Pointer to the CORDIC hardware register structure
|
||||||
|
* @return True if result is ready, false otherwise
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline))
|
||||||
|
static inline bool cordic_ll_is_calculate_result_ready(cordic_dev_t *hw)
|
||||||
|
{
|
||||||
|
return hw->csr_cfg.res_rdy_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "hal/cordic_types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct cordic_dev_t *cordic_soc_handle_t; // cordic SOC layer handle
|
||||||
|
|
||||||
|
// Forward declaration for function pointer types
|
||||||
|
typedef struct cordic_hal_context_t cordic_hal_context_t;
|
||||||
|
|
||||||
|
// Function pointer type for setting CORDIC arguments
|
||||||
|
typedef void (*cordic_hal_set_argument_func_t)(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index);
|
||||||
|
|
||||||
|
// Function pointer type for getting CORDIC results
|
||||||
|
typedef void (*cordic_hal_get_result_func_t)(cordic_hal_context_t *hal, cordic_output_buffer_desc_t *output_buffer, size_t index);
|
||||||
|
|
||||||
|
// Function pointer arrays for setting arguments
|
||||||
|
extern const cordic_hal_set_argument_func_t cordic_hal_set_argument_funcs[ESP_CORDIC_IQ_SIZE_MAX][2];
|
||||||
|
extern const cordic_hal_get_result_func_t cordic_hal_get_result_funcs[ESP_CORDIC_IQ_SIZE_MAX];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context that should be maintained by both the driver and the HAL
|
||||||
|
*/
|
||||||
|
typedef struct cordic_hal_context_t {
|
||||||
|
cordic_soc_handle_t dev; // cordic SOC layer handle (i.e. register base address)
|
||||||
|
} cordic_hal_context_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the cordic codec HAL driver
|
||||||
|
*
|
||||||
|
* @param hal: cordic codec HAL context
|
||||||
|
*/
|
||||||
|
void cordic_hal_init(cordic_hal_context_t *hal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Deinitialize the cordic codec HAL driver
|
||||||
|
*
|
||||||
|
* @param hal: cordic codec HAL context
|
||||||
|
*/
|
||||||
|
void cordic_hal_deinit(cordic_hal_context_t *hal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CORDIC arguments for Q15 format with two arguments (PHASE_FUNC, MODULUS_FUNC)
|
||||||
|
*
|
||||||
|
* @param hal: cordic HAL context
|
||||||
|
* @param input_buffer: input buffer descriptor (HAL layer type)
|
||||||
|
* @param index: data index
|
||||||
|
*/
|
||||||
|
void cordic_hal_set_argument_q15_two_args(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CORDIC arguments for Q15 format with one argument
|
||||||
|
*
|
||||||
|
* @param hal: cordic HAL context
|
||||||
|
* @param input_buffer: input buffer descriptor (HAL layer type)
|
||||||
|
* @param index: data index
|
||||||
|
*/
|
||||||
|
void cordic_hal_set_argument_q15_one_arg(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CORDIC arguments for Q31 format with two arguments (PHASE_FUNC, MODULUS_FUNC)
|
||||||
|
*
|
||||||
|
* @param hal: cordic HAL context
|
||||||
|
* @param input_buffer: input buffer descriptor (HAL layer type)
|
||||||
|
* @param index: data index
|
||||||
|
*/
|
||||||
|
void cordic_hal_set_argument_q31_two_args(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set CORDIC arguments for Q31 format with one argument
|
||||||
|
*
|
||||||
|
* @param hal: cordic HAL context
|
||||||
|
* @param input_buffer: input buffer descriptor (HAL layer type)
|
||||||
|
* @param index: data index
|
||||||
|
*/
|
||||||
|
void cordic_hal_set_argument_q31_one_arg(cordic_hal_context_t *hal, const cordic_input_buffer_desc_t *input_buffer, size_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CORDIC results for Q15 format
|
||||||
|
*
|
||||||
|
* @param hal: cordic HAL context
|
||||||
|
* @param output_buffer: output buffer descriptor (HAL layer type)
|
||||||
|
* @param index: data index
|
||||||
|
*/
|
||||||
|
void cordic_hal_get_result_q15(cordic_hal_context_t *hal, cordic_output_buffer_desc_t *output_buffer, size_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get CORDIC results for Q31 format
|
||||||
|
*
|
||||||
|
* @param hal: cordic HAL context
|
||||||
|
* @param output_buffer: output buffer descriptor (HAL layer type)
|
||||||
|
* @param index: data index
|
||||||
|
*/
|
||||||
|
void cordic_hal_get_result_q31(cordic_hal_context_t *hal, cordic_output_buffer_desc_t *output_buffer, size_t index);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "hal/cordic_types.h"
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_CORDIC_SUPPORTED
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Algorithm allowable scale, format [min, max]
|
||||||
|
*
|
||||||
|
* @param 1: function type
|
||||||
|
* @param 2: [min, max] scale
|
||||||
|
*/
|
||||||
|
extern uint16_t cordic_hal_algorithm_allowable_scale[ESP_CORDIC_FUNC_MAX][2];
|
||||||
|
|
||||||
|
#endif // SOC_CORDIC_SUPPORTED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "soc/soc_caps.h"
|
||||||
|
#include "soc/clk_tree_defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_CORDIC_SUPPORTED
|
||||||
|
/**
|
||||||
|
* @brief CORDIC group clock source
|
||||||
|
*/
|
||||||
|
typedef soc_periph_cordic_clk_src_t cordic_clock_source_t;
|
||||||
|
#else
|
||||||
|
/**
|
||||||
|
* @brief default type
|
||||||
|
*/
|
||||||
|
typedef int cordic_clock_source_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input buffer descriptor for CORDIC operations
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t *p_data_arg1; /*!< Pointer to input data argument 1 buffer */
|
||||||
|
uint32_t *p_data_arg2; /*!< Pointer to input data argument 2 buffer (can be NULL for single argument functions) */
|
||||||
|
} cordic_input_buffer_desc_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Output buffer descriptor for CORDIC operations
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t *p_data_res1; /*!< Pointer to output result 1 buffer */
|
||||||
|
uint32_t *p_data_res2; /*!< Pointer to output result 2 buffer (can be NULL for single result) */
|
||||||
|
} cordic_output_buffer_desc_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CORDIC calculation function type
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_CORDIC_FUNC_COS = 0, ///< Cosine function (can have both cos, sin results)
|
||||||
|
ESP_CORDIC_FUNC_SIN, ///< Sine function (can have both sin, cos results)
|
||||||
|
ESP_CORDIC_FUNC_PHASE, ///< Phase function (requires two arguments) (can have both phase, modulus results)
|
||||||
|
ESP_CORDIC_FUNC_MODULUS, ///< Modulus function (requires two arguments) (can have both phase, modulus results)
|
||||||
|
ESP_CORDIC_FUNC_ARCTAN, ///< Arctangent function
|
||||||
|
ESP_CORDIC_FUNC_COSH, ///< Hyperbolic cosine function (can have both cosh, sinh results)
|
||||||
|
ESP_CORDIC_FUNC_SINH, ///< Hyperbolic sine function (can have both sinh, cosh results)
|
||||||
|
ESP_CORDIC_FUNC_ARCHTANH, ///< Hyperbolic arctangent function
|
||||||
|
ESP_CORDIC_FUNC_LOGE, ///< Natural logarithm function
|
||||||
|
ESP_CORDIC_FUNC_SQUARE_ROOT, ///< Square root function
|
||||||
|
ESP_CORDIC_FUNC_MAX, ///< Maximum function type (for boundary checking)
|
||||||
|
} cordic_func_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CORDIC data format size
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_CORDIC_FORMAT_Q15 = 0, ///< Q15 format: 16-bit fixed-point (range: -1.0 to 1.0)
|
||||||
|
ESP_CORDIC_FORMAT_Q31 = 1, ///< Q31 format: 32-bit fixed-point (range: -1.0 to 1.0)
|
||||||
|
ESP_CORDIC_IQ_SIZE_MAX, ///< Maximum size type (for boundary checking)
|
||||||
|
} cordic_iq_format_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -71,6 +71,10 @@ config SOC_SPI_FLASH_SUPPORTED
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_CORDIC_SUPPORTED
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_XTAL_SUPPORT_40M
|
config SOC_XTAL_SUPPORT_40M
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|||||||
@@ -358,6 +358,20 @@ typedef enum {
|
|||||||
CLK_CAL_LP_PLL, /*!< Select to calculate frequency of LP_PLL_CLK */
|
CLK_CAL_LP_PLL, /*!< Select to calculate frequency of LP_PLL_CLK */
|
||||||
} soc_clk_freq_calculation_src_t;
|
} soc_clk_freq_calculation_src_t;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////CORDIC///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array initializer for all supported clock sources of CORDIC
|
||||||
|
*/
|
||||||
|
#define SOC_CORDIC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F160M}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CORDIC_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,
|
||||||
|
CORDIC_CLK_SRC_PLL_F160M = SOC_MOD_CLK_PLL_F160M,
|
||||||
|
CORDIC_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,
|
||||||
|
CORDIC_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M,
|
||||||
|
} soc_periph_cordic_clk_src_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -96,6 +96,7 @@
|
|||||||
// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14648
|
// #define SOC_PM_SUPPORTED 1 // TODO: [ESP32S31] IDF-14648
|
||||||
// #define SOC_BITSCRAMBLER_SUPPORTED 1 // TODO: [ESP32S31] IDF-14714
|
// #define SOC_BITSCRAMBLER_SUPPORTED 1 // TODO: [ESP32S31] IDF-14714
|
||||||
// #define SOC_SIMD_INSTRUCTION_SUPPORTED 1 // TODO: [ESP32S31] IDF-14661
|
// #define SOC_SIMD_INSTRUCTION_SUPPORTED 1 // TODO: [ESP32S31] IDF-14661
|
||||||
|
#define SOC_CORDIC_SUPPORTED 1
|
||||||
|
|
||||||
/*-------------------------- XTAL CAPS ---------------------------------------*/
|
/*-------------------------- XTAL CAPS ---------------------------------------*/
|
||||||
#define SOC_XTAL_SUPPORT_40M 1
|
#define SOC_XTAL_SUPPORT_40M 1
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ typedef union {
|
|||||||
} cordic_version_reg_t;
|
} cordic_version_reg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct cordic_dev_t {
|
||||||
volatile cordic_csr_cfg_reg_t csr_cfg;
|
volatile cordic_csr_cfg_reg_t csr_cfg;
|
||||||
volatile cordic_arg1_reg_t arg1;
|
volatile cordic_arg1_reg_t arg1;
|
||||||
volatile cordic_arg2_reg_t arg2;
|
volatile cordic_arg2_reg_t arg2;
|
||||||
@@ -319,6 +319,7 @@ typedef struct {
|
|||||||
volatile cordic_version_reg_t version;
|
volatile cordic_version_reg_t version;
|
||||||
} cordic_dev_t;
|
} cordic_dev_t;
|
||||||
|
|
||||||
|
extern cordic_dev_t CORDIC;
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
_Static_assert(sizeof(cordic_dev_t) == 0x44, "Invalid size of cordic_dev_t structure");
|
_Static_assert(sizeof(cordic_dev_t) == 0x44, "Invalid size of cordic_dev_t structure");
|
||||||
|
|||||||
Reference in New Issue
Block a user