Compare commits

...

203 Commits

Author SHA1 Message Date
Ivan Grokhotkov
bef9896305 Merge branch 'bugfix/xtal_freq_40_2.0' into 'release/v2.0'
esp32: by default, set 40MHz crystal frequency

See merge request !1144
2017-08-24 15:48:06 +08:00
He Yin Ling
18dbdd46f4 CI: checkout relative branch of test_script
test script interface could change. we need to use the correct version
of test script to run test on old release versions of IDF.
2017-08-24 11:38:52 +08:00
Ivan Grokhotkov
4184968469 esp32: by default, set 40MHz crystal frequency 2017-08-23 16:41:51 +08:00
Ivan Grokhotkov
024ef51d1a Merge branch 'bugfix/bt_increase_btc_task_queue_size' into 'release/v2.0'
bt component: increase BTC task queue size



See merge request !637
2017-04-06 10:57:00 +08:00
island
4d9778e208 bt component: increase BTC task queue number 2017-04-05 21:42:12 +08:00
Ivan Grokhotkov
6181af2a0b Merge branch 'test/reboot_between_unit_test_cases' into 'release/v2.0'
CI: add reset between running each unit test cases

Unit test is designed to detect bug **within** each test case. Therefore we'll reset between each case to provide a clean context. We will later add stress cases to run unit test cases together to detect potential bugs.

See merge request !636
2017-04-05 20:52:13 +08:00
He Yin Ling
abf0cd8421 CI: add reset between running each unit test cases 2017-04-05 18:41:56 +08:00
Ivan Grokhotkov
7a83c87c44 Merge branch 'bugfix/cpu1_isr_stack_location' into 'master'
Fix finding location of ISR stack space for CPU1

Up to now, the CPU1 interrupts erroneously used the area *after* the ISR stack region, leading to bugs in BT Classic. This fixes that.

See merge request !618
2017-04-01 16:56:21 +08:00
island
6ad86f0d67 bt component: fix gatt delete service memory leak problem 2017-04-01 15:34:38 +08:00
Liu Zhi Fu
fddebe4bcc Merge branch 'bugfix/merge_esptouch_fix' into 'release/v2.0'
esp32: update wifi lib for esptouch issue

Disconnect station before enabling esptouch

See merge request !617
2017-03-28 19:16:06 +08:00
Liu Zhi Fu
2102acf266 esp32: update wifi lib for esptouch issue
Disconnect station before enabling esptouch
2017-03-28 15:45:19 +08:00
Liu Zhi Fu
a4ac9bf80b Merge branch 'bugfix/merge_some_wifi_bugs_into_release2.0' into 'release/v2.0'
esp32: update wifi lib for some fixes

1. Fix AMSDU flags issue
2. Fix smartconfig cause serial no response issue
3. Fix restore cause exception issue
4. smartconfig cause crash

See merge request !611
2017-03-27 15:01:21 +08:00
Liu Zhi Fu
6e2601f389 esp32: update wifi lib for some bugfix
1. Fix AMSDU flags issue
2. Fix smartconfig cause serial no response issue
3. Fix restore cause exception issue
4. Fix smartconfig cause crash
2017-03-27 11:29:08 +08:00
Ivan Grokhotkov
ea48f43f87 Merge branch 'bugfix/timer_stack_size' into 'release/v2.0'
freertos: increase timer task stack size to 2048 bytes

Current timer task stack size is insufficient for logging calls which
use non-nano vprintf.

See merge request !607
2017-03-24 15:54:57 +08:00
Ivan Grokhotkov
1b0b34247a Merge branch 'bugfix/btdm_isr_alloc' into 'release/v2.0'
component/bt : fix rx packet assert bug and malloc in ISR bug in bluetooth

1. fix alloc in ISR context bug
2. fix rx bluetooth packets cause assert bug

See merge request !609
2017-03-24 15:54:09 +08:00
Tian Hao
4aaa453b31 component/bt : fix rx packet assert bug and malloc in ISR bug in bluetooth 2017-03-24 14:57:07 +08:00
Ivan Grokhotkov
fe69377782 freertos: increase timer task stack size to 2048 bytes
Current timer task stack size is insufficient for logging calls which
use non-nano vprintf.
2017-03-24 08:40:05 +08:00
island
1c9d8744ab bt component: Fix HCI task stack overflow bug 2017-03-23 17:27:15 +08:00
Ivan Grokhotkov
7db3370e20 Merge branch 'bugfix/vhci_callback' into 'release/v2.0'
component/bt: let "vhci_notify_host_send_available" be called in task context

Previously the callback function "vhci_notify_host_send_available" can be called in both interrupt context or BT controller task context, which is one of the cause that Bluedroid tasks cannot work on dual CPUs. 

See merge request !603
2017-03-22 22:42:58 +08:00
Angus Gratton
eece22d075 ci: Swap github/gitlab submodules for release branches & tags also 2017-03-22 21:21:00 +08:00
Angus Gratton
2cc668bbb1 ci: Also run deployment steps for tags of form vX.Y (with optional -suffix) 2017-03-22 21:21:00 +08:00
wangmengyang
ad4a1b600a component/bt: let vhci callback "vhci_notify_host_send_available" be called in the context of BT controller task. 2017-03-22 19:38:47 +08:00
Tian Hao
877b407c8c component/bt : fix blufi bug of sec_mode reset 2017-03-22 16:17:20 +08:00
me-no-dev
5850f423d5 address security issues with mDNS 2017-03-22 16:16:44 +08:00
island
ea74033d1e bt component: fix bluetooth gatt packets process bugs
1. Add process of prepare write request packets
2. Add process of execute write request packets
3. Add process of reliable write request packets
4. Fix bug of processing read blob request packets
5. Fix bug of processing write request packets
6. Optimize error check and process in stack
2017-03-21 14:32:25 +08:00
Angus Gratton
7cd1e0ef4b ci: Fix master branch being pushed to master
Previous change in 8b6993f7 doesn't work if branch exists locally.
2017-03-17 18:17:41 +08:00
Angus Gratton
f72888544e build/CI: Push all allocated release branches to github
Previously CI deployment only pushed to master.
2017-03-17 18:17:11 +08:00
Tian Hao
a513ac4dec add extra check before bluedroid init and disable 2017-03-17 18:15:11 +08:00
Angus Gratton
b337b20270 docs/eclipse: Add considerations for PATH, PYTHONPATH
Thanks to @motla who mentioned these on github:
https://github.com/espressif/esp-idf/pull/157#issuecomment-271109920
2017-03-17 18:14:17 +08:00
Angus Gratton
8ab96b13af esp_err: Use separate code path for ESP_ERROR_CHECK assertion
* Minimum code size overhead
* Makes function safe to use when flash cache is disabled

Builds on #339 https://github.com/espressif/esp-idf/pull/339
2017-03-17 18:14:17 +08:00
Angus Gratton
50f414f54c spi_flash: Add spi_flash_cache_enabled() test function 2017-03-17 18:13:46 +08:00
Angus Gratton
0dfef8c16c sdmmc: Use slot width as default slot_config width parameter, instead of 4
Ref #361 https://github.com/espressif/esp-idf/pull/361
2017-03-17 18:12:41 +08:00
Derek Gregory
6bb1367fe5 component/bt: fix bug where uuid was not reset in btc_gatts_act_create_attr_tab.
Merges #307 https://github.com/espressif/esp-idf/pull/307
2017-03-17 18:12:41 +08:00
lucashutchinson
a286846095 ble: Fix ble_adv data truncation
Fixed issue with ble_adv data being truncated after the 31st octet due to an incorrect length passed in a memcpy.

Merges #389 https://github.com/espressif/esp-idf/pull/389
2017-03-17 18:12:41 +08:00
Angus Gratton
2b2dd845ae docs/*-setup: Use --enable-local instead of --prefix=$PWD for ct-ng 2017-03-17 18:12:41 +08:00
Daniel Bovensiepen
b9f9e681ba docs/linux-setup: Install dependencies for Ubuntu 16.04
Not sure which Ubuntu is used in the installation guide but for the latest LTS release 16.04 we need libtool-bin for
compiling crosstool-NG proper

Merges #46 https://github.com/espressif/esp-idf/pull/46
2017-03-17 18:12:41 +08:00
Angus Gratton
3429241e1a esp_err: add NDEBUG guard, comment about flash cache
Follow-up to 316b040
2017-03-17 18:12:41 +08:00
Neil Kolban
455a7784a9 Update to ESP_ERROR_CHECK
See request from ESP_Angus here:
https://esp32.com/viewtopic.php?f=18&t=1179

Merges #339 https://github.com/espressif/esp-idf/pull/339
2017-03-17 18:12:41 +08:00
Anne Jan Brouwer
7d9a20e714 Added missing platform.h to mbedtls ssl.h
There was a missing definition of mbedtls_time_t

See for example:
https://travis-ci.org/SHA2017-badge/Firmware/jobs/202459377

Merges #348 https://github.com/espressif/esp-idf/pull/348
2017-03-17 18:12:41 +08:00
Angus Gratton
a6980fce4c lwip: Use strlcpy() instead of memcpy() to copy hostname to static buffer 2017-03-17 18:12:41 +08:00
alarruskain
4bd41d4082 lwip: Fix hostname set in tcpip_adapter_lwip
Hostname for each interface is not correctly stored in "hostinfo" variable.

Merges #350 https://github.com/espressif/esp-idf/pull/350
2017-03-17 18:12:41 +08:00
gbcwbz
3302a38432 docs: Fix typo in build-system.rst
Merges #355 https://github.com/espressif/esp-idf/pull/355
2017-03-17 18:12:41 +08:00
Daniel Campora
82ef2b9485 sdmmc: Add width field to the slot config.
Therefore if the width is set to 1, you can choose to only
configure the CLK, DAT0 and CMD pins.

Merges #361 https://github.com/espressif/esp-idf/pull/361
2017-03-17 18:12:41 +08:00
rudi ;-)
de461671aa examples/ethernet: Same sense of meaning SW_STRAP
Merges #366 #367
https://github.com/espressif/esp-idf/pull/366
https://github.com/espressif/esp-idf/pull/367
2017-03-17 18:12:41 +08:00
rudi ;-)
aa2f5e4ae5 examples/ethernet: typo, better named
Merges #382 https://github.com/espressif/esp-idf/pull/382
2017-03-17 18:12:41 +08:00
Ivan Grokhotkov
c01dff8263 Merge branch 'feature/run_test_on_release_branches' into 'master'
CI: support running CI test on release branches

Patches will be cherry-picked to release branches after it's released. Therefore we need to run test jobs with the same strategy as master.

See merge request !551
2017-03-04 15:06:37 +08:00
Wu Jian Gang
06274ff5a5 Merge branch 'bugfix/fix_mpdu_len_error' into 'master'
esp32: update wifi lib to fix mpdu len error

Fix mpdu len error which impact espressif smartconfig

See merge request !552
2017-03-04 15:03:46 +08:00
Jiang Jiang Jian
c62ae777c2 Merge branch 'feature/tw10306_menuconfig_adds_some_wifi_options' into 'master'
menuconfig adds some WiFi options

menuconfig adds some WiFi options
 1. Add options to enable/disable AMPDU
  2. Add options to configure WiFi task stack size
  3. Add options to configure WiFi RX/TX buffer number


See merge request !519
2017-03-02 19:46:29 +08:00
Liu Zhi Fu
abdd8feebb esp32: menuconfig adds some WiFi options
1. Add options to enable/disable AMPDU
2. Add options to enable/disable WIFI NVS
3. Add options to configure WiFi RX/TX buffer number
2017-03-02 18:13:49 +08:00
Jiang Jiang Jian
3b8c9a407f Merge branch 'feature/add_user_set_mac' into 'master'
Feature/add user set mac

1. Add menuconfig for user to set mac address of wifi, bt and ethernet.
2. Add the number of MAC address generated from efuse for user to choose.
3. Add MAC address derive method.

See merge request !542
2017-03-02 17:34:14 +08:00
Jiang Jiang Jian
6451c57e52 Merge branch 'bugfix/tw10169_dhcp_release_cause_tcp_abort' into 'master'
Bugfix/tw10169 dhcp release cause tcp abort

Modify the DHCP timer granularity from 1 minutes to 1 second.

See merge request !539
2017-03-02 17:28:11 +08:00
Jeroen Domburg
432b25f755 Merge branch 'feature/in_isr_context' into 'master'
Add xPortInIsrContext function + unit test

As title states.

See merge request !533
2017-03-02 17:17:23 +08:00
Jeroen Domburg
6739d5b99f Add xPortInIsrContext function + unit test. This function returns true when the current CPU runs in an interrupt handler context. 2017-03-02 17:00:32 +08:00
XiaXiaotian
d3eede2110 mac address: add the number of MAC address generated from efuse for user to choose
1. Add the number of MAC address generated from efuse for user to choose.

2. Add MAC address derive method.
2017-03-02 15:54:35 +08:00
Ivan Grokhotkov
ecbe5a66f2 Merge branch 'bugfix/rng_disabled_wifi_stop_2' into 'master'
esp32: Fix hardware rng after esp_wifi_stop (second implementation)

Ensures hardware RNG remains enabled at all times.

Reworked  version of !534

See merge request !536
2017-03-02 10:51:30 +08:00
Jiang Jiang Jian
4e5e154603 Merge branch 'bugfix/fix_some_default_lwip_bool_options' into 'master'
Bugfix/fix some default lwip bool options

menuconfig options with bool type should use 'y/n' to set the default value, instead of '1/0'


See merge request !538
2017-03-01 22:03:57 +08:00
wangmengyang
6d061ec903 component/bt: modify the bluetooth read_efuse_mac interface 2017-03-01 21:04:12 +08:00
XiaXiaotian
fabe0493c2 mac address: add user set mac address
add menuconfig for user to set mac address of wifi, bt and ethernet.
2017-03-01 20:51:49 +08:00
Liu Zhi Fu
66199b1efe Check DHCP rebind timer before checking dhcp release timer in cause they have the same value.
lwip: modify dhcp timer granularity from 60s to 1s

Current DHCP granularity is 60 seconds, it's not accurate, it can cause DHCP release/rebind/renew timer
timeout at the same time, also it may renew/rebind/release at wrong time, thus cause problem.
2017-03-01 20:50:58 +08:00
XiaXiaotian
23f933a78d mac address: add user set mac address
add menuconfig for user to set mac address of wifi, bt and ethernet.
2017-03-01 20:42:46 +08:00
Liu Zhi Fu
3b3c3210a6 lwip: fix bool options default value wrong issue
menuconfig options with bool type should use 'y/n' to use the default value,
instead of '1/0'
2017-03-01 13:37:36 +08:00
Liu Zhi Fu
ae09a46cb8 Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf 2017-03-01 13:32:04 +08:00
Angus Gratton
4d67a2ba8b esp32 phy_init: Move DPORT Wifi clock masks to macro values
Amended fix for c642079 !534
2017-03-01 12:11:57 +11:00
Angus Gratton
98f8594151 esp32 dport_reg.h: Fix typo in register bit names 2017-03-01 12:01:07 +11:00
Ivan Grokhotkov
c025dfbfa7 Merge branch 'bugfix/mmap_instr' into 'master'
spi_flash: fix mmap not working for SPI_FLASH_MMAP_INST

Fixes https://github.com/espressif/esp-idf/issues/378

See merge request !528
2017-02-28 17:14:38 +08:00
Ivan Grokhotkov
f3687f7177 spi_flash: fix memory leak when spi_flash_mmap arguments are invalid
Check src_addr and size first, then allocate new_entry.
2017-02-28 15:11:54 +08:00
Wu Jian Gang
8f43567a68 Merge branch 'bugfix/esp_get_random_return_zero' into 'master'
Do not disable clock for generating random number.

1. Do not disable clock for generating random number.
2. And fix the bug that system crashes if call esp_wifi_stop() twice.

See merge request !534
2017-02-28 14:35:22 +08:00
XiaXiaotian
f36c909528 update phy and rtc lib
1. RTC V214: modify APLL function for the chip of ECO version.

2. Add API phy_close_rf() and use it in esp_phy_deinit() instead of pm_close_rf().

3. RTC V213: fix BT will not work when BT-init is called more than once.
2017-02-27 19:54:22 +08:00
Liu Zhi Fu
cd83bfb31c Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf 2017-02-27 17:22:47 +08:00
XiaXiaotian
c6420792f2 1. Do not disable clock for generating random number.
2. And fix the bug that system crashes if call esp_wifi_stop() twice.
2017-02-27 16:48:04 +08:00
Ivan Grokhotkov
290c40a4ab Merge branch 'bugfix/sdmmc_fail_no_card' into 'master'
vfs_fat_sdmmc: if card init fails, fail cleanly

This fixes the issue with sdmmc_host not returned to clean state after a failed attempt to mount the card, with no SD card in the slot.

See merge request !527
2017-02-27 10:00:55 +08:00
Jiang Jiang Jian
13dfb5568d Merge branch 'bugfix/set_channel_fail_before_enable_sniffer' into 'master'
wifi: fix issue in setting channel API

Update wifi libs to fix issue in setting channel API.

See merge request !529
2017-02-24 22:23:06 +08:00
qiyueixa
d9c649d26e wifi: fix issue in setting channel API 2017-02-24 22:08:54 +08:00
Ivan Grokhotkov
75115e1d83 spi_flash: fix mmap not working for SPI_FLASH_MMAP_INST 2017-02-24 21:50:05 +08:00
Ivan Grokhotkov
c17e05040a vfs_fat_sdmmc: if card init fails, fail cleanly
This fixes the issue with sdmmc_host not returned to clean state after
a failed attempt to mount the card, with no SD card in the slot.
2017-02-24 21:04:22 +08:00
Jiang Jiang Jian
63e0140ae6 Merge branch 'bugfix/btdm_adv_scan_enable_report' into 'master'
component/bt : add adv/scan start complete event

1. indicate adv/scan start complete success or failed
2. controller do limit of adv/scan concurrence, so add some codes to report adv/scan start failed or not.

See merge request !524
2017-02-24 16:24:22 +08:00
Ivan Grokhotkov
1671879b7a Merge branch 'bugfix/set_channel_fail_before_enable_sniffer' into 'master'
wifi: fix issue in setting channel before sniffer is enabled



See merge request !526
2017-02-24 16:15:39 +08:00
qiyueixa
ff81e17504 wifi: fix issue in setting channel before sniffer is enabled 2017-02-24 15:19:31 +08:00
Ivan Grokhotkov
708539c559 Merge branch 'bugfix/btdm_gatts_write_desc_error' into 'master'
component/bt:fixed the write ccc crash bug error

fix the gatt server write ccc lead to the system crash if not initialize the ccc value.

See merge request !515
2017-02-24 15:11:18 +08:00
Ivan Grokhotkov
36b3963efb Merge branch 'feature/btdm_ram_config' into 'master'
Optimize or release memory in bluetooth

1. add option to release about 30K from BT if BLE only
2. later BT/BLE will be separated by BT/BLE macro, but this option should use when user make sure that in BLE only mode.

See merge request !520
2017-02-23 18:21:16 +08:00
Tian Hao
b582697889 component/bt : add adv/scan start complete event
1. indicate adv/scan start complete success or failed
2. controller do limit of adv/scan concurrence, so add some codes to report adv/scan start failed or not.
2017-02-23 17:54:22 +08:00
Jeroen Domburg
7dfb1c2e97 Merge branch 'bugfix/app_tasks_start_on_wrong_cpu' into 'master'
Fix a scheduling bug

Fixes:
- Trivial bug where in some special cases a task could be started on the wrong core (and would run there for max 1 tick)
- More major bug causing a yield to be done with a mux held.

See merge request !523
2017-02-23 11:19:37 +08:00
Jeroen Domburg
c057f067c7 Merge branch 'bugfix/spi_master_length' into 'master'
Fix SPI master transmit length

Tx/Rx length fix from https://github.com/espressif/esp-idf/pull/336

I also added an extra commit in to make use of a define instead of a literal, plus fix a (harmless) off-by-one condition.

See merge request !521
2017-02-22 17:11:00 +08:00
Jeroen Domburg
ce7d0a7015 Fixed a small bug where a task could initially be scheduled on a wrong CPU, and a much bigger bug where a yield was performed with a held mux. 2017-02-22 17:04:51 +08:00
Ivan Grokhotkov
d772e1489b Merge branch 'bugfix/bootloader_disable_sar_test_mux' into 'master'
Deep sleep fixes

This change fixes extra 24 uA current consumption in deep sleep mode (https://esp32.com/viewtopic.php?f=2&t=1133).

Recent update to libphy/librtc caused another problem that WiFi related parts of RTC are no longer disabled by RTC sleep functions. This means that if WiFi is not disabled by the application before entering deep sleep, extra ~200uA of current would be consumed. This is fixed, and documentation for esp_deep_sleep and SNTP example are updated to mention that applications should take care of disabling WiFi and BT before going into the deep sleep mode.

See merge request !516
2017-02-22 14:32:32 +08:00
Ivan Grokhotkov
dca0377e19 Merge branch 'bugfix/flash_write_single_core' into 'master'
spi_flash: fix protection issues

This MR fixes the two spi_flash related issues:

- esp_intr_noniram_{disable,enable} not being protected by spi_flash_op_{lock,unlock} in single core mode. This caused a safety assert to be triggered in esp_intr_noniram_disable.

- spi_flash_unlock not being protected by spi_flash_guard_{start,end}. This caused a conflict between SPI0 and SPI1 controllers when accessing SPI flash, manifesting in cache data corruption and IllegalInstruction exceptions, for some flash chips.


See merge request !522
2017-02-22 14:17:40 +08:00
Ivan Grokhotkov
cbb71baca9 spi_flash: protect spi_flash_unlock
spi_flash_unlock was missing spi_flash_guard_start, which caused cache
to be enabled during unlock operation, causing hard-to-trace crashes
and cache data corruption.
2017-02-22 12:51:16 +08:00
Angus Gratton
045307ea0f Merge branch 'bugfix/make_config_problems' into 'master'
build system: Fix several make & configuration problems

Collection of quasi-related build system fixes:
* Fix issues with "make menuconfig" running twice when no existing sdkconfig
* Fix issues with menuconfig getting into a bad state if "make -jN" and no existing sdkconfig
* Hopefully fix intermittent issue with build system sometimes not picking up all config, leading to missing BT/WiFi libs at compile/link time.
* Fix issues with path resolution on Windows (including in Eclipse)
* Add new BATCH_BUILD variable for IDEs and automated build environments.

See merge request !485
2017-02-22 10:10:34 +08:00
Angus Gratton
f29768c404 Build system: Add new BATCH_BUILD flag to disable interactive parts of the build
Mostly useful for Eclipse (where accidentally running interactive
config hangs the build), but also good for CI and other automated
build systems.
2017-02-22 11:59:37 +11:00
Angus Gratton
c0f155f6ff kconfig: Ignore Windows host-compiled executables 2017-02-22 11:59:37 +11:00
Angus Gratton
8dede8f8a4 Eclipse: Process Windows paths correctly using cygpath
Includes splitting the Windows Eclipse setup doc into a separate page,
as it has so many additional steps.

Addresses github #17 and #166
https://github.com/espressif/esp-idf/issues/17
https://github.com/espressif/esp-idf/issues/166
2017-02-22 11:59:37 +11:00
Angus Gratton
d28ee9a25e build system: Account for Windows behaviour of make wildcard for some dirs
See github #166
2017-02-22 11:59:37 +11:00
Angus Gratton
c3544dc090 Build system: Fix error if librtc submodule not available to bootloader
Closes #220 https://github.com/espressif/esp-idf/issues/220
2017-02-22 11:59:37 +11:00
Angus Gratton
3c90032369 build system: Fix parallel & double menuconfig issues when sdkconfig missing
Fixes misbehaviour of default menuconfig when sdkconfig is missing.

(Either appearing twice, or breaking if make -jN is used.)
2017-02-22 11:58:49 +11:00
Angus Gratton
e91d436e45 build system: Probable fix for errors due to bad config bypassing components
See github #311 https://github.com/espressif/esp-idf/issues/311

Should fix weird compiler/linker bugs where config says something is
enabled, but build system says it is disabled.
Particularly noticeable when WiFi/BT libraries fail to
compile/link despite being enabled.

Underlying cause is configuration file regenerating, but component
Makefiles not reevaluating.

Entirely removes the idea that we don't need to generate config for some
targets (like 'clean'). We need valid config for these targets,
otherwise they don't know which files to clean (etc).
2017-02-22 11:58:49 +11:00
Angus Gratton
de28d3a655 Merge branch 'feature/partition_table_envvars' into 'master'
partition tables: Expand environment variables in gen_esp32part

Allows parametrizing partition table with (exported) make variables.

Merges PR #301 https://github.com/espressif/esp-idf/pull/301

See merge request !505
2017-02-22 07:22:04 +08:00
Ivan Grokhotkov
e76c187efb spi_flash: protect esp_intr_noniram_{disable,enable} in 1-core config
MR !441 (7c155ab) has fixed issue with esp_intr_noniram_{disable,enable}
calls not being properly protected by spi_flash_op_{lock,unlock}.
Unit test was added, but the unit test environment tests only dual-core
config. Similar issue was present in the code path for the single-core
config, where esp_intr_noniram_{disable,enable} calls were unprotected.

This change fixes the protection issue and updates the unit test to
run properly in single core config as well.

The issue with running unit tests for single core config will be
addressed in a separate MR.
2017-02-21 21:57:53 +08:00
Jeroen Domburg
e35ebbf813 Use THRESH_DMA_TRANS define everywhere, make code match "smaller or equal" description 2017-02-21 18:27:56 +08:00
Lourens Naudé
04f7d96623 Fix SPI read edges in spi_intr
Signed-off-by: Jeroen Domburg <jeroen@espressif.com>
2017-02-21 18:26:03 +08:00
Tian Hao
55693b1168 component/bt : add option to release about 30K from BT if BLE only
1. later BT/BLE will be separated by BT/BLE macro, but this option should use when user make sure that in BLE only mode.
2017-02-21 17:46:59 +08:00
Ivan Grokhotkov
26dec992eb deep sleep: add note about disabling WiFi and BT
This change adds a note to esp_deep_sleep that applications should disable WiFi and BT before going into deep sleep.
SNTP example is also updated.
2017-02-21 17:07:16 +08:00
Ivan Grokhotkov
d3fde5188e deep sleep: bring some registers into known state
In case WiFi/BT stack has been enabled but wasn’t disabled, some RTC
bits may be left enabled, causing increased current consumption.
This change returns some of the bits back to their default values.
2017-02-21 17:07:15 +08:00
Ivan Grokhotkov
3b583c150f bootloader: disconnect VRTC from SAR input in bootloader_random_disable
Bootloader enables SAR ADC in test mode to get some entropy for the RNG.
The bits which control the ADC test mux were not disabled, which caused
extra ~24uA current to be drawn from VRTC, increasing deep sleep current
consumption. This change disables relevant test mode bits in
bootloader_random_disable.
2017-02-21 17:07:15 +08:00
Ivan Grokhotkov
1405fd1fef Merge branch 'bugfix/exception_after_merge_phy_disable' into 'master'
bugfix: it causes exception that wifi interrupt happens when read/write flash, i…

…f pp_post() is on icache.

See merge request !518
2017-02-21 16:16:41 +08:00
Liu Zhi Fu
adfb289e81 Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf 2017-02-21 15:03:34 +08:00
XiaXiaotian
a51f378ecc bugfix: it causes exception that wifi interrupt happens when read/write flash, if pp_post() is on icache. 2017-02-21 14:25:34 +08:00
Jiang Jiang Jian
b5d1eb42b4 Merge branch 'feature/disable_phy_rf_when_disable_wifi_bt' into 'master'
disable PHY and RF when stop WiFi and disable BT

1. Add disable PHY and RF when WiFi and BT are both disabled(including call sniffer disable API).

2. Do not init PHY and RF when cpu start. Init PHY and RF when call Wifi or BT start APIs(including sniffer enable API).

3. Add a temporary lib: librtc_clk.a and will delete it when CPU frequency switching function is done.

4. Add an function to get OS tick rate.

5. Do not put the whole pp.a in iram0, only put lmac.o, ieee80211_misc.o, ets_time.o and wdev.o in iram0.

See merge request !510
2017-02-21 01:40:49 +08:00
XiaXiaotian
678ec0bd04 Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf into feature/disable_phy_rf_when_disable_wifi_bt 2017-02-21 01:20:48 +08:00
Tian Hao
12a7293b31 component/bt : add bluetooth status check
1. add bluetooth controller/host initialize status check
2. separate bluetooth controller task schedule loop from controller init
2017-02-21 01:05:37 +08:00
XiaXiaotian
bb0298bc71 coexist: enable coexist when wifi&bt are enabled, disable coexist when one of wifi&bt is disabled. 2017-02-20 23:53:25 +08:00
Yulong
abf87b000d component/bt:fixed the write ccc crash bug error 2017-02-20 08:50:02 -05:00
Ivan Grokhotkov
7eaf1c76dc Merge branch 'bugfix/vfat_open_append' into 'master'
Fix fopen() in “a” (append) mode

fopen() does not work when file is opened in “a” (append) mode

* Merges github PR #302 https://github.com/espressif/esp-idf/pull/302
* Closes #328 https://github.com/espressif/esp-idf/issues/328

See merge request !503
2017-02-20 13:32:32 +08:00
XiaXiaotian
770c2ade05 phy init: modify some comments 2017-02-20 10:44:40 +08:00
Angus Gratton
95b62ef980 Merge branch 'feature/doc_drivers' into 'master'
docs: Add missing peripheral driver docs (ADC, DAC, RTC I/O, I2S)

Plus some general driver doc related cleanup.

touch_pad docs to follow in a subsequent MR.

See merge request !508
2017-02-20 10:28:52 +08:00
Angus Gratton
4db4e28b6e uart driver docs: Remove references to setting interrupt number
Closes #185 https://github.com/espressif/esp-idf/issues/185
2017-02-20 10:39:29 +11:00
Angus Gratton
bfdfcbfaef docs: Add missing peripheral driver docs (ADC, DAC, RTC I/O, I2S) 2017-02-20 10:39:29 +11:00
Angus Gratton
21964a42fb rtc_gpio: Replace RTC_GPIO_IS_VALID_GPIO macro with inline function 2017-02-20 10:39:29 +11:00
Tian Hao
4bd5b0c91a component/bt : add bt enable/disable for power save
1. add new APIs bt controller enable/disab/deinit
2. make bt controller work need to call two APIs of esp_bt_controller_init and enable
3. modify phy init to make mac reset once
2017-02-17 19:24:58 +08:00
XiaXiaotian
8f3d1d3184 fix compile error that if enable CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION compile fail 2017-02-17 15:29:11 +08:00
Jiang Jiang Jian
4494e15ecf Merge branch 'feature/btdm_pll_track' into 'master'
component/bt : wide range work temperature for bluetooth RF

1. add PLL track for bluetooth RF for wide range temperature
2. move some initialized codes to cache

See merge request !511
2017-02-17 13:48:26 +08:00
Tian Hao
ad890aa5ea component/bt : wide range work temperature for bluetooth RF
1. add PLL track for bluetooth RF for wide range temperature
2. move some initialized codes to cache
2017-02-17 12:26:28 +08:00
XiaXiaotian
cd13c9e95d disable phy and rf
1. add a macro in menuconfig for users to choose whether store phy calibration data into NVS or not.

2. rename some disable phy and rf APIs so that existing code which calls old APIS will fail to compile.
2017-02-17 10:24:55 +08:00
XiaXiaotian
eb14284c92 disable PHY and RF when stop WiFi and disable BT
1. Add disable PHY and RF when WiFi and BT are both disabled(including call sniffer disable API).

2. Do not init PHY and RF when cpu start. Init PHY and RF when call Wifi or BT start APIs(including sniffer enable API).

3. Add a temporary lib: librtc_clk.a and will delete it when CPU frequency switching function is done.

4. Add an function to get OS tick rate.

5. Do not put the whole pp.a in iram0, only put lmac.o, ieee80211_misc.o, ets_time.o and wdev.o in iram0.
2017-02-17 10:24:54 +08:00
Jiang Jiang Jian
61c7bd3c3a Merge branch 'bugfix/btdm_gatt' into 'master'
component/bt : fix gatt write memory leak

fix bug of GATT write cause memory leak 

See merge request !506
2017-02-16 15:13:05 +08:00
Jiang Jiang Jian
6c139c8ffb Merge branch 'feature/ethernet_phy_power' into 'master'
ethernet: add a gpio to enable/disable phy power

ethernet board v2 use gpio 17 .

See merge request !495
2017-02-16 15:12:09 +08:00
Jiang Jiang Jian
997fbf9e18 Merge branch 'bugfix/btdm_iphone10_0_2' into 'master'
Bugfix/btdm iphone10 0 2

This connection error caused by iPhone, it think that TX data length must large than 27 when slave support EXTEND_DATA_LENGTH. But this should be allow. Besides,  the problem cannot be found on higher version of Iphone7, apple seemed to have fixed it.
Actually maybe other BLE device have the same problem.

See merge request !509
2017-02-16 15:10:50 +08:00
shangke
2fc4413dae ethernet: add pin macro 2017-02-16 14:36:46 +08:00
Tian Hao
6648ff427c component/bt : fix connection bug of Iphone7 10.0.2
This connection error caused by iPhone, it think that TX data length must large than 27 when slave support EXTEND_DATA_LENGTH. But this should be allow. Besides,  the problem cannot be found on higher version of Iphone7, apple seemed to have fixed it.
Actually maybe other BLE device have the same problem.
2017-02-16 14:15:46 +08:00
Tian Hao
5023e30a33 component/bt : fix gatt write memory leak 2017-02-15 20:08:39 +08:00
Angus Gratton
9cea5ea075 fatfs: Add unit test for overwrite/append fix 2017-02-15 18:04:28 +11:00
Ivan Grokhotkov
34d0b0086e Merge branch 'bugfix/openssl_server_example' into 'master'
Example 10_openssl_server should use TLSv1.2 instead of SSLv3; fixed corrupted HTTP Header

* Merges github PR #214 https://github.com/espressif/esp-idf/pull/214
* Closes #333 https://github.com/espressif/esp-idf/issues/333

See merge request !501
2017-02-15 14:34:08 +08:00
Angus Gratton
39c546d63f openssl_server example: Roll back to TLS_server_method() for compatibility
Add a comment recommending TLS v1.2.
2017-02-15 17:19:09 +11:00
Ivan Grokhotkov
413f05ce09 Merge branch 'docs/flash_encryption_disable' into 'master'
Docs: Document flash encryption disable steps, clean up flash encryption & secure boot docs

Generate clean up of flash encryption & secure boot docs

Including steps for disabling flash encryption (for people who accidentally enable it).

See merge request !500
2017-02-15 13:31:08 +08:00
Ivan Grokhotkov
578e93803a Merge branch 'bugfix/gperf_v3_1' into 'master'
kconfig: Remove gperf 3.1+ incompatible kconf_conf_id forward declaration

Forward declaration was unused. gperf 3.1+ changed parameter type from
'unsigned int' to 'size_t'.

Ref github #200 https://github.com/espressif/esp-idf/issues/200#issuecomment-279377753
Fixes #315 https://github.com/espressif/esp-idf/issues/315
Fixes #251 https://github.com/espressif/esp-idf/issues/251

See merge request !498
2017-02-15 13:29:18 +08:00
Ivan Grokhotkov
fe44bc9e79 Merge branch 'bugfix/add_espcoredump_to_add_paths_script' into 'master'
Add espcoredump to the add_path shell helper

Merges PR #335 https://github.com/espressif/esp-idf/pull/335


See merge request !504
2017-02-15 13:27:18 +08:00
Ivan Grokhotkov
174c313d3d Merge branch 'bugfix/send_crosscore_iram' into 'master'
esp32: Move esp_crosscore_int_send_yield() to IRAM

Merges PR #257 https://github.com/espressif/esp-idf/pull/257

See merge request !502
2017-02-15 13:26:56 +08:00
Ivan Grokhotkov
dd5401749d Merge branch 'bugfix/phy_init_write_nvs_once' into 'master'
phy_init: don’t rewrite valid calibration data

In the default PHY init routine, calibration data is loaded from NVS.
Most of the time the incremental changes to calibration will be fairly
small, so we don’t need to rewrite the existing calibration data stored
in the NVS.

Possible enhancement to be done in the future: expose a function in PHY
library to tell how big was the change in calibration data. If the
change was significant, then calibration data stored in NVS should be
updated.

See merge request !487
2017-02-15 13:26:22 +08:00
Ivan Grokhotkov
01c4a980ee Merge branch 'bugfix/fix_protection_of_queue_list' into 'master'
freertos: fix protection issue in freertos queue event list

When functions in queue.c calls listLIST_IS_EMPTY() to check queue event list, the queue list is
protected by queue mutex, on the other hand, when xTaskIncrementTick() modify the queue list, the
 queue list is protected by xTaskQueueMutex, this may cause xTaskRemoveFromEventList operate on
the empty queue list and cause problem.
This change works around the problem by reducing the window where the race condition can happen.

See merge request !465
2017-02-15 13:25:51 +08:00
Ivan Grokhotkov
25f05bef71 Merge branch 'bugfix/OTA_and_flash_encryption_incompatible' into 'master'
bootloader_support: fix bug OTA & flash encryption incompatible

github issue:https://github.com/espressif/esp-idf/issues/253

See merge request !464
2017-02-15 13:24:10 +08:00
Angus Gratton
24cfe78962 partition table: Fix comment at top of gen_esp32part.py 2017-02-15 10:28:45 +11:00
Angus Gratton
4c9fdb7c52 Docs: Mark PDF links as such in the documentation index
Nothing worse than clicking what you think is an internal page link
and finding a PDF downloading!
2017-02-15 09:42:46 +11:00
Angus Gratton
0eb5c06ad4 README: Add some tips on using menuconfig 2017-02-15 09:42:46 +11:00
Angus Gratton
7c7edab328 flash encryption/secure boot: Restructure documentation
Also add steps to disable flash encryption, as some people seem to
accidentally enable it.

Explicitly mark the flash encryption and secure boot as "READ DOCS
FIRST" in menuconfig.
2017-02-15 09:42:46 +11:00
Deomid Ryabkov
22c3877183 Expand environment variables in gen_esp32part
Allows parametrizing partition table with (exported) make variables.
2017-02-14 13:53:17 +08:00
nineisk
57af0d70d3 Fix fopen() in “a” (append) mode
fopen() does not work when file is opened in “a” (append) mode
2017-02-14 16:15:08 +11:00
Marcin Galczynski
10c2e984dc esp32: Move esp_crosscore_int_send_yield() to IRAM 2017-02-14 15:55:16 +11:00
Malte Janduda
dcd5c5bb73 Example 10_openssl_server should use TLSv1.2 instead of SSLv3; fixed corrupted HTTP Header 2017-02-14 15:38:37 +11:00
Angus Gratton
473f2cff51 kconfig: Remove gperf 3.1+ incompatible kconf_conf_id forward declaration
Forward declaration was unused. gperf 3.1+ changed parameter type from
'unsigned int' to 'size_t'.
2017-02-14 10:01:44 +11:00
Jiang Jiang Jian
a65944a8cb Merge branch 'bugfix/update_wifi_lib_to_include_some_fix_and_optimization' into 'master'
esp32: update wifi lib for some fixes and optimizations

1. Reduce the default static rx buffer size from 25 to 10
2. Adjust ampdu interrupt size to 3, namely, raise 1 interrupt per 3-mpdu
3. Make a copy for all received packets, including AMSDU/AMPDU/MPDU
4. Fix softap mis-forward issue
5. Fix pp q full issue
6. Fix sniffer copy wrong content issue

See merge request !491
2017-02-13 21:22:43 +08:00
Liu Zhi Fu
97eef61184 Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf 2017-02-13 17:39:53 +08:00
Jiang Jiang Jian
2664291ba5 Merge branch 'bugfix/btdm_blufi' into 'master'
fix BLUFI bug

fix BLUFI bug with small MTU size

See merge request !493
2017-02-13 14:52:46 +08:00
Jiang Jiang Jian
483411fd1a Merge branch 'bugfix/btdm_gatt_memleak' into 'master'
component/bt : fix GATT disconnect memory leak bug

fix a bug of memory leak of GATT disconnection

See merge request !496
2017-02-13 14:30:09 +08:00
Jiang Jiang Jian
554237bf5e Merge branch 'bugfix/btdm_demo_adv_raw_data' into 'master'
component/bt : use real adv data to set raw adv data

Use real advertising data to set raw advertising data in GATT-SERVER demo.

See merge request !492
2017-02-13 14:27:21 +08:00
Tian Hao
5fd7bd14db component/bt : fix GATT disconnect memory leak bug 2017-02-13 14:00:26 +08:00
Lourens Naudé
3aa2b571ae Add espcoredump to the add_path shell helper 2017-02-12 22:48:41 +00:00
shangke
e8b7670db3 ethernet: add doc 2017-02-11 16:42:16 +08:00
shangke
9893b71096 ethernet: add a gpio to enable/disable phy power 2017-02-11 15:19:53 +08:00
Tian Hao
cf917567e9 component/bt : use real adv data to set raw adv data 2017-02-10 16:40:40 +08:00
Tian Hao
2c334b46e0 component/bt : fix BLUFI bug with small MTU size 2017-02-10 11:20:34 +08:00
Liu Zhi Fu
0017e75bda freertos: fix protection issue in freertos queue event list
When functions in queue.c calls listLIST_IS_EMPTY() to check queue event list, the queue list is
protected by queue mutex, on the other hand, when xTaskIncrementTick() modify the queue list, the
 queue list is protected by xTaskQueueMutex, this may cause xTaskRemoveFromEventList operate on
the empty queue list and cause problem. This commit is to fix this bug.

may cause
2017-02-10 10:30:17 +08:00
Liu Zhi Fu
7093c59a74 esp32: update wifi lib for some fixes and optimizations
1. Reduce the default static rx buffer size from 25 to 10
2. Adjust ampdu interrupt size to 3, namely, raise 1 interrupt per 3-mpdu
3. Make a copy for all received packets, including AMSDU/AMPDU/MPDU
4. Fix softap mis-forward issue
5. Fix pp q full issue
6. Fix sniffer copy wrong content issue
2017-02-10 10:28:03 +08:00
Ivan Grokhotkov
02460ff864 Merge branch 'test/get_test_env_config_from_gitlab' into 'master'
CI: get test env config from gitlab

Previous design was put test env config on local runners. It's not easy to manage as test runners count growing. 

Now we'll put config files for test runners to a Gitlab repository. Test runners will get its config from Gitlab every time before running.

See merge request !480
2017-02-08 16:56:38 +08:00
Jeroen Domburg
c61fdff729 Merge branch 'bugfix/yield_other_core_prio_check_fix' into 'master'
Fix interrupting task on other CPU that has lower prio than current task on current CPU

Fix for a very subtle bug introduced somewhere in december. This bug would cause a cross-core interrupt to only be sent if the activated task has a higher priority than the task currently running on *this* cpu, instead of on the other CPU.

See merge request !475
2017-02-08 12:19:34 +08:00
Ivan Grokhotkov
777816cb99 phy_init: don’t rewrite valid calibration data
In the default PHY init routine, calibration data is loaded from NVS.
Most of the time the incremental changes to calibration will be fairly
small, so we don’t need to rewrite the existing calibration data stored
in the NVS.

Possible enhancement to be done in the future: expose a function in PHY
library to tell how big was the change in calibration data. If the
change was significant, then calibration data stored in NVS should be
updated.
2017-02-07 15:14:45 +08:00
Jiang Jiang Jian
89fea85a45 Merge branch 'bugfix/fix_several_wifi_misc_issues' into 'master'
esp32: fix several misc wifi issue

1. Fix ssid_str not free issue
2. Fix sniffer not work issue
3. Fix null parameter cause esp_wifi_init crash issue
4. Enable ap ampdu rx interface

See merge request !484
2017-02-07 11:15:58 +08:00
Liu Zhi Fu
b748a63a43 esp32: fix several misc wifi issue
1. Fix ssid_str not free issue
2. Fix sniffer not work issue
3. Fix null parameter cause esp_wifi_init crash issue
4. Enable ap ampdu rx interface
2017-02-06 17:56:42 +08:00
Jeroen Domburg
d07a149e2c Fix interrupting task on other CPU that has lower prio than current task on current CPU 2017-02-06 17:53:07 +08:00
Ivan Grokhotkov
c78aa138b0 Merge branch 'bugfix/esp32_core_dump_wd_uart' into 'master'
esp32: Fixes watchdog problem when printing core dump to uart

1) Fixes watchdog problem when printing core dump to uart
2) Also fixes generation of core dumps when flash cache is disabled


See merge request !472
2017-02-06 17:44:08 +08:00
Wu Jian Gang
e8adb5ab57 Merge branch 'bugfix/ethernet_flow_ctrl' into 'master'
ethernet:disable flow control when select l2_to_l3_copy_mode

Disable flow control when select l2_to_l3_copy_mode ,because this mode can not touch flow control watermark  .

See merge request !482
2017-02-06 13:42:18 +08:00
shangke
627bc23b1c ethernet:disable flow control when select l2_to_l3_copy_mode 2017-02-06 11:19:16 +08:00
Liu Zhi Fu
96e6839745 Merge branch 'master' of ssh://gitlab.espressif.cn:27227/idf/esp-idf 2017-02-05 15:34:36 +08:00
Angus Gratton
2d5162dc3c OTA: Always clean up OTA handle regardless of esp_ota_end() result
As reported on forum: http://esp32.com/viewtopic.php?f=14&t=1093
2017-02-03 10:07:30 +11:00
He Yin Ling
732a5fd0b2 CI: get test env config from gitlab
Previous design was put test env config on local runners. It's not easy
to manage as test runners count growing. Now we'll put config files for
test runners to a Gitlab repository. Test runners will get its config
from Gitlab every time before running.
2017-02-02 21:59:00 +08:00
Alexey Gerenkov
04acc88023 esp32: Fixes watchdog problem when printing core dump to uart
Also fixes generation of core dumps when flash cache is disabled
2017-02-01 18:39:28 +03:00
Ivan Grokhotkov
b8e2edc99f Merge branch 'bugfix/esp32_core_dump_esptool_search_path' into 'master'
esp32: Fixed search path for esptool

@igrokhotkov @angus Could you review the fix?

See merge request !474
2017-02-01 13:59:40 +08:00
Ivan Grokhotkov
f21275b910 Merge branch 'bugfix/esp32_core_dump_doc' into 'master'
esp32: Fixed and updated core dump docs



See merge request !473
2017-02-01 13:59:15 +08:00
Angus Gratton
0a678ebe8c Merge branch 'feature/openssl_option' into 'master'
components/openssl: refactor openssl debugging and assert function

1. add openssl option at menuconfig
2. remove SSL_ERR to reduce complexity
3. add more functions about debugging and assert

According these, our coders and customers may use and debug the OpenSSL code easily.


See merge request !400
2017-01-27 08:37:02 +08:00
Angus Gratton
21c7fc624a Merge branch 'bugfix/encrypted_partition_flag' into 'master'
Use PART_FLAG_ENCRYPTED value in gen_esp32part.py

Currently paritions marked as encrypted by gen_esp32part.py are not
recognized as such and encrypted writes don't work.

This is part of espressif/esp-idf#253

Merges Pull Request #293 https://github.com/espressif/esp-idf/pull/293

See merge request !470
2017-01-27 08:34:08 +08:00
Angus Gratton
aaa891ada9 Merge branch 'feature/custom_partition_table_csv_path' into 'master'
Allow providing custom PARTITION_TABLE_CSV_PATH

Provide direct absolute path to CSV, without project_path

Github pull request #296: https://github.com/espressif/esp-idf/pull/296

See merge request !469
2017-01-27 08:33:41 +08:00
Angus Gratton
a4c76671c2 Merge branch 'bugfix/spi_multiple_cs_fix' into 'master'
Add missing variable initialisation to make SPI work for multiple CS

Ref https://github.com/espressif/esp-idf/pull/277
From PR: "I am not especially familiar with this platform or with esp-idf -- so review with care.

The spi-master driver would not work for me when the number of devices on a bus exceeded 1 (caused device hang). I believe this is because cur_cs is not properly set (anywhere), and yet is used. This is likely just not noticed because 0 is presumably the correct value when there's only 1 device (and I'm guessing multi-device setup is not tested as thoroughly).

Simply setting cur_cs to the correct slot value resolves the problem and multiple devices on a single bus behave correctly in my test environment."

Looks like a small oversight on my side.

See merge request !468
2017-01-27 08:33:16 +08:00
Alexey Gerenkov
f512923791 esp32: Fixed search path for esptool 2017-01-26 19:28:13 +03:00
Alexey Gerenkov
e6f8837152 esp32: Fixed and updated core dump docs 2017-01-26 18:47:10 +03:00
Jiang Jiang Jian
5e3b30da3a Merge branch 'bugfix/fix_two_wifi_datapath_issues' into 'master'
esp32: udpate wifi lib to fix two datapath issues

1. fix ampdu<->mpdu<->ampdu switch may cause rx slow issue by put mpdu into ampdu reorder queue
2. fix each ac first sending always fail issue by adding retry

See merge request !471
2017-01-26 21:52:28 +08:00
Angus Gratton
b6a2329f0f FreeRTOS: esp_crosscore_int_send_yield() should be in IRAM
Possible for xQueueGenericSendFromISR -> xTaskRemoveFromEventQueueList
-> taskYIELD_OTHER_CORE code path to occur while cache is off.
2017-01-26 18:53:02 +11:00
Angus Gratton
eea2788f5a OTA: Fix issues with encrypted OTA
- OTA source can write non-16-byte multiples of data
- Assumption that empty ota_data is 0xFFFFFFFF untrue when encrypted
2017-01-26 18:52:35 +11:00
Liu Zhi Fu
385c61e183 esp32: udpate wifi lib to fix two datapath issues
1. fix ampdu<->mpdu<->ampdu switch may cause rx slow issue by put mpdu into ampdu reorder queue
2. fix each ac first sending always fail issue by adding retry
2017-01-26 15:35:04 +08:00
Liu Zhi Fu
39fe51924e esp32: update wifi lib to fix two datapath issues
1. fix ampdu<->mpdu<->ampdu switch may cause rx slow issue by put mpdu into ampdu reorder queue
2. fix each ac first sending always fail issue by adding retry
2017-01-26 15:33:23 +08:00
Angus Gratton
d8aae55eeb Flash encryption: Temporary fix for issue with stale cache reads
Seems doing certain kinds of short reads while flash encryption is
enabled will return stale data. This fixes it, but is probably a
little heavy-handed performance wise.
2017-01-26 18:29:18 +11:00
Angus Gratton
67336672bd OTA: Improve verification of OTA image before writing, incl. secure boot
Verify 0xE9 magic byte on first write, verify entire image before
switching.

Enable verification for secure boot signature (was using invalid ifdef
guard)
2017-01-26 16:20:06 +11:00
Angus Gratton
813395adcb OTA: Fall back to factory partition if ota data partition is invalid 2017-01-26 16:20:06 +11:00
Tian Zhong Xing
2173ad3b45 bootloader_support: fix bug OTA & flash encryption incompatible
ota data partition should be encrypted unconditionally when flash encrypt enable
2017-01-26 16:20:06 +11:00
Ivan Grokhotkov
4dd81fddd8 Merge branch 'feature/add_build_at_job_in_ci' into 'master'
CI: add job to check build esp-at in esp-idf

Add a job to check if latest IDF breaks `esp-at` build.

As `esp-at` is an application and has its own CI, we don't save binary as artifacts.

See merge request !462
2017-01-26 10:46:45 +08:00
Dong Heng
93395a3370 components/openssl: Add more debugging information at platform level 2017-01-26 10:12:58 +08:00
Deomid Ryabkov
4f7e4dd0f5 Use PART_FLAG_ENCRYPTED value in gen_esp32part.py
Currently paritions marked as encrypted by gen_esp32part.py are not
recognized as such and encrypted writes don't work.

This is part of espressif/esp-idf#253
2017-01-26 12:27:00 +11:00
Dermot Duffy
33500f2561 Add missing variable initialisation.
Signed-off-by: Jeroen Domburg <jeroen@espressif.com>
2017-01-25 21:41:45 +08:00
Jiang Jiang Jian
32ad1e676d Merge branch 'lwip/optimize_dhcpc_taken_time' into 'master'
lwip: optimize the dhcp client

1. modify the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s.
2. add DHCP_DOES_ARP_CHECK to menuconfig for users to specify if do a ARP check on the offered address.
   If enable, one more second will be taken.

See merge request !459
2017-01-25 21:39:17 +08:00
Ivan Grokhotkov
8e467801bc Merge branch 'bugfix/btdm_debug_gatt_attr_table' into 'master'
component/bt: Fix Gatt table read_req bug and advertising channel 39 not available bug

1. Fix Gatt table read request bug
2. Fix advertising channel 39 not available bug

See merge request !463
2017-01-25 11:48:09 +08:00
Island
c6bb239f0c component/bt: Fix Gatt table read_req bug and advertising channel 39 not available bug 2017-01-25 11:18:26 +08:00
Deomid Ryabkov
74f78540ae Allow providing custom PARTITION_TABLE_CSV_PATH
Provide direct absolute path to CSV, without project_path
2017-01-25 00:30:29 +00:00
Dong Heng
1d0c909daf components/openssl: fixes for github issues 219
"SSL_write" doesn't send large buffers correctly
2017-01-24 17:36:32 +08:00
He Yin Ling
d193424ae8 CI: add job to check build esp-at in esp-idf 2017-01-24 15:52:07 +08:00
qiyueixa
03e3b137bf lwip: optimize the dhcp client
1. modify the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s.
2. add DHCP_DOES_ARP_CHECK to menuconfig for users to specify if do a ARP check on the offered address.
   If enable, one more second will be taken in obtaining IP address.
3. update wifi libs
2017-01-23 13:44:34 +08:00
Dong Heng
905180667c components/openssl: refactor openssl debugging and assert function
1. add openssl option at menuconfig
2. remove SSL_ERR to reduce complexity
3. add more functions about debugging and assert

According these, our coders and customers may use and debug the OpenSSL code easily.
2017-01-17 10:15:26 +08:00
161 changed files with 4270 additions and 1514 deletions

View File

@@ -14,10 +14,11 @@ before_script:
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
# if testing master branch, use github wifi and bt libs.
# if testing other branches, use gitlab wifi and bt libs (as maybe changes aren't merged to master yet)
- test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-wifi-lib%${GITLAB_SSH_SERVER}/idf/esp32-wifi-lib%" .gitmodules
- test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-bt-lib%${GITLAB_SSH_SERVER}/idf/esp32-bt-lib%" .gitmodules
# Set IS_PRIVATE or IS_PUBLIC depending on if our branch is public or not
#
# (the same regular expressions are used to set these are used in 'only:' sections below
- source make/configure_ci_environment.sh
# fetch all submodules
- git submodule update --init --recursive
@@ -31,6 +32,7 @@ build_template_app:
SDK_PATH: "$CI_PROJECT_DIR"
IDF_PATH: "$CI_PROJECT_DIR"
GIT_STRATEGY: clone
BATCH_BUILD: "1"
script:
- git clone https://github.com/espressif/esp-idf-template.git
@@ -39,13 +41,11 @@ build_template_app:
# using on esp-idf. If it doesn't exist then just stick to the default
# branch
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
- make defconfig
# Test debug build (default)
- make all V=1
# Now test release build
- make clean
- sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig
- make defconfig
- make all V=1
# Check if there are any stray printf/ets_printf references in WiFi libs
- cd ../components/esp32/lib
@@ -63,6 +63,8 @@ build_template_app:
SDK_PATH: "$CI_PROJECT_DIR"
IDF_PATH: "$CI_PROJECT_DIR"
GIT_STRATEGY: clone
BATCH_BUILD: "1"
build_ssc:
<<: *build_template
@@ -79,6 +81,15 @@ build_ssc:
- chmod +x gen_misc_ng.sh
- ./gen_misc_ng.sh
build_at:
<<: *build_template
script:
- git clone $GITLAB_SSH_SERVER/application/esp-at.git
- cd esp-at
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-at default branch..."
- make defconfig
- make
build_esp_idf_tests:
<<: *build_template
artifacts:
@@ -94,7 +105,6 @@ build_esp_idf_tests:
script:
- cd tools/unit-test-app
- git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..."
- make defconfig
- make TESTS_ALL=1
- python UnitTestParser.py
@@ -124,7 +134,7 @@ build_docs:
- cd docs
- doxygen
# If not building master branch, and there are Doxygen warnings, print them and bail out
- test "${CI_BUILD_REF_NAME}" = "master" || test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
- test -n $IS_PRIVATE && test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
- make gh-linkcheck
- make html
artifacts:
@@ -150,6 +160,7 @@ test_build_system:
variables:
IDF_PATH: "$CI_PROJECT_DIR"
script:
- ./make/test_configure_ci_environment.sh
- ./make/test_build_system.sh
test_report:
@@ -158,6 +169,8 @@ test_report:
only:
- master
- triggers
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
tags:
- report
variables:
@@ -207,13 +220,15 @@ push_master_to_github:
stage: deploy
only:
- master
- /^release\/v.*$/
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
tags:
- deploy
when: on_success
image: espressif/esp32-ci-env
variables:
GIT_STRATEGY: clone
GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master
script:
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
@@ -222,7 +237,14 @@ push_master_to_github:
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
- git remote add github git@github.com:espressif/esp-idf.git
- git push --follow-tags github HEAD:master
# What the next line of script does: goes through the list of refs for all branches we push to github,
# generates a snippet of shell which is evaluated. The snippet checks CI_BUILD_REF against the SHA
# (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch
# and then pushes that ref to a corresponding github branch
#
# NB: In gitlab 9.x, CI_BUILD_REF was deprecated. New name is CI_COMMIT_REF. If below command suddenly
# generates bash syntax errors, this is probably why.
- eval $(git for-each-ref --shell bash --format 'if [ $CI_BUILD_REF == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS)
deploy_docs:
@@ -231,7 +253,8 @@ deploy_docs:
stage: deploy
only:
- master
- /^release\/v.*$/
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
- triggers
tags:
- deploy
@@ -278,12 +301,13 @@ check_doc_links:
when: on_success
only:
- master
- /^release\/v/
- /^v\d+\.\d+(\.\d+)?($|-)/
- triggers
allow_failure: true
variables:
# LOCAL_ENV_CONFIG_PATH: define in template and jobs can overwrite if required
LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF
LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF
BIN_PATH: "$CI_PROJECT_DIR/SSC/ssc_bin/SSC"
APP_NAME: "ssc"
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
@@ -308,9 +332,12 @@ check_doc_links:
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
# clone local test env configs
- git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git
# clone test bench
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- cd auto_test_script
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using default branch..."
# run test
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH
@@ -333,9 +360,12 @@ check_doc_links:
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
# clone local test env configs
- git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git
# clone test bench
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
- cd auto_test_script
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using default branch..."
# run test
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH
@@ -346,14 +376,13 @@ check_doc_links:
stage: unit_test
variables:
# jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF
LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF
BIN_PATH: "$CI_PROJECT_DIR/tools/unit-test-app/build/"
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
APP_NAME: "ut"
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/ModuleDefinition.yml"
dependencies:
- build_esp_idf_tests

View File

@@ -24,6 +24,16 @@ Once you've found the project you want to work with, change to its directory and
`make menuconfig`
* Opens a text-based configuration menu for the project.
* Use up & down arrow keys to navigate the menu.
* Use Enter key to go into a submenu, Escape key to go out or to exit.
* Type `?` to see a help screen. Enter key exits the help screen.
* Use Space key, or `Y` and `N` keys to enable (Yes) and disable (No) configuration items with checkboxes "`[*]`"
* Pressing `?` while highlighting a configuration item displays help about that item.
* Type `/` to search the configuration items.
Once done configuring, press Escape multiple times to exit and say "Yes" to save the new configuration when prompted.
## Compiling the Project
`make all`
@@ -59,7 +69,7 @@ After the initial flash, you may just want to build and flash just your app, not
`make app-flash` will automatically rebuild the app if it needs it.
(There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
## Parallel Builds

View File

@@ -9,7 +9,7 @@
if [ -z ${IDF_PATH} ]; then
echo "IDF_PATH must be set before including this script."
else
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/partition_table/"
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/espcoredump:${IDF_PATH}/components/partition_table/"
export PATH="${PATH}:${IDF_ADD_PATHS_EXTRAS}"
echo "Added to PATH: ${IDF_ADD_PATHS_EXTRAS}"
fi

View File

@@ -27,6 +27,7 @@
#include "esp_spi_flash.h"
#include "esp_image_format.h"
#include "esp_secure_boot.h"
#include "esp_flash_encrypt.h"
#include "sdkconfig.h"
#include "esp_ota_ops.h"
@@ -44,6 +45,10 @@ typedef struct ota_ops_entry_ {
esp_partition_t part;
uint32_t erased_size;
uint32_t wrote_size;
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
uint8_t partial_bytes;
uint8_t partial_data[16];
#endif
LIST_ENTRY(ota_ops_entry_) entries;
} ota_ops_entry_t;
@@ -106,6 +111,7 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
{
const uint8_t *data_bytes = (const uint8_t *)data;
esp_err_t ret;
ota_ops_entry_t *it;
@@ -119,7 +125,47 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
if (it->handle == handle) {
// must erase the partition before writing to it
assert(it->erased_size > 0 && "must erase the partition before writing to it");
ret = esp_partition_write(&it->part, it->wrote_size, data, size);
if(it->wrote_size == 0 && size > 0 && data_bytes[0] != 0xE9) {
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
return ESP_ERR_OTA_VALIDATE_FAILED;
}
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
if (esp_flash_encryption_enabled()) {
/* Can only write 16 byte blocks to flash, so need to cache anything else */
size_t copy_len;
/* check if we have partially written data from earlier */
if (it->partial_bytes != 0) {
copy_len = OTA_MIN(16 - it->partial_bytes, size);
memcpy(it->partial_data + it->partial_bytes, data_bytes, copy_len);
it->partial_bytes += copy_len;
if (it->partial_bytes != 16) {
return ESP_OK; /* nothing to write yet, just filling buffer */
}
/* write 16 byte to partition */
ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16);
if (ret != ESP_OK) {
return ret;
}
it->partial_bytes = 0;
memset(it->partial_data, 0xFF, 16);
it->wrote_size += 16;
data_bytes += copy_len;
size -= copy_len;
}
/* check if we need to save trailing data that we're about to write */
it->partial_bytes = size % 16;
if (it->partial_bytes != 0) {
size -= it->partial_bytes;
memcpy(it->partial_data, data_bytes + size, it->partial_bytes);
}
}
#endif
ret = esp_partition_write(&it->part, it->wrote_size, data_bytes, size);
if(ret == ESP_OK){
it->wrote_size += size;
}
@@ -135,26 +181,11 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
esp_err_t esp_ota_end(esp_ota_handle_t handle)
{
ota_ops_entry_t *it;
size_t image_size;
esp_err_t ret = ESP_OK;
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
if (it->handle == handle) {
// an ota handle need to be ended after erased and wrote data in it
if ((it->erased_size == 0) || (it->wrote_size == 0)) {
return ESP_ERR_INVALID_ARG;
}
#ifdef CONFIG_SECUREBOOTLOADER
esp_err_t ret;
size_t image_size;
if (esp_image_basic_verify(it->part.address, &image_size) != ESP_OK) {
return ESP_ERR_OTA_VALIDATE_FAILED;
}
ret = esp_secure_boot_verify_signature(it->part.address, image_size);
if (ret != ESP_OK) {
return ESP_ERR_OTA_VALIDATE_FAILED;
}
#endif
LIST_REMOVE(it, entries);
break;
}
}
@@ -163,8 +194,44 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
return ESP_ERR_NOT_FOUND;
}
/* 'it' holds the ota_ops_entry_t for 'handle' */
// esp_ota_end() is only valid if some data was written to this handle
if ((it->erased_size == 0) || (it->wrote_size == 0)) {
ret = ESP_ERR_INVALID_ARG;
goto cleanup;
}
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
if (it->partial_bytes > 0 && esp_flash_encryption_enabled()) {
/* Write out last 16 bytes, if necessary */
ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16);
if (ret != ESP_OK) {
ret = ESP_ERR_INVALID_STATE;
goto cleanup;
}
it->wrote_size += 16;
it->partial_bytes = 0;
}
#endif
if (esp_image_basic_verify(it->part.address, true, &image_size) != ESP_OK) {
ret = ESP_ERR_OTA_VALIDATE_FAILED;
goto cleanup;
}
#ifdef CONFIG_SECURE_BOOT_ENABLED
ret = esp_secure_boot_verify_signature(it->part.address, image_size);
if (ret != ESP_OK) {
ret = ESP_ERR_OTA_VALIDATE_FAILED;
goto cleanup;
}
#endif
cleanup:
LIST_REMOVE(it, entries);
free(it);
return ESP_OK;
return ret;
}
static uint32_t ota_select_crc(const ota_select *s)
@@ -271,11 +338,9 @@ static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
}
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
} else if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
} else {
return ESP_ERR_OTA_SELECT_INFO_INVALID;
/* Both OTA slots are invalid, probably because unformatted... */
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
}
} else {
@@ -285,17 +350,18 @@ static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
{
size_t image_size;
const esp_partition_t *find_partition = NULL;
if (partition == NULL) {
return ESP_ERR_INVALID_ARG;
}
#ifdef CONFIG_SECUREBOOTLOADER
size_t image_size;
if (esp_image_basic_verify(partition->address, &image_size) != ESP_OK) {
if (esp_image_basic_verify(partition->address, true, &image_size) != ESP_OK) {
return ESP_ERR_OTA_VALIDATE_FAILED;
}
ret = esp_secure_boot_verify_signature(partition->address, image_size);
#ifdef CONFIG_SECURE_BOOT_ENABLED
esp_err_t ret = esp_secure_boot_verify_signature(partition->address, image_size);
if (ret != ESP_OK) {
return ESP_ERR_OTA_VALIDATE_FAILED;
}
@@ -349,33 +415,34 @@ const esp_partition_t *esp_ota_get_boot_partition(void)
}
ota_app_count = get_ota_partition_count();
ESP_LOGD(TAG, "found ota bin max = %d", ota_app_count);
ESP_LOGD(TAG, "found ota app max = %d", ota_app_count);
if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
ESP_LOGD(TAG, "finding factory bin......");
ESP_LOGD(TAG, "finding factory app......");
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
} else if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
ESP_LOGD(TAG, "finding ota_%d bin......", \
ESP_LOGD(TAG, "finding ota_%d app......", \
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count));
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count), NULL);
} else if (ota_select_valid(&s_ota_select[0])) {
ESP_LOGD(TAG, "finding ota_%d bin......", \
ESP_LOGD(TAG, "finding ota_%d app......", \
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count);
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count, NULL);
} else if (ota_select_valid(&s_ota_select[1])) {
ESP_LOGD(TAG, "finding ota_%d bin......", \
ESP_LOGD(TAG, "finding ota_%d app......", \
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count);
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL);
} else {
ESP_LOGE(TAG, "not found current bin");
return NULL;
ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory");
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
}
}

View File

@@ -73,11 +73,16 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
/**
* @brief Finish the update and validate written data
*
* @param handle Handle obtained from esp_ota_begin
* @param handle Handle obtained from esp_ota_begin.
*
* @return:
* - ESP_OK: if validate ota image pass
* - ESP_ERR_OTA_VALIDATE_FAILED: validate the ota image is invalid
* @note After calling esp_ota_end(), the handle is no longer valid and any memory associated with it is freed (regardless of result).
*
* @return:
* - ESP_OK: Newly written OTA app image is valid.
* - ESP_ERR_NOT_FOUND: OTA handle was not found.
* - ESP_ERR_INVALID_ARG: Handle was never written to.
* - ESP_ERR_OTA_VALIDATE_FAILED: OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.)
* - ESP_ERR_INVALID_STATE: If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash.
*/
esp_err_t esp_ota_end(esp_ota_handle_t handle);

View File

@@ -35,16 +35,16 @@ endmenu
menu "Security features"
config SECURE_BOOT_ENABLED
bool "Enable secure boot in bootloader"
bool "Enable secure boot in bootloader (READ DOCS FIRST)"
default N
help
Build a bootloader which enables secure boot on first boot.
Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition table or boot an app if the data has a verified digital signature.
Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition table or boot an app if the data has a verified digital signature. There are implications for reflashing updated apps once secure boot is enabled.
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
See docs/security/secure-boot.rst for details.
Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
choice SECURE_BOOTLOADER_MODE
bool "Secure bootloader mode"
@@ -108,7 +108,7 @@ config SECURE_BOOT_VERIFICATION_KEY
PEM formatted private key using the espsecure.py
extract_public_key command.
See docs/security/secure-boot.rst for details.
Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
config SECURE_BOOT_INSECURE
bool "Allow potentially insecure options"
@@ -119,16 +119,18 @@ config SECURE_BOOT_INSECURE
Only enable these options if you are very sure.
Refer to docs/security/secure-boot.rst and docs/security/flash-encryption.rst for details.
Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
config FLASH_ENCRYPTION_ENABLED
bool "Enable flash encryption on boot"
bool "Enable flash encryption on boot (READ DOCS FIRST)"
default N
help
If this option is set, flash contents will be encrypted by the bootloader on first boot.
Note: After first boot, the system will be permanently encrypted.
See docs/securityflash-encryption.rst for details.
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
system is complicated and not always possible.
Read http://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html before enabling.
config FLASH_ENCRYPTION_INSECURE
bool "Allow potentially insecure options"

View File

@@ -0,0 +1,4 @@
# Submodules normally added in component.mk, but fully qualified
# paths can be added at this level (we need binary librtc to be
# available to link bootloader).
COMPONENT_SUBMODULES += $(IDF_PATH)/components/esp32/lib

View File

@@ -323,12 +323,15 @@ void bootloader_main()
} else {
if(ota_select_valid(&sa) && ota_select_valid(&sb)) {
load_part_pos = bs.ota[(((sa.ota_seq > sb.ota_seq)?sa.ota_seq:sb.ota_seq) - 1)%bs.app_count];
}else if(ota_select_valid(&sa)) {
} else if(ota_select_valid(&sa)) {
load_part_pos = bs.ota[(sa.ota_seq - 1) % bs.app_count];
}else if(ota_select_valid(&sb)) {
} else if(ota_select_valid(&sb)) {
load_part_pos = bs.ota[(sb.ota_seq - 1) % bs.app_count];
}else {
ESP_LOGE(TAG, "ota data partition info error");
} else if (bs.factory.offset != 0) {
ESP_LOGE(TAG, "ota data partition invalid, falling back to factory");
load_part_pos = bs.factory;
} else {
ESP_LOGE(TAG, "ota data partition invalid and no factory, can't boot");
return;
}
}

View File

@@ -14,10 +14,10 @@ COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SC
COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS)
ifdef IS_BOOTLOADER_BUILD
# following lines are a workaround to link librtc into the
# bootloader, until clock setting code is in a source-based esp-idf
# component. See also rtc_printf() in bootloader_start.c
COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc
#
# See also matching COMPONENT_SUBMODULES line in Makefile.projbuild
COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc_clk -lrtc
COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/
endif

View File

@@ -15,14 +15,17 @@
#define __ESP32_FLASH_ENCRYPT_H
#include <stdbool.h>
#include <esp_err.h>
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_spi_flash.h"
#include "soc/efuse_reg.h"
/* Support functions for flash encryption features.
Can be compiled as part of app or bootloader code.
*/
/**
* @file esp_partition.h
* @brief Support functions for flash encryption features
*
* Can be compiled as part of app or bootloader code.
*/
/** @brief Is flash encryption currently enabled in hardware?
*
@@ -30,9 +33,17 @@
*
* @return true if flash encryption is enabled.
*/
static inline bool esp_flash_encryption_enabled(void) {
static inline IRAM_ATTR bool esp_flash_encryption_enabled(void) {
uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT);
return __builtin_parity(flash_crypt_cnt) == 1;
/* __builtin_parity is in flash, so we calculate parity inline */
bool enabled = false;
while(flash_crypt_cnt) {
if (flash_crypt_cnt & 1) {
enabled = !enabled;
}
flash_crypt_cnt >>= 1;
}
return enabled;
}
/* @brief Update on-device flash encryption

View File

@@ -16,6 +16,7 @@
#include <bootloader_flash.h>
#include <esp_log.h>
#include <esp_spi_flash.h> /* including in bootloader for error values */
#include <esp_flash_encrypt.h>
#ifndef BOOTLOADER_BUILD
/* Normal app version maps to esp_spi_flash.h operations...
@@ -48,7 +49,11 @@ void bootloader_munmap(const void *mapping)
esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_decrypt)
{
return spi_flash_read(src, dest, size);
if (allow_decrypt && esp_flash_encryption_enabled()) {
return spi_flash_read_encrypted(src, dest, size);
} else {
return spi_flash_read(src, dest, size);
}
}
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)

View File

@@ -62,6 +62,11 @@ void bootloader_fill_random(void *buffer, size_t length)
void bootloader_random_enable(void)
{
/* Ensure the hardware RNG is enabled following a soft reset. This should always be the case already (this clock is
never disabled while the CPU is running), this is a "belts and braces" type check.
*/
SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_RNG_EN);
/* Enable SAR ADC in test mode to feed ADC readings of the 1.1V
reference via I2S into the RNG entropy input.
@@ -135,4 +140,8 @@ void bootloader_random_disable(void)
/* Reset i2s peripheral */
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
/* Disable pull supply voltage to SAR ADC */
CLEAR_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC);
SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 0, RTC_CNTL_DTEST_RTC_S);
}

View File

@@ -285,6 +285,9 @@ static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partit
} else {
should_encrypt = false;
}
} else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) {
/* check if we have ota data partition and the partition should be encrypted unconditionally */
should_encrypt = true;
}
if (!should_encrypt) {

View File

@@ -17,6 +17,15 @@ config BLUEDROID_MEM_DEBUG
help
Bluedroid memory debug
config BT_DRAM_RELEASE
bool "Release DRAM from Classic BT controller"
depends on BT_ENABLED
default n
help
This option should only be used when BLE only.
Open this option will release about 30K DRAM from Classic BT.
The released DRAM will be used as system heap memory.
# Memory reserved at start of DRAM for Bluetooth stack
config BT_RESERVE_DRAM
hex

View File

@@ -16,15 +16,16 @@
#include "esp_bt_main.h"
#include "btc_task.h"
#include "btc_main.h"
#include "bt.h"
#include "future.h"
static bool esp_already_enable = false;
static bool esp_already_init = false;
static bool bd_already_enable = false;
static bool bd_already_init = false;
esp_bluedroid_status_t esp_bluedroid_get_status(void)
{
if (esp_already_init) {
if (esp_already_enable) {
if (bd_already_init) {
if (bd_already_enable) {
return ESP_BLUEDROID_STATUS_ENABLED;
} else {
return ESP_BLUEDROID_STATUS_INITIALIZED;
@@ -39,15 +40,20 @@ esp_err_t esp_bluedroid_enable(void)
btc_msg_t msg;
future_t **future_p;
if (esp_already_enable) {
LOG_ERROR("%s already enable\n", __func__);
if (!bd_already_init) {
LOG_ERROR("Bludroid not initialised\n");
return ESP_ERR_INVALID_STATE;
}
if (bd_already_enable) {
LOG_ERROR("Bluedroid already enabled\n");
return ESP_ERR_INVALID_STATE;
}
future_p = btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE);
*future_p = future_new();
if (*future_p == NULL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid enable failed\n");
return ESP_ERR_NO_MEM;
}
@@ -57,11 +63,11 @@ esp_err_t esp_bluedroid_enable(void)
btc_transfer_context(&msg, NULL, 0, NULL);
if (future_await(*future_p) == FUTURE_FAIL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid enable failed\n");
return ESP_FAIL;
}
esp_already_enable = true;
bd_already_enable = true;
return ESP_OK;
}
@@ -71,15 +77,15 @@ esp_err_t esp_bluedroid_disable(void)
btc_msg_t msg;
future_t **future_p;
if (!esp_already_enable) {
LOG_ERROR("%s already disable\n", __func__);
if (!bd_already_enable) {
LOG_ERROR("Bluedroid already disabled\n");
return ESP_ERR_INVALID_STATE;
}
future_p = btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE);
*future_p = future_new();
if (*future_p == NULL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid disable failed\n");
return ESP_ERR_NO_MEM;
}
@@ -89,11 +95,11 @@ esp_err_t esp_bluedroid_disable(void)
btc_transfer_context(&msg, NULL, 0, NULL);
if (future_await(*future_p) == FUTURE_FAIL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid disable failed\n");
return ESP_FAIL;
}
esp_already_enable = false;
bd_already_enable = false;
return ESP_OK;
}
@@ -103,15 +109,20 @@ esp_err_t esp_bluedroid_init(void)
btc_msg_t msg;
future_t **future_p;
if (esp_already_init) {
LOG_ERROR("%s already init\n", __func__);
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
LOG_ERROR("Conroller not initialised\n");
return ESP_ERR_INVALID_STATE;
}
if (bd_already_init) {
LOG_ERROR("Bluedroid already initialised\n");
return ESP_ERR_INVALID_STATE;
}
future_p = btc_main_get_future_p(BTC_MAIN_INIT_FUTURE);
*future_p = future_new();
if (*future_p == NULL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid initialise failed\n");
return ESP_ERR_NO_MEM;
}
@@ -123,11 +134,11 @@ esp_err_t esp_bluedroid_init(void)
btc_transfer_context(&msg, NULL, 0, NULL);
if (future_await(*future_p) == FUTURE_FAIL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid initialise failed\n");
return ESP_FAIL;
}
esp_already_init = true;
bd_already_init = true;
return ESP_OK;
}
@@ -138,15 +149,20 @@ esp_err_t esp_bluedroid_deinit(void)
btc_msg_t msg;
future_t **future_p;
if (!esp_already_init) {
LOG_ERROR("%s already deinit\n", __func__);
if (!bd_already_init) {
LOG_ERROR("Bluedroid already de-initialised\n");
return ESP_ERR_INVALID_STATE;
}
if (bd_already_enable) {
LOG_ERROR("Bludroid already enabled, do disable first\n");
return ESP_ERR_INVALID_STATE;
}
future_p = btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE);
*future_p = future_new();
if (*future_p == NULL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid de-initialise failed\n");
return ESP_ERR_NO_MEM;
}
@@ -156,15 +172,14 @@ esp_err_t esp_bluedroid_deinit(void)
btc_transfer_context(&msg, NULL, 0, NULL);
if (future_await(*future_p) == FUTURE_FAIL) {
LOG_ERROR("%s failed\n", __func__);
LOG_ERROR("Bluedroid de-initialise failed\n");
return ESP_FAIL;
}
btc_deinit();
esp_already_init = false;
bd_already_init = false;
return ESP_OK;
}

View File

@@ -142,6 +142,27 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_
return ESP_ERR_INVALID_STATE;
}
/* parameter validation check */
if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){
if (char_val == NULL){
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_val should not be NULL here\n",\
__func__, __LINE__);
return ESP_ERR_INVALID_ARG;
} else if (char_val->attr_max_len == 0){
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\
__func__, __LINE__);
return ESP_ERR_INVALID_ARG;
}
}
if (char_val != NULL){
if (char_val->attr_len > char_val->attr_max_len){
LOG_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\
__func__, __LINE__, char_val->attr_len, char_val->attr_max_len);
return ESP_ERR_INVALID_ARG;
}
}
memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GATTS;
@@ -175,6 +196,29 @@ esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
/* parameter validation check */
if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){
if (char_descr_val == NULL){
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_descr_val should not be NULL here\n",\
__func__, __LINE__);
return ESP_ERR_INVALID_ARG;
}
else if (char_descr_val->attr_max_len == 0){
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\
__func__, __LINE__);
return ESP_ERR_INVALID_ARG;
}
}
if (char_descr_val != NULL){
if (char_descr_val->attr_len > char_descr_val->attr_max_len){
LOG_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\
__func__, __LINE__, char_descr_val->attr_len, char_descr_val->attr_max_len);
return ESP_ERR_INVALID_ARG;
}
}
memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
msg.sig = BTC_SIG_API_CALL;

View File

@@ -46,6 +46,8 @@ typedef enum {
ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */
ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */
ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */
ESP_GAP_BLE_ADV_START_COMPLETE_EVT, /*!< When start advertising complete, the event comes */
ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, /*!< When start scan complete, the event comes */
} esp_gap_ble_cb_event_t;
/// Advertising data maximum length
@@ -95,7 +97,7 @@ typedef enum {
typedef enum {
ADV_CHNL_37 = 0x01,
ADV_CHNL_38 = 0x02,
ADV_CHNL_39 = 0x03,
ADV_CHNL_39 = 0x04,
ADV_CHNL_ALL = 0x07,
} esp_ble_adv_channel_t;
@@ -284,6 +286,18 @@ typedef union {
struct ble_scan_rsp_data_raw_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */
} scan_rsp_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_ADV_START_COMPLETE_EVT
*/
struct ble_adv_start_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate advertising start operation success status */
} adv_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_START_COMPLETE_EVT */
/**
* @brief ESP_GAP_BLE_SCAN_START_COMPLETE_EVT
*/
struct ble_scan_start_cmpl_evt_param {
esp_bt_status_t status; /*!< Indicate scan start operation success status */
} scan_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_START_COMPLETE_EVT */
} esp_ble_gap_cb_param_t;
/**

View File

@@ -4534,12 +4534,11 @@ void bta_dm_ble_observe (tBTA_DM_MSG *p_data)
bta_dm_search_cb.p_scan_cback = p_data->ble_observe.p_cback;
if ((status = BTM_BleObserve(TRUE, p_data->ble_observe.duration,
bta_dm_observe_results_cb, bta_dm_observe_cmpl_cb)) != BTM_CMD_STARTED) {
tBTA_DM_SEARCH data;
APPL_TRACE_WARNING(" %s BTM_BleObserve failed. status %d\n", __FUNCTION__, status);
data.inq_cmpl.num_resps = 0;
if (bta_dm_search_cb.p_scan_cback) {
bta_dm_search_cb.p_scan_cback(BTA_DM_INQ_CMPL_EVT, &data);
}
}
if (p_data->ble_observe.p_start_scan_cback) {
status = (status == BTM_CMD_STARTED ? BTA_SUCCESS : BTA_FAILURE);
p_data->ble_observe.p_start_scan_cback(status);
}
} else {
bta_dm_search_cb.p_scan_cback = NULL;
@@ -4576,13 +4575,21 @@ void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
*******************************************************************************/
void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
{
BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
tBTA_STATUS status = BTA_FAILURE;
if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
p_data->ble_set_adv_params_all.adv_int_max,
p_data->ble_set_adv_params_all.adv_type,
p_data->ble_set_adv_params_all.addr_type_own,
p_data->ble_set_adv_params_all.p_dir_bda,
p_data->ble_set_adv_params_all.channel_map,
p_data->ble_set_adv_params_all.adv_filter_policy);
p_data->ble_set_adv_params_all.adv_filter_policy) == BTM_SUCCESS) {
status = BTA_SUCCESS;
}
if (p_data->ble_set_adv_params_all.p_start_adv_cback) {
(*p_data->ble_set_adv_params_all.p_start_adv_cback)(status);
}
}
/*******************************************************************************

View File

@@ -1009,7 +1009,7 @@ void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own,
tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol,
tBLE_BD_ADDR *p_dir_bda)
tBLE_BD_ADDR *p_dir_bda, tBTA_START_ADV_CMPL_CBACK p_start_adv_cb)
{
#if BLE_INCLUDED == TRUE
tBTA_DM_API_BLE_ADV_PARAMS_ALL *p_msg;
@@ -1029,6 +1029,7 @@ void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
p_msg->addr_type_own = addr_type_own;
p_msg->channel_map = chnl_map;
p_msg->adv_filter_policy = adv_fil_pol;
p_msg->p_start_adv_cback = p_start_adv_cb;
if (p_dir_bda != NULL) {
p_msg->p_dir_bda = (tBLE_BD_ADDR *)(p_msg + 1);
memcpy(p_msg->p_dir_bda, p_dir_bda, sizeof(tBLE_BD_ADDR));
@@ -2127,7 +2128,8 @@ void BTA_DmCloseACL(BD_ADDR bd_addr, BOOLEAN remove_dev, tBTA_TRANSPORT transpor
**
*******************************************************************************/
extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration,
tBTA_DM_SEARCH_CBACK *p_results_cb)
tBTA_DM_SEARCH_CBACK *p_results_cb,
tBTA_START_SCAN_CMPL_CBACK *p_start_scan_cb)
{
tBTA_DM_API_BLE_OBSERVE *p_msg;
@@ -2140,6 +2142,7 @@ extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration,
p_msg->start = start;
p_msg->duration = duration;
p_msg->p_cback = p_results_cb;
p_msg->p_start_scan_cback = p_start_scan_cb;
bta_sys_sendmsg(p_msg);
}

View File

@@ -471,7 +471,8 @@ typedef struct {
BT_HDR hdr;
BOOLEAN start;
UINT16 duration;
tBTA_DM_SEARCH_CBACK *p_cback;
tBTA_DM_SEARCH_CBACK *p_cback;
tBTA_START_SCAN_CMPL_CBACK *p_start_scan_cback;
} tBTA_DM_API_BLE_OBSERVE;
typedef struct {
@@ -506,6 +507,7 @@ typedef struct {
tBTM_BLE_ADV_CHNL_MAP channel_map;
tBTM_BLE_AFP adv_filter_policy;
tBLE_BD_ADDR *p_dir_bda;
tBTA_START_ADV_CMPL_CBACK *p_start_adv_cback;
} tBTA_DM_API_BLE_ADV_PARAMS_ALL;

View File

@@ -400,6 +400,8 @@ typedef struct {
typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status);
typedef void (tBTA_START_ADV_CMPL_CBACK) (tBTA_STATUS status);
/* advertising channel map */
#define BTA_BLE_ADV_CHNL_37 BTM_BLE_ADV_CHNL_37
#define BTA_BLE_ADV_CHNL_38 BTM_BLE_ADV_CHNL_38
@@ -1095,6 +1097,8 @@ typedef void (tBTA_BLE_SCAN_SETUP_CBACK) (tBTA_BLE_BATCH_SCAN_EVT evt,
tBTA_DM_BLE_REF_VALUE ref_value,
tBTA_STATUS status);
typedef void (tBTA_START_SCAN_CMPL_CBACK) (tBTA_STATUS status);
typedef void (tBTA_BLE_TRACK_ADV_CMPL_CBACK)(int action, tBTA_STATUS status,
tBTA_DM_BLE_PF_AVBL_SPACE avbl_space,
tBTA_DM_BLE_REF_VALUE ref_value);
@@ -1891,7 +1895,7 @@ extern void BTA_DmSetBleAdvParams (UINT16 adv_int_min, UINT16 adv_int_max,
extern void BTA_DmSetBleAdvParamsAll (UINT16 adv_int_min, UINT16 adv_int_max,
UINT8 adv_type, tBLE_ADDR_TYPE addr_type_own,
tBTM_BLE_ADV_CHNL_MAP chnl_map, tBTM_BLE_AFP adv_fil_pol,
tBLE_BD_ADDR *p_dir_bda);
tBLE_BD_ADDR *p_dir_bda, tBTA_START_ADV_CMPL_CBACK p_start_adv_cb);
/*******************************************************************************
@@ -1997,7 +2001,8 @@ extern void BTA_DmSetEncryption(BD_ADDR bd_addr, tBTA_TRANSPORT transport,
**
*******************************************************************************/
extern void BTA_DmBleObserve(BOOLEAN start, UINT8 duration,
tBTA_DM_SEARCH_CBACK *p_results_cb);
tBTA_DM_SEARCH_CBACK *p_results_cb,
tBTA_START_SCAN_CMPL_CBACK *p_start_scan_cb);
extern void BTA_DmBleStopAdvertising(void);

View File

@@ -177,6 +177,10 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
blufi_env.prepare_buf = NULL;
}
break;
case BTA_GATTS_MTU_EVT:
LOG_DEBUG("MTU size %d\n", p_data->req_data.p_data->mtu);
blufi_env.frag_size = p_data->req_data.p_data->mtu - BLUFI_MTU_RESERVED_SIZE;
break;
case BTA_GATTS_CONF_EVT:
LOG_DEBUG("CONIRM EVT\n");
@@ -264,6 +268,7 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
blufi_env.conn_id = p_data->conn.conn_id;
blufi_env.is_connected = false;
blufi_env.recv_seq = blufi_env.send_seq = 0;
blufi_env.sec_mode = 0x0;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_BLUFI;
@@ -294,6 +299,7 @@ static tGATT_STATUS btc_blufi_profile_init(void)
memset(&blufi_env, 0x0, sizeof(blufi_env));
blufi_env.cbs = store_p; /* if set callback prior, restore the point */
blufi_env.frag_size = BLUFI_FRAG_DATA_DEFAULT_LEN;
/* register the BLUFI profile to the BTA_GATTS module*/
BTA_GATTS_AppRegister(&blufi_app_uuid, blufi_profile_cb);
@@ -406,16 +412,16 @@ void btc_blufi_send_encap(uint8_t type, uint8_t *data, int total_data_len)
int ret;
while (remain_len > 0) {
if (remain_len > BLUFI_FRAG_DATA_MAX_LEN) {
hdr = GKI_getbuf(sizeof(struct blufi_hdr) + 2 + BLUFI_FRAG_DATA_MAX_LEN + 2);
if (remain_len > blufi_env.frag_size) {
hdr = GKI_getbuf(sizeof(struct blufi_hdr) + 2 + blufi_env.frag_size + 2);
if (hdr == NULL) {
LOG_ERROR("%s no mem\n", __func__);
return;
}
hdr->fc = 0x0;
hdr->data_len = BLUFI_FRAG_DATA_MAX_LEN + 2;
hdr->data_len = blufi_env.frag_size + 2;
*(uint16_t *)hdr->data = remain_len;
memcpy(hdr->data + 2, &data[total_data_len - remain_len], BLUFI_FRAG_DATA_MAX_LEN); //copy first, easy for check sum
memcpy(hdr->data + 2, &data[total_data_len - remain_len], blufi_env.frag_size); //copy first, easy for check sum
hdr->fc |= BLUFI_FC_FRAG;
} else {
hdr = GKI_getbuf(sizeof(struct blufi_hdr) + remain_len + 2);

View File

@@ -33,6 +33,7 @@ typedef struct {
BD_ADDR remote_bda;
UINT32 trans_id;
UINT8 congest;
UINT16 frag_size;
#define BLUFI_PREPAIR_BUF_MAX_SIZE 1024
uint8_t *prepare_buf;
int prepare_len;
@@ -160,7 +161,9 @@ typedef struct blufi_frag_hdr blufi_frag_hdr_t;
#define BLUFI_FC_IS_REQ_ACK(fc) ((fc) & BLUFI_FC_REQ_ACK_MASK)
#define BLUFI_FC_IS_FRAG(fc) ((fc) & BLUFI_FC_FRAG_MASK)
#define BLUFI_FRAG_DATA_MAX_LEN 50
/* BLUFI HEADER + TOTAL(REMAIN) LENGTH + CRC + L2CAP RESERVED */
#define BLUFI_MTU_RESERVED_SIZE (sizeof(struct blufi_hdr) + 2 + 2 + 3)
#define BLUFI_FRAG_DATA_DEFAULT_LEN (GATT_DEF_BLE_MTU_SIZE - BLUFI_MTU_RESERVED_SIZE)
//function declare
void btc_blufi_protocol_handler(uint8_t type, uint8_t *data, int len);

View File

@@ -367,7 +367,26 @@ static void btc_ble_set_scan_rsp_data_raw(uint8_t *raw_scan_rsp, uint32_t raw_sc
BTA_DmBleSetScanRspRaw(raw_scan_rsp, raw_scan_rsp_len, p_scan_rsp_data_cback);
}
static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params)
static void btc_start_adv_callback(tBTA_STATUS status)
{
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_ADV_START_COMPLETE_EVT;
param.adv_start_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params, tBTA_START_ADV_CMPL_CBACK start_adv_cback)
{
tBLE_BD_ADDR peer_addr;
@@ -398,7 +417,8 @@ static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params)
ble_adv_params->own_addr_type,
ble_adv_params->channel_map,
ble_adv_params->adv_filter_policy,
&peer_addr);
&peer_addr,
start_adv_cback);
}
@@ -456,8 +476,7 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
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;
memcpy(param.scan_rst.ble_adv, p_data->inq_res.p_eir,
ESP_BLE_ADV_DATA_LEN_MAX);
memcpy(param.scan_rst.ble_adv, p_data->inq_res.p_eir, sizeof(param.scan_rst.ble_adv));
break;
}
case BTA_DM_INQ_CMPL_EVT: {
@@ -487,12 +506,33 @@ static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data
btc_transfer_context(&msg, &param, sizeof(esp_ble_gap_cb_param_t), NULL);
}
static void btc_ble_start_scanning(uint8_t duration, tBTA_DM_SEARCH_CBACK *results_cb)
static void btc_start_scan_callback(tBTA_STATUS status)
{
if ((duration != 0) && (results_cb != NULL)) {
esp_ble_gap_cb_param_t param;
bt_status_t ret;
btc_msg_t msg;
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_SCAN_START_COMPLETE_EVT;
param.scan_start_cmpl.status = status;
ret = btc_transfer_context(&msg, &param,
sizeof(esp_ble_gap_cb_param_t), NULL);
if (ret != BT_STATUS_SUCCESS) {
LOG_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
static void btc_ble_start_scanning(uint8_t duration,
tBTA_DM_SEARCH_CBACK *results_cb,
tBTA_START_SCAN_CMPL_CBACK *start_scan_cb)
{
if ((duration != 0) && (results_cb != NULL) && (start_scan_cb != NULL)) {
///Start scan the device
BTA_DmBleObserve(true, duration, results_cb);
BTA_DmBleObserve(true, duration, results_cb, start_scan_cb);
} else {
LOG_ERROR("The scan duration or p_results_cb invalid\n");
}
@@ -501,7 +541,7 @@ static void btc_ble_start_scanning(uint8_t duration, tBTA_DM_SEARCH_CBACK *resul
static void btc_ble_stop_scanning(void)
{
uint8_t duration = 0;
BTA_DmBleObserve(false, duration, NULL);
BTA_DmBleObserve(false, duration, NULL, NULL);
}
@@ -576,6 +616,12 @@ void btc_gap_ble_cb_handler(btc_msg_t *msg)
case ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_ADV_START_COMPLETE_EVT, param);
break;
case ESP_GAP_BLE_SCAN_START_COMPLETE_EVT:
btc_gap_ble_cb_to_app(ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, param);
break;
default:
break;
@@ -695,13 +741,13 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
btc_ble_set_scan_params(&arg->set_scan_param.scan_params, btc_scan_params_callback);
break;
case BTC_GAP_BLE_ACT_START_SCAN:
btc_ble_start_scanning(arg->start_scan.duration, btc_search_callback);
btc_ble_start_scanning(arg->start_scan.duration, btc_search_callback, btc_start_scan_callback);
break;
case BTC_GAP_BLE_ACT_STOP_SCAN:
btc_ble_stop_scanning();
break;
case BTC_GAP_BLE_ACT_START_ADV:
btc_ble_start_advertising(&arg->start_adv.adv_params);
btc_ble_start_advertising(&arg->start_adv.adv_params, btc_start_adv_callback);
break;
case BTC_GAP_BLE_ACT_STOP_ADV:
btc_ble_stop_advertising();

View File

@@ -166,6 +166,30 @@ void btc_gatts_arg_deep_free(btc_msg_t *msg)
}
break;
}
case BTC_GATTS_ACT_ADD_CHAR:{
if (arg->add_char.char_val.attr_value != NULL) {
GKI_freebuf(arg->add_char.char_val.attr_value);
}
break;
}
case BTC_GATTS_ACT_ADD_CHAR_DESCR:{
if (arg->add_descr.descr_val.attr_value != NULL){
GKI_freebuf(arg->add_descr.descr_val.attr_value);
}
break;
}
case BTC_GATTS_ACT_CREATE_ATTR_TAB:{
if (arg->create_attr_tab.gatts_attr_db != NULL){
GKI_freebuf(arg->create_attr_tab.gatts_attr_db);
}
break;
}
case BTC_GATTS_ACT_SET_ATTR_VALUE:{
if (arg->set_attr_val.value != NULL){
GKI_freebuf(arg->set_attr_val.value);
}
}
default:
LOG_DEBUG("%s Unhandled deep free %d\n", __func__, msg->act);
break;
@@ -182,13 +206,16 @@ static void btc_gatts_act_create_attr_tab(esp_gatts_attr_db_t *gatts_attr_db,
future_t *future_p;
esp_ble_gatts_cb_param_t param;
//set the attribute table create service flag to ture
//set the attribute table create service flag to true
btc_creat_tab_env.is_tab_creat_svc = true;
btc_creat_tab_env.num_handle = max_nb_attr;
for(int i = 0; i < max_nb_attr; i++){
if(gatts_attr_db[i].att_desc.uuid_length== ESP_UUID_LEN_16){
uuid = (gatts_attr_db[i].att_desc.uuid_p[1] << 8) + (gatts_attr_db[i].att_desc.uuid_p[0]);
}
else{
continue;
}
future_p = future_new();
if (future_p == NULL) {
LOG_ERROR("%s failed:no mem\n", __func__);

View File

@@ -221,6 +221,10 @@ static void start_up(void)
}
if (HCI_LE_DATA_LEN_EXT_SUPPORTED(features_ble.as_array)) {
/* set default tx data length to MAX 251 */
response = AWAIT_COMMAND(packet_factory->make_ble_write_suggested_default_data_length(BTM_BLE_DATA_SIZE_MAX, BTM_BLE_DATA_TX_TIME_MAX));
packet_parser->parse_generic_command_complete(response);
response = AWAIT_COMMAND(packet_factory->make_ble_read_suggested_default_data_length());
packet_parser->parse_ble_read_suggested_default_data_length_response(
response,

View File

@@ -154,6 +154,17 @@ static BT_HDR *make_ble_read_suggested_default_data_length(void)
return make_command_no_params(HCI_BLE_READ_DEFAULT_DATA_LENGTH);
}
static BT_HDR *make_ble_write_suggested_default_data_length(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime)
{
uint8_t *stream;
uint8_t parameter_size = sizeof(uint16_t) + sizeof(uint16_t);
BT_HDR *packet = make_command(HCI_BLE_WRITE_DEFAULT_DATA_LENGTH, parameter_size, &stream);
UINT16_TO_STREAM(stream, SuggestedMaxTxOctets);
UINT16_TO_STREAM(stream, SuggestedMaxTxTime);
return packet;
}
static BT_HDR *make_ble_set_event_mask(const bt_event_mask_t *event_mask)
{
uint8_t *stream;
@@ -215,6 +226,7 @@ static const hci_packet_factory_t interface = {
make_ble_read_local_supported_features,
make_ble_read_resolving_list_size,
make_ble_read_suggested_default_data_length,
make_ble_write_suggested_default_data_length,
make_ble_set_event_mask
};

View File

@@ -40,6 +40,7 @@ typedef struct {
BT_HDR *(*make_ble_read_local_supported_features)(void);
BT_HDR *(*make_ble_read_resolving_list_size)(void);
BT_HDR *(*make_ble_read_suggested_default_data_length)(void);
BT_HDR *(*make_ble_write_suggested_default_data_length)(uint16_t SuggestedMaxTxOctets, uint16_t SuggestedMaxTxTime);
BT_HDR *(*make_ble_set_event_mask)(const bt_event_mask_t *event_mask);
} hci_packet_factory_t;

View File

@@ -43,25 +43,27 @@ enum {
SIG_BTIF_WORK = 0xff
};
#define HCI_HOST_TASK_STACK_SIZE 1500
#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 2)
#define HCI_HOST_TASK_NAME "hciHostT"
#define HCI_HOST_QUEUE_NUM 40
#define HCI_H4_TASK_STACK_SIZE 1500
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 3)
#define HCI_H4_TASK_NAME "hciH4T"
#define HCI_H4_QUEUE_NUM 60
#define BT_TASK_EXTRA_STACK_SIZE 512
#define HCI_HOST_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 2)
#define HCI_HOST_TASK_NAME "hciHostT"
#define HCI_HOST_QUEUE_NUM 40
#define BTU_TASK_STACK_SIZE 4096
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 4)
#define BTU_TASK_NAME "btuT"
#define BTU_QUEUE_NUM 50
#define HCI_H4_TASK_STACK_SIZE (2048 + BT_TASK_EXTRA_STACK_SIZE)
#define HCI_H4_TASK_PRIO (configMAX_PRIORITIES - 3)
#define HCI_H4_TASK_NAME "hciH4T"
#define HCI_H4_QUEUE_NUM 60
#define BTC_TASK_STACK_SIZE CONFIG_BTC_TASK_STACK_SIZE //by menuconfig
#define BTC_TASK_NAME "btcT"
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 5)
#define BTC_TASK_QUEUE_NUM 20
#define BTU_TASK_STACK_SIZE (3584 + BT_TASK_EXTRA_STACK_SIZE)
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 4)
#define BTU_TASK_NAME "btuT"
#define BTU_QUEUE_NUM 50
#define BTC_TASK_STACK_SIZE (CONFIG_BTC_TASK_STACK_SIZE + BT_TASK_EXTRA_STACK_SIZE) //by menuconfig
#define BTC_TASK_NAME "btcT"
#define BTC_TASK_PRIO (configMAX_PRIORITIES - 5)
#define BTC_TASK_QUEUE_NUM 60
void btu_task_post(uint32_t sig);
void hci_host_task_post(void);

View File

@@ -2935,14 +2935,18 @@ tBTM_STATUS btm_ble_start_scan(void)
tBTM_BLE_INQ_CB *p_inq = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS status = BTM_CMD_STARTED;
/* start scan, disable duplicate filtering */
if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) {
if (p_inq->adv_mode != BTM_BLE_ADV_DISABLE) {
status = BTM_NO_RESOURCES;
} else {
if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) {
btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
/* start scan, disable duplicate filtering */
if (!btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_ENABLE, p_inq->scan_duplicate_filter)) {
status = BTM_NO_RESOURCES;
} else {
btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
if (p_inq->scan_type == BTM_BLE_SCAN_MODE_ACTI) {
btm_ble_set_topology_mask(BTM_BLE_STATE_ACTIVE_SCAN_BIT);
} else {
btm_ble_set_topology_mask(BTM_BLE_STATE_PASSIVE_SCAN_BIT);
}
}
}
return status;
@@ -2961,15 +2965,17 @@ void btm_ble_stop_scan(void)
{
BTM_TRACE_EVENT ("btm_ble_stop_scan ");
/* Clear the inquiry callback if set */
btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
if (btm_cb.ble_ctr_cb.inq_var.adv_mode == BTM_BLE_ADV_DISABLE) {
/* Clear the inquiry callback if set */
btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE;
/* stop discovery now */
btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
/* stop discovery now */
btsnd_hcic_ble_set_scan_enable (BTM_BLE_SCAN_DISABLE, BTM_BLE_DUPLICATE_ENABLE);
btm_update_scanner_filter_policy(SP_ADV_ALL);
btm_update_scanner_filter_policy(SP_ADV_ALL);
btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN;
btm_cb.ble_ctr_cb.wl_state &= ~BTM_BLE_WL_SCAN;
}
}
/*******************************************************************************
**
@@ -3089,9 +3095,15 @@ static BOOLEAN btm_ble_adv_states_operation(BTM_TOPOLOGY_FUNC_PTR *p_handler, UI
*******************************************************************************/
tBTM_STATUS btm_ble_start_adv(void)
{
tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS rt = BTM_NO_RESOURCES;
BTM_TRACE_EVENT ("btm_ble_start_adv\n");
if (BTM_BLE_IS_OBS_ACTIVE(p_ble_cb->scan_activity)) {
return BTM_NO_RESOURCES;
}
if (!btm_ble_adv_states_operation (btm_ble_topology_check, p_cb->evt_type)) {
return BTM_WRONG_MODE;
}
@@ -3133,10 +3145,12 @@ tBTM_STATUS btm_ble_start_adv(void)
*******************************************************************************/
tBTM_STATUS btm_ble_stop_adv(void)
{
tBTM_BLE_CB *p_ble_cb = & btm_cb.ble_ctr_cb;
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
tBTM_STATUS rt = BTM_SUCCESS;
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE) {
if (p_cb->adv_mode == BTM_BLE_ADV_ENABLE
&& !BTM_BLE_IS_OBS_ACTIVE(p_ble_cb->scan_activity)) {
if (btsnd_hcic_ble_set_adv_enable (BTM_BLE_ADV_DISABLE)) {
p_cb->fast_adv_on = FALSE;
p_cb->adv_mode = BTM_BLE_ADV_DISABLE;

View File

@@ -214,6 +214,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
if (p_list) {
gatt_remove_an_item_from_list(p_list_info, p_list);
gatt_free_attr_value_buffer(p_list);
gatt_free_hdl_buffer(p_list);
}
return (0);
@@ -227,6 +228,7 @@ UINT16 GATTS_CreateService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid,
GATT_TRACE_ERROR ("GATTS_ReserveHandles: service DB initialization failed\n");
if (p_list) {
gatt_remove_an_item_from_list(p_list_info, p_list);
gatt_free_attr_value_buffer(p_list);
gatt_free_hdl_buffer(p_list);
}
@@ -413,6 +415,7 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_
}
gatt_remove_an_item_from_list(p_list_info, p_list);
gatt_free_attr_value_buffer(p_list);
gatt_free_hdl_buffer(p_list);
return (TRUE);

View File

@@ -268,14 +268,21 @@ static tGATT_STATUS read_attr_value (void *p_attr,
status = GATT_SUCCESS;
}
} else { /* characteristic description or characteristic value */
if (p_attr16->control.auto_rsp == GATT_RSP_BY_STACK) {
if (p_attr16->p_value != NULL && p_attr16->p_value->attr_val.attr_val != NULL) {
uint8_t *value = p_attr16->p_value->attr_val.attr_val + offset;
len = (mtu >= p_attr16->p_value->attr_val.attr_len) ? (p_attr16->p_value->attr_val.attr_len) : mtu;
ARRAY_TO_STREAM(p, value, len);
if (p_attr16->p_value == NULL || p_attr16->p_value->attr_val.attr_val == NULL) {
status = GATT_ESP_ERROR;
}
else if (offset > p_attr16->p_value->attr_val.attr_len){
/*if offset equal to max_len, should respond with zero byte value
//if offset is greater than max_len, should respond with an error*/
status = GATT_INVALID_OFFSET;
} else {
UINT8 *value = (UINT8 *)(p_attr16->p_value->attr_val.attr_val) + offset;
UINT16 len_left = p_attr16->p_value->attr_val.attr_len - offset;
len = (mtu >= len_left) ? (len_left) : mtu;
ARRAY_TO_STREAM(p, value, len);
status = GATT_STACK_RSP;
}
status = GATT_STACK_RSP;
} else {
status = GATT_PENDING;
@@ -463,6 +470,27 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_DECLARE}};
GATT_TRACE_DEBUG("gatts_add_characteristic perm=0x%0x property=0x%0x\n", perm, property);
/* parameter validation check */
if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){
if (attr_val == NULL){
GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attr_val should not be NULL here\n",\
__func__, __LINE__);
return 0;
} else if (attr_val->attr_max_len == 0){
GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\
__func__, __LINE__);
return 0;
}
}
if (attr_val != NULL){
if (attr_val->attr_len > attr_val->attr_max_len){
GATT_TRACE_ERROR("Error in %s, line=%d,attribute actual length should not be larger than max length\n",\
__func__, __LINE__);
return 0;
}
}
if ((p_char_decl = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, &uuid, GATT_PERM_READ)) != NULL) {
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_decl->p_value, sizeof(tGATT_CHAR_DECL))) {
@@ -483,10 +511,9 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
p_char_val->control.auto_rsp = control->auto_rsp;
} else {
p_char_val->control.auto_rsp = GATT_RSP_DEFAULT;
}
if (attr_val != NULL) {
if (attr_val != NULL) {
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_val->p_value, sizeof(tGATT_ATTR_VAL))) {
deallocate_attr_in_db(p_db, p_char_val);
return 0;
@@ -496,12 +523,27 @@ UINT16 gatts_add_characteristic (tGATT_SVC_DB *p_db, tGATT_PERM perm,
p_char_val->p_value->attr_val.attr_len = attr_val->attr_len;
p_char_val->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
p_char_val->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
if (p_char_val->p_value->attr_val.attr_val != NULL) {
GATT_TRACE_DEBUG("attribute value not NULL");
memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
if (p_char_val->p_value->attr_val.attr_val == NULL) {
deallocate_attr_in_db(p_db, p_char_decl);
deallocate_attr_in_db(p_db, p_char_val);
GATT_TRACE_WARNING("Warning in %s, line=%d, insufficient resource to allocate for attribute value\n", __func__, __LINE__);
return 0;
}
else {
//add mask to indicate that p_value->attr_val.attr_val is dynamic allocated
p_char_val->mask |= GATT_ATTR_VALUE_ALLOCATED;
}
//initiate characteristic attribute value part
memset(p_char_val->p_value->attr_val.attr_val, 0, attr_val->attr_max_len);
if (attr_val->attr_val != NULL) {
if (attr_val->attr_max_len < attr_val->attr_len){
GATT_TRACE_ERROR("Error in %s, Line=%d, attribute actual length (%d) should not larger than max size (%d)\n",
__func__, __LINE__, attr_val->attr_len, attr_val->attr_max_len);
}
UINT16 actual_len = (attr_val->attr_max_len < attr_val->attr_len) ? (attr_val->attr_max_len) : (attr_val->attr_len);
memcpy(p_char_val->p_value->attr_val.attr_val, attr_val->attr_val, actual_len);
}
} else {
p_char_val->p_value = NULL;
}
return p_char_val->handle;
@@ -582,14 +624,35 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
GATT_TRACE_DEBUG("gatts_add_char_descr uuid=0x%04x\n", p_descr_uuid->uu.uuid16);
/* parameter validation check */
if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){
if (attr_val == NULL){
GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attr_val should not be NULL here\n",\
__func__, __LINE__);
return 0;
} else if (attr_val->attr_max_len == 0){
GATT_TRACE_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\
__func__, __LINE__);
return 0;
}
}
if (attr_val != NULL){
if (attr_val->attr_len > attr_val->attr_max_len){
GATT_TRACE_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\
__func__, __LINE__, attr_val->attr_len, attr_val->attr_max_len);
return 0;
}
}
/* Add characteristic descriptors */
if ((p_char_dscptr = (tGATT_ATTR16 *)allocate_attr_in_db(p_db, p_descr_uuid, perm)) == NULL) {
deallocate_attr_in_db(p_db, p_char_dscptr);
GATT_TRACE_DEBUG("gatts_add_char_descr Fail for adding char descriptors.");
return 0;
} else {
if (control != NULL) {
p_char_dscptr->control.auto_rsp = control->auto_rsp;
}
p_char_dscptr->control.auto_rsp = (control == NULL) ? GATT_RSP_DEFAULT : (control->auto_rsp);
if (attr_val != NULL) {
if (!copy_extra_byte_in_db(p_db, (void **)&p_char_dscptr->p_value, sizeof(tGATT_ATTR_VAL))) {
deallocate_attr_in_db(p_db, p_char_dscptr);
@@ -597,10 +660,21 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
}
p_char_dscptr->p_value->attr_val.attr_len = attr_val->attr_len;
p_char_dscptr->p_value->attr_val.attr_max_len = attr_val->attr_max_len;
if (attr_val->attr_val != NULL) {
if (attr_val->attr_max_len != 0) {
p_char_dscptr->p_value->attr_val.attr_val = GKI_getbuf(attr_val->attr_max_len);
if (p_char_dscptr->p_value->attr_val.attr_val != NULL) {
memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len);
if (p_char_dscptr->p_value->attr_val.attr_val == NULL) {
deallocate_attr_in_db(p_db, p_char_dscptr);
GATT_TRACE_WARNING("Warning in %s, line=%d, insufficient resource to allocate for descriptor value\n", __func__, __LINE__);
return 0;
}
else {
//add mask to indicate that p_value->attr_val.attr_val is dynamic allocated
p_char_dscptr->mask |= GATT_ATTR_VALUE_ALLOCATED;
}
//initiate characteristic attribute value part
memset(p_char_dscptr->p_value->attr_val.attr_val, 0, attr_val->attr_max_len);
if(attr_val->attr_val != NULL) {
memcpy(p_char_dscptr->p_value->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
}
}
@@ -625,7 +699,7 @@ UINT16 gatts_add_char_descr (tGATT_SVC_DB *p_db, tGATT_PERM perm,
**
*******************************************************************************/
tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
UINT16 length, UINT8 *value)
UINT16 length, UINT8 *value)
{
tGATT_ATTR16 *p_cur;
@@ -637,51 +711,46 @@ tGATT_STATUS gatts_set_attribute_value(tGATT_SVC_DB *p_db, UINT16 attr_handle,
GATT_TRACE_DEBUG("gatts_set_attribute_value Fail:p_db->p_attr_list is NULL.\n");
return GATT_INVALID_PDU;
}
if ((length > 0) && (value == NULL)){
GATT_TRACE_ERROR("Error in %s, line=%d, value should not be NULL here\n",__func__, __LINE__);
return GATT_INVALID_PDU;
}
p_cur = (tGATT_ATTR16 *) p_db->p_attr_list;
while (p_cur != NULL) {
if (p_cur->handle == attr_handle) {
/* for characteristic should not be set, return GATT_NOT_FOUND */
if (p_cur->uuid_type == GATT_ATTR_UUID_TYPE_16) {
switch (p_cur->uuid) {
case GATT_UUID_PRI_SERVICE:
case GATT_UUID_SEC_SERVICE:
case GATT_UUID_CHAR_DECLARE:
case GATT_UUID_INCLUDE_SERVICE:
return GATT_NOT_FOUND;
default:
if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len < length) {
GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
return GATT_INVALID_ATTR_LEN;
} else if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len > 0) {
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
p_cur->p_value->attr_val.attr_len = length;
} else {
return GATT_INVALID_ATTR_LEN;
}
break;
}
} else {
if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len < length) {
GATT_TRACE_ERROR("gatts_set_attribute_vaule failt:Invalid value length");
} else if (p_cur->p_value != NULL && p_cur->p_value->attr_val.attr_max_len > 0) {
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
p_cur->p_value->attr_val.attr_len = length;
} else {
return GATT_INVALID_ATTR_LEN;
case GATT_UUID_PRI_SERVICE:
case GATT_UUID_SEC_SERVICE:
case GATT_UUID_CHAR_DECLARE:
return GATT_NOT_FOUND;
break;
}
}
/* in other cases, value can be set*/
if ((p_cur->p_value == NULL) || (p_cur->p_value->attr_val.attr_val == NULL) \
|| (p_cur->p_value->attr_val.attr_max_len == 0)){
GATT_TRACE_ERROR("Error in %s, line=%d, attribute value should not be NULL here\n", __func__, __LINE__);
return GATT_NOT_FOUND;
} else if (p_cur->p_value->attr_val.attr_max_len < length) {
GATT_TRACE_ERROR("gatts_set_attribute_value failed:Invalid value length");
return GATT_INVALID_ATTR_LEN;
} else{
memcpy(p_cur->p_value->attr_val.attr_val, value, length);
p_cur->p_value->attr_val.attr_len = length;
}
break;
}
p_cur = p_cur->p_next;
}
return GATT_SUCCESS;
}
/*******************************************************************************
**
** Function gatts_get_attribute_value
@@ -872,20 +941,25 @@ tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
return GATT_APP_RSP;
}
if (p_attr->p_value != NULL && (p_attr->p_value->attr_val.attr_max_len >=
offset + len)) {
if ((p_attr->p_value != NULL) &&
(p_attr->p_value->attr_val.attr_max_len >= offset + len) &&
p_attr->p_value->attr_val.attr_val != NULL) {
memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
p_attr->p_value->attr_val.attr_len = len + offset;
return GATT_SUCCESS;
} else {
return GATT_NOT_LONG;
} else if (p_attr->p_value->attr_val.attr_max_len < offset + len){
GATT_TRACE_DEBUG("Remote device try to write with a length larger then attribute's max length\n");
return GATT_INVALID_ATTR_LEN;
} else if ((p_attr->p_value == NULL) || (p_attr->p_value->attr_val.attr_val == NULL)){
GATT_TRACE_ERROR("Error in %s, line=%d, %s should not be NULL here\n", __func__, __LINE__, \
(p_attr->p_value == NULL) ? "p_value" : "attr_val.attr_val");
return GATT_ESP_ERROR;
}
}
p_attr = (tGATT_ATTR16 *)p_attr->p_next;
}
}
return status;
@@ -1332,7 +1406,13 @@ static tGATT_STATUS gatts_send_app_read_request(tGATT_TCB *p_tcb, UINT8 op_code,
gatt_sr_send_req_callback(conn_id,
trans_id, GATTS_REQ_TYPE_READ, &sr_data);
return (tGATT_STATUS) GATT_PENDING;
if (need_rsp) {
return (tGATT_STATUS) GATT_PENDING;
}
else{
return (tGATT_STATUS) GATT_STACK_RSP;
}
} else {
return (tGATT_STATUS) GATT_BUSY; /* max pending command, application error */
}

View File

@@ -33,6 +33,42 @@
#define GATT_MTU_REQ_MIN_LEN 2
/*******************************************************************************
**
** Function gatt_send_packet
**
** Description This function is called to send gatt packets directly
**
** Returns status
**
*******************************************************************************/
tGATT_STATUS gatt_send_packet (tGATT_TCB *p_tcb, UINT8 *p_data, UINT16 len)
{
BT_HDR *p_msg = NULL;
UINT8 *p_m = NULL;
UINT16 buf_len;
tGATT_STATUS status;
if (len > p_tcb->payload_size){
return GATT_ILLEGAL_PARAMETER;
}
buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
return GATT_NO_RESOURCES;
}
memset(p_msg, 0, buf_len);
p_msg->len = len;
p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
memcpy(p_m, p_data, len);
status = attp_send_sr_msg(p_tcb, p_msg);
return status;
}
/*******************************************************************************
**
** Function gatt_sr_enqueue_cmd
@@ -300,7 +336,11 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
UINT32 trans_id = 0;
tGATT_IF gatt_if;
UINT16 conn_id;
UINT16 queue_num = 0;
BOOLEAN is_prepare_write_valid = FALSE;
BOOLEAN is_need_dequeue_sr_cmd = FALSE;
tGATT_PREPARE_WRITE_RECORD *prepare_record = NULL;
tGATT_PREPARE_WRITE_QUEUE_DATA * queue_data = NULL;
UNUSED(len);
#if GATT_CONFORMANCE_TESTING == TRUE
@@ -319,11 +359,60 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
/* mask the flag */
flag &= GATT_PREP_WRITE_EXEC;
prepare_record = &(p_tcb->prepare_write_record);
queue_num = prepare_record->queue._count;
/* no prep write is queued */
//if received prepare_write packets include stack_rsp and app_rsp,
//stack respond to execute_write only when stack_rsp handle has invalid_offset
//or invalid_length error;
//app need to respond to execute_write if it has received app_rsp handle packets
if (((prepare_record->error_code_app == GATT_SUCCESS) &&
(prepare_record->total_num == queue_num))
|| (flag == GATT_PREP_WRITE_CANCEL)){
tGATT_EXEC_WRITE_RSP gatt_exec_write_rsp;
gatt_exec_write_rsp.op_code = GATT_RSP_EXEC_WRITE;
gatt_send_packet(p_tcb, (UINT8 *)(&gatt_exec_write_rsp), sizeof(gatt_exec_write_rsp));
gatt_dequeue_sr_cmd(p_tcb);
if (flag != GATT_PREP_WRITE_CANCEL){
is_prepare_write_valid = TRUE;
}
GATT_TRACE_DEBUG("Send execute_write_rsp\n");
} else if ((prepare_record->error_code_app == GATT_SUCCESS) &&
(prepare_record->total_num > queue_num)){
//No error for stack_rsp's handles and there exist some app_rsp's handles,
//so exec_write_rsp depends to app's response; but stack_rsp's data is valid
//TODO: there exist problem if stack_rsp's data is valid but app_rsp's data is not valid.
is_prepare_write_valid = TRUE;
} else if(prepare_record->total_num < queue_num) {
GATT_TRACE_ERROR("Error in %s, line=%d, prepare write total number (%d) \
should not smaller than prepare queue number (%d)\n", \
__func__, __LINE__,prepare_record->total_num, queue_num);
} else if (prepare_record->error_code_app != GATT_SUCCESS){
GATT_TRACE_DEBUG("Send error code for execute_write, code=0x%x\n", prepare_record->error_code_app);
is_need_dequeue_sr_cmd = (prepare_record->total_num == queue_num) ? TRUE : FALSE;
gatt_send_error_rsp(p_tcb, prepare_record->error_code_app, GATT_REQ_EXEC_WRITE, 0, is_need_dequeue_sr_cmd);
}
//dequeue prepare write data
while(GKI_getfirst(&(prepare_record->queue))) {
queue_data = GKI_dequeue(&(prepare_record->queue));
if (is_prepare_write_valid){
if((queue_data->p_attr->p_value != NULL) && (queue_data->p_attr->p_value->attr_val.attr_val != NULL)){
memcpy(queue_data->p_attr->p_value->attr_val.attr_val+queue_data->offset, queue_data->value, queue_data->len);
}
}
GKI_freebuf(queue_data);
}
/* according to ble spec, even if there is no prep write queued,
* need to respond execute_write_response
* Note: exec_write_rsp callback should be called after all data has been written*/
if (!gatt_sr_is_prep_cnt_zero(p_tcb)) {
trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, 0);
gatt_sr_copy_prep_cnt_to_cback_cnt(p_tcb);
if (prepare_record->total_num > queue_num){
trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, 0);
gatt_sr_copy_prep_cnt_to_cback_cnt(p_tcb);
}
for (i = 0; i < GATT_MAX_APPS; i++) {
if (p_tcb->prep_cnt[i]) {
@@ -336,10 +425,10 @@ void gatt_process_exec_write_req (tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, U
p_tcb->prep_cnt[i] = 0;
}
}
} else { /* nothing needs to be executed , send response now */
GATT_TRACE_ERROR("gatt_process_exec_write_req: no prepare write pending");
gatt_send_error_rsp(p_tcb, GATT_ERROR, GATT_REQ_EXEC_WRITE, 0, FALSE);
}
prepare_record->total_num = 0;
prepare_record->error_code_app = GATT_SUCCESS;
}
/*******************************************************************************
@@ -987,54 +1076,29 @@ void gatts_process_read_by_type_req(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len,
void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
UINT8 op_code, UINT16 len, UINT8 *p_data)
{
UINT16 buf_len = (UINT16)(sizeof(BT_HDR) + p_tcb->payload_size + L2CAP_MIN_OFFSET);
tGATTS_DATA sr_data;
UINT32 trans_id;
tGATT_STATUS status;
UINT8 sec_flag, key_size, *p = p_data, *p_m;
UINT8 sec_flag, key_size, *p = p_data;
tGATT_SR_REG *p_sreg;
UINT16 conn_id, offset = 0;
BT_HDR *p_msg = NULL;
memset(&sr_data, 0, sizeof(tGATTS_DATA));
sr_data.write_req.need_rsp = FALSE;
if ((p_msg = (BT_HDR *)GKI_getbuf(buf_len)) == NULL) {
GATT_TRACE_ERROR("gatts_process_write_req failed. no resources.\n");
}
memset(p_msg, 0, buf_len);
p_m = (UINT8 *)(p_msg + 1) + L2CAP_MIN_OFFSET;
*p_m ++ = op_code + 1;
p_msg->len = 1;
buf_len = p_tcb->payload_size - 1;
switch (op_code) {
case GATT_REQ_PREPARE_WRITE:
sr_data.write_req.is_prep = TRUE;
STREAM_TO_UINT16(sr_data.write_req.offset, p);
UINT16_TO_STREAM(p_m, sr_data.write_req.is_prep);
offset = sr_data.write_req.offset;
len -= 2;
/* fall through */
case GATT_SIGN_CMD_WRITE:
if (op_code == GATT_SIGN_CMD_WRITE) {
GATT_TRACE_DEBUG("Write CMD with data sigining" );
GATT_TRACE_DEBUG("Write CMD with data signing" );
len -= GATT_AUTH_SIGN_LEN;
}
/* fall through */
case GATT_CMD_WRITE:
case GATT_REQ_WRITE:
if (op_code == GATT_REQ_WRITE || op_code == GATT_REQ_PREPARE_WRITE) {
sr_data.write_req.need_rsp = TRUE;
if(op_code == GATT_REQ_PREPARE_WRITE){
memcpy(p_m, p, len);
p_msg->len += len;
}
}
sr_data.write_req.handle = handle;
sr_data.write_req.len = len;
if (len != 0 && p != NULL) {
memcpy (sr_data.write_req.value, p, len);
}
break;
}
@@ -1059,40 +1123,182 @@ void gatts_process_write_req (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
status = gatts_write_attr_value_by_handle(gatt_cb.sr_reg[i_rcb].p_db,
handle, offset, p, len);
if((sr_data.write_req.need_rsp == TRUE) && (status == GATT_APP_RSP)){
if((op_code == GATT_REQ_WRITE) && (status == GATT_APP_RSP)){
sr_data.write_req.need_rsp = TRUE;
status = GATT_PENDING;
}
else{
sr_data.write_req.need_rsp = FALSE;
}
gatt_sr_send_req_callback(conn_id,
trans_id,
GATTS_REQ_TYPE_WRITE,
&sr_data);
if(status == GATT_SUCCESS){
attp_send_sr_msg(p_tcb, p_msg);
gatt_dequeue_sr_cmd(p_tcb);
}
} else {
GATT_TRACE_ERROR("max pending command, send error\n");
GATT_TRACE_ERROR("Error in %s, line=%d, max pending command, send error\n", __func__, __LINE__);
status = GATT_BUSY; /* max pending command, application error */
}
}
/* in theroy BUSY is not possible(should already been checked), protected check */
if (status != GATT_PENDING && status != GATT_BUSY && status != GATT_SUCCESS &&
(op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_REQ_WRITE)) {
gatt_send_error_rsp (p_tcb, status, op_code, handle, FALSE);
gatt_dequeue_sr_cmd(p_tcb);
/* response should be sent only for write_request */
if ((op_code == GATT_REQ_WRITE) && (sr_data.write_req.need_rsp == FALSE)){
if (status == GATT_SUCCESS){
tGATT_WRITE_REQ_RSP gatt_write_req_rsp;
gatt_write_req_rsp.op_code = GATT_RSP_WRITE;
gatt_send_packet(p_tcb, (UINT8 *)(&gatt_write_req_rsp), sizeof(gatt_write_req_rsp));
gatt_dequeue_sr_cmd(p_tcb);
} else if (status != GATT_PENDING){
/* note: in case of GATT_BUSY, will respond this application error to remote device */
gatt_send_error_rsp (p_tcb, status, op_code, handle, TRUE);
}
}
return;
}
/*******************************************************************************
**
** Function gatts_attr_process_preapre_write
**
** Description This function is called to process the prepare write request
** from client.
**
** Returns void
**
*******************************************************************************/
void gatt_attr_process_prepare_write (tGATT_TCB *p_tcb, UINT8 i_rcb, UINT16 handle,
UINT8 op_code, UINT16 len, UINT8 *p_data)
{
tGATT_STATUS status;
tGATT_PREPARE_WRITE_QUEUE_DATA * queue_data = NULL;
tGATT_ATTR16 *p_attr;
tGATT_ATTR16 *p_attr_temp;
tGATTS_DATA sr_data;
UINT32 trans_id = 0;
UINT8 sec_flag, key_size, *p = p_data;
tGATT_SR_REG *p_sreg;
UINT16 conn_id, offset = 0;
tGATT_SVC_DB *p_db;
BOOLEAN is_need_prepare_write_rsp = FALSE;
BOOLEAN is_need_queue_data = FALSE;
tGATT_PREPARE_WRITE_RECORD *prepare_record = NULL;
memset(&sr_data, 0, sizeof(tGATTS_DATA));
//get offset from p_data
STREAM_TO_UINT16(offset, p);
len -= 2;
p_sreg = &gatt_cb.sr_reg[i_rcb];
conn_id = GATT_CREATE_CONN_ID(p_tcb->tcb_idx, p_sreg->gatt_if);
//prepare_record = &(prepare_write_record);
prepare_record = &(p_tcb->prepare_write_record);
gatt_sr_get_sec_info(p_tcb->peer_bda,
p_tcb->transport,
&sec_flag,
&key_size);
status = gatts_write_attr_perm_check (gatt_cb.sr_reg[i_rcb].p_db,
op_code,
handle,
sr_data.write_req.offset,
p,
len,
sec_flag,
key_size);
if (status == GATT_SUCCESS){
if ((trans_id = gatt_sr_enqueue_cmd(p_tcb, op_code, handle)) != 0) {
p_db = gatt_cb.sr_reg[i_rcb].p_db;
if (p_db && p_db->p_attr_list) {
p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
while (p_attr && handle >= p_attr->handle) {
if (p_attr->handle == handle ) {
p_attr_temp = p_attr;
if (p_attr->control.auto_rsp == GATT_RSP_BY_APP) {
status = GATT_APP_RSP;
} else if (p_attr->p_value != NULL &&
offset > p_attr->p_value->attr_val.attr_max_len) {
status = GATT_INVALID_OFFSET;
is_need_prepare_write_rsp = TRUE;
is_need_queue_data = TRUE;
} else if (p_attr->p_value != NULL &&
((offset + len) > p_attr->p_value->attr_val.attr_max_len)){
status = GATT_INVALID_ATTR_LEN;
is_need_prepare_write_rsp = TRUE;
is_need_queue_data = TRUE;
} else if (p_attr->p_value == NULL) {
LOG_ERROR("Error in %s, attribute of handle 0x%x not allocate value buffer\n",
__func__, handle);
status = GATT_ESP_ERROR;
} else {
//valid prepare write request, need to send response and queue the data
//status: GATT_SUCCESS
is_need_prepare_write_rsp = TRUE;
is_need_queue_data = TRUE;
}
}
p_attr = (tGATT_ATTR16 *)p_attr->p_next;
}
}
} else{
status = GATT_ESP_ERROR;
GATT_TRACE_ERROR("Error in %s, Line %d: GATT BUSY\n", __func__, __LINE__);
}
}
if (is_need_queue_data){
queue_data = (tGATT_PREPARE_WRITE_QUEUE_DATA *)GKI_getbuf(len + sizeof(tGATT_PREPARE_WRITE_QUEUE_DATA));
if (queue_data == NULL){
status = GATT_PREPARE_Q_FULL;
} else {
queue_data->p_attr = p_attr_temp;
queue_data->len = len;
queue_data->handle = handle;
queue_data->offset = offset;
memcpy(queue_data->value, p, len);
GKI_enqueue(&(prepare_record->queue), queue_data);
}
}
if (is_need_prepare_write_rsp){
//send prepare write response
if (queue_data != NULL){
queue_data->op_code = op_code + 1;
//5: op_code 1 + handle 2 + offset 2
tGATT_STATUS rsp_send_status = gatt_send_packet(p_tcb, &(queue_data->op_code), queue_data->len + 5);
gatt_sr_update_prep_cnt(p_tcb, p_sreg->gatt_if, TRUE, FALSE);
gatt_dequeue_sr_cmd(p_tcb);
if (rsp_send_status != GATT_SUCCESS){
LOG_ERROR("Error in %s, line=%d, fail to send prepare_write_rsp, status=0x%x\n",
__func__, __LINE__, rsp_send_status);
}
} else{
LOG_ERROR("Error in %s, line=%d, queue_data should not be NULL here, fail to send prepare_write_rsp\n",
__func__, __LINE__);
}
}
if ((status == GATT_APP_RSP) || (is_need_prepare_write_rsp)){
prepare_record->total_num++;
memset(&sr_data, 0, sizeof(sr_data));
sr_data.write_req.is_prep = TRUE;
sr_data.write_req.handle = handle;
sr_data.write_req.offset = offset;
sr_data.write_req.len = len;
sr_data.write_req.need_rsp = (status == GATT_APP_RSP) ? TRUE : FALSE;
memcpy(sr_data.write_req.value, p, len);
gatt_sr_send_req_callback(conn_id, trans_id, GATTS_REQ_TYPE_WRITE, &sr_data);
} else{
gatt_send_error_rsp(p_tcb, status, GATT_REQ_PREPARE_WRITE, handle, TRUE);
}
if ((prepare_record->error_code_app == GATT_SUCCESS)
&& ((status == GATT_INVALID_OFFSET) || (status == GATT_INVALID_ATTR_LEN))){
prepare_record->error_code_app = status;
}
}
/*******************************************************************************
**
** Function gatts_process_read_req
@@ -1162,6 +1368,10 @@ static void gatts_process_read_req(tGATT_TCB *p_tcb, tGATT_SR_REG *p_rcb, UINT8
} else if (reason == GATT_SUCCESS || reason == GATT_STACK_RSP) {
attp_send_sr_msg(p_tcb, p_msg);
gatt_dequeue_sr_cmd(p_tcb);
} else {
if (p_msg) {
GKI_freebuf(p_msg);
}
}
}
@@ -1220,9 +1430,11 @@ void gatts_process_attribute_req (tGATT_TCB *p_tcb, UINT8 op_code,
case GATT_REQ_WRITE: /* write char/char descriptor value */
case GATT_CMD_WRITE:
case GATT_SIGN_CMD_WRITE:
case GATT_REQ_PREPARE_WRITE:
gatts_process_write_req(p_tcb, i, handle, op_code, len, p);
break;
case GATT_REQ_PREPARE_WRITE:
gatt_attr_process_prepare_write (p_tcb, i, handle, op_code, len, p);
default:
break;
}

View File

@@ -116,6 +116,26 @@ void gatt_free_pending_enc_queue(tGATT_TCB *p_tcb)
}
}
/*******************************************************************************
**
** Function gatt_free_pending_prepare_write_queue
**
** Description Free all buffers in pending prepare write packets queue
**
** Returns None
**
*******************************************************************************/
void gatt_free_pending_prepare_write_queue(tGATT_TCB *p_tcb)
{
GATT_TRACE_DEBUG("gatt_free_pending_prepare_write_queue");
/* release all queued prepare write packets */
while (!GKI_queue_is_empty(&(p_tcb->prepare_write_record.queue))) {
GKI_freebuf (GKI_dequeue (&(p_tcb->prepare_write_record.queue)));
}
p_tcb->prepare_write_record.total_num = 0;
p_tcb->prepare_write_record.error_code_app = GATT_SUCCESS;
}
/*******************************************************************************
**
** Function gatt_delete_dev_from_srv_chg_clt_list
@@ -377,11 +397,38 @@ tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_app_id (tBT_UUID *p_app_uuid128,
}
/*******************************************************************************
**
** Function gatt_free_attr_value_buffer
**
** Description free characteristic attribute value buffer in a service
**
** Returns None
**
*******************************************************************************/
void gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM *p)
{
if (p){
tGATT_SVC_DB *p_db = &(p->svc_db);
tGATT_ATTR16 *p_attr = p_db->p_attr_list;
tGATT_ATTR_VALUE *p_value = NULL;
while(p_attr){
if (p_attr->mask & GATT_ATTR_VALUE_ALLOCATED){
p_value = p_attr->p_value;
if ((p_value != NULL) && (p_value->attr_val.attr_val != NULL)){
GKI_freebuf(p_value->attr_val.attr_val);
}
}
p_attr = p_attr->p_next;
}
}
}
/*******************************************************************************
**
** Function gatt_free_hdl_buffer
**
** Description free a handle buffer
** Description free a handle buffer
**
** Returns None
** Returns None
**
*******************************************************************************/
void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p)
@@ -2108,6 +2155,7 @@ void gatt_cleanup_upon_disc(BD_ADDR bda, UINT16 reason, tBT_TRANSPORT transport)
btu_stop_timer (&p_tcb->conf_timer_ent);
gatt_free_pending_ind(p_tcb);
gatt_free_pending_enc_queue(p_tcb);
gatt_free_pending_prepare_write_queue(p_tcb);
for (i = 0; i < GATT_MAX_APPS; i ++) {
p_reg = &gatt_cb.cl_rcb[i];

View File

@@ -133,6 +133,16 @@ typedef struct {
UINT8 reason;
} tGATT_ERROR;
/* Execute write response structure */
typedef struct {
UINT8 op_code;
}__attribute__((packed)) tGATT_EXEC_WRITE_RSP;
/* Write request response structure */
typedef struct {
UINT8 op_code;
}__attribute__((packed)) tGATT_WRITE_REQ_RSP;
/* server response message to ATT protocol
*/
typedef union {
@@ -175,6 +185,7 @@ typedef struct {
tGATT_ATTR_UUID_TYPE uuid_type;
tGATT_PERM permission;
tGATTS_ATTR_CONTROL control;
tGATT_ATTR_MASK mask;
UINT16 handle;
UINT16 uuid;
} tGATT_ATTR16;
@@ -187,6 +198,7 @@ typedef struct {
tGATT_ATTR_UUID_TYPE uuid_type;
tGATT_PERM permission;
tGATTS_ATTR_CONTROL control;
tGATT_ATTR_MASK mask;
UINT16 handle;
UINT32 uuid;
} tGATT_ATTR32;
@@ -200,6 +212,7 @@ typedef struct {
tGATT_ATTR_UUID_TYPE uuid_type;
tGATT_PERM permission;
tGATTS_ATTR_CONTROL control;
tGATT_ATTR_MASK mask;
UINT16 handle;
UINT8 uuid[LEN_UUID_128];
} tGATT_ATTR128;
@@ -329,6 +342,32 @@ typedef struct {
UINT16 count;
} tGATT_SRV_LIST_INFO;
/* prepare write queue data */
typedef struct{
//len: length of value
tGATT_ATTR16 *p_attr;
UINT16 len;
UINT8 op_code;
UINT16 handle;
UINT16 offset;
UINT8 value[2];
}__attribute__((packed)) tGATT_PREPARE_WRITE_QUEUE_DATA;
/* structure to store prepare write packts information */
typedef struct{
//only store prepare write packets which need
//to be responded by stack (not by application)
BUFFER_Q queue;
//store the total number of prepare write packets
//including that should be responded by stack or by application
UINT16 total_num;
//store application error code for prepare write,
//invalid offset && invalid length
UINT8 error_code_app;
}tGATT_PREPARE_WRITE_RECORD;
typedef struct {
BUFFER_Q pending_enc_clcb; /* pending encryption channel q */
tGATT_SEC_ACTION sec_act;
@@ -362,6 +401,7 @@ typedef struct {
BOOLEAN in_use;
UINT8 tcb_idx;
tGATT_PREPARE_WRITE_RECORD prepare_write_record; /* prepare write packets record */
} tGATT_TCB;
@@ -584,6 +624,7 @@ extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_handle(UINT16 handle);
extern tGATT_HDL_LIST_ELEM *gatt_find_hdl_buffer_by_attr_handle(UINT16 attr_handle);
extern tGATT_HDL_LIST_ELEM *gatt_alloc_hdl_buffer(void);
extern void gatt_free_hdl_buffer(tGATT_HDL_LIST_ELEM *p);
extern void gatt_free_attr_value_buffer(tGATT_HDL_LIST_ELEM *p);
extern BOOLEAN gatt_is_last_attribute(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_start, tBT_UUID value);
extern void gatt_update_last_pri_srv_info(tGATT_SRV_LIST_INFO *p_list);
extern BOOLEAN gatt_add_a_srv_to_list(tGATT_SRV_LIST_INFO *p_list, tGATT_SRV_LIST_ELEM *p_new);

View File

@@ -65,6 +65,8 @@
#define GATT_CONGESTED 0x8f
#define GATT_STACK_RSP 0x90
#define GATT_APP_RSP 0x91
//Error caused by customer application or stack bug
#define GATT_ESP_ERROR 0X9f
/* 0xE0 ~ 0xFC reserved for future use */
#define GATT_CCC_CFG_ERR 0xFD /* Client Characteristic Configuration Descriptor Improperly Configured */
@@ -324,6 +326,10 @@ typedef struct{
uint8_t auto_rsp;
}tGATTS_ATTR_CONTROL;
/* Mask for gatt server attribute */
#define GATT_ATTR_VALUE_ALLOCATED 0x01
typedef UINT8 tGATT_ATTR_MASK;
/* Union of the event data which is used in the server respond API to carry the server response information
*/
typedef union {

View File

@@ -27,13 +27,24 @@
#include "esp_task.h"
#include "esp_intr.h"
#include "esp_attr.h"
#include "esp_phy_init.h"
#include "bt.h"
#if CONFIG_BT_ENABLED
/* Bluetooth system and controller config */
#define BTDM_CFG_BT_EM_RELEASE (1<<0)
#define BTDM_CFG_BT_DATA_RELEASE (1<<1)
/* Other reserved for future */
/* not for user call, so don't put to include file */
extern void btdm_osi_funcs_register(void *osi_funcs);
extern void btdm_controller_init(void);
extern void btdm_controller_init(uint32_t config_mask);
extern void btdm_controller_schedule(void);
extern void btdm_controller_deinit(void);
extern int btdm_controller_enable(esp_bt_mode_t mode);
extern int btdm_controller_disable(esp_bt_mode_t mode);
extern void btdm_rf_bb_init(void);
/* VHCI function interface */
typedef struct vhci_host_callback {
@@ -67,9 +78,17 @@ struct osi_funcs_t {
void *(*_mutex_create)(void);
int32_t (*_mutex_lock)(void *mutex);
int32_t (*_mutex_unlock)(void *mutex);
esp_err_t (* _read_efuse_mac)(uint8_t mac[6]);
int32_t (* _read_efuse_mac)(uint8_t mac[6]);
void (* _srand)(unsigned int seed);
int (* _rand)(void);
};
/* Static variable declare */
static bool btdm_bb_init_flag = false;
static esp_bt_controller_status_t btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
static xTaskHandle btControllerTaskHandle;
static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
static void IRAM_ATTR interrupt_disable(void)
@@ -112,6 +131,21 @@ static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex)
return (int32_t)xSemaphoreGive(mutex);
}
static int32_t IRAM_ATTR read_mac_wrapper(uint8_t mac[6])
{
return esp_read_mac(mac, ESP_MAC_BT);
}
static void IRAM_ATTR srand_wrapper(unsigned int seed)
{
/* empty function */
}
static int IRAM_ATTR rand_wrapper(void)
{
return (int)esp_random();
}
static struct osi_funcs_t osi_funcs = {
._set_isr = xt_set_interrupt_handler,
._ints_on = xt_ints_on,
@@ -124,7 +158,9 @@ static struct osi_funcs_t osi_funcs = {
._mutex_create = mutex_create_wrapper,
._mutex_lock = mutex_lock_wrapper,
._mutex_unlock = mutex_unlock_wrapper,
._read_efuse_mac = esp_efuse_read_mac,
._read_efuse_mac = read_mac_wrapper,
._srand = srand_wrapper,
._rand = rand_wrapper,
};
bool esp_vhci_host_check_send_available(void)
@@ -142,17 +178,104 @@ void esp_vhci_host_register_callback(const esp_vhci_host_callback_t *callback)
API_vhci_host_register_callback((const vhci_host_callback_t *)callback);
}
static uint32_t btdm_config_mask_load(void)
{
uint32_t mask = 0x0;
#ifdef CONFIG_BT_DRAM_RELEASE
mask |= (BTDM_CFG_BT_EM_RELEASE | BTDM_CFG_BT_DATA_RELEASE);
#endif
return mask;
}
static void bt_controller_task(void *pvParam)
{
uint32_t btdm_cfg_mask = 0;
btdm_osi_funcs_register(&osi_funcs);
btdm_controller_init();
btdm_cfg_mask = btdm_config_mask_load();
btdm_controller_init(btdm_cfg_mask);
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
/* Loop */
btdm_controller_schedule();
}
void esp_bt_controller_init()
{
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_IDLE) {
return;
}
xTaskCreatePinnedToCore(bt_controller_task, "btController",
ESP_TASK_BT_CONTROLLER_STACK, NULL,
ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0);
ESP_TASK_BT_CONTROLLER_PRIO, &btControllerTaskHandle, 0);
}
void esp_bt_controller_deinit(void)
{
vTaskDelete(btControllerTaskHandle);
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_IDLE;
}
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode)
{
int ret;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_INITED) {
return ESP_ERR_INVALID_STATE;
}
if (mode != ESP_BT_MODE_BTDM) {
return ESP_ERR_INVALID_ARG;
}
esp_phy_load_cal_and_init();
if (btdm_bb_init_flag == false) {
btdm_bb_init_flag = true;
btdm_rf_bb_init(); /* only initialise once */
}
ret = btdm_controller_enable(mode);
if (ret) {
return ESP_ERR_INVALID_STATE;
}
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_ENABLED;
return ESP_OK;
}
esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode)
{
int ret;
if (btdm_controller_status != ESP_BT_CONTROLLER_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}
if (mode != ESP_BT_MODE_BTDM) {
return ESP_ERR_INVALID_ARG;
}
ret = btdm_controller_disable(mode);
if (ret) {
return ESP_ERR_INVALID_STATE;
}
esp_phy_rf_deinit();
btdm_controller_status = ESP_BT_CONTROLLER_STATUS_INITED;
return ESP_OK;
}
esp_bt_controller_status_t esp_bt_controller_get_status(void)
{
return btdm_controller_status;
}
#endif

View File

@@ -23,14 +23,63 @@
extern "C" {
#endif
/**
* @brief Bluetooth mode for controller enable/disable
*/
typedef enum {
ESP_BT_MODE_ILDE = 0x00, /*!< Bluetooth is not run */
ESP_BT_MODE_BLE = 0x01, /*!< Run BLE mode */
ESP_BT_MODE_CLASSIC_BT = 0x02, /*!< Run Classic BT mode */
ESP_BT_MODE_BTDM = 0x03, /*!< Run dual mode */
} esp_bt_mode_t;
/**
* @brief Initialize BT controller
* @brief Bluetooth controller enable/disable/initialised/de-initialised status
*/
typedef enum {
ESP_BT_CONTROLLER_STATUS_IDLE = 0,
ESP_BT_CONTROLLER_STATUS_INITED,
ESP_BT_CONTROLLER_STATUS_ENABLED,
ESP_BT_CONTROLLER_STATUS_NUM,
} esp_bt_controller_status_t;
/**
* @brief Initialize BT controller to allocate task and other resource.
*
* This function should be called only once, before any other BT functions are called.
*/
void esp_bt_controller_init(void);
/**
* @brief De-initialize BT controller to free resource and delete task.
*
* This function should be called only once, after any other BT functions are called.
* This function is not whole completed, esp_bt_controller_init cannot called after this function.
*/
void esp_bt_controller_deinit(void);
/**
* @brief Enable BT controller
* @param mode : the mode(BLE/BT/BTDM) to enable.
* Now only support BTDM.
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_enable(esp_bt_mode_t mode);
/**
* @brief Disable BT controller
* @param mode : the mode(BLE/BT/BTDM) to disable.
* Now only support BTDM.
* @return ESP_OK - success, other - failed
*/
esp_err_t esp_bt_controller_disable(esp_bt_mode_t mode);
/**
* @brief Get BT controller is initialised/de-initialised/enabled/disabled
* @return status value
*/
esp_bt_controller_status_t esp_bt_controller_get_status(void);
/** @brief esp_vhci_host_callback
* used for vhci call host function to notify what host need to do
*/

View File

@@ -49,11 +49,11 @@ typedef enum {
} adc1_channel_t;
/**
* @brief Configuration ADC1 capture width.
* @brief Configure ADC1 capture width.
*
* The configuration is in effect for all channels of ADC1
* The configuration is for all channels of ADC1
*
* @param width_bit ADC1
* @param width_bit Bit capture width for ADC1
*
* @return
* - ESP_OK success
@@ -62,10 +62,29 @@ typedef enum {
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
/**
* @brief Configuration ADC1 capture attenuation of channels.
* @brief Configure the ADC1 channel, including setting attenuation.
*
* @param channel the ADC1 channel
* @param atten attenuation
* @note This function also configures the input GPIO pin mux to
* connect it to the ADC1 channel. It must be called before calling
* adc1_get_voltage() for this channel.
*
* The default ADC full-scale voltage is 1.1V. To read higher voltages (up to the pin maximum voltage,
* usually 3.3V) requires setting >0dB signal attenuation for that ADC channel.
*
* When VDD_A is 3.3V:
*
* - 0dB attenuaton (ADC_ATTEN_0db) gives full-scale voltage 1.1V
* - 2.5dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5V
* - 6dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2V
* - 11dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9V (see note below)
*
* @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured
* bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
*
* @note At 11dB attenuation the maximum voltage is limited by VDD_A, not the full scale voltage.
*
* @param channel ADC1 channel to configure
* @param atten Attenuation level
*
* @return
* - ESP_OK success
@@ -74,46 +93,38 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit);
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten);
/**
* @brief ADC1 get the value of the voltage.
* @brief Take an ADC1 reading on a single channel
*
* @param channel the ADC1 channel
* @note Call adc1_config_width() before the first time this
* function is called.
*
* @note For a given channel, adc1_config_channel_atten(channel)
* must be called before the first time this function is called.
*
* @param channel ADC1 channel to read
*
* @return
* - -1 Parameter error
* - Other the value of ADC1 channel
* - -1: Parameter error
* - Other: ADC1 channel reading.
*/
int adc1_get_voltage(adc1_channel_t channel);
/**
* @brief Hall Sensor output value.
* @note
* The Hall Sensor uses Channel_0 and Channel_3 of ADC1.
* So, firstly: please configure ADC1 module by calling adc1_config_width before calling hall_sensor_read.
We recommend that the WIDTH ADC1 be configured as 12Bit, because the values of hall_sensor_read are small and almost the same if WIDTH ADC1 is configured as 9Bit, 10Bit or 11Bit.
* secondly: when you use the hall sensor, please do not use Channel_0 and Channel_3 of ADC1 as
* ADC channels.
* @brief Read Hall Sensor
*
* @return the value of hall sensor
* @note The Hall Sensor uses channels 0 and 3 of ADC1. Do not configure
* these channels for use as ADC channels.
*
* @note The ADC1 module must be enabled by calling
* adc1_config_width() before calling hall_sensor_read(). ADC1
* should be configured for 12 bit readings, as the hall sensor
* readings are low values and do not cover the full range of the
* ADC.
*
* @return The hall sensor reading.
*/
int hall_sensor_read();
/**
*----------EXAMPLE TO USE ADC1------------ *
* @code{c}
* adc1_config_width(ADC_WIDTH_12Bit);//config adc1 width
* adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db);//config channel0 attenuation
* int val=adc1_get_voltage(ADC1_CHANNEL_0);//get the val of channel0
* @endcode
**/
/**
*----------EXAMPLE TO USE HALL SENSOR------------ *
* @code{c}
* adc1_config_width(ADC_WIDTH_12Bit);//config adc1 width
* int val=hall_sensor_read();
* @endcode
**/
#ifdef __cplusplus
}
#endif

View File

@@ -29,12 +29,15 @@ typedef enum {
} dac_channel_t;
/**
* @brief Set Dac output voltage.
* @brief Set DAC output voltage.
*
* Dac width is 8bit ,and the voltage max is vdd
* DAC output is 8-bit. Maximum (255) corresponds to VDD.
*
* @param channel dac channel
* @param dac_value dac output value
* @note When this function is called, function for the DAC
* channel's GPIO pin is reconfigured for RTC DAC function.
*
* @param channel DAC channel
* @param dac_value DAC output value
*
* @return
* - ESP_OK success
@@ -42,13 +45,6 @@ typedef enum {
*/
esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value);
/**
*----------EXAMPLE TO USE DAC------------ *
* @code{c}
* dac_out_voltage(DAC_CHANNEL_1,200);//the dac out voltage ≈ 200*vdd/255
* @endcode
**/
#ifdef __cplusplus
}
#endif

View File

@@ -302,9 +302,9 @@ int gpio_get_level(gpio_num_t gpio_num);
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
/**
* @brief GPIO set pull
* @brief Configure GPIO pull-up/pull-down resistors
*
* User this Function,configure GPIO pull mode,such as pull-up,pull-down
* Only pins that support both input & output have integrated pull-up and pull-down resistors. Input-only GPIOs 34-39 do not.
*
* @param gpio_num GPIO number. If you want to set pull up or down mode for e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
* @param pull GPIO pull up/down mode.
@@ -317,7 +317,7 @@ esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
/**
* @brief enable GPIO wake-up function.
* @brief Enable GPIO wake-up function.
*
* @param gpio_num GPIO number.
*
@@ -341,15 +341,23 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
/**
* @brief register GPIO interrupt handler, the handler is an ISR.
* @brief Register GPIO interrupt handler, the handler is an ISR.
* The handler will be attached to the same CPU core that this function is running on.
*
* This ISR function is called whenever any GPIO interrupt occurs. See
* the alternative gpio_install_isr_service() and
* gpio_isr_handler_add() API in order to have the driver support
* per-GPIO ISRs.
*
* @param fn Interrupt handler function.
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param arg Parameter for handler function
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
* be returned here.
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will be returned here.
*
* \verbatim embed:rst:leading-asterisk
* To disable or remove the ISR, pass the returned handle to the :doc:`interrupt allocation functions </api/system/intr_alloc>`.
* \endverbatim
*
* @return
* - ESP_OK Success ;
@@ -402,7 +410,9 @@ esp_err_t gpio_pulldown_en(gpio_num_t gpio_num);
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
/**
* @brief Install a GPIO ISR service, so we can assign different ISR handler for different pins
* @brief Install the driver's GPIO ISR handler service, which allows per-pin GPIO interrupt handlers.
*
* This function is incompatible with gpio_isr_register() - if that function is used, a single global ISR is registered for all GPIO interrupts. If this function is used, the ISR service provides a global GPIO ISR and individual pin handlers are registered via the gpio_isr_register() function.
*
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
@@ -415,17 +425,24 @@ esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
esp_err_t gpio_install_isr_service(int intr_alloc_flags);
/**
* @brief Un-install GPIO ISR service, free the resources.
* @brief Uninstall the driver's GPIO ISR service, freeing related resources.
*/
void gpio_uninstall_isr_service();
/**
* @brief Add ISR handler for the corresponding GPIO.
* @brief Add ISR handler for the corresponding GPIO pin.
*
* Interrupt handlers no longer need to be declared with IRAM_ATTR, unless you pass the ESP_INTR_FLAG_IRAM flag
* when allocating the ISR in gpio_install_isr_service().
* This ISR handler will be called from an ISR. So there probably is some stack size limit, and this limit
* is smaller compared to a "raw" interrupt handler due to another level of indirection.
* Call this function after using gpio_install_isr_service() to
* install the driver's GPIO ISR handler service.
*
* The pin ISR handlers no longer need to be declared with IRAM_ATTR,
* unless you pass the ESP_INTR_FLAG_IRAM flag when allocating the
* ISR in gpio_install_isr_service().
*
* This ISR handler will be called from an ISR. So there is a stack
* size limit (configurable as "ISR stack size" in menuconfig). This
* limit is smaller compared to a global GPIO interrupt handler due
* to the additional level of indirection.
*
* @param gpio_num GPIO number
* @param isr_handler ISR handler function for the corresponding GPIO number.
@@ -439,7 +456,7 @@ void gpio_uninstall_isr_service();
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void* args);
/**
* @brief Remove ISR handler for the corresponding GPIO.
* @brief Remove ISR handler for the corresponding GPIO pin.
*
* @param gpio_num GPIO number
*

View File

@@ -32,9 +32,6 @@
extern "C" {
#endif
#define I2S_PIN_NO_CHANGE (-1)
/**
* @brief I2S bit width per sample.
*
@@ -147,6 +144,8 @@ typedef struct {
size_t size; /*!< I2S data size for I2S_DATA event*/
} i2s_event_t;
#define I2S_PIN_NO_CHANGE (-1) /*!< Use in i2s_pin_config_t for pins which should not be changed */
/**
* @brief I2S pin number for i2s_set_pin
*
@@ -160,15 +159,18 @@ typedef struct {
typedef intr_handle_t i2s_isr_handle_t;
/**
* @brief Set I2S pin number
* @brief Set I2S pin number
*
* @note
* Internal signal can be output to multiple GPIO pads
* Only one GPIO pad can connect with input signal
* @note
* The I2S peripheral output signals can be connected to multiple GPIO pads.
* However, the I2S peripheral input signal can only be connected to one GPIO pad.
*
* @param i2s_num I2S_NUM_0 or I2S_NUM_1
*
* @param pin I2S Pin struct, or NULL for 2-channels, 8-bits DAC pin configuration (GPIO25 & GPIO26)
* @param pin I2S Pin structure, or NULL to set 2-channel 8-bit internal DAC pin configuration (GPIO25 & GPIO26)
*
* Inside the pin configuration structure, set I2S_PIN_NO_CHANGE for any pin where
* the current configuration should not be changed.
*
* @return
* - ESP_OK Success
@@ -177,15 +179,17 @@ typedef intr_handle_t i2s_isr_handle_t;
esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin);
/**
* @brief i2s install and start driver
* @brief Install and start I2S driver.
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @param i2s_config I2S configurations - see i2s_config_t struct
* @param i2s_config I2S configurations - see i2s_config_t struct
*
* @param queue_size I2S event queue size/depth.
* @param queue_size I2S event queue size/depth.
*
* @param i2s_queue I2S event queue handle, if set NULL, driver will not use an event queue.
* @param i2s_queue I2S event queue handle, if set NULL, driver will not use an event queue.
*
* This function must be called before any I2S driver read/write operations.
*
* @return
* - ESP_OK Success
@@ -205,68 +209,88 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
esp_err_t i2s_driver_uninstall(i2s_port_t i2s_num);
/**
* @brief i2s read data buffer to i2s dma buffer
* @brief Write data to I2S DMA transmit buffer.
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @param src source address to write
* @param src Source address to write from
*
* @param size size of data (size in bytes)
* @param size Size of data in bytes
*
* @param ticks_to_wait Write timeout
* @param ticks_to_wait TX buffer wait timeout in RTOS ticks. If this
* many ticks pass without space becoming available in the DMA
* transmit buffer, then the function will return (note that if the
* data is written to the DMA buffer in pieces, the overall operation
* may still take longer than this timeout.) Pass portMAX_DELAY for no
* timeout.
*
* @return number of written bytes
* Format of the data in source buffer is determined by the I2S
* configuration (see i2s_config_t).
*
* @return Number of bytes written, or ESP_FAIL (-1) for parameter error. If a timeout occurred, bytes written will be less than total size.
*/
int i2s_write_bytes(i2s_port_t i2s_num, const char *src, size_t size, TickType_t ticks_to_wait);
/**
* @brief i2s write data buffer to i2s dma buffer
* @brief Read data from I2S DMA receive buffer
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @param dest destination address to read
* @param dest Destination address to read into
*
* @param size size of data (size in bytes)
* @param size Size of data in bytes
*
* @param ticks_to_wait Read timeout
* @param ticks_to_wait RX buffer wait timeout in RTOS ticks. If this many ticks pass without bytes becoming available in the DMA receive buffer, then the function will return (note that if data is read from the DMA buffer in pieces, the overall operation may still take longer than this timeout.) Pass portMAX_DELAY for no timeout.
*
* @return number of read bytes
* Format of the data in source buffer is determined by the I2S
* configuration (see i2s_config_t).
*
* @return Number of bytes read, or ESP_FAIL (-1) for parameter error. If a timeout occurred, bytes read will be less than total size.
*/
int i2s_read_bytes(i2s_port_t i2s_num, char* dest, size_t size, TickType_t ticks_to_wait);
/**
* @brief i2s push 1 sample to i2s dma buffer, with the size parameter equal to one sample's size in bytes = bits_per_sample/8.
* @brief Push (write) a single sample to the I2S DMA TX buffer.
*
* Size of the sample is determined by the channel_format (mono or stereo)) & bits_per_sample configuration (see i2s_config_t).
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @param sample destination address to write (depend on bits_per_sample, size of sample (in bytes) = 2*bits_per_sample/8)
* @param sample Pointer to buffer containing sample to write. Size of buffer (in bytes) = (number of channels) * bits_per_sample / 8.
*
* @param ticks_to_wait Push timeout
* @param ticks_to_wait Push timeout in RTOS ticks. If space is not available in the DMA TX buffer within this period, no data is written and function returns 0.
*
* @return number of push bytes
* @return Number of bytes successfully pushed to DMA buffer, or ESP_FAIL (-1) for parameter error. Will be either zero or the size of configured sample buffer.
*/
int i2s_push_sample(i2s_port_t i2s_num, const char *sample, TickType_t ticks_to_wait);
/**
* @brief Pop 1 sample to i2s dma buffer, with the size parameter equal to one sample's size in bytes = bits_per_sample/8.
* @brief Pop (read) a single sample from the I2S DMA RX buffer.
*
* Size of the sample is determined by the channel_format (mono or stereo)) & bits_per_sample configuration (see i2s_config_t).
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @param sample destination address to write (depend on bits_per_sample, size of sample (in bytes) = 2*bits_per_sample/8)
* @param sample Buffer sample data will be read into. Size of buffer (in bytes) = (number of channels) * bits_per_sample / 8.
*
* @param ticks_to_wait Pop timeout
* @param ticks_to_wait Pop timeout in RTOS ticks. If a sample is not available in the DMA buffer within this period, no data is read and function returns zero.
*
* @return number of pop bytes
* @return Number of bytes successfully read from DMA buffer, or ESP_FAIL (-1) for parameter error. Byte count will be either zero or the size of the configured sample buffer.
*/
int i2s_pop_sample(i2s_port_t i2s_num, char *sample, TickType_t ticks_to_wait);
/**
* @brief Set clock rate used for I2S RX and TX
* @brief Set sample rate used for I2S RX and TX.
*
* The bit clock rate is determined by the sample rate and i2s_config_t configuration parameters (number of channels, bits_per_sample).
*
* `bit_clock = rate * (number of channels) * bits_per_sample`
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @param rate I2S clock (ex: 8000, 44100...)
* @param rate I2S sample rate (ex: 8000, 44100...)
*
* @return
* - ESP_OK Success
@@ -275,18 +299,9 @@ int i2s_pop_sample(i2s_port_t i2s_num, char *sample, TickType_t ticks_to_wait);
esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate);
/**
* @brief Start driver
* @brief Stop I2S driver
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t i2s_start(i2s_port_t i2s_num);
/**
* @brief Stop driver
* Disables I2S TX/RX, until i2s_start() is called.
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
@@ -297,7 +312,23 @@ esp_err_t i2s_start(i2s_port_t i2s_num);
esp_err_t i2s_stop(i2s_port_t i2s_num);
/**
* @brief Set the TX DMA buffer contents to all zeroes
* @brief Start I2S driver
*
* It is not necessary to call this function after i2s_driver_install() (it is started automatically), however it is necessary to call it after i2s_stop().
*
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t i2s_start(i2s_port_t i2s_num);
/**
* @brief Zero the contents of the TX DMA buffer.
*
* Pushes zero-byte samples into the TX DMA buffer, until it is full.
*
* @param i2s_num I2S_NUM_0, I2S_NUM_1
*
@@ -307,72 +338,6 @@ esp_err_t i2s_stop(i2s_port_t i2s_num);
*/
esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num);
/***************************EXAMPLE**********************************
*
*
* ----------------EXAMPLE OF I2S SETTING ---------------------
* @code{c}
*
* #include "freertos/queue.h"
* #define I2S_INTR_NUM 17 //choose one interrupt number from soc.h
* int i2s_num = 0; //i2s port number
* i2s_config_t i2s_config = {
* .mode = I2S_MODE_MASTER | I2S_MODE_TX,
* .sample_rate = 44100,
* .bits_per_sample = 16, //16, 32
* .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //format LEFT_RIGHT
* .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
* .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
* .dma_buf_count = 8,
* .dma_buf_len = 64
* };
*
* i2s_pin_config_t pin_config = {
* .bck_io_num = 26,
* .ws_io_num = 25,
* .data_out_num = 22,
* .data_in_num = I2S_PIN_NO_CHANGE
* };
*
* i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver
*
* i2s_set_pin(i2s_num, &pin_config);
*
* i2s_set_sample_rates(i2s_num, 22050); //set sample rates
*
*
* i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver
*@endcode
*
* ----------------EXAMPLE USING I2S WITH DAC ---------------------
* @code{c}
*
* #include "freertos/queue.h"
* #define I2S_INTR_NUM 17 //choose one interrupt number from soc.h
* int i2s_num = 0; //i2s port number
* i2s_config_t i2s_config = {
* .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN,
* .sample_rate = 44100,
* .bits_per_sample = 8, // Only 8-bit DAC support
* .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, //
* .communication_format = I2S_COMM_FORMAT_I2S_MSB,
* .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
* .dma_buf_count = 8,
* .dma_buf_len = 64
* };
*
*
* i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver
*
* i2s_set_pin(i2s_num, NULL); //for internal DAC
*
* i2s_set_sample_rates(i2s_num, 22050); //set sample rates
*
* i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver
*@endcode
*-----------------------------------------------------------------------------*
***************************END OF EXAMPLE**********************************/
#ifdef __cplusplus
}
#endif

View File

@@ -24,7 +24,10 @@ extern "C" {
#endif
/**
* @brief Pullup/pulldown information for a single GPIO pad
* @brief Pin function information for a single GPIO pad's RTC functions.
*
* This is an internal function of the driver, and is not usually useful
* for external use.
*/
typedef struct {
uint32_t reg; /*!< Register of RTC pad, or 0 if not an RTC GPIO */
@@ -46,10 +49,29 @@ typedef enum {
RTC_GPIO_MODE_DISABLED, /*!< Pad (output + input) disable */
} rtc_gpio_mode_t;
#define RTC_GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && rtc_gpio_desc[gpio_num].reg != 0)) //to decide whether it is a valid GPIO number
/**
* @brief Provides access to a constant table of RTC I/O pin
* function information.
*
* This is an internal function of the driver, and is not usually useful
* for external use.
*/
extern const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT];
/**
* @brief Determine if the specified GPIO is a valid RTC GPIO.
*
* @param gpio_num GPIO number
* @return true if GPIO is valid for RTC GPIO use. talse otherwise.
*/
inline static bool rtc_gpio_is_valid_gpio(gpio_num_t gpio_num)
{
return gpio_num < GPIO_PIN_COUNT
&& rtc_gpio_desc[gpio_num].reg != 0;
}
#define RTC_GPIO_IS_VALID_GPIO(gpio_num) rtc_gpio_is_valid_gpio(gpio_num) // Deprecated, use rtc_gpio_is_valid_gpio()
/**
* @brief Init a GPIO as RTC GPIO
*

View File

@@ -50,10 +50,12 @@ extern "C" {
typedef struct {
gpio_num_t gpio_cd; ///< GPIO number of card detect signal
gpio_num_t gpio_wp; ///< GPIO number of write protect signal
uint8_t width; ///< Bus width used by the slot (might be less than the max width supported)
} sdmmc_slot_config_t;
#define SDMMC_SLOT_NO_CD ((gpio_num_t) -1) ///< indicates that card detect line is not used
#define SDMMC_SLOT_NO_WP ((gpio_num_t) -1) ///< indicates that write protect line is not used
#define SDMMC_SLOT_WIDTH_DEFAULT 0 ///< use the default width for the slot (8 for slot 0, 4 for slot 1)
/**
* Macro defining default configuration of SDMMC host slot
@@ -61,6 +63,7 @@ typedef struct {
#define SDMMC_SLOT_CONFIG_DEFAULT() {\
.gpio_cd = SDMMC_SLOT_NO_CD, \
.gpio_wp = SDMMC_SLOT_NO_WP, \
.width = SDMMC_SLOT_WIDTH_DEFAULT, \
}
/**

View File

@@ -469,8 +469,6 @@ esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_
* @brief Install UART driver.
*
* UART ISR handler will be attached to the same CPU core that this function is running on.
* Users should know that which CPU is running and then pick a INUM that is not used by system.
* We can find the information of INUM and interrupt level in soc.h.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param rx_buffer_size UART RX ring buffer size, rx_buffer_size should be greater than UART_FIFO_LEN.
@@ -644,7 +642,6 @@ esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, u
* @code{c}
* //1. Setup UART
* #include "freertos/queue.h"
* #define UART_INTR_NUM 17 //choose one interrupt number from soc.h
* //a. Set UART parameter
* int uart_num = 0; //uart port number
* uart_config_t uart_config = {

View File

@@ -87,7 +87,7 @@ const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
---------------------------------------------------------------*/
esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux));
@@ -100,7 +100,7 @@ esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Select Gpio as Digital Gpio
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux));
@@ -131,7 +131,7 @@ static esp_err_t rtc_gpio_output_disable(gpio_num_t gpio_num)
static esp_err_t rtc_gpio_input_enable(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie);
portEXIT_CRITICAL(&rtc_spinlock);
@@ -141,7 +141,7 @@ static esp_err_t rtc_gpio_input_enable(gpio_num_t gpio_num)
static esp_err_t rtc_gpio_input_disable(gpio_num_t gpio_num)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie);
portEXIT_CRITICAL(&rtc_spinlock);
@@ -152,7 +152,7 @@ static esp_err_t rtc_gpio_input_disable(gpio_num_t gpio_num)
esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
{
int rtc_gpio_num = rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;;
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
if (level) {
WRITE_PERI_REG(RTC_GPIO_OUT_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_OUT_DATA_W1TS_S)));
@@ -167,7 +167,7 @@ uint32_t rtc_gpio_get_level(gpio_num_t gpio_num)
{
uint32_t level = 0;
int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
level = READ_PERI_REG(RTC_GPIO_IN_REG);
@@ -177,7 +177,7 @@ uint32_t rtc_gpio_get_level(gpio_num_t gpio_num)
esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode)
{
RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(rtc_gpio_is_valid_gpio(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG);
switch (mode) {
case RTC_GPIO_MODE_INPUT_ONLY:

View File

@@ -299,20 +299,31 @@ esp_err_t sdmmc_host_init_slot(int slot, const sdmmc_slot_config_t* slot_config)
}
int gpio_cd = slot_config->gpio_cd;
int gpio_wp = slot_config->gpio_wp;
uint8_t slot_width = slot_config->width;
// Configure pins
const sdmmc_slot_info_t* pslot = &s_slot_info[slot];
if (slot_width == SDMMC_SLOT_WIDTH_DEFAULT) {
slot_width = pslot->width;
}
else if (slot_width > pslot->width) {
return ESP_ERR_INVALID_ARG;
}
configure_pin(pslot->clk);
configure_pin(pslot->cmd);
configure_pin(pslot->d0);
configure_pin(pslot->d1);
configure_pin(pslot->d2);
configure_pin(pslot->d3);
if (pslot->width == 8) {
configure_pin(pslot->d4);
configure_pin(pslot->d5);
configure_pin(pslot->d6);
configure_pin(pslot->d7);
if (slot_width >= 4) {
configure_pin(pslot->d1);
configure_pin(pslot->d2);
configure_pin(pslot->d3);
if (slot_width == 8) {
configure_pin(pslot->d4);
configure_pin(pslot->d5);
configure_pin(pslot->d6);
configure_pin(pslot->d7);
}
}
if (gpio_cd != -1) {
gpio_set_direction(gpio_cd, GPIO_MODE_INPUT);

View File

@@ -502,6 +502,7 @@ static void IRAM_ATTR spi_intr(void *arg)
//We have a transaction. Send it.
spi_device_t *dev=host->device[i];
host->cur_trans=trans;
host->cur_cs=i;
//We should be done with the transmission.
assert(host->hw->cmd.usr == 0);
@@ -510,7 +511,7 @@ static void IRAM_ATTR spi_intr(void *arg)
trans->rxlength=trans->length;
}
//Reconfigure accoding to device settings, but only if we change CSses.
//Reconfigure according to device settings, but only if we change CSses.
if (i!=prevCs) {
//Assumes a hardcoded 80MHz Fapb for now. ToDo: figure out something better once we have
//clock scaling working.
@@ -599,7 +600,7 @@ static void IRAM_ATTR spi_intr(void *arg)
} else {
data=trans->rx_buffer;
}
if (trans->rxlength<THRESH_DMA_TRANS) {
if (trans->rxlength <= THRESH_DMA_TRANS) {
//No need for DMA; we'll copy the result out of the work registers directly later.
} else {
host->hw->user.usr_miso_highpart=0;
@@ -624,9 +625,9 @@ static void IRAM_ATTR spi_intr(void *arg)
} else {
data=(uint32_t *)trans->tx_buffer;
}
if (trans->rxlength < 8*32) {
if (trans->length <= THRESH_DMA_TRANS) {
//No need for DMA.
for (int x=0; x < trans->rxlength; x+=32) {
for (int x=0; x < trans->length; x+=32) {
//Use memcpy to get around alignment issues for txdata
uint32_t word;
memcpy(&word, &data[x/32], 4);
@@ -655,7 +656,7 @@ static void IRAM_ATTR spi_intr(void *arg)
host->hw->addr=trans->address & 0xffffffff;
}
host->hw->user.usr_mosi=(trans->tx_buffer==NULL)?0:1;
host->hw->user.usr_miso=(trans->tx_buffer==NULL)?0:1;
host->hw->user.usr_miso=(trans->rx_buffer==NULL)?0:1;
//Call pre-transmission callback, if any
if (dev->cfg.pre_cb) dev->cfg.pre_cb(trans);

View File

@@ -105,6 +105,28 @@ config MEMMAP_SPISRAM
main memory map. Enable this if you have this hardware and want to use it in the same
way as on-chip RAM.
choice NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
bool "Number of MAC address generated from the hardware MAC address in efuse"
default FOUR_MAC_ADDRESS_FROM_EFUSE
help
Config the number of MAC address which is generated from the hardware MAC address in efuse.
If the number is two, the MAC addresses of WiFi station and bluetooth are generated from
the hardware MAC address in efuse. The MAC addresses of WiFi softap and ethernet are derived
from that of WiFi station and bluetooth respectively.
If the number is four, the MAC addresses of WiFi station, WiFi softap, bluetooth and ethernet
are all generated from the hardware MAC address in efuse.
config TWO_MAC_ADDRESS_FROM_EFUSE
bool "Two"
config FOUR_MAC_ADDRESS_FROM_EFUSE
bool "Four"
endchoice
config NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
int
default 2 if TWO_MAC_ADDRESS_FROM_EFUSE
default 4 if FOUR_MAC_ADDRESS_FROM_EFUSE
config SYSTEM_EVENT_QUEUE_SIZE
int "System event queue size"
default 32
@@ -491,15 +513,61 @@ config SW_COEXIST_ENABLE
automatically managed, no user intervention is required.
config ESP32_WIFI_RX_BUFFER_NUM
int "Max number of WiFi RX buffers"
config ESP32_WIFI_STATIC_RX_BUFFER_NUM
int "Max number of WiFi static RX buffers"
depends on WIFI_ENABLED
range 2 25
default 25
default 10
help
Set the number of WiFi rx buffers. Each buffer takes approximately 1.6KB of RAM.
Larger number for higher throughput but more memory. Smaller number for lower
throughput but less memory.
Set the number of WiFi static rx buffers. Each buffer takes approximately 1.6KB of RAM.
The static rx buffers are allocated when esp_wifi_init is called, they are not freed
until esp_wifi_deinit is called.
WiFi hardware use these buffers to receive packets, generally larger number for higher
throughput but more memory, smaller number for lower throughput but less memory.
config ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM
int "Max number of WiFi dynamic RX buffers"
depends on WIFI_ENABLED
range 0 64
default 0
help
Set the number of WiFi dynamic rx buffers, 0 means no limitation for dynamic rx buffer
allocation. The size of dynamic rx buffers is not fixed.
For each received packet in static rx buffers, WiFi driver makes a copy
to dynamic rx buffers and then deliver it to high layer stack. The dynamic rx buffer
is freed when the application, such as socket, successfully received the packet.
For some applications, the WiFi driver receiving speed is faster than application
consuming speed, we may run out of memory if no limitation for the dynamic rx buffer
number. Generally the number of dynamic rx buffer should be no less than static
rx buffer number if it is not 0.
config ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM
int "Max number of WiFi dynamic TX buffers"
depends on WIFI_ENABLED
range 16 64
default 32
help
Set the number of WiFi dynamic tx buffers, 0 means no limitation for dynamic tx buffer
allocation. The size of dynamic tx buffers is not fixed.
For each tx packet from high layer stack, WiFi driver make a copy of it. For some applications,
especially the UDP application, the high layer deliver speed is faster than the WiFi tx
speed, we may run out of memory if no limitation for the dynamic tx buffer number.
config ESP32_WIFI_AMPDU_ENABLED
bool "WiFi AMPDU"
depends on WIFI_ENABLED
default y
help
Select this option to enable AMPDU feature
config ESP32_WIFI_NVS_ENABLED
bool "WiFi NVS flash"
depends on WIFI_ENABLED
default y
help
Select this option to enable WiFi NVS flash
config PHY_ENABLED
bool
@@ -507,19 +575,15 @@ config PHY_ENABLED
menu PHY
visible if PHY_ENABLED
config ESP32_PHY_AUTO_INIT
bool "Initialize PHY in startup code"
config ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
bool "Do phy calibration and store calibration data in NVS"
depends on PHY_ENABLED
default y
help
If enabled, PHY will be initialized in startup code, before
app_main function runs.
If this is undesired, disable this option and call esp_phy_init
from the application before enabling WiFi or BT.
If this option is enabled, startup code will also initialize
NVS prior to initializing PHY.
If this option is enabled, NVS will be initialized and calibration data will be loaded from there.
PHY calibration will be skipped on deep sleep wakeup. If calibration data is not found, full calibration
will be performed and stored in NVS. In all other cases, only partial calibration will be performed.
If unsure, choose 'y'.

View File

@@ -3,7 +3,7 @@
#
COMPONENT_SRCDIRS := . hwcrypto
LIBS := core rtc
LIBS := core rtc rtc_clk
ifdef CONFIG_PHY_ENABLED # BT || WIFI
LIBS += phy coexist
endif

View File

@@ -26,16 +26,17 @@
#if CONFIG_ESP32_ENABLE_COREDUMP
#define LOG_LOCAL_LEVEL CONFIG_ESP32_CORE_DUMP_LOG_LEVEL
#include "esp_log.h"
const static char *TAG = "esp_core_dump";
const static DRAM_ATTR char TAG[] = "esp_core_dump";
#define ESP_COREDUMP_LOGE( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_ERROR) { ets_printf(LOG_FORMAT(E, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOGW( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_WARN) { ets_printf(LOG_FORMAT(W, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOGI( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { ets_printf(LOG_FORMAT(I, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOGD( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOGV( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_VERBOSE) { ets_printf(LOG_FORMAT(V, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOG( level, format, ... ) if (LOG_LOCAL_LEVEL >= level) { ets_printf(DRAM_STR(format), esp_log_early_timestamp(), (const char *)TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOGE( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_ERROR, LOG_FORMAT(E, format), ##__VA_ARGS__)
#define ESP_COREDUMP_LOGW( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_WARN, LOG_FORMAT(W, format), ##__VA_ARGS__)
#define ESP_COREDUMP_LOGI( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_INFO, LOG_FORMAT(I, format), ##__VA_ARGS__)
#define ESP_COREDUMP_LOGD( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_DEBUG, LOG_FORMAT(D, format), ##__VA_ARGS__)
#define ESP_COREDUMP_LOGV( format, ... ) ESP_COREDUMP_LOG(ESP_LOG_VERBOSE, LOG_FORMAT(V, format), ##__VA_ARGS__)
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) { ets_printf(LOG_FORMAT(D, format), esp_log_early_timestamp(), TAG, ##__VA_ARGS__); }
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) ESP_COREDUMP_LOGD(format, ##__VA_ARGS__)
#else
#define ESP_COREDUMP_LOG_PROCESS( format, ... ) do{/*(__VA_ARGS__);*/}while(0)
#endif
@@ -345,8 +346,9 @@ void esp_core_dump_to_flash(XtExcFrame *frame)
#endif
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8_t *dst) {
static const char *b64 =
const static DRAM_ATTR char b64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int i, j, a, b, c;
@@ -373,14 +375,14 @@ static void esp_core_dump_b64_encode(const uint8_t *src, uint32_t src_len, uint8
static esp_err_t esp_core_dump_uart_write_start(void *priv)
{
esp_err_t err = ESP_OK;
ets_printf("================= CORE DUMP START =================\r\n");
ets_printf(DRAM_STR("================= CORE DUMP START =================\r\n"));
return err;
}
static esp_err_t esp_core_dump_uart_write_end(void *priv)
{
esp_err_t err = ESP_OK;
ets_printf("================= CORE DUMP END =================\r\n");
ets_printf(DRAM_STR("================= CORE DUMP END =================\r\n"));
return err;
}
@@ -398,7 +400,7 @@ static esp_err_t esp_core_dump_uart_write_data(void *priv, void * data, uint32_t
memcpy(tmp, addr, len);
esp_core_dump_b64_encode((const uint8_t *)tmp, len, (uint8_t *)buf);
addr += len;
ets_printf("%s\r\n", buf);
ets_printf(DRAM_STR("%s\r\n"), buf);
}
return err;
@@ -427,7 +429,8 @@ void esp_core_dump_to_uart(XtExcFrame *frame)
wr_cfg.priv = NULL;
//Make sure txd/rxd are enabled
gpio_pullup_dis(1);
// use direct reg access instead of gpio_pullup_dis which can cause exception when flash cache is disabled
REG_CLR_BIT(GPIO_PIN_REG_1, FUN_PU);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_U0RXD);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_U0TXD);
@@ -438,10 +441,6 @@ void esp_core_dump_to_uart(XtExcFrame *frame)
tm_cur = xthal_get_ccount() / (XT_CLOCK_FREQ / 1000);
if (tm_cur >= tm_end)
break;
/* Feed the Cerberus. */
TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE;
TIMERG0.wdt_feed = 1;
TIMERG0.wdt_wprotect = 0;
ch = esp_core_dump_uart_get_char();
}
ESP_COREDUMP_LOGI("Print core dump to uart...");
@@ -455,18 +454,18 @@ void esp_core_dump_init()
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
const esp_partition_t *core_part;
ESP_LOGI(TAG, "Init core dump to flash");
ESP_COREDUMP_LOGI("Init core dump to flash");
core_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, NULL);
if (!core_part) {
ESP_LOGE(TAG, "No core dump partition found!");
ESP_COREDUMP_LOGE("No core dump partition found!");
return;
}
ESP_LOGI(TAG, "Found partition '%s' @ %x %d bytes", core_part->label, core_part->address, core_part->size);
ESP_COREDUMP_LOGI("Found partition '%s' @ %x %d bytes", core_part->label, core_part->address, core_part->size);
s_core_part_start = core_part->address;
s_core_part_size = core_part->size;
#endif
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART
ESP_LOGI(TAG, "Init core dump to UART");
ESP_COREDUMP_LOGI("Init core dump to UART");
#endif
}

View File

@@ -36,7 +36,7 @@ void esp_set_cpu_freq(void)
// wait uart tx finish, otherwise some uart output will be lost
uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM);
rtc_init_lite(XTAL_AUTO);
rtc_init_lite(XTAL_40M);
// work around a bug that RTC fast memory may be isolated
// from the system after rtc_init_lite
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_NOISO_M);

View File

@@ -73,9 +73,6 @@ static bool app_cpu_started = false;
static void do_global_ctors(void);
static void main_task(void* args);
extern void app_main(void);
#if CONFIG_ESP32_PHY_AUTO_INIT
static void do_phy_init();
#endif
extern int _bss_start;
extern int _bss_end;
@@ -210,17 +207,6 @@ void start_cpu0_default(void)
/* init default OS-aware flash access critical section */
spi_flash_guard_set(&g_flash_guard_default_ops);
#if CONFIG_ESP32_PHY_AUTO_INIT
nvs_flash_init();
do_phy_init();
#endif
#if CONFIG_SW_COEXIST_ENABLE
if (coex_init() == ESP_OK) {
coexist_set_enable(true);
}
#endif
#if CONFIG_ESP32_ENABLE_COREDUMP
esp_core_dump_init();
#endif
@@ -268,39 +254,3 @@ static void main_task(void* args)
vTaskDelete(NULL);
}
#if CONFIG_ESP32_PHY_AUTO_INIT
static void do_phy_init()
{
esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL;
if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
calibration_mode = PHY_RF_CAL_NONE;
}
const esp_phy_init_data_t* init_data = esp_phy_get_init_data();
if (init_data == NULL) {
ESP_LOGE(TAG, "failed to obtain PHY init data");
abort();
}
esp_phy_calibration_data_t* cal_data =
(esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1);
if (cal_data == NULL) {
ESP_LOGE(TAG, "failed to allocate memory for RF calibration data");
abort();
}
esp_err_t err = esp_phy_load_cal_data_from_nvs(cal_data);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to load RF calibration data, falling back to full calibration");
calibration_mode = PHY_RF_CAL_FULL;
}
esp_phy_init(init_data, calibration_mode, cal_data);
if (calibration_mode != PHY_RF_CAL_NONE) {
err = esp_phy_store_cal_data_to_nvs(cal_data);
} else {
err = ESP_OK;
}
esp_phy_release_init_data(init_data);
free(cal_data); // PHY maintains a copy of calibration data, so we can free this
}
#endif //CONFIG_ESP32_PHY_AUTO_INIT

View File

@@ -82,7 +82,7 @@ void esp_crosscore_int_init() {
assert(err == ESP_OK);
}
void esp_crosscore_int_send_yield(int coreId) {
void IRAM_ATTR esp_crosscore_int_send_yield(int coreId) {
assert(coreId<portNUM_PROCESSORS);
//Mark the reason we interrupt the other CPU
portENTER_CRITICAL(&reasonSpinlock);

View File

@@ -22,6 +22,7 @@
#include "rom/uart.h"
#include "soc/cpu.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "soc/dport_reg.h"
#include "driver/rtc_io.h"
#include "freertos/FreeRTOS.h"
@@ -111,6 +112,13 @@ void IRAM_ATTR esp_deep_sleep_start()
// Decide which power domains can be powered down
uint32_t pd_flags = get_power_down_flags();
// Shut down parts of RTC which may have been left enabled by the wireless drivers
CLEAR_PERI_REG_MASK(RTC_CNTL_ANA_CONF_REG,
RTC_CNTL_CKGEN_I2C_PU | RTC_CNTL_PLL_I2C_PU |
RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M, 0, SENS_FORCE_XPD_SAR_S);
// Configure pins for external wakeup
if (s_config.wakeup_triggers & EXT_EVENT0_TRIG_EN) {
ext0_wakeup_prepare();

View File

@@ -193,8 +193,14 @@ void heap_alloc_caps_init() {
disable_mem_region((void*)0x3ffe0000, (void*)0x3ffe8000); //knock out ROM data region
#if CONFIG_BT_ENABLED
#if CONFIG_BT_DRAM_RELEASE
disable_mem_region((void*)0x3ffb0000, (void*)0x3ffb3000); //knock out BT data region
disable_mem_region((void*)0x3ffb8000, (void*)0x3ffbbb28); //knock out BT data region
disable_mem_region((void*)0x3ffbdb28, (void*)0x3ffc0000); //knock out BT data region
#else
disable_mem_region((void*)0x3ffb0000, (void*)0x3ffc0000); //knock out BT data region
#endif
#endif
#if CONFIG_MEMMAP_TRACEMEM
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS

View File

@@ -25,6 +25,11 @@ extern "C" {
*/
esp_err_t coex_init(void);
/**
* @brief De-init software coexist
*/
void coex_deinit(void);
/**
* @brief Get software coexist enable or not
*

View File

@@ -164,6 +164,14 @@ void esp_deep_sleep_start() __attribute__((noreturn));
* Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup
* followed by a call to esp_deep_sleep_start.
*
* esp_deep_sleep does not shut down WiFi, BT, and higher level protocol
* connections gracefully.
* Make sure relevant WiFi and BT stack functions are called to close any
* connections and deinitialize the peripherals. These include:
* - esp_bluedroid_disable
* - esp_bt_controller_disable
* - esp_wifi_stop
*
* This function does not return.
*
* @param time_in_us deep-sleep time, unit: microsecond

View File

@@ -11,10 +11,10 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __ESP_ERR_H__
#define __ESP_ERR_H__
#pragma once
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#ifdef __cplusplus
@@ -40,15 +40,38 @@ typedef int32_t esp_err_t;
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression) __attribute__((noreturn));
#ifndef __ASSERT_FUNC
/* This won't happen on IDF, which defines __ASSERT_FUNC in assert.h, but it does happen when building on the host which
uses /usr/include/assert.h or equivalent.
*/
#ifdef __ASSERT_FUNCTION
#define __ASSERT_FUNC __ASSERT_FUNCTION /* used in glibc assert.h */
#else
#define __ASSERT_FUNC "??"
#endif
#endif
/**
* Macro which can be used to check the error code,
* and terminate the program in case the code is not ESP_OK.
* Prints the failed statement to serial output.
* Prints the error code, error location, and the failed statement to serial output.
*
* Disabled if assertions are disabled.
*/
#define ESP_ERROR_CHECK(x) do { esp_err_t rc = (x); if (rc != ESP_OK) { assert(0 && #x);} } while(0);
#ifdef NDEBUG
#define ESP_ERROR_CHECK(x) do { (x); } while (0)
#else
#define ESP_ERROR_CHECK(x) do { \
esp_err_t rc = (x); \
if (rc != ESP_OK) { \
_esp_error_check_failed(rc, __FILE__, __LINE__, \
__ASSERT_FUNC, #x); \
} \
} while(0);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __ESP_ERR_H__ */

View File

@@ -14,6 +14,7 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#ifdef __cplusplus
@@ -192,7 +193,7 @@ void esp_phy_release_init_data(const esp_phy_init_data_t* data);
* mechanism for loading calibration data, disable
* "Initialize PHY in startup code" option in menuconfig and call esp_phy_init
* function from the application. For an example usage of esp_phy_init and
* this function, see do_phy_init function in cpu_start.c
* this function, see esp_phy_store_cal_data_to_nvs function in cpu_start.c
*
* @param out_cal_data pointer to calibration data structure to be filled with
* loaded data.
@@ -220,28 +221,39 @@ esp_err_t esp_phy_load_cal_data_from_nvs(esp_phy_calibration_data_t* out_cal_dat
esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_data);
/**
* @brief Initialize PHY module
* @brief Initialize PHY and RF module
*
* PHY module should be initialized in order to use WiFi or BT.
* If "Initialize PHY in startup code" option is set in menuconfig,
* this function will be called automatically before app_main is called,
* using parameters obtained from esp_phy_get_init_data.
*
* Applications which don't need to enable PHY on every start up should
* disable this menuconfig option and call esp_phy_init before calling
* esp_wifi_init or esp_bt_controller_init. See do_phy_init function in
* cpu_start.c for an example of using this function.
* PHY and RF module should be initialized in order to use WiFi or BT.
* Now PHY and RF initializing job is done automatically when start WiFi or BT. Users should not
* call this API in their application.
*
* @param init_data PHY parameters. Default set of parameters can
* be obtained by calling esp_phy_get_default_init_data
* function.
* @param mode Calibration mode (Full, partial, or no calibration)
* @param[inout] calibration_data
* @param is_sleep WiFi wakes up from sleep or not
* @return ESP_OK on success.
* @return ESP_FAIL on fail.
*/
esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data,
esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data, bool is_sleep);
/**
* @brief De-initialize PHY and RF module
*
* PHY module should be de-initialized in order to shutdown WiFi or BT.
* Now PHY and RF de-initializing job is done automatically when stop WiFi or BT. Users should not
* call this API in their application.
*
* @return ESP_OK on success.
*/
esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data,
esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data);
esp_err_t esp_phy_rf_deinit(void);
/**
* @brief Load calibration data from NVS and initialize PHY and RF module
*/
void esp_phy_load_cal_and_init(void);
#ifdef __cplusplus
}

View File

@@ -24,6 +24,17 @@
extern "C" {
#endif
typedef enum {
ESP_MAC_WIFI_STA,
ESP_MAC_WIFI_SOFTAP,
ESP_MAC_BT,
ESP_MAC_ETH,
} esp_mac_type_t;
#define TWO_MAC_ADDRESS_FROM_EFUSE 2
#define FOUR_MAC_ADDRESS_FROM_EFUSE 4
#define NUM_MAC_ADDRESS_FROM_EFUSE CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
/**
* @attention application don't need to call this function anymore. It do nothing and will
* be removed in future version.
@@ -115,6 +126,47 @@ esp_err_t esp_efuse_read_mac(uint8_t* mac);
*/
esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated));
/**
* @brief Read hardware MAC address and set MAC address of the interface.
*
* This function first reads hardware MAC address from efuse. Then set the MAC address of the interface
* including wifi station, wifi softap, bluetooth and ethernet.
*
* @param mac MAC address of the interface, length: 6 bytes.
* @param type type of MAC address, 0:wifi station, 1:wifi softap, 2:bluetooth, 3:ethernet.
*
* @return ESP_OK on success
*/
esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type);
/**
* @brief Derive MAC address.
*
* This function derives a local MAC address from an universal MAC address.
* Addresses can either be universally administered addresses or locally administered addresses.
* A universally administered address is uniquely assigned to a device by its manufacturer.
* The first three octets (in transmission order) identify the organization that issued the identifier
* and are known as the Organizationally Unique Identifier (OUI).[4] The remainder of the address
* (three octets for MAC-48 and EUI-48 or five for EUI-64) are assigned by that organization in nearly
* any manner they please, subject to the constraint of uniqueness. A locally administered address is
* assigned to a device by a network administrator, overriding the burned-in address.
* Universally administered and locally administered addresses are distinguished by setting
* the second-least-significant bit of the first octet of the address. This bit is also referred to
* as the U/L bit, short for Universal/Local, which identifies how the address is administered.
* If the bit is 0, the address is universally administered. If it is 1, the address is locally administered.
* In the example address 06-00-00-00-00-00 the first octet is 06 (hex), the binary form of which is 00000110,
* where the second-least-significant bit is 1. Therefore, it is a locally administered address.[7] Consequently,
* this bit is 0 in all OUIs.
* In ESP32, universal MAC address is generated from the hardware MAC address in efuse.
* Local MAC address is derived from the universal MAC address.
*
* @param dst_mac Derived local MAC address, length: 6 bytes.
* @param src_mac Source universal MAC address, length: 6 bytes.
*
* @return ESP_OK on success
*/
esp_err_t esp_derive_mac(uint8_t* dst_mac, const uint8_t* src_mac);
/**
* Get SDK version
*

View File

@@ -31,18 +31,6 @@
#define ESP_TASK_PRIO_MAX (configMAX_PRIORITIES)
#define ESP_TASK_PRIO_MIN (0)
/* Wifi library task */
#define ESP_TASKD_WATCHDOG_PRIO (ESP_TASK_PRIO_MAX - 1)
#define ESP_TASKD_WATCHDOG_STACK 2048
#define ESP_TASK_WPA2_PRIO (ESP_TASK_PRIO_MAX - 1)
#define ESP_TASK_WPA2_STACK 2048
#define ESP_TASKD_WIFI_PRIO (ESP_TASK_PRIO_MAX - 2)
#define ESP_TASKD_WIFI_STACK 8196
#define ESP_TASKD_WIFI_TIMER_PRIO (ESP_TASK_PRIO_MAX - 3)
#define ESP_TASKD_WIFI_TIMER_STACK 2048
#define ESP_TASK_WPS_PRIO (ESP_TASK_PRIO_MIN + 2)
#define ESP_TASK_WPS_STACK 2048
/* Bt contoller Task */
/* controller */
#define ESP_TASK_BT_CONTROLLER_PRIO (ESP_TASK_PRIO_MAX - 1)

View File

@@ -94,14 +94,45 @@ extern "C" {
* @brief WiFi stack configuration parameters passed to esp_wifi_init call.
*/
typedef struct {
system_event_handler_t event_handler; /**< WiFi event handler */
uint32_t rx_buf_num; /**< WiFi RX buffer number */
system_event_handler_t event_handler; /**< WiFi event handler */
int static_rx_buf_num; /**< WiFi static RX buffer number */
int dynamic_rx_buf_num; /**< WiFi dynamic RX buffer number */
int dynamic_tx_buf_num; /**< WiFi dynamic TX buffer number */
int ampdu_enable; /**< WiFi AMPDU feature enable flag */
int nvs_enable; /**< WiFi NVS flash enable flag */
int nano_enable; /**< Nano option for printf/scan family enable flag */
int magic; /**< WiFi init magic number, it should be the last field */
} wifi_init_config_t;
#if CONFIG_ESP32_WIFI_AMPDU_ENABLED
#define WIFI_AMPDU_ENABLED 1
#else
#define WIFI_AMPDU_ENABLED 0
#endif
#if CONFIG_ESP32_WIFI_NVS_ENABLED
#define WIFI_NVS_ENABLED 1
#else
#define WIFI_NVS_ENABLED 0
#endif
#if CONFIG_NEWLIB_NANO_FORMAT
#define WIFI_NANO_FORMAT_ENABLED 1
#else
#define WIFI_NANO_FORMAT_ENABLED 0
#endif
#define WIFI_INIT_CONFIG_MAGIC 0x1F2F3F4F
#ifdef CONFIG_WIFI_ENABLED
#define WIFI_INIT_CONFIG_DEFAULT() { \
.event_handler = &esp_event_send, \
.rx_buf_num = CONFIG_ESP32_WIFI_RX_BUFFER_NUM, \
.static_rx_buf_num = CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM,\
.dynamic_rx_buf_num = CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM,\
.dynamic_tx_buf_num = CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM,\
.ampdu_enable = WIFI_AMPDU_ENABLED,\
.nvs_enable = WIFI_NVS_ENABLED,\
.nano_enable = WIFI_NANO_FORMAT_ENABLED,\
.magic = WIFI_INIT_CONFIG_MAGIC\
};
#else
#define WIFI_INIT_CONFIG_DEFAULT #error Wifi is disabled in config, WIFI_INIT_CONFIG_DEFAULT will not work
@@ -113,8 +144,11 @@ typedef struct {
* WiFi NVS structure etc, this WiFi also start WiFi task
*
* @attention 1. This API must be called before all other WiFi API can be called
* @attention 2. event_handler field in cfg should be set to a valid event handler function.
* In most cases, use the WIFI_INIT_CONFIG_DEFAULT macro which sets esp_event_send().
* @attention 2. Always use WIFI_INIT_CONFIG_DEFAULT macro to init the config to default values, this can
* guarantee all the fields got correct value when more fields are added into wifi_init_config_t
* in future release. If you want to set your owner initial values, overwrite the default values
* which are set by WIFI_INIT_CONFIG_DEFAULT, please be notified that the field 'magic' of
* wifi_init_config_t should always be WIFI_INIT_CONFIG_MAGIC!
*
* @param config provide WiFi init configuration
*
@@ -130,6 +164,7 @@ esp_err_t esp_wifi_init(wifi_init_config_t *config);
* Free all resource allocated in esp_wifi_init and stop WiFi task
*
* @attention 1. This API should be called if you want to remove WiFi driver from the system
* @attention 2. This API can not be called yet and will be done in the future.
*
* @return ESP_OK: succeed
*/
@@ -421,6 +456,7 @@ esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw);
* @brief Set primary/secondary channel of ESP32
*
* @attention 1. This is a special API for sniffer
* @attention 2. This API should be called after esp_wifi_start() or esp_wifi_set_promiscuous()
*
* @param primary for HT20, primary is the channel number, for HT40, primary is the primary channel
* @param second for HT20, second is ignored, for HT40, second is the second channel

View File

@@ -36,16 +36,6 @@ static inline void *get_sp()
return sp;
}
/* Return true if the CPU is in an interrupt context
(PS.UM == 0)
*/
static inline bool cpu_in_interrupt_context(void)
{
uint32_t ps;
RSR(PS, ps);
return (ps & PS_UM) == 0;
}
/* Functions to set page attributes for Region Protection option in the CPU.
* See Xtensa ISA Reference manual for explanation of arguments (section 4.6.3.2).
*/

View File

@@ -1035,11 +1035,27 @@
#define DPORT_WIFI_CLK_EN_V 0xFFFFFFFF
#define DPORT_WIFI_CLK_EN_S 0
/* Mask for all Wifi clock bits - 0, 1, 2, 3, 6, 7, 8, 9, 10, 15 */
#define DPORT_WIFI_CLK_WIFI_EN 0x000007cf
#define DPORT_WIFI_CLK_WIFI_EN_M ((DPORT_WIFI_CLK_WIFI_EN_V)<<(DPORT_WIFI_CLK_WIFI_EN_S))
#define DPORT_WIFI_CLK_WIFI_EN_V 0x1FF
#define DPORT_WIFI_CLK_WIFI_EN_S 0
/* Mask for all Bluetooth clock bits - 11, 16, 17 */
#define DPORT_WIFI_CLK_BT_EN 0x61
#define DPORT_WIFI_CLK_BT_EN_M ((DPORT_WIFI_CLK_BT_EN_V)<<(DPORT_WIFI_CLK_BT_EN_S))
#define DPORT_WIFI_CLK_BT_EN_V 0x61
#define DPORT_WIFI_CLK_BT_EN_S 11
/* Remaining single bit clock masks */
#define DPORT_WIFI_CLK_SDIOSLAVE_EN BIT(4)
#define DPORT_WIFI_CLK_SDIO_HOST_EN BIT(13)
#define DPORT_WIFI_CLK_EMAC_EN BIT(14)
#define DPORT_WIFI_CLK_RNG_EN BIT(15)
#define DPORT_CORE_RST_EN_REG (DR_REG_DPORT_BASE + 0x0D0)
/* DPORT_CORE_RST : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
/*description: */
#define DPROT_RW_BTLP_RST (BIT(10))
#define DPROT_RW_BTMAC_RST (BIT(9))
#define DPORT_RW_BTLP_RST (BIT(10))
#define DPORT_RW_BTMAC_RST (BIT(9))
#define DPORT_MACPWR_RST (BIT(8))
#define DPORT_EMAC_RST (BIT(7))
#define DPORT_SDIO_HOST_RST (BIT(6))

View File

@@ -268,10 +268,10 @@
* 2 1 extern level
* 3 1 extern level
* 4 1 extern level WBB
* 5 1 extern level BT Controller
* 5 1 extern level BT/BLE Controller
* 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1)
* 7 1 software Reserved Reserved
* 8 1 extern level BLE Controller
* 8 1 extern level BT/BLE BB(RX/TX)
* 9 1 extern level
* 10 1 extern edge Internal Timer
* 11 3 profiling

View File

@@ -686,7 +686,7 @@ esp_err_t IRAM_ATTR esp_intr_disable(intr_handle_t handle)
}
void esp_intr_noniram_disable()
void IRAM_ATTR esp_intr_noniram_disable()
{
int oldint;
int cpu=xPortGetCoreID();
@@ -705,7 +705,7 @@ void esp_intr_noniram_disable()
non_iram_int_disabled[cpu]=oldint&non_iram_int_mask[cpu];
}
void esp_intr_noniram_enable()
void IRAM_ATTR esp_intr_noniram_enable()
{
int cpu=xPortGetCoreID();
int intmask=non_iram_int_disabled[cpu];

View File

@@ -80,9 +80,15 @@ SECTIONS
*(.iram1 .iram1.*)
*libfreertos.a:(.literal .text .literal.* .text.*)
*libesp32.a:panic.o(.literal .text .literal.* .text.*)
*libesp32.a:core_dump.o(.literal .text .literal.* .text.*)
*libphy.a:(.literal .text .literal.* .text.*)
*librtc.a:(.literal .text .literal.* .text.*)
*libpp.a:(.literal .text .literal.* .text.*)
*librtc_clk.a:(.literal .text .literal.* .text.*)
*libpp.a:pp.o(.literal .text .literal.* .text.*)
*libpp.a:lmac.o(.literal .text .literal.* .text.*)
*libpp.a:wdev.o(.literal .text .literal.* .text.*)
*libcore.a:ets_timer.o(.literal .text .literal.* .text.*)
*libnet80211.a:ieee80211_misc.o(.literal .text .literal.* .text.*)
*libhal.a:(.literal .text .literal.* .text.*)
*libcoexist.a:(.literal .text .literal.* .text.*)
_iram_text_end = ABSOLUTE(.);

View File

@@ -34,6 +34,7 @@
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_core_dump.h"
#include "esp_spi_flash.h"
/*
Panic handlers; these get called when an unhandled exception occurs or the assembly-level
@@ -107,11 +108,8 @@ void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, s
static bool abort_called;
void abort()
static __attribute__((noreturn)) inline void invoke_abort()
{
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
#endif
abort_called = true;
while(1) {
__asm__ ("break 0,0");
@@ -119,6 +117,14 @@ void abort()
}
}
void abort()
{
#if !CONFIG_ESP32_PANIC_SILENT_REBOOT
ets_printf("abort() was called at PC 0x%08x\n", (intptr_t)__builtin_return_address(0) - 3);
#endif
invoke_abort();
}
static const char *edesc[] = {
"IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError",
@@ -267,7 +273,7 @@ static void reconfigureAllWdts()
TIMERG1.wdt_wprotect = 0;
}
#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT
#if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT || CONFIG_ESP32_ENABLE_COREDUMP
/*
This disables all the watchdogs for when we call the gdbstub.
*/
@@ -367,11 +373,15 @@ static void commonErrorHandler(XtExcFrame *frame)
panicPutStr("Entering gdb stub now.\r\n");
esp_gdbstub_panic_handler(frame);
#else
#if CONFIG_ESP32_ENABLE_COREDUMP
disableAllWdts();
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH
esp_core_dump_to_flash(frame);
#endif
#if CONFIG_ESP32_ENABLE_COREDUMP_TO_UART && !CONFIG_ESP32_PANIC_SILENT_REBOOT
esp_core_dump_to_uart(frame);
#endif
reconfigureAllWdts();
#endif
#if CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT
panicPutStr("Rebooting...\r\n");
@@ -437,4 +447,11 @@ void esp_clear_watchpoint(int no)
}
}
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
ets_printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at 0x%08x\n", rc, (intptr_t)__builtin_return_address(0) - 3);
if (spi_flash_cache_enabled()) { // strings may be in flash cache
ets_printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
}
invoke_abort();
}

View File

@@ -17,7 +17,10 @@
#include <string.h>
#include <stdbool.h>
#include <sys/lock.h>
#include "rom/ets_sys.h"
#include "rom/rtc.h"
#include "soc/dport_reg.h"
#include "esp_err.h"
@@ -25,30 +28,71 @@
#include "esp_system.h"
#include "esp_log.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "sdkconfig.h"
#ifdef CONFIG_PHY_ENABLED
#include "phy.h"
#include "phy_init_data.h"
#include "rtc.h"
#include "esp_coexist.h"
static const char* TAG = "phy_init";
/* Count value to indicate if there is peripheral that has initialized PHY and RF */
static int s_phy_rf_init_count = 0;
static bool s_mac_rst_flag = false;
esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data,
esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data)
static _lock_t s_phy_rf_init_lock;
esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data,
esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data, bool is_sleep)
{
assert(init_data);
assert(calibration_data);
assert((s_phy_rf_init_count <= 1) && (s_phy_rf_init_count >= 0));
REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
// Enable WiFi peripheral clock
SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf);
ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d",
init_data, calibration_data, mode);
phy_set_wifi_mode_only(0);
register_chipv7_phy(init_data, calibration_data, mode);
coex_bt_high_prio();
_lock_acquire(&s_phy_rf_init_lock);
if (s_phy_rf_init_count == 0) {
if (is_sleep == false) {
if (s_mac_rst_flag == false) {
s_mac_rst_flag = true;
REG_SET_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
REG_CLR_BIT(DPORT_CORE_RST_EN_REG, DPORT_MAC_RST);
}
}
// Enable WiFi peripheral clock
SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN | DPORT_WIFI_CLK_RNG_EN);
ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d",
init_data, calibration_data, mode);
phy_set_wifi_mode_only(0);
register_chipv7_phy(init_data, calibration_data, mode);
coex_bt_high_prio();
} else {
#if CONFIG_SW_COEXIST_ENABLE
coex_init();
#endif
}
s_phy_rf_init_count++;
_lock_release(&s_phy_rf_init_lock);
return ESP_OK;
}
esp_err_t esp_phy_rf_deinit(void)
{
assert((s_phy_rf_init_count <= 2) && (s_phy_rf_init_count >= 1));
_lock_acquire(&s_phy_rf_init_lock);
if (s_phy_rf_init_count == 1) {
// Disable PHY and RF.
phy_close_rf();
// Disable WiFi peripheral clock. Do not disable clock for hardware RNG
CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN);
} else {
#if CONFIG_SW_COEXIST_ENABLE
coex_deinit();
#endif
}
s_phy_rf_init_count--;
_lock_release(&s_phy_rf_init_lock);
return ESP_OK;
}
@@ -220,4 +264,43 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
return err;
}
void esp_phy_load_cal_and_init(void)
{
#ifdef CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
nvs_flash_init();
esp_phy_calibration_mode_t calibration_mode = PHY_RF_CAL_PARTIAL;
if (rtc_get_reset_reason(0) == DEEPSLEEP_RESET) {
calibration_mode = PHY_RF_CAL_NONE;
}
const esp_phy_init_data_t* init_data = esp_phy_get_init_data();
if (init_data == NULL) {
ESP_LOGE(TAG, "failed to obtain PHY init data");
abort();
}
esp_phy_calibration_data_t* cal_data =
(esp_phy_calibration_data_t*) calloc(sizeof(esp_phy_calibration_data_t), 1);
if (cal_data == NULL) {
ESP_LOGE(TAG, "failed to allocate memory for RF calibration data");
abort();
}
esp_err_t err = esp_phy_load_cal_data_from_nvs(cal_data);
if (err != ESP_OK) {
ESP_LOGW(TAG, "failed to load RF calibration data, falling back to full calibration");
calibration_mode = PHY_RF_CAL_FULL;
}
esp_phy_rf_init(init_data, calibration_mode, cal_data, false);
if (calibration_mode != PHY_RF_CAL_NONE && err != ESP_OK) {
err = esp_phy_store_cal_data_to_nvs(cal_data);
} else {
err = ESP_OK;
}
esp_phy_release_init_data(init_data);
free(cal_data); // PHY maintains a copy of calibration data, so we can free this
#else
esp_phy_rf_init(NULL, PHY_RF_CAL_NONE, NULL, false);
#endif
}
#endif // CONFIG_PHY_ENABLED

View File

@@ -135,6 +135,10 @@ void rtc_slp_prep_lite(uint32_t deep_slp, uint32_t cpu_lp_mode);
*/
uint32_t rtc_sleep(uint32_t cycles_h, uint32_t cycles_l, uint32_t wakeup_opt, uint32_t reject_opt);
/**
* @brief Shutdown PHY and RF. TODO: convert this function to another one.
*/
void phy_close_rf(void);
#ifdef __cplusplus
}

View File

@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string.h>
#include "esp_system.h"
#include "esp_attr.h"
#include "esp_wifi.h"
@@ -72,6 +74,87 @@ esp_err_t esp_efuse_read_mac(uint8_t* mac)
esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__((alias("esp_efuse_read_mac")));
esp_err_t esp_derive_mac(uint8_t* dst_mac, const uint8_t* src_mac)
{
uint8_t idx;
if (dst_mac == NULL || src_mac == NULL) {
ESP_LOGE(TAG, "mac address param is NULL");
return ESP_ERR_INVALID_ARG;
}
memcpy(dst_mac, src_mac, 6);
for (idx = 0; idx < 64; idx++) {
dst_mac[0] = src_mac[0] | 0x02;
dst_mac[0] ^= idx << 2;
if (memcmp(dst_mac, src_mac, 6)) {
break;
}
}
return ESP_OK;
}
esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
{
uint8_t efuse_mac[6];
if (mac == NULL) {
ESP_LOGE(TAG, "mac address param is NULL");
return ESP_ERR_INVALID_ARG;
}
if (type < ESP_MAC_WIFI_STA || type > ESP_MAC_ETH) {
ESP_LOGE(TAG, "mac type is incorrect");
return ESP_ERR_INVALID_ARG;
}
_Static_assert(NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE \
|| NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE, \
"incorrect NUM_MAC_ADDRESS_FROM_EFUSE value");
esp_efuse_read_mac(efuse_mac);
switch (type) {
case ESP_MAC_WIFI_STA:
memcpy(mac, efuse_mac, 6);
break;
case ESP_MAC_WIFI_SOFTAP:
if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) {
memcpy(mac, efuse_mac, 6);
mac[5] += 1;
}
else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) {
esp_derive_mac(mac, efuse_mac);
}
break;
case ESP_MAC_BT:
memcpy(mac, efuse_mac, 6);
if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) {
mac[5] += 2;
}
else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) {
mac[5] += 1;
}
break;
case ESP_MAC_ETH:
if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) {
memcpy(mac, efuse_mac, 6);
mac[5] += 3;
}
else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) {
efuse_mac[5] += 1;
esp_derive_mac(mac, efuse_mac);
}
break;
default:
ESP_LOGW(TAG, "incorrect mac type");
break;
}
return ESP_OK;
}
void esp_restart_noos() __attribute__ ((noreturn));
@@ -132,7 +215,7 @@ void IRAM_ATTR esp_restart_noos()
DPORT_BB_RST | DPORT_FE_RST | DPORT_MAC_RST |
DPORT_BT_RST | DPORT_BTMAC_RST | DPORT_SDIO_RST |
DPORT_SDIO_HOST_RST | DPORT_EMAC_RST | DPORT_MACPWR_RST |
DPROT_RW_BTMAC_RST | DPROT_RW_BTLP_RST);
DPORT_RW_BTMAC_RST | DPORT_RW_BTLP_RST);
REG_WRITE(DPORT_CORE_RST_EN_REG, 0);
// Reset timer/spi/uart

View File

@@ -12,15 +12,15 @@ import array
import errno
import base64
idf_path = os.getenv('IDF_PATH')
if idf_path:
sys.path.insert(0, os.path.join(idf_path, 'components', 'esptool_py', 'esptool'))
try:
import esptool
except ImportError:
idf_path = os.getenv('IDF_PATH')
if idf_path is None:
print "Esptool is not found! Install it or set proper $IDF_PATH in environment."
sys.exit(2)
sys.path.append('%s/components/esptool_py/esptool' % idf_path)
import esptool
print "Esptool is not found! Set proper $IDF_PATH in environment."
sys.exit(2)
__version__ = "0.1-dev"

View File

@@ -75,6 +75,7 @@ struct emac_config_data {
bool emac_flow_ctrl_enable;
bool emac_flow_ctrl_partner_support;
eth_phy_get_partner_pause_enable_func emac_phy_get_partner_pause_enable;
eth_phy_power_enable_func emac_phy_power_enable;
};
enum emac_post_type {

View File

@@ -75,8 +75,7 @@ esp_err_t emac_post(emac_sig_t sig, emac_par_t par);
static void emac_macaddr_init(void)
{
esp_efuse_read_mac(&(emac_config.macaddr[0]));
emac_config.macaddr[5] = emac_config.macaddr[5] + 3;
esp_read_mac(&(emac_config.macaddr[0]), ESP_MAC_ETH);
}
void esp_eth_get_mac(uint8_t mac[6])
@@ -225,6 +224,7 @@ static void emac_set_user_config_data(eth_config_t *config )
emac_config.emac_flow_ctrl_enable = false;
#endif
emac_config.emac_phy_get_partner_pause_enable = config->phy_get_partner_pause_enable;
emac_config.emac_phy_power_enable = config->phy_power_enable;
}
static void emac_enable_intr()
@@ -291,6 +291,11 @@ static esp_err_t emac_verify_args(void)
ret = ESP_FAIL;
}
if(emac_config.emac_phy_power_enable == NULL) {
ESP_LOGE(TAG, "phy power enable func is null");
ret = ESP_FAIL;
}
return ret;
}
@@ -537,6 +542,10 @@ static void emac_check_phy_init(void)
} else {
REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED);
}
#if CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE
emac_disable_flowctrl();
emac_config.emac_flow_ctrl_partner_support = false;
#else
if (emac_config.emac_flow_ctrl_enable == true) {
if (emac_config.emac_phy_get_partner_pause_enable() == true && emac_config.emac_phy_get_duplex_mode() == ETH_MDOE_FULLDUPLEX) {
emac_enable_flowctrl();
@@ -549,6 +558,7 @@ static void emac_check_phy_init(void)
emac_disable_flowctrl();
emac_config.emac_flow_ctrl_partner_support = false;
}
#endif
emac_mac_enable_txrx();
}
static void emac_process_link_updown(bool link_status)
@@ -938,6 +948,8 @@ esp_err_t esp_eth_init(eth_config_t *config)
emac_set_user_config_data(config);
}
emac_config.emac_phy_power_enable(true);
ret = emac_verify_args();
if (ret != ESP_OK) {

View File

@@ -80,7 +80,7 @@ typedef void (*eth_phy_func)(void);
typedef esp_err_t (*eth_tcpip_input_func)(void *buffer, uint16_t len, void *eb);
typedef void (*eth_gpio_config_func)(void);
typedef bool (*eth_phy_get_partner_pause_enable_func)(void);
typedef void (*eth_phy_power_enable_func)(bool enable);
/**
* @brief ethernet configuration
@@ -98,6 +98,7 @@ typedef struct {
eth_gpio_config_func gpio_config; /*!< gpio config func */
bool flow_ctrl_enable; /*!< flag of flow ctrl enable */
eth_phy_get_partner_pause_enable_func phy_get_partner_pause_enable; /*!< get partner pause enable */
eth_phy_power_enable_func phy_power_enable; /*!< enable or disable phy power */
} eth_config_t;

View File

@@ -152,7 +152,7 @@ static int fat_mode_conv(int m)
}
if ((m & O_CREAT) && (m & O_EXCL)) {
res |= FA_CREATE_NEW;
} else if (m & O_CREAT) {
} else if ((m & O_CREAT) && (m & O_TRUNC)) {
res |= FA_CREATE_ALWAYS;
} else if (m & O_APPEND) {
res |= FA_OPEN_ALWAYS;

View File

@@ -39,14 +39,19 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
sdmmc_host_init();
// enable card slot
sdmmc_host_init_slot(host_config->slot, slot_config);
esp_err_t err = sdmmc_host_init_slot(host_config->slot, slot_config);
if (err != ESP_OK) {
return err;
}
s_card = malloc(sizeof(sdmmc_card_t));
if (s_card == NULL) {
return ESP_ERR_NO_MEM;
err = ESP_ERR_NO_MEM;
goto fail;
}
// probe and initialize card
esp_err_t err = sdmmc_card_init(host_config, s_card);
err = sdmmc_card_init(host_config, s_card);
if (err != ESP_OK) {
ESP_LOGD(TAG, "sdmmc_card_init failed 0x(%x)", err);
goto fail;
@@ -104,6 +109,7 @@ esp_err_t esp_vfs_fat_sdmmc_mount(const char* base_path,
return ESP_OK;
fail:
sdmmc_host_deinit();
free(workbuf);
esp_vfs_unregister(base_path);
free(s_card);

View File

@@ -52,6 +52,25 @@ static void create_file_with_text(const char* name, const char* text)
TEST_ASSERT_EQUAL(0, fclose(f));
}
TEST_CASE("Mount fails cleanly without card inserted", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5
};
for (int i = 0; i < 3; ++i) {
printf("Initializing card, attempt %d ", i);
esp_err_t err = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, NULL);
printf(" err=%d\n", err);
TEST_ESP_ERR(ESP_FAIL, err);
}
HEAP_SIZE_CHECK(0);
}
TEST_CASE("can create and write file on sd card", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
@@ -69,6 +88,55 @@ TEST_CASE("can create and write file on sd card", "[fatfs][ignore]")
HEAP_SIZE_CHECK(0);
}
TEST_CASE("overwrite and append file on sd card", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 5
};
TEST_ESP_OK(esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, NULL));
/* Create new file with 'aaaa' */
const char *NAME = "/sdcard/hello.txt";
create_file_with_text(NAME, "aaaa");
/* Append 'bbbb' to file */
FILE *f_a = fopen(NAME, "a");
TEST_ASSERT_NOT_NULL(f_a);
TEST_ASSERT_NOT_EQUAL(EOF, fputs("bbbb", f_a));
TEST_ASSERT_EQUAL(0, fclose(f_a));
/* Read back 8 bytes from file, verify it's 'aaaabbbb' */
char buf[10] = { 0 };
FILE *f_r = fopen(NAME, "r");
TEST_ASSERT_NOT_NULL(f_r);
TEST_ASSERT_EQUAL(8, fread(buf, 1, 8, f_r));
TEST_ASSERT_EQUAL_STRING_LEN("aaaabbbb", buf, 8);
/* Be sure we're at end of file */
TEST_ASSERT_EQUAL(0, fread(buf, 1, 8, f_r));
TEST_ASSERT_EQUAL(0, fclose(f_r));
/* Overwrite file with 'cccc' */
create_file_with_text(NAME, "cccc");
/* Verify file now only contains 'cccc' */
f_r = fopen(NAME, "r");
TEST_ASSERT_NOT_NULL(f_r);
bzero(buf, sizeof(buf));
TEST_ASSERT_EQUAL(4, fread(buf, 1, 8, f_r)); // trying to read 8 bytes, only expecting 4
TEST_ASSERT_EQUAL_STRING_LEN("cccc", buf, 4);
TEST_ASSERT_EQUAL(0, fclose(f_r));
TEST_ESP_OK(esp_vfs_fat_sdmmc_unmount());
HEAP_SIZE_CHECK(0);
}
TEST_CASE("can read file on sd card", "[fatfs][ignore]")
{
HEAP_SIZE_CAPTURE();

View File

@@ -254,7 +254,7 @@
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY 1
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
#define configTIMER_TASK_STACK_DEPTH 2048
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_eTaskGetState 1

View File

@@ -194,6 +194,12 @@ void vPortYieldOtherCore( BaseType_t coreid) PRIVILEGED_FUNCTION;
*/
void vPortSetStackWatchpoint( void* pxStackStart );
/*
* Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
* aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
*/
BaseType_t xPortInIsrContext();
/*
* The structures and methods of manipulating the MPU are contained within the
* port layer.
@@ -216,6 +222,9 @@ static inline uint32_t xPortGetCoreID() {
return id;
}
/* Get tick rate per second */
uint32_t xPortGetTickRateHz(void);
#ifdef __cplusplus
}
#endif

View File

@@ -115,7 +115,7 @@ extern void _xt_coproc_init(void);
/*-----------------------------------------------------------*/
unsigned port_xSchedulerRunning[portNUM_PROCESSORS] = {0}; // Duplicate of inaccessible xSchedulerRunning; needed at startup to avoid counting nesting
unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level
unsigned port_interruptNesting[portNUM_PROCESSORS] = {0}; // Interrupt nesting level. Increased/decreased in portasm.c, _frxt_int_enter/_frxt_int_exit
/*-----------------------------------------------------------*/
@@ -256,9 +256,24 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMOR
#endif
/*
* Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs
* aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
*/
BaseType_t xPortInIsrContext()
{
unsigned int irqStatus;
BaseType_t ret;
irqStatus=portENTER_CRITICAL_NESTED();
ret=(port_interruptNesting[xPortGetCoreID()] != 0);
portEXIT_CRITICAL_NESTED(irqStatus);
return ret;
}
void vPortAssertIfInISR()
{
configASSERT(port_interruptNesting[xPortGetCoreID()]==0)
configASSERT(xPortInIsrContext());
}
/*
@@ -406,7 +421,9 @@ void vPortSetStackWatchpoint( void* pxStackStart ) {
esp_set_watchpoint(1, (char*)addr, 32, ESP_WATCHPOINT_STORE);
}
uint32_t xPortGetTickRateHz(void) {
return (uint32_t)configTICK_RATE_HZ;
}

View File

@@ -132,8 +132,8 @@ _frxt_int_enter:
l32i a2, a2, 0 /* a2 = current TCB */
beqz a2, 1f
s32i a1, a2, TOPOFSTACK_OFFS /* pxCurrentTCB->pxTopOfStack = SP */
movi a1, port_IntStackTop /* a1 = top of intr stack */
movi a2, configISR_STACK_SIZE
movi a1, port_IntStack+configISR_STACK_SIZE /* a1 = top of intr stack for CPU 0 */
movi a2, configISR_STACK_SIZE /* add configISR_STACK_SIZE * cpu_num to arrive at top of stack for cpu_num */
mull a2, a4, a2
add a1, a1, a2 /* for current proc */

View File

@@ -632,7 +632,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
*/
void taskYIELD_OTHER_CORE( BaseType_t xCoreID, UBaseType_t uxPriority )
{
TCB_t *curTCB = xTaskGetCurrentTaskHandle();
TCB_t *curTCB = pxCurrentTCB[xCoreID];
BaseType_t i;
if (xCoreID != tskNO_AFFINITY) {
@@ -1056,11 +1056,15 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
taskENTER_CRITICAL(&xTaskQueueMutex);
{
uxCurrentNumberOfTasks++;
if( pxCurrentTCB[ xPortGetCoreID() ] == NULL )
//If the task has no affinity and nothing is scheduled on this core, just throw it this core.
//If it has affinity, throw it on the core that needs it if nothing is already scheduled there.
BaseType_t xMyCore = xCoreID;
if ( xMyCore == tskNO_AFFINITY) xMyCore = xPortGetCoreID();
if( pxCurrentTCB[ xMyCore ] == NULL )
{
/* There are no other tasks, or all the other tasks are in
the suspended state - make this the current task. */
pxCurrentTCB[ xPortGetCoreID() ] = pxNewTCB;
pxCurrentTCB[ xMyCore ] = pxNewTCB;
if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 )
{
@@ -1121,12 +1125,13 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
portSETUP_TCB( pxNewTCB );
}
curTCB = pxCurrentTCB[ xPortGetCoreID() ];
taskEXIT_CRITICAL(&xTaskQueueMutex);
if( xSchedulerRunning != pdFALSE )
{
taskENTER_CRITICAL(&xTaskQueueMutex);
curTCB = pxCurrentTCB[ xPortGetCoreID() ];
/* Scheduler is running. If the created task is of a higher priority than an executing task
then it should run now.
ToDo: This only works for the current core. If a task is scheduled on an other processor,
@@ -1141,7 +1146,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
*/
if( tskCAN_RUN_HERE( xCoreID ) && curTCB->uxPriority < pxNewTCB->uxPriority )
{
taskYIELD_IF_USING_PREEMPTION();
taskYIELD_IF_USING_PREEMPTION_MUX(&xTaskQueueMutex);
}
else if( xCoreID != xPortGetCoreID() ) {
taskYIELD_OTHER_CORE(xCoreID, pxNewTCB->uxPriority);
@@ -2659,11 +2664,13 @@ BaseType_t xSwitchRequired = pdFALSE;
void vTaskSwitchContext( void )
{
tskTCB * pxTCB;
//This can be called both from IRQ as well as normal context, so we can't
//use taskENTER_CRITICAL() here. Instead, save the irq status and disable
//IRQs, so we can use taskENTER_CRITICAL_ISR and friends.
//Note: This can be called from interrupt context as well as from non-interrupt context (voluntary yield). The
//taskENTER_CRITICAL/taskEXIT_CRITICAL is modified to work in both scenarios for the ESP32, so we can freely use
//them here. However, in case of a voluntary yield, a nonvoluntary yield can still happen *during* the voluntary
//yield. Disabling interrupts using portENTER_CRITICAL_NESTED puts a stop to this and makes the rest of the code a
//bit neater.
int irqstate=portENTER_CRITICAL_NESTED();
tskTCB * pxTCB;
if( uxSchedulerSuspended[ xPortGetCoreID() ] != ( UBaseType_t ) pdFALSE )
{
/* The scheduler is currently suspended - do not allow a context
@@ -3012,9 +3019,14 @@ BaseType_t xReturn;
This function assumes that a check has already been made to ensure that
pxEventList is not empty. */
pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
configASSERT( pxUnblockedTCB );
( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
if ( ( listLIST_IS_EMPTY( pxEventList ) ) == pdFALSE ) {
pxUnblockedTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
configASSERT( pxUnblockedTCB );
( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) );
} else {
taskEXIT_CRITICAL_ISR(&xTaskQueueMutex);
return pdFALSE;
}
if( uxSchedulerSuspended[ xPortGetCoreID() ] == ( UBaseType_t ) pdFALSE )
{
@@ -3025,9 +3037,7 @@ BaseType_t xReturn;
{
/* The delayed and ready lists cannot be accessed, so hold this task
pending until the scheduler is resumed. */
taskENTER_CRITICAL(&xTaskQueueMutex);
vListInsertEnd( &( xPendingReadyList[ xPortGetCoreID() ] ), &( pxUnblockedTCB->xEventListItem ) );
taskEXIT_CRITICAL(&xTaskQueueMutex);
}
if ( tskCAN_RUN_HERE(pxUnblockedTCB->xCoreID) && pxUnblockedTCB->uxPriority >= pxCurrentTCB[ xPortGetCoreID() ]->uxPriority )

View File

@@ -0,0 +1,51 @@
/*
See if xPortInIsrContext works
*/
#include <esp_types.h>
#include <stdio.h>
#include "rom/ets_sys.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/xtensa_api.h"
#include "unity.h"
#include "esp_intr_alloc.h"
#include "xtensa/hal.h"
static volatile int in_int_context, int_handled;
static void testint(void *arg) {
xthal_set_ccompare(1, xthal_get_ccount()+8000000000);
ets_printf("INT!\n");
if (xPortInIsrContext()) in_int_context++;
int_handled++;
}
static void testthread(void *arg) {
intr_handle_t handle;
in_int_context=0;
int_handled=0;
TEST_ASSERT(!xPortInIsrContext());
xthal_set_ccompare(2, xthal_get_ccount()+8000000);
esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, &testint, NULL, &handle);
vTaskDelay(100 / portTICK_PERIOD_MS);
TEST_ASSERT(int_handled);
TEST_ASSERT(in_int_context);
esp_intr_free(handle);
vTaskDelete(NULL);
}
TEST_CASE("xPortInIsrContext test", "[freertos]")
{
xTaskCreatePinnedToCore(testthread, "tst" , 4096, NULL, 3, NULL, 0);
vTaskDelay(150 / portTICK_PERIOD_MS);
xTaskCreatePinnedToCore(testthread, "tst" , 4096, NULL, 3, NULL, 1);
vTaskDelay(150 / portTICK_PERIOD_MS);
}

View File

@@ -2935,12 +2935,18 @@ initial condition:
test script: InitCondBase
- check cmd set:
- ''
- - FREBOOT UT1
- ['']
- - DELAY 3
- ['']
- - UT UT1 -
- [R UT1 C Tests C Failures C Ignored]
force restore cmd set:
- ''
- - FREBOOT UT1
- ['']
- - DELAY 3
- ['']
- - UT UT1 -
- [R UT1 C Tests C Failures C Ignored]
initial condition detail: At UT menu page
@@ -2948,6 +2954,8 @@ initial condition:
- ''
- - FREBOOT UT1
- ['']
- - DELAY 3
- ['']
- - UT UT1 -
- [R UT1 C Tests C Failures C Ignored]
restore post cmd set:

View File

@@ -2,7 +2,7 @@ menu "LWIP"
config L2_TO_L3_COPY
bool "Enable copy between Layer2 and Layer3 packets"
default 0
default n
help
If this feature is enabled, all traffic from layer2(WIFI Driver) will be
copied to a new buffer before sending it to layer3(LWIP stack), freeing
@@ -35,14 +35,14 @@ config LWIP_THREAD_LOCAL_STORAGE_INDEX
config LWIP_SO_REUSE
bool "Enable SO_REUSEADDR option"
default 0
default n
help
Enabling this option allows binding to a port which remains in
TIME_WAIT.
config LWIP_SO_RCVBUF
bool "Enable SO_RCVBUF option"
default 0
default n
help
Enabling this option allows checking for available data on a netconn.
@@ -57,14 +57,14 @@ config LWIP_DHCP_MAX_NTP_SERVERS
config LWIP_IP_FRAG
bool "Enable fragment outgoing IP packets"
default 0
default n
help
Enabling this option allows fragmenting outgoing IP packets if their size
exceeds MTU.
config LWIP_IP_REASSEMBLY
bool "Enable reassembly incoming fragmented IP packets"
default 0
default n
help
Enabling this option allows reassemblying incoming fragmented IP packets.
@@ -82,6 +82,13 @@ config TCP_SYNMAXRTX
help
Set maximum number of retransmissions of SYN segments.
config LWIP_DHCP_DOES_ARP_CHECK
bool "Enable an ARP check on the offered address"
default y
help
Enabling this option allows check if the offered IP address is not already
in use by another host on the network.
endmenu

View File

@@ -550,10 +550,17 @@ dhcp_t1_timeout(struct netif *netif)
DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */
dhcp_renew(netif);
/* Calculate next timeout */
#if ESP_DHCP_TIMER
if (((netif->dhcp->t2_timeout - dhcp->lease_used) / 2) >= (60 + DHCP_COARSE_TIMER_SECS / 2) )
{
netif->dhcp->t1_renew_time = (netif->dhcp->t2_timeout - dhcp->lease_used) / 2;
}
#else
if (((netif->dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
{
netif->dhcp->t1_renew_time = ((netif->dhcp->t2_timeout - dhcp->lease_used) / 2);
}
#endif
}
}
@@ -576,10 +583,17 @@ dhcp_t2_timeout(struct netif *netif)
DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */
dhcp_rebind(netif);
/* Calculate next timeout */
#if ESP_DHCP_TIMER
if (((netif->dhcp->t0_timeout - dhcp->lease_used) / 2) >= (60 + DHCP_COARSE_TIMER_SECS / 2))
{
netif->dhcp->t2_rebind_time = ((netif->dhcp->t0_timeout - dhcp->lease_used) / 2);
}
#else
if (((netif->dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS))
{
netif->dhcp->t2_rebind_time = ((netif->dhcp->t0_timeout - dhcp->lease_used) / 2);
}
#endif
}
}
@@ -1029,7 +1043,12 @@ dhcp_discover(struct netif *netif)
autoip_start(netif);
}
#endif /* LWIP_DHCP_AUTOIP_COOP */
msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
/* Since for embedded devices it's not that hard to miss a discover packet, so lower
* the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s.
* Original msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000;
*/
msecs = (dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 250;
dhcp->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs));
return result;
@@ -1055,6 +1074,47 @@ dhcp_bind(struct netif *netif)
/* reset time used of lease */
dhcp->lease_used = 0;
#if ESP_DHCP_TIMER
if (dhcp->offered_t0_lease != 0xffffffffUL) {
/* set renewal period timer */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease));
timeout = dhcp->offered_t0_lease;
dhcp->t0_timeout = timeout;
if (dhcp->t0_timeout == 0) {
dhcp->t0_timeout = 120;
}
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease*1000));
}
/* temporary DHCP lease? */
if (dhcp->offered_t1_renew != 0xffffffffUL) {
/* set renewal period timer */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew));
timeout = dhcp->offered_t1_renew;
dhcp->t1_timeout = timeout;
if (dhcp->t1_timeout == 0) {
dhcp->t1_timeout = dhcp->t0_timeout>>1;
}
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000));
dhcp->t1_renew_time = dhcp->t1_timeout;
}
/* set renewal period timer */
if (dhcp->offered_t2_rebind != 0xffffffffUL) {
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind));
timeout = dhcp->offered_t2_rebind;
dhcp->t2_timeout = timeout;
if (dhcp->t2_timeout == 0) {
dhcp->t2_timeout = (dhcp->t0_timeout>>3)*7;
}
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000));
dhcp->t2_rebind_time = dhcp->t2_timeout;
}
/* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */
if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
dhcp->t1_timeout = 0;
}
#else
if (dhcp->offered_t0_lease != 0xffffffffUL) {
/* set renewal period timer */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease));
@@ -1103,6 +1163,7 @@ dhcp_bind(struct netif *netif)
if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) {
dhcp->t1_timeout = 0;
}
#endif
if (dhcp->subnet_mask_given) {
/* copy offered network mask */

View File

@@ -45,7 +45,7 @@ extern "C" {
#endif
/** period (in seconds) of the application calling dhcp_coarse_tmr() */
#define DHCP_COARSE_TIMER_SECS 60
#define DHCP_COARSE_TIMER_SECS 1
/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */
#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL)
/** period (in milliseconds) of the application calling dhcp_fine_tmr() */
@@ -76,12 +76,12 @@ struct dhcp
struct dhcp_msg *msg_out; /* outgoing msg */
u16_t options_out_len; /* outgoing msg options length */
u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
u16_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */
u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */
u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */
u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */
u32_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
u32_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
u32_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */
u32_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */
u32_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */
u32_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */
ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */
ip4_addr_t offered_ip_addr;
ip4_addr_t offered_sn_mask;

View File

@@ -206,6 +206,11 @@
#define DHCP_MAXRTX 0
/**
* DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address.
*/
#define DHCP_DOES_ARP_CHECK CONFIG_LWIP_DHCP_DOES_ARP_CHECK
/*
------------------------------------
---------- AUTOIP options ----------
@@ -597,6 +602,7 @@
#define ESP_LIGHT_SLEEP 1
#define ESP_L2_TO_L3_COPY CONFIG_L2_TO_L3_COPY
#define ESP_CNT_DEBUG 0
#define ESP_DHCP_TIMER 1
#define TCP_WND_DEFAULT (4*TCP_MSS)
#define TCP_SND_BUF_DEFAULT (2*TCP_MSS)

View File

@@ -29,6 +29,7 @@
#include MBEDTLS_CONFIG_FILE
#endif
#include "platform.h"
#include "bignum.h"
#include "ecp.h"

View File

@@ -491,7 +491,7 @@ static const uint8_t * _mdns_read_fqdn(const uint8_t * packet, const uint8_t * s
&& (strcmp(buf, MDNS_DEFAULT_DOMAIN) != 0)
&& (strcmp(buf, "ip6") != 0)
&& (strcmp(buf, "in-addr") != 0)) {
sprintf((char*)name, "%s.%s", name->host, buf);
snprintf((char*)name, MDNS_NAME_BUF_LEN, "%s.%s", name->host, buf);
} else if (strcmp(buf, MDNS_SUB_STR) == 0) {
name->sub = 1;
} else {
@@ -499,7 +499,7 @@ static const uint8_t * _mdns_read_fqdn(const uint8_t * packet, const uint8_t * s
}
} else {
size_t address = (((uint16_t)len & 0x3F) << 8) | start[index++];
if ((packet + address) > start) {
if ((packet + address) >= start) {
//reference address can not be after where we are
return NULL;
}
@@ -1182,13 +1182,13 @@ static mdns_service_t * _mdns_create_service(const char * service, const char *
s->txt = NULL;
s->port = port;
s->service = strdup(service);
s->service = strndup(service, MDNS_NAME_BUF_LEN - 1);
if (!s->service) {
free(s);
return NULL;
}
s->proto = strdup(proto);
s->proto = strndup(proto, MDNS_NAME_BUF_LEN - 1);
if (!s->proto) {
free((char *)s->service);
free(s);
@@ -1341,7 +1341,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
(strcmp(name->proto, server->search.proto) != 0)) {
continue;//not searching for service or wrong service/proto
}
sprintf(answer->instance, "%s", name->host);
strlcpy(answer->instance, name->host, MDNS_NAME_BUF_LEN);
} else if (type == MDNS_TYPE_SRV) {
if (server->search.host[0] ||
(strcmp(name->service, server->search.service) != 0) ||
@@ -1353,7 +1353,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
continue;//instance name is not the same as the one in the PTR record
}
} else {
sprintf(answer->instance, "%s", name->host);
strlcpy(answer->instance, name->host, MDNS_NAME_BUF_LEN);
}
//parse record value
if (!_mdns_parse_fqdn(data, data_ptr + MDNS_SRV_FQDN_OFFSET, name)) {
@@ -1367,15 +1367,19 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
if (answer->host[0]) {
if (strcmp(answer->host, name->host) != 0) {
answer->addr = 0;
sprintf(answer->host, "%s", name->host);
strlcpy(answer->host, name->host, MDNS_NAME_BUF_LEN);
}
} else {
sprintf(answer->host, "%s", name->host);
strlcpy(answer->host, name->host, MDNS_NAME_BUF_LEN);
}
} else if (type == MDNS_TYPE_TXT) {
uint16_t i=0,b=0, y;
while(i < data_len) {
uint8_t partLen = data_ptr[i++];
//check if partLen will fit in the buffer
if (partLen > (MDNS_TXT_MAX_LEN - b - 1)) {
break;
}
for(y=0; y<partLen; y++) {
char d = data_ptr[i++];
answer->txt[b++] = d;
@@ -1391,7 +1395,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
continue;//wrong host
}
} else if (!answer->ptr) {
sprintf(answer->host, "%s", name->host);
strlcpy(answer->host, name->host, MDNS_NAME_BUF_LEN);
} else if (strcmp(answer->host, name->host) != 0) {
continue;//wrong host
}
@@ -1402,7 +1406,7 @@ static void _mdns_parse_packet(mdns_server_t * server, const uint8_t * data, siz
continue;//wrong host
}
} else if (!answer->ptr) {
sprintf(answer->host, "%s", name->host);
strlcpy(answer->host, name->host, MDNS_NAME_BUF_LEN);
} else if (strcmp(answer->host, name->host) != 0) {
continue;//wrong host
}
@@ -1534,6 +1538,9 @@ esp_err_t mdns_set_hostname(mdns_server_t * server, const char * hostname)
if (!server) {
return ESP_ERR_INVALID_ARG;
}
if (strlen(hostname) > (MDNS_NAME_BUF_LEN - 1)) {
return ESP_ERR_INVALID_ARG;
}
MDNS_MUTEX_LOCK();
free((char*)server->hostname);
server->hostname = (char *)malloc(strlen(hostname)+1);
@@ -1541,7 +1548,7 @@ esp_err_t mdns_set_hostname(mdns_server_t * server, const char * hostname)
MDNS_MUTEX_UNLOCK();
return ESP_ERR_NO_MEM;
}
sprintf((char *)server->hostname, "%s", hostname);
strlcpy((char *)server->hostname, hostname, MDNS_NAME_BUF_LEN);
MDNS_MUTEX_UNLOCK();
return ERR_OK;
}
@@ -1551,6 +1558,9 @@ esp_err_t mdns_set_instance(mdns_server_t * server, const char * instance)
if (!server) {
return ESP_ERR_INVALID_ARG;
}
if (strlen(instance) > (MDNS_NAME_BUF_LEN - 1)) {
return ESP_ERR_INVALID_ARG;
}
MDNS_MUTEX_LOCK();
free((char*)server->instance);
server->instance = (char *)malloc(strlen(instance)+1);
@@ -1558,7 +1568,7 @@ esp_err_t mdns_set_instance(mdns_server_t * server, const char * instance)
MDNS_MUTEX_UNLOCK();
return ESP_ERR_NO_MEM;
}
sprintf((char *)server->instance, "%s", instance);
strlcpy((char *)server->instance, instance, MDNS_NAME_BUF_LEN);
MDNS_MUTEX_UNLOCK();
return ERR_OK;
}
@@ -1655,6 +1665,9 @@ esp_err_t mdns_service_instance_set(mdns_server_t * server, const char * service
if (!server || !server->services || !service || !proto) {
return ESP_ERR_INVALID_ARG;
}
if (strlen(instance) > (MDNS_NAME_BUF_LEN - 1)) {
return ESP_ERR_INVALID_ARG;
}
mdns_srv_item_t * s = _mdns_get_service_item(server, service, proto);
if (!s) {
return ESP_ERR_NOT_FOUND;
@@ -1741,10 +1754,10 @@ uint32_t mdns_query(mdns_server_t * server, const char * service, const char * p
mdns_result_free(server);
if (proto) {
server->search.host[0] = 0;
snprintf(server->search.service, MDNS_NAME_MAX_LEN, "%s", service);
snprintf(server->search.proto, MDNS_NAME_MAX_LEN, "%s", proto);
strlcpy(server->search.service, service, MDNS_NAME_BUF_LEN);
strlcpy(server->search.proto, proto, MDNS_NAME_BUF_LEN);
} else {
snprintf(server->search.host, MDNS_NAME_MAX_LEN, "%s", service);
strlcpy(server->search.host, service, MDNS_NAME_BUF_LEN);
server->search.service[0] = 0;
server->search.proto[0] = 0;
qtype = MDNS_TYPE_A;

View File

@@ -21,6 +21,7 @@
#include "freertos/semphr.h"
#include "freertos/portmacro.h"
#include "freertos/task.h"
#include "freertos/portable.h"
/* Notes on our newlib lock implementation:
*
@@ -126,7 +127,7 @@ static int IRAM_ATTR lock_acquire_generic(_lock_t *lock, uint32_t delay, uint8_t
}
BaseType_t success;
if (cpu_in_interrupt_context()) {
if (xPortInIsrContext()) {
/* In ISR Context */
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
abort(); /* recursive mutexes make no sense in ISR context */
@@ -180,7 +181,7 @@ static void IRAM_ATTR lock_release_generic(_lock_t *lock, uint8_t mutex_type) {
return;
}
if (cpu_in_interrupt_context()) {
if (xPortInIsrContext()) {
if (mutex_type == queueQUEUE_TYPE_RECURSIVE_MUTEX) {
abort(); /* indicates logic bug, it shouldn't be possible to lock recursively in ISR */
}

View File

@@ -2,6 +2,7 @@ TEST_PROGRAM=test_nvs
all: $(TEST_PROGRAM)
SOURCE_FILES = \
esp_error_check_stub.cpp \
$(addprefix ../src/, \
nvs_types.cpp \
nvs_api.cpp \

View File

@@ -0,0 +1,9 @@
#include "catch.hpp"
#include "esp_err.h"
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
printf("ESP_ERROR_CHECK failed: esp_err_t 0x%x at %p\n", rc, __builtin_return_address(0));
printf("file: \"%s\" line %d\nfunc: %s\nexpression: %s\n", file, line, function, expression);
abort();
}

View File

@@ -0,0 +1,70 @@
menu "OpenSSL"
config OPENSSL_DEBUG
bool "Enable OpenSSL debugging"
default n
help
Enable OpenSSL debugging function.
If the option is enabled, "SSL_DEBUG" works.
config OPENSSL_DEBUG_LEVEL
int "OpenSSL debugging level"
default 0
range 0 255
depends on OPENSSL_DEBUG
help
OpenSSL debugging level.
Only function whose debugging level is higher than "OPENSSL_DEBUG_LEVEL" works.
For example:
If OPENSSL_DEBUG_LEVEL = 2, you use function "SSL_DEBUG(1, "malloc failed")". Because 1 < 2, it will not print.
config OPENSSL_LOWLEVEL_DEBUG
bool "Enable OpenSSL low-level module debugging"
default n
depends on OPENSSL_DEBUG
select MBEDTLS_DEBUG
help
If the option is enabled, low-level module debugging function of OpenSSL is enabled, e.g. mbedtls internal debugging function.
choice OPENSSL_ASSERT
prompt "Select OpenSSL assert function"
default CONFIG_OPENSSL_ASSERT_EXIT
help
OpenSSL function needs "assert" function to check if input parameters are valid.
If you want to use assert debugging function, "OPENSSL_DEBUG" should be enabled.
config OPENSSL_ASSERT_DO_NOTHING
bool "Do nothing"
help
Do nothing and "SSL_ASSERT" does not work.
config OPENSSL_ASSERT_EXIT
bool "Check and exit"
help
Enable assert exiting, it will check and return error code.
config OPENSSL_ASSERT_DEBUG
bool "Show debugging message"
depends on OPENSSL_DEBUG
help
Enable assert debugging, it will check and show debugging message.
config OPENSSL_ASSERT_DEBUG_EXIT
bool "Show debugging message and exit"
depends on OPENSSL_DEBUG
help
Enable assert debugging and exiting, it will check, show debugging message and return error code.
config OPENSSL_ASSERT_DEBUG_BLOCK
bool "Show debugging message and block"
depends on OPENSSL_DEBUG
help
Enable assert debugging and blocking, it will check, show debugging message and block by "while (1);".
endchoice
endmenu

View File

@@ -22,72 +22,170 @@
extern "C" {
#endif
#ifndef SSL_DEBUG_ENBALE
#define SSL_DEBUG_ENBALE 0
#endif
#ifndef SSL_DEBUG_LEVEL
#define SSL_DEBUG_LEVEL 0
#endif
#ifndef SSL_ASSERT_ENABLE
#define SSL_ASSERT_ENABLE 0
#endif
#ifndef SSL_DEBUG_LOCATION_ENABLE
#define SSL_DEBUG_LOCATION_ENABLE 0
#endif
#if SSL_DEBUG_ENBALE
#if !defined(SSL_PRINT_LOG) || !defined(SSL_ERROR_LOG) || !defined(SSL_LOCAL_LOG)
#include "stdio.h"
extern int printf(const char *fmt, ...);
#ifndef SSL_PRINT_LOG
#define SSL_PRINT_LOG printf
#endif
#ifndef SSL_ERROR_LOG
#define SSL_ERROR_LOG printf
#endif
#ifndef SSL_LOCAL_LOG
#define SSL_LOCAL_LOG printf
#endif
#endif
#ifdef CONFIG_OPENSSL_DEBUG_LEVEL
#define SSL_DEBUG_LEVEL CONFIG_OPENSSL_DEBUG_LEVEL
#else
#ifdef SSL_PRINT_LOG
#undef SSL_PRINT_LOG
#endif
#define SSL_PRINT_LOG(...)
#ifdef SSL_ERROR_LOG
#undef SSL_ERROR_LOG
#endif
#define SSL_ERROR_LOG(...)
#ifdef SSL_LOCAL_LOG
#undef SSL_LOCAL_LOG
#endif
#define SSL_LOCAL_LOG(...)
#define SSL_DEBUG_LEVEL 0
#endif
#if SSL_DEBUG_LOCATION_ENABLE
#define SSL_DEBUG_LOCATION() SSL_LOCAL_LOG("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__)
#define SSL_DEBUG_ON (SSL_DEBUG_LEVEL + 1)
#define SSL_DEBUG_OFF (SSL_DEBUG_LEVEL - 1)
#ifdef CONFIG_OPENSSL_DEBUG
#ifndef SSL_DEBUG_LOG
#error "SSL_DEBUG_LOG is not defined"
#endif
#ifndef SSL_DEBUG_FL
#define SSL_DEBUG_FL "\n"
#endif
#define SSL_SHOW_LOCATION() \
SSL_DEBUG_LOG("SSL assert : %s %d\n", \
__FILE__, __LINE__)
#define SSL_DEBUG(level, fmt, ...) \
{ \
if (level > SSL_DEBUG_LEVEL) { \
SSL_DEBUG_LOG(fmt SSL_DEBUG_FL, ##__VA_ARGS__); \
} \
}
#else /* CONFIG_OPENSSL_DEBUG */
#define SSL_SHOW_LOCATION()
#define SSL_DEBUG(level, fmt, ...)
#endif /* CONFIG_OPENSSL_DEBUG */
/**
* OpenSSL assert function
*
* if select "CONFIG_OPENSSL_ASSERT_DEBUG", SSL_ASSERT* will show error file name and line
* if select "CONFIG_OPENSSL_ASSERT_EXIT", SSL_ASSERT* will just return error code.
* if select "CONFIG_OPENSSL_ASSERT_DEBUG_EXIT" SSL_ASSERT* will show error file name and line,
* then return error code.
* if select "CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK", SSL_ASSERT* will show error file name and line,
* then block here with "while (1)"
*
* SSL_ASSERT1 may will return "-1", so function's return argument is integer.
* SSL_ASSERT2 may will return "NULL", so function's return argument is a point.
* SSL_ASSERT2 may will return nothing, so function's return argument is "void".
*/
#if defined(CONFIG_OPENSSL_ASSERT_DEBUG)
#define SSL_ASSERT1(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
} \
}
#define SSL_ASSERT2(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
} \
}
#define SSL_ASSERT3(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
} \
}
#elif defined(CONFIG_OPENSSL_ASSERT_EXIT)
#define SSL_ASSERT1(s) \
{ \
if (!(s)) { \
return -1; \
} \
}
#define SSL_ASSERT2(s) \
{ \
if (!(s)) { \
return NULL; \
} \
}
#define SSL_ASSERT3(s) \
{ \
if (!(s)) { \
return ; \
} \
}
#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_EXIT)
#define SSL_ASSERT1(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
return -1; \
} \
}
#define SSL_ASSERT2(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
return NULL; \
} \
}
#define SSL_ASSERT3(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
return ; \
} \
}
#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK)
#define SSL_ASSERT1(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
while (1); \
} \
}
#define SSL_ASSERT2(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
while (1); \
} \
}
#define SSL_ASSERT3(s) \
{ \
if (!(s)) { \
SSL_SHOW_LOCATION(); \
while (1); \
} \
}
#else
#define SSL_DEBUG_LOCATION()
#define SSL_ASSERT1(s)
#define SSL_ASSERT2(s)
#define SSL_ASSERT3(s)
#endif
#if SSL_ASSERT_ENABLE
#define SSL_ASSERT(s) { if (!(s)) { SSL_DEBUG_LOCATION(); } }
#else
#define SSL_ASSERT(s)
#endif
#define SSL_PLATFORM_DEBUG_LEVEL SSL_DEBUG_OFF
#define SSL_PLATFORM_ERROR_LEVEL SSL_DEBUG_ON
#define SSL_ERR(err, go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); ret = err; goto go; }
#define SSL_CERT_DEBUG_LEVEL SSL_DEBUG_OFF
#define SSL_CERT_ERROR_LEVEL SSL_DEBUG_ON
#define SSL_RET(go, fmt, ...) { SSL_DEBUG_LOCATION(); SSL_ERROR_LOG(fmt, ##__VA_ARGS__); goto go; }
#define SSL_PKEY_DEBUG_LEVEL SSL_DEBUG_OFF
#define SSL_PKEY_ERROR_LEVEL SSL_DEBUG_ON
#define SSL_DEBUG(level, fmt, ...) { if (level > SSL_DEBUG_LEVEL) {SSL_PRINT_LOG(fmt, ##__VA_ARGS__);} }
#define SSL_X509_DEBUG_LEVEL SSL_DEBUG_OFF
#define SSL_X509_ERROR_LEVEL SSL_DEBUG_ON
#define SSL_LIB_DEBUG_LEVEL SSL_DEBUG_OFF
#define SSL_LIB_ERROR_LEVEL SSL_DEBUG_ON
#define SSL_STACK_DEBUG_LEVEL SSL_DEBUG_OFF
#define SSL_STACK_ERROR_LEVEL SSL_DEBUG_ON
#ifdef __cplusplus
}
}
#endif
#endif

View File

@@ -15,34 +15,6 @@
#ifndef _SSL_OPT_H_
#define _SSL_OPT_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* if not define "ESP32_IDF_PLATFORM", system will use esp8266 platform interface
*/
#define ESP32_IDF_PLATFORM
/**
* openssl debug print function enable
*/
#define SSL_DEBUG_ENBALE 0
/**
* openssl debug print function level. function whose level is lower that "SSL_DEBUG_LEVEL"
* will not print message
*/
#define SSL_DEBUG_LEVEL 0
/**
* openssl assert function enable, it will check the input paramter and print the message
*/
#define SSL_ASSERT_ENABLE 0
/**
* openssl location function enable, it will print location of the positioning error
*/
#define SSL_DEBUG_LOCATION_ENABLE 0
#include "sdkconfig.h"
#endif

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