Merge branch 'fix/driver_issue_by_coverity' into 'master'

Fix some false issue report by coverity

Closes IDF-13116, IDF-13120, IDF-13104, IDF-13106, IDF-13107, IDF-13109, IDF-13112, IDF-13124, and IDF-13126

See merge request espressif/esp-idf!39287
This commit is contained in:
morris
2025-05-21 10:05:28 +08:00
12 changed files with 131 additions and 107 deletions

View File

@@ -23,13 +23,11 @@ static esp_err_t ana_cmpr_del_etm_event(esp_etm_event_handle_t base_event)
esp_err_t ana_cmpr_new_etm_event(ana_cmpr_handle_t cmpr, const ana_cmpr_etm_event_config_t *config, esp_etm_event_handle_t *ret_event)
{
esp_err_t ret = ESP_OK;
ana_cmpr_etm_event_t *event = NULL;
ana_cmpr_unit_t unit = ana_cmpr_get_unit_id(cmpr);
ESP_RETURN_ON_FALSE(((int)unit) >= 0, ESP_ERR_INVALID_ARG, TAG, "invalid analog comparator handle");
ESP_RETURN_ON_FALSE(config && ret_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
event = heap_caps_calloc(1, sizeof(ana_cmpr_etm_event_t), ETM_MEM_ALLOC_CAPS);
ESP_GOTO_ON_FALSE(event, ESP_ERR_NO_MEM, err, TAG, "no mem for analog comparator event");
ana_cmpr_etm_event_t *event = heap_caps_calloc(1, sizeof(ana_cmpr_etm_event_t), ETM_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no mem for analog comparator event");
uint32_t event_id = ANALOG_CMPR_LL_ETM_SOURCE(unit, config->event_type);
event->base.del = ana_cmpr_del_etm_event;
@@ -38,11 +36,4 @@ esp_err_t ana_cmpr_new_etm_event(ana_cmpr_handle_t cmpr, const ana_cmpr_etm_even
ESP_LOGD(TAG, "new event @%p, event_id=%"PRIu32", unit_id=%d", event, event_id, unit);
*ret_event = &event->base;
return ESP_OK;
err:
if (event) {
free(event);
event = NULL;
}
return ret;
}

View File

@@ -50,6 +50,9 @@ typedef struct {
/**
* @brief Allocate BitScrambler handle for a hardware channel
*
* @note This function can only be used to create a single direction BitScrambler handle.
* If you need a loopback BitScrambler, call bitscrambler_loopback_create() instead.
*
* @param config Configuration for requested BitScrambler
* @param[out] handle BitScrambler controller handle
*

View File

@@ -5,6 +5,7 @@
*/
#include <string.h>
#include <stdatomic.h>
#include "soc/soc_caps.h"
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "driver/bitscrambler.h"
@@ -20,6 +21,13 @@ static const char *TAG = "bitscrambler";
#define BITSCRAMBLER_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
#endif
#if !SOC_RCC_IS_INDEPENDENT
// Reset and Clock Control registers are mixing with other peripherals, so we need to use a critical section
#define BS_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
#else
#define BS_RCC_ATOMIC()
#endif
#define BITSCRAMBLER_BINARY_VER 1 //max version we're compatible with
#define BITSCRAMBLER_HW_REV 0
@@ -54,38 +62,66 @@ typedef struct {
atomic_flag tx_in_use = ATOMIC_FLAG_INIT;
atomic_flag rx_in_use = ATOMIC_FLAG_INIT;
// Claim both TX and RX channels for loopback use
// Returns true on success, false if any of the two directions already is claimed.
static bool claim_channel_loopback(void)
{
bool old_val_tx = atomic_flag_test_and_set(&tx_in_use);
if (old_val_tx) {
return false;
}
bool old_val_rx = atomic_flag_test_and_set(&rx_in_use);
if (old_val_rx) {
atomic_flag_clear(&tx_in_use);
return false;
}
return true;
}
// This is a reference count for the BitScrambler module. It is used to keep track of how many clients are using the module.
atomic_int group_ref_count = 0;
// Claim a channel using the direction it indicated.
// Returns true on success, false if the direction already is claimed
static bool claim_channel(bitscrambler_direction_t dir)
{
int old_use_count = atomic_fetch_add(&group_ref_count, 1);
if (old_use_count == 0) {
BS_RCC_ATOMIC() {
// This is the first client using the module, so we need to enable the sys clock
bitscrambler_ll_set_bus_clock_sys_enable(true);
bitscrambler_ll_reset_sys();
// also power on the memory
bitscrambler_ll_mem_power_by_pmu();
}
}
if (dir == BITSCRAMBLER_DIR_TX) {
bool old_val = atomic_flag_test_and_set(&tx_in_use);
if (old_val) {
return false;
goto err;
} else {
BS_RCC_ATOMIC() {
bitscrambler_ll_set_bus_clock_tx_enable(true);
bitscrambler_ll_reset_tx();
}
}
} else if (dir == BITSCRAMBLER_DIR_RX) {
} else {
bool old_val = atomic_flag_test_and_set(&rx_in_use);
if (old_val) {
return false;
goto err;
} else {
BS_RCC_ATOMIC() {
bitscrambler_ll_set_bus_clock_rx_enable(true);
bitscrambler_ll_reset_rx();
}
}
}
return true;
err:
atomic_fetch_sub(&group_ref_count, 1);
return false;
}
// Release the channel using the direction it indicated.
static void release_channel(bitscrambler_direction_t dir)
{
if (dir == BITSCRAMBLER_DIR_TX) {
atomic_flag_clear(&tx_in_use);
} else if (dir == BITSCRAMBLER_DIR_RX) {
atomic_flag_clear(&rx_in_use);
}
int old_use_count = atomic_fetch_sub(&group_ref_count, 1);
if (old_use_count == 1) {
// This is the last client using the module, so we need to disable the sys clock
BS_RCC_ATOMIC() {
bitscrambler_ll_set_bus_clock_sys_enable(false);
bitscrambler_ll_mem_force_power_off();
}
}
}
//Initialize the BitScrambler object and hardware using the given config.
@@ -96,53 +132,22 @@ static esp_err_t init_from_config(bitscrambler_t *bs, const bitscrambler_config_
return ESP_OK;
}
static void enable_clocks(bitscrambler_t *bs)
{
PERIPH_RCC_ACQUIRE_ATOMIC(PERIPH_BITSCRAMBLER_MODULE, ref_count) {
if (ref_count == 0) { //we're the first to enable the BitScrambler module
bitscrambler_ll_set_bus_clock_sys_enable(1);
bitscrambler_ll_reset_sys();
bitscrambler_ll_mem_power_by_pmu();
}
if (bs->cfg.dir == BITSCRAMBLER_DIR_RX || bs->loopback) {
bitscrambler_ll_set_bus_clock_rx_enable(1);
bitscrambler_ll_reset_rx();
}
if (bs->cfg.dir == BITSCRAMBLER_DIR_TX || bs->loopback) {
bitscrambler_ll_set_bus_clock_tx_enable(1);
bitscrambler_ll_reset_tx();
}
}
}
static void disable_clocks(bitscrambler_t *bs)
{
PERIPH_RCC_RELEASE_ATOMIC(PERIPH_BITSCRAMBLER_MODULE, ref_count) {
if (bs->cfg.dir == BITSCRAMBLER_DIR_RX || bs->loopback) {
bitscrambler_ll_set_bus_clock_rx_enable(0);
}
if (bs->cfg.dir == BITSCRAMBLER_DIR_TX || bs->loopback) {
bitscrambler_ll_set_bus_clock_tx_enable(0);
}
if (ref_count == 0) { //we're the last to disable the BitScrambler module
bitscrambler_ll_set_bus_clock_sys_enable(0);
bitscrambler_ll_mem_force_power_off();
}
}
}
//Private function: init an existing BitScrambler object as a loopback BitScrambler.
// init an existing BitScrambler object as a loopback BitScrambler, only used by the bitscrambler loopback driver
esp_err_t bitscrambler_init_loopback(bitscrambler_handle_t handle, const bitscrambler_config_t *config)
{
if (!claim_channel_loopback()) {
// claim the TX channel first
if (!claim_channel(BITSCRAMBLER_DIR_TX)) {
return ESP_ERR_NOT_FOUND;
}
// claim the RX channel, if it fails, release the TX channel
if (!claim_channel(BITSCRAMBLER_DIR_RX)) {
release_channel(BITSCRAMBLER_DIR_TX);
return ESP_ERR_NOT_FOUND;
}
assert(config->dir == BITSCRAMBLER_DIR_TX);
// mark the BitScrambler object as a loopback BitScrambler
handle->loopback = true;
enable_clocks(handle);
esp_err_t r = init_from_config(handle, config);
return r;
return init_from_config(handle, config);
}
esp_err_t bitscrambler_new(const bitscrambler_config_t *config, bitscrambler_handle_t *handle)
@@ -172,8 +177,6 @@ esp_err_t bitscrambler_new(const bitscrambler_config_t *config, bitscrambler_han
return r;
}
enable_clocks(bs);
// Return the handle
*handle = bs;
return ESP_OK;
@@ -304,14 +307,11 @@ void bitscrambler_free(bitscrambler_handle_t handle)
if (!handle) {
return;
}
disable_clocks(handle);
if (handle->loopback) {
atomic_flag_clear(&tx_in_use);
atomic_flag_clear(&rx_in_use);
} else if (handle->cfg.dir == BITSCRAMBLER_DIR_TX) {
atomic_flag_clear(&tx_in_use);
} else if (handle->cfg.dir == BITSCRAMBLER_DIR_RX) {
atomic_flag_clear(&rx_in_use);
release_channel(BITSCRAMBLER_DIR_TX);
release_channel(BITSCRAMBLER_DIR_RX);
} else {
release_channel(handle->cfg.dir);
}
if (handle->extra_clean_up) {
handle->extra_clean_up(handle, handle->clean_up_user_ctx);

View File

@@ -740,6 +740,7 @@ esp_err_t parlio_rx_unit_enable(parlio_rx_unit_handle_t rx_unit, bool reset_queu
parlio_ll_rx_enable_clock(hal->regs, false);
}
}
assert(trans.delimiter);
parlio_rx_set_delimiter_config(rx_unit, trans.delimiter);
parlio_rx_mount_transaction_buffer(rx_unit, &trans);
gdma_start(rx_unit->dma_chan, (intptr_t)rx_unit->curr_desc);

View File

@@ -258,7 +258,8 @@ esp_err_t ppa_do_blend(ppa_client_handle_t ppa_client, const ppa_blend_oper_conf
esp_err_t ret = ESP_OK;
ppa_trans_t *trans_elm = NULL;
if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) {
if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0) == pdTRUE) {
assert(trans_elm);
dma2d_trans_config_t *dma_trans_desc = trans_elm->trans_desc;
ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = dma_trans_desc->user_config;

View File

@@ -113,7 +113,8 @@ esp_err_t ppa_do_fill(ppa_client_handle_t ppa_client, const ppa_fill_oper_config
esp_err_t ret = ESP_OK;
ppa_trans_t *trans_elm = NULL;
if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) {
if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0) == pdTRUE) {
assert(trans_elm);
dma2d_trans_config_t *dma_trans_desc = trans_elm->trans_desc;
ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = dma_trans_desc->user_config;

View File

@@ -252,7 +252,8 @@ esp_err_t ppa_do_scale_rotate_mirror(ppa_client_handle_t ppa_client, const ppa_s
esp_err_t ret = ESP_OK;
ppa_trans_t *trans_elm = NULL;
if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0)) {
if (xQueueReceive(ppa_client->trans_elm_ptr_queue, (void *)&trans_elm, 0) == pdTRUE) {
assert(trans_elm);
dma2d_trans_config_t *dma_trans_desc = trans_elm->trans_desc;
ppa_dma2d_trans_on_picked_config_t *trans_on_picked_desc = dma_trans_desc->user_config;

View File

@@ -42,6 +42,7 @@ touch_sensor_handle_t g_touch = NULL;
static void touch_channel_pin_init(int id)
{
gpio_num_t pin = touch_sensor_channel_io_map[id];
assert(pin >= 0);
if (esp_gpio_reserve(BIT64(pin)) & BIT64(pin)) {
ESP_LOGW(TAG, "The GPIO%d is conflict with other module", (int)pin);
}

View File

@@ -198,6 +198,7 @@ esp_err_t touch_priv_config_controller(touch_sensor_handle_t sens_handle, const
sens_handle->sample_cfg_num = 1; // Only have one set of sampling configuration
/* Configure the hardware */
assert(hal_cfg.sample_cfg_num == 1);
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
touch_hal_config_controller(&hal_cfg);
touch_ll_reset_trigger_groups();

View File

@@ -88,6 +88,8 @@ static bool uhci_gdma_tx_callback_eof(gdma_channel_handle_t dma_chan, gdma_event
expected_fsm = UHCI_TX_FSM_ENABLE;
if (atomic_compare_exchange_strong(&uhci_ctrl->tx_dir.tx_fsm, &expected_fsm, UHCI_TX_FSM_RUN_WAIT)) {
if (xQueueReceiveFromISR(uhci_ctrl->tx_dir.trans_queues[UHCI_TRANS_QUEUE_PROGRESS], &trans_desc, &do_yield) == pdTRUE) {
// sanity check
assert(trans_desc);
atomic_store(&uhci_ctrl->tx_dir.tx_fsm, UHCI_TX_FSM_RUN);
uhci_do_transmit(uhci_ctrl, trans_desc);
if (do_yield) {
@@ -219,7 +221,7 @@ static esp_err_t uhci_gdma_initialize(uhci_controller_handle_t uhci_ctrl, const
ESP_RETURN_ON_ERROR(gdma_new_link_list(&dma_link_config, &uhci_ctrl->rx_dir.dma_link), TAG, "DMA rx link list alloc failed");
ESP_LOGD(TAG, "rx_dma node number is %d", uhci_ctrl->rx_dir.rx_num_dma_nodes);
uhci_ctrl->rx_dir.buffer_size_per_desc_node = heap_caps_calloc(uhci_ctrl->rx_dir.rx_num_dma_nodes, sizeof(uhci_ctrl->rx_dir.buffer_size_per_desc_node), UHCI_MEM_ALLOC_CAPS);
uhci_ctrl->rx_dir.buffer_size_per_desc_node = heap_caps_calloc(uhci_ctrl->rx_dir.rx_num_dma_nodes, sizeof(*uhci_ctrl->rx_dir.buffer_size_per_desc_node), UHCI_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(uhci_ctrl->rx_dir.buffer_size_per_desc_node, ESP_ERR_NO_MEM, TAG, "no memory for recording buffer size for desc node");
uhci_ctrl->rx_dir.buffer_pointers = heap_caps_calloc(uhci_ctrl->rx_dir.rx_num_dma_nodes, sizeof(*uhci_ctrl->rx_dir.buffer_pointers), UHCI_MEM_ALLOC_CAPS);
ESP_RETURN_ON_FALSE(uhci_ctrl->rx_dir.buffer_pointers, ESP_ERR_NO_MEM, TAG, "no memory for recording buffer pointers for desc node");

View File

@@ -298,7 +298,7 @@ static inline bool bitscrambler_ll_is_fifo_ready(bitscrambler_dev_t *hw, bitscra
/**
* @brief Enable the bus clock for BitScrambler module
*/
static inline void _bitscrambler_ll_set_bus_clock_sys_enable(bool enable)
static inline void bitscrambler_ll_set_bus_clock_sys_enable(bool enable)
{
PCR.bs_conf.bs_clk_en = enable;
}
@@ -306,7 +306,7 @@ static inline void _bitscrambler_ll_set_bus_clock_sys_enable(bool enable)
/**
* @brief Enable the bus clock for RX BitScrambler module
*/
static inline void _bitscrambler_ll_set_bus_clock_rx_enable(bool enable)
static inline void bitscrambler_ll_set_bus_clock_rx_enable(bool enable)
{
// empty
}
@@ -314,7 +314,7 @@ static inline void _bitscrambler_ll_set_bus_clock_rx_enable(bool enable)
/**
* @brief Enable the bus clock for TX BitScrambler module
*/
static inline void _bitscrambler_ll_set_bus_clock_tx_enable(bool enable)
static inline void bitscrambler_ll_set_bus_clock_tx_enable(bool enable)
{
// empty
}
@@ -349,7 +349,7 @@ static inline void bitscrambler_ll_mem_power_by_pmu(void)
/**
* @brief Reset the BitScrambler module
*/
static inline void _bitscrambler_ll_reset_sys(void)
static inline void bitscrambler_ll_reset_sys(void)
{
PCR.bs_conf.bs_rst_en = 1;
PCR.bs_conf.bs_rst_en = 0;
@@ -358,7 +358,7 @@ static inline void _bitscrambler_ll_reset_sys(void)
/**
* @brief Reset the BitScrambler RX module
*/
static inline void _bitscrambler_ll_reset_rx(void)
static inline void bitscrambler_ll_reset_rx(void)
{
PCR.bs_func_conf.bs_rx_rst_en = 1;
PCR.bs_func_conf.bs_rx_rst_en = 0;
@@ -367,22 +367,12 @@ static inline void _bitscrambler_ll_reset_rx(void)
/**
* @brief Reset the BitScrambler TX module
*/
static inline void _bitscrambler_ll_reset_tx(void)
static inline void bitscrambler_ll_reset_tx(void)
{
PCR.bs_func_conf.bs_tx_rst_en = 1;
PCR.bs_func_conf.bs_tx_rst_en = 0;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_set_bus_clock_sys_enable(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_set_bus_clock_sys_enable(__VA_ARGS__)
#define bitscrambler_ll_set_bus_clock_rx_enable(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_set_bus_clock_rx_enable(__VA_ARGS__)
#define bitscrambler_ll_set_bus_clock_tx_enable(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_set_bus_clock_tx_enable(__VA_ARGS__)
#define bitscrambler_ll_reset_sys(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_reset_sys(__VA_ARGS__)
#define bitscrambler_ll_reset_rx(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_reset_rx(__VA_ARGS__)
#define bitscrambler_ll_reset_tx(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_reset_tx(__VA_ARGS__)
#ifdef __cplusplus
}
#endif

View File

@@ -303,6 +303,13 @@ static inline void _bitscrambler_ll_set_bus_clock_sys_enable(bool enable)
HP_SYS_CLKRST.soc_clk_ctrl1.reg_bitscrambler_sys_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_set_bus_clock_sys_enable(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_bitscrambler_ll_set_bus_clock_sys_enable(__VA_ARGS__); \
} while (0)
/**
* @brief Enable the bus clock for RX BitScrambler module
*/
@@ -311,6 +318,13 @@ static inline void _bitscrambler_ll_set_bus_clock_rx_enable(bool enable)
HP_SYS_CLKRST.soc_clk_ctrl1.reg_bitscrambler_rx_sys_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_set_bus_clock_rx_enable(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_bitscrambler_ll_set_bus_clock_rx_enable(__VA_ARGS__); \
} while (0)
/**
* @brief Enable the bus clock for TX BitScrambler module
*/
@@ -319,6 +333,13 @@ static inline void _bitscrambler_ll_set_bus_clock_tx_enable(bool enable)
HP_SYS_CLKRST.soc_clk_ctrl1.reg_bitscrambler_tx_sys_clk_en = enable;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_set_bus_clock_tx_enable(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_bitscrambler_ll_set_bus_clock_tx_enable(__VA_ARGS__); \
} while (0)
/**
* @brief Force power on the bitscrambler memory block, regardless of the outside PMU logic
*/
@@ -352,6 +373,13 @@ static inline void _bitscrambler_ll_reset_sys(void)
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_bitscrambler = 0;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_reset_sys(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_bitscrambler_ll_reset_sys(__VA_ARGS__); \
} while (0)
/**
* @brief Reset the BitScrambler RX module
*/
@@ -361,6 +389,13 @@ static inline void _bitscrambler_ll_reset_rx(void)
HP_SYS_CLKRST.hp_rst_en2.reg_rst_en_bitscrambler_rx = 0;
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_reset_rx(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_bitscrambler_ll_reset_rx(__VA_ARGS__); \
} while (0)
/**
* @brief Reset the BitScrambler TX module
*/
@@ -371,14 +406,11 @@ static inline void _bitscrambler_ll_reset_tx(void)
}
/// use a macro to wrap the function, force the caller to use it in a critical section
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_set_bus_clock_sys_enable(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_set_bus_clock_sys_enable(__VA_ARGS__)
#define bitscrambler_ll_set_bus_clock_rx_enable(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_set_bus_clock_rx_enable(__VA_ARGS__)
#define bitscrambler_ll_set_bus_clock_tx_enable(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_set_bus_clock_tx_enable(__VA_ARGS__)
#define bitscrambler_ll_reset_sys(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_reset_sys(__VA_ARGS__)
#define bitscrambler_ll_reset_rx(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_reset_rx(__VA_ARGS__)
#define bitscrambler_ll_reset_tx(...) (void)__DECLARE_RCC_RC_ATOMIC_ENV; _bitscrambler_ll_reset_tx(__VA_ARGS__)
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
#define bitscrambler_ll_reset_tx(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_bitscrambler_ll_reset_tx(__VA_ARGS__); \
} while (0)
#ifdef __cplusplus
}