diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 667d0d9f2d..6a0a8ecc7c 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -85,6 +85,7 @@ /components/efuse/ @esp-idf-codeowners/system /components/esp_adc/ @esp-idf-codeowners/peripherals /components/esp_app_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities +/components/esp_asrc_adapter/ @esp-idf-codeowners/peripherals /components/esp_blockdev/ @esp-idf-codeowners/storage /components/esp_bootloader_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities /components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154 diff --git a/components/esp_asrc_adapter/CMakeLists.txt b/components/esp_asrc_adapter/CMakeLists.txt new file mode 100644 index 0000000000..742304d8af --- /dev/null +++ b/components/esp_asrc_adapter/CMakeLists.txt @@ -0,0 +1,15 @@ +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 "include") +set(srcs) +# ASRC related source files +if(CONFIG_SOC_ASRC_SUPPORTED) + list(APPEND srcs "asrc_adapter.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${includes} + REQUIRES esp_hal_asrc esp_driver_dma esp_mm) diff --git a/components/esp_asrc_adapter/asrc_adapter.c b/components/esp_asrc_adapter/asrc_adapter.c new file mode 100644 index 0000000000..af6a2ec3d2 --- /dev/null +++ b/components/esp_asrc_adapter/asrc_adapter.c @@ -0,0 +1,215 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "esp_private/gdma.h" +#include "esp_private/gdma_link.h" +#include "soc/ahb_dma_struct.h" +#include "hal/dma_types.h" +#include "esp_check.h" +#include "esp_err.h" +#include "esp_cache.h" +#include "esp_memory_utils.h" +#include "esp_private/esp_cache_private.h" +#include "asrc_adapter.h" + +#define TAG "ASRC_ADAPTER" +#define ASRC_HW_GDMA_DESC_BUFFER_MAX_SIZE DMA_DESCRIPTOR_BUFFER_MAX_SIZE_16B_ALIGNED + +static bool IRAM_ATTR asrc_hw_rx_eof(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data) +{ + portBASE_TYPE higher_priority_task_awoken = pdFALSE; + asrc_hw_gdma_evt_t asrc_evt = {.gdma_evt = ASRC_HW_GDMA_RECV_FRAME_DONE}; + xQueueSendFromISR(user_data, &asrc_evt, &higher_priority_task_awoken); + return higher_priority_task_awoken; +} + +esp_err_t asrc_hw_gdma_create_channel(int asrc_idx, void *user_data, uint16_t max_data_burst_size, + asrc_hw_gdma_channel_handle_t *dma_tx_chan, asrc_hw_gdma_channel_handle_t *dma_rx_chan) +{ + ESP_RETURN_ON_FALSE(dma_tx_chan, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + ESP_RETURN_ON_FALSE(dma_rx_chan, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + esp_err_t ret = ESP_OK; + gdma_trigger_t trig = {0}; + trig.instance_id = asrc_idx == 0 ? SOC_GDMA_TRIG_PERIPH_ASRC0 : SOC_GDMA_TRIG_PERIPH_ASRC1; + trig.bus_id = asrc_idx == 0 ? SOC_GDMA_TRIG_PERIPH_ASRC0_BUS : SOC_GDMA_TRIG_PERIPH_ASRC1_BUS; + gdma_channel_alloc_config_t dma_cfg = {0}; + gdma_channel_handle_t dma_tx = NULL; + gdma_channel_handle_t dma_rx = NULL; + bool tx_connected = false; + bool rx_connected = false; + ret = gdma_new_ahb_channel(&dma_cfg, &dma_tx, &dma_rx); + ESP_RETURN_ON_ERROR(ret, TAG, "Fail to new gdma channel"); + + ESP_GOTO_ON_ERROR(gdma_connect(dma_tx, trig), cleanup, TAG, "Fail to connect tx channel"); + tx_connected = true; + ESP_GOTO_ON_ERROR(gdma_connect(dma_rx, trig), cleanup, TAG, "Fail to connect rx channel"); + rx_connected = true; + gdma_strategy_config_t strategy_config = { + .auto_update_desc = false, + .owner_check = true, + .eof_till_data_popped = true, + }; + ESP_GOTO_ON_ERROR(gdma_apply_strategy(dma_tx, &strategy_config), cleanup, TAG, "Fail to apply tx strategy"); + ESP_GOTO_ON_ERROR(gdma_apply_strategy(dma_rx, &strategy_config), cleanup, TAG, "Fail to apply rx strategy"); + gdma_transfer_config_t transfer_config = { + .max_data_burst_size = max_data_burst_size, + .access_ext_mem = true, + }; + ESP_GOTO_ON_ERROR(gdma_config_transfer(dma_rx, &transfer_config), cleanup, TAG, "Fail to config rx transfer"); + ESP_GOTO_ON_ERROR(gdma_config_transfer(dma_tx, &transfer_config), cleanup, TAG, "Fail to config tx transfer"); + gdma_rx_event_callbacks_t cb = {.on_recv_eof = asrc_hw_rx_eof}; + ESP_GOTO_ON_ERROR(gdma_register_rx_event_callbacks(dma_rx, &cb, user_data), cleanup, TAG, "Fail to register rx event callbacks"); + *dma_tx_chan = dma_tx; + *dma_rx_chan = dma_rx; + return ESP_OK; +cleanup: + if (tx_connected) { + gdma_disconnect(dma_tx); + } + if (rx_connected) { + gdma_disconnect(dma_rx); + } + if (dma_tx != NULL) { + gdma_del_channel(dma_tx); + } + if (dma_rx != NULL) { + gdma_del_channel(dma_rx); + } + *dma_tx_chan = NULL; + *dma_rx_chan = NULL; + return ret; +} + +esp_err_t asrc_hw_gdma_create_link_list(uint32_t byte_cnt, asrc_hw_gdma_link_list_handle_t *list_hd, uint32_t *max_desc_num) +{ + ESP_RETURN_ON_FALSE(list_hd, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + ESP_RETURN_ON_FALSE(max_desc_num, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + esp_err_t ret = ESP_OK; + int32_t desc_num = byte_cnt / ASRC_HW_GDMA_DESC_BUFFER_MAX_SIZE; + if (byte_cnt % ASRC_HW_GDMA_DESC_BUFFER_MAX_SIZE != 0) { + desc_num++; + } + gdma_link_list_handle_t list = (gdma_link_list_handle_t)(*list_hd); + *list_hd = NULL; + if (desc_num > *max_desc_num) { + if (list != NULL) { + gdma_del_link_list(list); + list = NULL; + } + gdma_link_list_config_t config = { + .num_items = desc_num, + }; + ret = gdma_new_link_list(&config, &list); + ESP_RETURN_ON_ERROR(ret, TAG, "Fail to new link list"); + *max_desc_num = desc_num; + } + *list_hd = list; + return ESP_OK; +} + +esp_err_t asrc_hw_gdma_mount_link_list(asrc_hw_gdma_link_list_handle_t list_hd, uint32_t desc_num, uint8_t *buf, uint32_t byte_cnt) +{ + ESP_RETURN_ON_FALSE(buf, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + ESP_RETURN_ON_FALSE(list_hd, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + esp_err_t ret = ESP_OK; + uint32_t remaining_byte_cnt = byte_cnt; + gdma_buffer_mount_config_t mount_config[desc_num] = {}; + for (int i = 0; i < desc_num; i++) { + mount_config[i].buffer = buf; + mount_config[i].flags.bypass_buffer_align_check = true; + if ((i + 1) != desc_num) { + mount_config[i].length = ASRC_HW_GDMA_DESC_BUFFER_MAX_SIZE; + mount_config[i].flags.mark_eof = 0; + mount_config[i].flags.mark_final = GDMA_FINAL_LINK_TO_DEFAULT; + remaining_byte_cnt -= ASRC_HW_GDMA_DESC_BUFFER_MAX_SIZE; + } else { + mount_config[i].length = remaining_byte_cnt; + mount_config[i].flags.mark_eof = 1; + mount_config[i].flags.mark_final = GDMA_FINAL_LINK_TO_NULL; + } + buf += ASRC_HW_GDMA_DESC_BUFFER_MAX_SIZE; + } + ret = gdma_link_mount_buffers((gdma_link_list_handle_t)list_hd, 0, mount_config, desc_num, NULL); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Fail to mount link list, ret: %d", ret); + return ret; + } + return ESP_OK; +} + +esp_err_t asrc_hw_gdma_start_channel(asrc_hw_gdma_channel_handle_t dma_chan, asrc_hw_gdma_link_list_handle_t desc) +{ + ESP_RETURN_ON_FALSE(dma_chan, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + ESP_RETURN_ON_FALSE(desc, ESP_ERR_INVALID_ARG, TAG, "NULL pointer"); + gdma_channel_handle_t dma_chan_handle = (gdma_channel_handle_t)dma_chan; + gdma_reset(dma_chan_handle); + gdma_start(dma_chan_handle, gdma_link_get_head_addr((gdma_link_list_handle_t)desc)); + return ESP_OK; +} + +void asrc_hw_gdma_free_link_list(asrc_hw_gdma_link_list_handle_t list_hd) +{ + if (list_hd != NULL) { + gdma_del_link_list((gdma_link_list_handle_t)list_hd); + } +} + +void asrc_hw_gdma_destroy_channel(asrc_hw_gdma_channel_handle_t dma_tx_chan, asrc_hw_gdma_channel_handle_t dma_rx_chan) +{ + if (dma_tx_chan != NULL) { + gdma_channel_handle_t dma_tx_chan_handle = (gdma_channel_handle_t)dma_tx_chan; + gdma_disconnect(dma_tx_chan_handle); + gdma_del_channel(dma_tx_chan_handle); + } + if (dma_rx_chan != NULL) { + gdma_channel_handle_t dma_rx_chan_handle = (gdma_channel_handle_t)dma_rx_chan; + gdma_disconnect(dma_rx_chan_handle); + gdma_del_channel(dma_rx_chan_handle); + } +} + +esp_err_t asrc_hw_get_buffer_alignment(uint32_t heap_caps, size_t *out_alignment) +{ + return esp_cache_get_alignment(heap_caps, out_alignment); +} + +esp_err_t asrc_hw_check_buffer_alignment(uint8_t *buffer, uint32_t buffer_size) +{ + if (esp_ptr_external_ram(buffer) == true) { + size_t cache_line_size = 0; + esp_cache_get_alignment(MALLOC_CAP_SPIRAM, &cache_line_size); + bool aligned_addr = (((uint32_t)buffer % cache_line_size) == 0) && ((buffer_size % cache_line_size) == 0); + if (!aligned_addr) { + ESP_LOGE(TAG, "The buffer address(%p) or the buffer size(%ld) is(are) not aligned with cache line size (%ld)", + buffer, buffer_size, cache_line_size); + ESP_LOGE(TAG, "Please use esp_asrc_alloc_mem to malloc your buffer"); + return ESP_ERR_INVALID_ARG; + } + } + return ESP_OK; +} + +esp_err_t asrc_hw_cache_msync_c2m(uint8_t *buffer, uint32_t buffer_size) +{ + if (esp_ptr_external_ram(buffer) == true) { + esp_err_t ret = esp_cache_msync(buffer, buffer_size, + ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED); + ESP_RETURN_ON_ERROR(ret, TAG, "Inbuf cache sync failed"); + } + return ESP_OK; +} + +esp_err_t asrc_hw_cache_msync_m2c(uint8_t *buffer, uint32_t buffer_size) +{ + if (esp_ptr_external_ram(buffer) == true) { + esp_err_t ret = esp_cache_msync(buffer, buffer_size, ESP_CACHE_MSYNC_FLAG_DIR_M2C); + ESP_RETURN_ON_ERROR(ret, TAG, "Outbuf cache sync failed"); + } + return ESP_OK; +} diff --git a/components/esp_asrc_adapter/include/asrc_adapter.h b/components/esp_asrc_adapter/include/asrc_adapter.h new file mode 100644 index 0000000000..329d059786 --- /dev/null +++ b/components/esp_asrc_adapter/include/asrc_adapter.h @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief GDMA channel handle type for ASRC hardware + */ +typedef void *asrc_hw_gdma_channel_handle_t; + +/** + * @brief GDMA descriptor link list handle type for ASRC hardware + */ +typedef void *asrc_hw_gdma_link_list_handle_t; + +/** + * @brief GDMA event type + */ +typedef enum { + ASRC_HW_GDMA_RECV_FRAME_DONE = (1 << 0), /*!< GDMA receive frame done event */ +} asrc_hw_gdma_evt_enum_t; + +/** + * @brief GDMA event structure + */ +typedef struct { + asrc_hw_gdma_evt_enum_t gdma_evt; /*!< GDMA event from interrupt */ +} asrc_hw_gdma_evt_t; + +/** + * @brief Create GDMA channels for ASRC hardware + * + * @param[in] asrc_idx ASRC hardware index + * @param[in] user_data User context passed to GDMA callbacks + * @param[in] max_data_burst_size Maximum data burst size + * @param[out] dma_tx_chan Returned GDMA TX channel handle + * @param[out] dma_rx_chan Returned GDMA RX channel handle + * + * @return + * - ESP_OK Create successful + * - Others Create failed + */ +esp_err_t asrc_hw_gdma_create_channel(int asrc_idx, void *user_data, uint16_t max_data_burst_size, + asrc_hw_gdma_channel_handle_t *dma_tx_chan, asrc_hw_gdma_channel_handle_t *dma_rx_chan); + +/** + * @brief Create or recreate GDMA descriptor link list if needed + * + * @param[in] byte_cnt Total transfer size in bytes + * @param[inout] list_hd Pointer to descriptor list handle (will be updated if new list is created) + * @param[inout] max_desc_num Pointer to maximum descriptor number (will be updated if new list is created) + * + * @return + * - ESP_OK Create successful + * - Others Create failed + */ +esp_err_t asrc_hw_gdma_create_link_list(uint32_t byte_cnt, asrc_hw_gdma_link_list_handle_t *list_hd, uint32_t *max_desc_num); + +/** + * @brief Mount buffers to GDMA descriptor link list + * + * @param[in] list_hd Descriptor list handle (must be created by asrc_hw_gdma_create_link_list) + * @param[in] desc_num Number of descriptors to mount + * @param[in] buf Pointer to DMA buffer + * @param[in] byte_cnt Total transfer size in bytes + * + * @return + * - ESP_OK Mount successful + * - Others Mount failed + */ +esp_err_t asrc_hw_gdma_mount_link_list(asrc_hw_gdma_link_list_handle_t list_hd, uint32_t desc_num, uint8_t *buf, uint32_t byte_cnt); + +/** + * @brief Start GDMA channel for ASRC hardware + * + * @param[in] dma_chan GDMA channel handle + * @param[in] desc GDMA descriptor link list handle + * + * @return + * - ESP_OK Start successful + * - Others Start failed + */ +esp_err_t asrc_hw_gdma_start_channel(asrc_hw_gdma_channel_handle_t dma_chan, asrc_hw_gdma_link_list_handle_t desc); + +/** + * @brief Free GDMA descriptor link list + * + * @param[in] list_hd Descriptor list handle to free + */ +void asrc_hw_gdma_free_link_list(asrc_hw_gdma_link_list_handle_t list_hd); + +/** + * @brief Deinitialize GDMA channels for ASRC hardware + * + * @param[in] dma_tx_chan GDMA TX channel handle + * @param[in] dma_rx_chan GDMA RX channel handle + */ +void asrc_hw_gdma_destroy_channel(asrc_hw_gdma_channel_handle_t dma_tx_chan, asrc_hw_gdma_channel_handle_t dma_rx_chan); + +/** + * @brief Get buffer alignment for a given heap capability + * + * @param[in] heap_caps Heap capability to check + * @param[out] out_alignment Returned buffer alignment + * + * @return + * - ESP_OK Alignment retrieval successful + * - Others Alignment retrieval failed + */ +esp_err_t asrc_hw_get_buffer_alignment(uint32_t heap_caps, size_t *out_alignment); + +/** + * @brief Check if buffer alignment is valid for ASRC hardware + * + * @param[in] buffer Pointer to buffer to check + * @param[in] buffer_size Buffer size in bytes + * + * @return + * - ESP_OK Buffer alignment is valid + * - Others Buffer alignment is invalid + */ +esp_err_t asrc_hw_check_buffer_alignment(uint8_t *buffer, uint32_t buffer_size); + +/** + * @brief Cache sync from CPU to memory + * + * @param[in] buffer Pointer to buffer to sync + * @param[in] buffer_size Buffer size in bytes + * + * @return + * - ESP_OK Cache sync successful + * - Others Cache sync failed + */ +esp_err_t asrc_hw_cache_msync_c2m(uint8_t *buffer, uint32_t buffer_size); + +/** + * @brief Cache sync from memory to CPU + * + * @param[in] buffer Pointer to buffer to sync + * @param[in] buffer_size Buffer size in bytes + * + * @return + * - ESP_OK Cache sync successful + * - Others Cache sync failed + */ +esp_err_t asrc_hw_cache_msync_m2c(uint8_t *buffer, uint32_t buffer_size); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/components/esp_hal_asrc/CMakeLists.txt b/components/esp_hal_asrc/CMakeLists.txt new file mode 100644 index 0000000000..292058a189 --- /dev/null +++ b/components/esp_hal_asrc/CMakeLists.txt @@ -0,0 +1,23 @@ +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) + +# ASRC related source files +if(CONFIG_SOC_ASRC_SUPPORTED) + list(APPEND srcs "${target}/asrc_periph.c" + "${target}/asrc_hal.c") +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${includes} + REQUIRES soc hal) diff --git a/components/esp_hal_asrc/esp32h4/asrc_hal.c b/components/esp_hal_asrc/esp32h4/asrc_hal.c new file mode 100644 index 0000000000..d3b9cb2163 --- /dev/null +++ b/components/esp_hal_asrc/esp32h4/asrc_hal.c @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "hal/asrc_ll.h" +#include "hal/asrc_hal.h" + +void asrc_hal_init(asrc_hal_context_t *hal) +{ + hal->dev = ASRC_LL_GET_HW(); +} + +void asrc_hal_enable_asrc_module(asrc_hal_context_t *hal, bool enable) +{ + asrc_ll_enable_asrc_module(enable); +} + +void asrc_hal_init_stream(asrc_hal_context_t *hal, asrc_hal_config_t *asrc_cfg, uint8_t asrc_idx) +{ + asrc_ll_stop_stream(hal->dev, asrc_idx); + asrc_ll_reset_stream(hal->dev, asrc_idx); + asrc_ll_reset_input_fifo(hal->dev, asrc_idx); + asrc_ll_reset_output_fifo(hal->dev, asrc_idx); + asrc_ll_set_channel_mode(hal->dev, asrc_idx, asrc_cfg->src_info.channel, + asrc_cfg->dest_info.channel, asrc_cfg->weight, asrc_cfg->weight_len); + asrc_ll_set_rate_reg(hal->dev, asrc_idx, asrc_cfg->src_info.sample_rate, asrc_cfg->dest_info.sample_rate); + asrc_ll_clear_incnt_counter(hal->dev, asrc_idx); + asrc_ll_clear_outcnt_counter(hal->dev, asrc_idx); + asrc_ll_enable_outcnt_counter(hal->dev, asrc_idx); + asrc_ll_set_eof_mode(hal->dev, asrc_idx, 0); + asrc_ll_enable_outsample_comp(hal->dev, asrc_idx); +} + +void asrc_hal_deinit_stream(asrc_hal_context_t *hal, uint8_t asrc_idx) +{ + asrc_ll_stop_stream(hal->dev, asrc_idx); + asrc_ll_reset_stream(hal->dev, asrc_idx); + asrc_ll_reset_input_fifo(hal->dev, asrc_idx); + asrc_ll_reset_output_fifo(hal->dev, asrc_idx); + asrc_ll_clear_incnt_counter(hal->dev, asrc_idx); + asrc_ll_clear_outcnt_counter(hal->dev, asrc_idx); +} + +void asrc_hal_set_in_bytes_num(asrc_hal_context_t *hal, uint8_t asrc_idx, uint32_t in_bytes_num) +{ + asrc_ll_set_in_bytes_num(hal->dev, asrc_idx, in_bytes_num); +} + +void asrc_hal_set_out_bytes_num(asrc_hal_context_t *hal, uint8_t asrc_idx, uint32_t out_bytes_num) +{ + asrc_ll_set_out_bytes_num(hal->dev, asrc_idx, out_bytes_num); +} + +void asrc_hal_start(asrc_hal_context_t *hal, uint8_t asrc_idx) +{ + asrc_ll_start_stream(hal->dev, asrc_idx); +} + +uint32_t asrc_hal_get_out_data_bytes(asrc_hal_context_t *hal, uint8_t asrc_idx) +{ + return asrc_ll_get_outbytes_cnt(hal->dev, asrc_idx); +} + +void asrc_hal_deinit(asrc_hal_context_t *hal) +{ + hal->dev = NULL; +} diff --git a/components/esp_hal_asrc/esp32h4/asrc_periph.c b/components/esp_hal_asrc/esp32h4/asrc_periph.c new file mode 100644 index 0000000000..61008280c3 --- /dev/null +++ b/components/esp_hal_asrc/esp32h4/asrc_periph.c @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "hal/asrc_periph.h" + +/** + * @brief ASRC rate conversion configuration lookup table + * Table structure: asrc_periph_rate_table[src_rate_index][dest_rate_index] + * Rate index mapping: 0=8kHz, 1=16kHz, 2=24kHz, 3=32kHz, 4=44.1kHz, 5=48kHz + */ +const asrc_periph_rate_config_t asrc_periph_rate_table[6][6] = { + { + {1, 1, 1, 0, 0, 0, 0, 0, 0}, // 8k->8k (bypass) + {1, 0, 1, 0, 0, 0, 0, 0, 0}, // 8k->16k (up_2) + {0, 0, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))}, // 8k->32k->24k (up_4 + frac: 4/3) + {0, 0, 1, 0, 0, 0, 0, 0, 0}, // 8k->32k (up_4) + {0, 0, 0, 0, 0, 0, 320, 441, (int)(((1 << 20) + 441) / (2 * 441))}, // 8k->32k->44.1k (up_4 + frac: 320/441) + {0, 0, 0, 0, 0, 0, 2, 3, (int)(((1 << 20) + 3) / (2 * 3))} // 8k->32k->48k (up_4 + frac: 2/3) + }, + { + {1, 0, 1, 0, 1, 0, 0, 0, 0}, // 16k->8k (down_2) + {1, 1, 1, 0, 0, 0, 0, 0, 0}, // 16k->16k (bypass) + {1, 0, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))}, // 16k->32k->24k (up_2 + frac: 4/3) + {1, 0, 1, 0, 0, 0, 0, 0, 0}, // 16k->32k (up_2) + {1, 0, 0, 0, 0, 0, 320, 441, (int)(((1 << 20) + 441) / (2 * 441))}, // 16k->32k->44.1k (up_2 + frac: 320/441) + {1, 0, 0, 0, 0, 0, 2, 3, (int)(((1 << 20) + 3) / (2 * 3))} // 16k->32k->48k (up_2 + frac: 2/3) + }, + { + {0, 0, 0, 1, 1, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 24k->32k->8k (frac: 3/4 + down_4) + {1, 0, 0, 0, 1, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 24k->32k->16k (frac: 3/4 + down_2) + {1, 1, 1, 0, 0, 0, 0, 0, 0}, // 24k->24k (bypass) + {1, 1, 0, 0, 0, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 24k->32k (frac: 3/4) + {0, 0, 0, 0, 0, 0, 320, 147, (int)(((1 << 20) + 147) / (2 * 147))}, // 24k->96k->44.1k (up_4 + frac: 320/147) + {1, 0, 1, 0, 0, 0, 0, 0, 0} // 24k->48k (up_2) + }, + { + {0, 0, 1, 1, 1, 0, 0, 0, 0}, // 32k->8k (down_4) + {1, 0, 1, 0, 1, 0, 0, 0, 0}, // 32k->16k (down_2) + {1, 1, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))}, // 32k->24k (frac: 4/3) + {1, 1, 1, 0, 0, 0, 0, 0, 0}, // 32k->32k (bypass) + {1, 0, 0, 0, 0, 0, 640, 441, (int)(((1 << 20) + 441) / (2 * 441))}, // 32k->64k->44.1k (up_2 + frac: 640/441) + {1, 0, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))} // 32k->64k->48k (up_2 + frac: 4/3) + }, + { + {0, 0, 0, 1, 1, 1, 441, 320, (int)(((1 << 20) + 320) / (2 * 320))}, // 44.1k->32k->8k (frac: 441/320 + down_4) + {1, 0, 0, 0, 1, 1, 441, 320, (int)(((1 << 20) + 320) / (2 * 320))}, // 44.1k->32k->16k (frac: 441/320 + down_2) + {0, 0, 0, 1, 1, 1, 147, 320, (int)(((1 << 20) + 320) / (2 * 320))}, // 44.1k->96k->24k (frac: 147/320 + down_4) + {1, 0, 0, 0, 1, 1, 441, 640, (int)(((1 << 20) + 640) / (2 * 640))}, // 44.1k->64k->32k (frac: 441/640 + down_2) + {1, 1, 1, 0, 0, 0, 0, 0, 0}, // 44.1k->44.1k (bypass) + {1, 0, 0, 0, 0, 0, 147, 80, (int)(((1 << 20) + 80) / (2 * 80))} // 44.1k->88.2k->48k (up_2 + frac: 147/80) + }, + { + {0, 0, 0, 1, 1, 1, 3, 2, (int)(((1 << 20) + 2) / (2 * 2))}, // 48k->32k->8k (frac: 3/2 + down_4) + {1, 0, 0, 0, 1, 1, 3, 2, (int)(((1 << 20) + 2) / (2 * 2))}, // 48k->32k->16k (frac: 3/2 + down_2) + {1, 0, 1, 0, 1, 0, 0, 0, 0}, // 48k->24k (down_2) + {1, 0, 0, 0, 1, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 48k->64k->32k (frac: 3/4 + down_2) + {1, 0, 0, 0, 1, 1, 80, 147, (int)(((1 << 20) + 147) / (2 * 147))}, // 48k->88.2k->44.1k (frac: 80/147 + down_2) + {1, 1, 1, 0, 0, 0, 0, 0, 0} // 48k->48k (bypass) + }, +}; diff --git a/components/esp_hal_asrc/esp32h4/include/hal/asrc_ll.h b/components/esp_hal_asrc/esp32h4/include/hal/asrc_ll.h new file mode 100644 index 0000000000..ad1528d9a9 --- /dev/null +++ b/components/esp_hal_asrc/esp32h4/include/hal/asrc_ll.h @@ -0,0 +1,356 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "soc/asrc_struct.h" +#include "soc/pcr_struct.h" +#include "hal/assert.h" +#include "hal/asrc_periph.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define ASRC_LL_GET_HW() (&ASRC) +#define ASRC_LL_STREAM_NUM (2) + +/** + * @brief ASRC interrupt types + */ +typedef enum { + ASRC_LL_INTR_OUTCNT_EOF = (1 << 0), /**< Output counter EOF interrupt */ +} asrc_ll_intr_type_t; + +/** + * @brief Convert sample rate to table index + * + * @param[in] rate Sample rate in Hz (8000/16000/24000/32000/44100/48000) + * + * @return + * - Table index + * - -1 if rate not supported + */ +static inline int8_t asrc_ll_get_rate_index(uint32_t rate) +{ + int32_t idx = rate / 8000; + if (idx == 5) { + return (rate == 44100) ? 4 : -1; + } + if (idx && rate == idx * 8000 && idx <= 6) { + return idx - 1; + } + return -1; +} + +/** + * @brief Reset ASRC module + * + * @param[in] hw Peripheral ASRC hardware instance address + */ +static inline void asrc_ll_reset_asrc_module(asrc_dev_t *hw) +{ + PCR.asrc_func_clk_conf.asrc_rst_en = 1; + PCR.asrc_func_clk_conf.asrc_rst_en = 0; +} + +/** + * @brief Enable the bus clock for the ASRC module + * + * @param[in] enable Enable the bus clock + */ +static inline void asrc_ll_enable_asrc_module(bool enable) +{ + PCR.asrc_func_clk_conf.asrc_apb_clk_en = enable; + PCR.asrc_func_clk_conf.asrc_func_clk_en = enable; +} + +/** + * @brief Force enable the register clock for the ASRC module + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] enable Enable the register clock + */ +static inline void asrc_ll_force_enable_reg_clock(asrc_dev_t *hw, bool enable) +{ + hw->sys.clk_en = enable; +} + +/** + * @brief Reset specific ASRC stream + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_reset_stream(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg3.reset = 1; + hw->asrc_para[asrc_idx].cfg3.reset = 0; +} + +/** + * @brief Start ASRC processing + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_start_stream(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg4.start = 1; +} + +/** + * @brief Stop ASRC processing + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_stop_stream(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg4.start = 0; +} + +/** + * @brief Set ASRC rate register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + * @param[in] src_rate Source sample rate + * @param[in] dest_rate Destination sample rate + */ +static inline void asrc_ll_set_rate_reg(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t src_rate, uint32_t dest_rate) +{ + int8_t src_idx = asrc_ll_get_rate_index(src_rate); + int8_t dest_idx = asrc_ll_get_rate_index(dest_rate); + HAL_ASSERT(src_idx != -1 && dest_idx != -1); + const asrc_periph_rate_config_t *config = &asrc_periph_rate_table[src_idx][dest_idx]; + hw->asrc_para[asrc_idx].cfg0.rs2_stg0_bypass = config->stg0_bypass; + hw->asrc_para[asrc_idx].cfg0.rs2_stg1_bypass = config->stg1_bypass; + hw->asrc_para[asrc_idx].cfg0.rs2_stg0_mode = config->stg0_mode; + hw->asrc_para[asrc_idx].cfg0.rs2_stg1_mode = config->stg1_mode; + hw->asrc_para[asrc_idx].cfg0.frac_bypass = config->frac_bypass; + hw->asrc_para[asrc_idx].cfg0.frac_ahead = config->frac_ahead; + hw->asrc_para[asrc_idx].cfg1.frac_m = config->frac_m; + hw->asrc_para[asrc_idx].cfg1.frac_l = config->frac_l; + hw->asrc_para[asrc_idx].cfg2.frac_recipl = config->frac_recipl; +} + +/** + * @brief Set ASRC channel mode configuration + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + * @param[in] src_ch Source channel number + * @param[in] dest_ch Destination channel number + * @param[in] weight Weight array + * @param[in] weight_len Weight array length + */ +static inline void asrc_ll_set_channel_mode(asrc_dev_t *hw, uint8_t asrc_idx, uint8_t src_ch, + uint8_t dest_ch, float *weight, uint8_t weight_len) +{ + if (src_ch == 1 && dest_ch == 1) { + // Mode 0: Mono to Mono (1 channel -> 1 channel) + hw->asrc_para[asrc_idx].cfg0.mode = 0; + } else if (src_ch == 1 && dest_ch == 2) { + // Mode 2: Mono to Dual (1 channel -> 2 channels, duplicate mono channel to both outputs) + hw->asrc_para[asrc_idx].cfg0.mode = 2; + } else if (src_ch == 2 && dest_ch == 1) { + // Mode 3: Dual to Mono (2 channels -> 1 channel) + // ch_sel determines channel selection: 0 = select channel 0 only, 1 = mix both channels + HAL_ASSERT(weight_len == 2); + uint32_t ch_sel = (weight[0] == 1.0f && weight[1] == 0.0f) ? 0 : 1; + hw->asrc_para[asrc_idx].cfg0.mode = 3; + hw->asrc_para[asrc_idx].cfg0.sel = ch_sel; + } else { + // Mode 1: Dual to Dual (2 channels -> 2 channels) + hw->asrc_para[asrc_idx].cfg0.mode = 1; + } +} + +/** + * @brief Clear input samples counter register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_clear_incnt_counter(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg5.in_cnt_clr = 1; +} + +/** + * @brief Enable input samples counter register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_enable_incnt_counter(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg5.in_cnt_ena = 1; +} + +/** + * @brief Set expected input samples count register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + * @param[in] in_bytes_num Number of input samples expected + */ +static inline void asrc_ll_set_in_bytes_num(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t in_bytes_num) +{ + hw->asrc_para[asrc_idx].cfg5.in_samples = in_bytes_num; +} + +/** + * @brief Clear output samples counter register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_clear_outcnt_counter(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg6.out_cnt_clr = 1; +} + +/** + * @brief Enable output samples counter register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_enable_outcnt_counter(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg6.out_cnt_ena = 1; +} + +/** + * @brief Enable output samples counter compensation register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_enable_outsample_comp(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].cfg6.out_samples_comp = 1; +} + +/** + * @brief Set expected output sample count register + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + * @param[in] out_bytes_num Number of output samples expected + */ +static inline void asrc_ll_set_out_bytes_num(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t out_bytes_num) +{ + hw->asrc_para[asrc_idx].cfg6.out_samples = out_bytes_num; +} + +/** + * @brief Set EOF (End of Frame) generation mode + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + * @param[in] eof_mode EOF generation mode + */ +static inline void asrc_ll_set_eof_mode(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t eof_mode) +{ + hw->asrc_para[asrc_idx].cfg6.out_eof_gen_mode = eof_mode; +} + +/** + * @brief Reset input fifo + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_reset_input_fifo(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].fifo_ctrl.infifo_reset = 1; + hw->asrc_para[asrc_idx].fifo_ctrl.infifo_reset = 0; +} + +/** + * @brief Reset output fifo + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + */ +static inline void asrc_ll_reset_output_fifo(asrc_dev_t *hw, uint8_t asrc_idx) +{ + hw->asrc_para[asrc_idx].fifo_ctrl.outfifo_reset = 1; + hw->asrc_para[asrc_idx].fifo_ctrl.outfifo_reset = 0; +} + +/** + * @brief Enable ASRC interrupt + * + * @param[in] hw Pointer to ASRC hardware. + * @param[in] asrc_idx ASRC stream index + * @param[in] mask Interrupt mask to enable + */ +static inline void asrc_ll_enable_intr_mask(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t mask) +{ + hw->asrc_para[asrc_idx].int_ena.val |= mask; +} + +/** + * @brief Clear ASRC interrupt + * + * @param[in] hw Pointer to ASRC hardware. + * @param[in] asrc_idx ASRC stream index + * @param[in] mask Interrupt mask to clear + */ +static inline void asrc_ll_clear_intr_mask(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t mask) +{ + hw->asrc_para[asrc_idx].int_clr.val = mask; +} + +/** + * @brief Disable ASRC interrupt + * + * @param[in] hw Pointer to ASRC hardware. + * @param[in] asrc_idx ASRC stream index + * @param[in] mask Interrupt mask to disable + */ +static inline void asrc_ll_disable_intr_mask(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t mask) +{ + hw->asrc_para[asrc_idx].int_ena.val &= (~mask); +} + +/** + * @brief Get ASRC interrupt status + * + * @param[in] hw Pointer to ASRC hardware. + * @param[in] asrc_idx ASRC stream index + * + * @return + * - Interrupt status (masked) + */ +static inline uint32_t asrc_ll_get_intr_status(asrc_dev_t *hw, uint8_t asrc_idx) +{ + return hw->asrc_para[asrc_idx].int_st.val; +} + +/** + * @brief Get current output sample count + * + * @param[in] hw Peripheral ASRC hardware instance address + * @param[in] asrc_idx ASRC stream index + * + * @return + * - Current output samples count + */ +static inline uint32_t asrc_ll_get_outbytes_cnt(asrc_dev_t *hw, uint8_t asrc_idx) +{ + uint32_t out_cnt = hw->asrc_para[asrc_idx].out_cnt.out_cnt; + return out_cnt; +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/components/esp_hal_asrc/esp32h4/include/hal/asrc_periph.h b/components/esp_hal_asrc/esp32h4/include/hal/asrc_periph.h new file mode 100644 index 0000000000..98ef1694bd --- /dev/null +++ b/components/esp_hal_asrc/esp32h4/include/hal/asrc_periph.h @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @brief ASRC rate conversion register configuration structure + */ +typedef struct { + uint32_t stg1_bypass; /*!< Stage 1 bypass control + - 0: Enable stage 1 processing + - 1: Bypass stage 1 (pass-through) */ + uint32_t stg0_bypass; /*!< Stage 0 bypass control + - 0: Enable stage 0 processing + - 1: Bypass stage 0 (pass-through) */ + uint32_t frac_bypass; /*!< Fractional resampler bypass control + - 0: Enable fractional resampler + - 1: Bypass fractional resampler */ + uint32_t stg1_mode; /*!< Stage 1 operation mode + - 1: Down-sampling by 2 (decimation) + - 0: Up-sampling by 2 (interpolation) */ + uint32_t stg0_mode; /*!< Stage 0 operation mode + - 1: Down-sampling by 2 (decimation) + - 0: Up-sampling by 2 (interpolation) */ + uint32_t frac_ahead; /*!< Fractional resampler advance flag + - 0: Normal operation + - 1: Advance mode (implementation specific) */ + uint32_t frac_m; /*!< Fractional resampler numerator + Used in ratio calculation: frac_m/frac_l + Range: Depends on sample rate conversion ratio */ + uint32_t frac_l; /*!< Fractional resampler denominator + Used in ratio calculation: frac_m/frac_l + Range: Depends on sample rate conversion ratio */ + uint32_t frac_recipl; /*!< Fractional resampler reciprocal value + Pre-calculated reciprocal for hardware efficiency + Formula: ((1 << 20) + frac_l) / (2 * frac_l) */ +} asrc_periph_rate_config_t; + +extern const asrc_periph_rate_config_t asrc_periph_rate_table[6][6]; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/components/esp_hal_asrc/include/hal/asrc_hal.h b/components/esp_hal_asrc/include/hal/asrc_hal.h new file mode 100644 index 0000000000..38cb13c61f --- /dev/null +++ b/components/esp_hal_asrc/include/hal/asrc_hal.h @@ -0,0 +1,122 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct asrc_dev_t *asrc_soc_handle_t; // ASRC SOC layer handle + +/** + * @brief Context of the HAL + */ +typedef struct asrc_hal_context { + asrc_soc_handle_t dev; /* #ifdef __cplusplus extern "C" { -#endif +#endif /* __cplusplus */ /** Group: Control and configuration registers */ -/** Type of chnl0_cfg0 register +/** Type of cfg0 register * Control and configuration registers */ typedef union { struct { - /** chnl0_rs2_stg1_bypass : R/W; bitpos: [0]; default: 1; + /** rs2_stg1_bypass : R/W; bitpos: [0]; default: 1; * Set this bit to bypass stage 1 re-sampler in channel0. */ - uint32_t chnl0_rs2_stg1_bypass:1; - /** chnl0_rs2_stg0_bypass : R/W; bitpos: [1]; default: 1; + uint32_t rs2_stg1_bypass : 1; + /** rs2_stg0_bypass : R/W; bitpos: [1]; default: 1; * Set this bit to bypass stage 0 re-sampler in channel0. */ - uint32_t chnl0_rs2_stg0_bypass:1; - /** chnl0_frac_bypass : R/W; bitpos: [2]; default: 1; + uint32_t rs2_stg0_bypass : 1; + /** frac_bypass : R/W; bitpos: [2]; default: 1; * Set this bit to bypass fractional re-sampler in channel0. */ - uint32_t chnl0_frac_bypass:1; - /** chnl0_rs2_stg1_mode : R/W; bitpos: [3]; default: 0; + uint32_t frac_bypass : 1; + /** rs2_stg1_mode : R/W; bitpos: [3]; default: 0; * Write this bit to configure stage 1 re-sampler mode in channel0, 0: interpolation * by factor of 2, 1: decimation by factor of 2. */ - uint32_t chnl0_rs2_stg1_mode:1; - /** chnl0_rs2_stg0_mode : R/W; bitpos: [4]; default: 0; + uint32_t rs2_stg1_mode : 1; + /** rs2_stg0_mode : R/W; bitpos: [4]; default: 0; * Write this bit to configure stage 0 re-sampler mode in channel0, 0: interpolation * by factor of 2, 1: decimation by factor of 2. */ - uint32_t chnl0_rs2_stg0_mode:1; - /** chnl0_frac_ahead : R/W; bitpos: [5]; default: 0; + uint32_t rs2_stg0_mode : 1; + /** frac_ahead : R/W; bitpos: [5]; default: 0; * Set this bit to move fraction re-sampler to the first stage in channel0, it should * be 1 when input frequency is higher the output. */ - uint32_t chnl0_frac_ahead:1; - uint32_t reserved_6:1; - /** chnl0_mode : R/W; bitpos: [8:7]; default: 0; + uint32_t frac_ahead : 1; + uint32_t reserved_6 : 1; + /** mode : R/W; bitpos: [8:7]; default: 0; * Write the bit to configure the channel mode,0: in and out are both mono, 1: in and * out is both dual, 2: in is mono, out is dual, 3, in is dual, out is mono. */ - uint32_t chnl0_mode:2; - /** chnl0_sel : R/W; bitpos: [9]; default: 0; + uint32_t mode : 2; + /** sel : R/W; bitpos: [9]; default: 0; * Write the bit to configure which 16bits data will be processing. */ - uint32_t chnl0_sel:1; - uint32_t reserved_10:22; + uint32_t sel : 1; + uint32_t reserved_10 : 22; }; uint32_t val; -} asrc_chnl0_cfg0_reg_t; +} asrc_cfg0_reg_t; -/** Type of chnl0_cfg1 register +/** Type of cfg1 register * Control and configuration registers */ typedef union { struct { - /** chnl0_frac_m : R/W; bitpos: [9:0]; default: 0; + /** frac_m : R/W; bitpos: [9:0]; default: 0; * Write the bits to specify the denominator of factor of fraction re-sampler in - * channel0, reg_chnl0_frac_m and reg_chnl0_frac_l are relatively prime. + * channel0, reg_frac_m and reg_frac_l are relatively prime. */ - uint32_t chnl0_frac_m:10; - /** chnl0_frac_l : R/W; bitpos: [19:10]; default: 0; + uint32_t frac_m : 10; + /** frac_l : R/W; bitpos: [19:10]; default: 0; * Write the bits to specify the nominator of factor of fraction re-sampler in - * channel0, reg_chnl0_frac_l and reg_chnl0_frac_m are relatively prime. + * channel0, reg_frac_l and reg_frac_m are relatively prime. */ - uint32_t chnl0_frac_l:10; - uint32_t reserved_20:12; + uint32_t frac_l : 10; + uint32_t reserved_20 : 12; }; uint32_t val; -} asrc_chnl0_cfg1_reg_t; +} asrc_cfg1_reg_t; -/** Type of chnl0_cfg2 register +/** Type of cfg2 register * Control and configuration registers */ typedef union { struct { - /** chnl0_frac_recipl : R/W; bitpos: [19:0]; default: 0; + /** frac_recipl : R/W; bitpos: [19:0]; default: 0; * Write the bits with ((2^19+L)/(2L)) round down in channel0. */ - uint32_t chnl0_frac_recipl:20; - uint32_t reserved_20:12; + uint32_t frac_recipl : 20; + uint32_t reserved_20 : 12; }; uint32_t val; -} asrc_chnl0_cfg2_reg_t; +} asrc_cfg2_reg_t; -/** Type of chnl0_cfg3 register +/** Type of cfg3 register * Control and configuration registers */ typedef union { struct { - /** chnl0_reset : WT; bitpos: [0]; default: 0; + /** reset : WT; bitpos: [0]; default: 0; * Set this bit to reset channel0. */ - uint32_t chnl0_reset:1; - uint32_t reserved_1:31; + uint32_t reset : 1; + uint32_t reserved_1 : 31; }; uint32_t val; -} asrc_chnl0_cfg3_reg_t; +} asrc_cfg3_reg_t; -/** Type of chnl0_cfg4 register +/** Type of cfg4 register * Control and configuration registers */ typedef union { struct { - /** chnl0_start : R/W; bitpos: [0]; default: 0; + /** start : R/W; bitpos: [0]; default: 0; * Set this bit to start channel0. */ - uint32_t chnl0_start:1; - uint32_t reserved_1:31; + uint32_t start : 1; + uint32_t reserved_1 : 31; }; uint32_t val; -} asrc_chnl0_cfg4_reg_t; +} asrc_cfg4_reg_t; -/** Type of chnl0_cfg5 register +/** Type of cfg5 register * Control and configuration registers */ typedef union { struct { - /** chnl0_in_cnt_ena : R/W; bitpos: [0]; default: 0; - * Set this bit to enable in data byte counter. + /** in_cnt_ena : R/W; bitpos: [0]; default: 0; + * Set this bit to enable in samples counter. */ - uint32_t chnl0_in_cnt_ena:1; - /** chnl0_in_cnt_clr : WT; bitpos: [1]; default: 0; - * Set this bit to clear in data byte counter. + uint32_t in_cnt_ena : 1; + /** in_cnt_clr : WT; bitpos: [1]; default: 0; + * Set this bit to clear in samples counter. */ - uint32_t chnl0_in_cnt_clr:1; - uint32_t reserved_2:6; - /** chnl0_in_len : R/W; bitpos: [31:8]; default: 0; - * Write the bits to specify the data byte number of data from the DMA + uint32_t in_cnt_clr : 1; + uint32_t reserved_2 : 6; + /** in_samples : R/W; bitpos: [31:8]; default: 0; + * Write the bits to specify the samples number of data from the DMA */ - uint32_t chnl0_in_len:24; + uint32_t in_samples : 24; }; uint32_t val; -} asrc_chnl0_cfg5_reg_t; +} asrc_cfg5_reg_t; -/** Type of chnl0_cfg6 register +/** Type of cfg6 register * Control and configuration registers */ typedef union { struct { - /** chnl0_out_eof_gen_mode : R/W; bitpos: [1:0]; default: 0; + /** out_eof_gen_mode : R/W; bitpos: [1:0]; default: 0; * Write the bits to specify the which eof will be written to DMA. 0: counter eof, 1: * DMA ineof, 2: both counter eof and DMA ineof, 3 none. */ - uint32_t chnl0_out_eof_gen_mode:2; - /** chnl0_out_cnt_ena : R/W; bitpos: [2]; default: 0; - * Set this bit to enable out data byte counter. + uint32_t out_eof_gen_mode : 2; + /** out_cnt_ena : R/W; bitpos: [2]; default: 0; + * Set this bit to enable out samples counter. */ - uint32_t chnl0_out_cnt_ena:1; - /** chnl0_out_cnt_clr : WT; bitpos: [3]; default: 0; - * Set this bit to clear out data byte counter. + uint32_t out_cnt_ena : 1; + /** out_cnt_clr : WT; bitpos: [3]; default: 0; + * Set this bit to clear out samples counter. */ - uint32_t chnl0_out_cnt_clr:1; - /** chnl0_out_len_comp : R/W; bitpos: [4]; default: 0; - * Set this bit to enable out data byte counter compensation when using fractional - * re-sampler and decimation by factor of 2 which results in reg_chnl0_out_cnt >= - * reg_chnl0_out_len + uint32_t out_cnt_clr : 1; + /** out_samples_comp : R/W; bitpos: [4]; default: 0; + * Set this bit to enable out samples counter compensation when using fractional + * re-sampler and decimation by factor of 2 which results in reg_out_cnt >= + * reg_out_samples */ - uint32_t chnl0_out_len_comp:1; - uint32_t reserved_5:3; - /** chnl0_out_len : R/W; bitpos: [31:8]; default: 0; - * Write the bits to specify the data byte number of data to the DMA, the counter eof + uint32_t out_samples_comp : 1; + uint32_t reserved_5 : 3; + /** out_samples : R/W; bitpos: [31:8]; default: 0; + * Write the bits to specify the samples number of data to the DMA, the counter eof * will be set when the counter approaches. */ - uint32_t chnl0_out_len:24; + uint32_t out_samples : 24; }; uint32_t val; -} asrc_chnl0_cfg6_reg_t; +} asrc_cfg6_reg_t; -/** Type of chnl0_fifo_ctrl register +/** Type of fifo_ctrl register * Control and configuration registers */ typedef union { struct { - /** chnl0_infifo_reset : WT; bitpos: [0]; default: 0; + /** infifo_reset : WT; bitpos: [0]; default: 0; * Set this bit to reset outfifo. */ - uint32_t chnl0_infifo_reset:1; - /** chnl0_outfifo_reset : WT; bitpos: [1]; default: 0; + uint32_t infifo_reset : 1; + /** outfifo_reset : WT; bitpos: [1]; default: 0; * Set this bit to reset infifo. */ - uint32_t chnl0_outfifo_reset:1; - uint32_t reserved_2:30; + uint32_t outfifo_reset : 1; + uint32_t reserved_2 : 30; }; uint32_t val; -} asrc_chnl0_fifo_ctrl_reg_t; - -/** Type of chnl1_cfg0 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_rs2_stg1_bypass : R/W; bitpos: [0]; default: 1; - * Set this bit to bypass stage 1 re-sampler in channel1. - */ - uint32_t chnl1_rs2_stg1_bypass:1; - /** chnl1_rs2_stg0_bypass : R/W; bitpos: [1]; default: 1; - * Set this bit to bypass stage 0 re-sampler in channel1. - */ - uint32_t chnl1_rs2_stg0_bypass:1; - /** chnl1_frac_bypass : R/W; bitpos: [2]; default: 1; - * Set this bit to bypass fractional re-sampler in channel1. - */ - uint32_t chnl1_frac_bypass:1; - /** chnl1_rs2_stg1_mode : R/W; bitpos: [3]; default: 0; - * Write this bit to configure stage 1 re-sampler mode in channel1, 0: interpolation - * by factor of 2, 1: decimation by factor of 2. - */ - uint32_t chnl1_rs2_stg1_mode:1; - /** chnl1_rs2_stg0_mode : R/W; bitpos: [4]; default: 0; - * Write this bit to configure stage 0 re-sampler mode in channel1, 0: interpolation - * by factor of 2, 1: decimation by factor of 2. - */ - uint32_t chnl1_rs2_stg0_mode:1; - /** chnl1_frac_ahead : R/W; bitpos: [5]; default: 0; - * Set this bit to move fraction re-sampler to the first stage in channel1, it should - * be 1 when input frequency is higher the output. - */ - uint32_t chnl1_frac_ahead:1; - uint32_t reserved_6:1; - /** chnl1_mode : R/W; bitpos: [8:7]; default: 0; - * Write the bit to configure the channel mode,0: in and out are both mono, 1: in and - * out is both dual, 2: in is mono, out is dual, 3, in is dual, out is mono. - */ - uint32_t chnl1_mode:2; - /** chnl1_sel : R/W; bitpos: [9]; default: 0; - * Write the bit to configure which 16bits data will be processing. - */ - uint32_t chnl1_sel:1; - uint32_t reserved_10:22; - }; - uint32_t val; -} asrc_chnl1_cfg0_reg_t; - -/** Type of chnl1_cfg1 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_frac_m : R/W; bitpos: [9:0]; default: 0; - * Write the bits to specify the denominator of factor of fraction re-sampler in - * channel1, reg_chnl0_frac_m and reg_chnl0_frac_l are relatively prime. - */ - uint32_t chnl1_frac_m:10; - /** chnl1_frac_l : R/W; bitpos: [19:10]; default: 0; - * Write the bits to specify the nominator of factor of fraction re-sampler in - * channel1, reg_chnl0_frac_l and reg_chnl0_frac_m are relatively prime. - */ - uint32_t chnl1_frac_l:10; - uint32_t reserved_20:12; - }; - uint32_t val; -} asrc_chnl1_cfg1_reg_t; - -/** Type of chnl1_cfg2 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_frac_recipl : R/W; bitpos: [19:0]; default: 0; - * Write the bits with ((2^19+L)/(2L)) round down in channel1. - */ - uint32_t chnl1_frac_recipl:20; - uint32_t reserved_20:12; - }; - uint32_t val; -} asrc_chnl1_cfg2_reg_t; - -/** Type of chnl1_cfg3 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_reset : WT; bitpos: [0]; default: 0; - * Set this bit to reset channel1. - */ - uint32_t chnl1_reset:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} asrc_chnl1_cfg3_reg_t; - -/** Type of chnl1_cfg4 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_start : R/W; bitpos: [0]; default: 0; - * Set this bit to start channel1. - */ - uint32_t chnl1_start:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} asrc_chnl1_cfg4_reg_t; - -/** Type of chnl1_cfg5 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_in_cnt_ena : R/W; bitpos: [0]; default: 0; - * Set this bit to enable in data byte counter. - */ - uint32_t chnl1_in_cnt_ena:1; - /** chnl1_in_cnt_clr : WT; bitpos: [1]; default: 0; - * Set this bit to clear in data byte counter. - */ - uint32_t chnl1_in_cnt_clr:1; - uint32_t reserved_2:6; - /** chnl1_in_len : R/W; bitpos: [31:8]; default: 0; - * Write the bits to specify the data byte numbers of data from the DMA - */ - uint32_t chnl1_in_len:24; - }; - uint32_t val; -} asrc_chnl1_cfg5_reg_t; - -/** Type of chnl1_cfg6 register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_out_eof_gen_mode : R/W; bitpos: [1:0]; default: 0; - * Write the bits to specify the which eof will be written to DMA. 0: counter eof, 1: - * DMA ineof, 2: both counter eof and DMA ineof, 3 none. - */ - uint32_t chnl1_out_eof_gen_mode:2; - /** chnl1_out_cnt_ena : R/W; bitpos: [2]; default: 0; - * Set this bit to enable out data byte counter. - */ - uint32_t chnl1_out_cnt_ena:1; - /** chnl1_out_cnt_clr : WT; bitpos: [3]; default: 0; - * Set this bit to clear out data byte counter. - */ - uint32_t chnl1_out_cnt_clr:1; - /** chnl1_out_samples_comp : R/W; bitpos: [4]; default: 0; - * Set this bit to enable out data byte counter compensation when using fractional - * re-sampler and decimation by factor of 2 which results in reg_chnl1_out_cnt >= - * reg_chnl1_out_len - */ - uint32_t chnl1_out_samples_comp:1; - uint32_t reserved_5:3; - /** chnl1_out_len : R/W; bitpos: [31:8]; default: 0; - * Write the bits to specify the data byte number of data to the DMA, the counter eof - * will be set when the counter approaches. - */ - uint32_t chnl1_out_len:24; - }; - uint32_t val; -} asrc_chnl1_cfg6_reg_t; - -/** Type of chnl1_fifo_ctrl register - * Control and configuration registers - */ -typedef union { - struct { - /** chnl1_infifo_reset : WT; bitpos: [0]; default: 0; - * Set this bit to reset outfifo. - */ - uint32_t chnl1_infifo_reset:1; - /** chnl1_outfifo_reset : WT; bitpos: [1]; default: 0; - * Set this bit to reset infifo. - */ - uint32_t chnl1_outfifo_reset:1; - uint32_t reserved_2:30; - }; - uint32_t val; -} asrc_chnl1_fifo_ctrl_reg_t; - +} asrc_fifo_ctrl_reg_t; /** Group: Interrupt Register */ -/** Type of chnl0_int_raw register +/** Type of int_raw register * Raw interrupt status */ typedef union { struct { - /** chnl0_outcnt_eof_int_raw : R/WTC/SS; bitpos: [0]; default: 0; - * This interrupt raw bit turns to high level when the counter approach to reg_out_len. + /** outcnt_eof_int_raw : R/WTC/SS; bitpos: [0]; default: 0; + * This interrupt raw bit turns to high level when the counter approach to + * reg_out_samples. */ - uint32_t chnl0_outcnt_eof_int_raw:1; - uint32_t reserved_1:31; + uint32_t outcnt_eof_int_raw : 1; + uint32_t reserved_1 : 31; }; uint32_t val; -} asrc_chnl0_int_raw_reg_t; +} asrc_int_raw_reg_t; -/** Type of chnl0_int_st register +/** Type of int_st register * Masked interrupt status */ typedef union { struct { - /** chnl0_outcnt_eof_int_st : RO; bitpos: [0]; default: 0; + /** outcnt_eof_int_st : RO; bitpos: [0]; default: 0; * This is the status bit for reg_out_cnt_eof_int_raw when reg_out_cnt_eof_int_ena is * set to 1. */ - uint32_t chnl0_outcnt_eof_int_st:1; - uint32_t reserved_1:31; + uint32_t outcnt_eof_int_st : 1; + uint32_t reserved_1 : 31; }; uint32_t val; -} asrc_chnl0_int_st_reg_t; +} asrc_int_st_reg_t; -/** Type of chnl0_int_ena register +/** Type of int_ena register * Interrupt enable bits */ typedef union { struct { - /** chnl0_outcnt_eof_int_ena : R/W; bitpos: [0]; default: 0; + /** outcnt_eof_int_ena : R/W; bitpos: [0]; default: 0; * This is the enable bit for reg_out_cnt_eof_int_st register. */ - uint32_t chnl0_outcnt_eof_int_ena:1; - uint32_t reserved_1:31; + uint32_t outcnt_eof_int_ena : 1; + uint32_t reserved_1 : 31; }; uint32_t val; -} asrc_chnl0_int_ena_reg_t; +} asrc_int_ena_reg_t; -/** Type of chnl0_int_clr register +/** Type of int_clr register * Interrupt clear bits */ typedef union { struct { - /** chnl0_outcnt_eof_int_clr : WT; bitpos: [0]; default: 0; + /** outcnt_eof_int_clr : WT; bitpos: [0]; default: 0; * Set this bit to clear the reg_out_cnt_eof_int_raw interrupt. */ - uint32_t chnl0_outcnt_eof_int_clr:1; - uint32_t reserved_1:31; + uint32_t outcnt_eof_int_clr : 1; + uint32_t reserved_1 : 31; }; uint32_t val; -} asrc_chnl0_int_clr_reg_t; - -/** Type of chnl1_int_raw register - * Raw interrupt status - */ -typedef union { - struct { - /** chnl1_outcnt_eof_int_raw : R/WTC/SS; bitpos: [0]; default: 0; - * This interrupt raw bit turns to high level when the counter approach to reg_out_len. - */ - uint32_t chnl1_outcnt_eof_int_raw:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} asrc_chnl1_int_raw_reg_t; - -/** Type of chnl1_int_st register - * Masked interrupt status - */ -typedef union { - struct { - /** chnl1_outcnt_eof_int_st : RO; bitpos: [0]; default: 0; - * This is the status bit for reg_out_cnt_eof_int_raw when reg_out_cnt_eof_int_ena is - * set to 1. - */ - uint32_t chnl1_outcnt_eof_int_st:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} asrc_chnl1_int_st_reg_t; - -/** Type of chnl1_int_ena register - * Interrupt enable bits - */ -typedef union { - struct { - /** chnl1_outcnt_eof_int_ena : R/W; bitpos: [0]; default: 0; - * This is the enable bit for reg_out_cnt_eof_int_st register. - */ - uint32_t chnl1_outcnt_eof_int_ena:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} asrc_chnl1_int_ena_reg_t; - -/** Type of chnl1_int_clr register - * Interrupt clear bits - */ -typedef union { - struct { - /** chnl1_outcnt_eof_int_clr : WT; bitpos: [0]; default: 0; - * Set this bit to clear the reg_out_cnt_eof_int_raw interrupt. - */ - uint32_t chnl1_outcnt_eof_int_clr:1; - uint32_t reserved_1:31; - }; - uint32_t val; -} asrc_chnl1_int_clr_reg_t; - +} asrc_int_clr_reg_t; /** Group: Status registers */ -/** Type of chnl0_out_cnt register +/** Type of out_cnt register * Status Registers */ typedef union { struct { - /** chnl0_out_cnt : RO; bitpos: [23:0]; default: 0; + /** out_cnt : RO; bitpos: [23:0]; default: 0; * Represents the bytes numbers send to the DMA when EOF occurs. */ - uint32_t chnl0_out_cnt:24; - uint32_t reserved_24:8; + uint32_t out_cnt : 24; + uint32_t reserved_24 : 8; }; uint32_t val; -} asrc_chnl0_out_cnt_reg_t; - -/** Type of chnl1_out_cnt register - * Status Registers - */ -typedef union { - struct { - /** chnl1_out_cnt : RO; bitpos: [23:0]; default: 0; - * Represents the data byte numbers send to the DMA when EOF occurs. - */ - uint32_t chnl1_out_cnt:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} asrc_chnl1_out_cnt_reg_t; - +} asrc_out_cnt_reg_t; /** Group: DEBUG registers */ -/** Type of chnl0_trace1 register +/** Type of trace1 register * Debug Register1 */ typedef union { struct { - /** chnl0_out_inc : RO; bitpos: [23:0]; default: 0; + /** out_inc : RO; bitpos: [23:0]; default: 0; * Represents the samples numbers send to the DMA */ - uint32_t chnl0_out_inc:24; - uint32_t reserved_24:8; + uint32_t out_inc : 24; + uint32_t reserved_24 : 8; }; uint32_t val; -} asrc_chnl0_trace1_reg_t; - -/** Type of chnl1_trace1 register - * Debug Register1 - */ -typedef union { - struct { - /** chnl1_out_inc : RO; bitpos: [23:0]; default: 0; - * Represents the data byte numbers send to the DMA - */ - uint32_t chnl1_out_inc:24; - uint32_t reserved_24:8; - }; - uint32_t val; -} asrc_chnl1_trace1_reg_t; - +} asrc_trace1_reg_t; /** Group: Configuration registers */ /** Type of sys register - * Control and configuration + * Control and configuration samples */ typedef union { struct { /** clk_en : R/W; bitpos: [0]; default: 0; * Reserved */ - uint32_t clk_en:1; + uint32_t clk_en : 1; /** chnl0_clk_fo : R/W; bitpos: [1]; default: 0; * Set this bit to make channel0 clock free run. */ - uint32_t chnl0_clk_fo:1; + uint32_t chnl0_clk_fo : 1; /** chnl1_clk_fo : R/W; bitpos: [2]; default: 0; * Set this bit to make channel1 clock free run. */ - uint32_t chnl1_clk_fo:1; + uint32_t chnl1_clk_fo : 1; /** chnl0_outfifo_clk_fo : R/W; bitpos: [3]; default: 0; * Set this bit to make channel0 outfifo clock free run. */ - uint32_t chnl0_outfifo_clk_fo:1; + uint32_t chnl0_outfifo_clk_fo : 1; /** chnl0_infifo_clk_fo : R/W; bitpos: [4]; default: 0; * Set this bit to make channel0 infifo clock free run. */ - uint32_t chnl0_infifo_clk_fo:1; + uint32_t chnl0_infifo_clk_fo : 1; /** chnl1_outfifo_clk_fo : R/W; bitpos: [5]; default: 0; * Set this bit to make channel1 outfifo clock free run. */ - uint32_t chnl1_outfifo_clk_fo:1; + uint32_t chnl1_outfifo_clk_fo : 1; /** chnl1_infifo_clk_fo : R/W; bitpos: [6]; default: 0; * Set this bit to make channel1 infifo clock free run. */ - uint32_t chnl1_infifo_clk_fo:1; - uint32_t reserved_7:25; + uint32_t chnl1_infifo_clk_fo : 1; + uint32_t reserved_7 : 25; }; uint32_t val; } asrc_sys_reg_t; - /** Group: Version register */ /** Type of date register * Control and configuration registers @@ -603,55 +332,41 @@ typedef union { /** date : R/W; bitpos: [27:0]; default: 37777984; * Reserved */ - uint32_t date:28; - uint32_t reserved_28:4; + uint32_t date : 28; + uint32_t reserved_28 : 4; }; uint32_t val; } asrc_date_reg_t; - -typedef struct { - volatile asrc_chnl0_cfg0_reg_t chnl0_cfg0; - volatile asrc_chnl0_cfg1_reg_t chnl0_cfg1; - volatile asrc_chnl0_cfg2_reg_t chnl0_cfg2; - volatile asrc_chnl0_cfg3_reg_t chnl0_cfg3; - volatile asrc_chnl0_cfg4_reg_t chnl0_cfg4; - volatile asrc_chnl0_cfg5_reg_t chnl0_cfg5; - volatile asrc_chnl0_cfg6_reg_t chnl0_cfg6; - volatile asrc_chnl0_fifo_ctrl_reg_t chnl0_fifo_ctrl; - volatile asrc_chnl0_int_raw_reg_t chnl0_int_raw; - volatile asrc_chnl0_int_st_reg_t chnl0_int_st; - volatile asrc_chnl0_int_ena_reg_t chnl0_int_ena; - volatile asrc_chnl0_int_clr_reg_t chnl0_int_clr; - volatile asrc_chnl0_out_cnt_reg_t chnl0_out_cnt; - uint32_t reserved_034; - volatile asrc_chnl0_trace1_reg_t chnl0_trace1; - volatile asrc_chnl1_cfg0_reg_t chnl1_cfg0; - volatile asrc_chnl1_cfg1_reg_t chnl1_cfg1; - volatile asrc_chnl1_cfg2_reg_t chnl1_cfg2; - volatile asrc_chnl1_cfg3_reg_t chnl1_cfg3; - volatile asrc_chnl1_cfg4_reg_t chnl1_cfg4; - volatile asrc_chnl1_cfg5_reg_t chnl1_cfg5; - volatile asrc_chnl1_cfg6_reg_t chnl1_cfg6; - volatile asrc_chnl1_fifo_ctrl_reg_t chnl1_fifo_ctrl; - volatile asrc_chnl1_int_raw_reg_t chnl1_int_raw; - volatile asrc_chnl1_int_st_reg_t chnl1_int_st; - volatile asrc_chnl1_int_ena_reg_t chnl1_int_ena; - volatile asrc_chnl1_int_clr_reg_t chnl1_int_clr; - volatile asrc_chnl1_out_cnt_reg_t chnl1_out_cnt; - uint32_t reserved_070; - volatile asrc_chnl1_trace1_reg_t chnl1_trace1; - uint32_t reserved_078[32]; - volatile asrc_sys_reg_t sys; +typedef struct asrc_dev_t { + struct { + volatile asrc_cfg0_reg_t cfg0; + volatile asrc_cfg1_reg_t cfg1; + volatile asrc_cfg2_reg_t cfg2; + volatile asrc_cfg3_reg_t cfg3; + volatile asrc_cfg4_reg_t cfg4; + volatile asrc_cfg5_reg_t cfg5; + volatile asrc_cfg6_reg_t cfg6; + volatile asrc_fifo_ctrl_reg_t fifo_ctrl; + volatile asrc_int_raw_reg_t int_raw; + volatile asrc_int_st_reg_t int_st; + volatile asrc_int_ena_reg_t int_ena; + volatile asrc_int_clr_reg_t int_clr; + volatile asrc_out_cnt_reg_t out_cnt; + uint32_t reserved_32; + volatile asrc_trace1_reg_t trace1; + } asrc_para[2]; + uint32_t reserved_078[32]; + volatile asrc_sys_reg_t sys; volatile asrc_date_reg_t date; } asrc_dev_t; -extern asrc_dev_t SAMPLE_RATE_CONVERTER; +extern asrc_dev_t ASRC; #ifndef __cplusplus _Static_assert(sizeof(asrc_dev_t) == 0x100, "Invalid size of asrc_dev_t structure"); -#endif +#endif /* __cplusplus */ #ifdef __cplusplus } -#endif +#endif /* __cplusplus */