Merge branch 'bugfix/fix_bci_416' into 'master'

Fixed BLE interrupt allocation using esp API on ESP32C3

See merge request espressif/esp-idf!30652
This commit is contained in:
Island 2024-05-22 17:57:01 +08:00
commit a3cb889ba3
7 changed files with 67 additions and 79 deletions

View File

@ -115,7 +115,7 @@ do{\
} while(0) } while(0)
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff #define OSI_FUNCS_TIME_BLOCKING 0xffffffff
#define OSI_VERSION 0x00010008 #define OSI_VERSION 0x00010009
#define OSI_MAGIC_VALUE 0xFADEBEAD #define OSI_MAGIC_VALUE 0xFADEBEAD
/* Types definition /* Types definition
@ -142,15 +142,24 @@ typedef struct {
typedef void (* osi_intr_handler)(void); typedef void (* osi_intr_handler)(void);
typedef struct {
int source; /*!< ISR source */
int flags; /*!< ISR alloc flag */
void (*fn)(void *); /*!< ISR function */
void *arg; /*!< ISR function args*/
intr_handle_t *handle; /*!< ISR handle */
esp_err_t ret;
} btdm_isr_alloc_t;
/* OSI function */ /* OSI function */
struct osi_funcs_t { struct osi_funcs_t {
uint32_t _magic; uint32_t _magic;
uint32_t _version; uint32_t _version;
void (*_interrupt_set)(int cpu_no, int intr_source, int interrupt_no, int interrpt_prio); int (* _interrupt_alloc)(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle);
void (*_interrupt_clear)(int interrupt_source, int interrupt_no); int (* _interrupt_free)(void *handle);
void (*_interrupt_handler_set)(int interrupt_no, intr_handler_t fn, void *arg); void (*_interrupt_handler_set_rsv)(int interrupt_no, intr_handler_t fn, void *arg);
void (*_interrupt_disable)(void); void (*_global_intr_disable)(void);
void (*_interrupt_restore)(void); void (*_global_intr_restore)(void);
void (*_task_yield)(void); void (*_task_yield)(void);
void (*_task_yield_from_isr)(void); void (*_task_yield_from_isr)(void);
void *(*_semphr_create)(uint32_t max, uint32_t init); void *(*_semphr_create)(uint32_t max, uint32_t init);
@ -195,8 +204,8 @@ struct osi_funcs_t {
uint32_t (* _coex_schm_interval_get)(void); uint32_t (* _coex_schm_interval_get)(void);
uint8_t (* _coex_schm_curr_period_get)(void); uint8_t (* _coex_schm_curr_period_get)(void);
void *(* _coex_schm_curr_phase_get)(void); void *(* _coex_schm_curr_phase_get)(void);
void (* _interrupt_on)(int intr_num); int (* _interrupt_enable)(void *handle);
void (* _interrupt_off)(int intr_num); int (* _interrupt_disable)(void *handle);
void (* _esp_hw_power_down)(void); void (* _esp_hw_power_down)(void);
void (* _esp_hw_power_up)(void); void (* _esp_hw_power_up)(void);
void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem); void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem);
@ -277,11 +286,10 @@ extern uint32_t _bt_controller_data_end;
/* Local Function Declare /* Local Function Declare
********************************************************************* *********************************************************************
*/ */
static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio); static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle);
static void interrupt_clear_wrapper(int intr_source, int intr_num); static int interrupt_free_wrapper(void *handle);
static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg); static void global_interrupt_disable(void);
static void interrupt_disable(void); static void global_interrupt_restore(void);
static void interrupt_restore(void);
static void task_yield_from_isr(void); static void task_yield_from_isr(void);
static void *semphr_create_wrapper(uint32_t max, uint32_t init); static void *semphr_create_wrapper(uint32_t max, uint32_t init);
static void semphr_delete_wrapper(void *semphr); static void semphr_delete_wrapper(void *semphr);
@ -319,8 +327,8 @@ static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
static uint32_t coex_schm_interval_get_wrapper(void); static uint32_t coex_schm_interval_get_wrapper(void);
static uint8_t coex_schm_curr_period_get_wrapper(void); static uint8_t coex_schm_curr_period_get_wrapper(void);
static void * coex_schm_curr_phase_get_wrapper(void); static void * coex_schm_curr_phase_get_wrapper(void);
static void interrupt_on_wrapper(int intr_num); static int interrupt_enable_wrapper(void *handle);
static void interrupt_off_wrapper(int intr_num); static int interrupt_disable_wrapper(void *handle);
static void btdm_hw_mac_power_up_wrapper(void); static void btdm_hw_mac_power_up_wrapper(void);
static void btdm_hw_mac_power_down_wrapper(void); static void btdm_hw_mac_power_down_wrapper(void);
static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem); static void btdm_backup_dma_copy_wrapper(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_mem);
@ -341,11 +349,11 @@ static void bt_controller_deinit_internal(void);
static const struct osi_funcs_t osi_funcs_ro = { static const struct osi_funcs_t osi_funcs_ro = {
._magic = OSI_MAGIC_VALUE, ._magic = OSI_MAGIC_VALUE,
._version = OSI_VERSION, ._version = OSI_VERSION,
._interrupt_set = interrupt_set_wrapper, ._interrupt_alloc = interrupt_alloc_wrapper,
._interrupt_clear = interrupt_clear_wrapper, ._interrupt_free = interrupt_free_wrapper,
._interrupt_handler_set = interrupt_handler_set_wrapper, ._interrupt_handler_set_rsv = NULL,
._interrupt_disable = interrupt_disable, ._global_intr_disable = global_interrupt_disable,
._interrupt_restore = interrupt_restore, ._global_intr_restore = global_interrupt_restore,
._task_yield = vPortYield, ._task_yield = vPortYield,
._task_yield_from_isr = task_yield_from_isr, ._task_yield_from_isr = task_yield_from_isr,
._semphr_create = semphr_create_wrapper, ._semphr_create = semphr_create_wrapper,
@ -390,8 +398,8 @@ static const struct osi_funcs_t osi_funcs_ro = {
._coex_schm_interval_get = coex_schm_interval_get_wrapper, ._coex_schm_interval_get = coex_schm_interval_get_wrapper,
._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper, ._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper,
._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper, ._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
._interrupt_on = interrupt_on_wrapper, ._interrupt_enable = interrupt_enable_wrapper,
._interrupt_off = interrupt_off_wrapper, ._interrupt_disable = interrupt_disable_wrapper,
._esp_hw_power_down = btdm_hw_mac_power_down_wrapper, ._esp_hw_power_down = btdm_hw_mac_power_down_wrapper,
._esp_hw_power_up = btdm_hw_mac_power_up_wrapper, ._esp_hw_power_up = btdm_hw_mac_power_up_wrapper,
._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper, ._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper,
@ -478,35 +486,44 @@ static inline void esp_bt_power_domain_off(void)
esp_wifi_bt_power_domain_off(); esp_wifi_bt_power_domain_off();
} }
static void interrupt_set_wrapper(int cpu_no, int intr_source, int intr_num, int intr_prio) static void btdm_intr_alloc(void *arg)
{ {
esp_rom_route_intr_matrix(cpu_no, intr_source, intr_num); btdm_isr_alloc_t *p = arg;
#if __riscv p->ret = esp_intr_alloc(p->source, p->flags, p->fn, p->arg, p->handle);
esprv_int_set_priority(intr_num, intr_prio); }
esprv_int_set_type(intr_num, 0);
static int interrupt_alloc_wrapper(int cpu_id, int source, intr_handler_t handler, void *arg, void **ret_handle)
{
btdm_isr_alloc_t p;
p.source = source;
p.flags = ESP_INTR_FLAG_LEVEL3 | ESP_INTR_FLAG_IRAM;
p.fn = handler;
p.arg = arg;
p.handle = (intr_handle_t *)ret_handle;
#if CONFIG_FREERTOS_UNICORE
btdm_intr_alloc(&p);
#else
esp_ipc_call_blocking(cpu_id, btdm_intr_alloc, &p);
#endif #endif
return p.ret;
} }
static void interrupt_clear_wrapper(int intr_source, int intr_num) static int interrupt_free_wrapper(void *handle)
{ {
return esp_intr_free((intr_handle_t)handle);
} }
static void interrupt_handler_set_wrapper(int n, intr_handler_t fn, void *arg) static int interrupt_enable_wrapper(void *handle)
{ {
esp_cpu_intr_set_handler(n, fn, arg); return esp_intr_enable((intr_handle_t)handle);
} }
static void interrupt_on_wrapper(int intr_num) static int interrupt_disable_wrapper(void *handle)
{ {
esp_cpu_intr_enable(1 << intr_num); return esp_intr_disable((intr_handle_t)handle);
} }
static void interrupt_off_wrapper(int intr_num) static void IRAM_ATTR global_interrupt_disable(void)
{
esp_cpu_intr_disable(1<<intr_num);
}
static void IRAM_ATTR interrupt_disable(void)
{ {
if (xPortInIsrContext()) { if (xPortInIsrContext()) {
portENTER_CRITICAL_ISR(&global_int_mux); portENTER_CRITICAL_ISR(&global_int_mux);
@ -515,7 +532,7 @@ static void IRAM_ATTR interrupt_disable(void)
} }
} }
static void IRAM_ATTR interrupt_restore(void) static void IRAM_ATTR global_interrupt_restore(void)
{ {
if (xPortInIsrContext()) { if (xPortInIsrContext()) {
portEXIT_CRITICAL_ISR(&global_int_mux); portEXIT_CRITICAL_ISR(&global_int_mux);

@ -1 +1 @@
Subproject commit 4b1338827fa19fbacc02dd9e46e76be2b0dd17a9 Subproject commit 1a086eab61e78fa243d67c33206ece4022129ee1

View File

@ -11,11 +11,10 @@ void esp_cpu_intr_get_desc(int core_id, int intr_num, esp_cpu_intr_desc_t *intr_
{ {
/* On the ESP32-C3, interrupt: /* On the ESP32-C3, interrupt:
* - 1 is for Wi-Fi * - 1 is for Wi-Fi
* - 5 and 8 for Bluetooth
* - 6 for "permanently disabled interrupt", named INT_MUX_DISABLED_INTNO in the interrupt allocator * - 6 for "permanently disabled interrupt", named INT_MUX_DISABLED_INTNO in the interrupt allocator
*/ */
// [TODO: IDF-2465] // [TODO: IDF-2465]
const uint32_t rsvd_mask = BIT(1) | BIT(5) | BIT(6) | BIT(8); const uint32_t rsvd_mask = BIT(1) | BIT(6);
intr_desc_ret->priority = 1; intr_desc_ret->priority = 1;
intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA; intr_desc_ret->type = ESP_CPU_INTR_TYPE_NA;

View File

@ -20,31 +20,6 @@ typedef struct {
} intr_desc_t; } intr_desc_t;
/**
* @brief Reserve the interrupts on the core where Bluetooth will run.
* The macro CONFIG_BT_CTRL_PINNED_TO_CORE is only defined if Bluetooth controller is enabled.
* It is set to the core where it will run.
*/
#ifdef CONFIG_BT_CTRL_PINNED_TO_CORE
#if CONFIG_BT_CTRL_PINNED_TO_CORE == 0
#define CORE_0_INTERRUPT_5 ESP_CPU_INTR_DESC_FLAG_RESVD
#define CORE_1_INTERRUPT_5 0
#define CORE_0_INTERRUPT_8 ESP_CPU_INTR_DESC_FLAG_RESVD
#define CORE_1_INTERRUPT_8 0
#elif CONFIG_BT_CTRL_PINNED_TO_CORE == 1
#define CORE_0_INTERRUPT_5 0
#define CORE_1_INTERRUPT_5 ESP_CPU_INTR_DESC_FLAG_RESVD
#define CORE_0_INTERRUPT_8 0
#define CORE_1_INTERRUPT_8 ESP_CPU_INTR_DESC_FLAG_RESVD
#endif
#else // Bluetooth not enabled
#define CORE_0_INTERRUPT_5 0
#define CORE_1_INTERRUPT_5 0
#define CORE_0_INTERRUPT_8 0
#define CORE_1_INTERRUPT_8 0
#endif
const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = { const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = {
/* Interrupt 0 reserved for WMAC (Wifi) */ /* Interrupt 0 reserved for WMAC (Wifi) */
#if CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0 #if CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0
@ -57,12 +32,10 @@ const static intr_desc_t intr_desc_table [SOC_CPU_INTR_NUM] = {
[3] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, [3] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } },
/* Interrupt 4 reserved for WBB */ /* Interrupt 4 reserved for WBB */
[4] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } }, [4] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { ESP_CPU_INTR_DESC_FLAG_RESVD, 0 } },
/* Interrupt 5 reserved for BT/BLE Controller */ [5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } },
[5] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_5, CORE_1_INTERRUPT_5 } },
[6] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, [6] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } },
[7] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, [7] = { 1, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } },
/* Interrupt 8 reserved for BT/BLE Controller */ [8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } },
[8] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { CORE_0_INTERRUPT_8, CORE_1_INTERRUPT_8 } },
[9] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } }, [9] = { 1, ESP_CPU_INTR_TYPE_LEVEL, { 0, 0 } },
[10] = { 1, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } }, [10] = { 1, ESP_CPU_INTR_TYPE_EDGE, { 0, 0 } },
[11] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } }, [11] = { 3, ESP_CPU_INTR_TYPE_NA, { ESP_CPU_INTR_DESC_FLAG_SPECIAL, ESP_CPU_INTR_DESC_FLAG_SPECIAL } },

View File

@ -1243,7 +1243,7 @@ r_rw_cryto_aes_cmac = 0x4000145c;
r_rw_v9_init_em_radio_table = 0x40001460; r_rw_v9_init_em_radio_table = 0x40001460;
r_rwble_sleep_enter = 0x40001468; r_rwble_sleep_enter = 0x40001468;
r_rwble_sleep_wakeup_end = 0x4000146c; r_rwble_sleep_wakeup_end = 0x4000146c;
r_rwbtdm_isr_wrapper = 0x40001470; /* r_rwbtdm_isr_wrapper = 0x40001470; */
r_rwip_active_check = 0x40001474; r_rwip_active_check = 0x40001474;
r_rwip_aes_encrypt = 0x40001478; r_rwip_aes_encrypt = 0x40001478;
r_rwip_assert = 0x4000147c; r_rwip_assert = 0x4000147c;

View File

@ -1493,7 +1493,7 @@ r_rw_cryto_aes_cmac = 0x40004cf8;
r_rw_v9_init_em_radio_table = 0x40004d04; r_rw_v9_init_em_radio_table = 0x40004d04;
r_rwble_sleep_enter = 0x40004d1c; r_rwble_sleep_enter = 0x40004d1c;
r_rwble_sleep_wakeup_end = 0x40004d28; r_rwble_sleep_wakeup_end = 0x40004d28;
r_rwbtdm_isr_wrapper = 0x40004d34; /* r_rwbtdm_isr_wrapper = 0x40004d34; */
r_rwip_active_check = 0x40004d40; r_rwip_active_check = 0x40004d40;
r_rwip_aes_encrypt = 0x40004d4c; r_rwip_aes_encrypt = 0x40004d4c;
r_rwip_assert = 0x40004d58; r_rwip_assert = 0x40004d58;

View File

@ -5,11 +5,11 @@ CPU 0 interrupt status:
2 1 Level Used: RTC_CORE 2 1 Level Used: RTC_CORE
3 1 Level Used: FROM_CPU_INTR0 3 1 Level Used: FROM_CPU_INTR0
4 1 Level Used: SYSTIMER_TARGET0_EDGE 4 1 Level Used: SYSTIMER_TARGET0_EDGE
5 * * Reserved 5 1 Level Used: TG0_WDT_LEVEL
6 * * Reserved 6 * * Reserved
7 1 Level Used: TG0_WDT_LEVEL 7 1 Level Used: UART0
8 * * Reserved 8 * * Free
9 1 Level Used: UART0 9 * * Free
10 * * Free 10 * * Free
11 * * Free 11 * * Free
12 * * Free 12 * * Free
@ -32,5 +32,4 @@ CPU 0 interrupt status:
29 * * Free 29 * * Free
30 * * Free 30 * * Free
31 * * Free 31 * * Free
Interrupts available for general use: 18 Interrupts available for general use: 20
Shared interrupts: 0