Compare commits

..

158 Commits

Author SHA1 Message Date
Ivan Grokhotkov
012fafb827 versions: Update version to 5.1.0 2022-08-04 09:55:43 +02:00
Marius Vikhammer
87fbc2f487 Merge branch 'bugfix/ulp_wformat' into 'master'
ulp: fix -Wformat errors in ULP tests

See merge request espressif/esp-idf!19379
2022-08-04 14:13:14 +08:00
Vilem Zavodny
6e98440ab1 Merge branch 'example/i80_controller_touch' into 'master'
Add support touch into LCD example

See merge request espressif/esp-idf!18436
2022-08-04 13:50:08 +08:00
Marius Vikhammer
75cdc683ff ulp: fix -Wformat errors in ULP tests 2022-08-04 12:19:28 +08:00
Island
6c8375e2d2 Merge branch 'feature/support_ble_on_esp32c2_26M' into 'master'
support BLE with 26M xtal for esp32c2

See merge request espressif/esp-idf!19300
2022-08-04 11:07:20 +08:00
Marius Vikhammer
bc08de5f46 Merge branch 'feature/ulp_test_app' into 'master'
ulp: migrate tests to pytest embedded

Closes IDF-5605

See merge request espressif/esp-idf!19342
2022-08-04 09:12:56 +08:00
Alexey Lapshin
c462711c74 Merge branch 'bugfix/wno-format-riscv' into 'master'
build system: re-enable -Wformat warnings for RISC-V

Closes IDF-3735

See merge request espressif/esp-idf!17000
2022-08-03 23:16:53 +08:00
Jiang Jiang Jian
d8190673fe Merge branch 'bugfix/fix_disconnect_after_set_country_issue' into 'master'
esp_wifi: fix disconnect after set country issue

Closes WIFI-4637, WIFI-4638, and TCI-988

See merge request espressif/esp-idf!19204
2022-08-03 21:43:27 +08:00
Alexey Lapshin
03ce915668 build system: re-add -Wno-format as private flag for some test_apps 2022-08-03 16:42:47 +04:00
Alexey Lapshin
d10d57a597 build system: remove -Wno-format global option 2022-08-03 16:42:47 +04:00
Ivan Grokhotkov
e596c84d49 build system: re-add -Wno-format as private flag for some example components 2022-08-03 16:42:47 +04:00
Ivan Grokhotkov
401c10ecfb build system: re-add -Wno-format as private flag for some components 2022-08-03 16:42:47 +04:00
Ivan Grokhotkov
879352b7f3 build system: remove -Wno-format flag for RISC-V targets 2022-08-03 16:42:47 +04:00
Ivan Grokhotkov
cb1033abf8 log: fix -Wformat issue when uint32_t == unsigned long 2022-08-03 16:42:47 +04:00
Song Ruo Jing
842efaf753 Merge branch 'bugfix/rtc_fastmem_lpu_c3_h2' into 'master'
sleep: fix wrong register access to set/clear rtc fast mem low power mode on c3 and h2

Closes IDF-5746

See merge request espressif/esp-idf!19361
2022-08-03 19:52:24 +08:00
Alex Lisitsyn
f352469cd3 Merge branch 'bugfix/uart_fails_1M_baud_rate' into 'master'
driver: check UART physical communication on 1M baudrate

Closes IDFGH-7366

See merge request espressif/esp-idf!18211
2022-08-03 19:50:09 +08:00
Alex Lisitsyn
76a084caa3 driver: check UART physical communication on 1M baudrate 2022-08-03 19:50:09 +08:00
morris
38264f0812 Merge branch 'bugfix/kconfig_allow_pain_comment' into 'master'
kconfig: support plain comment in the menu

See merge request espressif/esp-idf!19345
2022-08-03 19:43:43 +08:00
Omar Chebib
b2eb0e16d4 Merge branch 'bugfix/TWDT_link_interruptee_stack' into 'master'
Task WDT: Interuptee task stack is now used for backtracing

Closes IDF-4976

See merge request espressif/esp-idf!19026
2022-08-03 18:23:28 +08:00
Kevin (Lao Kaiyao)
762da7e5ba Merge branch 'bugfix/fix_legacy_i2s_clock_test_failure' into 'master'
i2s_legacy_test: fix the clock test failure

Closes IDFCI-1402 and IDFCI-1408

See merge request espressif/esp-idf!19319
2022-08-03 17:13:43 +08:00
morris
104bd44377 kconfig: support plain comment in the menu 2022-08-03 17:03:54 +08:00
morris
307d26659e Merge branch 'bugfix/rmt_hw_issue' into 'master'
rmt: only use register to control the IDLE state (hardware issue workaround)

See merge request espressif/esp-idf!19344
2022-08-03 17:01:44 +08:00
Shubham Kulkarni
7bfb89e3b3 Merge branch 'feature/custom_partition_subtypes' into 'master'
gen_esp32part.py: Support custom partition types

See merge request espressif/esp-idf!18656
2022-08-03 16:43:57 +08:00
Jiang Jiang Jian
373524cec2 Merge branch 'opt/bluedroid_adv_report_datapath' into 'master'
component/bt: optimize BLE adv report datapath and adv report flow control mechanism

Closes BT-2561

See merge request espressif/esp-idf!19171
2022-08-03 16:31:23 +08:00
Armando (Dou Yiwen)
df1c54d6fc Merge branch 'ci/raise_c3_adc_high_low_test_threshold' into 'master'
ci: raise legacy adc high/low test low thresh on ESP32C3

See merge request espressif/esp-idf!19356
2022-08-03 15:21:45 +08:00
songruojing
e8915e14e7 esp_hw_support: fix wrong register access to set/clear rtc fast mem low power mode on c3 and h2 2022-08-03 14:33:13 +08:00
Konstantin Kondrashov
e57257a6db Merge branch 'feature/adds_efuse_hdr' into 'master'
efuse: Adds missing header

Closes IDF-5734

See merge request espressif/esp-idf!19328
2022-08-03 13:43:44 +08:00
Shubham Kulkarni
3689035b7c tests: Fix CI build failures 2022-08-03 05:18:37 +00:00
Shubham Kulkarni
1bb1b70e0f docs: Add documentation for define extra partition subtypes through build system 2022-08-03 05:18:37 +00:00
Shubham Kulkarni
24f9e348c9 test_apps: Add a test to verify working of custom partition subtypes 2022-08-03 05:18:37 +00:00
Shubham Kulkarni
b6d69840e8 partition_table: Support registering custom subtypes 2022-08-03 05:18:37 +00:00
laokaiyao
4c446222e1 i2s_test: fix mono stereo test 2022-08-03 13:14:48 +08:00
laokaiyao
a32a89b002 i2s_legacy_test: fix the clock test issue 2022-08-03 13:14:48 +08:00
Shu Chen
3e4c0a40c2 Merge branch 'feature/update_esp32h2beta2_libphy_libbtbb' into 'master'
esp_phy: update esp32h2beta2 libphy and libbtbb

See merge request espressif/esp-idf!19231
2022-08-03 12:46:00 +08:00
Shu Chen
e380704731 Merge branch 'feature/otbr-nat64' into 'master'
openthread: add NAT64 and DNS64 support

See merge request espressif/esp-idf!18708
2022-08-03 12:01:23 +08:00
muhaidong
5fd42affdb esp_wifi: fix disconnect after set country issue 2022-08-03 11:53:37 +08:00
Chen Jian Xing
804bdc1721 Merge branch 'bugfix/fix_deinit_return_ok_when_wifi_no_longer_initialized_issue' into 'master'
esp_wifi: fix deinit return wrong value.

Closes IDFGH-7037, IDFGH-7475, and DOC-3220

See merge request espressif/esp-idf!18445
2022-08-03 11:41:20 +08:00
Armando
50229cfe06 ci: raise legacy adc high/low test low thresh 2022-08-03 11:28:52 +08:00
morris
de365f0e7a Merge branch 'feature/mcpwm_test_iram_safe' into 'master'
driver-ng: test with CONFIG_COMPILER_OPTIMIZATION_NONE=y

See merge request espressif/esp-idf!19283
2022-08-03 10:55:02 +08:00
morris
8de9fd8cd7 rmt: only use register to control IDLE state
hardware issue: we can't control the IDLE level by the stop item
when loop transmission is enabled.
But we can always control the IDLE state by register.
2022-08-03 10:51:43 +08:00
morris
45524408df coverity: fix uninit variable issue in driver
Related CID:
389832, 389838, 389880, 286743, 286752, 395156, 291011, 396001, 396002
2022-08-03 10:46:50 +08:00
Marius Vikhammer
035924a8f1 ulp: migrate tests to pytest embedded 2022-08-03 09:36:17 +08:00
Ivan Grokhotkov
f332790af5 Merge branch 'feature/update-gdb-to-11.2_20220729' into 'master'
tools: update gdb version to '11.2_20220729'

Closes IDFGH-7851

See merge request espressif/esp-idf!19293
2022-08-02 23:59:19 +08:00
morris
480f80868a mcpwm: test iram safe interrupt 2022-08-02 23:07:06 +08:00
morris
cf4cfc69ed esp_adc: add test with -O0 2022-08-02 23:07:06 +08:00
morris
a5a171926b rmt: add test with -O0 2022-08-02 23:07:06 +08:00
morris
031adc01c4 gpio: add test with -O0 2022-08-02 23:07:06 +08:00
morris
ca175857d1 pcnt: add test with -O0 2022-08-02 23:07:06 +08:00
morris
8987164385 i2s: add test with -O0 2022-08-02 23:07:06 +08:00
morris
7faf1bee73 gptimer: add test with -O0 2022-08-02 22:53:36 +08:00
KonstantinKondrashov
3f6a1625bb efuse: Adds missing header 2022-08-02 22:43:12 +08:00
Ivan Grokhotkov
a0689f0434 Merge branch 'feature/format-hint' into 'master'
Tools: Add hint to resolve [u]int32_t formatting errors

See merge request espressif/esp-idf!19296
2022-08-02 22:41:06 +08:00
Roland Dobai
8e88444f29 Merge branch 'bugfix/enable-extending-fat-table' into 'master'
fatfsgen.py/fatfsparse.py: enabled extension of the FAT table

Closes IDF-5688 and IDF-5733

See merge request espressif/esp-idf!19299
2022-08-02 22:39:06 +08:00
zhangwenxu
0da97b43d3 esp_phy: update esp32h2beta2 libphy and libbtbb
esp32h2beta2 rx performance optimization
2022-08-02 14:01:05 +00:00
Martin Gano
59ecac263e Merge branch 'docs/add-missing-cmd-parameter-fatfsparse' into 'master'
fatfsparse.py/docs: Added missing cmd parameter to the docs

See merge request espressif/esp-idf!19301
2022-08-02 18:56:25 +08:00
Karl Wang
2462003fde component/bt: use OSI utility "osi_event" for HCI downstream data processing 2022-08-02 17:40:00 +08:00
wangmengyang
f402778320 component/bt: consider to handle HCI LE Direct Advertising Report 2022-08-02 17:40:00 +08:00
Karl Wang
8c756dad23 component/bt: allocate and use one static buffer for HCI adv flow control command 2022-08-02 17:40:00 +08:00
wangmengyang
85fc8321c8 component/bt: use fixed_pkt_queue instead of fixed_queue for hci commands
some fixes after modifications:
  1. removed the use of waiting_command_t
  2. fix assert for HCI write_eir command
  3. fixed the crash upon handling command status event when trying to free to the HCI command buffer
  4. fixed the issue in transmitting HCI vendor specific commands
  5. fixed the lost command complete callbacks for HCI commands LE_RAND and LE_ENCRYPT
2022-08-02 17:37:24 +08:00
Alexey Lapshin
5fb109f2e8 Tools: Add hint to resolve [u]int32_t formatting errors 2022-08-02 12:45:10 +04:00
Fu Hanxi
f315986401 Merge branch 'feat/add_ci_related_requirements_txt' into 'master'
Feat/add ci related requirements txt

Closes IDF-4590 and IDFCI-1389

See merge request espressif/esp-idf!19246
2022-08-02 15:49:36 +08:00
Jiang Jiang Jian
c47c0097e2 Merge branch 'bugfix/memory_debug_not_work' into 'master'
bugfix/fix the dependency error of macro for memory debug

Closes IDFGH-9248

See merge request espressif/esp-idf!19233
2022-08-02 15:48:58 +08:00
wangmengyang
9bda2381ea component/bt: add a timer to monitor the adv flow control credits downwards procedure 2022-08-02 14:14:07 +08:00
wangmengyang
5f074e1336 component/bt: fix adv report flow control logic, give ADV report credits every 10 packets 2022-08-02 14:14:07 +08:00
wangmengyang
0a1fa3e204 component/bt: add simple ADV flow control mechanism -- drop the packets when the adv report queues are considered full 2022-08-02 14:14:07 +08:00
wangmengyang
9a5f854760 component/bt: use the OSI utility "osi_event" to handle adv report in btc_layer 2022-08-02 14:14:07 +08:00
Karl Wang
a075aa564f component/bt: use the OSI utility "pkt_queue" to store ADV report packet in btu layer 2022-08-02 14:14:07 +08:00
wangmengyang
57336e0a0e component/bt: use the OSI utility "osi_event" for hci_hal_h4 upstream data packets handling 2022-08-02 14:14:07 +08:00
wangmengyang
3c8671f592 component/bt: use the OSI utility "osi_event" to handle A2DP source data Tx processing 2022-08-02 14:14:07 +08:00
wangmengyang
578bfa3600 component/bt: use the OSI utility "osi_event" to handle A2DP sink data Rx processing 2022-08-02 14:14:07 +08:00
wangmengyang
c0b86fefc6 component/bt: add new OSI utility "fixed_pkt_queue", which has same functionality with "fixed_queue" 2022-08-02 14:14:07 +08:00
Karl Wang
eea8a285e3 component/bt: add new OSI utility "pkt_queue" which acts as a mutex-protected linked list, to be used as data queue between tasks 2022-08-02 14:14:07 +08:00
wangmengyang
7c1ee339bc component/bt: add new OSI utility "osi_event" to support the scenario that event need only to be handle once. 2022-08-02 14:14:07 +08:00
wangmengyang
81c87cf4ca component/bt: make OSI thread workqueue length configurable through API
reduce the length of workqueue1 for BTC and HCI task

# Conflicts:
#	components/bt/common/osi/thread.c
2022-08-02 14:14:07 +08:00
wangmengyang
77e98e468d component/bt: modify the implementation of osi_thread using freeRTOS queue 2022-08-02 14:14:07 +08:00
Vilem Zavodny
036705fe8f examples/lcd: Add touch support into i80 lcd example. 2022-08-02 08:11:13 +02:00
Omar Chebib
2f7bae7a6e Task WDT: add a panic test case for to test panic on both CPU cores 2022-08-02 12:41:14 +08:00
Omar Chebib
e25cda2c40 Task WDT: Interuptee task stack is now used for backtracing, regardless of the CPU core
For RISC-V and Xtensa targets, in case a panic needs to happen when
Task WDT is triggered (ESP_TASK_WDT_PANIC), the interruptee's stack
is now used for printing the backtrace.
Abort after Task Watchdog is triggered can happen on APP CPU (second core).
2022-08-02 12:41:14 +08:00
muhaidong
ab8be80c3c esp_wifi: fix deinit return wrong value
1. Deinit does not return ESP_ERR_WIFI_NOT_INIT if the wifi driver is no longer initialized.
2. Fix get wrong channel value use esp_wifi_get_config.
3. Fix bug of missing unlock when wifi stop.
4. Fix annotation error of api esp_wifi_connect.
2022-08-02 11:45:21 +08:00
Marius Vikhammer
d7ab8fd4ba Merge branch 'docs/pdf_lcd' into 'master'
docs: fix broken link to lcd example

See merge request espressif/esp-idf!19331
2022-08-02 11:35:34 +08:00
Jiang Jiang Jian
03a8235098 Merge branch 'bugfix/set_default_authmode_wpa2' into 'master'
esp_wifi: set default authmode threshold as wpa2 for STA mode

Closes WIFI-2438

See merge request espressif/esp-idf!19034
2022-08-02 11:10:56 +08:00
Marius Vikhammer
1fa411d515 Merge branch 'feature/system_test_pytest' into 'master'
CI: migrate esp_event and select example to pytest

See merge request espressif/esp-idf!19295
2022-08-02 10:50:46 +08:00
Marius Vikhammer
67d0a10548 Merge branch 'bugfix/rtc_brownout_isr_handler_stall' into 'master'
system: fix brownout ISR triggering assert on single-core configs.

Closes IDFGH-7939

See merge request espressif/esp-idf!19304
2022-08-02 10:38:29 +08:00
Marius Vikhammer
ff71e54f70 docs: fix broken link to lcd example 2022-08-02 10:15:31 +08:00
Marius Vikhammer
5d23a757d6 Merge branch 'feature/ulp_uart' into 'master'
ulp-riscv: uart print

See merge request espressif/esp-idf!19229
2022-08-02 09:14:48 +08:00
morris
7d5eb1fc01 Merge branch 'example/lcd_spi_1' into 'master'
Change LCD example gc9a01 to universal SPI LCD example with SPI touch

Closes IDF-5399

See merge request espressif/esp-idf!19221
2022-08-02 08:03:15 +08:00
Martin Gaňo
2d173c0777 fatfsgen.py: enabled extension of the FAT table
Closes IDF-5688
2022-08-01 20:29:02 +02:00
morris
06b31d487b Merge branch 'touch_sensor/update_touch_sensor_examples' into 'master'
touch_sensor: update touch sensor examples

Closes IDF-3885 and IDFGH-7751

See merge request espressif/esp-idf!19284
2022-08-02 01:25:04 +08:00
morris
30639b1093 example: update example_lvgl_demo_ui prototype 2022-08-01 23:02:44 +08:00
Vilem Zavodny
df3e506703 example: LCD and touch panel share the same SPI bus 2022-08-01 23:02:44 +08:00
Roland Dobai
956f08826f Merge branch 'fix/esp32c2_gcov_example_build' into 'master'
esp32c2: fix gcov example build

See merge request espressif/esp-idf!19201
2022-08-01 20:28:36 +08:00
Jiang Jiang Jian
681fe85dd6 Merge branch 'docs/c2_protocols_update' into 'master'
docs: remove protocols chapters from C2 not updated list

See merge request espressif/esp-idf!19310
2022-08-01 19:42:40 +08:00
Wei Tian Hua
b9b047399d Merge branch 'bugfix/fix_legacy_pair_not_send_link_key_host' into 'master'
component_bt: fix legacy pair controller does not send the link key to the host

Closes BTCI-107

See merge request espressif/esp-idf!14670
2022-08-01 16:59:49 +08:00
morris
20e253e663 Merge branch 'feature/rgb_lcd_rotation' into 'master'
rgb_lcd: support mirror and swap axis

See merge request espressif/esp-idf!19059
2022-08-01 16:47:12 +08:00
Fu Hanxi
7720e348c2 Merge branch 'ci/system_apps_pytest' into 'master'
ci: migrate system flash_psram test app to pytest

Closes IDFCI-1141

See merge request espressif/esp-idf!19161
2022-08-01 16:45:09 +08:00
Mahavir Jain
9b518380b2 Merge branch 'contrib/github_pr_9452' into 'master'
coap: Update examples to use latest features of libcoap component (GitHub PR)

Closes IDFGH-7934

See merge request espressif/esp-idf!19308
2022-08-01 16:35:24 +08:00
Marius Vikhammer
0f555b2a1d system: fix brownout ISR triggering assert on single-core configs.
ISR handler was incorrectly calling stall other cpu even on single core systems

Closes https://github.com/espressif/esp-idf/issues/9456
2022-08-01 16:18:30 +08:00
morris
dba813bac4 Merge branch 'bugfix/disable_rom_lgo' into 'master'
system: moved placement of disable rom log efuse in startup flow

Closes IDFGH-7940

See merge request espressif/esp-idf!19305
2022-08-01 16:04:20 +08:00
Fu Hanxi
b684730da2 ci: use the new requirement txt
will be cleaned up in IDFCI-1347
2022-08-01 15:52:21 +08:00
Fu Hanxi
17e312f87b docs: improve the installation instructions 2022-08-01 15:52:21 +08:00
Fu Hanxi
d0a2849b02 feat: add requirements.ttfw.txt 2022-08-01 15:52:21 +08:00
Fu Hanxi
01baaf33ed feat: add requirements.ci.txt 2022-08-01 15:49:15 +08:00
Fu Hanxi
9c6e636c0a ci: --preserve-all is mandatory to run locally for unit-test apps 2022-08-01 15:49:15 +08:00
Fu Hanxi
742663dd9b feat: add requirements.docs.txt 2022-08-01 15:49:15 +08:00
Fu Hanxi
8132f8b5e1 ci: add esp32h2 marker to pytest.ini 2022-08-01 15:49:15 +08:00
Jiang Jiang Jian
b885499c74 Merge branch 'refactor/move_common_adc_part_to_hw_support' into 'master'
esp_adc: move esp_adc out of g1 dependency list

Closes IDF-5637

See merge request espressif/esp-idf!19159
2022-08-01 15:39:45 +08:00
Jiacheng Guo
905856a054 openthread: add NAT64 and DNS64 support
* Add required configs and headers for NAT64 and DNS64
* Add hook for DNS name resolution
* Add NAT64 and DNS64 example commands
2022-08-01 15:31:49 +08:00
Chen Yu Dong
4d0385d9f0 Merge branch 'ci/target_test_do_not_need_submodules' into 'master'
CI: Do not need submodules in target test

See merge request espressif/esp-idf!19139
2022-08-01 15:21:06 +08:00
Roland Dobai
592afea93e Merge branch 'ci/lift_restriction_on_ttfw_idf' into 'master'
ci: lift the restriction on pygdbmi in ttfw_idf

See merge request espressif/esp-idf!18982
2022-08-01 14:55:04 +08:00
Mahavir Jain
3fcfc80c17 Merge branch 'bugfix/ulp_adc_miss_cpp_guard' into 'master'
ulp: fix missing cpp header guard

Closes IDFGH-7953

See merge request espressif/esp-idf!19303
2022-08-01 14:48:54 +08:00
Wei Tian Hua
aeb9cd267f Merge branch 'bugfix/memory_copy_bugs_in_bluedroid' into 'master'
components_bt/bluedroid: Fix Memory Copy Build Err

Closes IDFGH-7871

See merge request espressif/esp-idf!19182
2022-08-01 14:32:39 +08:00
Ivan Grokhotkov
0d4a533b74 Merge branch 'bugfix/usb_console_reset' into 'master'
esp_system: usb_console: fix restart when Wi-Fi is working

Closes IDFGH-5683

See merge request espressif/esp-idf!19289
2022-08-01 13:36:44 +08:00
wangyuanze
59ef1e1928 touch_sensor: add pytest for all examples 2022-08-01 13:16:04 +08:00
wangyuanze
526f8f048b touch_sensor: enlarge task stack in examples 2022-08-01 13:16:04 +08:00
wangyuanze
0e3bd7592f touch_sensor: update readme for all examples 2022-08-01 13:16:04 +08:00
wangyuanze
4a617e459a touch_sensor: make touch_element compile on esp32s3
Closes: https://github.com/espressif/esp-idf/issues/9292
2022-08-01 13:16:03 +08:00
Guillaume Souchere
8357fc728f Merge branch 'bugfix/update-doc-freertos-task-header' into 'master'
freertos: Update the documentation of the ulBitsToClearOnEntry parameter

Closes IDFGH-5468

See merge request espressif/esp-idf!19277
2022-08-01 13:07:45 +08:00
Marius Vikhammer
c0030f6d62 docs: remove protocols chapters from C2 not updated list 2022-08-01 12:58:06 +08:00
Marius Vikhammer
7c78de7be8 CI: migrate esp_event and select example to pytest 2022-08-01 12:20:06 +08:00
Kevin (Lao Kaiyao)
6658b7eb0a Merge branch 'feature/setup_target_test_for_c2_26m' into 'master'
ci: setup 26mhz esp32c2 runner

Closes IDF-5526

See merge request espressif/esp-idf!19032
2022-08-01 11:54:09 +08:00
weitianhua
e51df179ad components_bt/bluedroid: Fix Memory&String Copy Build Err
1. When setting compilier into -O2 optimization, build for classic bt demo will get wrong
   2. Fix a memcpy bug that maybe get memory truncated

Closes https://github.com/espressif/esp-idf/issues/9398
2022-08-01 11:37:46 +08:00
Marius Vikhammer
da91fb7a81 system: moved placement of disable rom log efuse in startup flow
Functions used for burning this efuse would log, but at this point
esp_log is not initialized. Moved to a later point in the startup process.

Closes https://github.com/espressif/esp-idf/issues/9457
2022-08-01 11:16:17 +08:00
zhouli
13770a2660 rgb_lcd: support mirror and swap axis 2022-08-01 03:05:19 +00:00
Marius Vikhammer
af329784b1 ulp: fix missing cpp header guard
https://github.com/espressif/esp-idf/issues/9464
2022-08-01 10:19:32 +08:00
Wan Lei
1265a2db9d Merge branch 'refactor/add_missing_include_path_for_soc_struct_files' into 'master'
Fix check_public_headers violations for soc component

Closes IDF-5397

See merge request espressif/esp-idf!19158
2022-08-01 10:14:04 +08:00
Wu Zheng Hui
7c17a04733 Merge branch 'feature/optimize_chips_memory_allocation' into 'master'
system: Optimize chips bootloader and heap memory allocation

Closes IDF-4585 and IDF-4299

See merge request espressif/esp-idf!18807
2022-08-01 10:11:01 +08:00
Michael (XIAO Xufeng)
198fd08fb3 Merge branch 'contrib/github_pr_7872' into 'master'
QA: Check driver installation status (GitHub PR)

Closes IDFGH-6196

See merge request espressif/esp-idf!16630
2022-08-01 09:59:26 +08:00
Kapil Gupta
e9c18ad02f esp_wifi: set default authmode as wpa2 2022-07-30 10:43:39 +05:30
Shen Weilong
028d071e84 support BLE with 26M xtal for esp32c2 2022-07-29 21:36:33 +08:00
Martin Gaňo
a542e9424c fatfsparse.py/docs: Added missing cmd parameter to the docs 2022-07-29 15:29:23 +02:00
Alexey Lapshin
f44196c46b tools: update gdb version to '11.2_20220729'
Closes https://github.com/espressif/esp-idf/issues/9379
2022-07-29 13:47:34 +04:00
laokaiyao
4ab8f00b47 ci: setup 26mhz esp32c2 runner 2022-07-29 17:10:34 +08:00
wuzhenghui
5e8ba9cea8 use enum and designated initializers in soc_memory_type define 2022-07-29 17:07:41 +08:00
wuzhenghui
70eabb5492 ci: fix ci 2022-07-29 17:07:41 +08:00
wuzhenghui
7cb9304b65 Clean IRAM and DRAM address space conversion macros 2022-07-29 17:07:39 +08:00
jincheng
ca0d8be5b8 fix the dependency error of macro for memory debug 2022-07-29 17:03:59 +08:00
Chen Yudong
486dbf441b CI: Do not need submodules in target test 2022-07-29 08:31:33 +00:00
Marius Vikhammer
32efa1e92d Add ULP-RISCV print and bitbanged UART tx API
Add example to demonstrate the use of this API.
2022-07-29 12:18:01 +08:00
Aleksei Apaseev
22f65d961f ci: lift the restriction on pygdbmi in ttfw_idf 2022-07-29 11:24:12 +08:00
wanlei
bb5a95f1aa soc: fix register header files not self-contain 2022-07-29 11:18:06 +08:00
wuzhenghui
65aea5d177 stack/dram is also IRAM0 accessible 2022-07-29 10:51:48 +08:00
wuzhenghui
2ad49a9be5 update bootloader.ld rom_boot ram usage info 2022-07-29 10:51:47 +08:00
wuzhenghui
31183270fb bugfix: fix SOC_ROM_STACK_START defines 2022-07-29 10:51:47 +08:00
wuzhenghui
21a4eda4d4 Use the entire sharedbuffer space as the heap of the D/IRAM attribute 2022-07-29 10:51:47 +08:00
wuzhenghui
d6461d91e2 update bootloader memory allocation 2022-07-29 10:51:47 +08:00
Ivan Grokhotkov
bf10146a15 esp_system, vfs: fix incomplete blocking reads in vfs_cdcacm
Blocking read from cdcacm VFS could return less bytes than requested.
This didn’t match the behaviour of other VFS drivers, and higher level
code could misbehave.
2022-07-28 17:28:08 +02:00
Ivan Grokhotkov
3254f8deae esp_system: usb_console: fix restart when Wi-Fi is working
Previously, reset over USB CDC was done by calling esp_restart from
an interrupt handler. This works only until some restart hook function
is registered using esp_register_shutdown_handler, and the hook
function tries to do something that isn’t allowed in an interrupt
handler. One such case is with Wi-Fi. When Wi-Fi driver is installed,
it registers esp_wifi_stop as a shutdown handler function. However
esp_wifi_stop cannot be called from an ISR, and hence we shouldn’t
call esp_restart from an ISR either.

This commit modifies USB CDC driver to call esp_restart by posting it
to esp_timer task.

Closes https://github.com/espressif/esp-idf/issues/7404
2022-07-28 17:15:03 +02:00
Jon Shallow
98d346a81e coap: Update examples to use latest features of libcoap component
Support libcoap build with Client Only or Server Only code.
2022-07-28 13:11:52 +00:00
Erhan Kurubas
b0881a1e6c examples/gcov: add missing supported targets to readme 2022-07-28 13:59:29 +02:00
Erhan Kurubas
3a9f711f77 examples/gcov: set esp32c2 default blink gpio 2022-07-28 13:59:29 +02:00
Erhan Kurubas
22d771bf51 esp32c2: fix gcov example build 2022-07-28 13:59:29 +02:00
Guillaume Souchere
421a408b42 freertos: Update the docuementation of the ulBitsToClearOnEntry parameter in xTaskGenericNotifyWait() function.
Closes https://github.com/espressif/esp-idf/issues/7207

The description of how the xTaskGenericNotifyWait parameter is handled in the
xTaskGenericNotifyWait() function was inaccurate.

In this commit, the description was updated to match the implementation of xTaskGenericNotifyWait().
2022-07-28 10:30:41 +02:00
xiongweichao
7eedd710c2 fix legacy pair controller does not send the link key to the host
Closes https://github.com/espressif/esp-idf/issues/5850
2022-07-28 14:21:48 +08:00
Armando
4f80c0f27e esp_adc: remove esp_adc from g1 component dependencies 2022-07-28 03:49:48 +00:00
Armando
5e6a16380a esp_adc: move adc common hw related code into esp_hw_support 2022-07-28 03:49:48 +00:00
Marius Vikhammer
4f1046a292 ulp-riscv: made ulp_riscv_delay_cycles more accurate 2022-07-26 14:32:39 +08:00
Marius Vikhammer
c2a5f48498 ci: migrate system test apps to pytest 2022-07-26 11:47:28 +08:00
Hassan DRAGA
5d27d66ddd QA: Check driver installation status
When you have a large project, uart_driver_install() may fail. For QA we should always check the status of the driver first.
2022-07-18 09:25:22 +00:00
661 changed files with 6926 additions and 3038 deletions

View File

@@ -89,7 +89,7 @@ variables:
CI_PYTHON_CONSTRAINT_BRANCH: ""
# Update the filename for a specific ESP-IDF release. It is used only with CI_PYTHON_CONSTRAINT_BRANCH.
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.0.txt"
CI_PYTHON_CONSTRAINT_FILE: "espidf.constraints.v5.1.txt"
# Set this variable to repository name of a Python tool you wish to install and test in the context of ESP-IDF CI.
# Keep the variable empty when not used.
@@ -211,7 +211,7 @@ before_script:
# This adds tools (compilers) and the version-specific Python environment to PATH
- *setup_tools_unless_target_test
# Install packages required by CI scripts into IDF Python environment
- pip install -r $IDF_PATH/tools/ci/python_packages/ttfw_idf/requirements.txt
- pip install -r $IDF_PATH/tools/requirements/requirements.ci.txt
- source tools/ci/configure_ci_environment.sh
# Part of tools/ci/setup_python.sh; we don't use pyenv on macOS, so can't run the rest of the script.
- export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
@@ -228,9 +228,8 @@ before_script:
- *setup_tools_unless_target_test
- fetch_submodules
- *download_test_python_contraint_file
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest
# TODO: remove this, IDFCI-1207
- pip install esptool -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
# only need ci and pytest related packages, ttfw requirements would be mocked if not installed
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest,ci
- eval "$($IDF_PATH/tools/idf_tools.py export)" # use idf venv instead
.before_script_build_jobs:
@@ -244,13 +243,9 @@ before_script:
- *setup_tools_unless_target_test
- fetch_submodules
- *download_test_python_contraint_file
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest
# TODO: remove this, IDFCI-1207
- pip install esptool -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
# only need ci and pytest related packages, ttfw requirements would be mocked if not installed
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest,ci
- eval "$($IDF_PATH/tools/idf_tools.py export)" # use idf venv instead
# not only need pytest related packages, but also needs ttfw requirements
- internal_pip_install $IDF_BUILD_APPS_PROJ idf_build_apps
- pip install -r tools/ci/python_packages/ttfw_idf/requirements.txt -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
- export EXTRA_CFLAGS=${PEDANTIC_CFLAGS}
- export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS}

View File

@@ -300,11 +300,11 @@ build_ssc_esp32s3:
-t $IDF_TARGET
--config "configs/*="
--copy-sdkconfig
--preserve-all
--collect-size-info $SIZE_INFO_LOCATION
--collect-app-info list_job_${CI_NODE_INDEX:-1}.json
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
--preserve-all
- run_cmd python tools/unit-test-app/tools/UnitTestParser.py tools/unit-test-app ${CI_NODE_INDEX:-1}
build_esp_idf_tests_cmake_esp32:

View File

@@ -62,7 +62,7 @@ check_docs_lang_sync:
dependencies: []
script:
- cd docs
- pip install -U -r requirements.txt
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
- build-docs -t $DOCTGT -bs $DOC_BUILDERS -l $DOCLANG build
parallel:
matrix:
@@ -76,7 +76,7 @@ check_docs_gh_links:
- .doc-rules:build:docs
script:
- cd docs
- pip install -U -r requirements.txt
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
- build-docs gh-linkcheck
# stage: build_doc
@@ -161,7 +161,7 @@ build_docs_pdf:
script:
- add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
- export GIT_VER=$(git describe --always ${PIPELINE_COMMIT_SHA} --)
- pip install -U -r docs/requirements.txt
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
- deploy-docs
# stage: test_deploy
@@ -227,5 +227,5 @@ check_doc_links:
allow_failure: true
script:
- cd docs
- pip install -U -r requirements.txt
- pip install -U -r $IDF_PATH/tools/requirements/requirements.docs.txt
- build-docs -t $DOCTGT -l $DOCLANG linkcheck

View File

@@ -1,8 +1,21 @@
.pytest_template:
.target_test_template:
image: $TARGET_TEST_ENV_IMAGE
stage: target_test
timeout: 1 hour
extends: .before_script_pytest
variables:
GIT_DEPTH: 1
SUBMODULES_TO_FETCH: "none"
cache:
# Usually do not need submodule-cache in target_test
- key: pip-cache
paths:
- .cache/pip
policy: pull
.pytest_template:
extends:
- .target_test_template
- .before_script_pytest
artifacts:
when: always
paths:
@@ -11,9 +24,6 @@
reports:
junit: XUNIT_RESULT.xml
expire_in: 1 week
variables:
GIT_DEPTH: 1
SUBMODULES_TO_FETCH: "none"
script:
- retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases
# get runner env config file
@@ -70,6 +80,14 @@ example_test_pytest_esp32c2_generic:
- build_pytest_examples_esp32c2
tags: [ esp32c2, generic, xtal_40mhz ]
example_test_pytest_esp32c2_26mhz:
extends:
- .pytest_examples_dir_template
- .rules:test:example_test-esp32c2
needs:
- build_pytest_examples_esp32c2
tags: [ esp32c2, xtal_26mhz ]
example_test_pytest_esp32c3_generic:
extends:
- .pytest_examples_dir_template
@@ -340,6 +358,14 @@ test_app_test_pytest_esp32c2_generic:
- build_pytest_test_apps_esp32c2
tags: [ esp32c2, generic, xtal_40mhz ]
test_app_test_pytest_esp32c2_26mhz:
extends:
- .pytest_test_apps_dir_template
- .rules:test:custom_test-esp32c2
needs:
- build_pytest_test_apps_esp32c2
tags: [ esp32c2, xtal_26mhz ]
test_app_test_pytest_esp32c3_generic:
extends:
- .pytest_test_apps_dir_template
@@ -356,6 +382,30 @@ test_app_test_pytest_esp32s2_usb_host:
- build_pytest_test_apps_esp32s2
tags: [ esp32s2, usb_host ]
test_app_test_pytest_esp32s3_mspi_f8r8:
extends:
- .pytest_test_apps_dir_template
- .rules:test:custom_test-esp32s3
needs:
- build_pytest_test_apps_esp32s3
tags: [ esp32s3, MSPI_F8R8 ]
test_app_test_pytest_esp32s3_mspi_f4r8:
extends:
- .pytest_test_apps_dir_template
- .rules:test:custom_test-esp32s3
needs:
- build_pytest_test_apps_esp32s3
tags: [ esp32s3, MSPI_F4R8 ]
test_app_test_pytest_esp32s3_mspi_f4r4:
extends:
- .pytest_test_apps_dir_template
- .rules:test:custom_test-esp32s3
needs:
- build_pytest_test_apps_esp32s3
tags: [ esp32s3, MSPI_F4R4 ]
# for parallel jobs, CI_JOB_NAME will be "job_name index/total" (for example, "IT_001 1/2")
# we need to convert to pattern "job_name_index.yml"
.define_config_file_name: &define_config_file_name |
@@ -364,9 +414,8 @@ test_app_test_pytest_esp32s2_usb_host:
CONFIG_FILE="${CONFIG_FILE_PATH}/${JOB_FULL_NAME}.yml"
.target_test_job_template:
stage: target_test
timeout: 1 hour
image: $TARGET_TEST_ENV_IMAGE
extends:
- .target_test_template
artifacts:
when: always
paths:
@@ -378,11 +427,9 @@ test_app_test_pytest_esp32s2_usb_host:
junit: $LOG_PATH/*/XUNIT_RESULT.xml
expire_in: 1 week
variables:
GIT_DEPTH: 1
TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw"
LOG_PATH: "$CI_PROJECT_DIR/TEST_LOGS"
ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml"
SUBMODULES_TO_FETCH: "none"
script:
- *define_config_file_name
# first test if config file exists, if not exist, exit 0
@@ -405,13 +452,6 @@ test_app_test_pytest_esp32s2_usb_host:
TEST_CASE_PATH: "$CI_PROJECT_DIR/examples"
CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/examples/test_configs"
.example_debug_template:
extends:
- .example_test_template
- .rules:test:example_test-esp32
variables:
SUBMODULES_TO_FETCH: "all"
test_weekend_mqtt:
extends:
- .test_app_esp32_template
@@ -543,12 +583,10 @@ example_test_010:
- Example_ExtFlash
example_test_011:
extends: .example_debug_template
extends: .example_test_esp32_template
tags:
- ESP32
- Example_T2_RS485
variables:
SETUP_TOOLS: "1"
example_test_013:
extends: .example_test_esp32_template
@@ -654,6 +692,12 @@ test_app_test_esp32c2_generic:
- Example_GENERIC
- xtal_40mhz
test_app_test_esp32c2_26mhz:
extends: .test_app_esp32c2_template
tags:
- ESP32C2
- xtal_26mhz
test_app_test_005:
extends: .test_app_esp32c3_template
tags:
@@ -672,24 +716,6 @@ test_app_test_esp32_generic:
- ESP32
- Example_GENERIC
test_app_test_flash_psram_f4r4:
extends: .test_app_esp32s3_template
tags:
- ESP32S3
- MSPI_F4R4
test_app_test_flash_psram_f4r8:
extends: .test_app_esp32s3_template
tags:
- ESP32S3
- MSPI_F4R8
test_app_test_flash_psram_f8r8:
extends: .test_app_esp32s3_template
tags:
- ESP32S3
- MSPI_F8R8
.unit_test_template:
extends: .target_test_job_template
needs: # the assign already needs all the build jobs
@@ -923,6 +949,13 @@ UT_C2:
- UT_T1_1
- xtal_40mhz
UT_C2_26M:
extends: .unit_test_esp32c2_template
tags:
- ESP32C2_IDF
- UT_T1_1
- xtal_26mhz
UT_C3:
extends: .unit_test_esp32c3_template
parallel: 31

View File

@@ -24,9 +24,7 @@ upload-pip-cache:
- is_based_on_commits $REQUIRED_ANCESTOR_COMMITS
- source tools/ci/setup_python.sh
- rm -rf .cache/pip # clear old packages
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest
# TODO: remove this, IDFCI-1207
- pip install esptool -c ~/.espressif/${CI_PYTHON_CONSTRAINT_FILE}
- $IDF_PATH/tools/idf_tools.py install-python-env --features pytest,ci
parallel:
matrix:
- GEO: [ 'shiny', 'brew' ]

View File

@@ -1,3 +1,4 @@
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES cmock driver)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -2,3 +2,4 @@ idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES cmock test_utils app_update bootloader_support nvs_flash driver
)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -5,15 +5,41 @@
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
* We put 2nd bootloader in the high address space (before ROM stack/data/bss).
* See memory usage for ROM bootloader at the end of this file.
*
* ESP32-C2 ROM static data usage is as follows:
* - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only
* - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup
* - 0x3fcdeb70 - 0x3fce0000: ROM .bss and .data (not easily reclaimable)
*
* The 2nd stage bootloader can take space up to the end of ROM shared
* buffers area (0x3fcdcb70).
*/
/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */
iram_dram_offset = 0x6e0000;
/* We consider 0x3fcdcb70 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
* and work out iram_seg and iram_loader_seg addresses from there, backwards.
*/
/* These lengths can be adjusted, if necessary: */
bootloader_usable_dram_end = 0x3fcdcb70;
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0x5000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_seg_len = 0x2000;
/* Start of the lower region is determined by region size and the end of the higher region */
bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset;
bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
MEMORY
{
iram_seg (RWX) : org = 0x403AE000, len = 0x2000
iram_loader_seg (RWX) : org = 0x403B0000, len = 0x6000
dram_seg (RW) : org = 0x3FCD6000, len = 0x4000
iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
}
/* Default entry point: */
@@ -183,17 +209,34 @@ SECTIONS
/**
* Appendix: Memory Usage of ROM bootloader
*
* +--------+--------------+------+ 0x3FCC_B0B0
* | ^ |
* | | |
* | | data/bss |
* | | |
* | v |
* +------------------------------+ 0x3FCD_C9C0
* | ^ |
* | | |
* | | stack |
* | | |
* | v |
* +------------------------------+ 0x3FCD_E9C0
* 0x3fccb264 ------------------> _dram0_0_start
* | |
* | |
* | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h
* | |
* | |
* 0x3fcdcb70 ------------------> __stack_sentry
* | |
* | | 2. Startup pro cpu stack (freed when IDF app is running)
* | |
* 0x3fcdeb70 ------------------> __stack (pro cpu)
* | |
* | |
* | | 3. Shared memory only used in startup code or nonos/early boot*
* | | (can be freed when IDF runs)
* | |
* | |
* 0x3fcdf4bc ------------------> _dram0_rtos_reserved_start
* | |
* | |
* | | 4. Shared memory used in startup code and when IDF runs
* | |
* | |
* 0x3fcdfa70 ------------------> _dram0_rtos_reserved_end
* | |
* 0x3fcdfa74 ------------------> _data_start_interface
* | |
* | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible)
* | |
* 0x3fce0000 ------------------> _data_end_interface
*/

View File

@@ -5,15 +5,41 @@
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
* We put 2nd bootloader in the high address space (before ROM stack/data/bss).
* See memory usage for ROM bootloader at the end of this file.
*
* ESP32-C3 ROM static data usage is as follows:
* - 0x3fccae00 - 0x3fcdc710: Shared buffers, used in UART/USB/SPI download mode only
* - 0x3fcdc710 - 0x3fcde710: PRO CPU stack, can be reclaimed as heap after RTOS startup
* - 0x3fcde710 - 0x3fce0000: ROM .bss and .data (not easily reclaimable)
*
* The 2nd stage bootloader can take space up to the end of ROM shared
* buffers area (0x3fcdc710).
*/
/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */
iram_dram_offset = 0x700000;
/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
* and work out iram_seg and iram_loader_seg addresses from there, backwards.
*/
/* These lengths can be adjusted, if necessary: */
bootloader_usable_dram_end = 0x3fcdc710;
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0x5000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_seg_len = 0x2000;
/* Start of the lower region is determined by region size and the end of the higher region */
bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset;
bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
MEMORY
{
iram_seg (RWX) : org = 0x403CE000, len = 0x1600
iram_loader_seg (RWX) : org = 0x403CF600, len = 0x6A00
dram_seg (RW) : org = 0x3FCD6000, len = 0x4000
iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
}
/* Default entry point: */
@@ -184,17 +210,34 @@ SECTIONS
/**
* Appendix: Memory Usage of ROM bootloader
*
* +--------+--------------+------+ 0x3FCC_AE00
* | ^ |
* | | |
* | | data/bss |
* | | |
* | v |
* +------------------------------+ 0x3FCD_C710
* | ^ |
* | | |
* | | stack |
* | | |
* | v |
* +------------------------------+ 0x3FCD_E710
* 0x3fccae00 ------------------> _dram0_0_start
* | |
* | |
* | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h
* | |
* | |
* 0x3fcdc710 ------------------> __stack_sentry
* | |
* | | 2. Startup pro cpu stack (freed when IDF app is running)
* | |
* 0x3fcde710 ------------------> __stack (pro cpu)
* | |
* | |
* | | 3. Shared memory only used in startup code or nonos/early boot*
* | | (can be freed when IDF runs)
* | |
* | |
* 0x3fcdf060 ------------------> _dram0_rtos_reserved_start
* | |
* | |
* | | 4. Shared memory used in startup code and when IDF runs
* | |
* | |
* 0x3fcdf664 ------------------> _dram0_rtos_reserved_end
* | |
* 0x3fcdf830 ------------------> _data_start_interface
* | |
* | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible)
* | |
* 0x3fce0000 ------------------> _data_end_interface
*/

View File

@@ -5,15 +5,41 @@
*/
/** Simplified memory map for the bootloader.
* Make sure the bootloader can load into main memory without overwriting itself.
* We put 2nd bootloader in the high address space (before ROM stack/data/bss).
* See memory usage for ROM bootloader at the end of this file.
*
* ESP32-H2 ROM static data usage is as follows:
* - 0x3fccb900 - 0x3fcdd210: Shared buffers, used in UART/USB/SPI download mode only
* - 0x3fcdd210 - 0x3fcdf210: PRO CPU stack, can be reclaimed as heap after RTOS startup
* - 0x3fcdf210 - 0x3fce0000: ROM .bss and .data (not easily reclaimable)
*
* The 2nd stage bootloader can take space up to the end of ROM shared
* buffers area (0x3fce9704). For alignment purpose we shall use value (0x3fce9700).
*/
/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */
iram_dram_offset = 0x700000;
/* We consider 0x3fce9700 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg,
* and work out iram_seg and iram_loader_seg addresses from there, backwards.
*/
/* These lengths can be adjusted, if necessary: */
bootloader_usable_dram_end = 0x3fcdd120;
bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */
bootloader_dram_seg_len = 0x5000;
bootloader_iram_loader_seg_len = 0x7000;
bootloader_iram_seg_len = 0x2000;
/* Start of the lower region is determined by region size and the end of the higher region */
bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead;
bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len;
bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset;
bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len;
MEMORY
{
iram_seg (RWX) : org = 0x403CE000, len = 0x2000
iram_loader_seg (RWX) : org = 0x403D0000, len = 0x6000
dram_seg (RW) : org = 0x3FCD6000, len = 0x4000
iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len
iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len
dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len
}
/* Default entry point: */
@@ -181,17 +207,34 @@ SECTIONS
/**
* Appendix: Memory Usage of ROM bootloader
*
* +--------+--------------+------+ 0x3FCC_B900
* | ^ |
* | | |
* | | data/bss |
* | | |
* | v |
* +------------------------------+ 0x3FCD_D210
* | ^ |
* | | |
* | | stack |
* | | |
* | v |
* +------------------------------+ 0x3FCD_F210
* 0x3fccb81c ------------------> _dram0_0_start
* | |
* | |
* | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h
* | |
* | |
* 0x3fcdd120 ------------------> __stack_sentry
* | |
* | | 2. Startup pro cpu stack (freed when IDF app is running)
* | |
* 0x3fcdf120 ------------------> __stack (pro cpu)
* | |
* | |
* | | 3. Shared memory only used in startup code or nonos/early boot*
* | | (can be freed when IDF runs)
* | |
* | |
* 0x3fcdfa6c ------------------> _dram0_rtos_reserved_start
* | |
* | |
* | | 4. Shared memory used in startup code and when IDF runs
* | |
* | |
* 0x3fcdfe40 ------------------> _dram0_rtos_reserved_end
* | |
* 0x3fcdfe4c ------------------> _data_start_interface
* | |
* | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible)
* | |
* 0x3fce0000 ------------------> _data_end_interface
*/

View File

@@ -233,3 +233,42 @@ SECTIONS
}
}
/**
* Appendix: Memory Usage of ROM bootloader
*
* 0x3fcd7e00 ------------------> _dram0_0_start
* | |
* | |
* | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h
* | |
* | |
* 0x3fce9710 ------------------> __stack_sentry
* | |
* | | 2. Startup pro cpu stack (freed when IDF app is running)
* | |
* 0x3fceb710 ------------------> __stack (pro cpu)
* | |
* | | Startup app cpu stack
* | |
* 0x3fced710 ------------------> __stack_app (app cpu)
* | |
* | |
* | | 3. Shared memory only used in startup code or nonos/early boot*
* | | (can be freed when IDF runs)
* | |
* | |
* 0x3fceee34 ------------------> _dram0_rtos_reserved_start
* | |
* | |
* | | 4. Shared memory used in startup code and when IDF runs
* | |
* | |
* 0x3fcef770 ------------------> _dram0_rtos_reserved_end
* | |
* 0x3fcef81c ------------------> _data_start_interface
* | |
* | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible)
* | |
* 0x3fcf0000 ------------------> _data_end_interface
*/

View File

@@ -148,3 +148,5 @@ endif()
if(BOOTLOADER_BUILD)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u abort")
endif()
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -1,3 +1,4 @@
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES cmock bootloader_support app_update)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -53,6 +53,8 @@ if(CONFIG_BT_ENABLED)
"common/osi/buffer.c"
"common/osi/config.c"
"common/osi/fixed_queue.c"
"common/osi/pkt_queue.c"
"common/osi/fixed_pkt_queue.c"
"common/osi/future.c"
"common/osi/hash_functions.c"
"common/osi/hash_map.c"
@@ -715,6 +717,8 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/btc/profile/std/gatt/btc_gatt_util.c"
"host/bluedroid/btc/profile/std/gatt/btc_gatts.c"
PROPERTIES COMPILE_FLAGS -Wno-address-of-packed-member)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
endif()
if(CONFIG_BT_NIMBLE_MESH)

View File

@@ -60,6 +60,10 @@
#endif /* #if CLASSIC_BT_INCLUDED */
#endif
#if (BLE_INCLUDED == TRUE)
#include "btc_gap_ble.h"
#endif
#if CONFIG_BLE_MESH
#include "btc_ble_mesh_ble.h"
#include "btc_ble_mesh_prov.h"
@@ -75,6 +79,9 @@
#define BTC_TASK_STACK_SIZE (BT_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
#define BTC_TASK_NAME "BTC_TASK"
#define BTC_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 6)
#define BTC_TASK_WORKQUEUE_NUM (2)
#define BTC_TASK_WORKQUEUE0_LEN (0)
#define BTC_TASK_WORKQUEUE1_LEN (5)
osi_thread_t *btc_thread;
@@ -414,7 +421,9 @@ error_exit:;
bt_status_t btc_init(void)
{
btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE, 2);
const size_t workqueue_len[] = {BTC_TASK_WORKQUEUE0_LEN, BTC_TASK_WORKQUEUE1_LEN};
btc_thread = osi_thread_create(BTC_TASK_NAME, BTC_TASK_STACK_SIZE, BTC_TASK_PRIO, BTC_TASK_PINNED_TO_CORE,
BTC_TASK_WORKQUEUE_NUM, workqueue_len);
if (btc_thread == NULL) {
return BT_STATUS_NOMEM;
}
@@ -427,6 +436,7 @@ bt_status_t btc_init(void)
#if (BLE_INCLUDED == TRUE)
btc_gap_callback_init();
btc_gap_ble_init();
#endif ///BLE_INCLUDED == TRUE
#if SCAN_QUEUE_CONGEST_CHECK
@@ -444,7 +454,9 @@ void btc_deinit(void)
osi_thread_free(btc_thread);
btc_thread = NULL;
#if (BLE_INCLUDED == TRUE)
btc_gap_ble_deinit();
#endif ///BLE_INCLUDED == TRUE
#if SCAN_QUEUE_CONGEST_CHECK
btc_adv_list_deinit();
#endif
@@ -463,3 +475,8 @@ int get_btc_work_queue_size(void)
{
return osi_thread_queue_wait_size(btc_thread, 0);
}
osi_thread_t *btc_get_current_thread(void)
{
return btc_thread;
}

View File

@@ -124,6 +124,13 @@ void btc_deinit(void);
bool btc_check_queue_is_congest(void);
int get_btc_work_queue_size(void);
/**
* get the BTC thread handle
* @return NULL: fail
* others: pointer of osi_thread structure of BTC
*/
osi_thread_t *btc_get_current_thread(void);
#ifdef __cplusplus
}
#endif

View File

@@ -85,4 +85,11 @@
#define UC_BT_BLUFI_ENABLE FALSE
#endif
//MEMORY DEBUG
#ifdef CONFIG_BT_BLUEDROID_MEM_DEBUG
#define UC_BT_BLUEDROID_MEM_DEBUG TRUE
#else
#define UC_BT_BLUEDROID_MEM_DEBUG FALSE
#endif
#endif /* __BT_USER_CONFIG_H__ */

View File

@@ -0,0 +1,161 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "osi/allocator.h"
#include "osi/pkt_queue.h"
#include "osi/fixed_pkt_queue.h"
#include "osi/osi.h"
#include "osi/semaphore.h"
typedef struct fixed_pkt_queue_t {
struct pkt_queue *pkt_list;
osi_sem_t enqueue_sem;
osi_sem_t dequeue_sem;
size_t capacity;
fixed_pkt_queue_cb dequeue_ready;
} fixed_pkt_queue_t;
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity)
{
fixed_pkt_queue_t *ret = osi_calloc(sizeof(fixed_pkt_queue_t));
if (!ret) {
goto error;
}
ret->capacity = capacity;
ret->pkt_list = pkt_queue_create();
if (!ret->pkt_list) {
goto error;
}
osi_sem_new(&ret->enqueue_sem, capacity, capacity);
if (!ret->enqueue_sem) {
goto error;
}
osi_sem_new(&ret->dequeue_sem, capacity, 0);
if (!ret->dequeue_sem) {
goto error;
}
return ret;
error:
fixed_pkt_queue_free(ret, NULL);
return NULL;
}
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb)
{
if (queue == NULL) {
return;
}
fixed_pkt_queue_unregister_dequeue(queue);
pkt_queue_destroy(queue->pkt_list, (pkt_queue_free_cb)free_cb);
queue->pkt_list = NULL;
if (queue->enqueue_sem) {
osi_sem_free(&queue->enqueue_sem);
}
if (queue->dequeue_sem) {
osi_sem_free(&queue->dequeue_sem);
}
osi_free(queue);
}
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue)
{
if (queue == NULL) {
return true;
}
return pkt_queue_is_empty(queue->pkt_list);
}
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue)
{
if (queue == NULL) {
return 0;
}
return pkt_queue_length(queue->pkt_list);
}
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue)
{
assert(queue != NULL);
return queue->capacity;
}
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout)
{
bool ret = false;
assert(queue != NULL);
assert(linked_pkt != NULL);
if (osi_sem_take(&queue->enqueue_sem, timeout) != 0) {
return false;
}
ret = pkt_queue_enqueue(queue->pkt_list, linked_pkt);
assert(ret == true);
osi_sem_give(&queue->dequeue_sem);
return ret;
}
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout)
{
pkt_linked_item_t *ret = NULL;
assert(queue != NULL);
if (osi_sem_take(&queue->dequeue_sem, timeout) != 0) {
return NULL;
}
ret = pkt_queue_dequeue(queue->pkt_list);
osi_sem_give(&queue->enqueue_sem);
return ret;
}
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue)
{
if (queue == NULL) {
return NULL;
}
return pkt_queue_try_peek_first(queue->pkt_list);
}
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb)
{
assert(queue != NULL);
assert(ready_cb != NULL);
queue->dequeue_ready = ready_cb;
}
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue)
{
assert(queue != NULL);
queue->dequeue_ready = NULL;
}
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue)
{
assert(queue != NULL);
if (queue->dequeue_ready) {
queue->dequeue_ready(queue);
}
}

View File

@@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _FIXED_PKT_QUEUE_H_
#define _FIXED_PKT_QUEUE_H_
#include "osi/pkt_queue.h"
#include "osi/semaphore.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef FIXED_PKT_QUEUE_SIZE_MAX
#define FIXED_PKT_QUEUE_SIZE_MAX 254
#endif
#define FIXED_PKT_QUEUE_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
struct fixed_pkt_queue_t;
typedef struct fixed_pkt_queue_t fixed_pkt_queue_t;
typedef void (*fixed_pkt_queue_free_cb)(pkt_linked_item_t *data);
typedef void (*fixed_pkt_queue_cb)(fixed_pkt_queue_t *queue);
// Creates a new fixed queue with the given |capacity|. If more elements than
// |capacity| are added to the queue, the caller is blocked until space is
// made available in the queue. Returns NULL on failure. The caller must free
// the returned queue with |fixed_pkt_queue_free|.
fixed_pkt_queue_t *fixed_pkt_queue_new(size_t capacity);
// Freeing a queue that is currently in use (i.e. has waiters
// blocked on it) results in undefined behaviour.
void fixed_pkt_queue_free(fixed_pkt_queue_t *queue, fixed_pkt_queue_free_cb free_cb);
// Returns a value indicating whether the given |queue| is empty. If |queue|
// is NULL, the return value is true.
bool fixed_pkt_queue_is_empty(fixed_pkt_queue_t *queue);
// Returns the length of the |queue|. If |queue| is NULL, the return value
// is 0.
size_t fixed_pkt_queue_length(fixed_pkt_queue_t *queue);
// Returns the maximum number of elements this queue may hold. |queue| may
// not be NULL.
size_t fixed_pkt_queue_capacity(fixed_pkt_queue_t *queue);
// Enqueues the given |data| into the |queue|. The caller will be blocked or immediately return or wait for timeout according to the parameter timeout.
// If enqueue failed, it will return false, otherwise return true
bool fixed_pkt_queue_enqueue(fixed_pkt_queue_t *queue, pkt_linked_item_t *linked_pkt, uint32_t timeout);
// Dequeues the next element from |queue|. If the queue is currently empty,
// this function will block the caller until an item is enqueued or immediately return or wait for timeout according to the parameter timeout.
// If dequeue failed, it will return NULL, otherwise return a point.
pkt_linked_item_t *fixed_pkt_queue_dequeue(fixed_pkt_queue_t *queue, uint32_t timeout);
// Returns the first element from |queue|, if present, without dequeuing it.
// This function will never block the caller. Returns NULL if there are no
// elements in the queue or |queue| is NULL.
pkt_linked_item_t *fixed_pkt_queue_try_peek_first(fixed_pkt_queue_t *queue);
// Registers |queue| with |reactor| for dequeue operations. When there is an element
// in the queue, ready_cb will be called. The |context| parameter is passed, untouched,
// to the callback routine. Neither |queue|, nor |reactor|, nor |read_cb| may be NULL.
// |context| may be NULL.
void fixed_pkt_queue_register_dequeue(fixed_pkt_queue_t *queue, fixed_pkt_queue_cb ready_cb);
// Unregisters the dequeue ready callback for |queue| from whichever reactor
// it is registered with, if any. This function is idempotent.
void fixed_pkt_queue_unregister_dequeue(fixed_pkt_queue_t *queue);
void fixed_pkt_queue_process(fixed_pkt_queue_t *queue);
#endif

View File

@@ -0,0 +1,88 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _PKT_LIST_H_
#define _PKT_LIST_H_
#include "sys/queue.h"
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct pkt_queue;
typedef struct pkt_linked_item {
STAILQ_ENTRY(pkt_linked_item) next;
uint8_t data[];
} pkt_linked_item_t;
#define BT_PKT_LINKED_HDR_SIZE (sizeof (pkt_linked_item_t))
typedef void (*pkt_queue_free_cb)(pkt_linked_item_t *item);
/*
* brief: create a pkt_queue instance. pkt_queue is a wrapper class of a FIFO implemented by single linked list.
* The enqueue and dequeue operations of the FIFO are protected against race conditions of multiple tasks
* return: NULL if not enough memory, otherwise a valid pointer
*/
struct pkt_queue *pkt_queue_create(void);
/*
* brief: enqueue one item to the FIFO
* param queue: pkt_queue instance created using pkt_queue_create
* param item: the item to be enqueued to the FIFO
* return: true if enqueued successfully, false when the arguments passed in are invalid
*/
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item);
/*
* brief: dequeue one item for the FIFO
* param queue: pkt_queue instance created using pkt_queue_create
* return: pointer of type pkt_linked_item_t dequeued, NULL if the queue is empty or upon exception
*/
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue);
/*
* brief: get the pointer of the first item from the FIFO but not get it dequeued
* param queue: pkt_queue instance created using pkt_queue_create
* return: pointer of the first item in the FIFO, NULL if the FIFO is empty
*/
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue);
/*
* brief: retrieve the number of items existing in the FIFO
* param queue: pkt_queue instance created using pkt_queue_create
* return: total number of items in the FIFO
*/
size_t pkt_queue_length(const struct pkt_queue *queue);
/*
* brief: retrieve the status whether the FIFO is empty
* param queue: pkt_queue instance created using pkt_queue_create
* return: false if the FIFO is not empty, otherwise true
*/
bool pkt_queue_is_empty(const struct pkt_queue *queue);
/*
* brief: delete the item in the FIFO one by one
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default
*/
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb);
/*
* brief: delete the items in the FIFO and then destroy the pkt_queue instance.
* param free_cb: destructor function for each item in the FIFO, if set to NULL, will use osi_free_func by default
*/
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -20,6 +20,7 @@
#define OSI_THREAD_MAX_TIMEOUT OSI_SEM_MAX_TIMEOUT
struct osi_thread;
struct osi_event;
typedef struct osi_thread osi_thread_t;
@@ -40,7 +41,7 @@ typedef enum {
* param work_queue_num: speicify queue number, the queue[0] has highest priority, and the priority is decrease by index
* return : if create successfully, return thread handler; otherwise return NULL.
*/
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num);
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[]);
/*
* brief: Destroy a thread or task
@@ -80,4 +81,42 @@ const char *osi_thread_name(osi_thread_t *thread);
*/
int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx);
/*
* brief: Create an osi_event struct and register the handler function and its argument
* An osi_event is a kind of work that can be posted to the workqueue of osi_thread to process,
* but the work can have at most one instance the thread workqueue before it is processed. This
* allows the "single post, multiple data processing" jobs.
* param func: the handler to process the job
* param context: the argument to be passed to the handler function when the job is being processed
* return: NULL if no memory, otherwise a valid struct pointer
*/
struct osi_event *osi_event_create(osi_thread_func_t func, void *context);
/*
* brief: Bind an osi_event to a specific work queue for an osi_thread.
* After binding is completed, a function call of API osi_thread_post_event will send a work
* to the workqueue of the thread, with specified queue index.
* param func: event: the pointer to osi_event that is created using osi_event_create
* param thread: the pointer to osi_thread that is created using osi_thread_create
* param queue_idx: the index of the workqueue of the specified osi_thread, with range starting from 0 to work_queue_num - 1
* return: true if osi_event binds to the thread's workqueue successfully, otherwise false
*/
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx);
/*
* brief: Destroy the osi_event struct created by osi_event_create and free the allocated memory
* param event: the pointer to osi_event
*/
void osi_event_delete(struct osi_event* event);
/*
* brief: try sending a work to the binded thread's workqueue, so that it can be handled by the worker thread
* param event: pointer to osi_event, created by osi_event_create
* param timeout: post timeout, OSI_THREAD_MAX_TIMEOUT means blocking forever, 0 means never blocking, others means block millisecond
* return: true if the message is enqueued to the thread workqueue, otherwise failed
* note: if the return value of function is false, it is the case that the workqueue of the thread is full, and users
* are expected to post the event sometime later to get the work handled.
*/
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout);
#endif /* __THREAD_H__ */

View File

@@ -0,0 +1,144 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "osi/pkt_queue.h"
#include "osi/allocator.h"
#include "osi/mutex.h"
STAILQ_HEAD(pkt_queue_header, pkt_linked_item);
struct pkt_queue {
osi_mutex_t lock;
size_t length;
struct pkt_queue_header header;
} pkt_queue_t;
struct pkt_queue *pkt_queue_create(void)
{
struct pkt_queue *queue = calloc(1, sizeof(struct pkt_queue));
if (queue == NULL) {
return NULL;
}
if (osi_mutex_new(&queue->lock) != 0) {
osi_free(queue);
}
struct pkt_queue_header *p = &queue->header;
STAILQ_INIT(p);
return queue;
}
static void pkt_queue_cleanup(struct pkt_queue *queue, pkt_queue_free_cb free_cb)
{
if (queue == NULL) {
return;
}
struct pkt_queue_header *header = &queue->header;
pkt_linked_item_t *item = STAILQ_FIRST(header);
pkt_linked_item_t *tmp;
pkt_queue_free_cb free_func = (free_cb != NULL) ? free_cb : (pkt_queue_free_cb)osi_free_func;
while (item != NULL) {
tmp = STAILQ_NEXT(item, next);
free_func(item);
item = tmp;
queue->length--;
}
STAILQ_INIT(header);
queue->length = 0;
}
void pkt_queue_flush(struct pkt_queue *queue, pkt_queue_free_cb free_cb)
{
if (queue == NULL) {
return;
}
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
pkt_queue_cleanup(queue, free_cb);
osi_mutex_unlock(&queue->lock);
}
void pkt_queue_destroy(struct pkt_queue *queue, pkt_queue_free_cb free_cb)
{
if (queue == NULL) {
return;
}
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
pkt_queue_cleanup(queue, free_cb);
osi_mutex_unlock(&queue->lock);
osi_mutex_free(&queue->lock);
osi_free(queue);
}
pkt_linked_item_t *pkt_queue_dequeue(struct pkt_queue *queue)
{
if (queue == NULL || queue->length == 0) {
return NULL;
}
struct pkt_linked_item *item;
struct pkt_queue_header *header;
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
header = &queue->header;
item = STAILQ_FIRST(header);
if (item != NULL) {
STAILQ_REMOVE_HEAD(header, next);
if (queue->length > 0) {
queue->length--;
}
}
osi_mutex_unlock(&queue->lock);
return item;
}
bool pkt_queue_enqueue(struct pkt_queue *queue, pkt_linked_item_t *item)
{
if (queue == NULL || item == NULL) {
return false;
}
struct pkt_queue_header *header;
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
header = &queue->header;
STAILQ_INSERT_TAIL(header, item, next);
queue->length++;
osi_mutex_unlock(&queue->lock);
return true;
}
size_t pkt_queue_length(const struct pkt_queue *queue)
{
if (queue == NULL) {
return 0;
}
return queue->length;
}
bool pkt_queue_is_empty(const struct pkt_queue *queue)
{
return pkt_queue_length(queue) == 0;
}
pkt_linked_item_t *pkt_queue_try_peek_first(struct pkt_queue *queue)
{
if (queue == NULL) {
return NULL;
}
struct pkt_queue_header *header = &queue->header;
pkt_linked_item_t *item;
osi_mutex_lock(&queue->lock, OSI_MUTEX_MAX_TIMEOUT);
item = STAILQ_FIRST(header);
osi_mutex_unlock(&queue->lock);
return item;
}

View File

@@ -19,16 +19,28 @@
#include <string.h>
#include "osi/allocator.h"
#include "osi/fixed_queue.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "osi/semaphore.h"
#include "osi/thread.h"
#include "osi/mutex.h"
struct work_item {
osi_thread_func_t func;
void *context;
};
struct work_queue {
QueueHandle_t queue;
size_t capacity;
};
struct osi_thread {
TaskHandle_t thread_handle; /*!< Store the thread object */
int thread_id; /*!< May for some OS, such as Linux */
bool stop;
uint8_t work_queue_num; /*!< Work queue number */
fixed_queue_t **work_queues; /*!< Point to queue array, and the priority inverse array index */
struct work_queue **work_queues; /*!< Point to queue array, and the priority inverse array index */
osi_sem_t work_sem;
osi_sem_t stop_sem;
};
@@ -39,13 +51,98 @@ struct osi_thread_start_arg {
int error;
};
typedef struct {
osi_thread_func_t func;
void *context;
} work_item_t;
struct osi_event {
struct work_item item;
osi_mutex_t lock;
uint16_t is_queued;
uint16_t queue_idx;
osi_thread_t *thread;
};
static const size_t DEFAULT_WORK_QUEUE_CAPACITY = 100;
static struct work_queue *osi_work_queue_create(size_t capacity)
{
if (capacity == 0) {
return NULL;
}
struct work_queue *wq = (struct work_queue *)osi_malloc(sizeof(struct work_queue));
if (wq != NULL) {
wq->queue = xQueueCreate(capacity, sizeof(struct work_item));
if (wq->queue != 0) {
wq->capacity = capacity;
return wq;
} else {
osi_free(wq);
}
}
return NULL;
}
static void osi_work_queue_delete(struct work_queue *wq)
{
if (wq != NULL) {
if (wq->queue != 0) {
vQueueDelete(wq->queue);
}
wq->queue = 0;
wq->capacity = 0;
osi_free(wq);
}
return;
}
static bool osi_thead_work_queue_get(struct work_queue *wq, struct work_item *item)
{
assert (wq != NULL);
assert (wq->queue != 0);
assert (item != NULL);
if (pdTRUE == xQueueReceive(wq->queue, item, 0)) {
return true;
} else {
return false;
}
}
static bool osi_thead_work_queue_put(struct work_queue *wq, const struct work_item *item, uint32_t timeout)
{
assert (wq != NULL);
assert (wq->queue != 0);
assert (item != NULL);
bool ret = true;
if (timeout == OSI_SEM_MAX_TIMEOUT) {
if (xQueueSend(wq->queue, item, portMAX_DELAY) != pdTRUE) {
ret = false;
}
} else {
if (xQueueSend(wq->queue, item, timeout / portTICK_PERIOD_MS) != pdTRUE) {
ret = false;
}
}
return ret;
}
static size_t osi_thead_work_queue_len(struct work_queue *wq)
{
assert (wq != NULL);
assert (wq->queue != 0);
assert (wq->capacity != 0);
size_t available_spaces = (size_t)uxQueueSpacesAvailable(wq->queue);
if (available_spaces <= wq->capacity) {
return wq->capacity - available_spaces;
} else {
assert (0);
}
return 0;
}
static void osi_thread_run(void *arg)
{
struct osi_thread_start_arg *start = (struct osi_thread_start_arg *)arg;
@@ -62,11 +159,10 @@ static void osi_thread_run(void *arg)
break;
}
struct work_item item;
while (!thread->stop && idx < thread->work_queue_num) {
work_item_t *item = fixed_queue_dequeue(thread->work_queues[idx], 0);
if (item) {
item->func(item->context);
osi_free(item);
if (osi_thead_work_queue_get(thread->work_queues[idx], &item) == true) {
item.func(item.context);
idx = 0;
continue;
} else {
@@ -107,14 +203,14 @@ static void osi_thread_stop(osi_thread_t *thread)
}
//in linux, the stack_size, priority and core may not be set here, the code will be ignore the arguments
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num)
osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priority, osi_thread_core_t core, uint8_t work_queue_num, const size_t work_queue_len[])
{
int ret;
struct osi_thread_start_arg start_arg = {0};
if (stack_size <= 0 ||
core < OSI_THREAD_CORE_0 || core > OSI_THREAD_CORE_AFFINITY ||
work_queue_num <= 0) {
work_queue_num <= 0 || work_queue_len == NULL) {
return NULL;
}
@@ -125,13 +221,14 @@ osi_thread_t *osi_thread_create(const char *name, size_t stack_size, int priorit
thread->stop = false;
thread->work_queue_num = work_queue_num;
thread->work_queues = (fixed_queue_t **)osi_malloc(sizeof(fixed_queue_t *) * work_queue_num);
thread->work_queues = (struct work_queue **)osi_malloc(sizeof(struct work_queue *) * work_queue_num);
if (thread->work_queues == NULL) {
goto _err;
}
for (int i = 0; i < thread->work_queue_num; i++) {
thread->work_queues[i] = fixed_queue_new(DEFAULT_WORK_QUEUE_CAPACITY);
size_t queue_len = work_queue_len[i] ? work_queue_len[i] : DEFAULT_WORK_QUEUE_CAPACITY;
thread->work_queues[i] = osi_work_queue_create(queue_len);
if (thread->work_queues[i] == NULL) {
goto _err;
}
@@ -175,12 +272,14 @@ _err:
for (int i = 0; i < thread->work_queue_num; i++) {
if (thread->work_queues[i]) {
fixed_queue_free(thread->work_queues[i], osi_free_func);
osi_work_queue_delete(thread->work_queues[i]);
}
thread->work_queues[i] = NULL;
}
if (thread->work_queues) {
osi_free(thread->work_queues);
thread->work_queues = NULL;
}
if (thread->work_sem) {
@@ -206,12 +305,14 @@ void osi_thread_free(osi_thread_t *thread)
for (int i = 0; i < thread->work_queue_num; i++) {
if (thread->work_queues[i]) {
fixed_queue_free(thread->work_queues[i], osi_free_func);
osi_work_queue_delete(thread->work_queues[i]);
thread->work_queues[i] = NULL;
}
}
if (thread->work_queues) {
osi_free(thread->work_queues);
thread->work_queues = NULL;
}
if (thread->work_sem) {
@@ -235,15 +336,12 @@ bool osi_thread_post(osi_thread_t *thread, osi_thread_func_t func, void *context
return false;
}
work_item_t *item = (work_item_t *)osi_malloc(sizeof(work_item_t));
if (item == NULL) {
return false;
}
item->func = func;
item->context = context;
struct work_item item;
if (fixed_queue_enqueue(thread->work_queues[queue_idx], item, timeout) == false) {
osi_free(item);
item.func = func;
item.context = context;
if (osi_thead_work_queue_put(thread->work_queues[queue_idx], &item, timeout) == false) {
return false;
}
@@ -273,5 +371,83 @@ int osi_thread_queue_wait_size(osi_thread_t *thread, int wq_idx)
return -1;
}
return fixed_queue_length(thread->work_queues[wq_idx]);
return (int)(osi_thead_work_queue_len(thread->work_queues[wq_idx]));
}
struct osi_event *osi_event_create(osi_thread_func_t func, void *context)
{
struct osi_event *event = osi_calloc(sizeof(struct osi_event));
if (event != NULL) {
if (osi_mutex_new(&event->lock) == 0) {
event->item.func = func;
event->item.context = context;
return event;
}
osi_free(event);
}
return NULL;
}
void osi_event_delete(struct osi_event* event)
{
if (event != NULL) {
osi_mutex_free(&event->lock);
memset(event, 0, sizeof(struct osi_event));
osi_free(event);
}
}
bool osi_event_bind(struct osi_event* event, osi_thread_t *thread, int queue_idx)
{
if (event == NULL || event->thread != NULL) {
return false;
}
if (thread == NULL || queue_idx >= thread->work_queue_num) {
return false;
}
event->thread = thread;
event->queue_idx = queue_idx;
return true;
}
static void osi_thread_generic_event_handler(void *context)
{
struct osi_event *event = (struct osi_event *)context;
if (event != NULL && event->item.func != NULL) {
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT);
event->is_queued = 0;
osi_mutex_unlock(&event->lock);
event->item.func(event->item.context);
}
}
bool osi_thread_post_event(struct osi_event *event, uint32_t timeout)
{
assert(event != NULL && event->thread != NULL);
assert(event->queue_idx >= 0 && event->queue_idx < event->thread->work_queue_num);
bool ret = false;
if (event->is_queued == 0) {
uint16_t acquire_cnt = 0;
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT);
event->is_queued += 1;
acquire_cnt = event->is_queued;
osi_mutex_unlock(&event->lock);
if (acquire_cnt == 1) {
ret = osi_thread_post(event->thread, osi_thread_generic_event_handler, event, event->queue_idx, timeout);
if (!ret) {
// clear "is_queued" when post failure, to allow for following event posts
osi_mutex_lock(&event->lock, OSI_MUTEX_MAX_TIMEOUT);
event->is_queued = 0;
osi_mutex_unlock(&event->lock);
}
}
}
return ret;
}

View File

@@ -571,12 +571,18 @@ void ble_rtc_clk_init(void)
// LP_TIMER_SEL_XTAL -> 1
// LP_TIMER_SEL_8M -> 0
// LP_TIMER_SEL_RTC_SLOW -> 0
// LP_TIMER_CLK_DIV_NUM -> 1250
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_XTAL32K_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 1, MODEM_CLKRST_LP_TIMER_SEL_XTAL_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_8M_S);
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, 1, 0, MODEM_CLKRST_LP_TIMER_SEL_RTC_SLOW_S);
#ifdef CONFIG_ESP32C2_XTAL_FREQ_26
// LP_TIMER_CLK_DIV_NUM -> 130
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 129, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
#else
// LP_TIMER_CLK_DIV_NUM -> 250
SET_PERI_REG_BITS(MODEM_CLKRST_MODEM_LP_TIMER_CONF_REG, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM, 249, MODEM_CLKRST_LP_TIMER_CLK_DIV_NUM_S);
#endif // CONFIG_ESP32C2_XTAL_FREQ_26
// MODEM_CLKRST_ETM_CLK_ACTIVE -> 1
// MODEM_CLKRST_ETM_CLK_SEL -> 0

View File

@@ -117,9 +117,8 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
if (p_service_name) {
BCM_STRNCPY_S(p_buf->p_service_name, p_service_name, BTA_SERVICE_NAME_LEN);
p_buf->p_service_name[BTA_SERVICE_NAME_LEN - 1] = 0;
} else {
p_buf->p_service_name[0] = 0;
p_buf->p_service_name[0] = '\0';
}
p_buf->app_id = app_id;
p_buf->p_app_data_cback = p_data_cback;
@@ -307,9 +306,10 @@ void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
p_buf->num_protect = num_protect;
p_buf->suspend = suspend;
p_buf->sep_info_idx = sep_info_idx;
p_buf->p_protect_info = (UINT8 *)(p_buf + 1);
memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
if (p_protect_info && num_protect) {
memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
}
bta_sys_sendmsg(p_buf);
}
}

View File

@@ -74,21 +74,17 @@ void bta_av_ci_setconfig(tBTA_AV_HNDL hndl, UINT8 err_code, UINT8 category,
{
tBTA_AV_CI_SETCONFIG *p_buf;
if ((p_buf = (tBTA_AV_CI_SETCONFIG *) osi_malloc(sizeof(tBTA_AV_CI_SETCONFIG))) != NULL) {
if ((p_buf = (tBTA_AV_CI_SETCONFIG *) osi_malloc(sizeof(tBTA_AV_CI_SETCONFIG) + num_seid)) != NULL) {
p_buf->hdr.layer_specific = hndl;
p_buf->hdr.event = (err_code == AVDT_SUCCESS) ?
BTA_AV_CI_SETCONFIG_OK_EVT : BTA_AV_CI_SETCONFIG_FAIL_EVT;
p_buf->err_code = err_code;
p_buf->category = category;
p_buf->recfg_needed = recfg_needed;
p_buf->num_seid = num_seid;
p_buf->avdt_handle = avdt_handle;
p_buf->num_seid = num_seid;
if (p_seid && num_seid) {
p_buf->p_seid = (UINT8 *)(p_buf + 1);
memcpy(p_buf->p_seid, p_seid, num_seid);
} else {
p_buf->p_seid = NULL;
p_buf->num_seid = 0;
}
bta_sys_sendmsg(p_buf);

View File

@@ -474,6 +474,7 @@ static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data)
APPL_TRACE_DEBUG("bta_av_api_sink_enable %d \n", activate_sink)
char p_service_name[BTA_SERVICE_NAME_LEN + 1];
BCM_STRNCPY_S(p_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
p_service_name[BTA_SERVICE_NAME_LEN] = '\0';
if (activate_sink) {
AVDT_SINK_Activate();
@@ -537,6 +538,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
UINT8 index = 0;
char p_avk_service_name[BTA_SERVICE_NAME_LEN + 1];
BCM_STRNCPY_S(p_avk_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
p_avk_service_name[BTA_SERVICE_NAME_LEN] = '\0';
memset(&cs, 0, sizeof(tAVDT_CS));

View File

@@ -264,10 +264,10 @@ typedef struct {
typedef struct {
BT_HDR hdr;
UINT8 codec_info[AVDT_CODEC_SIZE]; /* codec configuration */
UINT8 *p_protect_info;
UINT8 num_protect;
BOOLEAN suspend;
UINT8 sep_info_idx;
UINT8 num_protect;
UINT8 p_protect_info[0];
} tBTA_AV_API_RCFG;
/* data type for BTA_AV_CI_SETCONFIG_OK_EVT and BTA_AV_CI_SETCONFIG_FAIL_EVT */
@@ -276,10 +276,10 @@ typedef struct {
tBTA_AV_HNDL hndl;
UINT8 err_code;
UINT8 category;
UINT8 num_seid;
UINT8 *p_seid;
BOOLEAN recfg_needed;
UINT8 avdt_handle; /* local sep type for which this stream will be set up */
UINT8 num_seid;
UINT8 p_seid[0];
} tBTA_AV_CI_SETCONFIG;
/* data type for all stream events from AVDTP */

View File

@@ -705,7 +705,7 @@ static BOOLEAN bta_dm_read_remote_device_name (BD_ADDR bd_addr, tBT_TRANSPORT tr
APPL_TRACE_DEBUG("bta_dm_read_remote_device_name");
bdcpy(bta_dm_search_cb.peer_bdaddr, bd_addr);
bta_dm_search_cb.peer_name[0] = 0;
bta_dm_search_cb.peer_name[0] = '\0';
btm_status = BTM_ReadRemoteDeviceName (bta_dm_search_cb.peer_bdaddr,
(tBTM_CMPL_CB *) bta_dm_remname_cback,
@@ -743,7 +743,7 @@ void bta_dm_read_rmt_name(tBTA_DM_MSG *p_data)
{
APPL_TRACE_DEBUG("%s",__func__);
bdcpy(bta_dm_search_cb.peer_bdaddr, p_data->get_rmt_name.rmt_addr);
bta_dm_search_cb.peer_name[0] = 0;
bta_dm_search_cb.peer_name[0] = '\0';
tBTM_STATUS btm_status = BTM_ReadRemoteDeviceName(bta_dm_search_cb.peer_bdaddr,
(tBTM_CMPL_CB *) p_data->get_rmt_name.rmt_name_cb,
@@ -1621,7 +1621,7 @@ void bta_dm_discover (tBTA_DM_MSG *p_data)
bta_dm_search_cb.services_to_search = bta_dm_search_cb.services;
bta_dm_search_cb.service_index = 0;
bta_dm_search_cb.services_found = 0;
bta_dm_search_cb.peer_name[0] = 0;
bta_dm_search_cb.peer_name[0] = '\0';
bta_dm_search_cb.sdp_search = p_data->discover.sdp_search;
bta_dm_search_cb.p_btm_inq_info = BTM_InqDbRead (p_data->discover.bd_addr);
bta_dm_search_cb.transport = p_data->discover.transport;
@@ -1896,8 +1896,8 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
/* send result back to app now, one by one */
bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
result.disc_ble_res.bd_name[BD_NAME_LEN] = '\0';
result.disc_ble_res.service.len = service_uuid.len;
result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
@@ -2037,10 +2037,8 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
}
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
/* make sure the string is null terminated */
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN] = '\0';
bta_sys_sendmsg(p_msg);
}
@@ -2063,10 +2061,8 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
/* make sure the string is null terminated */
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN] = '\0';
bta_sys_sendmsg(p_msg);
}
@@ -2447,10 +2443,8 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
/* make sure the string is terminated */
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), BD_NAME_LEN);
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN] = '\0';
bta_sys_sendmsg(p_msg);
}
@@ -2632,10 +2626,8 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,(char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
/* make sure the string is terminated */
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN] = '\0';
bta_sys_sendmsg(p_msg);
}
@@ -2772,11 +2764,11 @@ static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc,
/* if this is what we are looking for */
if (!bdcmp( bta_dm_search_cb.peer_bdaddr, bd_addr)) {
rem_name.length = strlen((char *)bd_name);
if (rem_name.length > (BD_NAME_LEN - 1)) {
rem_name.length = (BD_NAME_LEN - 1);
rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
if (rem_name.length > BD_NAME_LEN) {
rem_name.length = BD_NAME_LEN;
}
BCM_STRNCPY_S((char *)rem_name.remote_bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
BCM_STRNCPY_S((char *)rem_name.remote_bd_name, (char *)bd_name, BD_NAME_LEN);
rem_name.remote_bd_name[BD_NAME_LEN] = '\0';
rem_name.status = BTM_SUCCESS;
bta_dm_remname_cback(&rem_name);
@@ -2793,7 +2785,7 @@ static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc,
APPL_TRACE_WARNING("bta_dm_service_search_remname_cback: BTM_ReadRemoteDeviceName returns 0x%02X", btm_status);
rem_name.length = 0;
rem_name.remote_bd_name[0] = 0;
rem_name.remote_bd_name[0] = '\0';
rem_name.status = btm_status;
bta_dm_remname_cback(&rem_name);
}
@@ -2818,8 +2810,8 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
p_remote_name->remote_bd_name);
/* remote name discovery is done but it could be failed */
bta_dm_search_cb.name_discover_done = TRUE;
BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, (char *)p_remote_name->remote_bd_name, BD_NAME_LEN);
bta_dm_search_cb.peer_name[BD_NAME_LEN] = '\0';
BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
@@ -2831,10 +2823,8 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
/* make sure the string is null terminated */
p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, (char *)p_remote_name->remote_bd_name, BD_NAME_LEN);
p_msg->result.disc_res.bd_name[BD_NAME_LEN] = '\0';
p_msg->hdr.event = BTA_DM_REMT_NAME_EVT;
bta_sys_sendmsg(p_msg);
@@ -2862,10 +2852,8 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
bdcpy(sec_event.authorize.bd_addr, bd_addr);
memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
/* make sure the string is null terminated */
sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, (char *)bd_name, BD_NAME_LEN);
sec_event.authorize.bd_name[BD_NAME_LEN] = '\0';
#if ( defined(BTA_JV_INCLUDED) && BTA_JV_INCLUDED == TRUE )
sec_event.authorize.service = service_id;
@@ -2911,7 +2899,6 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
{
tBTM_REMOTE_DEV_NAME *p_result = (tBTM_REMOTE_DEV_NAME *)p_data;
tBTA_DM_SEC sec_event;
UINT32 bytes_to_copy;
tBTA_DM_SEC_EVT event = bta_dm_cb.pin_evt;
if (BTA_DM_SP_CFM_REQ_EVT == event) {
@@ -2920,12 +2907,10 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
BTA_COPY_DEVICE_CLASS(sec_event.cfm_req.dev_class, bta_dm_cb.pin_dev_class);
if (p_result && p_result->status == BTM_SUCCESS) {
bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
? p_result->length : (BD_NAME_LEN - 1);
memcpy(sec_event.cfm_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.cfm_req.bd_name, (char *)p_result->remote_bd_name, BD_NAME_LEN);
sec_event.pin_req.bd_name[BD_NAME_LEN] = '\0';
} else { /* No name found */
sec_event.cfm_req.bd_name[0] = 0;
sec_event.cfm_req.bd_name[0] = '\0';
}
sec_event.key_notif.passkey = bta_dm_cb.num_val; /* get PIN code numeric number */
@@ -2938,12 +2923,10 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, bta_dm_cb.pin_dev_class);
if (p_result && p_result->status == BTM_SUCCESS) {
bytes_to_copy = (p_result->length < (BD_NAME_LEN - 1))
? p_result->length : (BD_NAME_LEN - 1);
memcpy(sec_event.pin_req.bd_name, p_result->remote_bd_name, bytes_to_copy);
sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, (char *)p_result->remote_bd_name, BD_NAME_LEN);
sec_event.pin_req.bd_name[BD_NAME_LEN] = '\0';
} else { /* No name found */
sec_event.pin_req.bd_name[0] = 0;
sec_event.pin_req.bd_name[0] = '\0';
}
event = bta_dm_cb.pin_evt;
@@ -2976,8 +2959,8 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_
bdcpy(sec_event.pin_req.bd_addr, bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, (char *)bd_name, BD_NAME_LEN);
sec_event.pin_req.bd_name[BD_NAME_LEN] = '\0';
sec_event.pin_req.min_16_digit = min_16_digit;
bta_dm_cb.p_sec_cback(BTA_DM_PIN_REQ_EVT, &sec_event);
@@ -3151,8 +3134,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
copy these values into key_notif from cfm_req */
bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->cfm_req.bd_name, BD_NAME_LEN);
sec_event.key_notif.bd_name[BD_NAME_LEN] = '\0';
}
}
@@ -3172,8 +3155,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
} else {
bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->key_notif.bd_name, BD_NAME_LEN);
sec_event.key_notif.bd_name[BD_NAME_LEN] = '\0';
}
}
@@ -3193,8 +3176,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
} else {
bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,(char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,(char *)p_data->key_notif.bd_name, BD_NAME_LEN);
sec_event.key_notif.bd_name[BD_NAME_LEN] = '\0';
}
}
bta_dm_cb.p_sec_cback(pin_evt, &sec_event);
@@ -3222,8 +3205,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, (char *)p_data->rmt_oob.bd_name, BD_NAME_LEN);
sec_event.rmt_oob.bd_name[BD_NAME_LEN] = '\0';
bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
@@ -4656,11 +4639,11 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
bdcpy(sec_event.ble_req.bd_addr, bda);
p_name = BTM_SecReadDevName(bda);
if (p_name != NULL) {
BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,p_name, (BD_NAME_LEN));
BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name, p_name, BD_NAME_LEN);
sec_event.ble_req.bd_name[BD_NAME_LEN] = '\0';
} else {
sec_event.ble_req.bd_name[0] = 0;
sec_event.ble_req.bd_name[0] = '\0';
}
sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
bta_dm_cb.p_sec_cback(BTA_DM_BLE_SEC_REQ_EVT, &sec_event);
break;
@@ -4668,11 +4651,11 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
bdcpy(sec_event.key_notif.bd_addr, bda);
p_name = BTM_SecReadDevName(bda);
if (p_name != NULL) {
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, p_name, (BD_NAME_LEN));
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, p_name, BD_NAME_LEN);
sec_event.key_notif.bd_name[BD_NAME_LEN] = '\0';
} else {
sec_event.key_notif.bd_name[0] = 0;
sec_event.key_notif.bd_name[0] = '\0';
}
sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
sec_event.key_notif.passkey = p_data->key_notif;
bta_dm_cb.p_sec_cback(BTA_DM_BLE_PASSKEY_NOTIF_EVT, &sec_event);
break;
@@ -4689,8 +4672,8 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
case BTM_LE_NC_REQ_EVT:
bdcpy(sec_event.key_notif.bd_addr, bda);
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,bta_dm_get_remname(), (BD_NAME_LEN));
sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,bta_dm_get_remname(), BD_NAME_LEN);
sec_event.key_notif.bd_name[BD_NAME_LEN] = '\0';
sec_event.key_notif.passkey = p_data->key_notif;
bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
break;
@@ -4709,9 +4692,10 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
#endif
p_name = BTM_SecReadDevName(bda);
if (p_name != NULL) {
BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name, p_name, BD_NAME_LEN);
sec_event.auth_cmpl.bd_name[BD_NAME_LEN] = '\0';
} else {
sec_event.auth_cmpl.bd_name[0] = 0;
sec_event.auth_cmpl.bd_name[0] = '\0';
}
if (p_data->complt.reason != 0) {
sec_event.auth_cmpl.fail_reason = BTA_DM_AUTH_CONVERT_SMP_CODE(((UINT8)p_data->complt.reason));
@@ -6197,8 +6181,8 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
/* send result back to app now, one by one */
bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
result.disc_ble_res.bd_name[BD_NAME_LEN] = '\0';
memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
bta_dm_search_cb.p_search_cback(BTA_DM_DISC_BLE_RES_EVT, &result);
@@ -6240,10 +6224,8 @@ static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
p_msg->disc_result.result.disc_res.num_uuids = 0;
p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
/* make sure the string is terminated */
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), BD_NAME_LEN);
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN] = '\0';
p_msg->disc_result.result.disc_res.device_type |= BT_DEVICE_TYPE_BLE;
if ( bta_dm_search_cb.ble_raw_used > 0 ) {

View File

@@ -174,8 +174,8 @@ void BTA_DmSetDeviceName(const char *p_name)
if ((p_msg = (tBTA_DM_API_SET_NAME *) osi_malloc(sizeof(tBTA_DM_API_SET_NAME))) != NULL) {
p_msg->hdr.event = BTA_DM_API_SET_NAME_EVT;
/* truncate the name if needed */
BCM_STRNCPY_S((char *)p_msg->name, p_name, BD_NAME_LEN - 1);
p_msg->name[BD_NAME_LEN - 1] = 0;
BCM_STRNCPY_S((char *)p_msg->name, p_name, BD_NAME_LEN);
p_msg->name[BD_NAME_LEN] = '\0';
bta_sys_sendmsg(p_msg);
}

View File

@@ -123,9 +123,9 @@ void BTA_AgRegister(tBTA_SERVICE_MASK services, tBTA_SEC sec_mask,tBTA_AG_FEAT f
for (i = 0; i < BTA_AG_NUM_IDX; i++) {
if(p_service_names[i]) {
BCM_STRNCPY_S(p_buf->p_name[i], p_service_names[i], BTA_SERVICE_NAME_LEN);
p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = 0;
p_buf->p_name[i][BTA_SERVICE_NAME_LEN] = '\0';
} else {
p_buf->p_name[i][0] = 0;
p_buf->p_name[i][0] = '\0';
}
}
bta_sys_sendmsg(p_buf);

View File

@@ -798,7 +798,7 @@ void bta_ag_at_hsp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
val.hdr.app_id = p_scb->app_id;
val.num = (UINT16) int_arg;
BCM_STRNCPY_S(val.str, p_arg, BTA_AG_AT_MAX_LEN);
val.str[BTA_AG_AT_MAX_LEN] = 0;
val.str[BTA_AG_AT_MAX_LEN] = '\0';
/* call callback with event */
(*bta_ag_cb.p_cback)(bta_ag_hsp_cb_evt[cmd], (tBTA_AG *) &val);
}
@@ -836,7 +836,7 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB *p_scb, UINT16 cmd, UINT8 arg_type,
val.num = int_arg;
bdcpy(val.bd_addr, p_scb->peer_addr);
BCM_STRNCPY_S(val.str, p_arg, BTA_AG_AT_MAX_LEN);
val.str[BTA_AG_AT_MAX_LEN] = 0;
val.str[BTA_AG_AT_MAX_LEN] = '\0';
event = bta_ag_hfp_cb_evt[cmd];
switch (cmd)
@@ -1212,7 +1212,7 @@ void bta_ag_at_err_cback(tBTA_AG_SCB *p_scb, BOOLEAN unknown, char *p_arg)
val.hdr.app_id = p_scb->app_id;
val.num = 0;
BCM_STRNCPY_S(val.str, p_arg, BTA_AG_AT_MAX_LEN);
val.str[BTA_AG_AT_MAX_LEN] = 0;
val.str[BTA_AG_AT_MAX_LEN] = '\0';
(*bta_ag_cb.p_cback)(BTA_AG_AT_UNAT_EVT, (tBTA_AG *) &val);
} else {
bta_ag_send_error(p_scb, BTA_AG_ERR_OP_NOT_SUPPORTED);
@@ -1357,7 +1357,7 @@ void bta_ag_hfp_result(tBTA_AG_SCB *p_scb, tBTA_AG_API_RESULT *p_result)
}
}
APPL_TRACE_DEBUG("CLIP type :%d", p_result->data.num);
p_scb->clip[0] = 0;
p_scb->clip[0] = '\0';
if (p_result->data.str[0] != 0) {
snprintf(p_scb->clip, sizeof(p_scb->clip), "%s,%d", p_result->data.str, p_result->data.num);
}

View File

@@ -142,7 +142,7 @@ void BTA_HfClientRegister(tBTA_SEC sec_mask, tBTA_HF_CLIENT_FEAT features,
p_buf->sec_mask = sec_mask;
if (p_service_name) {
BCM_STRNCPY_S(p_buf->name, p_service_name, BTA_SERVICE_NAME_LEN);
p_buf->name[BTA_SERVICE_NAME_LEN] = 0;
p_buf->name[BTA_SERVICE_NAME_LEN] = '\0';
} else {
p_buf->name[0] = '\0';
}

View File

@@ -74,9 +74,6 @@ static void btc_deinit_bluetooth(void)
#if BTA_DYNAMIC_MEMORY
xSemaphoreTake(deinit_semaphore, BTA_DISABLE_DELAY / portTICK_PERIOD_MS);
#endif /* #if BTA_DYNAMIC_MEMORY */
#if (BLE_INCLUDED == TRUE)
btc_gap_ble_deinit();
#endif ///BLE_INCLUDED == TRUE
bta_dm_sm_deinit();
#if (GATTC_INCLUDED)
bta_gattc_deinit();

View File

@@ -16,7 +16,6 @@
#include "common/bt_defs.h"
#include "osi/allocator.h"
#include "osi/mutex.h"
#include "osi/semaphore.h"
#include "osi/thread.h"
#include "osi/fixed_queue.h"
#include "stack/a2d_api.h"
@@ -38,8 +37,6 @@
#if (BTC_AV_SINK_INCLUDED == TRUE)
extern osi_thread_t *btc_thread;
/*****************************************************************************
** Constants
*****************************************************************************/
@@ -82,6 +79,8 @@ enum {
#define MAX_OUTPUT_A2DP_SNK_FRAME_QUEUE_SZ (25)
#define JITTER_BUFFER_WATER_LEVEL (5)
#define BTC_A2DP_SNK_DATA_QUEUE_IDX (1)
typedef struct {
uint32_t sig;
void *param;
@@ -97,7 +96,7 @@ typedef struct {
typedef struct {
BOOLEAN rx_flush; /* discards any incoming data when true */
UINT8 channel_count;
osi_sem_t post_sem;
struct osi_event *data_ready_event;
fixed_queue_t *RxSbcQ;
UINT32 sample_rate;
} tBTC_A2DP_SINK_CB;
@@ -214,7 +213,7 @@ bool btc_a2dp_sink_startup(void)
APPL_TRACE_EVENT("## A2DP SINK START MEDIA THREAD ##");
a2dp_sink_local_param.btc_aa_snk_task_hdl = btc_thread;
a2dp_sink_local_param.btc_aa_snk_task_hdl = btc_get_current_thread();
if (btc_a2dp_sink_ctrl(BTC_MEDIA_TASK_SINK_INIT, NULL) == false) {
goto error_exit;
@@ -294,11 +293,6 @@ void btc_a2dp_sink_on_suspended(tBTA_AV_SUSPEND *p_av)
return;
}
static void btc_a2dp_sink_data_post(void)
{
osi_thread_post(a2dp_sink_local_param.btc_aa_snk_task_hdl, btc_a2dp_sink_data_ready, NULL, 1, OSI_THREAD_MAX_TIMEOUT);
}
/*******************************************************************************
**
** Function btc_a2dp_sink_clear_track
@@ -356,7 +350,6 @@ static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
tBT_SBC_HDR *p_msg;
int nb_of_msgs_to_process = 0;
osi_sem_give(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem);
if (fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ)) {
APPL_TRACE_DEBUG(" QUE EMPTY ");
} else {
@@ -380,6 +373,10 @@ static void btc_a2dp_sink_data_ready(UNUSED_ATTR void *context)
nb_of_msgs_to_process--;
}
APPL_TRACE_DEBUG(" Process Frames - ");
if (!fixed_queue_is_empty(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ)) {
osi_thread_post_event(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event, OSI_THREAD_MAX_TIMEOUT);
}
}
}
@@ -691,9 +688,7 @@ UINT8 btc_a2dp_sink_enque_buf(BT_HDR *p_pkt)
APPL_TRACE_VERBOSE("btc_a2dp_sink_enque_buf %d + \n", p_msg->num_frames_to_be_processed);
fixed_queue_enqueue(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ, p_msg, FIXED_QUEUE_MAX_TIMEOUT);
if (fixed_queue_length(a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ) >= JITTER_BUFFER_WATER_LEVEL) {
if (osi_sem_take(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem, 0) == 0) {
btc_a2dp_sink_data_post();
}
osi_thread_post_event(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event, OSI_THREAD_MAX_TIMEOUT);
}
} else {
/* let caller deal with a failed allocation */
@@ -729,9 +724,12 @@ static void btc_a2dp_sink_thread_init(UNUSED_ATTR void *context)
memset(&a2dp_sink_local_param.btc_aa_snk_cb, 0, sizeof(a2dp_sink_local_param.btc_aa_snk_cb));
btc_a2dp_sink_state = BTC_A2DP_SINK_STATE_ON;
if (!a2dp_sink_local_param.btc_aa_snk_cb.post_sem) {
osi_sem_new(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem, 1, 1);
}
struct osi_event *data_event = osi_event_create(btc_a2dp_sink_data_ready, NULL);
assert (data_event != NULL);
osi_event_bind(data_event, a2dp_sink_local_param.btc_aa_snk_task_hdl, BTC_A2DP_SNK_DATA_QUEUE_IDX);
a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event = data_event;
a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ = fixed_queue_new(QUEUE_SIZE_MAX);
btc_a2dp_control_init();
@@ -749,10 +747,8 @@ static void btc_a2dp_sink_thread_cleanup(UNUSED_ATTR void *context)
a2dp_sink_local_param.btc_aa_snk_cb.RxSbcQ = NULL;
if (a2dp_sink_local_param.btc_aa_snk_cb.post_sem) {
osi_sem_free(&a2dp_sink_local_param.btc_aa_snk_cb.post_sem);
a2dp_sink_local_param.btc_aa_snk_cb.post_sem = NULL;
}
osi_event_delete(a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event);
a2dp_sink_local_param.btc_aa_snk_cb.data_ready_event = NULL;
}
#endif /* BTC_AV_SINK_INCLUDED */

View File

@@ -42,8 +42,6 @@
#if BTC_AV_SRC_INCLUDED
extern osi_thread_t *btc_thread;
/*****************************************************************************
** Constants
*****************************************************************************/
@@ -118,6 +116,8 @@ enum {
#define MAX_OUTPUT_A2DP_FRAME_QUEUE_SZ (5)
#define MAX_OUTPUT_A2DP_SRC_FRAME_QUEUE_SZ (27) // 18 for 20ms tick
#define BTC_A2DP_SRC_DATA_QUEUE_IDX (1)
typedef struct {
uint32_t sig;
void *param;
@@ -154,6 +154,7 @@ typedef struct {
tBTC_AV_MEDIA_FEEDINGS media_feeding;
SBC_ENC_PARAMS encoder;
osi_alarm_t *media_alarm;
struct osi_event *poll_data;
} tBTC_A2DP_SOURCE_CB;
typedef struct {
@@ -283,7 +284,7 @@ bool btc_a2dp_source_startup(void)
APPL_TRACE_EVENT("## A2DP SOURCE START MEDIA THREAD ##");
a2dp_source_local_param.btc_aa_src_task_hdl = btc_thread;
a2dp_source_local_param.btc_aa_src_task_hdl = btc_get_current_thread();
if (btc_a2dp_source_ctrl(BTC_MEDIA_TASK_INIT, NULL) == false) {
goto error_exit;
@@ -1532,7 +1533,7 @@ static void btc_a2dp_source_aa_stop_tx(void)
static void btc_a2dp_source_alarm_cb(UNUSED_ATTR void *context)
{
if (a2dp_source_local_param.btc_aa_src_task_hdl) {
osi_thread_post(a2dp_source_local_param.btc_aa_src_task_hdl, btc_a2dp_source_handle_timer, NULL, 1, OSI_THREAD_MAX_TIMEOUT);
osi_thread_post_event(a2dp_source_local_param.btc_aa_src_cb.poll_data, OSI_THREAD_MAX_TIMEOUT);
} else {
APPL_TRACE_DEBUG("[%s] A2DP ALREADY FREED", __func__);
btc_a2dp_source_aa_stop_tx();
@@ -1587,6 +1588,11 @@ static void btc_a2dp_source_thread_init(UNUSED_ATTR void *context)
btc_a2dp_source_state = BTC_A2DP_SOURCE_STATE_ON;
struct osi_event *poll_data = osi_event_create(btc_a2dp_source_handle_timer, NULL);
assert(poll_data != NULL);
osi_event_bind(poll_data, a2dp_source_local_param.btc_aa_src_task_hdl, BTC_A2DP_SRC_DATA_QUEUE_IDX);
a2dp_source_local_param.btc_aa_src_cb.poll_data = poll_data;
a2dp_source_local_param.btc_aa_src_cb.TxAaQ = fixed_queue_new(QUEUE_SIZE_MAX);
btc_a2dp_control_init();
@@ -1602,6 +1608,9 @@ static void btc_a2dp_source_thread_cleanup(UNUSED_ATTR void *context)
fixed_queue_free(a2dp_source_local_param.btc_aa_src_cb.TxAaQ, osi_free_func);
a2dp_source_local_param.btc_aa_src_cb.TxAaQ = NULL;
osi_event_delete(a2dp_source_local_param.btc_aa_src_cb.poll_data);
a2dp_source_local_param.btc_aa_src_cb.poll_data = NULL;
}
#endif /* BTC_AV_INCLUDED */

View File

@@ -21,6 +21,8 @@
#include "btc/btc_dm.h"
#include "btc/btc_util.h"
#include "osi/mutex.h"
#include "osi/thread.h"
#include "osi/pkt_queue.h"
#include "esp_bt.h"
#if (BLE_INCLUDED == TRUE)
@@ -48,6 +50,19 @@ static uint16_t btc_adv_list_count = 0;
#define BTC_ADV_LIST_MAX_COUNT 200
#endif
#define BTC_GAP_BLE_ADV_RPT_QUEUE_IDX (1)
#define BTC_GAP_BLE_ADV_RPT_BATCH_SIZE (10)
#define BTC_GAP_BLE_ADV_RPT_QUEUE_LEN_MAX (200)
#if (BLE_42_FEATURE_SUPPORT == TRUE)
typedef struct {
struct pkt_queue *adv_rpt_queue;
struct osi_event *adv_rpt_ready;
} btc_gap_ble_env_t;
static btc_gap_ble_env_t btc_gap_ble_env;
#endif
static inline void btc_gap_ble_cb_to_app(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
esp_gap_ble_cb_t btc_gap_ble_cb = (esp_gap_ble_cb_t)btc_profile_cb_get(BTC_PID_GAP_BLE);
@@ -548,8 +563,82 @@ static void btc_ble_set_scan_params(esp_ble_scan_params_t *scan_params, tBLE_SCA
}
}
static void btc_gap_ble_adv_pkt_handler(void *arg)
{
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
size_t pkts_to_process = pkt_queue_length(p_env->adv_rpt_queue);
if (pkts_to_process > BTC_GAP_BLE_ADV_RPT_BATCH_SIZE) {
pkts_to_process = BTC_GAP_BLE_ADV_RPT_BATCH_SIZE;
}
for (size_t i = 0; i < pkts_to_process; i++) {
pkt_linked_item_t *linked_pkt = pkt_queue_dequeue(p_env->adv_rpt_queue);
if (linked_pkt != NULL) {
esp_ble_gap_cb_param_t *param = (esp_ble_gap_cb_param_t *)(linked_pkt->data);
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RESULT_EVT, param);
osi_free(linked_pkt);
}
}
if (pkt_queue_length(p_env->adv_rpt_queue) != 0) {
osi_thread_post_event(p_env->adv_rpt_ready, OSI_THREAD_MAX_TIMEOUT);
}
}
static void btc_process_adv_rpt_pkt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
#if SCAN_QUEUE_CONGEST_CHECK
if(btc_check_queue_is_congest()) {
BTC_TRACE_DEBUG("BtcQueue is congested");
if(btc_get_adv_list_length() > BTC_ADV_LIST_MAX_LENGTH || btc_adv_list_count > BTC_ADV_LIST_MAX_COUNT) {
btc_adv_list_refresh();
btc_adv_list_count = 0;
}
if(btc_check_adv_list(p_data->inq_res.bd_addr, p_data->inq_res.ble_addr_type)) {
return;
}
}
btc_adv_list_count ++;
#endif
// drop ADV packets if data queue length goes above threshold
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
if (pkt_queue_length(p_env->adv_rpt_queue) >= BTC_GAP_BLE_ADV_RPT_QUEUE_LEN_MAX) {
return;
}
pkt_linked_item_t *linked_pkt = osi_calloc(BT_PKT_LINKED_HDR_SIZE + sizeof(esp_ble_gap_cb_param_t));
if (linked_pkt == NULL) {
return;
}
struct ble_scan_result_evt_param *scan_rst = (struct ble_scan_result_evt_param *)linked_pkt->data;
do {
scan_rst->search_evt = event;
bdcpy(scan_rst->bda, p_data->inq_res.bd_addr);
scan_rst->dev_type = p_data->inq_res.device_type;
scan_rst->rssi = p_data->inq_res.rssi;
scan_rst->ble_addr_type = p_data->inq_res.ble_addr_type;
scan_rst->ble_evt_type = p_data->inq_res.ble_evt_type;
scan_rst->flag = p_data->inq_res.flag;
scan_rst->num_resps = 1;
scan_rst->adv_data_len = p_data->inq_res.adv_data_len;
scan_rst->scan_rsp_len = p_data->inq_res.scan_rsp_len;
memcpy(scan_rst->ble_adv, p_data->inq_res.p_eir, sizeof(scan_rst->ble_adv));
} while (0);
pkt_queue_enqueue(p_env->adv_rpt_queue, linked_pkt);
osi_thread_post_event(p_env->adv_rpt_ready, OSI_THREAD_MAX_TIMEOUT);
}
static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
{
if (event == BTA_DM_INQ_RES_EVT) {
btc_process_adv_rpt_pkt(event, p_data);
return;
}
esp_ble_gap_cb_param_t param;
btc_msg_t msg = {0};
@@ -559,32 +648,8 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
param.scan_rst.search_evt = event;
switch (event) {
case BTA_DM_INQ_RES_EVT: {
#if SCAN_QUEUE_CONGEST_CHECK
if(btc_check_queue_is_congest()) {
BTC_TRACE_DEBUG("BtcQueue is congested");
if(btc_get_adv_list_length() > BTC_ADV_LIST_MAX_LENGTH || btc_adv_list_count > BTC_ADV_LIST_MAX_COUNT) {
btc_adv_list_refresh();
btc_adv_list_count = 0;
}
if(btc_check_adv_list(p_data->inq_res.bd_addr, p_data->inq_res.ble_addr_type)) {
return;
}
}
btc_adv_list_count ++;
#endif
bdcpy(param.scan_rst.bda, p_data->inq_res.bd_addr);
param.scan_rst.dev_type = p_data->inq_res.device_type;
param.scan_rst.rssi = p_data->inq_res.rssi;
param.scan_rst.ble_addr_type = p_data->inq_res.ble_addr_type;
param.scan_rst.ble_evt_type = p_data->inq_res.ble_evt_type;
param.scan_rst.flag = p_data->inq_res.flag;
param.scan_rst.num_resps = 1;
param.scan_rst.adv_data_len = p_data->inq_res.adv_data_len;
param.scan_rst.scan_rsp_len = p_data->inq_res.scan_rsp_len;
memcpy(param.scan_rst.ble_adv, p_data->inq_res.p_eir, sizeof(param.scan_rst.ble_adv));
case BTA_DM_INQ_RES_EVT:
break;
}
case BTA_DM_INQ_CMPL_EVT: {
param.scan_rst.num_resps = p_data->inq_cmpl.num_resps;
BTC_TRACE_DEBUG("%s BLE observe complete. Num Resp %d\n", __FUNCTION__, p_data->inq_cmpl.num_resps);
@@ -1841,9 +1906,31 @@ void btc_gap_callback_init(void)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
}
bool btc_gap_ble_init(void)
{
#if (BLE_42_FEATURE_SUPPORT == TRUE)
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
p_env->adv_rpt_queue = pkt_queue_create();
assert(p_env->adv_rpt_queue != NULL);
p_env->adv_rpt_ready = osi_event_create(btc_gap_ble_adv_pkt_handler, NULL);
assert(p_env->adv_rpt_ready != NULL);
osi_event_bind(p_env->adv_rpt_ready, btc_get_current_thread(), BTC_GAP_BLE_ADV_RPT_QUEUE_IDX);
#endif
return true;
}
void btc_gap_ble_deinit(void)
{
#if (BLE_42_FEATURE_SUPPORT == TRUE)
#if (BLE_42_FEATURE_SUPPORT == TRUE)
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
osi_event_delete(p_env->adv_rpt_ready);
p_env->adv_rpt_ready = NULL;
pkt_queue_destroy(p_env->adv_rpt_queue, NULL);
p_env->adv_rpt_queue = NULL;
btc_cleanup_adv_data(&gl_bta_adv_data);
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)

View File

@@ -345,6 +345,7 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_free(btc_msg_t *msg);
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
void btc_gap_callback_init(void);
bool btc_gap_ble_init(void);
void btc_gap_ble_deinit(void);
void btc_adv_list_init(void);
void btc_adv_list_deinit(void);

View File

@@ -19,24 +19,38 @@
#include "common/bt_defs.h"
#include "common/bt_trace.h"
#include "stack/bt_types.h"
#include "osi/fixed_queue.h"
#include "hci/hci_hal.h"
#include "hci/hci_internals.h"
#include "hci/hci_layer.h"
#include "osi/thread.h"
#include "osi/pkt_queue.h"
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
#include "osi/mutex.h"
#include "osi/alarm.h"
#endif
#include "esp_bt.h"
#include "stack/hcimsgs.h"
#if SOC_ESP_NIMBLE_CONTROLLER
#include "nimble/ble_hci_trans.h"
#endif
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
#include "l2c_int.h"
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
#include "stack/hcimsgs.h"
#if SOC_ESP_NIMBLE_CONTROLLER
#include "nimble/ble_hci_trans.h"
#endif
#define HCI_HAL_SERIAL_BUFFER_SIZE 1026
#define HCI_BLE_EVENT 0x3e
#define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
#define PACKET_TYPE_TO_INDEX(type) ((type) - 1)
#define HCI_UPSTREAM_DATA_QUEUE_IDX (1)
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
#define HCI_BLE_ADV_MIN_CREDITS_TO_RELEASE (10)
#define HCI_ADV_FLOW_MONITOR_PERIOD_MS (500)
#else
#define HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX (200)
#endif
extern bool BTU_check_queue_is_congest(void);
@@ -55,64 +69,102 @@ static const uint16_t outbound_event_types[] = {
};
typedef struct {
size_t buffer_size;
fixed_queue_t *rx_q;
uint16_t adv_free_num;
struct pkt_queue *adv_rpt_q;
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
osi_mutex_t adv_flow_lock;
osi_alarm_t *adv_flow_monitor;
int adv_credits;
int adv_credits_to_release;
pkt_linked_item_t *adv_fc_cmd_buf;
bool cmd_buf_in_use;
#endif
hci_hal_callbacks_t *callbacks;
osi_thread_t *hci_h4_thread;
struct osi_event *upstream_data_ready;
} hci_hal_env_t;
static hci_hal_env_t hci_hal_env;
static const hci_hal_t interface;
static const hci_hal_callbacks_t *callbacks;
static const esp_vhci_host_callback_t vhci_host_cb;
static osi_thread_t *hci_h4_thread;
static void host_send_pkt_available_cb(void);
static int host_recv_pkt_cb(uint8_t *data, uint16_t len);
static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet);
static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt);
static void hci_upstream_data_handler(void *arg);
static bool hci_upstream_data_post(uint32_t timeout);
static void hci_hal_h4_rx_handler(void *arg);
static void event_uart_has_bytes(fixed_queue_t *queue);
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
static void hci_adv_flow_monitor(void *context);
static void hci_adv_flow_cmd_free_cb(pkt_linked_item_t *linked_pkt);
#endif
static void hci_hal_env_init(
size_t buffer_size,
size_t max_buffer_count)
static bool hci_hal_env_init(const hci_hal_callbacks_t *upper_callbacks, osi_thread_t *task_thread)
{
assert(buffer_size > 0);
assert(max_buffer_count > 0);
assert(upper_callbacks != NULL);
assert(task_thread != NULL);
hci_hal_env.buffer_size = buffer_size;
hci_hal_env.adv_free_num = 0;
hci_hal_env.hci_h4_thread = task_thread;
hci_hal_env.callbacks = (hci_hal_callbacks_t *)upper_callbacks;
hci_hal_env.rx_q = fixed_queue_new(max_buffer_count);
if (hci_hal_env.rx_q) {
fixed_queue_register_dequeue(hci_hal_env.rx_q, event_uart_has_bytes);
} else {
HCI_TRACE_ERROR("%s unable to create rx queue.\n", __func__);
}
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_hal_env.adv_fc_cmd_buf = osi_calloc(HCI_CMD_LINKED_BUF_SIZE(HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL));
assert(hci_hal_env.adv_fc_cmd_buf != NULL);
osi_mutex_new(&hci_hal_env.adv_flow_lock);
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
hci_hal_env.adv_credits = BLE_ADV_REPORT_FLOW_CONTROL_NUM;
hci_hal_env.adv_credits_to_release = 0;
hci_hal_env.cmd_buf_in_use = false;
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
hci_hal_env.adv_flow_monitor = osi_alarm_new("adv_fc_mon", hci_adv_flow_monitor, NULL, HCI_ADV_FLOW_MONITOR_PERIOD_MS);
assert (hci_hal_env.adv_flow_monitor != NULL);
#endif
return;
hci_hal_env.rx_q = fixed_queue_new(QUEUE_SIZE_MAX);
assert(hci_hal_env.rx_q != NULL);
hci_hal_env.adv_rpt_q = pkt_queue_create();
assert(hci_hal_env.adv_rpt_q != NULL);
struct osi_event *event = osi_event_create(hci_upstream_data_handler, NULL);
assert(event != NULL);
hci_hal_env.upstream_data_ready = event;
osi_event_bind(hci_hal_env.upstream_data_ready, hci_hal_env.hci_h4_thread, HCI_UPSTREAM_DATA_QUEUE_IDX);
return true;
}
static void hci_hal_env_deinit(void)
{
fixed_queue_free(hci_hal_env.rx_q, osi_free_func);
hci_hal_env.rx_q = NULL;
pkt_queue_destroy(hci_hal_env.adv_rpt_q, NULL);
hci_hal_env.adv_rpt_q = NULL;
osi_event_delete(hci_hal_env.upstream_data_ready);
hci_hal_env.upstream_data_ready = NULL;
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_hal_env.cmd_buf_in_use = true;
osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
osi_alarm_free(hci_hal_env.adv_flow_monitor);
hci_hal_env.adv_flow_monitor = NULL;
osi_mutex_free(&hci_hal_env.adv_flow_lock);
osi_free(hci_hal_env.adv_fc_cmd_buf);
hci_hal_env.adv_fc_cmd_buf = NULL;
#endif
hci_hal_env.hci_h4_thread = NULL;
memset(&hci_hal_env, 0, sizeof(hci_hal_env_t));
}
static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thread)
{
assert(upper_callbacks != NULL);
assert(task_thread != NULL);
callbacks = upper_callbacks;
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, BLE_ADV_REPORT_FLOW_CONTROL_NUM + L2CAP_HOST_FC_ACL_BUFS + QUEUE_SIZE_MAX); // adv flow control num + ACL flow control num + hci cmd numeber
#else
hci_hal_env_init(HCI_HAL_SERIAL_BUFFER_SIZE, QUEUE_SIZE_MAX);
#endif
hci_h4_thread = (osi_thread_t *)task_thread;
hci_hal_env_init(upper_callbacks, (osi_thread_t *)task_thread);
//register vhci host cb
if (esp_vhci_host_register_callback(&vhci_host_cb) != ESP_OK) {
@@ -125,8 +177,6 @@ static bool hal_open(const hci_hal_callbacks_t *upper_callbacks, void *task_thre
static void hal_close(void)
{
hci_hal_env_deinit();
hci_h4_thread = NULL;
}
/**
@@ -166,14 +216,40 @@ static uint16_t transmit_data(serial_data_type_t type,
}
// Internal functions
static void hci_hal_h4_rx_handler(void *arg)
static void hci_upstream_data_handler(void *arg)
{
fixed_queue_process(hci_hal_env.rx_q);
fixed_queue_t *rx_q = hci_hal_env.rx_q;
struct pkt_queue *adv_rpt_q = hci_hal_env.adv_rpt_q;
size_t pkts_to_process;
do {
pkts_to_process = fixed_queue_length(rx_q);
for (size_t i = 0; i < pkts_to_process; i++) {
BT_HDR *packet = fixed_queue_dequeue(rx_q, 0);
if (packet != NULL) {
hci_hal_h4_hdl_rx_packet(packet);
}
}
} while (0);
do {
pkts_to_process = pkt_queue_length(adv_rpt_q);
for (size_t i = 0; i < pkts_to_process; i++) {
pkt_linked_item_t *linked_pkt = pkt_queue_dequeue(adv_rpt_q);
if (linked_pkt != NULL) {
hci_hal_h4_hdl_rx_adv_rpt(linked_pkt);
}
}
} while (0);
if (!fixed_queue_is_empty(rx_q) || pkt_queue_length(adv_rpt_q) > 0) {
hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT);
}
}
bool hci_hal_h4_task_post(uint32_t timeout)
static bool hci_upstream_data_post(uint32_t timeout)
{
return osi_thread_post(hci_h4_thread, hci_hal_h4_rx_handler, NULL, 1, timeout);
return osi_thread_post_event(hci_hal_env.upstream_data_ready, timeout);
}
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
@@ -192,13 +268,13 @@ static void hci_packet_complete(BT_HDR *packet){
}
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
bool host_recv_adv_packet(BT_HDR *packet)
bool host_recv_adv_packet(uint8_t *packet)
{
assert(packet);
if(packet->data[0] == DATA_TYPE_EVENT && packet->data[1] == HCI_BLE_EVENT) {
if(packet->data[3] == HCI_BLE_ADV_PKT_RPT_EVT
if(packet[0] == DATA_TYPE_EVENT && packet[1] == HCI_BLE_EVENT) {
if(packet[3] == HCI_BLE_ADV_PKT_RPT_EVT || packet[3] == HCI_BLE_DIRECT_ADV_EVT
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|| packet->data[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT
|| packet[3] == HCI_BLE_ADV_DISCARD_REPORT_EVT
#endif
) {
return true;
@@ -208,21 +284,128 @@ bool host_recv_adv_packet(BT_HDR *packet)
}
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
static void hci_update_adv_report_flow_control(BT_HDR *packet)
static void hci_adv_flow_monitor(void *context)
{
// this is adv packet
if(host_recv_adv_packet(packet)) {
// update adv free number
hci_hal_env.adv_free_num ++;
if (esp_vhci_host_check_send_available()){
// send hci cmd
btsnd_hcic_ble_update_adv_report_flow_control(hci_hal_env.adv_free_num);
hci_hal_env.adv_free_num = 0;
hci_adv_credits_force_release(0);
}
static void hci_adv_credits_consumed(uint16_t num)
{
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
assert(hci_hal_env.adv_credits >= num);
hci_hal_env.adv_credits -= num;
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
}
int hci_adv_credits_prep_to_release(uint16_t num)
{
if (num == 0) {
return hci_hal_env.adv_credits_to_release;
}
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
int credits_to_release = hci_hal_env.adv_credits_to_release + num;
assert(hci_hal_env.adv_credits_to_release <= BLE_ADV_REPORT_FLOW_CONTROL_NUM);
hci_hal_env.adv_credits_to_release = credits_to_release;
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
if (credits_to_release == num && num != 0) {
osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
osi_alarm_set(hci_hal_env.adv_flow_monitor, HCI_ADV_FLOW_MONITOR_PERIOD_MS);
}
return credits_to_release;
}
static int hci_adv_credits_release(void)
{
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
int credits_released = hci_hal_env.adv_credits_to_release;
hci_hal_env.adv_credits += credits_released;
hci_hal_env.adv_credits_to_release -= credits_released;
assert(hci_hal_env.adv_credits <= BLE_ADV_REPORT_FLOW_CONTROL_NUM);
assert(hci_hal_env.adv_credits_to_release >= 0);
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
if (hci_hal_env.adv_credits_to_release == 0) {
osi_alarm_cancel(hci_hal_env.adv_flow_monitor);
}
return credits_released;
}
static int hci_adv_credits_release_rollback(uint16_t num)
{
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
hci_hal_env.adv_credits -= num;
hci_hal_env.adv_credits_to_release += num;
assert(hci_hal_env.adv_credits >=0);
assert(hci_hal_env.adv_credits_to_release <= BLE_ADV_REPORT_FLOW_CONTROL_NUM);
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
return num;
}
static void hci_adv_flow_cmd_free_cb(pkt_linked_item_t *linked_pkt)
{
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
hci_hal_env.cmd_buf_in_use = false;
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
hci_adv_credits_try_release(0);
}
bool hci_adv_flow_try_send_command(uint16_t credits_released)
{
bool sent = false;
bool use_static_buffer = false;
/* first try using static buffer, then dynamic buffer */
if (!hci_hal_env.cmd_buf_in_use) {
osi_mutex_lock(&hci_hal_env.adv_flow_lock, OSI_MUTEX_MAX_TIMEOUT);
if (!hci_hal_env.cmd_buf_in_use) {
hci_hal_env.cmd_buf_in_use = true;
use_static_buffer = true;
}
osi_mutex_unlock(&hci_hal_env.adv_flow_lock);
}
if (use_static_buffer) {
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(hci_hal_env.adv_fc_cmd_buf->data);
BT_HDR *static_buffer = &metadata->command;
metadata->command_free_cb = hci_adv_flow_cmd_free_cb;
sent = btsnd_hcic_ble_update_adv_report_flow_control(credits_released, static_buffer);
} else {
sent = btsnd_hcic_ble_update_adv_report_flow_control(credits_released, NULL);
}
return sent;
}
int hci_adv_credits_try_release(uint16_t num)
{
int credits_released = 0;
if (hci_adv_credits_prep_to_release(num) >= HCI_BLE_ADV_MIN_CREDITS_TO_RELEASE) {
credits_released = hci_adv_credits_release();
if (credits_released > 0) {
if (!hci_adv_flow_try_send_command(credits_released)) {
hci_adv_credits_release_rollback(credits_released);
}
} else {
//do nothing
assert (credits_released == 0);
}
}
return credits_released;
}
int hci_adv_credits_force_release(uint16_t num)
{
hci_adv_credits_prep_to_release(num);
int credits_released = hci_adv_credits_release();
if (credits_released > 0) {
if (!hci_adv_flow_try_send_command(credits_released)) {
hci_adv_credits_release_rollback(credits_released);
}
}
return credits_released;
}
#endif
@@ -283,61 +466,125 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
return;
}
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_update_adv_report_flow_control(packet);
#endif
#if SCAN_QUEUE_CONGEST_CHECK
if(BTU_check_queue_is_congest() && host_recv_adv_packet(packet)) {
HCI_TRACE_DEBUG("BtuQueue is congested");
osi_free(packet);
return;
}
#endif
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
callbacks->packet_ready(packet);
hci_hal_env.callbacks->packet_ready(packet);
}
static void event_uart_has_bytes(fixed_queue_t *queue)
static void hci_hal_h4_hdl_rx_adv_rpt(pkt_linked_item_t *linked_pkt)
{
BT_HDR *packet;
while (!fixed_queue_is_empty(queue)) {
packet = fixed_queue_dequeue(queue, FIXED_QUEUE_MAX_TIMEOUT);
hci_hal_h4_hdl_rx_packet(packet);
uint8_t type;
uint8_t hdr_size;
uint16_t length;
uint8_t *stream = NULL;
if (!linked_pkt) {
return;
}
BT_HDR* packet = (BT_HDR *)linked_pkt->data;
stream = packet->data + packet->offset;
assert(host_recv_adv_packet(stream) == true);
STREAM_TO_UINT8(type, stream);
packet->offset++;
packet->len--;
hdr_size = preamble_sizes[type - 1];
if (packet->len < hdr_size) {
HCI_TRACE_ERROR("Wrong packet length type=%d pkt_len=%d hdr_len=%d",
type, packet->len, hdr_size);
goto _discard_packet;
}
stream += hdr_size - 1;
STREAM_TO_UINT8(length, stream);
if ((length + hdr_size) != packet->len) {
HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
"pkt_len=%d", type, hdr_size, length, packet->len);
goto _discard_packet;
}
#if SCAN_QUEUE_CONGEST_CHECK
if(BTU_check_queue_is_congest()) {
HCI_TRACE_DEBUG("BtuQueue is congested");
goto _discard_packet;
}
#endif
packet->event = outbound_event_types[PACKET_TYPE_TO_INDEX(type)];
hci_hal_env.callbacks->adv_rpt_ready(linked_pkt);
return;
_discard_packet:
osi_free(linked_pkt);
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_prep_to_release(1);
#endif
}
static void host_send_pkt_available_cb(void)
{
//Controller rx cache buffer is ready for receiving new host packet
//Just Call Host main thread task to process pending packets.
hci_host_task_post(OSI_THREAD_MAX_TIMEOUT);
hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT);
}
static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
{
//Target has packet to host, malloc new buffer for packet
BT_HDR *pkt;
BT_HDR *pkt = NULL;
pkt_linked_item_t *linked_pkt = NULL;
size_t pkt_size;
if (hci_hal_env.rx_q == NULL) {
return 0;
}
pkt_size = BT_HDR_SIZE + len;
pkt = (BT_HDR *) osi_calloc(pkt_size);
bool is_adv_rpt = host_recv_adv_packet(data);
if (!pkt) {
HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
return -1;
if (!is_adv_rpt) {
pkt_size = BT_HDR_SIZE + len;
pkt = (BT_HDR *) osi_calloc(pkt_size);
if (!pkt) {
HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__);
assert(0);
}
pkt->offset = 0;
pkt->len = len;
pkt->layer_specific = 0;
memcpy(pkt->data, data, len);
fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
} else {
#if !BLE_ADV_REPORT_FLOW_CONTROL
// drop the packets if pkt_queue length goes beyond upper limit
if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) {
return 0;
}
#endif
pkt_size = BT_PKT_LINKED_HDR_SIZE + BT_HDR_SIZE + len;
linked_pkt = (pkt_linked_item_t *) osi_calloc(pkt_size);
if (!linked_pkt) {
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_consumed(1);
hci_adv_credits_prep_to_release(1);
#endif
return 0;
}
pkt = (BT_HDR *)linked_pkt->data;
pkt->offset = 0;
pkt->len = len;
pkt->layer_specific = 0;
memcpy(pkt->data, data, len);
pkt_queue_enqueue(hci_hal_env.adv_rpt_q, linked_pkt);
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_consumed(1);
#endif
}
pkt->offset = 0;
pkt->len = len;
pkt->layer_specific = 0;
memcpy(pkt->data, data, len);
fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
hci_hal_h4_task_post(0);
hci_upstream_data_post(OSI_THREAD_MAX_TIMEOUT);
BTTRC_DUMP_BUFFER("Recv Pkt", pkt->data, len);

View File

@@ -35,20 +35,17 @@
#include "osi/thread.h"
#include "osi/mutex.h"
#include "osi/fixed_queue.h"
#include "osi/fixed_pkt_queue.h"
#define HCI_HOST_TASK_PINNED_TO_CORE (TASK_PINNED_TO_CORE)
#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_HOST_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 3)
#define HCI_HOST_TASK_NAME "hciT"
#define HCI_HOST_TASK_WORKQUEUE_NUM (2)
#define HCI_HOST_TASK_WORKQUEUE0_LEN (1) // for downstream datapath
#define HCI_HOST_TASK_WORKQUEUE1_LEN (1) // for upstream datapath
typedef struct {
uint16_t opcode;
future_t *complete_future;
command_complete_cb complete_callback;
command_status_cb status_callback;
void *context;
BT_HDR *command;
} waiting_command_t;
#define HCI_DOWNSTREAM_DATA_QUEUE_IDX (0)
typedef struct {
bool timer_is_set;
@@ -59,9 +56,9 @@ typedef struct {
typedef struct {
int command_credits;
fixed_queue_t *command_queue;
fixed_pkt_queue_t *command_queue;
fixed_queue_t *packet_queue;
struct osi_event *downstream_data_ready;
command_waiting_response_t cmd_waiting_q;
/*
@@ -89,16 +86,17 @@ static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks;
static int hci_layer_init_env(void);
static void hci_layer_deinit_env(void);
static void hci_host_thread_handler(void *arg);
static void event_command_ready(fixed_queue_t *queue);
static void hci_downstream_data_handler(void *arg);
static void event_command_ready(fixed_pkt_queue_t *queue);
static void event_packet_ready(fixed_queue_t *queue);
static void restart_command_waiting_response_timer(command_waiting_response_t *cmd_wait_q);
static void command_timed_out(void *context);
static void hal_says_packet_ready(BT_HDR *packet);
static bool filter_incoming_event(BT_HDR *packet);
static serial_data_type_t event_to_data_type(uint16_t event);
static waiting_command_t *get_waiting_command(command_opcode_t opcode);
static pkt_linked_item_t *get_waiting_command(command_opcode_t opcode);
static void dispatch_reassembled(BT_HDR *packet);
static void dispatch_adv_report(pkt_linked_item_t *linked_pkt);
// Module lifecycle functions
int hci_start_up(void)
@@ -107,11 +105,15 @@ int hci_start_up(void)
goto error;
}
hci_host_thread = osi_thread_create(HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, HCI_HOST_TASK_PRIO, HCI_HOST_TASK_PINNED_TO_CORE, 2);
const size_t workqueue_len[] = {HCI_HOST_TASK_WORKQUEUE0_LEN, HCI_HOST_TASK_WORKQUEUE1_LEN};
hci_host_thread = osi_thread_create(HCI_HOST_TASK_NAME, HCI_HOST_TASK_STACK_SIZE, HCI_HOST_TASK_PRIO, HCI_HOST_TASK_PINNED_TO_CORE,
HCI_HOST_TASK_WORKQUEUE_NUM, workqueue_len);
if (hci_host_thread == NULL) {
return -2;
}
osi_event_bind(hci_host_env.downstream_data_ready, hci_host_thread, HCI_DOWNSTREAM_DATA_QUEUE_IDX);
packet_fragmenter->init(&packet_fragmenter_callbacks);
hal->open(&hal_callbacks, hci_host_thread);
@@ -136,10 +138,9 @@ void hci_shut_down(void)
hci_host_thread = NULL;
}
bool hci_host_task_post(uint32_t timeout)
bool hci_downstream_data_post(uint32_t timeout)
{
return osi_thread_post(hci_host_thread, hci_host_thread_handler, NULL, 0, timeout);
return osi_thread_post_event(hci_host_env.downstream_data_ready, timeout);
}
static int hci_layer_init_env(void)
@@ -150,14 +151,18 @@ static int hci_layer_init_env(void)
// as per the Bluetooth spec, Volume 2, Part E, 4.4 (Command Flow Control)
// This value can change when you get a command complete or command status event.
hci_host_env.command_credits = 1;
hci_host_env.command_queue = fixed_queue_new(QUEUE_SIZE_MAX);
hci_host_env.command_queue = fixed_pkt_queue_new(QUEUE_SIZE_MAX);
if (hci_host_env.command_queue) {
fixed_queue_register_dequeue(hci_host_env.command_queue, event_command_ready);
fixed_pkt_queue_register_dequeue(hci_host_env.command_queue, event_command_ready);
} else {
HCI_TRACE_ERROR("%s unable to create pending command queue.", __func__);
return -1;
}
struct osi_event *event = osi_event_create(hci_downstream_data_handler, NULL);
assert(event != NULL);
hci_host_env.downstream_data_ready = event;
hci_host_env.packet_queue = fixed_queue_new(QUEUE_SIZE_MAX);
if (hci_host_env.packet_queue) {
fixed_queue_register_dequeue(hci_host_env.packet_queue, event_packet_ready);
@@ -191,8 +196,11 @@ static void hci_layer_deinit_env(void)
{
command_waiting_response_t *cmd_wait_q;
osi_event_delete(hci_host_env.downstream_data_ready);
hci_host_env.downstream_data_ready = NULL;
if (hci_host_env.command_queue) {
fixed_queue_free(hci_host_env.command_queue, osi_free_func);
fixed_pkt_queue_free(hci_host_env.command_queue, (fixed_pkt_queue_free_cb)osi_free_func);
}
if (hci_host_env.packet_queue) {
fixed_queue_free(hci_host_env.packet_queue, osi_free_func);
@@ -208,7 +216,7 @@ static void hci_layer_deinit_env(void)
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
}
static void hci_host_thread_handler(void *arg)
static void hci_downstream_data_handler(void *arg)
{
/*
* Previous task handles RX queue and two TX Queues, Since there is
@@ -218,18 +226,19 @@ static void hci_host_thread_handler(void *arg)
* All packets will be directly copied to single queue in driver layer with
* H4 type header added (1 byte).
*/
if (esp_vhci_host_check_send_available()) {
while (esp_vhci_host_check_send_available()) {
/*Now Target only allowed one packet per TX*/
BT_HDR *pkt = packet_fragmenter->fragment_current_packet();
if (pkt != NULL) {
packet_fragmenter->fragment_and_dispatch(pkt);
} else {
if (!fixed_queue_is_empty(hci_host_env.command_queue) &&
} else if (!fixed_pkt_queue_is_empty(hci_host_env.command_queue) &&
hci_host_env.command_credits > 0) {
fixed_queue_process(hci_host_env.command_queue);
} else if (!fixed_queue_is_empty(hci_host_env.packet_queue)) {
fixed_queue_process(hci_host_env.packet_queue);
}
fixed_pkt_queue_process(hci_host_env.command_queue);
} else if (!fixed_queue_is_empty(hci_host_env.packet_queue)) {
fixed_queue_process(hci_host_env.packet_queue);
} else {
// No downstream packet to send, stop processing
break;
}
}
}
@@ -240,81 +249,73 @@ static void transmit_command(
command_status_cb status_callback,
void *context)
{
uint8_t *stream;
waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t));
if (!wait_entry) {
HCI_TRACE_ERROR("%s couldn't allocate space for wait entry.", __func__);
return;
}
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(command);
pkt_linked_item_t *linked_pkt = HCI_GET_CMD_LINKED_STRUCT(metadata);
stream = command->data + command->offset;
STREAM_TO_UINT16(wait_entry->opcode, stream);
wait_entry->complete_callback = complete_callback;
wait_entry->status_callback = status_callback;
wait_entry->command = command;
wait_entry->context = context;
assert(command->layer_specific == HCI_CMD_BUF_TYPE_METADATA);
metadata->flags_vnd |= HCI_CMD_MSG_F_VND_QUEUED;
// Store the command message type in the event field
// in case the upper layer didn't already
command->event = MSG_STACK_TO_HC_HCI_CMD;
HCI_TRACE_DEBUG("HCI Enqueue Comamnd opcode=0x%x\n", wait_entry->opcode);
HCI_TRACE_DEBUG("HCI Enqueue Comamnd opcode=0x%x\n", metadata->opcode);
BTTRC_DUMP_BUFFER(NULL, command->data + command->offset, command->len);
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry, FIXED_QUEUE_MAX_TIMEOUT);
hci_host_task_post(OSI_THREAD_MAX_TIMEOUT);
fixed_pkt_queue_enqueue(hci_host_env.command_queue, linked_pkt, FIXED_PKT_QUEUE_MAX_TIMEOUT);
hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT);
}
static future_t *transmit_command_futured(BT_HDR *command)
{
waiting_command_t *wait_entry = osi_calloc(sizeof(waiting_command_t));
assert(wait_entry != NULL);
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(command);
pkt_linked_item_t *linked_pkt = HCI_GET_CMD_LINKED_STRUCT(metadata);
assert(command->layer_specific == HCI_CMD_BUF_TYPE_METADATA);
metadata->flags_vnd |= (HCI_CMD_MSG_F_VND_QUEUED | HCI_CMD_MSG_F_VND_FUTURE);
future_t *future = future_new();
uint8_t *stream = command->data + command->offset;
STREAM_TO_UINT16(wait_entry->opcode, stream);
wait_entry->complete_future = future;
wait_entry->command = command;
metadata->complete_future = future;
// Store the command message type in the event field
// in case the upper layer didn't already
command->event = MSG_STACK_TO_HC_HCI_CMD;
fixed_queue_enqueue(hci_host_env.command_queue, wait_entry, FIXED_QUEUE_MAX_TIMEOUT);
hci_host_task_post(OSI_THREAD_MAX_TIMEOUT);
fixed_pkt_queue_enqueue(hci_host_env.command_queue, linked_pkt, FIXED_PKT_QUEUE_MAX_TIMEOUT);
hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT);
return future;
}
static void transmit_downward(uint16_t type, void *data)
{
if (type == MSG_STACK_TO_HC_HCI_CMD) {
transmit_command((BT_HDR *)data, NULL, NULL, NULL);
HCI_TRACE_WARNING("%s legacy transmit of command. Use transmit_command instead.\n", __func__);
HCI_TRACE_ERROR("%s legacy transmit of command. Use transmit_command instead.\n", __func__);
assert(0);
} else {
fixed_queue_enqueue(hci_host_env.packet_queue, data, FIXED_QUEUE_MAX_TIMEOUT);
}
hci_host_task_post(OSI_THREAD_MAX_TIMEOUT);
hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT);
}
// Command/packet transmitting functions
static void event_command_ready(fixed_queue_t *queue)
static void event_command_ready(fixed_pkt_queue_t *queue)
{
waiting_command_t *wait_entry = NULL;
pkt_linked_item_t *wait_entry = NULL;
command_waiting_response_t *cmd_wait_q = &hci_host_env.cmd_waiting_q;
wait_entry = fixed_queue_dequeue(queue, FIXED_QUEUE_MAX_TIMEOUT);
wait_entry = fixed_pkt_queue_dequeue(queue, FIXED_QUEUE_MAX_TIMEOUT);
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(wait_entry->data);
metadata->flags_vnd |= HCI_CMD_MSG_F_VND_SENT;
metadata->flags_vnd &= ~HCI_CMD_MSG_F_VND_QUEUED;
if(wait_entry->opcode == HCI_HOST_NUM_PACKETS_DONE
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
|| wait_entry->opcode == HCI_VENDOR_BLE_ADV_REPORT_FLOW_CONTROL
#endif
){
packet_fragmenter->fragment_and_dispatch(wait_entry->command);
osi_free(wait_entry->command);
osi_free(wait_entry);
if (metadata->flags_src & HCI_CMD_MSG_F_SRC_NOACK) {
packet_fragmenter->fragment_and_dispatch(&metadata->command);
hci_cmd_free_cb free_func = metadata->command_free_cb ? metadata->command_free_cb : (hci_cmd_free_cb) osi_free_func;
free_func(wait_entry);
return;
}
hci_host_env.command_credits--;
@@ -324,7 +325,7 @@ static void event_command_ready(fixed_queue_t *queue)
osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock);
// Send it off
packet_fragmenter->fragment_and_dispatch(wait_entry->command);
packet_fragmenter->fragment_and_dispatch(&metadata->command);
restart_command_waiting_response_timer(cmd_wait_q);
}
@@ -389,7 +390,7 @@ static void restart_command_waiting_response_timer(command_waiting_response_t *c
static void command_timed_out(void *context)
{
command_waiting_response_t *cmd_wait_q = (command_waiting_response_t *)context;
waiting_command_t *wait_entry;
pkt_linked_item_t *wait_entry;
osi_mutex_lock(&cmd_wait_q->commands_pending_response_lock, OSI_MUTEX_MAX_TIMEOUT);
wait_entry = (list_is_empty(cmd_wait_q->commands_pending_response) ?
@@ -402,7 +403,8 @@ static void command_timed_out(void *context)
// We shouldn't try to recover the stack from this command timeout.
// If it's caused by a software bug, fix it. If it's a hardware bug, fix it.
{
HCI_TRACE_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, wait_entry->opcode);
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(wait_entry->data);
HCI_TRACE_ERROR("%s hci layer timeout waiting for response to a command. opcode: 0x%x", __func__, metadata->opcode);
}
}
@@ -416,12 +418,18 @@ static void hal_says_packet_ready(BT_HDR *packet)
}
}
static void hal_says_adv_rpt_ready(pkt_linked_item_t *linked_pkt)
{
dispatch_adv_report(linked_pkt);
}
// Returns true if the event was intercepted and should not proceed to
// higher layers. Also inspects an incoming event for interesting
// information, like how many commands are now able to be sent.
static bool filter_incoming_event(BT_HDR *packet)
{
waiting_command_t *wait_entry = NULL;
pkt_linked_item_t *wait_entry = NULL;
hci_cmd_metadata_t *metadata = NULL;
uint8_t *stream = packet->data + packet->offset;
uint8_t event_code;
command_opcode_t opcode;
@@ -435,10 +443,11 @@ static bool filter_incoming_event(BT_HDR *packet)
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
STREAM_TO_UINT16(opcode, stream);
wait_entry = get_waiting_command(opcode);
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
if (!wait_entry) {
HCI_TRACE_WARNING("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
} else if (wait_entry->complete_callback) {
wait_entry->complete_callback(packet, wait_entry->context);
} else if (metadata->command_complete_cb) {
metadata->command_complete_cb(packet, metadata->context);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
BlE_SYNC *sync_info = btsnd_hcic_ble_get_sync_info();
if(!sync_info) {
@@ -450,8 +459,8 @@ static bool filter_incoming_event(BT_HDR *packet)
}
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
} else if (wait_entry->complete_future) {
future_ready(wait_entry->complete_future, packet);
} else if (metadata->flags_vnd & HCI_CMD_MSG_F_VND_FUTURE) {
future_ready((future_t *)(metadata->complete_future), packet);
}
goto intercepted;
@@ -464,10 +473,11 @@ static bool filter_incoming_event(BT_HDR *packet)
// If a command generates a command status event, it won't be getting a command complete event
wait_entry = get_waiting_command(opcode);
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
if (!wait_entry) {
HCI_TRACE_WARNING("%s command status event with no matching command. opcode: 0x%x", __func__, opcode);
} else if (wait_entry->status_callback) {
wait_entry->status_callback(status, wait_entry->command, wait_entry->context);
} else if (metadata->command_status_cb) {
metadata->command_status_cb(status, &metadata->command, metadata->context);
}
goto intercepted;
@@ -479,23 +489,22 @@ intercepted:
/*Tell HCI Host Task to continue TX Pending commands*/
if (hci_host_env.command_credits &&
!fixed_queue_is_empty(hci_host_env.command_queue)) {
hci_host_task_post(OSI_THREAD_MAX_TIMEOUT);
!fixed_pkt_queue_is_empty(hci_host_env.command_queue)) {
hci_downstream_data_post(OSI_THREAD_MAX_TIMEOUT);
}
if (wait_entry) {
// If it has a callback, it's responsible for freeing the packet
if (event_code == HCI_COMMAND_STATUS_EVT ||
(!wait_entry->complete_callback && !wait_entry->complete_future)) {
(!metadata->command_complete_cb && !metadata->complete_future)) {
osi_free(packet);
}
// If it has a callback, it's responsible for freeing the command
if (event_code == HCI_COMMAND_COMPLETE_EVT || !wait_entry->status_callback) {
osi_free(wait_entry->command);
if (event_code == HCI_COMMAND_COMPLETE_EVT || !metadata->command_status_cb) {
hci_cmd_free_cb free_func = metadata->command_free_cb ? metadata->command_free_cb : (hci_cmd_free_cb) osi_free_func;
free_func(wait_entry);
}
osi_free(wait_entry);
} else {
osi_free(packet);
}
@@ -513,6 +522,17 @@ static void dispatch_reassembled(BT_HDR *packet)
}
}
static void dispatch_adv_report(pkt_linked_item_t *linked_pkt)
{
// Events should already have been dispatched before this point
//Tell Up-layer received packet.
if (btu_task_post(SIG_BTU_HCI_ADV_RPT_MSG, linked_pkt, OSI_THREAD_MAX_TIMEOUT) == false) {
osi_free(linked_pkt);
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_try_release(1);
#endif
}
}
// Misc internal functions
// TODO(zachoverflow): we seem to do this a couple places, like the HCI inject module. #centralize
@@ -531,7 +551,7 @@ static serial_data_type_t event_to_data_type(uint16_t event)
return 0;
}
static waiting_command_t *get_waiting_command(command_opcode_t opcode)
static pkt_linked_item_t *get_waiting_command(command_opcode_t opcode)
{
command_waiting_response_t *cmd_wait_q = &hci_host_env.cmd_waiting_q;
osi_mutex_lock(&cmd_wait_q->commands_pending_response_lock, OSI_MUTEX_MAX_TIMEOUT);
@@ -539,15 +559,15 @@ static waiting_command_t *get_waiting_command(command_opcode_t opcode)
for (const list_node_t *node = list_begin(cmd_wait_q->commands_pending_response);
node != list_end(cmd_wait_q->commands_pending_response);
node = list_next(node)) {
waiting_command_t *wait_entry = list_node(node);
if (!wait_entry || wait_entry->opcode != opcode) {
continue;
pkt_linked_item_t *wait_entry = list_node(node);
if (wait_entry) {
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)(wait_entry->data);
if (metadata->opcode == opcode) {
list_remove(cmd_wait_q->commands_pending_response, wait_entry);
osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock);
return wait_entry;
}
}
list_remove(cmd_wait_q->commands_pending_response, wait_entry);
osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock);
return wait_entry;
}
osi_mutex_unlock(&cmd_wait_q->commands_pending_response_lock);
@@ -565,7 +585,8 @@ static void init_layer_interface(void)
}
static const hci_hal_callbacks_t hal_callbacks = {
hal_says_packet_ready
hal_says_packet_ready,
hal_says_adv_rpt_ready,
};
static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = {

View File

@@ -27,7 +27,6 @@
#include "hci/hci_packet_factory.h"
static BT_HDR *make_packet(size_t data_size);
static BT_HDR *make_command_no_params(uint16_t opcode);
static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **stream_out);
@@ -234,7 +233,9 @@ static BT_HDR *make_command_no_params(uint16_t opcode)
static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **stream_out)
{
BT_HDR *packet = make_packet(HCI_COMMAND_PREAMBLE_SIZE + parameter_size);
BT_HDR *packet = HCI_GET_CMD_BUF(parameter_size);
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(packet);
metadata->opcode = opcode;
uint8_t *stream = packet->data;
UINT16_TO_STREAM(stream, opcode);
@@ -247,17 +248,6 @@ static BT_HDR *make_command(uint16_t opcode, size_t parameter_size, uint8_t **st
return packet;
}
static BT_HDR *make_packet(size_t data_size)
{
BT_HDR *ret = (BT_HDR *)osi_calloc(sizeof(BT_HDR) + data_size);
assert(ret);
ret->event = 0;
ret->offset = 0;
ret->layer_specific = 0;
ret->len = data_size;
return ret;
}
static const hci_packet_factory_t interface = {
make_reset,
make_read_buffer_size,

View File

@@ -21,7 +21,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "osi/pkt_queue.h"
#include "stack/bt_types.h"
#if SOC_ESP_NIMBLE_CONTROLLER
#include "os/os_mbuf.h"
@@ -34,12 +34,14 @@ typedef enum {
} serial_data_type_t;
typedef void (*packet_ready_cb)(BT_HDR *packet);
typedef void (*adv_rpt_ready_cb)(pkt_linked_item_t *linked_pkt);
typedef struct {
// Called when the HAL detects inbound data.
// Data |type| may be ACL, SCO, or EVENT.
// Executes in the context of the thread supplied to |init|.
packet_ready_cb packet_ready;
adv_rpt_ready_cb adv_rpt_ready;
/*
// Called when the HAL detects inbound astronauts named Dave.

View File

@@ -19,11 +19,13 @@
#ifndef _HCI_LAYER_H_
#define _HCI_LAYER_H_
#include "common/bt_target.h"
#include "stack/bt_types.h"
#include "osi/allocator.h"
#include "osi/osi.h"
#include "osi/future.h"
#include "osi/thread.h"
#include "osi/pkt_queue.h"
///// LEGACY DEFINITIONS /////
@@ -46,6 +48,9 @@
/* Local Bluetooth Controller ID for BR/EDR */
#define LOCAL_BR_EDR_CONTROLLER_ID 0
#define HCI_CMD_MSG_F_VND_FUTURE (0x01)
#define HCI_CMD_MSG_F_VND_QUEUED (0x02)
#define HCI_CMD_MSG_F_VND_SENT (0x04)
///// END LEGACY DEFINITIONS /////
typedef struct hci_hal_t hci_hal_t;
@@ -97,6 +102,12 @@ const hci_t *hci_layer_get_interface(void);
int hci_start_up(void);
void hci_shut_down(void);
bool hci_host_task_post(uint32_t timeout);
bool hci_downstream_data_post(uint32_t timeout);
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
int hci_adv_credits_prep_to_release(uint16_t num);
int hci_adv_credits_try_release(uint16_t num);
int hci_adv_credits_force_release(uint16_t num);
#endif
#endif /* _HCI_LAYER_H_ */

View File

@@ -34,7 +34,7 @@
#include "device/controller.h"
#include "stack/hcimsgs.h"
#include "stack/gap_api.h"
#include "hci/hci_layer.h"
#if BLE_INCLUDED == TRUE
#include "l2c_int.h"
@@ -57,6 +57,8 @@
#define MIN_ADV_LENGTH 2
#define BTM_VSC_CHIP_CAPABILITY_RSP_LEN_L_RELEASE 9
#define BTM_BLE_GAP_ADV_RPT_BATCH_SIZE (10)
#if BTM_DYNAMIC_MEMORY == FALSE
static tBTM_BLE_VSC_CB cmn_ble_gap_vsc_cb;
#else
@@ -82,6 +84,7 @@ static UINT8 btm_set_conn_mode_adv_init_addr(tBTM_BLE_INQ_CB *p_cb,
tBLE_ADDR_TYPE *p_own_addr_type);
static void btm_ble_stop_observe(void);
static void btm_ble_stop_discover(void);
static void btm_adv_pkt_handler(void *arg);
uint32_t BTM_BleUpdateOwnType(uint8_t *own_bda_type, tBTM_START_ADV_CMPL_CBACK *cb);
#define BTM_BLE_INQ_RESULT 0x01
@@ -3455,6 +3458,49 @@ void btm_send_sel_conn_callback(BD_ADDR remote_bda, UINT8 evt_type, UINT8 *p_dat
}
}
static void btm_adv_pkt_handler(void *arg)
{
UINT8 hci_evt_code, hci_evt_len;
UINT8 ble_sub_code;
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
size_t pkts_to_process = pkt_queue_length(p_cb->adv_rpt_queue);
if (pkts_to_process > BTM_BLE_GAP_ADV_RPT_BATCH_SIZE) {
pkts_to_process = BTM_BLE_GAP_ADV_RPT_BATCH_SIZE;
}
for (size_t i = 0; i < pkts_to_process; i++) {
pkt_linked_item_t *linked_pkt = pkt_queue_dequeue(p_cb->adv_rpt_queue);
assert(linked_pkt != NULL);
BT_HDR *packet = (BT_HDR *)linked_pkt->data;
uint8_t *p = packet->data + packet->offset;
STREAM_TO_UINT8 (hci_evt_code, p);
STREAM_TO_UINT8 (hci_evt_len, p);
STREAM_TO_UINT8 (ble_sub_code, p);
if (ble_sub_code == HCI_BLE_ADV_PKT_RPT_EVT) {
btm_ble_process_adv_pkt(p);
} else if (ble_sub_code == HCI_BLE_ADV_DISCARD_REPORT_EVT) {
btm_ble_process_adv_discard_evt(p);
} else if (ble_sub_code == HCI_BLE_DIRECT_ADV_EVT) {
btm_ble_process_direct_adv_pkt(p);
} else {
assert (0);
}
osi_free(linked_pkt);
#if (BLE_ADV_REPORT_FLOW_CONTROL == TRUE)
hci_adv_credits_try_release(1);
#endif
}
if (pkt_queue_length(p_cb->adv_rpt_queue) != 0) {
btu_task_post(SIG_BTU_HCI_ADV_RPT_MSG, NULL, OSI_THREAD_MAX_TIMEOUT);
}
UNUSED(hci_evt_code);
UNUSED(hci_evt_len);
}
/*******************************************************************************
**
** Function btm_ble_process_adv_pkt
@@ -3750,6 +3796,12 @@ void btm_ble_process_adv_discard_evt(UINT8 *p)
}
#endif
}
void btm_ble_process_direct_adv_pkt(UINT8 *p)
{
// TODO
}
/*******************************************************************************
**
** Function btm_ble_start_scan
@@ -4414,6 +4466,13 @@ void btm_ble_init (void)
p_cb->inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT;
p_cb->adv_rpt_queue = pkt_queue_create();
assert(p_cb->adv_rpt_queue != NULL);
p_cb->adv_rpt_ready = osi_event_create(btm_adv_pkt_handler, NULL);
assert(p_cb->adv_rpt_ready != NULL);
osi_event_bind(p_cb->adv_rpt_ready, btu_get_current_thread(), 0);
#if BLE_VND_INCLUDED == FALSE
btm_ble_adv_filter_init();
#endif
@@ -4436,6 +4495,12 @@ void btm_ble_free (void)
fixed_queue_free(p_cb->conn_pending_q, osi_free_func);
pkt_queue_destroy(p_cb->adv_rpt_queue, NULL);
p_cb->adv_rpt_queue = NULL;
osi_event_delete(p_cb->adv_rpt_ready);
p_cb->adv_rpt_ready = NULL;
#if BTM_DYNAMIC_MEMORY == TRUE
osi_free(cmn_ble_gap_vsc_cb_ptr);
cmn_ble_gap_vsc_cb_ptr = NULL;
@@ -4530,4 +4595,22 @@ BOOLEAN BTM_Ble_Authorization(BD_ADDR bd_addr, BOOLEAN authorize)
return FALSE;
}
bool btm_ble_adv_pkt_ready(void)
{
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
osi_thread_post_event(p_cb->adv_rpt_ready, OSI_THREAD_MAX_TIMEOUT);
return true;
}
bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt)
{
if (pkt == NULL) {
return false;
}
tBTM_BLE_CB *p_cb = &btm_cb.ble_ctr_cb;
pkt_queue_enqueue(p_cb->adv_rpt_queue, pkt);
return true;
}
#endif /* BLE_INCLUDED */

View File

@@ -662,14 +662,13 @@ tBTM_DEV_STATUS_CB *BTM_RegisterForDeviceStatusNotif (tBTM_DEV_STATUS_CB *p_cb)
tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len,
UINT8 *p_param_buf, tBTM_VSC_CMPL_CB *p_cb)
{
void *p_buf;
BT_HDR *p_buf;
BTM_TRACE_EVENT ("BTM: BTM_VendorSpecificCommand: Opcode: 0x%04X, ParamLen: %i.",
opcode, param_len);
/* Allocate a buffer to hold HCI command plus the callback function */
if ((p_buf = osi_malloc((UINT16)(sizeof(BT_HDR) + sizeof (tBTM_CMPL_CB *) +
param_len + HCIC_PREAMBLE_SIZE))) != NULL) {
if ((p_buf = HCI_GET_CMD_BUF(param_len)) != NULL) {
/* Send the HCI command (opcode will be OR'd with HCI_GRP_VENDOR_SPECIFIC) */
btsnd_hcic_vendor_spec_cmd (p_buf, opcode, param_len, p_param_buf, (void *)p_cb);

View File

@@ -2304,7 +2304,7 @@ void btm_process_remote_name (BD_ADDR bda, BD_NAME bdn, UINT16 evt_len, UINT8 hc
else {
rem_name.status = BTM_BAD_VALUE_RET;
rem_name.length = 0;
rem_name.remote_bd_name[0] = 0;
rem_name.remote_bd_name[0] = '\0';
}
memcpy(rem_name.bd_addr, p_inq->remname_bda, BD_ADDR_LEN);
/* Reset the remote BAD to zero and call callback if possible */
@@ -2395,6 +2395,7 @@ tBTM_STATUS BTM_WriteEIR( BT_HDR *p_buff, BOOLEAN fec_required)
if (controller_get_interface()->supports_extended_inquiry_response()) {
BTM_TRACE_API("Write Extended Inquiry Response to controller\n");
btsnd_hcic_write_ext_inquiry_response (p_buff, fec_required);
osi_free(p_buff);
return BTM_SUCCESS;
} else {
osi_free(p_buff);

View File

@@ -592,6 +592,7 @@ static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, const char
p_srec->orig_mx_chan_id = mx_chan_id;
#if BTM_SEC_SERVICE_NAME_LEN > 0
BCM_STRNCPY_S ((char *)p_srec->orig_service_name, p_name, BTM_SEC_SERVICE_NAME_LEN);
p_srec->orig_service_name[BTM_SEC_SERVICE_NAME_LEN] = '\0';
#endif
/* clear out the old setting, just in case it exists */
#if (L2CAP_UCD_INCLUDED == TRUE)
@@ -637,6 +638,7 @@ static BOOLEAN btm_sec_set_security_level (CONNECTION_TYPE conn_type, const char
p_srec->term_mx_chan_id = mx_chan_id;
#if BTM_SEC_SERVICE_NAME_LEN > 0
BCM_STRNCPY_S ((char *)p_srec->term_service_name, p_name, BTM_SEC_SERVICE_NAME_LEN);
p_srec->term_service_name[BTM_SEC_SERVICE_NAME_LEN] = '\0';
#endif
/* clear out the old setting, just in case it exists */
#if (L2CAP_UCD_INCLUDED == TRUE)
@@ -3031,11 +3033,12 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
old_sec_state = p_dev_rec->sec_state;
if (status == HCI_SUCCESS) {
BCM_STRNCPY_S ((char *)p_dev_rec->sec_bd_name, (char *)p_bd_name, BTM_MAX_REM_BD_NAME_LEN);
p_dev_rec->sec_bd_name[BTM_MAX_REM_BD_NAME_LEN] = '\0';
p_dev_rec->sec_flags |= BTM_SEC_NAME_KNOWN;
BTM_TRACE_EVENT ("setting BTM_SEC_NAME_KNOWN sec_flags:0x%x\n", p_dev_rec->sec_flags);
} else {
/* Notify all clients waiting for name to be resolved even if it failed so clients can continue */
p_dev_rec->sec_bd_name[0] = 0;
p_dev_rec->sec_bd_name[0] = '\0';
}
if (p_dev_rec->sec_state == BTM_SEC_STATE_GETTING_NAME) {
@@ -3755,7 +3758,7 @@ void btm_rem_oob_req (UINT8 *p)
memcpy (evt_data.bd_addr, p_dev_rec->bd_addr, BD_ADDR_LEN);
memcpy (evt_data.dev_class, p_dev_rec->dev_class, DEV_CLASS_LEN);
BCM_STRNCPY_S((char *)evt_data.bd_name, (char *)p_dev_rec->sec_bd_name, BTM_MAX_REM_BD_NAME_LEN);
evt_data.bd_name[BTM_MAX_REM_BD_NAME_LEN] = 0;
evt_data.bd_name[BTM_MAX_REM_BD_NAME_LEN] = '\0';
btm_sec_change_pairing_state(BTM_PAIR_STATE_WAIT_LOCAL_OOB_RSP);
if ((*btm_cb.api.p_sp_callback) (BTM_SP_RMT_OOB_EVT, (tBTM_SP_EVT_DATA *)&evt_data) == BTM_NOT_AUTHORIZED) {
@@ -4903,7 +4906,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
/* We need to notify the UI that no longer need the PIN */
if (btm_cb.api.p_auth_complete_callback) {
if (p_dev_rec == NULL) {
name[0] = 0;
name[0] = '\0';
(*btm_cb.api.p_auth_complete_callback) (p_cb->pairing_bda,
NULL,
name, HCI_ERR_CONNECTION_TOUT);
@@ -4963,7 +4966,7 @@ static void btm_sec_pairing_timeout (TIMER_LIST_ENT *p_tle)
btm_sec_change_pairing_state (BTM_PAIR_STATE_IDLE);
if (btm_cb.api.p_auth_complete_callback) {
if (p_dev_rec == NULL) {
name[0] = 0;
name[0] = '\0';
(*btm_cb.api.p_auth_complete_callback) (p_cb->pairing_bda,
NULL,
name, HCI_ERR_CONNECTION_TOUT);

View File

@@ -28,6 +28,8 @@
#include "common/bt_target.h"
#include "osi/fixed_queue.h"
#include "osi/pkt_queue.h"
#include "osi/thread.h"
#include "stack/hcidefs.h"
#include "stack/btm_ble_api.h"
#include "btm_int.h"
@@ -341,6 +343,9 @@ typedef struct {
tBTM_CMPL_CB *p_scan_cmpl_cb;
TIMER_LIST_ENT scan_timer_ent;
struct pkt_queue *adv_rpt_queue;
struct osi_event *adv_rpt_ready;
/* background connection procedure cb value */
tBTM_BLE_CONN_TYPE bg_conn_type;
UINT32 scan_int;
@@ -384,6 +389,9 @@ extern "C" {
void btm_ble_timeout(TIMER_LIST_ENT *p_tle);
void btm_ble_process_adv_pkt (UINT8 *p);
void btm_ble_process_adv_discard_evt(UINT8 *p);
void btm_ble_process_direct_adv_pkt (UINT8 *p);
bool btm_ble_adv_pkt_ready(void);
bool btm_ble_adv_pkt_post(pkt_linked_item_t *pkt);
void btm_ble_proc_scan_rsp_rpt (UINT8 *p);
tBTM_STATUS btm_ble_read_remote_name(BD_ADDR remote_bda, tBTM_INQ_INFO *p_cur, tBTM_CMPL_CB *p_cb);
BOOLEAN btm_ble_cancel_remote_name(BD_ADDR remote_bda);

View File

@@ -43,6 +43,7 @@
#include "common/bt_trace.h"
#include "osi/thread.h"
#include "osi/pkt_queue.h"
//#include "osi/mutex.h"
// TODO(zachoverflow): remove this horrible hack
#include "stack/btu.h"
@@ -124,8 +125,6 @@ static void btu_hcif_ssr_evt_dump (UINT8 *p, UINT16 evt_len);
#if BLE_INCLUDED == TRUE
static void btu_ble_ll_conn_complete_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_process_adv_pkt (UINT8 *p);
static void btu_ble_process_adv_dis(UINT8 *p);
static void btu_ble_read_remote_feat_evt (UINT8 *p);
static void btu_ble_ll_conn_param_upd_evt (UINT8 *p, UINT16 evt_len);
static void btu_ble_ll_get_conn_param_format_err_from_contoller (UINT8 status, UINT16 handle);
@@ -360,10 +359,10 @@ void btu_hcif_process_event (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_msg)
switch (ble_sub_code) {
case HCI_BLE_ADV_PKT_RPT_EVT: /* result of inquiry */
btu_ble_process_adv_pkt(p);
break;
case HCI_BLE_ADV_DISCARD_REPORT_EVT:
btu_ble_process_adv_dis(p);
case HCI_BLE_DIRECT_ADV_EVT:
// These three events are directed to another specialized processing path
HCI_TRACE_ERROR("Unexpected HCI BLE event = 0x%02x", ble_sub_code);
break;
case HCI_BLE_CONN_COMPLETE_EVT:
btu_ble_ll_conn_complete_evt(p, hci_evt_len);
@@ -453,15 +452,21 @@ void btu_hcif_send_cmd (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_buf)
STREAM_TO_UINT16(opcode, stream);
// Eww...horrible hackery here
/* If command was a VSC, then extract command_complete callback */
if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC
assert (p_buf->layer_specific == HCI_CMD_BUF_TYPE_METADATA);
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(p_buf);
metadata->command_complete_cb = btu_hcif_command_complete_evt;
metadata->command_status_cb = btu_hcif_command_status_evt;
metadata->opcode = opcode;
vsc_callback = metadata->context;
/* If command is not a VSC, then the context field should be empty */
if ((opcode & HCI_GRP_VENDOR_SPECIFIC) != HCI_GRP_VENDOR_SPECIFIC
#if BLE_INCLUDED == TRUE
|| (opcode == HCI_BLE_RAND)
|| (opcode == HCI_BLE_ENCRYPT)
&& (opcode != HCI_BLE_RAND)
&& (opcode != HCI_BLE_ENCRYPT)
#endif
) {
vsc_callback = *((void **)(p_buf + 1));
) {
assert (vsc_callback == NULL);
}
hci_layer_get_interface()->transmit_command(
@@ -474,6 +479,7 @@ void btu_hcif_send_cmd (UNUSED_ATTR UINT8 controller_id, BT_HDR *p_buf)
btu_check_bt_sleep ();
#endif
}
#if (BLE_50_FEATURE_SUPPORT == TRUE)
UINT8 btu_hcif_send_cmd_sync (UINT8 controller_id, BT_HDR *p_buf)
{
@@ -494,15 +500,22 @@ UINT8 btu_hcif_send_cmd_sync (UINT8 controller_id, BT_HDR *p_buf)
sync_info->opcode = opcode;
// Eww...horrible hackery here
/* If command was a VSC, then extract command_complete callback */
if ((opcode & HCI_GRP_VENDOR_SPECIFIC) == HCI_GRP_VENDOR_SPECIFIC
assert (p_buf->layer_specific == HCI_CMD_BUF_TYPE_METADATA);
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(p_buf);
metadata->command_complete_cb = btu_hcif_command_complete_evt;
metadata->command_status_cb = btu_hcif_command_status_evt;
metadata->command_free_cb = NULL;
metadata->opcode = opcode;
vsc_callback = metadata->context;
/* If command is not a VSC, then the context field should be empty */
if ((opcode & HCI_GRP_VENDOR_SPECIFIC) != HCI_GRP_VENDOR_SPECIFIC
#if BLE_INCLUDED == TRUE
|| (opcode == HCI_BLE_RAND)
|| (opcode == HCI_BLE_ENCRYPT)
&& (opcode != HCI_BLE_RAND)
&& (opcode != HCI_BLE_ENCRYPT)
#endif
) {
vsc_callback = *((void **)(p_buf + 1));
) {
assert (vsc_callback == NULL);
}
hci_layer_get_interface()->transmit_command(
@@ -1436,7 +1449,11 @@ static void btu_hcif_command_status_evt_on_task(BT_HDR *event)
stream,
hack->context);
osi_free(hack->command);
// check the HCI command integrity: opcode
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(hack->command);
assert(metadata->opcode == opcode);
HCI_FREE_CMD_BUF(hack->command);
osi_free(event);
}
@@ -2015,18 +2032,6 @@ static void btu_hcif_encryption_key_refresh_cmpl_evt (UINT8 *p)
}
#endif ///SMP_INCLUDED == TRUE
static void btu_ble_process_adv_pkt (UINT8 *p)
{
HCI_TRACE_DEBUG("btu_ble_process_adv_pkt\n");
btm_ble_process_adv_pkt(p);
}
static void btu_ble_process_adv_dis(UINT8 *p)
{
btm_ble_process_adv_discard_evt(p);
}
static void btu_ble_ll_conn_complete_evt ( UINT8 *p, UINT16 evt_len)
{
btm_ble_conn_complete(p, evt_len, FALSE);

View File

@@ -48,6 +48,8 @@
#define BTU_TASK_STACK_SIZE (BT_BTU_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE)
#define BTU_TASK_PRIO (BT_TASK_MAX_PRIORITIES - 5)
#define BTU_TASK_NAME "BTU_TASK"
#define BTU_TASK_WORKQUEUE_NUM (2)
#define BTU_TASK_WORKQUEUE0_LEN (0)
hash_map_t *btu_general_alarm_hash_map;
osi_mutex_t btu_general_alarm_lock;
@@ -181,7 +183,9 @@ void BTU_StartUp(void)
osi_mutex_new(&btu_l2cap_alarm_lock);
btu_thread = osi_thread_create(BTU_TASK_NAME, BTU_TASK_STACK_SIZE, BTU_TASK_PRIO, BTU_TASK_PINNED_TO_CORE, 1);
const size_t workqueue_len[] = {BTU_TASK_WORKQUEUE0_LEN};
btu_thread = osi_thread_create(BTU_TASK_NAME, BTU_TASK_STACK_SIZE, BTU_TASK_PRIO, BTU_TASK_PINNED_TO_CORE,
BTU_TASK_WORKQUEUE_NUM, workqueue_len);
if (btu_thread == NULL) {
goto error_exit;
}
@@ -265,3 +269,8 @@ int get_btu_work_queue_size(void)
{
return osi_thread_queue_wait_size(btu_thread, 0);
}
osi_thread_t *btu_get_current_thread(void)
{
return btu_thread;
}

View File

@@ -227,6 +227,18 @@ bool btu_task_post(uint32_t sig, void *param, uint32_t timeout)
case SIG_BTU_HCI_MSG:
status = osi_thread_post(btu_thread, btu_hci_msg_process, param, 0, timeout);
break;
case SIG_BTU_HCI_ADV_RPT_MSG:
#if BLE_INCLUDED == TRUE
if (param != NULL) {
btm_ble_adv_pkt_post(param);
}
btm_ble_adv_pkt_ready();
status = true;
#else
osi_free(param);
status = false;
#endif
break;
#if (defined(BTA_INCLUDED) && BTA_INCLUDED == TRUE)
case SIG_BTU_BTA_MSG:
status = osi_thread_post(btu_thread, bta_sys_event, param, 0, timeout);

View File

@@ -33,7 +33,6 @@
#include <stddef.h>
#include <string.h>
#define HCI_GET_CMD_BUF(paramlen) ((BT_HDR *)osi_malloc(HCIC_PREAMBLE_SIZE + sizeof(BT_HDR) + paramlen))
#if (BLE_50_FEATURE_SUPPORT == TRUE)
static BlE_SYNC ble_sync_info;
@@ -557,19 +556,17 @@ BOOLEAN btsnd_hcic_ble_encrypt (UINT8 *key, UINT8 key_len,
BT_HDR *p;
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF(sizeof (void *) +
HCIC_PARAM_SIZE_BLE_ENCRYPT)) == NULL) {
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_ENCRYPT)) == NULL) {
return (FALSE);
}
pp = (UINT8 *)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENCRYPT;
p->offset = sizeof(void *);
*((void **)pp) = p_cmd_cplt_cback; /* Store command complete callback in buffer */
pp += sizeof(void *); /* Skip over callback pointer */
p->offset = 0;
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(p);
metadata->context = p_cmd_cplt_cback;
UINT16_TO_STREAM (pp, HCI_BLE_ENCRYPT);
UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_ENCRYPT);
@@ -596,18 +593,17 @@ BOOLEAN btsnd_hcic_ble_rand (void *p_cmd_cplt_cback)
BT_HDR *p;
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF(sizeof (void *) +
HCIC_PARAM_SIZE_BLE_RAND)) == NULL) {
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_RAND)) == NULL) {
return (FALSE);
}
pp = (UINT8 *)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RAND;
p->offset = sizeof(void *);
p->offset = 0;
*((void **)pp) = p_cmd_cplt_cback; /* Store command complete callback in buffer */
pp += sizeof(void *); /* Skip over callback pointer */
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(p);
metadata->context = p_cmd_cplt_cback;
UINT16_TO_STREAM (pp, HCI_BLE_RAND);
UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_RAND);
@@ -1032,15 +1028,26 @@ BOOLEAN btsnd_hcic_ble_set_data_length(UINT16 conn_handle, UINT16 tx_octets, UIN
return TRUE;
}
BOOLEAN btsnd_hcic_ble_update_adv_report_flow_control (UINT16 num)
BOOLEAN btsnd_hcic_ble_update_adv_report_flow_control (UINT16 num, BT_HDR *static_buf)
{
BT_HDR *p;
UINT8 *pp;
if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL)) == NULL) {
return (FALSE);
if (static_buf != NULL) {
p = static_buf;
} else {
if ((p = HCI_GET_CMD_BUF (HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL)) == NULL) {
return (FALSE);
}
}
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(p);
metadata->flags_src = HCI_CMD_MSG_F_SRC_NOACK;
if (static_buf == p) {
assert(metadata->command_free_cb != NULL);
}
p->layer_specific = HCI_CMD_BUF_TYPE_METADATA;
pp = (UINT8 *)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_UPDATE_ADV_FLOW_CONTROL;

View File

@@ -35,8 +35,6 @@
#include "btm_int.h" /* Included for UIPC_* macro definitions */
#define HCI_GET_CMD_BUF(paramlen) ((BT_HDR *)osi_malloc(HCIC_PREAMBLE_SIZE + sizeof(BT_HDR) + paramlen))
BOOLEAN btsnd_hcic_inquiry(const LAP inq_lap, UINT8 duration, UINT8 response_cnt)
{
BT_HDR *p;
@@ -1331,6 +1329,9 @@ BOOLEAN btsnd_hcic_host_num_xmitted_pkts (UINT8 num_handles, UINT16 *handle,
p->len = HCIC_PREAMBLE_SIZE + 1 + (num_handles * 4);
p->offset = 0;
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(p);
metadata->flags_src |= HCI_CMD_MSG_F_SRC_NOACK;
UINT16_TO_STREAM (pp, HCI_HOST_NUM_PACKETS_DONE);
UINT8_TO_STREAM (pp, p->len - HCIC_PREAMBLE_SIZE);
@@ -1431,9 +1432,13 @@ BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat,
#endif /* BTM_SSR_INCLUDED */
/**** Extended Inquiry Response Commands ****/
void btsnd_hcic_write_ext_inquiry_response (void *buffer, UINT8 fec_req)
void btsnd_hcic_write_ext_inquiry_response (BT_HDR *buffer, UINT8 fec_req)
{
BT_HDR *p = (BT_HDR *)buffer;
BT_HDR *p;
if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_EXT_INQ_RESP)) == NULL) {
return;
}
UINT8 *pp = (UINT8 *)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_EXT_INQ_RESP;
@@ -1441,9 +1446,10 @@ void btsnd_hcic_write_ext_inquiry_response (void *buffer, UINT8 fec_req)
UINT16_TO_STREAM (pp, HCI_WRITE_EXT_INQ_RESPONSE);
UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_EXT_INQ_RESP);
UINT8_TO_STREAM (pp, fec_req);
memcpy(pp, buffer->data + 4, p->len - 4);
btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
}
@@ -1862,17 +1868,17 @@ BOOLEAN btsnd_hcic_write_pagescan_type (UINT8 type)
#error "HCI_CMD_POOL_BUF_SIZE must be larger than 268"
#endif
void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode, UINT8 len,
void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode, UINT8 len,
UINT8 *p_data, void *p_cmd_cplt_cback)
{
BT_HDR *p = (BT_HDR *)buffer;
BT_HDR *p = buffer;
UINT8 *pp = (UINT8 *)(p + 1);
p->len = HCIC_PREAMBLE_SIZE + len;
p->offset = sizeof(void *);
p->offset = 0;
*((void **)pp) = p_cmd_cplt_cback; /* Store command complete callback in buffer */
pp += sizeof(void *); /* Skip over callback pointer */
hci_cmd_metadata_t * metadata = HCI_GET_CMD_METAMSG(p);
metadata->context = p_cmd_cplt_cback;
UINT16_TO_STREAM (pp, HCI_GRP_VENDOR_SPECIFIC | opcode);
UINT8_TO_STREAM (pp, len);

View File

@@ -175,6 +175,7 @@ typedef enum {
SIG_BTU_GENERAL_ALARM,
SIG_BTU_ONESHOT_ALARM,
SIG_BTU_L2CAP_ALARM,
SIG_BTU_HCI_ADV_RPT_MSG,
SIG_BTU_NUM,
} SIG_BTU_t;
@@ -297,6 +298,7 @@ bool btu_task_post(uint32_t sig, void *param, uint32_t timeout);
int get_btu_work_queue_size(void);
osi_thread_t *btu_get_current_thread(void);
/*
#ifdef __cplusplus
}

View File

@@ -19,9 +19,66 @@
#ifndef HCIMSGS_H
#define HCIMSGS_H
#include <stddef.h>
#include "common/bt_target.h"
#include "stack/hcidefs.h"
#include "stack/bt_types.h"
#include "osi/pkt_queue.h"
#include "osi/allocator.h"
#define HCI_CMD_BUF_TYPE_METADATA (0xa56e)
#define HCI_CMD_MSG_F_SRC_NOACK (0x01)
typedef void (*hci_cmd_cmpl_cb)(BT_HDR *response, void *context);
typedef void (*hci_cmd_stat_cb)(uint8_t status, BT_HDR *command, void *context);
typedef void (*hci_cmd_free_cb)(pkt_linked_item_t *linked_pkt);
typedef struct {
uint8_t flags_src;
uint8_t flags_vnd; // used for downstream layer
uint16_t opcode;
hci_cmd_cmpl_cb command_complete_cb;
hci_cmd_stat_cb command_status_cb;
void *context;
void *complete_future;
hci_cmd_free_cb command_free_cb;
BT_HDR command;
} hci_cmd_metadata_t;
#define HCI_CMD_METADATA_HDR_SIZE (sizeof(hci_cmd_metadata_t))
#define HCI_CMD_LINKED_BUF_SIZE(paramlen) (BT_PKT_LINKED_HDR_SIZE + HCI_CMD_METADATA_HDR_SIZE + HCIC_PREAMBLE_SIZE + (paramlen))
#define HCI_GET_CMD_METAMSG(cmd_ptr) (hci_cmd_metadata_t *)((void *)(cmd_ptr) - offsetof(hci_cmd_metadata_t, command))
#define HCI_GET_CMD_LINKED_STRUCT(metadata_ptr) (pkt_linked_item_t *)((void *)(metadata_ptr) - offsetof(pkt_linked_item_t, data))
static inline BT_HDR *hci_get_cmd_buf(size_t param_len)
{
pkt_linked_item_t *linked_pkt = osi_calloc(HCI_CMD_LINKED_BUF_SIZE(param_len));
if (linked_pkt == NULL) {
return NULL;
}
hci_cmd_metadata_t *metadata = (hci_cmd_metadata_t *)linked_pkt->data;
BT_HDR *command = &metadata->command;
command->layer_specific = HCI_CMD_BUF_TYPE_METADATA;
command->len = HCIC_PREAMBLE_SIZE + param_len;
command->offset = 0;
return command;
}
static inline void hci_free_cmd_buf(BT_HDR *buf)
{
assert(buf->layer_specific == HCI_CMD_BUF_TYPE_METADATA);
hci_cmd_metadata_t *metadata = HCI_GET_CMD_METAMSG(buf);
pkt_linked_item_t *linked_pkt = HCI_GET_CMD_LINKED_STRUCT(metadata);
osi_free(linked_pkt);
}
#define HCI_GET_CMD_BUF(param_len) hci_get_cmd_buf(param_len)
#define HCI_FREE_CMD_BUF(buf) hci_free_cmd_buf(buf)
void bte_main_hci_send(BT_HDR *p_msg, UINT16 event);
void bte_main_lpm_allow_bt_device_sleep(void);
@@ -378,7 +435,7 @@ BOOLEAN btsnd_hcic_sniff_sub_rate(UINT16 handle, UINT16 max_lat,
#endif /* BTM_SSR_INCLUDED */
/* Extended Inquiry Response */
void btsnd_hcic_write_ext_inquiry_response(void *buffer, UINT8 fec_req);
void btsnd_hcic_write_ext_inquiry_response(BT_HDR *buffer, UINT8 fec_req);
#define HCIC_PARAM_SIZE_EXT_INQ_RESP 241
@@ -641,7 +698,7 @@ BOOLEAN btsnd_hcic_write_inquiry_mode(UINT8 type); /* Write Inquiry
#define HCID_GET_SCO_LEN(p) (*((UINT8 *)((p) + 1) + p->offset + 2))
void btsnd_hcic_vendor_spec_cmd (void *buffer, UINT16 opcode,
void btsnd_hcic_vendor_spec_cmd (BT_HDR *buffer, UINT16 opcode,
UINT8 len, UINT8 *p_data,
void *p_cmd_cplt_cback);
@@ -882,7 +939,7 @@ BOOLEAN btsnd_hcic_read_authenticated_payload_tout(UINT16 handle);
BOOLEAN btsnd_hcic_write_authenticated_payload_tout(UINT16 handle,
UINT16 timeout);
BOOLEAN btsnd_hcic_ble_update_adv_report_flow_control (UINT16 num);
BOOLEAN btsnd_hcic_ble_update_adv_report_flow_control (UINT16 num, BT_HDR *static_buf);
#if (BLE_50_FEATURE_SUPPORT == TRUE)
BOOLEAN btsnd_hcic_ble_read_phy(UINT16 conn_handle);

View File

@@ -118,7 +118,7 @@ esp_err_t esp_ble_tx_power_set(esp_ble_power_type_t power_type, esp_power_level_
esp_power_level_t esp_ble_tx_power_get(esp_ble_power_type_t power_type);
#define CONFIG_VERSION 0x20220105
#define CONFIG_VERSION 0x20220729
#define CONFIG_MAGIC 0x5A5AA5A5
/**
@@ -173,6 +173,7 @@ typedef struct {
uint8_t coex_phy_coded_tx_rx_time_limit;
uint8_t dis_scan_backoff;
uint8_t esp_scan_filter_en;
uint8_t main_xtal_freq;
uint32_t config_magic;
} esp_bt_controller_config_t;
@@ -223,6 +224,7 @@ typedef struct {
.coex_phy_coded_tx_rx_time_limit = DEFAULT_BT_LE_COEX_PHY_CODED_TX_RX_TLIM_EFF, \
.dis_scan_backoff = NIMBLE_DISABLE_SCAN_BACKOFF, \
.esp_scan_filter_en = 0, \
.main_xtal_freq = CONFIG_ESP32C2_XTAL_FREQ, \
.config_magic = CONFIG_MAGIC, \
};

View File

@@ -192,7 +192,11 @@ extern "C" {
#define BLE_LL_CONN_DEF_AUTH_PYLD_TMO_N (3000)
#define RTC_FREQ_N (32000) /* in Hz */
#ifdef CONFIG_ESP32C2_XTAL_FREQ_26
#define RTC_FREQ_N (40000) /* in Hz */
#else
#define RTC_FREQ_N (32000) /* in Hz */
#endif // CONFIG_ESP32C2_XTAL_FREQ_26
#define BLE_LL_TX_PWR_DBM_N (0)

View File

@@ -2,4 +2,5 @@ if(CONFIG_BT_ENABLED OR CMAKE_BUILD_EARLY_EXPANSION)
idf_component_register(SRC_DIRS "."
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES cmock nvs_flash bt esp_ringbuf)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
endif()

View File

@@ -22,3 +22,6 @@ idf_component_register(SRCS "commands.c"
INCLUDE_DIRS "."
REQUIRES vfs
PRIV_REQUIRES driver)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -1,3 +1,4 @@
idf_component_register(SRC_DIRS .
PRIV_INCLUDE_DIRS .
PRIV_REQUIRES cmock test_utils console)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -121,7 +121,9 @@ else()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS ${includes}
PRIV_INCLUDE_DIRS "include/driver"
PRIV_REQUIRES efuse esp_timer esp_adc
PRIV_REQUIRES efuse esp_timer
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
LDFRAGMENTS linker.lf)
endif()
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -19,11 +19,11 @@
#include "freertos/timers.h"
#include "freertos/ringbuf.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/adc_private.h"
#include "esp_private/adc_lock.h"
#include "esp_private/adc_share_hw_ctrl.h"
#include "hal/adc_types.h"
#include "hal/adc_hal.h"
#include "hal/dma_types.h"
#include "hal/adc_hal_common.h"
#include "driver/gpio.h"
#include "driver/adc_types_legacy.h"
@@ -588,3 +588,23 @@ static void check_adc_continuous_driver_conflict(void)
}
ESP_EARLY_LOGW(ADC_TAG, "legacy driver is deprecated, please migrate to `esp_adc/adc_continuous.h`");
}
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
/*---------------------------------------------------------------
ADC Hardware Calibration
---------------------------------------------------------------*/
static __attribute__((constructor)) void adc_hw_calibration(void)
{
//Calculate all ICode
for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
adc_hal_calibration_init(i);
for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
/**
* This may get wrong when attenuations are NOT consecutive on some chips,
* update this when bringing up the calibration on that chip
*/
adc_calc_hw_calibration_code(i, j);
}
}
}
#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED

View File

@@ -20,7 +20,6 @@
#ifdef CONFIG_PM_ENABLE
#include "esp_pm.h"
#endif
#include "esp_private/adc_private.h"
#include "freertos/FreeRTOS.h"
#include "driver/adc_i2s_legacy.h"

View File

@@ -18,13 +18,13 @@
#include "driver/rtc_io.h"
#include "sys/lock.h"
#include "driver/gpio.h"
#include "esp_private/adc_private.h"
#include "esp_private/adc_share_hw_ctrl.h"
#include "adc1_private.h"
#include "hal/adc_types.h"
#include "hal/adc_hal.h"
#include "hal/adc_hal_common.h"
#include "hal/adc_hal_conf.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/adc_lock.h"
#include "driver/adc_types_legacy.h"
#if SOC_DAC_SUPPORTED
@@ -904,8 +904,6 @@ static esp_err_t adc_hal_convert(adc_unit_t adc_n, int channel, int *out_raw)
return ESP_OK;
}
#if !CONFIG_IDF_TARGET_ESP32
//wrapper should be removed after I2S deprecation
/**
* @brief This function will be called during start up, to check that adc_oneshot driver is not running along with the legacy adc oneshot driver
*/
@@ -921,4 +919,23 @@ static void check_adc_oneshot_driver_conflict(void)
}
ESP_EARLY_LOGW(ADC_TAG, "legacy driver is deprecated, please migrate to `esp_adc/adc_oneshot.h`");
}
#endif
#if SOC_ADC_CALIBRATION_V1_SUPPORTED
/*---------------------------------------------------------------
ADC Hardware Calibration
---------------------------------------------------------------*/
static __attribute__((constructor)) void adc_hw_calibration(void)
{
//Calculate all ICode
for (int i = 0; i < SOC_ADC_PERIPH_NUM; i++) {
adc_hal_calibration_init(i);
for (int j = 0; j < SOC_ADC_ATTEN_NUM; j++) {
/**
* This may get wrong when attenuations are NOT consecutive on some chips,
* update this when bringing up the calibration on that chip
*/
adc_calc_hw_calibration_code(i, j);
}
}
}
#endif //#if SOC_ADC_CALIBRATION_V1_SUPPORTED

View File

@@ -27,7 +27,7 @@
#include "hal/i2s_hal.h"
#if SOC_I2S_SUPPORTS_DAC
#include "driver/dac.h"
#include "esp_private/adc_private.h"
#include "esp_private/adc_share_hw_ctrl.h"
#include "adc1_private.h"
#include "driver/adc_i2s_legacy.h"
#include "driver/adc_types_legacy.h"
@@ -804,6 +804,8 @@ static esp_err_t i2s_calculate_clock(i2s_port_t i2s_num, i2s_hal_clock_info_t *c
/* Calculate clock for common mode */
ESP_RETURN_ON_ERROR(i2s_calculate_common_clock(i2s_num, clk_info), TAG, "Common clock calculate failed");
ESP_LOGD(TAG, "[sclk] %d [mclk] %d [mclk_div] %d [bclk] %d [bclk_div] %d",
clk_info->sclk, clk_info->mclk, clk_info->mclk_div, clk_info->bclk, clk_info->bclk_div);
return ESP_OK;
}

View File

@@ -177,9 +177,8 @@ esp_err_t mcpwm_new_soft_fault(const mcpwm_soft_fault_config_t *config, mcpwm_fa
return ESP_OK;
err:
if (soft_fault) {
free(soft_fault);
}
// soft_fault must be NULL in the error handling path, and it's a determined behaviour to free a NULL pointer in esp-idf
free(soft_fault);
return ret;
}

View File

@@ -252,9 +252,8 @@ esp_err_t mcpwm_new_soft_sync_src(const mcpwm_soft_sync_config_t *config, mcpwm_
return ESP_OK;
err:
if (soft_sync) {
free(soft_sync);
}
// soft_sync must be NULL in the error handling path, and it's a determined behaviour to free a NULL pointer in esp-idf
free(soft_sync);
return ret;
}

View File

@@ -46,6 +46,7 @@ static esp_err_t rmt_bytes_encoder_reset(rmt_encoder_t *encoder)
return ESP_OK;
}
__attribute__((always_inline))
static inline uint8_t _bitwise_reverse(uint8_t n)
{
n = ((n & 0xf0) >> 4) | ((n & 0x0f) << 4);

View File

@@ -268,8 +268,8 @@ esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_
rmt_ll_tx_set_limit(hal->regs, channel_id, tx_channel->ping_pong_symbols);
// disable carrier modulation by default, can reenable by `rmt_apply_carrier()`
rmt_ll_tx_enable_carrier_modulation(hal->regs, channel_id, false);
// idle level is determind by eof encoder, not set to a fixed value
rmt_ll_tx_fix_idle_level(hal->regs, channel_id, 0, false);
// idle level is determined by register value
rmt_ll_tx_fix_idle_level(hal->regs, channel_id, 0, true);
// always enable tx wrap, both DMA mode and ping-pong mode rely this feature
rmt_ll_tx_enable_wrap(hal->regs, channel_id, true);
@@ -662,6 +662,7 @@ static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_tr
#endif
// turn on the TX machine
portENTER_CRITICAL_ISR(&channel->spinlock);
rmt_ll_tx_fix_idle_level(hal->regs, channel_id, t->flags.eot_level, true);
rmt_ll_tx_start(hal->regs, channel_id);
portEXIT_CRITICAL_ISR(&channel->spinlock);
}
@@ -720,9 +721,6 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel)
int channel_id = channel->channel_id;
portENTER_CRITICAL(&channel->spinlock);
// when this function called, the transaction might be middle-way, the output level when we stop the transmitter is nondeterministic,
// so we fix the idle level temporarily
rmt_ll_tx_fix_idle_level(hal->regs, channel->channel_id, tx_chan->cur_trans ? tx_chan->cur_trans->flags.eot_level : 0, true);
rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false);
#if SOC_RMT_SUPPORT_TX_ASYNC_STOP
rmt_ll_tx_stop(hal->regs, channel->channel_id);
@@ -740,11 +738,6 @@ static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel)
rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id));
portEXIT_CRITICAL(&group->spinlock);
portENTER_CRITICAL(&channel->spinlock);
// restore the idle level selection, to be determind by eof symbol
rmt_ll_tx_fix_idle_level(hal->regs, channel_id, 0, false);
portEXIT_CRITICAL(&channel->spinlock);
#if SOC_RMT_SUPPORT_DMA
if (channel->dma_chan) {
gdma_stop(channel->dma_chan);

View File

@@ -2,3 +2,4 @@ idf_component_register(SRC_DIRS . param_test touch_sensor_test dac_dma_test
PRIV_INCLUDE_DIRS include param_test/include touch_sensor_test/include
PRIV_REQUIRES cmock test_utils driver nvs_flash esp_serial_slave_link
esp_timer esp_adc esp_event esp_wifi)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -5,7 +5,6 @@
*/
/* This file is from test_uart.c, but mainly about RS485 */
#include <string.h>
#include <sys/param.h>
#include "unity.h"
@@ -14,22 +13,17 @@
#include "esp_log.h"
#include "esp_random.h" // for uint32_t esp_random()
#define UART_TAG "Uart"
#define UART_NUM1 (UART_NUM_1)
#define BUF_SIZE (100)
#define UART1_RX_PIN (22)
#define UART1_TX_PIN (23)
#define UART_BAUD_11520 (11520)
#define UART_BAUD_115200 (115200)
#define TOLERANCE (0.02) //baud rate error tolerance 2%.
#define UART_TOLERANCE_CHECK(val, uper_limit, lower_limit) ( (val) <= (uper_limit) && (val) >= (lower_limit) )
#define UART_NUM1 (UART_NUM_1)
#define UART_BAUD_RATE (115200 * 10)
#define BUF_SIZE (512)
#define UART1_RX_PIN (22)
#define UART1_TX_PIN (23)
// RTS for RS485 Half-Duplex Mode manages DE/~RE
#define UART1_RTS_PIN (18)
#define UART1_RTS_PIN (18)
// Number of packets to be send during test
#define PACKETS_NUMBER (10)
#define PACKETS_NUMBER (40)
// Wait timeout for uart driver
#define PACKET_READ_TICS (1000 / portTICK_PERIOD_MS)
@@ -158,7 +152,7 @@ static uint16_t buffer_fill_random(uint8_t *buffer, size_t length)
static void rs485_init(void)
{
uart_config_t uart_config = {
.baud_rate = UART_BAUD_115200,
.baud_rate = UART_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
@@ -210,7 +204,7 @@ static void rs485_slave(void)
unity_wait_for_signal("Master_started");
for(int pack_count = 0; pack_count < PACKETS_NUMBER; pack_count++) {
//Read slave_data from UART
int len = uart_read_bytes(UART_NUM1, slave_data, BUF_SIZE, (PACKET_READ_TICS * 2));
int len = uart_read_bytes(UART_NUM1, slave_data, BUF_SIZE, PACKET_READ_TICS);
//Write slave_data back to UART
if (len > 2) {
esp_err_t status = print_packet_data("Received ", slave_data, len);
@@ -259,7 +253,7 @@ static void rs485_master(void)
uart_write_bytes(UART_NUM1, (char*)master_buffer, BUF_SIZE);
uart_wait_tx_idle_polling(UART_NUM1);
// Read translated packet from slave
int len = uart_read_bytes(UART_NUM1, slave_buffer, BUF_SIZE, (PACKET_READ_TICS * 2));
int len = uart_read_bytes(UART_NUM1, slave_buffer, BUF_SIZE, PACKET_READ_TICS);
// Check if the received packet is too short
if (len > 2) {
// Print received packet and check checksum
@@ -280,6 +274,7 @@ static void rs485_master(void)
uart_wait_tx_done(UART_NUM1, PACKET_READ_TICS);
// Free the buffer and delete driver at the end
free(master_buffer);
free(slave_buffer);
uart_driver_delete(UART_NUM1);
TEST_ASSERT(err_count <= 1);
printf("Test completed. Received packets = %d, errors = %d\r\n", (uint16_t)good_count, (uint16_t)err_count);

View File

@@ -1,4 +1,7 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
# GPIO test uses IPC call, the default stack size of IPC task can satisfy the -O0 optimization
CONFIG_ESP_IPC_TASK_STACK_SIZE=2048

View File

@@ -1,5 +1,6 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
CONFIG_GPTIMER_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y

View File

@@ -4,3 +4,4 @@ set(srcs "test_app_main.c"
idf_component_register(SRCS ${srcs}
WHOLE_ARCHIVE)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -364,18 +364,26 @@ TEST_CASE("I2S_thread_concurrent_safety_test", "[i2s]")
TEST_ESP_OK(i2s_del_channel(rx_handle));
}
static uint32_t get_start_index(uint16_t *buf, uint32_t len, uint32_t start_val)
static bool whether_contains_exapected_data(uint16_t *src, uint32_t src_len, uint32_t src_step, uint32_t start_val, uint32_t val_step)
{
uint32_t i = 0;
for (i = 0; i < len; i++) {
if (buf[i] == start_val) {
printf("%d %d %d %d %d %d %d %d\n",
buf[i], buf[i+1], buf[i+2], buf[i+3],
buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
break;
uint32_t val = start_val;
uint32_t index_step = 1;
for (int i = 0; val < 100 && i < src_len; i += index_step) {
if (src[i] == val) {
if (val == start_val && i < src_len - 8) {
printf("start index: %d ---> \n%d %d %d %d %d %d %d %d\n", i,
src[i], src[i+1], src[i+2], src[i+3],
src[i+4], src[i+5], src[i+6], src[i+7]);
}
index_step = src_step;
val += val_step;
} else {
index_step = 1;
val = start_val;
}
}
return i;
return val >= 100;
}
/**
@@ -394,6 +402,8 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
i2s_chan_handle_t tx_handle;
i2s_chan_handle_t rx_handle;
bool is_failed = false;
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
chan_cfg.dma_desc_num = 8;
chan_cfg.dma_frame_num = 128;
@@ -429,7 +439,6 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
uint16_t *r_buf = calloc(1, READ_BUF_LEN);
size_t w_bytes = 0;
size_t r_bytes = 0;
uint32_t index = 0;
uint32_t retry = 0;
for (int n = 0; n < WRITE_BUF_LEN / 2; n++) {
w_buf[n] = n%100;
@@ -439,7 +448,7 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
* tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ...
* rx receive: 0x01[R] 0x03[R] ... */
TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 50); retry++) {
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
#if CONFIG_IDF_TARGET_ESP32
/* The data of tx/rx channels are flipped on ESP32 */
@@ -449,12 +458,15 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
r_buf[n+1] = temp;
}
#endif
index = get_start_index(r_buf, READ_BUF_LEN / 2, 1);
/* Expected: 1 3 5 7 9 ... 97 99 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 1, 2)) {
break;
}
}
printf("Data start index: %d\n", index);
TEST_ASSERT(index < READ_BUF_LEN / 2 - 50);
for (int16_t j = 1; j < 100; j += 2) {
TEST_ASSERT_EQUAL_INT16(r_buf[index++], j);
if (retry >= RETEY_TIMES) {
printf("rx right mono test failed\n");
is_failed = true;
goto err;
}
printf("rx right mono test passed\n");
@@ -468,7 +480,7 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
TEST_ESP_OK(i2s_channel_enable(tx_handle));
TEST_ESP_OK(i2s_channel_enable(rx_handle));
TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 50); retry++) {
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
#if CONFIG_IDF_TARGET_ESP32
/* The data of tx/rx channels are flipped on ESP32 */
@@ -478,12 +490,15 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
r_buf[n+1] = temp;
}
#endif
index = get_start_index(r_buf, READ_BUF_LEN / 2, 2);
/* Expected: 2 4 6 8 10 ... 96 98 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 2, 2)) {
break;
}
}
printf("Data start index: %d\n", index);
TEST_ASSERT(index < READ_BUF_LEN / 2 - 50);
for (int16_t j = 2; j < 100; j += 2) {
TEST_ASSERT_EQUAL_INT16(r_buf[index++], j);
if (retry >= RETEY_TIMES) {
printf("rx left mono test failed\n");
is_failed = true;
goto err;
}
printf("rx left mono test passed\n");
@@ -498,15 +513,17 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
TEST_ESP_OK(i2s_channel_enable(tx_handle));
TEST_ESP_OK(i2s_channel_enable(rx_handle));
TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 100); retry++) {
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
index = get_start_index(r_buf, READ_BUF_LEN / 2, 1);
/* Expected: 1 2 3 4 ... 98 99 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 1, 1)) {
break;
}
}
printf("Data start index: %d\n", index);
TEST_ASSERT(index < READ_BUF_LEN / 2 - 100);
for (int16_t j = 1; j < 100; j ++) {
TEST_ASSERT_EQUAL_INT16(r_buf[index++], j); // receive all number
if (retry >= RETEY_TIMES) {
printf("tx/rx stereo test failed\n");
is_failed = true;
goto err;
}
printf("tx/rx stereo test passed\n");
@@ -522,25 +539,35 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s]")
TEST_ESP_OK(i2s_channel_enable(tx_handle));
TEST_ESP_OK(i2s_channel_enable(rx_handle));
TEST_ESP_OK(i2s_channel_write(tx_handle, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
for (retry = 0, index = READ_BUF_LEN / 2; (retry < RETEY_TIMES) && (index >= READ_BUF_LEN / 2 - 100); retry++) {
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_channel_read(rx_handle, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
index = get_start_index(r_buf, READ_BUF_LEN / 2, 1);
/* Expected: 1 x 2 x 3 x ... 98 x 99 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 2, 1, 1)) {
break;
}
}
printf("Data start index: %d\n", index);
TEST_ASSERT(index < READ_BUF_LEN / 2 - 200);
for (int16_t j = 1; j < 100; j ++) {
TEST_ASSERT_EQUAL_INT16(r_buf[index], j);
index += 2;
if (retry >= RETEY_TIMES) {
printf("tx mono rx stereo test failed\n");
is_failed = true;
goto err;
}
printf("tx mono rx stereo test passed\n");
#endif
err:
if (is_failed) {
for (int i = 0; i < READ_BUF_LEN / 2; i++) {
printf("%x ", r_buf[i]);
}
printf("\n");
}
free(w_buf);
free(r_buf);
TEST_ESP_OK(i2s_channel_disable(tx_handle));
TEST_ESP_OK(i2s_channel_disable(rx_handle));
TEST_ESP_OK(i2s_del_channel(tx_handle));
TEST_ESP_OK(i2s_del_channel(rx_handle));
TEST_ASSERT_FALSE(is_failed);
}
TEST_CASE("I2S_memory_leak_test", "[i2s]")

View File

@@ -1,5 +1,5 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_I2S_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y

View File

@@ -3,7 +3,6 @@ CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_I2S_ISR_IRAM_SAFE=y
CONFIG_COMPILER_DUMP_RTL_FILES=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y

View File

@@ -3,3 +3,4 @@ set(srcs "test_app_main.c"
idf_component_register(SRCS ${srcs}
WHOLE_ARCHIVE)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -29,6 +29,9 @@
#include "driver/pulse_cnt.h"
#include "soc/pcnt_periph.h"
#endif
#ifdef CONFIG_PM_ENABLE
#include "esp_pm.h"
#endif
#include "../../test_inc/test_i2s.h"
@@ -211,6 +214,28 @@ TEST_CASE("I2S_basic_driver_installation_uninstallation_and_settings_test", "[i2
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, i2s_driver_uninstall(I2S_NUM_0));
}
static bool whether_contains_exapected_data(uint16_t *src, uint32_t src_len, uint32_t src_step, uint32_t start_val, uint32_t val_step)
{
uint32_t val = start_val;
uint32_t index_step = 1;
for (int i = 0; val < 100 && i < src_len; i += index_step) {
if (src[i] == val) {
if (val == start_val && i < src_len - 8) {
printf("start index: %d ---> \n%d %d %d %d %d %d %d %d\n", i,
src[i], src[i+1], src[i+2], src[i+3],
src[i+4], src[i+5], src[i+6], src[i+7]);
}
index_step = src_step;
val += val_step;
} else {
index_step = 1;
val = start_val;
}
}
return val >= 100;
}
/**
* @brief Test mono and stereo mode of I2S by loopback
* @note Only rx channel distinguish left mono and right mono, tx channel does not
@@ -222,6 +247,7 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]")
{
#define WRITE_BUF_LEN 2000
#define READ_BUF_LEN 4000
#define RETEY_TIMES 3
// master driver installed and send data
i2s_config_t master_i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX,
@@ -269,6 +295,8 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]")
uint16_t *r_buf = calloc(1, READ_BUF_LEN);
size_t w_bytes = 0;
size_t r_bytes = 0;
uint32_t retry = 0;
bool is_failed = false;
for (int n = 0; n < WRITE_BUF_LEN / 2; n++) {
w_buf[n] = n%100;
}
@@ -276,28 +304,25 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]")
* tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ...
* rx receive: 0x01[R] 0x03[R] ... */
TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
#if CONFIG_IDF_TARGET_ESP32
/* The data of tx/rx channels are flipped on ESP32 */
for (int n = 0; n < READ_BUF_LEN / 2; n += 2) {
int16_t temp = r_buf[n];
r_buf[n] = r_buf[n+1];
r_buf[n+1] = temp;
}
#endif
int i = 0;
for (i = 0; (i < READ_BUF_LEN / 2); i++) {
if (r_buf[i] == 1) {
printf("%d %d %d %d\n%d %d %d %d\n",
r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3],
r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]);
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
#if CONFIG_IDF_TARGET_ESP32
/* The data of tx/rx channels are flipped on ESP32 */
for (int n = 0; n < READ_BUF_LEN / 2; n += 2) {
int16_t temp = r_buf[n];
r_buf[n] = r_buf[n+1];
r_buf[n+1] = temp;
}
#endif
/* Expected: 1 3 5 7 9 ... 97 99 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 1, 2)) {
break;
}
}
printf("Data start index: %d\n", i);
TEST_ASSERT(i < READ_BUF_LEN / 2 - 50);
for (int16_t j = 1; j < 100; j += 2) {
TEST_ASSERT_EQUAL_INT16(r_buf[i++], j);
if (retry >= RETEY_TIMES) {
printf("rx right mono test failed\n");
is_failed = true;
goto err;
}
printf("rx right mono test passed\n");
@@ -306,21 +331,17 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]")
* rx receive: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ... */
TEST_ESP_OK(i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, SAMPLE_BITS, I2S_CHANNEL_STEREO));
TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
for (i = 0; (i < READ_BUF_LEN / 2); i++) {
if (r_buf[i] == 1) {
printf("%d %d %d %d\n%d %d %d %d\n",
r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3],
r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]);
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
/* Expected: 1 2 3 4 ... 98 99 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 1, 1)) {
break;
}
}
printf("Data start index: %d\n", i);
TEST_ASSERT(i < READ_BUF_LEN / 2 - 100);
TEST_ASSERT(i % 2);
for (int16_t j = 1; j < 100; j ++) {
TEST_ASSERT_EQUAL_INT16(r_buf[i++], j); // receive all number
if (retry >= RETEY_TIMES) {
printf("tx/rx stereo test failed\n");
is_failed = true;
goto err;
}
printf("tx/rx stereo test passed\n");
@@ -329,20 +350,17 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]")
* rx receive: 0x01[R] 0x02[R] ... */
TEST_ESP_OK(i2s_set_clk(I2S_NUM_0, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_MONO));
TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
for (i = 0; i < READ_BUF_LEN / 2; i++) {
if (r_buf[i] == 1) {
printf("%d %d %d %d\n%d %d %d %d\n",
r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3],
r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]);
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
/* Expected: 1 2 3 4 ... 98 99 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 1, 1)) {
break;
}
}
printf("Data start index: %d\n", i);
TEST_ASSERT(i < READ_BUF_LEN / 2 - 100);
for (int16_t j = 1; j < 100; j ++) {
TEST_ASSERT_EQUAL_INT16(r_buf[i++], j);
if (retry >= RETEY_TIMES) {
printf("tx/rx mono test failed\n");
is_failed = true;
goto err;
}
printf("tx/rx mono test passed\n");
@@ -364,33 +382,39 @@ TEST_CASE("I2S_mono_stereo_loopback_test", "[i2s_legacy]")
* tx format: 0x00[L] 0x01[R] 0x02[L] 0x03[R] ...
* rx receive: 0x00[R] 0x02[R] ... */
TEST_ESP_OK(i2s_write(I2S_NUM_0, w_buf, WRITE_BUF_LEN, &w_bytes, portMAX_DELAY));
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
#if CONFIG_IDF_TARGET_ESP32
/* The data of tx/rx channels are flipped on ESP32 */
for (int n = 0; n < READ_BUF_LEN / 2; n += 2) {
int16_t temp = r_buf[n];
r_buf[n] = r_buf[n+1];
r_buf[n+1] = temp;
}
#endif
for (i = 0; (i < READ_BUF_LEN / 2); i++) {
if (r_buf[i] == 2) {
printf("%d %d %d %d\n%d %d %d %d\n",
r_buf[i], r_buf[i+1], r_buf[i+2], r_buf[i+3],
r_buf[i+4], r_buf[i+5], r_buf[i+6], r_buf[i+7]);
for (retry = 0; retry < RETEY_TIMES; retry++) {
TEST_ESP_OK(i2s_read(I2S_NUM_0, r_buf, READ_BUF_LEN, &r_bytes, portMAX_DELAY));
#if CONFIG_IDF_TARGET_ESP32
/* The data of tx/rx channels are flipped on ESP32 */
for (int n = 0; n < READ_BUF_LEN / 2; n += 2) {
int16_t temp = r_buf[n];
r_buf[n] = r_buf[n+1];
r_buf[n+1] = temp;
}
#endif
/* Expected: 2 4 6 8 10 ... 96 98 */
if (whether_contains_exapected_data(r_buf, READ_BUF_LEN / 2, 1, 2, 2)) {
break;
}
}
printf("Data start index: %d\n", i);
TEST_ASSERT(i < READ_BUF_LEN / 2 - 50);
for (int16_t j = 2; j < 100; j += 2) {
TEST_ASSERT_EQUAL_INT16(r_buf[i++], j);
if (retry >= RETEY_TIMES) {
printf("rx left mono test failed\n");
is_failed = true;
goto err;
}
printf("rx left mono test passed\n");
err:
if (is_failed) {
for (int i = 0; i < READ_BUF_LEN / 2; i++) {
printf("%x ", r_buf[i]);
}
printf("\n");
}
free(w_buf);
free(r_buf);
TEST_ESP_OK(i2s_driver_uninstall(I2S_NUM_0));
TEST_ASSERT_FALSE(is_failed);
}
#if SOC_I2S_SUPPORTS_TDM
@@ -854,6 +878,14 @@ static void i2s_test_common_sample_rate(i2s_port_t id)
32000, 44100, 48000, 64000, 88200, 96000,
128000, 144000, 196000};
int real_pulse = 0;
// Acquire the PM lock incase Dynamic Frequency Scaling(DFS) lower the frequency
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock;
esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX;
TEST_ESP_OK(esp_pm_lock_create(pm_type, 0, "legacy_i2s_test", &pm_lock));
esp_pm_lock_acquire(pm_lock);
#endif
for (int i = 0; i < 15; i++) {
int expt_pulse = (int16_t)((float)test_freq[i] * (TEST_I2S_PERIOD_MS / 1000.0));
TEST_ESP_OK(i2s_set_clk(id, test_freq[i], SAMPLE_BITS, I2S_CHANNEL_STEREO));
@@ -868,6 +900,10 @@ static void i2s_test_common_sample_rate(i2s_port_t id)
// Check if the error between real pulse number and expected pulse number is within 1%
TEST_ASSERT_INT_WITHIN(expt_pulse * 0.01, expt_pulse, real_pulse);
}
#ifdef CONFIG_PM_ENABLE
esp_pm_lock_release(pm_lock);
esp_pm_lock_delete(pm_lock);
#endif
TEST_ESP_OK(pcnt_del_channel(pcnt_chan));
TEST_ESP_OK(pcnt_unit_stop(pcnt_unit));
TEST_ESP_OK(pcnt_unit_disable(pcnt_unit));

View File

@@ -3,4 +3,3 @@ CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_I2S_ISR_IRAM_SAFE=y

View File

@@ -34,7 +34,7 @@
#elif CONFIG_IDF_TARGET_ESP32C3
#define ADC_TEST_LOW_VAL 0
#define ADC_TEST_LOW_THRESH 30
#define ADC_TEST_LOW_THRESH 50
#define ADC_TEST_HIGH_VAL 4095
#define ADC_TEST_HIGH_THRESH 10

View File

@@ -3,3 +3,4 @@ set(srcs "test_app_main.c"
idf_component_register(SRCS ${srcs}
WHOLE_ARCHIVE)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -8,7 +8,12 @@ set(srcs "test_app_main.c"
"test_mcpwm_timer.c"
"test_mcpwm_utils.c")
if(CONFIG_MCPWM_ISR_IRAM_SAFE)
list(APPEND srcs "test_mcpwm_iram.c")
endif()
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(SRCS ${srcs}
WHOLE_ARCHIVE)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -0,0 +1,90 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "unity.h"
#include "soc/soc_caps.h"
#include "esp_private/esp_clk.h"
#include "esp_private/spi_flash_os.h"
#include "driver/mcpwm_cap.h"
#include "driver/mcpwm_sync.h"
#include "driver/gpio.h"
#include "test_mcpwm_utils.h"
static bool IRAM_ATTR test_capture_callback_iram_safe(mcpwm_cap_channel_handle_t cap_channel, const mcpwm_capture_event_data_t *edata, void *user_data)
{
uint32_t *cap_value = (uint32_t *)user_data;
if (edata->cap_edge == MCPWM_CAP_EDGE_NEG) {
cap_value[1] = edata->cap_value;
} else {
cap_value[0] = edata->cap_value;
}
return false;
}
static void IRAM_ATTR test_mcpwm_capture_gpio_simulate(int gpio_sig)
{
// disable flash cache
spi_flash_guard_get()->start();
gpio_set_level(gpio_sig, 1);
esp_rom_delay_us(1000);
gpio_set_level(gpio_sig, 0);
// enable flash cache
spi_flash_guard_get()->end();
}
TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
{
printf("install mcpwm capture timer\r\n");
mcpwm_cap_timer_handle_t cap_timer = NULL;
mcpwm_capture_timer_config_t cap_timer_config = {
.clk_src = MCPWM_CAPTURE_CLK_SRC_APB,
.group_id = 0,
};
TEST_ESP_OK(mcpwm_new_capture_timer(&cap_timer_config, &cap_timer));
const int cap_gpio = 0;
// put the GPIO into a preset state
gpio_set_level(cap_gpio, 0);
printf("install mcpwm capture channel\r\n");
mcpwm_cap_channel_handle_t pps_channel;
mcpwm_capture_channel_config_t cap_chan_config = {
.gpio_num = cap_gpio,
.prescale = 1,
.flags.pos_edge = true,
.flags.neg_edge = true,
.flags.io_loop_back = true, // so we can use GPIO functions to simulate the external capture signal
.flags.pull_up = true,
};
TEST_ESP_OK(mcpwm_new_capture_channel(cap_timer, &cap_chan_config, &pps_channel));
printf("install callback for capture channel\r\n");
mcpwm_capture_event_callbacks_t cbs = {
.on_cap = test_capture_callback_iram_safe,
};
uint32_t cap_value[2] = {0};
TEST_ESP_OK(mcpwm_capture_channel_register_event_callbacks(pps_channel, &cbs, cap_value));
printf("enable and start capture timer\r\n");
TEST_ESP_OK(mcpwm_capture_timer_enable(cap_timer));
TEST_ESP_OK(mcpwm_capture_timer_start(cap_timer));
printf("disable cache, simulate GPIO capture signal\r\n");
test_mcpwm_capture_gpio_simulate(cap_gpio);
printf("capture value: Pos=%u, Neg=%u\r\n", cap_value[0], cap_value[1]);
// Capture timer is clocked from APB by default
uint32_t clk_src_res = esp_clk_apb_freq();
TEST_ASSERT_UINT_WITHIN(2000, clk_src_res / 1000, cap_value[1] - cap_value[0]);
printf("uninstall capture channel and timer\r\n");
TEST_ESP_OK(mcpwm_del_capture_channel(pps_channel));
TEST_ESP_OK(mcpwm_capture_timer_disable(cap_timer));
TEST_ESP_OK(mcpwm_del_capture_timer(cap_timer));
}

View File

@@ -1,5 +1,6 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_MCPWM_ISR_IRAM_SAFE=y
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y

View File

@@ -2,6 +2,6 @@ CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_PCNT_CTRL_FUNC_IN_IRAM=y
CONFIG_PCNT_ISR_IRAM_SAFE=y
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y

View File

@@ -1,6 +1,6 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_RMT_ISR_IRAM_SAFE=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y

View File

@@ -1,5 +1,5 @@
CONFIG_COMPILER_DUMP_RTL_FILES=y
CONFIG_SDM_CTRL_FUNC_IN_IRAM=y
CONFIG_COMPILER_OPTIMIZATION_NONE=y
# silent the error check, as the error string are stored in rodata, causing RTL check failure
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y

View File

@@ -77,3 +77,5 @@ set(EFUSE_TEST_TABLE_CSV_PATH "${COMPONENT_DIR}/test/esp_efuse_test_table.csv")
add_custom_target(efuse_test_table COMMAND "${python}"
"${CMAKE_CURRENT_SOURCE_DIR}/efuse_table_gen.py"
${EFUSE_TEST_TABLE_CSV_PATH} ${GEN_EFUSE_TABLE_ARG})
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")

View File

@@ -248,6 +248,7 @@ class FuseTable(list):
'extern "C" {',
'#endif',
'',
'#include "esp_efuse.h"',
'',
'// md5_digest_table ' + self.md5_digest_table,
'// This file was generated from the file ' + file_name + '.csv. DO NOT CHANGE THIS FILE MANUALLY.',

View File

@@ -8,6 +8,7 @@
extern "C" {
#endif
#include "esp_efuse.h"
// md5_digest_table 6256f9b7c6783e0b651bf52b5b162aa8
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.

View File

@@ -8,6 +8,7 @@
extern "C" {
#endif
#include "esp_efuse.h"
// md5_digest_table ef050bc1e4bf0d8384aa3e4c0256d7d3
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.

View File

@@ -8,6 +8,7 @@
extern "C" {
#endif
#include "esp_efuse.h"
// md5_digest_table d006c80095638b5dbdc8649bf7e04dce
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.

View File

@@ -8,6 +8,7 @@
extern "C" {
#endif
#include "esp_efuse.h"
// md5_digest_table 4ff665f7ab2f32b83f2b5b232bcdeac8
// This file was generated from the file esp_efuse_table.csv. DO NOT CHANGE THIS FILE MANUALLY.

Some files were not shown because too many files have changed in this diff Show More