Porównaj commity

...

36 Commity

Autor SHA1 Wiadomość Data
mitchellcairns ace5266e76
Merge 45729f0897 into ea967cf2fb 2024-04-18 08:58:52 -07:00
Roland Dobai ea967cf2fb Merge branch 'docs/external_flash_5.2' into 'release/v5.2'
docs(idf_py): Describe the option to configure esptool.py with --extra-args (backport to v5.2)

See merge request espressif/esp-idf!30323
2024-04-18 01:17:43 +08:00
Radim Karniš b6b04bbeff docs(idf_py): Describe the option to configure esptool.py with --extra-args 2024-04-17 14:38:44 +02:00
Island 568b693493 Merge branch 'bugfix/ble_mesh_fsm_list_init_v5.2' into 'release/v5.2'
bugfix/ble_mesh_fsm_list_init (v5.2)

See merge request espressif/esp-idf!30282
2024-04-17 20:10:01 +08:00
David Čermák 806b14dd22 Merge branch 'update_mqtt_v5.2' into 'release/v5.2'
Update Mqtt client (v5.2)

See merge request espressif/esp-idf!30273
2024-04-17 20:08:23 +08:00
Wang Meng Yang 228f92211b Merge branch 'feat/set_get_lpclk_src_v5.2' into 'release/v5.2'
feat(ble): Added API to get low power clock source(v5.2)

See merge request espressif/esp-idf!30107
2024-04-17 18:01:47 +08:00
morris 61210271a8 Merge branch 'bugfix/improve_lp_uart_test_docs' into 'release/v5.2'
refactor(uart): add support to be able to test LP_UART port (v5.2)

See merge request espressif/esp-idf!30175
2024-04-17 17:46:48 +08:00
Rahul Tank 01902148da Merge branch 'fix/removed_termination_upon_sign_write_fail_v5.2' into 'release/v5.2'
fix(nimble): Removed Code for Termination Upon Signed Write Operation Failure (v5.2)

See merge request espressif/esp-idf!30276
2024-04-17 16:08:26 +08:00
luoxu 9bd8d5f860 fix(ble_mesh): rpr server and df bug fixed(10f7fdc1a9) 2024-04-17 11:09:54 +08:00
morris b60280e2cf Merge branch 'bugfix/dm9051_phy_axs_wait_v5.2' into 'release/v5.2'
fix(esp_eth): made access to PHY registers for DM9051 more robust (v5.2)

See merge request espressif/esp-idf!30279
2024-04-17 10:41:16 +08:00
Jiang Jiang Jian 8c52152369 Merge branch 'bugfix/fix_some_ble_bugs_cjh_v5.2' into 'release/v5.2'
Fixed some BT and BLE bugs 2404 (backport v5.2)

See merge request espressif/esp-idf!30258
2024-04-17 10:37:38 +08:00
morris f3ec76b75b Merge branch 'doc/auto_suspend_disabled_by_default_v5.2' into 'release/v5.2'
doc(flash): fix auto suspend enabled by default issue (v5.2)

See merge request espressif/esp-idf!30253
2024-04-17 10:03:56 +08:00
Ondrej Kosta 5c53238853 fix(esp_eth): made access to PHY registers for DM9051 more robust 2024-04-16 16:13:17 +02:00
Xiao Xufeng a255e67a84 doc(flash): fix auto suspend enabled by default issue 2024-04-16 20:49:31 +08:00
Sumeet Singh 234ad8cd1e fix(nimble): Removed code for termination upon signed write operation failure 2024-04-16 17:54:51 +05:30
Euripedes Rocha 3ba9de778e change(mqtt): Update esp-mqtt submodule
git log --oneline e6afdb4025fe018ae0add44e3c45249ea1974774..aa6f889fb4f6f743b3a550aa587713aabbdca1fc

Detailed description of the changes:
* fix: regard reason codes greater than 0x80 as failures.
  - See merge request espressif/esp-mqtt!205
  - See commit https://github.com/espressif/esp-mqtt/commit/e7b9aa5
* PR: Return on allocation failure
  - See merge request espressif/esp-mqtt!204
  - set last_retransmit to now when first connected (espressif/esp-mqtt@c06f154)
  - add return to faile_message, avoid segment fault (espressif/esp-mqtt@37478a9)
* Minor warning of unused variable
  - See merge request espressif/esp-mqtt!203
  - fix: Minor warning of unused variable (espressif/esp-mqtt@726e5f2)
* Cover the case for SOC without MAC address
  - See merge request espressif/esp-mqtt!202
  - fix: Cover the case for SOC without MAC address (espressif/esp-mqtt@5e3abd4)
* Make state and size atomic
  - See merge request espressif/esp-mqtt!199
  - feat: Make state and size atomic (espressif/esp-mqtt@891380b)
* fix: Adjust the log level on few messages to avoid cluthering the logs
  - See merge request espressif/esp-mqtt!201
  - See commit https://github.com/espressif/esp-mqtt/commit/5c17fc4
* fix: Make automatic client_id soc dependent
  - See merge request espressif/esp-mqtt!200
  - See commit https://github.com/espressif/esp-mqtt/commit/657a2ae
* Clarify data that users need to take care of lifetime.
  - See merge request espressif/esp-mqtt!197
  - docs: Clarify data that users need to take care of lifetime. (espressif/esp-mqtt@371f594)
* Update mqtt_client.h
  - See merge request espressif/esp-mqtt!198
  - add const char * to esp_mqtt_client_subscribe() generic macros (espressif/esp-mqtt@acdb66d)
* client: Report failure on timeout in mid-message timeout (GitHub PR)
  - See merge request espressif/esp-mqtt!165
  - Merges https://github.com/espressif/esp-mqtt/pull/232
  - client: Report failure on timeout in mid-message timeout (espressif/esp-mqtt@ddde502)
* fix: Move buffer initialization to set config
  - See merge request espressif/esp-mqtt!194
  - Closes https://github.com/espressif/esp-mqtt/issues/267
  - See commit https://github.com/espressif/esp-mqtt/commit/ea0df31
* Fix check for message creation when processing publish
  - See merge request espressif/esp-mqtt!195
  - fix: Deliver publish verifies if message was created only for QoS >0
        (espressif/esp-mqtt@6780056)
2024-04-16 13:43:47 +02:00
chenjianhua 57de44f45b feat(bt): Update bt lib for ESP32-C3 and ESP32-S3(c23ab4c)
- Support QA test vendor HCI command and event
2024-04-16 11:33:19 +08:00
baohongde 41aa38ddf7 fix(ble/controller): Fixed LoadProhibited after bluetooth deinit 2024-04-16 11:33:11 +08:00
chenjianhua b69a5fe27c fix(bt): Update bt lib for ESP32-C3 and ESP32-S3(5274796)
- Fixed extended uncoded and coded scan scheduling
- Add config for channel assessment and ping procedure
- Clear random address for extended advertising
- Add periodic advertising list check
- Fixed periodic advertising data setting with zero length
2024-04-16 11:33:05 +08:00
baohongde ee47bebfad feat(ble/controller): Add coexist schm for BLE 2024-04-16 11:32:54 +08:00
chenjianhua 1265a44c17 feat(bt): Update bt lib for ESP32(e314148)
- Support QA test vendor HCI command and event
2024-04-16 11:32:35 +08:00
zhanghaipeng 51f7ddc223 fix(bt/controller): Update bt lib for ESP32(5838b68)
- Fixed BLE scan assert
 - Fixed assert(10,0) in lld_pdu
 - Add BLE scan backoff in menuconfig
2024-04-16 11:32:22 +08:00
Jin Cheng 2377b40784 fix(bt/controller): Use embedded assembly to get access to DPORT registers 2024-04-16 11:32:09 +08:00
gaoxu 1df5f07eee docs(uart): update lp uart uart programming guide 2024-04-15 19:39:38 +08:00
Song Ruo Jing c55a07bf57 refactor(uart): add support to be able to test LP_UART port
Increase LP_UART_EMPTY_THRESH_DEFAULT value to 4. The original value
could cause the FIFO become empty before filling next data into the FIFO
when the buadrate is high. TX_DONE interrupt would raise before actual
transmission complete in such case.
2024-04-15 19:39:30 +08:00
xiongweichao a5662dc290 feat(ble): Added API to get low power clock source 2024-04-08 19:25:13 +08:00
Mitch Cairns 45729f0897 Merge branch 'release/v5.2' of https://github.com/mitchellcairns/esp-idf into release/v5.2 2023-12-28 13:34:22 -08:00
Mitch Cairns 151ac2efbf Update Kconfig.in
Add BT HID task size config option
Update esp_hid_common.h

add #ifndef BT_HID_DEVICE_TASK_SIZE to set a default
Update ble_hidd.c

add defined BT_HID_DEVICE_TASK_SIZE
Update bt_hidd.c

Add defined BT_HID_DEVICE_TASK_SIZE
Update esp_hid_common.h

Increase default to 4096
Update Kconfig.in

Update default HID task size to 4096 bytes
Implement DID for Bluetooth Classic HID Device

- Add necessary attributes that get passed along from the esp_hidd component

Remove unneeded comment
2023-12-28 13:34:04 -08:00
Mitch Cairns db15af1aa8 Remove unneeded comment 2023-12-28 13:25:22 -08:00
Mitch Cairns 795edfdbf5 Implement DID for Bluetooth Classic HID Device
- Add necessary attributes that get passed along from the esp_hidd component
2023-12-28 12:20:33 -08:00
mitchellcairns 73616f8aab
Update Kconfig.in
Update default HID task size to 4096 bytes
2023-12-28 00:07:23 -08:00
mitchellcairns 35021387d2
Update esp_hid_common.h
Increase default to 4096
2023-12-28 00:03:49 -08:00
mitchellcairns 730919f274
Update bt_hidd.c
Add defined BT_HID_DEVICE_TASK_SIZE
2023-12-28 00:03:12 -08:00
mitchellcairns b86d322c3d
Update ble_hidd.c
add defined BT_HID_DEVICE_TASK_SIZE
2023-12-28 00:02:49 -08:00
mitchellcairns 3ccbb041e3
Update esp_hid_common.h
add #ifndef BT_HID_DEVICE_TASK_SIZE to set a default
2023-12-28 00:01:58 -08:00
mitchellcairns 9a36745d25
Update Kconfig.in
Add BT HID task size config option
2023-12-27 23:58:59 -08:00
51 zmienionych plików z 904 dodań i 435 usunięć

Wyświetl plik

@ -172,7 +172,7 @@ config BTDM_CTRL_PINNED_TO_CORE
choice BTDM_CTRL_HCI_MODE_CHOICE
prompt "HCI mode"
help
Speicify HCI mode as VHCI or UART(H4)
Specify HCI mode as VHCI or UART(H4)
config BTDM_CTRL_HCI_MODE_VHCI
bool "VHCI"
@ -398,6 +398,14 @@ config BTDM_CTRL_FULL_SCAN_SUPPORTED
The full scan function is mainly used to provide BLE scan performance.
This is required for scenes with high scan performance requirements, such as BLE Mesh scenes.
config BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX
bool "Disable active scan backoff"
default n
help
Disable active scan backoff. The bluetooth spec requires that scanners should run a backoff procedure to
minimize collision of scan request PDUs from nultiple scanners. If scan backoff is disabled, in active
scanning, scan request PDU will be sent every time when HW receives scannable ADV PDU.
config BTDM_BLE_ADV_REPORT_FLOW_CTRL_SUPP
bool "BLE adv report flow control supported"
depends on (BTDM_CTRL_MODE_BTDM || BTDM_CTRL_MODE_BLE_ONLY)

Wyświetl plik

@ -23,7 +23,7 @@ config BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB
default 0
help
BLE ACL buffer have two methods to be allocated. One is persistent allocating
(alloate when controller initialise, never free until controller de-initialise)
(allocate when controller initialise, never free until controller de-initialise)
another is dynamically allocating (allocate before TX and free after TX).
choice BT_CTRL_PINNED_TO_CORE_CHOICE
@ -72,11 +72,11 @@ config BT_CTRL_HCI_TL
HCI mode as VHCI or UART(H4)
config BT_CTRL_ADV_DUP_FILT_MAX
int "The maxinum number of 5.0 extend duplicate scan filter"
int "The maximum number of 5.0 extend duplicate scan filter"
range 1 500
default 30
help
The maxinum number of suplicate scan filter
The maximum number of suplicate scan filter
choice BT_BLE_CCA_MODE
prompt "BLE CCA mode"
@ -475,3 +475,17 @@ config BT_BLE_ADV_DATA_LENGTH_ZERO_AUX
When this option is enabled, auxiliary packets will be present in the events of
'Non-Connectable and Non-Scannable' regardless of whether the advertising length is 0.
If this option is not enabled, auxiliary packets will only be present when the advertising length is not 0.
config BT_CTRL_CHAN_ASS_EN
bool "Enable channel assessment"
default y
help
If this option is enabled, The Controller will records the communication quality
for each channel and then start a timer to check and update the channel map every 4 seconds.
config BT_CTRL_LE_PING_EN
bool "Enable LE Ping procedure"
default y
help
If this option is disabled, The Controller will not start the LE authenticated payload timer.
This option is used for some compatibility problems related to LE ping procedure.

Wyświetl plik

@ -64,6 +64,7 @@
// wakeup request sources
enum {
BTDM_ASYNC_WAKEUP_SRC_VHCI = 0,
BTDM_ASYNC_WAKEUP_REQ_COEX,
BTDM_ASYNC_WAKEUP_SRC_DISA,
BTDM_ASYNC_WAKEUP_SRC_TMR,
BTDM_ASYNC_WAKEUP_SRC_MAX,
@ -73,12 +74,12 @@ enum {
typedef union {
struct {
uint32_t enable : 1; // whether low power mode is required
uint32_t lpclk_sel : 2; // low power clock source
uint32_t lpclk_sel : 3; // low power clock source
uint32_t mac_bb_pd : 1; // whether hardware(MAC, BB) force-power-down is required during sleep
uint32_t wakeup_timer_required : 1; // whether system timer is needed
uint32_t no_light_sleep : 1; // do not allow system to enter light sleep after bluetooth is enabled
uint32_t main_xtal_pu : 1; // power up main XTAL
uint32_t reserved : 25; // reserved
uint32_t reserved : 24; // reserved
};
uint32_t val;
} btdm_lpcntl_t;
@ -110,7 +111,7 @@ do{\
} while(0)
#define OSI_FUNCS_TIME_BLOCKING 0xffffffff
#define OSI_VERSION 0x00010007
#define OSI_VERSION 0x00010008
#define OSI_MAGIC_VALUE 0xFADEBEAD
/* Types definition
@ -184,8 +185,12 @@ struct osi_funcs_t {
void (* _btdm_sleep_exit_phase3)(void); /* called from task */
void (* _coex_wifi_sleep_set)(bool sleep);
int (* _coex_core_ble_conn_dyn_prio_get)(bool *low, bool *high);
int (* _coex_schm_register_btdm_callback)(void *callback);
void (* _coex_schm_status_bit_set)(uint32_t type, uint32_t status);
void (* _coex_schm_status_bit_clear)(uint32_t type, uint32_t status);
uint32_t (* _coex_schm_interval_get)(void);
uint8_t (* _coex_schm_curr_period_get)(void);
void *(* _coex_schm_curr_phase_get)(void);
void (* _interrupt_on)(int intr_num);
void (* _interrupt_off)(int intr_num);
void (* _esp_hw_power_down)(void);
@ -193,6 +198,8 @@ struct osi_funcs_t {
void (* _ets_backup_dma_copy)(uint32_t reg, uint32_t mem_addr, uint32_t num, bool to_rem);
void (* _ets_delay_us)(uint32_t us);
void (* _btdm_rom_table_ready)(void);
bool (* _coex_bt_wakeup_request)(void);
void (* _coex_bt_wakeup_request_end)(void);
};
@ -306,14 +313,20 @@ static void btdm_sleep_enter_phase1_wrapper(uint32_t lpcycles);
static void btdm_sleep_enter_phase2_wrapper(void);
static void btdm_sleep_exit_phase3_wrapper(void);
static void coex_wifi_sleep_set_hook(bool sleep);
static int coex_schm_register_btdm_callback_wrapper(void *callback);
static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status);
static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status);
static uint32_t coex_schm_interval_get_wrapper(void);
static uint8_t coex_schm_curr_period_get_wrapper(void);
static void * coex_schm_curr_phase_get_wrapper(void);
static void interrupt_on_wrapper(int intr_num);
static void interrupt_off_wrapper(int intr_num);
static void btdm_hw_mac_power_up_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_funcs_table_ready_wrapper(void);
static bool coex_bt_wakeup_request(void);
static void coex_bt_wakeup_request_end(void);
static void btdm_slp_tmr_callback(void *arg);
@ -371,8 +384,12 @@ static const struct osi_funcs_t osi_funcs_ro = {
._btdm_sleep_exit_phase3 = btdm_sleep_exit_phase3_wrapper,
._coex_wifi_sleep_set = coex_wifi_sleep_set_hook,
._coex_core_ble_conn_dyn_prio_get = NULL,
._coex_schm_register_btdm_callback = coex_schm_register_btdm_callback_wrapper,
._coex_schm_status_bit_set = coex_schm_status_bit_set_wrapper,
._coex_schm_status_bit_clear = coex_schm_status_bit_clear_wrapper,
._coex_schm_interval_get = coex_schm_interval_get_wrapper,
._coex_schm_curr_period_get = coex_schm_curr_period_get_wrapper,
._coex_schm_curr_phase_get = coex_schm_curr_phase_get_wrapper,
._interrupt_on = interrupt_on_wrapper,
._interrupt_off = interrupt_off_wrapper,
._esp_hw_power_down = btdm_hw_mac_power_down_wrapper,
@ -380,6 +397,8 @@ static const struct osi_funcs_t osi_funcs_ro = {
._ets_backup_dma_copy = btdm_backup_dma_copy_wrapper,
._ets_delay_us = esp_rom_delay_us,
._btdm_rom_table_ready = btdm_funcs_table_ready_wrapper,
._coex_bt_wakeup_request = coex_bt_wakeup_request,
._coex_bt_wakeup_request_end = coex_bt_wakeup_request_end,
};
static DRAM_ATTR struct osi_funcs_t *osi_funcs_p;
@ -400,7 +419,7 @@ static DRAM_ATTR uint8_t btdm_lpcycle_us_frac = 0;
// semaphore used for blocking VHCI API to wait for controller to wake up
static DRAM_ATTR QueueHandle_t s_wakeup_req_sem = NULL;
// wakeup timer
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr;
static DRAM_ATTR esp_timer_handle_t s_btdm_slp_tmr = NULL;
#ifdef CONFIG_PM_ENABLE
static DRAM_ATTR esp_pm_lock_handle_t s_pm_lock;
@ -853,6 +872,22 @@ static bool async_wakeup_request(int event)
semphr_take_wrapper(s_wakeup_req_sem, OSI_FUNCS_TIME_BLOCKING);
}
break;
case BTDM_ASYNC_WAKEUP_REQ_COEX:
if (!btdm_power_state_active()) {
do_wakeup_request = true;
#if CONFIG_PM_ENABLE
if (s_lp_stat.pm_lock_released) {
esp_pm_lock_acquire(s_pm_lock);
s_lp_stat.pm_lock_released = 0;
}
#endif
btdm_wakeup_request();
if (s_lp_cntl.wakeup_timer_required && s_lp_stat.wakeup_timer_started) {
esp_timer_stop(s_btdm_slp_tmr);
s_lp_stat.wakeup_timer_started = 0;
}
}
default:
break;
}
@ -872,6 +907,9 @@ static void async_wakeup_request_end(int event)
case BTDM_ASYNC_WAKEUP_SRC_DISA:
allow_to_sleep = true;
break;
case BTDM_ASYNC_WAKEUP_REQ_COEX:
allow_to_sleep = false;
break;
default:
allow_to_sleep = true;
break;
@ -891,18 +929,25 @@ static void btdm_funcs_table_ready_wrapper(void)
#endif
}
static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
bool bt_async_wakeup_request(void)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_schm_status_bit_set(type, status);
#endif
return async_wakeup_request(BTDM_ASYNC_WAKEUP_SRC_VHCI);
}
static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status)
void bt_wakeup_request_end(void)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_schm_status_bit_clear(type, status);
#endif
async_wakeup_request_end(BTDM_ASYNC_WAKEUP_SRC_VHCI);
}
static bool coex_bt_wakeup_request(void)
{
return async_wakeup_request(BTDM_ASYNC_WAKEUP_REQ_COEX);
}
static void coex_bt_wakeup_request_end(void)
{
async_wakeup_request_end(BTDM_ASYNC_WAKEUP_REQ_COEX);
return;
}
bool esp_vhci_host_check_send_available(void)
@ -1112,6 +1157,147 @@ static void IRAM_ATTR btdm_mac_bb_power_up_cb(void)
}
#endif
// init low-power control resources
static esp_err_t btdm_low_power_mode_init(esp_bt_controller_config_t *cfg)
{
esp_err_t err = ESP_OK;
do {
// set default values for global states or resources
s_lp_stat.val = 0;
s_lp_cntl.val = 0;
s_lp_cntl.main_xtal_pu = 0;
s_wakeup_req_sem = NULL;
s_btdm_slp_tmr = NULL;
// configure and initialize resources
s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
s_lp_cntl.lpclk_sel = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? cfg->sleep_clock : ESP_BT_SLEEP_CLOCK_MAIN_XTAL;
s_lp_cntl.no_light_sleep = 0;
if (s_lp_cntl.enable) {
#if CONFIG_MAC_BB_PD
if (!btdm_deep_sleep_mem_init()) {
err = ESP_ERR_NO_MEM;
break;
}
s_lp_cntl.mac_bb_pd = 1;
#endif
#ifdef CONFIG_PM_ENABLE
s_lp_cntl.wakeup_timer_required = 1;
#endif
// async wakeup semaphore for VHCI
s_wakeup_req_sem = semphr_create_wrapper(1, 0);
if (s_wakeup_req_sem == NULL) {
err = ESP_ERR_NO_MEM;
break;
}
btdm_vnd_offload_task_register(BTDM_VND_OL_SIG_WAKEUP_TMR, btdm_sleep_exit_phase0);
if (s_lp_cntl.wakeup_timer_required) {
esp_timer_create_args_t create_args = {
.callback = btdm_slp_tmr_callback,
.arg = NULL,
.name = "btSlp",
};
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
break;
}
}
// set default bluetooth sleep clock cycle and its fractional bits
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) { // External 32 kHz XTAL
// check whether or not EXT_CRYS is working
if (rtc_clk_slow_src_get() != SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
s_lp_cntl.lpclk_sel = ESP_BT_SLEEP_CLOCK_MAIN_XTAL;
#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
s_lp_cntl.no_light_sleep = 1;
#endif
}
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_RTC_SLOW) { // Internal 136kHz RC oscillator
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
ESP_LOGW(BT_LOG_TAG, "Internal 136kHz RC oscillator. The accuracy of this clock is a lot larger than 500ppm which is "
"required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.");
} else {
ESP_LOGW(BT_LOG_TAG, "Internal 136kHz RC oscillator not detected.");
assert(0);
}
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) {
ESP_LOGI(BT_LOG_TAG, "Bluetooth will use main XTAL as Bluetooth sleep clock.");
#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
s_lp_cntl.no_light_sleep = 1;
#endif
}
} else {
s_lp_cntl.no_light_sleep = 1;
}
bool select_src_ret __attribute__((unused));
bool set_div_ret __attribute__((unused));
if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) {
#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON));
s_lp_cntl.main_xtal_pu = 1;
#endif
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() / MHZ);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 1 << (btdm_lpcycle_us_frac);
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_EXT_32K_XTAL) {
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
set_div_ret = btdm_lpclk_set_div(0);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
(1000000 >> (15 - RTC_CLK_CAL_FRACT));
assert(btdm_lpcycle_us != 0);
} else if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_RTC_SLOW) {
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
set_div_ret = btdm_lpclk_set_div(0);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = esp_clk_slowclk_cal_get();
} else {
err = ESP_ERR_INVALID_ARG;
break;
}
#if CONFIG_SW_COEXIST_ENABLE
coex_update_lpclk_interval();
#endif
#ifdef CONFIG_PM_ENABLE
if (s_lp_cntl.no_light_sleep) {
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
break;
}
ESP_LOGW(BT_LOG_TAG, "light sleep mode will not be able to apply when bluetooth is enabled.");
}
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
break;
} else {
s_lp_stat.pm_lock_released = 1;
}
#endif
} while (0);
return err;
}
esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void)
{
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED &&
btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
return ESP_BT_SLEEP_CLOCK_NONE;
}
return s_lp_cntl.lpclk_sel;
}
esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
{
esp_err_t err = ESP_FAIL;
@ -1147,6 +1333,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 enabled but sleep clock not configured");
return ESP_ERR_INVALID_ARG;
}
if (cfg->sleep_clock > ESP_BT_SLEEP_CLOCK_RTC_SLOW) {
ESP_LOGE(BT_LOG_TAG, "SLEEP_MODE_1 is enabled but this sleep clock is not supported");
return ESP_ERR_INVALID_ARG;
}
}
// overwrite some parameters
@ -1172,133 +1362,10 @@ esp_err_t esp_bt_controller_init(esp_bt_controller_config_t *cfg)
ESP_LOGI(BT_LOG_TAG, "BT controller compile version [%s]", btdm_controller_get_compile_version());
// init low-power control resources
do {
// set default values for global states or resources
s_lp_stat.val = 0;
s_lp_cntl.val = 0;
s_lp_cntl.main_xtal_pu = 0;
s_wakeup_req_sem = NULL;
s_btdm_slp_tmr = NULL;
// configure and initialize resources
s_lp_cntl.enable = (cfg->sleep_mode == ESP_BT_SLEEP_MODE_1) ? 1 : 0;
s_lp_cntl.no_light_sleep = 0;
if (s_lp_cntl.enable) {
#if CONFIG_MAC_BB_PD
if (!btdm_deep_sleep_mem_init()) {
err = ESP_ERR_NO_MEM;
goto error;
}
s_lp_cntl.mac_bb_pd = 1;
#endif
#ifdef CONFIG_PM_ENABLE
s_lp_cntl.wakeup_timer_required = 1;
#endif
// async wakeup semaphore for VHCI
s_wakeup_req_sem = semphr_create_wrapper(1, 0);
if (s_wakeup_req_sem == NULL) {
err = ESP_ERR_NO_MEM;
goto error;
}
btdm_vnd_offload_task_register(BTDM_VND_OL_SIG_WAKEUP_TMR, btdm_sleep_exit_phase0);
}
if (s_lp_cntl.wakeup_timer_required) {
esp_timer_create_args_t create_args = {
.callback = btdm_slp_tmr_callback,
.arg = NULL,
.name = "btSlp",
};
if ((err = esp_timer_create(&create_args, &s_btdm_slp_tmr)) != ESP_OK) {
goto error;
}
}
// set default bluetooth sleep clock cycle and its fractional bits
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 2 << (btdm_lpcycle_us_frac);
// set default bluetooth sleep clock source
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL; // set default value
#if CONFIG_BT_CTRL_LPCLK_SEL_EXT_32K_XTAL
// check whether or not EXT_CRYS is working
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_XTAL32K) {
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_XTAL32K; // External 32 kHz XTAL
} else {
ESP_LOGW(BT_LOG_TAG, "32.768kHz XTAL not detected, fall back to main XTAL as Bluetooth sleep clock");
#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
s_lp_cntl.no_light_sleep = 1;
#endif
}
#elif (CONFIG_BT_CTRL_LPCLK_SEL_MAIN_XTAL)
ESP_LOGI(BT_LOG_TAG, "Bluetooth will use main XTAL as Bluetooth sleep clock.");
#if !CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
s_lp_cntl.no_light_sleep = 1;
#endif
#elif (CONFIG_BT_CTRL_LPCLK_SEL_RTC_SLOW)
// check whether or not internal 150 kHz RC oscillator is working
if (rtc_clk_slow_src_get() == SOC_RTC_SLOW_CLK_SRC_RC_SLOW) {
s_lp_cntl.lpclk_sel = BTDM_LPCLK_SEL_RTC_SLOW; // Internal 150 kHz RC oscillator
ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC osciallator. The accuracy of this clock is a lot larger than 500ppm which is "
"required in Bluetooth communication, so don't select this option in scenarios such as BLE connection state.");
} else {
ESP_LOGW(BT_LOG_TAG, "Internal 150kHz RC oscillator not detected.");
assert(0);
}
#endif
bool select_src_ret __attribute__((unused));
bool set_div_ret __attribute__((unused));
if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON));
s_lp_cntl.main_xtal_pu = 1;
#endif
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL);
set_div_ret = btdm_lpclk_set_div(esp_clk_xtal_freq() / MHZ);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = 1 << (btdm_lpcycle_us_frac);
} else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL32K) {
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_XTAL32K);
set_div_ret = btdm_lpclk_set_div(0);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = (RTC_CLK_CAL_FRACT > 15) ? (1000000 << (RTC_CLK_CAL_FRACT - 15)) :
(1000000 >> (15 - RTC_CLK_CAL_FRACT));
assert(btdm_lpcycle_us != 0);
} else if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_RTC_SLOW) {
select_src_ret = btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
set_div_ret = btdm_lpclk_set_div(0);
assert(select_src_ret && set_div_ret);
btdm_lpcycle_us_frac = RTC_CLK_CAL_FRACT;
btdm_lpcycle_us = esp_clk_slowclk_cal_get();
} else {
err = ESP_ERR_INVALID_ARG;
goto error;
}
#if CONFIG_SW_COEXIST_ENABLE
coex_update_lpclk_interval();
#endif
#ifdef CONFIG_PM_ENABLE
if (s_lp_cntl.no_light_sleep) {
if ((err = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "btLS", &s_light_sleep_pm_lock)) != ESP_OK) {
err = ESP_ERR_NO_MEM;
goto error;
}
ESP_LOGW(BT_LOG_TAG, "light sleep mode will not be able to apply when bluetooth is enabled.");
}
if ((err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "bt", &s_pm_lock)) != ESP_OK) {
err = ESP_ERR_NO_MEM;
goto error;
} else {
s_lp_stat.pm_lock_released = 1;
}
#endif
} while (0);
if ((err = btdm_low_power_mode_init(cfg)) != ESP_OK) {
ESP_LOGE(BT_LOG_TAG, "Low power module initialization failed");
goto error;
}
#if CONFIG_SW_COEXIST_ENABLE
coex_init();
@ -1336,69 +1403,70 @@ esp_err_t esp_bt_controller_deinit(void)
return ESP_OK;
}
// deinit low power control resources
static void btdm_low_power_mode_deinit(void)
{
#if CONFIG_MAC_BB_PD
if (s_lp_cntl.mac_bb_pd) {
btdm_deep_sleep_mem_deinit();
s_lp_cntl.mac_bb_pd = 0;
}
#endif
#ifdef CONFIG_PM_ENABLE
if (s_lp_cntl.no_light_sleep) {
if (s_light_sleep_pm_lock != NULL) {
esp_pm_lock_delete(s_light_sleep_pm_lock);
s_light_sleep_pm_lock = NULL;
}
}
if (s_pm_lock != NULL) {
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
s_lp_stat.pm_lock_released = 0;
}
#endif
if (s_lp_cntl.wakeup_timer_required && s_btdm_slp_tmr != NULL) {
if (s_lp_stat.wakeup_timer_started) {
esp_timer_stop(s_btdm_slp_tmr);
}
s_lp_stat.wakeup_timer_started = 0;
esp_timer_delete(s_btdm_slp_tmr);
s_btdm_slp_tmr = NULL;
}
if (s_lp_cntl.enable) {
btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
if (s_wakeup_req_sem != NULL) {
semphr_delete_wrapper(s_wakeup_req_sem);
s_wakeup_req_sem = NULL;
}
}
if (s_lp_cntl.lpclk_sel == ESP_BT_SLEEP_CLOCK_MAIN_XTAL) {
#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
if (s_lp_cntl.main_xtal_pu) {
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF));
s_lp_cntl.main_xtal_pu = 0;
}
#endif
btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
btdm_lpclk_set_div(0);
#if CONFIG_SW_COEXIST_ENABLE
coex_update_lpclk_interval();
#endif
}
btdm_lpcycle_us = 0;
}
static void bt_controller_deinit_internal(void)
{
periph_module_disable(PERIPH_BT_MODULE);
// deinit low power control resources
do {
#if CONFIG_MAC_BB_PD
if (s_lp_cntl.mac_bb_pd) {
btdm_deep_sleep_mem_deinit();
s_lp_cntl.mac_bb_pd = 0;
}
#endif
#ifdef CONFIG_PM_ENABLE
if (s_lp_cntl.no_light_sleep) {
if (s_light_sleep_pm_lock != NULL) {
esp_pm_lock_delete(s_light_sleep_pm_lock);
s_light_sleep_pm_lock = NULL;
}
}
if (s_pm_lock != NULL) {
esp_pm_lock_delete(s_pm_lock);
s_pm_lock = NULL;
s_lp_stat.pm_lock_released = 0;
}
#endif
if (s_lp_cntl.wakeup_timer_required) {
if (s_lp_stat.wakeup_timer_started) {
esp_timer_stop(s_btdm_slp_tmr);
}
s_lp_stat.wakeup_timer_started = 0;
esp_timer_delete(s_btdm_slp_tmr);
s_btdm_slp_tmr = NULL;
}
if (s_lp_cntl.enable) {
btdm_vnd_offload_task_deregister(BTDM_VND_OL_SIG_WAKEUP_TMR);
if (s_wakeup_req_sem != NULL) {
semphr_delete_wrapper(s_wakeup_req_sem);
s_wakeup_req_sem = NULL;
}
}
if (s_lp_cntl.lpclk_sel == BTDM_LPCLK_SEL_XTAL) {
#ifdef CONFIG_BT_CTRL_MAIN_XTAL_PU_DURING_LIGHT_SLEEP
if (s_lp_cntl.main_xtal_pu) {
ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF));
s_lp_cntl.main_xtal_pu = 0;
}
#endif
btdm_lpclk_select_src(BTDM_LPCLK_SEL_RTC_SLOW);
btdm_lpclk_set_div(0);
#if CONFIG_SW_COEXIST_ENABLE
coex_update_lpclk_interval();
#endif
}
btdm_lpcycle_us = 0;
} while (0);
btdm_low_power_mode_deinit();
esp_bt_power_domain_off();
#if CONFIG_MAC_BB_PD
@ -1677,4 +1745,55 @@ static void coex_wifi_sleep_set_hook(bool sleep)
{
}
static int coex_schm_register_btdm_callback_wrapper(void *callback)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_register_callback(COEX_SCHM_CALLBACK_TYPE_BT, callback);
#else
return 0;
#endif
}
static void coex_schm_status_bit_clear_wrapper(uint32_t type, uint32_t status)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_schm_status_bit_clear(type, status);
#endif
}
static void coex_schm_status_bit_set_wrapper(uint32_t type, uint32_t status)
{
#if CONFIG_SW_COEXIST_ENABLE
coex_schm_status_bit_set(type, status);
#endif
}
static uint32_t coex_schm_interval_get_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_interval_get();
#else
return 0;
#endif
}
static uint8_t coex_schm_curr_period_get_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_curr_period_get();
#else
return 1;
#endif
}
static void * coex_schm_curr_phase_get_wrapper(void)
{
#if CONFIG_SW_COEXIST_ENABLE
return coex_schm_curr_phase_get();
#else
return NULL;
#endif
}
#endif /* CONFIG_BT_ENABLED */

@ -1 +1 @@
Subproject commit 889c1149140d330ad173b863a91b667d9f62b853
Subproject commit 44341b15e58792946cc65ed8d4483929194d182f

@ -1 +1 @@
Subproject commit e5c0f7256ecf5b5f8eb28c1793051a6b88f95124
Subproject commit 76ed4114ee7d081435a3c65793b4c8eb1dfaf199

@ -1 +1 @@
Subproject commit 41bf5fc0926fd6d3fb39cb5107e97f2fc6aed7e5
Subproject commit 4934ca903807dd74f7f808dadcd9a478e18fc6c3

Wyświetl plik

@ -144,6 +144,13 @@ config BT_HID_DEVICE_ENABLED
help
This enables the BT HID Device
config BT_HID_DEVICE_TASK_SIZE
int "Bluetooth HID event (callback to application) task stack size"
depends on BT_HID_DEVICE_ENABLED
default 4096
help
This selects the esp_hid task size
config BT_BLE_ENABLED
bool "Bluetooth Low Energy"
depends on BT_BLUEDROID_ENABLED

Wyświetl plik

@ -98,6 +98,12 @@ typedef struct {
uint8_t subclass; /*!< HID device subclass */
uint8_t *desc_list; /*!< HID descriptor list */
int desc_list_len; /*!< size in bytes of HID descriptor list */
// DID Profile SDP
uint16_t vendor_id; /*!< HID Vendor ID */
uint16_t product_id; /*!< HID Product ID */
uint16_t version; /*!< HID Product Version */
uint8_t vendor_id_source; /*!< HID Country Code */
} esp_hidd_app_param_t;
/**

Wyświetl plik

@ -175,6 +175,16 @@ void bta_hd_register_act(tBTA_HD_DATA *p_data)
p_app_data->subclass, p_app_data->d_len, p_app_data->d_data);
bta_sys_add_uuid(UUID_SERVCLASS_HUMAN_INTERFACE);
// Set DID Profile SDP Record
tBTA_DI_RECORD bqb_device_info;
bqb_device_info.vendor = p_app_data->vendor_id;
bqb_device_info.vendor_id_source = p_app_data->vendor_id_source;
bqb_device_info.product = p_app_data->product_id;
bqb_device_info.version = p_app_data->version;
bqb_device_info.primary_record = TRUE;
BTA_DmSetLocalDiRecord(&bqb_device_info, &bta_hd_cb.sdp_handle);
HID_DevSetIncomingQos(p_app_data->in_qos.service_type, p_app_data->in_qos.token_rate,
p_app_data->in_qos.token_bucket_size, p_app_data->in_qos.peak_bandwidth,
p_app_data->in_qos.access_latency, p_app_data->in_qos.delay_variation);

Wyświetl plik

@ -114,6 +114,13 @@ extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO *p_app_info, tBTA_HD_QOS_INFO *p_
p_buf->subclass = p_app_info->subclass;
p_buf->d_len = p_app_info->descriptor.dl_len;
memcpy(p_buf->d_data, p_app_info->descriptor.dsc_list, p_app_info->descriptor.dl_len);
// copy DID profile SDP info
p_buf->vendor_id = p_app_info->vendor_id;
p_buf->product_id = p_app_info->product_id;
p_buf->version = p_app_info->version;
p_buf->vendor_id_source = p_app_info->vendor_id_source;
// copy qos data as-is
memcpy(&p_buf->in_qos, p_in_qos, sizeof(tBTA_HD_QOS_INFO));
memcpy(&p_buf->out_qos, p_out_qos, sizeof(tBTA_HD_QOS_INFO));

Wyświetl plik

@ -75,6 +75,13 @@ typedef struct {
uint8_t subclass;
uint16_t d_len;
uint8_t d_data[BTA_HD_APP_DESCRIPTOR_LEN];
// DID SDP Information (Device Information)
uint16_t vendor_id;
uint16_t product_id;
uint16_t version;
uint8_t vendor_id_source;
tBTA_HD_QOS_INFO in_qos;
tBTA_HD_QOS_INFO out_qos;
} tBTA_HD_REGISTER_APP;

Wyświetl plik

@ -69,6 +69,13 @@ typedef struct {
char *p_description;
char *p_provider;
uint8_t subclass;
// SDP Idenification info
uint16_t vendor_id; // 0x0201
uint16_t product_id; // 0x0202
uint16_t version; // 0x0203
uint8_t vendor_id_source; // 0x0205
tBTA_HD_DEV_DESCR descriptor;
} tBTA_HD_APP_INFO;

Wyświetl plik

@ -341,6 +341,13 @@ static void btc_hd_register_app(esp_hidd_app_param_t *p_app_param, esp_hidd_qos_
btc_hd_cb.out_qos.access_latency = p_out_qos->access_latency;
btc_hd_cb.out_qos.delay_variation = p_out_qos->delay_variation;
// Copy SDP record information for DID (Device Identification Profile)
btc_hd_cb.app_info.vendor_id = p_app_param->vendor_id;
btc_hd_cb.app_info.product_id = p_app_param->product_id;
btc_hd_cb.app_info.version = p_app_param->version;
btc_hd_cb.app_info.vendor_id_source = p_app_param->vendor_id_source;
BTA_HdRegisterApp(&btc_hd_cb.app_info, &btc_hd_cb.in_qos, &btc_hd_cb.out_qos);
} while(0);

@ -1 +1 @@
Subproject commit 0a7f98cdf001a1f5d9be185f57d099bd5c852f31
Subproject commit acbe4fe3219cb7ce677be1aa2c4142f308ea4958

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -50,7 +50,7 @@ extern "C" {
#endif //CONFIG_BT_ENABLED
#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20221207
#define ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL 0x20240315
/**
* @brief Bluetooth mode for controller enable/disable
@ -167,6 +167,12 @@ the adv packet will be discarded until the memory is restored. */
#define BTDM_CONTROLLER_SCO_DATA_PATH_HCI 0 // SCO data is routed to HCI
#define BTDM_CONTROLLER_SCO_DATA_PATH_PCM 1 // SCO data path is PCM
#ifdef CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX
#define BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX CONFIG_BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX
#else
#define BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX 0
#endif
#define BT_CONTROLLER_INIT_CONFIG_DEFAULT() { \
.controller_task_stack_size = ESP_TASK_BT_CONTROLLER_STACK, \
.controller_task_prio = ESP_TASK_BT_CONTROLLER_PRIO, \
@ -190,6 +196,7 @@ the adv packet will be discarded until the memory is restored. */
.pcm_polar = CONFIG_BTDM_CTRL_PCM_POLAR_EFF, \
.hli = BTDM_CTRL_HLI, \
.dup_list_refresh_period = SCAN_DUPL_CACHE_REFRESH_PERIOD, \
.ble_scan_backoff = BTDM_CTRL_SCAN_BACKOFF_UPPERLIMITMAX, \
.magic = ESP_BT_CONTROLLER_CONFIG_MAGIC_VAL, \
}
@ -233,6 +240,7 @@ typedef struct {
uint8_t pcm_polar; /*!< PCM polar trig (falling clk edge & rising clk edge) */
bool hli; /*!< Using high level interrupt or not */
uint16_t dup_list_refresh_period; /*!< Duplicate scan list refresh period */
bool ble_scan_backoff; /*!< BLE scan backoff */
uint32_t magic; /*!< Magic number */
} esp_bt_controller_config_t;

Wyświetl plik

@ -19,7 +19,7 @@ extern "C" {
#endif
#define ESP_BT_CTRL_CONFIG_MAGIC_VAL 0x5A5AA5A5
#define ESP_BT_CTRL_CONFIG_VERSION 0x02401120
#define ESP_BT_CTRL_CONFIG_VERSION 0x02404010
#define ESP_BT_HCI_TL_MAGIC_VALUE 0xfadebead
#define ESP_BT_HCI_TL_VERSION 0x00010000
@ -194,6 +194,18 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
#define BT_BLE_ADV_DATA_LENGTH_ZERO_AUX (0)
#endif
#if defined(CONFIG_BT_CTRL_CHAN_ASS_EN)
#define BT_CTRL_CHAN_ASS_EN (CONFIG_BT_CTRL_CHAN_ASS_EN)
#else
#define BT_CTRL_CHAN_ASS_EN (0)
#endif
#if defined(CONFIG_BT_CTRL_LE_PING_EN)
#define BT_CTRL_LE_PING_EN (CONFIG_BT_CTRL_LE_PING_EN)
#else
#define BT_CTRL_LE_PING_EN (0)
#endif
#define AGC_RECORRECT_EN ((BT_CTRL_AGC_RECORRECT_EN << 0) | (BT_CTRL_CODED_AGC_RECORRECT <<1) | (BT_CTRL_AGC_RECORRECT_NEW << 2))
#define CFG_MASK_BIT_SCAN_DUPLICATE_OPTION (1<<0)
@ -241,6 +253,8 @@ typedef void (* esp_bt_hci_tl_callback_t) (void *arg, uint8_t status);
.ble_50_feat_supp = BT_CTRL_50_FEATURE_SUPPORT, \
.ble_cca_mode = BT_BLE_CCA_MODE, \
.ble_data_lenth_zero_aux = BT_BLE_ADV_DATA_LENGTH_ZERO_AUX, \
.ble_chan_ass_en = BT_CTRL_CHAN_ASS_EN, \
.ble_ping_en = BT_CTRL_LE_PING_EN, \
}
#else
@ -289,7 +303,7 @@ typedef struct {
uint8_t sleep_clock; /*!< controller sleep clock */
uint8_t ble_st_acl_tx_buf_nb; /*!< controller static ACL TX BUFFER number */
uint8_t ble_hw_cca_check; /*!< controller hardware triggered CCA check */
uint16_t ble_adv_dup_filt_max; /*!< maxinum number of duplicate scan filter */
uint16_t ble_adv_dup_filt_max; /*!< maximum number of duplicate scan filter */
bool coex_param_en; /*!< deprecated */
uint8_t ce_len_type; /*!< connection event length computation method */
bool coex_use_hooks; /*!< deprecated */
@ -312,7 +326,9 @@ typedef struct {
uint16_t dup_list_refresh_period; /*!< duplicate scan list refresh time */
bool ble_50_feat_supp; /*!< BLE 5.0 feature support */
uint8_t ble_cca_mode; /*!< BLE CCA mode */
uint8_t ble_data_lenth_zero_aux; /*!< Config ext adv aux option*/
uint8_t ble_data_lenth_zero_aux; /*!< Config ext adv aux option */
uint8_t ble_chan_ass_en; /*!< BLE channel assessment enable */
uint8_t ble_ping_en; /*!< BLE ping procedure enable */
} esp_bt_controller_config_t;
/**
@ -600,6 +616,15 @@ void esp_wifi_bt_power_domain_on(void);
*/
void esp_wifi_bt_power_domain_off(void);
/**
* @brief Get the Bluetooth module sleep clock source.
*
* Note that this function shall not be invoked before esp_bt_controller_init()
*
* @return clock source used in Bluetooth low power mode
*/
esp_bt_sleep_clock_t esp_bt_get_lpclk_src(void);
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -2,6 +2,6 @@
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
SRCS "test_app_main.c" "test_uart.c"
REQUIRES driver unity
REQUIRES driver unity test_utils
WHOLE_ARCHIVE
)

Wyświetl plik

@ -1,29 +1,61 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "unity.h"
#include "driver/uart.h" // for the uart driver access
#include "test_utils.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "esp_system.h" // for uint32_t esp_random()
#include "esp_rom_gpio.h"
#include "driver/lp_io.h"
#include "soc/uart_periph.h"
#include "soc/uart_pins.h"
#include "soc/soc_caps.h"
#include "soc/clk_tree_defs.h"
#define UART_TAG "Uart"
#define UART_NUM1 (UART_NUM_1)
#define BUF_SIZE (100)
#define UART1_RX_PIN (5)
#define UART1_TX_PIN (4)
#define UART_BAUD_11520 (11520)
#define UART_BAUD_115200 (115200)
#define TOLERANCE (0.02) //baud rate error tolerance 2%.
#define UART1_CTS_PIN (13)
typedef struct {
uart_port_t port_num;
soc_module_clk_t default_src_clk;
int tx_pin_num;
int rx_pin_num;
uint32_t rx_flow_ctrl_thresh;
} uart_port_param_t;
static void uart_config(uint32_t baud_rate, uart_sclk_t source_clk)
static bool port_select(uart_port_param_t *port_param)
{
char argv[10];
unity_wait_for_signal_param("select to test 'uart' or 'lp_uart' port", argv, sizeof(argv));
if (strcmp(argv, "uart") == 0) {
port_param->port_num = UART_NUM_1; // Test HP_UART with UART1 port
port_param->default_src_clk = UART_SCLK_DEFAULT;
port_param->tx_pin_num = 4;
port_param->rx_pin_num = 5;
port_param->rx_flow_ctrl_thresh = 120;
return true;
#if SOC_UART_LP_NUM > 0
} else if (strcmp(argv, "lp_uart") == 0) {
port_param->port_num = LP_UART_NUM_0;
port_param->default_src_clk = LP_UART_SCLK_DEFAULT;
port_param->tx_pin_num = LP_U0TXD_GPIO_NUM;
port_param->rx_pin_num = LP_U0RXD_GPIO_NUM;
port_param->rx_flow_ctrl_thresh = 12;
return true;
#endif
} else {
return false;
}
}
static void uart_config(uart_port_t uart_num, uint32_t baud_rate, uart_sclk_t source_clk)
{
uart_config_t uart_config = {
.baud_rate = baud_rate,
@ -34,49 +66,63 @@ static void uart_config(uint32_t baud_rate, uart_sclk_t source_clk)
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
uart_driver_install(UART_NUM1, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0);
uart_param_config(UART_NUM1, &uart_config);
TEST_ESP_OK(uart_set_loop_back(UART_NUM1, true));
TEST_ESP_OK(uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0));
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
TEST_ESP_OK(uart_set_loop_back(uart_num, true));
}
static volatile bool exit_flag, case_end;
typedef struct {
uart_port_t port_num;
SemaphoreHandle_t exit_sem;
} uart_task1_param_t;
static void test_task1(void *pvParameters)
{
SemaphoreHandle_t *sema = (SemaphoreHandle_t *) pvParameters;
uart_task1_param_t *param = (uart_task1_param_t *)pvParameters;
char* data = (char *) malloc(256);
while (exit_flag == false) {
uart_tx_chars(UART_NUM1, data, 256);
uart_tx_chars(param->port_num, data, 256);
// The uart_wait_tx_done() function does not block anything if ticks_to_wait = 0.
uart_wait_tx_done(UART_NUM1, 0);
uart_wait_tx_done(param->port_num, 0);
}
free(data);
xSemaphoreGive(*sema);
xSemaphoreGive(param->exit_sem);
vTaskDelete(NULL);
}
static void test_task2(void *pvParameters)
{
uart_port_t uart_num = (uart_port_t)pvParameters;
while (exit_flag == false) {
// This task obstruct a setting tx_done_sem semaphore in the UART interrupt.
// It leads to waiting the ticks_to_wait time in uart_wait_tx_done() function.
uart_disable_tx_intr(UART_NUM1);
uart_disable_tx_intr(uart_num);
}
vTaskDelete(NULL);
}
static void test_task3(void *pvParameters)
{
uart_config(UART_BAUD_11520, UART_SCLK_DEFAULT);
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_port_t uart_num = port_param.port_num;
uart_config(uart_num, UART_BAUD_11520, port_param.default_src_clk);
SemaphoreHandle_t exit_sema = xSemaphoreCreateBinary();
uart_task1_param_t task1_param = {
.port_num = uart_num,
.exit_sem = exit_sema,
};
exit_flag = false;
case_end = false;
xTaskCreate(test_task1, "tsk1", 2048, &exit_sema, 5, NULL);
xTaskCreate(test_task2, "tsk2", 2048, NULL, 5, NULL);
xTaskCreate(test_task1, "tsk1", 2048, (void *)&task1_param, 5, NULL);
xTaskCreate(test_task2, "tsk2", 2048, (void *)uart_num, 5, NULL);
printf("Waiting for 5 sec\n");
vTaskDelay(pdMS_TO_TICKS(5000));
@ -87,7 +133,7 @@ static void test_task3(void *pvParameters)
} else {
TEST_FAIL_MESSAGE("uart_wait_tx_done is blocked");
}
TEST_ESP_OK(uart_driver_delete(UART_NUM1));
TEST_ESP_OK(uart_driver_delete(uart_num));
vTaskDelay(2); // wait for test_task1 to exit
@ -104,41 +150,70 @@ TEST_CASE("test uart_wait_tx_done is not blocked when ticks_to_wait=0", "[uart]"
TEST_CASE("test uart get baud-rate", "[uart]")
{
#if SOC_UART_SUPPORT_REF_TICK
uint32_t baud_rate1 = 0;
printf("init uart%d, use reftick, baud rate : %d\n", (int)UART_NUM1, (int)UART_BAUD_11520);
uart_config(UART_BAUD_11520, UART_SCLK_REF_TICK);
uart_get_baudrate(UART_NUM1, &baud_rate1);
printf("get baud rate when use reftick: %d\n", (int)baud_rate1);
TEST_ASSERT_UINT32_WITHIN(UART_BAUD_11520 * TOLERANCE, UART_BAUD_11520, baud_rate1);
#endif
uint32_t baud_rate2 = 0;
printf("init uart%d, unuse reftick, baud rate : %d\n", (int)UART_NUM1, (int)UART_BAUD_115200);
uart_config(UART_BAUD_115200, UART_SCLK_DEFAULT);
uart_get_baudrate(UART_NUM1, &baud_rate2);
printf("get baud rate when don't use reftick: %d\n", (int)baud_rate2);
TEST_ASSERT_UINT32_WITHIN(UART_BAUD_115200 * TOLERANCE, UART_BAUD_115200, baud_rate2);
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_driver_delete(UART_NUM1);
ESP_LOGI(UART_TAG, "get baud-rate test passed ....");
uart_port_t uart_num = port_param.port_num;
soc_module_clk_t uart_clk_srcs[] = SOC_UART_CLKS;
uint32_t uart_clk_srcs_num = sizeof(uart_clk_srcs) / sizeof(uart_clk_srcs[0]);
soc_module_clk_t *clk_srcs = uart_clk_srcs;
uint32_t clk_srcs_num = uart_clk_srcs_num;
#if SOC_UART_LP_NUM > 0
soc_module_clk_t lp_uart_clk_srcs[] = SOC_LP_UART_CLKS;
uint32_t lp_uart_clk_srcs_num = sizeof(lp_uart_clk_srcs) / sizeof(lp_uart_clk_srcs[0]);
if (uart_num >= SOC_UART_HP_NUM) {
clk_srcs = lp_uart_clk_srcs;
clk_srcs_num = lp_uart_clk_srcs_num;
}
#endif
uart_config(uart_num, UART_BAUD_115200, port_param.default_src_clk);
const uint32_t test_baudrate_vals[] = {UART_BAUD_11520, UART_BAUD_115200};
for (size_t i = 0; i < sizeof(test_baudrate_vals) / sizeof(test_baudrate_vals[0]); i++) {
for (size_t j = 0; j < clk_srcs_num; j++) {
uart_config_t uart_config = {
.baud_rate = test_baudrate_vals[i],
.source_clk = clk_srcs[j],
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
uint32_t actual_baudrate = 0;
uart_get_baudrate(uart_num, &actual_baudrate);
TEST_ASSERT_UINT32_WITHIN(test_baudrate_vals[i] * TOLERANCE, test_baudrate_vals[i], actual_baudrate);
}
}
uart_driver_delete(uart_num);
}
TEST_CASE("test uart tx data with break", "[uart]")
{
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_port_t uart_num = port_param.port_num;
const int buf_len = 200;
const int send_len = 128;
const int brk_len = 10;
char *psend = (char *)malloc(buf_len);
TEST_ASSERT_NOT_NULL(psend);
memset(psend, '0', buf_len);
uart_config(UART_BAUD_115200, UART_SCLK_DEFAULT);
printf("Uart%d send %d bytes with break\n", UART_NUM1, send_len);
uart_write_bytes_with_break(UART_NUM1, (const char *)psend, send_len, brk_len);
uart_wait_tx_done(UART_NUM1, portMAX_DELAY);
uart_config(uart_num, UART_BAUD_115200, port_param.default_src_clk);
printf("Uart%d send %d bytes with break\n", uart_num, send_len);
uart_write_bytes_with_break(uart_num, (const char *)psend, send_len, brk_len);
uart_wait_tx_done(uart_num, portMAX_DELAY);
//If the code is running here, it means the test passed, otherwise it will crash due to the interrupt wdt timeout.
printf("Send data with break test passed\n");
free(psend);
uart_driver_delete(UART_NUM1);
uart_driver_delete(uart_num);
}
static void uart_word_len_set_get_test(int uart_num)
@ -210,14 +285,17 @@ static void uart_wakeup_set_get_test(int uart_num)
TEST_CASE("uart general API test", "[uart]")
{
const int uart_num = UART_NUM1;
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_port_t uart_num = port_param.port_num;
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
.source_clk = port_param.default_src_clk,
};
uart_param_config(uart_num, &uart_config);
uart_word_len_set_get_test(uart_num);
@ -229,7 +307,7 @@ TEST_CASE("uart general API test", "[uart]")
static void uart_write_task(void *param)
{
int uart_num = (int)param;
uart_port_t uart_num = (uart_port_t)param;
uint8_t *tx_buf = (uint8_t *)malloc(1024);
if(tx_buf == NULL) {
TEST_FAIL_MESSAGE("tx buffer malloc fail");
@ -241,25 +319,19 @@ static void uart_write_task(void *param)
//d[0] and d[1023] are header
tx_buf[0] = (i & 0xff);
tx_buf[1023] = ((~i) & 0xff);
uart_write_bytes(uart_num, (const char*)tx_buf, 1024);
uart_write_bytes(uart_num, (const char *)tx_buf, 1024);
uart_wait_tx_done(uart_num, portMAX_DELAY);
}
free(tx_buf);
vTaskDelete(NULL);
}
/**
* The following tests use loop back
*
* NOTE: In the following tests, because the internal loopback is enabled, the CTS signal is connected to
* the RTS signal internally. However, On ESP32S3, they are not, and the CTS keeps the default level (which
* is a high level). So the workaround is to map the CTS in_signal to a GPIO pin (here IO13 is used) and connect
* the RTS output_signal to this IO.
*/
TEST_CASE("uart read write test", "[uart]")
{
const int uart_num = UART_NUM1;
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_port_t uart_num = port_param.port_num;
uint8_t *rd_data = (uint8_t *)malloc(1024);
if(rd_data == NULL) {
TEST_FAIL_MESSAGE("rx buffer malloc fail");
@ -270,15 +342,13 @@ TEST_CASE("uart read write test", "[uart]")
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
.source_clk = UART_SCLK_DEFAULT,
.rx_flow_ctrl_thresh = 120
.source_clk = port_param.default_src_clk,
.rx_flow_ctrl_thresh = port_param.rx_flow_ctrl_thresh,
};
TEST_ESP_OK(uart_driver_install(uart_num, BUF_SIZE * 2, 0, 20, NULL, 0));
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
// Use loop back feature to connect TX signal to RX signal, CTS signal to RTS signal internally. Then no need to configure uart pins.
TEST_ESP_OK(uart_set_loop_back(uart_num, true));
TEST_ESP_OK(uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART1_CTS_PIN));
//Connect the RTS out_signal to the CTS pin (which is mapped to CTS in_signal)
esp_rom_gpio_connect_out_signal(UART1_CTS_PIN, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY));
vTaskDelay(pdMS_TO_TICKS(20)); // make sure last byte has flushed from TX FIFO
@ -322,12 +392,15 @@ TEST_CASE("uart read write test", "[uart]")
uart_driver_delete(uart_num);
free(rd_data);
vTaskDelay(pdMS_TO_TICKS(100)); // wait for uart_write_task to exit
vTaskDelay(2); // wait for uart_write_task to exit
}
TEST_CASE("uart tx with ringbuffer test", "[uart]")
{
const int uart_num = UART_NUM1;
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_port_t uart_num = port_param.port_num;
uint8_t *rd_data = (uint8_t *)malloc(1024);
uint8_t *wr_data = (uint8_t *)malloc(1024);
if(rd_data == NULL || wr_data == NULL) {
@ -339,16 +412,14 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]")
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
.rx_flow_ctrl_thresh = 120,
.source_clk = UART_SCLK_DEFAULT,
.rx_flow_ctrl_thresh = port_param.rx_flow_ctrl_thresh,
.source_clk = port_param.default_src_clk,
};
uart_wait_tx_idle_polling(uart_num);
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
TEST_ESP_OK(uart_driver_install(uart_num, 1024 * 2, 1024 *2, 20, NULL, 0));
TEST_ESP_OK(uart_driver_install(uart_num, 1024 * 2, 1024 * 2, 20, NULL, 0));
// Use loop back feature to connect TX signal to RX signal, CTS signal to RTS signal internally. Then no need to configure uart pins.
TEST_ESP_OK(uart_set_loop_back(uart_num, true));
TEST_ESP_OK(uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART1_CTS_PIN));
//Connect the RTS out_signal to the CTS pin (which is mapped to CTS in_signal)
esp_rom_gpio_connect_out_signal(UART1_CTS_PIN, UART_PERIPH_SIGNAL(uart_num, SOC_UART_RTS_PIN_IDX), 0, 0);
for (int i = 0; i < 1024; i++) {
wr_data[i] = i;
@ -358,7 +429,7 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]")
size_t tx_buffer_free_space;
uart_get_tx_buffer_free_size(uart_num, &tx_buffer_free_space);
TEST_ASSERT_EQUAL_INT(2048, tx_buffer_free_space); // full tx buffer space is free
uart_write_bytes(uart_num, (const char*)wr_data, 1024);
uart_write_bytes(uart_num, (const char *)wr_data, 1024);
uart_get_tx_buffer_free_size(uart_num, &tx_buffer_free_space);
TEST_ASSERT_LESS_THAN(2048, tx_buffer_free_space); // tx transmit in progress: tx buffer has content
TEST_ASSERT_GREATER_OR_EQUAL(1024, tx_buffer_free_space);
@ -374,56 +445,72 @@ TEST_CASE("uart tx with ringbuffer test", "[uart]")
TEST_CASE("uart int state restored after flush", "[uart]")
{
/**
* The first goal of this test is to make sure that when our RX FIFO is full,
* we can continue receiving back data after flushing
* For more details, check IDF-4374
*/
uart_port_param_t port_param = {};
TEST_ASSERT(port_select(&port_param));
uart_port_t uart_num = port_param.port_num;
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
.source_clk = port_param.default_src_clk,
};
const uart_port_t uart_echo = UART_NUM_1;
const int uart_tx_signal = uart_periph_signal[uart_echo].pins[SOC_UART_TX_PIN_IDX].signal;
const int uart_tx = UART1_TX_PIN;
const int uart_rx = UART1_RX_PIN;
const int uart_tx_signal = uart_periph_signal[uart_num].pins[SOC_UART_TX_PIN_IDX].signal;
const int uart_tx = port_param.tx_pin_num;
const int uart_rx = port_param.rx_pin_num;
const int buf_size = 256;
const int intr_alloc_flags = 0;
TEST_ESP_OK(uart_driver_install(uart_echo, buf_size * 2, 0, 0, NULL, intr_alloc_flags));
TEST_ESP_OK(uart_param_config(uart_echo, &uart_config));
TEST_ESP_OK(uart_set_pin(uart_echo, uart_tx, uart_rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
TEST_ESP_OK(uart_driver_install(uart_num, buf_size * 2, 0, 0, NULL, intr_alloc_flags));
TEST_ESP_OK(uart_param_config(uart_num, &uart_config));
TEST_ESP_OK(uart_set_pin(uart_num, uart_tx, uart_rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
/* Make sure UART2's RX signal is connected to TX pin
/* Make sure UART's TX signal is connected to RX pin
* This creates a loop that lets us receive anything we send on the UART */
esp_rom_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false);
if (uart_num < SOC_UART_HP_NUM) {
esp_rom_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false);
#if SOC_UART_LP_NUM > 0
} else {
// LP_UART
#if SOC_LP_GPIO_MATRIX_SUPPORTED
TEST_ESP_OK(lp_gpio_connect_out_signal(uart_rx, uart_tx_signal, false, false));
#else
// The only way is to use loop back feature
TEST_ESP_OK(uart_set_loop_back(uart_num, true));
#endif
#endif // SOC_UART_LP_NUM > 0
}
uint8_t *data = (uint8_t *) malloc(buf_size);
uint8_t *data = (uint8_t *)malloc(buf_size);
TEST_ASSERT_NOT_NULL(data);
uart_write_bytes(uart_echo, (const char *) data, buf_size);
uart_write_bytes(uart_num, (const char *)data, buf_size);
/* As we set up a loopback, we can read them back on RX */
int len = uart_read_bytes(uart_echo, data, buf_size, pdMS_TO_TICKS(1000));
int len = uart_read_bytes(uart_num, data, buf_size, pdMS_TO_TICKS(1000));
printf("len is %d\n", len);
TEST_ASSERT_EQUAL(len, buf_size);
/**
* The first goal of this test is to make sure that when our RX FIFO is full,
* we can continue receiving back data after flushing
* For more details, check IDF-4374 */
/* Fill the RX buffer, this should disable the RX interrupts */
int written = uart_write_bytes(uart_echo, (const char *) data, buf_size);
int written = uart_write_bytes(uart_num, (const char *)data, buf_size);
TEST_ASSERT_NOT_EQUAL(-1, written);
written = uart_write_bytes(uart_echo, (const char *) data, buf_size);
written = uart_write_bytes(uart_num, (const char *)data, buf_size);
TEST_ASSERT_NOT_EQUAL(-1, written);
written = uart_write_bytes(uart_echo, (const char *) data, buf_size);
written = uart_write_bytes(uart_num, (const char *)data, buf_size);
TEST_ASSERT_NOT_EQUAL(-1, written);
/* Flush the input buffer, RX interrupts should be re-enabled */
uart_flush_input(uart_echo);
written = uart_write_bytes(uart_echo, (const char *) data, buf_size);
uart_flush_input(uart_num);
written = uart_write_bytes(uart_num, (const char *)data, buf_size);
TEST_ASSERT_NOT_EQUAL(-1, written);
len = uart_read_bytes(uart_echo, data, buf_size, pdMS_TO_TICKS(1000));
len = uart_read_bytes(uart_num, data, buf_size, pdMS_TO_TICKS(1000));
/* len equals buf_size bytes if interrupts were indeed re-enabled */
TEST_ASSERT_EQUAL(len, buf_size);
@ -433,14 +520,15 @@ TEST_CASE("uart int state restored after flush", "[uart]")
* To do so, start by cleaning the RX FIFO, disable the RX interrupts,
* flush again, send data to the UART and check that we haven't received
* any of the bytes */
uart_flush_input(uart_echo);
uart_disable_rx_intr(uart_echo);
uart_flush_input(uart_echo);
written = uart_write_bytes(uart_echo, (const char *) data, buf_size);
uart_flush_input(uart_num);
uart_disable_rx_intr(uart_num);
uart_flush_input(uart_num);
written = uart_write_bytes(uart_num, (const char *)data, buf_size);
TEST_ASSERT_NOT_EQUAL(-1, written);
len = uart_read_bytes(uart_echo, data, buf_size, pdMS_TO_TICKS(250));
len = uart_read_bytes(uart_num, data, buf_size, pdMS_TO_TICKS(250));
TEST_ASSERT_EQUAL(len, 0);
TEST_ESP_OK(uart_driver_delete(uart_echo));
TEST_ESP_OK(uart_driver_delete(uart_num));
free(data);
}

Wyświetl plik

@ -1,8 +1,17 @@
# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import pytest
input_argv = {
'esp32': ['uart'],
'esp32s2': ['uart'],
'esp32s3': ['uart'],
'esp32c3': ['uart'],
'esp32c2': ['uart'],
'esp32c6': ['uart', 'lp_uart'],
'esp32h2': ['uart'],
}
@pytest.mark.supported_targets
@pytest.mark.generic
@ -15,4 +24,14 @@ import pytest
indirect=True,
)
def test_uart_single_dev(case_tester) -> None: # type: ignore
case_tester.run_all_normal_cases(reset=True)
dut = case_tester.dut
chip_type = dut.app.target
for uart_port in input_argv.get(chip_type, []):
for case in case_tester.test_menu:
dut.serial.hard_reset()
dut._get_ready()
dut.confirm_write(case.index, expect_str=f'Running {case.name}...')
dut.expect("select to test 'uart' or 'lp_uart' port", timeout=10)
dut.write(f'{uart_port}')
dut.expect_unity_test_output()

Wyświetl plik

@ -1,15 +1,11 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_err.h"
#include "esp_intr_alloc.h"
#include "soc/soc_caps.h"
@ -20,6 +16,10 @@ extern "C" {
#include "freertos/ringbuf.h"
#include "hal/uart_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* @brief When calling `uart_set_pin`, instead of GPIO number, `UART_PIN_NO_CHANGE`
* can be provided to keep the currently allocated pin.
*/

Wyświetl plik

@ -48,7 +48,7 @@
static const char *UART_TAG = "uart";
#define UART_EMPTY_THRESH_DEFAULT (10)
#define LP_UART_EMPTY_THRESH_DEFAULT (2)
#define LP_UART_EMPTY_THRESH_DEFAULT (4)
#define UART_FULL_THRESH_DEFAULT (120)
#define LP_UART_FULL_THRESH_DEFAULT (10)
#define UART_TOUT_THRESH_DEFAULT (10)

Wyświetl plik

@ -29,17 +29,18 @@
static const char *TAG = "dm9051.mac";
#define DM9051_SPI_LOCK_TIMEOUT_MS (50)
#define DM9051_SPI_LOCK_TIMEOUT_MS (50)
#define DM9051_PHY_OPERATION_TIMEOUT_US (1000)
#define DM9051_RX_MEM_START_ADDR (3072)
#define DM9051_RX_MEM_MAX_SIZE (16384)
#define DM9051_RX_HDR_SIZE (4)
#define DM9051_MULTI_REG_AXS_TIMEOUT_MS (50)
#define DM9051_RX_MEM_START_ADDR (3072)
#define DM9051_RX_MEM_MAX_SIZE (16384)
#define DM9051_RX_HDR_SIZE (4)
#define DM9051_ETH_MAC_RX_BUF_SIZE_AUTO (0)
typedef struct {
uint32_t copy_len;
uint32_t byte_cnt;
}__attribute__((packed)) dm9051_auto_buf_info_t;
} __attribute__((packed)) dm9051_auto_buf_info_t;
typedef struct {
uint8_t flag;
@ -66,6 +67,7 @@ typedef struct {
esp_eth_mediator_t *eth;
eth_spi_custom_driver_t spi;
TaskHandle_t rx_task_hdl;
SemaphoreHandle_t multi_reg_axs_mutex;
uint32_t sw_reset_timeout_ms;
int int_gpio_num;
esp_timer_handle_t poll_timer;
@ -92,7 +94,7 @@ static void *dm9051_spi_init(const void *spi_config)
spi_devcfg.address_bits = 7;
} else {
ESP_GOTO_ON_FALSE(dm9051_config->spi_devcfg->command_bits == 1 && dm9051_config->spi_devcfg->address_bits == 7,
NULL, err, TAG, "incorrect SPI frame format (command_bits/address_bits)");
NULL, err, TAG, "incorrect SPI frame format (command_bits/address_bits)");
}
ESP_GOTO_ON_FALSE(spi_bus_add_device(dm9051_config->spi_host_id, &spi_devcfg, &spi->hdl) == ESP_OK,
NULL, err, TAG, "adding device to SPI host #%d failed", dm9051_config->spi_host_id + 1);
@ -179,12 +181,22 @@ static esp_err_t dm9051_spi_read(void *spi_ctx, uint32_t cmd, uint32_t addr, voi
} else {
ret = ESP_ERR_TIMEOUT;
}
if ((trans.flags&SPI_TRANS_USE_RXDATA) && len <= 4) {
if ((trans.flags & SPI_TRANS_USE_RXDATA) && len <= 4) {
memcpy(value, trans.rx_data, len); // copy register values to output
}
return ret;
}
static inline bool dm9051_mutex_lock(emac_dm9051_t *emac)
{
return xSemaphoreTake(emac->multi_reg_axs_mutex, pdMS_TO_TICKS(DM9051_MULTI_REG_AXS_TIMEOUT_MS)) == pdTRUE;
}
static inline bool dm9051_mutex_unlock(emac_dm9051_t *emac)
{
return xSemaphoreGive(emac->multi_reg_axs_mutex) == pdTRUE;
}
/**
* @brief write value to dm9051 internal register
*/
@ -378,7 +390,7 @@ static esp_err_t emac_dm9051_start(esp_eth_mac_t *mac)
{
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
/* reset tx and rx memory pointer */
/* reset tx and rx memory pointer */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_MPTRCR, MPTRCR_RST_RX | MPTRCR_RST_TX), err, TAG, "write MPTRCR failed");
/* clear interrupt status */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_ISR, ISR_CLR_STATUS), err, TAG, "write ISR failed");
@ -441,59 +453,65 @@ err:
return ret;
}
static esp_err_t emac_dm9051_phy_access_compl(emac_dm9051_t *emac, uint32_t timeout_us)
{
uint8_t epcr = 0;
ESP_RETURN_ON_ERROR(dm9051_register_read(emac, DM9051_EPCR, &epcr), TAG, "read EPCR failed");
uint32_t to = 0;
if (epcr & EPCR_ERRE) {
do {
esp_rom_delay_us(100);
ESP_RETURN_ON_ERROR(dm9051_register_read(emac, DM9051_EPCR, &epcr), TAG, "read EPCR failed");
to += 100;
} while ((epcr & EPCR_ERRE) && to < timeout_us);
ESP_RETURN_ON_FALSE(!(epcr & EPCR_ERRE), ESP_ERR_TIMEOUT, TAG, "wait for PHY/EEPROM access completion timeouted");
}
return ESP_OK;
}
static esp_err_t emac_dm9051_write_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr, uint32_t phy_reg, uint32_t reg_value)
{
esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
/* check if phy access is in progress */
uint8_t epcr = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPCR, &epcr), err, TAG, "read EPCR failed");
ESP_GOTO_ON_FALSE(!(epcr & EPCR_ERRE), ESP_ERR_INVALID_STATE, err, TAG, "phy is busy");
/* The following commands need to be performed in atomic manner */
ESP_RETURN_ON_FALSE(dm9051_mutex_lock(emac), ESP_ERR_TIMEOUT, TAG, "multiple register access mutex timeout");
/* check if no PHY/EEPROM access is in progress */
ESP_GOTO_ON_ERROR(emac_dm9051_phy_access_compl(emac, DM9051_PHY_OPERATION_TIMEOUT_US), err, TAG, "PHY is busy");
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPAR, (uint8_t)(((phy_addr << 6) & 0xFF) | phy_reg)), err, TAG, "write EPAR failed");
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPDRL, (uint8_t)(reg_value & 0xFF)), err, TAG, "write EPDRL failed");
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPDRH, (uint8_t)((reg_value >> 8) & 0xFF)), err, TAG, "write EPDRH failed");
/* select PHY and select write operation */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPCR, EPCR_EPOS | EPCR_ERPRW), err, TAG, "write EPCR failed");
/* polling the busy flag */
uint32_t to = 0;
do {
esp_rom_delay_us(100);
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPCR, &epcr), err, TAG, "read EPCR failed");
to += 100;
} while ((epcr & EPCR_ERRE) && to < DM9051_PHY_OPERATION_TIMEOUT_US);
ESP_GOTO_ON_FALSE(!(epcr & EPCR_ERRE), ESP_ERR_TIMEOUT, err, TAG, "phy is busy");
return ESP_OK;
/* wait for PHY access completion */
ESP_GOTO_ON_ERROR(emac_dm9051_phy_access_compl(emac, DM9051_PHY_OPERATION_TIMEOUT_US), err, TAG, "PHY access completion check failed");
err:
dm9051_mutex_unlock(emac);
return ret;
}
static esp_err_t emac_dm9051_read_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr, uint32_t phy_reg, uint32_t *reg_value)
{
esp_err_t ret = ESP_OK;
ESP_GOTO_ON_FALSE(reg_value, ESP_ERR_INVALID_ARG, err, TAG, "can't set reg_value to null");
ESP_RETURN_ON_FALSE(reg_value, ESP_ERR_INVALID_ARG, TAG, "can't set reg_value to null");
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
/* check if phy access is in progress */
uint8_t epcr = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPCR, &epcr), err, TAG, "read EPCR failed");
ESP_GOTO_ON_FALSE(!(epcr & 0x01), ESP_ERR_INVALID_STATE, err, TAG, "phy is busy");
/* The following commands need to be performed in atomic manner */
ESP_RETURN_ON_FALSE(dm9051_mutex_lock(emac), ESP_ERR_TIMEOUT, TAG, "multiple register access mutex timeout");
/* check if no PHY/EEPROM access is in progress */
ESP_GOTO_ON_ERROR(emac_dm9051_phy_access_compl(emac, DM9051_PHY_OPERATION_TIMEOUT_US), err, TAG, "PHY is busy");
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPAR, (uint8_t)(((phy_addr << 6) & 0xFF) | phy_reg)), err, TAG, "write EPAR failed");
/* Select PHY and select read operation */
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPCR, 0x0C), err, TAG, "write EPCR failed");
/* polling the busy flag */
uint32_t to = 0;
do {
esp_rom_delay_us(100);
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPCR, &epcr), err, TAG, "read EPCR failed");
to += 100;
} while ((epcr & EPCR_ERRE) && to < DM9051_PHY_OPERATION_TIMEOUT_US);
ESP_GOTO_ON_FALSE(!(epcr & EPCR_ERRE), ESP_ERR_TIMEOUT, err, TAG, "phy is busy");
ESP_GOTO_ON_ERROR(dm9051_register_write(emac, DM9051_EPCR, EPCR_EPOS | EPCR_ERPRR), err, TAG, "write EPCR failed");
/* wait for PHY access completion */
ESP_GOTO_ON_ERROR(emac_dm9051_phy_access_compl(emac, DM9051_PHY_OPERATION_TIMEOUT_US), err, TAG, "PHY access completion check failed");
uint8_t value_h = 0;
uint8_t value_l = 0;
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPDRH, &value_h), err, TAG, "read EPDRH failed");
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_EPDRL, &value_l), err, TAG, "read EPDRL failed");
*reg_value = (value_h << 8) | value_l;
return ESP_OK;
err:
dm9051_mutex_unlock(emac);
return ret;
}
@ -529,14 +547,14 @@ static esp_err_t emac_dm9051_set_link(esp_eth_mac_t *mac, eth_link_t link)
ESP_GOTO_ON_ERROR(mac->start(mac), err, TAG, "dm9051 start failed");
if (emac->poll_timer) {
ESP_GOTO_ON_ERROR(esp_timer_start_periodic(emac->poll_timer, emac->poll_period_ms * 1000),
err, TAG, "start poll timer failed");
err, TAG, "start poll timer failed");
}
break;
case ETH_LINK_DOWN:
ESP_GOTO_ON_ERROR(mac->stop(mac), err, TAG, "dm9051 stop failed");
if (emac->poll_timer) {
ESP_GOTO_ON_ERROR(esp_timer_stop(emac->poll_timer),
err, TAG, "stop poll timer failed");
err, TAG, "stop poll timer failed");
}
break;
default:
@ -637,7 +655,7 @@ static esp_err_t emac_dm9051_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
int64_t wait_time = esp_timer_get_time();
do {
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_TCR, &tcr), err, TAG, "read TCR failed");
} while((tcr & TCR_TXREQ) && ((esp_timer_get_time() - wait_time) < 100));
} while ((tcr & TCR_TXREQ) && ((esp_timer_get_time() - wait_time) < 100));
if (tcr & TCR_TXREQ) {
ESP_LOGE(TAG, "last transmit still in progress, cannot send.");
@ -781,7 +799,7 @@ static esp_err_t emac_dm9051_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
/* dummy read, get the most updated data */
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte), err, TAG, "read MRCMDX failed");
/* check for remaing packets */
/* check for remaining packets */
ESP_GOTO_ON_ERROR(dm9051_register_read(emac, DM9051_MRCMDX, &rxbyte), err, TAG, "read MRCMDX failed");
emac->packets_remain = rxbyte > 0;
return ESP_OK;
@ -807,7 +825,7 @@ static esp_err_t emac_dm9051_init(esp_eth_mac_t *mac)
/* reset dm9051 */
ESP_GOTO_ON_ERROR(dm9051_reset(emac), err, TAG, "reset dm9051 failed");
/* verify chip id */
ESP_GOTO_ON_ERROR(dm9051_verify_id(emac), err, TAG, "vefiry chip ID failed");
ESP_GOTO_ON_ERROR(dm9051_verify_id(emac), err, TAG, "verify chip ID failed");
/* default setup of internal registers */
ESP_GOTO_ON_ERROR(dm9051_setup_default(emac), err, TAG, "dm9051 default setup failed");
/* clear multicast hash table */
@ -849,7 +867,7 @@ static void emac_dm9051_task(void *arg)
// check if the task receives any notification
if (emac->int_gpio_num >= 0) { // if in interrupt mode
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ...
gpio_get_level(emac->int_gpio_num) == 0) { // ...and no interrupt asserted
gpio_get_level(emac->int_gpio_num) == 0) { // ...and no interrupt asserted
continue; // -> just continue to check again
}
} else {
@ -908,6 +926,7 @@ static esp_err_t emac_dm9051_del(esp_eth_mac_t *mac)
}
vTaskDelete(emac->rx_task_hdl);
emac->spi.deinit(emac->spi.ctx);
vSemaphoreDelete(emac->multi_reg_axs_mutex);
heap_caps_free(emac->rx_buffer);
free(emac);
return ESP_OK;
@ -946,7 +965,7 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
emac->parent.receive = emac_dm9051_receive;
if (dm9051_config->custom_spi_driver.init != NULL && dm9051_config->custom_spi_driver.deinit != NULL
&& dm9051_config->custom_spi_driver.read != NULL && dm9051_config->custom_spi_driver.write != NULL) {
&& dm9051_config->custom_spi_driver.read != NULL && dm9051_config->custom_spi_driver.write != NULL) {
ESP_LOGD(TAG, "Using user's custom SPI Driver");
emac->spi.init = dm9051_config->custom_spi_driver.init;
emac->spi.deinit = dm9051_config->custom_spi_driver.deinit;
@ -964,13 +983,17 @@ esp_eth_mac_t *esp_eth_mac_new_dm9051(const eth_dm9051_config_t *dm9051_config,
ESP_GOTO_ON_FALSE((emac->spi.ctx = emac->spi.init(dm9051_config)) != NULL, NULL, err, TAG, "SPI initialization failed");
}
/* create mutex for accessing multiple registers in atomic manner */
emac->multi_reg_axs_mutex = xSemaphoreCreateMutex();
ESP_GOTO_ON_FALSE(emac->multi_reg_axs_mutex, NULL, err, TAG, "create multi registers access mutex failed");
/* create dm9051 task */
BaseType_t core_num = tskNO_AFFINITY;
if (mac_config->flags & ETH_MAC_FLAG_PIN_TO_CORE) {
core_num = esp_cpu_get_core_id();
}
BaseType_t xReturned = xTaskCreatePinnedToCore(emac_dm9051_task, "dm9051_tsk", mac_config->rx_task_stack_size, emac,
mac_config->rx_task_prio, &emac->rx_task_hdl, core_num);
mac_config->rx_task_prio, &emac->rx_task_hdl, core_num);
ESP_GOTO_ON_FALSE(xReturned == pdPASS, NULL, err, TAG, "create dm9051 task failed");
emac->rx_buffer = heap_caps_malloc(ETH_MAX_PACKET_SIZE + DM9051_RX_HDR_SIZE, MALLOC_CAP_DMA);
@ -999,6 +1022,9 @@ err:
if (emac->spi.ctx) {
emac->spi.deinit(emac->spi.ctx);
}
if (emac->multi_reg_axs_mutex) {
vSemaphoreDelete(emac->multi_reg_axs_mutex);
}
heap_caps_free(emac->rx_buffer);
free(emac);
}

Wyświetl plik

@ -23,6 +23,11 @@ extern "C" {
#include <stdbool.h>
#include <stdio.h>
/* HID BT Task Size Def */
#ifndef BT_HID_DEVICE_TASK_SIZE
#define BT_HID_DEVICE_TASK_SIZE 4096
#endif
/* HID Report Map Values */
#define HID_RM_INPUT 0x80
#define HID_RM_OUTPUT 0x90

Wyświetl plik

@ -976,7 +976,7 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf
.queue_size = 5,
.task_name = "ble_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = 4096,
.task_stack_size = BT_HID_DEVICE_TASK_SIZE,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_dev->event_loop_handle);

Wyświetl plik

@ -282,6 +282,12 @@ static void bt_hidd_init_app(void)
s_hidd_param.app_param.subclass = get_subclass_by_appearance(s_hidd_param.dev->appearance);
s_hidd_param.app_param.desc_list = (uint8_t *)s_hidd_param.dev->devices[0].reports_map.data;
s_hidd_param.app_param.desc_list_len = s_hidd_param.dev->devices[0].reports_map.len;
// Information SDP
s_hidd_param.app_param.vendor_id = p_config->vendor_id;
s_hidd_param.app_param.product_id = p_config->product_id;
s_hidd_param.app_param.version = p_config->version;
s_hidd_param.app_param.vendor_id_source = s_hidd_param.app_param.vendor_id_source;
}
static void bt_hidd_init_qos(void)
@ -812,7 +818,7 @@ esp_err_t esp_bt_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_confi
.queue_size = 5,
.task_name = "bt_hidd_events",
.task_priority = uxTaskPriorityGet(NULL),
.task_stack_size = 2048,
.task_stack_size = BT_HID_DEVICE_TASK_SIZE,
.task_core_id = tskNO_AFFINITY
};
ret = esp_event_loop_create(&event_task_args, &s_hidd_param.dev->event_loop_handle);

Wyświetl plik

@ -65,7 +65,6 @@ r_lld_con_tx_prog_new_packet_coex = 0x40001b70;
r_lld_per_adv_dynamic_pti_get = 0x40001b78;
r_lld_per_adv_evt_start_chm_upd = 0x40001b7c;
r_lld_ext_scan_dynamic_pti_get = 0x40001b80;
r_lld_scan_try_sched = 0x40001b84;
r_lld_sync_insert = 0x40001b88;
r_sch_prog_ble_push = 0x40001b8c;
r_sch_prog_bt_push = 0x40001b90;

Wyświetl plik

@ -116,7 +116,6 @@ r_lld_con_start_eco = 0x40001d10;
r_lld_con_frm_isr_eco = 0x40001d14;
r_lld_con_tx_eco = 0x40001d18;
r_lld_scan_evt_start_cbk_eco = 0x40001d20;
r_lld_scan_start_eco = 0x40001d24;
r_lld_ext_scan_dynamic_pti_process_eco = 0x40001d28;
r_lld_scan_frm_eof_isr_eco = 0x40001d2c;
r_lld_sync_start_eco = 0x40001d30;
@ -141,15 +140,9 @@ r_sch_plan_conflict_check = 0x40001d7c;
r_rwble_isr_hw_fixed = 0x40001d80;
r_bt_bb_recorrect_is_dead = 0x40001d84;
r_bt_bb_restart_hw_recorrect = 0x40001d88;
r_btdm_task_post_impl = 0x40001d8c;
r_btdm_task_post_from_isr_impl = 0x40001d90;
r_btdm_vnd_offload_post_from_isr = 0x40001d94;
r_btdm_vnd_offload_post = 0x40001d98;
r_btdm_vnd_offload_process = 0x40001d9c;
r_ke_task_handler_pre = 0x40001da0;
r_ke_task_handler_end = 0x40001da4;
r_ke_task_handler_get_overwrite = 0x40001da8;
r_lld_scan_try_sched_eco = 0x40001dac;
r_lld_scan_frm_skip_isr_eco = 0x40001db0;
r_lld_ext_scan_dynamic_pti_reset = 0x40001db4;
r_llc_rem_phy_upd_proc_continue_eco = 0x40001db8;
@ -220,6 +213,8 @@ r_lld_adv_ext_chain_none_construct = 0x40001b50;
r_llc_llcp_send_eco = 0x40001cf4;
r_llc_llcp_channel_map_ind_ack = 0x40001d68;
r_rwble_isr = 0x40001464;
r_lld_scan_start_eco = 0x40001d24;
r_lld_scan_try_sched_eco = 0x40001dac;
*/

Wyświetl plik

@ -922,7 +922,7 @@ r_llc_init_term_proc = 0x40000f1c;
r_llc_iv_skd_rand_gen = 0x40000f20;
r_llc_le_ping_proc_continue = 0x40000f24;
r_llc_le_ping_proc_err_cb = 0x40000f28;
r_llc_le_ping_restart = 0x40000f2c;
/* r_llc_le_ping_restart = 0x40000f2c; */
r_llc_le_ping_set = 0x40000f30;
r_llc_ll_pause_enc_rsp_ack_handler = 0x40000f34;
r_llc_ll_reject_ind_ack_handler = 0x40000f38;

Wyświetl plik

@ -1195,7 +1195,7 @@ r_llc_init_term_proc = 0x40003d38;
r_llc_iv_skd_rand_gen = 0x40003d44;
r_llc_le_ping_proc_continue = 0x40003d50;
r_llc_le_ping_proc_err_cb = 0x40003d5c;
r_llc_le_ping_restart = 0x40003d68;
/* r_llc_le_ping_restart = 0x40003d68; */
r_llc_le_ping_set = 0x40003d74;
r_llc_ll_pause_enc_rsp_ack_handler = 0x40003d80;
r_llc_ll_reject_ind_ack_handler = 0x40003d8c;
@ -1609,7 +1609,6 @@ r_lld_con_tx_prog_new_packet_coex = 0x4000519c;
r_lld_per_adv_dynamic_pti_get = 0x400051b4;
r_lld_per_adv_evt_start_chm_upd = 0x400051c0;
r_lld_ext_scan_dynamic_pti_get = 0x400051cc;
r_lld_scan_try_sched = 0x400051d8;
r_lld_sync_insert = 0x400051e4;
r_sch_prog_ble_push = 0x400051f0;
r_sch_prog_bt_push = 0x400051fc;

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -211,15 +211,18 @@ static inline void lp_uart_ll_reset_register(int hw_id)
*/
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG :
(uart_num == 1) ? PCR_UART1_CONF_REG : 0);
uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN :
(uart_num == 1) ? PCR_UART1_RST_EN : 0);
uint32_t uart_en_bit = ((uart_num == 0) ? PCR_UART0_CLK_EN :
(uart_num == 1) ? PCR_UART1_CLK_EN : 0);
return REG_GET_BIT(uart_clk_config_reg, uart_rst_bit) == 0 &&
REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0;
switch (uart_num) {
case 0:
return PCR.uart0_conf.uart0_clk_en && !PCR.uart0_conf.uart0_rst_en;
case 1:
return PCR.uart1_conf.uart1_clk_en && !PCR.uart1_conf.uart1_rst_en;
case 2: // LP_UART
return LPPERI.clk_en.lp_uart_ck_en && !LPPERI.reset_en.lp_uart_reset_en;
default:
// Unknown uart port number
HAL_ASSERT(false);
return false;
}
}
/**

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -100,9 +100,9 @@ FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *sou
case 1:
*source_clk = (soc_module_clk_t)LP_UART_SCLK_XTAL_D2;
break;
case 2:
*source_clk = (soc_module_clk_t)LP_UART_SCLK_LP_PLL;
break;
// case 2:
// *source_clk = (soc_module_clk_t)LP_UART_SCLK_LP_PLL;
// break;
}
}
@ -122,9 +122,9 @@ static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_
case LP_UART_SCLK_XTAL_D2:
LPPERI.core_clk_sel.lp_uart_clk_sel = 1;
break;
case LP_UART_SCLK_LP_PLL:
LPPERI.core_clk_sel.lp_uart_clk_sel = 2;
break;
// case LP_UART_SCLK_LP_PLL: // TODO: LP_PLL clock requires extra support
// LPPERI.core_clk_sel.lp_uart_clk_sel = 2;
// break;
default:
// Invalid LP_UART clock source
HAL_ASSERT(false);
@ -202,8 +202,7 @@ static inline void lp_uart_ll_reset_register(int hw_id)
*/
FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
{
HAL_ASSERT(uart_num < SOC_UART_HP_NUM);
bool uart_rst_en = false;
bool uart_rst_en = true;
bool uart_apb_en = false;
bool uart_sys_en = false;
switch (uart_num) {
@ -232,7 +231,14 @@ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num)
uart_apb_en = HP_SYS_CLKRST.soc_clk_ctrl2.reg_uart4_apb_clk_en;
uart_sys_en = HP_SYS_CLKRST.soc_clk_ctrl1.reg_uart4_sys_clk_en;
break;
case 5:
uart_rst_en = LPPERI.reset_en.rst_en_lp_uart;
uart_apb_en = LPPERI.clk_en.ck_en_lp_uart;
uart_sys_en = true;
break;
default:
// Unknown uart port number
HAL_ASSERT(false);
break;
}
return (!uart_rst_en && uart_apb_en && uart_sys_en);

@ -1 +1 @@
Subproject commit e6afdb4025fe018ae0add44e3c45249ea1974774
Subproject commit aa6f889fb4f6f743b3a550aa587713aabbdca1fc

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -202,6 +202,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_REF_TICK}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -175,6 +175,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F40M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -201,6 +201,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/

Wyświetl plik

@ -1179,6 +1179,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
bool
default y
config SOC_UART_HAS_LP_UART
bool
default y
config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
bool
default y

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -217,6 +217,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/
@ -227,6 +232,11 @@ typedef enum {
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
} soc_periph_uart_clk_src_legacy_t;
/**
* @brief Array initializer for all supported clock sources of LP_UART
*/
#define SOC_LP_UART_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL_D2}
/**
* @brief Type of LP_UART clock source
*/

Wyświetl plik

@ -477,6 +477,7 @@
#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -224,6 +224,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/

Wyświetl plik

@ -1139,6 +1139,10 @@ config SOC_UART_SUPPORT_WAKEUP_INT
bool
default y
config SOC_UART_HAS_LP_UART
bool
default y
config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND
bool
default y

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -258,6 +258,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/
@ -265,26 +270,22 @@ typedef enum {
UART_SCLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */
UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */
UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */
#if SOC_CLK_TREE_SUPPORTED
UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
#else
UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment */
#endif
} soc_periph_uart_clk_src_legacy_t;
/**
* @brief Array initializer for all supported clock sources of LP_UART
*/
#define SOC_LP_UART_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL_D2}
/**
* @brief Type of LP_UART clock source
*/
typedef enum {
LP_UART_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock is LP(RTC)_FAST */
LP_UART_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock is XTAL_D2 */
LP_UART_SCLK_LP_PLL = SOC_MOD_CLK_LP_PLL, /*!< LP_UART source clock is LP_PLL (8M PLL) */
#if SOC_CLK_TREE_SUPPORTED
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST,
#else
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL_D2, /*!< LP_UART source clock default choice is XTAL_D2 */
#endif
// LP_UART_SCLK_LP_PLL = SOC_MOD_CLK_LP_PLL, /*!< LP_UART source clock is LP_PLL (8M PLL) */ TODO: LP_PLL clock requires extra support
LP_UART_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_UART source clock default choice is LP(RTC)_FAST */
} soc_periph_lp_uart_clk_src_t;
//////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////

Wyświetl plik

@ -503,6 +503,7 @@
#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */
#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */
#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */
#define SOC_UART_HAS_LP_UART (1) /*!< Support LP UART */
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled
#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -217,6 +217,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_REF_TICK}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -219,6 +219,11 @@ typedef enum {
///////////////////////////////////////////////////UART/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of UART
*/
#define SOC_UART_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of UART clock source, reserved for the legacy UART driver
*/

Wyświetl plik

@ -97,7 +97,6 @@ api-reference/peripherals/dedic_gpio.rst
api-reference/peripherals/sd_pullup_requirements.rst
api-reference/peripherals/index.rst
api-reference/peripherals/sdmmc_host.rst
api-reference/peripherals/uart.rst
api-reference/network/esp_openthread.rst
api-reference/network/esp_eth.rst
api-reference/network/esp_netif_driver.rst

Wyświetl plik

@ -120,6 +120,8 @@ This command automatically builds the project if necessary, and then flash it to
.. note:: The environment variables ``ESPPORT`` and ``ESPBAUD`` can be used to set default values for the ``-p`` and ``-b`` options, respectively. Providing these options on the command line overrides the default.
``idf.py`` uses the ``write_flash`` command of ``esptool.py`` under the hood to flash the target. You can pass additional arguments to configure the flash writing process using the ``--extra-args`` option. For example, to `write to an external SPI flash chip <https://docs.espressif.com/projects/esptool/en/latest/esptool/advanced-options.html#custom-spi-pin-configuration>`_, use the following command: ``idf.py flash --extra-args="--spi-connection <CLK>,<Q>,<D>,<HD>,<CS>"``. To see the full list of available arguments, run ``esptool.py write_flash --help`` or see the `esptool.py documentation <https://docs.espressif.com/projects/esptool/en/latest/esptool/index.html>`_.
Similarly to the ``build`` command, the command can be run with ``app``, ``bootloader`` and ``partition-table`` arguments to flash only the app, bootloader or partition table as applicable.
Hints on How to Resolve Errors

Wyświetl plik

@ -13,7 +13,7 @@ The SPI0/1 bus is shared between the instruction & data cache (for firmware exec
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
On {IDF_TARGET_NAME}, the config option :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` (enabled by default) allows the cache to read flash concurrently with SPI1 operations. See :ref:`auto-suspend` for more details.
On {IDF_TARGET_NAME}, the config option :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` allows the cache to read flash concurrently with SPI1 operations. This is an optional feature that depends on special SPI Flash models, hence disabled by default. See :ref:`auto-suspend` for more details.
If this option is disabled, the caches must be disabled while reading/writing/erasing operations. There are some constraints using driver on the SPI1 bus, see :ref:`impact_disabled_cache`. These constraints will cause more IRAM/DRAM usages.

Wyświetl plik

@ -12,7 +12,7 @@ The {IDF_TARGET_NAME} chip has {IDF_TARGET_SOC_UART_HP_NUM} UART controllers (al
Each UART controller is independently configurable with parameters such as baud rate, data bit length, bit ordering, number of stop bits, parity bit, etc. All the regular UART controllers are compatible with UART-enabled devices from various manufacturers and can also support Infrared Data Association (IrDA) protocols.
.. only:: SOC_UART_LP_NUM
.. only:: SOC_UART_HAS_LP_UART
Additionally, the {IDF_TARGET_NAME} chip has one low-power (LP) UART controller. It is the cut-down version of regular UART. Usually, the LP UART controller only support basic UART functionality with a much smaller RAM size, and does not support IrDA or RS485 protocols. For a full list of difference between UART and LP UART, please refer to the **{IDF_TARGET_NAME} Technical Reference Manual** > **UART Controller (UART)** > **Features** [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]).
@ -30,6 +30,10 @@ The overview describes how to establish communication between an {IDF_TARGET_NAM
Steps 1 to 3 comprise the configuration stage. Step 4 is where the UART starts operating. Steps 5 and 6 are optional.
.. only:: SOC_UART_HAS_LP_UART
Additionally, when using the LP UART Controller you need to pay attention to :ref:`uart-api-lp-uart-driver`.
The UART driver's functions identify each of the UART controllers using :cpp:type:`uart_port_t`. This identification is needed for all the following function calls.
@ -239,12 +243,6 @@ The API provides a convenient way to handle specific interrupts discussed in thi
- Disable the interrupt using :cpp:func:`uart_disable_pattern_det_intr`
Macros
^^^^^^
The API also defines several macros. For example, :c:macro:`UART_HW_FIFO_LEN` defines the length of hardware FIFO buffers; :c:macro:`UART_BITRATE_MAX` gives the maximum baud rate supported by the UART controllers, etc.
.. _uart-api-deleting-driver:
Deleting a Driver
@ -253,6 +251,29 @@ Deleting a Driver
If the communication established with :cpp:func:`uart_driver_install` is no longer required, the driver can be removed to free allocated resources by calling :cpp:func:`uart_driver_delete`.
Macros
^^^^^^
The API also defines several macros. For example, :c:macro:`UART_HW_FIFO_LEN` defines the length of hardware FIFO buffers; :c:macro:`UART_BITRATE_MAX` gives the maximum baud rate supported by the UART controllers, etc.
.. only:: SOC_UART_HAS_LP_UART
.. _uart-api-lp-uart-driver:
Use LP UART Controller with HP Core
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The UART driver also supports to control the LP UART controller when the chip is in active mode. The configuration steps for the LP UART are the same as the steps for a normal UART controller, except:
.. list::
- The port number for the LP UART controller is defined by :c:macro:`LP_UART_NUM_0`.
- The available clock sources for the LP UART controller can be found in :cpp:type:`lp_uart_sclk_t`.
- The size of the hardware FIFO for the LP UART controller is much smaller, which is defined in :c:macro:`SOC_LP_UART_FIFO_LEN`.
:SOC_LP_GPIO_MATRIX_SUPPORTED: - The GPIO pins for the LP UART controller can only be selected from the LP GPIO pins.
:not SOC_LP_GPIO_MATRIX_SUPPORTED: - The GPIO pins for the LP UART controller are unalterable, because there is no LP GPIO matrix on the target. Please see **{IDF_TARGET_NAME} Technical Reference Manual** > **IO MUX and GPIO Matrix (GPIO, IO MUX)** > **LP IO MUX Functions List** [`PDF <{IDF_TARGET_TRM_EN_URL}#lp-io-mux-func-list>`__] for the specific pin numbers.
Overview of RS485 Specific Communication 0ptions
------------------------------------------------

Wyświetl plik

@ -85,6 +85,10 @@ To flash the image onto {IDF_TARGET_NAME} at offset 0x110000, run::
python esptool.py --chip {IDF_TARGET_PATH_NAME} --port [port] --baud [baud] write_flash -z 0x110000 spiffs.bin
.. note::
You can configure the ``write_flash`` command of ``esptool.py`` to `write the spiffs data to an external SPI flash chip <https://docs.espressif.com/projects/esptool/en/latest/esptool/advanced-options.html#custom-spi-pin-configuration>`_ using the ``--spi-connection <CLK>,<Q>,<D>,<HD>,<CS>`` option. Just specify the GPIO pins assigned to the external flash, e.g. ``python esptool.py write_flash --spi-connection 6,7,8,9,11 -z 0x110000 spiffs.bin``.
Notes on Which SPIFFS Tool to Use
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Wyświetl plik

@ -13,7 +13,7 @@ SPI1 flash 并发约束
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
在 {IDF_TARGET_NAME} 上,默认启用的配置选项 :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` 允许 flash/PSRAM 的 cache 访问和 SPI1 的操作并发执行。请参阅 :ref:`auto-suspend`,查看详细信息。
在 {IDF_TARGET_NAME} 上,配置选项 :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` 允许 Flash 的 cache 访问和 SPI1 的操作并发执行。该选项是可选的,依赖于特定的 SPI Flash 型号,因此默认是关闭的。请参阅 :ref:`auto-suspend`,查看详细信息。
禁用该选项时,在读取/写入/擦除 flash 期间,必须禁用 cache。使用驱动访问 SPI1 的相关约束参见 :ref:`impact_disabled_cache`。这些约束会带来更多的 IRAM/DRAM 消耗。

Wyświetl plik

@ -12,7 +12,7 @@
每个 UART 控制器可以独立配置波特率、数据位长度、位顺序、停止位位数、奇偶校验位等参数。所有具备完整功能的 UART 控制器都能与不同制造商的 UART 设备兼容,并且支持红外数据协会 (IrDA) 定义的标准协议。
.. only:: SOC_UART_LP_NUM
.. only:: SOC_UART_HAS_LP_UART
此外,{IDF_TARGET_NAME} 芯片还有一个满足低功耗需求的 LP UART 控制器。LP UART 是原 UART 的功能剪裁版本。它只支持基础 UART 功能,不支持 IrDA 或 RS485 协议,并且只有一块较小的 RAM 存储空间。想要全面了解的 UART 及 LP UART 功能区别,请参考 **{IDF_TARGET_NAME} 技术参考手册** > UART 控制器 (UART) > 主要特性 [`PDF <{IDF_TARGET_TRM_EN_URL}#uart>`__]。
@ -30,6 +30,10 @@
步骤 1 到 3 为配置阶段,步骤 4 为 UART 运行阶段,步骤 5 和 6 为可选步骤。
.. only:: SOC_UART_HAS_LP_UART
此外LP UART 控制器的编程需要注意 :ref:`uart-api-lp-uart-driver`
UART 驱动程序函数通过 :cpp:type:`uart_port_t` 识别不同的 UART 控制器。调用以下所有函数均需此标识。
@ -239,12 +243,6 @@ API 提供了一种便利的方法来处理本文所讨论的特定中断,即
- 禁用中断:调用 :cpp:func:`uart_disable_pattern_det_intr`
宏指令
^^^^^^^^^^^^
API 还定义了一些宏指令。例如,:c:macro:`UART_HW_FIFO_LEN` 定义了硬件 FIFO 缓冲区的长度,:c:macro:`UART_BITRATE_MAX` 定义了 UART 控制器支持的最大波特率。
.. _uart-api-deleting-driver:
删除驱动程序
@ -253,12 +251,35 @@ API 还定义了一些宏指令。例如,:c:macro:`UART_HW_FIFO_LEN` 定义了
如不再需要与 :cpp:func:`uart_driver_install` 建立通信,则可调用 :cpp:func:`uart_driver_delete` 删除驱动程序,释放已分配的资源。
宏指令
^^^^^^^^^^^^
API 还定义了一些宏指令。例如,:c:macro:`UART_HW_FIFO_LEN` 定义了硬件 FIFO 缓冲区的长度,:c:macro:`UART_BITRATE_MAX` 定义了 UART 控制器支持的最大波特率。
.. only:: SOC_UART_HAS_LP_UART
.. _uart-api-lp-uart-driver:
使用主核驱动 LP UART 控制器
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UART 驱动程序还适配了在 Active 模式下对 LP UART 控制器的驱动。LP UART 的配置流程和普通 UART 没有本质上的差别,除了有以下几点需要注意:
.. list::
- LP UART 控制器的端口号为 :c:macro:`LP_UART_NUM_0`
- LP UART 控制器的可选时钟源可以在 :cpp:type:`lp_uart_sclk_t` 中找到。
- LP UART 控制器的硬件 FIFO 大小要远小于普通 UART 控制器的硬件 FIFO 大小,其值为 :c:macro:`SOC_LP_UART_FIFO_LEN`
:SOC_LP_GPIO_MATRIX_SUPPORTED: - LP UART 控制器的 GPIO 引脚只能从 LP GPIO 引脚中选择。
:not SOC_LP_GPIO_MATRIX_SUPPORTED: - 由于该芯片没有 LP GPIO 交换矩阵LP UART 控制器的 GPIO 引脚不可改变。具体的引脚号请查看 **{IDF_TARGET_NAME} 技术参考手册** > **IO MUX 和 GPIO 交换矩阵 (GPIO, IO MUX)** > **LP IO MUX 管脚功能列表** [`PDF <{IDF_TARGET_TRM_CN_URL}#lp-io-mux-func-list>`__]。
RS485 特定通信模式简介
----------------------------------------------
.. note::
下文将使用 ``[UART_REGISTER_NAME].[UART_FIELD_BIT]`` 指代 UART 寄存器字段/位。了解特定模式位的更多信息,请参考 **{IDF_TARGET_NAME} 技术参考手册** > UART 控制器 (UART) > 寄存器摘要 [`PDF <{IDF_TARGET_TRM_EN_URL}#uart-reg-summ>`__]。请搜索寄存器名称导航至寄存器描述,找到相应字段/位。
下文将使用 ``[UART_REGISTER_NAME].[UART_FIELD_BIT]`` 指代 UART 寄存器字段/位。了解特定模式位的更多信息,请参考 **{IDF_TARGET_NAME} 技术参考手册** > UART 控制器 (UART) > 寄存器摘要 [`PDF <{IDF_TARGET_TRM_CN_URL}#uart-reg-summ>`__]。请搜索寄存器名称导航至寄存器描述,找到相应字段/位。
- ``UART_RS485_CONF_REG.UART_RS485_EN``:设置此位将启用 RS485 通信模式支持。
- ``UART_RS485_CONF_REG.UART_RS485TX_RX_EN``:设置此位,发送器的输出信号将环回到接收器的输入信号。