mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
component/bt: Merge branch 'master' into feature/btdm_a2dp
This commit is contained in:
commit
c94e0177c2
@ -14,9 +14,10 @@ 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 libs.
|
||||
# if testing other branches, use gitlab wifi 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%ssh://git@gitlab.espressif.cn:27227/idf/esp32-wifi-lib%" .gitmodules
|
||||
# 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
|
||||
# fetch all submodules
|
||||
- git submodule update --init --recursive
|
||||
|
||||
@ -247,6 +248,8 @@ deploy_docs:
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
# remove artifacts from last stage (UT logs)
|
||||
- rm -rf $LOG_PATH
|
||||
# add gitlab ssh key
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
@ -268,6 +271,8 @@ deploy_docs:
|
||||
# can only be triggered
|
||||
- triggers
|
||||
script:
|
||||
# remove artifacts from last stage (UT logs)
|
||||
- rm -rf $LOG_PATH
|
||||
# must be night build triggers, otherwise exit without test
|
||||
- test $NIGHT_BUILD = "Yes" || exit 0
|
||||
# add gitlab ssh key
|
||||
@ -345,7 +350,6 @@ IT_Function_TCPIP_02:
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml
|
||||
|
||||
@ -372,10 +376,73 @@ IT_Function_TCPIP_05:
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml
|
||||
|
||||
IT_Stress_WIFI_01:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_WIFI_01.yml
|
||||
|
||||
IT_Stress_TCPIP_01:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_01.yml
|
||||
|
||||
IT_Stress_TCPIP_02:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_02.yml
|
||||
|
||||
IT_Stress_TCPIP_03:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_03.yml
|
||||
|
||||
IT_Stress_TCPIP_04:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_04.yml
|
||||
|
||||
IT_Stable_TCPIP_01:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_01.yml
|
||||
|
||||
IT_Stable_TCPIP_02:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_02.yml
|
||||
|
||||
IT_Stable_TCPIP_03:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_03.yml
|
||||
|
||||
IT_Function_TCPIP_06:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
@ -388,7 +455,7 @@ IT_Function_WIFI_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_PhyMode
|
||||
- SSC_T1_APC
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml
|
||||
|
||||
@ -396,7 +463,7 @@ IT_Function_WIFI_04:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_APC
|
||||
- SSC_T3_PhyMode
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml
|
||||
|
||||
@ -422,7 +489,6 @@ IT_Function_TCPIP_07:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml
|
||||
|
||||
@ -431,6 +497,7 @@ IT_Function_TCPIP_08:
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml
|
||||
|
||||
@ -439,6 +506,7 @@ IT_Function_TCPIP_09:
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml
|
||||
|
||||
@ -448,7 +516,6 @@ IT_Function_TCPIP_10:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml
|
||||
|
||||
@ -457,7 +524,6 @@ IT_Function_TCPIP_11:
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml
|
||||
|
||||
@ -468,3 +534,4 @@ IT_Function_TCPIP_12:
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml
|
||||
|
||||
|
@ -64,6 +64,12 @@ In both cases the factory app is flashed at offset 0x10000. If you `make partiti
|
||||
|
||||
For more details about partition tables and how to create custom variations, view the `docs/partition-tables.rst` file.
|
||||
|
||||
# Erasing Flash
|
||||
|
||||
The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
|
||||
|
||||
This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
|
||||
|
||||
# Resources
|
||||
|
||||
* The [docs directory of the esp-idf repository](docs) contains source of [esp-idf](http://esp-idf.readthedocs.io/) documentation.
|
||||
|
@ -134,9 +134,7 @@ 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)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ota_ops_entry_t *it;
|
||||
size_t image_size;
|
||||
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
|
||||
@ -145,6 +143,8 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
@ -286,12 +286,12 @@ 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)
|
||||
{
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
size_t image_size;
|
||||
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) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
menu "Bootloader config"
|
||||
choice LOG_BOOTLOADER_LEVEL
|
||||
bool "Bootloader log verbosity"
|
||||
default LOG_BOOTLOADER_LEVEL_WARN
|
||||
default LOG_BOOTLOADER_LEVEL_INFO
|
||||
help
|
||||
Specify how much output to see in bootloader logs.
|
||||
|
||||
@ -32,23 +32,24 @@ endmenu
|
||||
|
||||
|
||||
|
||||
menu "Secure boot configuration"
|
||||
menu "Security features"
|
||||
|
||||
choice SECURE_BOOTLOADER
|
||||
bool "Secure bootloader"
|
||||
default SECURE_BOOTLOADER_DISABLED
|
||||
config SECURE_BOOT_ENABLED
|
||||
bool "Enable secure boot in bootloader"
|
||||
default N
|
||||
help
|
||||
Build a bootloader with the secure boot flag enabled.
|
||||
Build a bootloader which enables secure boot on first boot.
|
||||
|
||||
Secure bootloader can be one-time-flash (chip will only ever
|
||||
boot that particular bootloader), or a digest key can be used
|
||||
to allow the secure bootloader to be re-flashed with
|
||||
modifications. Secure boot also permanently disables JTAG.
|
||||
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.
|
||||
|
||||
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
|
||||
|
||||
See docs/security/secure-boot.rst for details.
|
||||
|
||||
config SECURE_BOOTLOADER_DISABLED
|
||||
bool "Disabled"
|
||||
choice SECURE_BOOTLOADER_MODE
|
||||
bool "Secure bootloader mode"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
config SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
bool "One-time flash"
|
||||
@ -62,18 +63,29 @@ config SECURE_BOOTLOADER_REFLASHABLE
|
||||
help
|
||||
Generate a reusable secure bootloader key, derived (via SHA-256) from the secure boot signing key.
|
||||
|
||||
This allows the secure bootloader to be re-flashed by anyone with access to the secure boot signing key.
|
||||
This allows the secure bootloader to be re-flashed by anyone with access to the secure boot signing key.
|
||||
|
||||
This option is less secure than one-time flash, because a leak of the digest key from one device allows reflashing of any device that uses it.
|
||||
|
||||
endchoice
|
||||
|
||||
config SECURE_BOOT_SIGNING_KEY
|
||||
string "Secure boot signing key"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default secure_boot_signing_key.pem
|
||||
config SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
bool "Sign binaries during build"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default y
|
||||
help
|
||||
Path to the key file used to sign partition tables and app images for secure boot.
|
||||
Once secure boot is enabled, bootloader will only boot if partition table and app image are signed.
|
||||
|
||||
If enabled, these binary files are signed as part of the build process. The file named in "Secure boot private signing key" will be used to sign the image.
|
||||
|
||||
If disabled, unsigned app/partition data will be built. They must be signed manually using espsecure.py (for example, on a remote signing server.)
|
||||
|
||||
config SECURE_BOOT_SIGNING_KEY
|
||||
string "Secure boot private signing key"
|
||||
depends on SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default secure_boot_signing_key.pem
|
||||
help
|
||||
Path to the key file used to sign partition tables and app images for secure boot. Once secure boot is enabled, bootloader will only boot if partition table and app image are signed.
|
||||
|
||||
Key file is an ECDSA private key (NIST256p curve) in PEM format.
|
||||
|
||||
@ -84,35 +96,120 @@ config SECURE_BOOT_SIGNING_KEY
|
||||
|
||||
See docs/security/secure-boot.rst for details.
|
||||
|
||||
config SECURE_BOOT_DISABLE_JTAG
|
||||
bool "First boot: Permanently disable JTAG"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default Y
|
||||
config SECURE_BOOT_VERIFICATION_KEY
|
||||
string "Secure boot public signature verification key"
|
||||
depends on SECURE_BOOT_ENABLED && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default signature_verification_key.bin
|
||||
help
|
||||
Path to a public key file used to verify signed images. This key is compiled into the bootloader,
|
||||
and may also be used to verify signatures on OTA images after download.
|
||||
|
||||
Key file is in raw binary format, and can be extracted from a
|
||||
PEM formatted private key using the espsecure.py
|
||||
extract_public_key command.
|
||||
|
||||
See docs/security/secure-boot.rst for details.
|
||||
|
||||
config SECURE_BOOT_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by secure boot, in order to enable testing or a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to docs/security/secure-boot.rst and docs/security/flash-encryption.rst for details.
|
||||
|
||||
config FLASH_ENCRYPTION_ENABLED
|
||||
bool "Enable flash encryption on boot"
|
||||
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.
|
||||
|
||||
config FLASH_ENCRYPTION_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on FLASH_ENCRYPTION_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by flash encryption, in order to enable testing or a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to docs/security/secure-boot.rst and docs/security/flash-encryption.rst for details.
|
||||
|
||||
menu "Potentially insecure options"
|
||||
visible if FLASH_ENCRYPTION_INSECURE || SECURE_BOOT_INSECURE
|
||||
|
||||
# NOTE: Options in this menu NEED to have SECURE_BOOT_INSECURE
|
||||
# and/or FLASH_ENCRYPTION_INSECURE in "depends on", as the menu
|
||||
# itself doesn't enable/disable its children (if it's not set,
|
||||
# it's possible for the insecure menu to be disabled but the insecure option
|
||||
# to remain on which is very bad.)
|
||||
|
||||
config SECURE_BOOT_ALLOW_ROM_BASIC
|
||||
bool "Leave ROM BASIC Interpreter available on reset"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
default N
|
||||
help
|
||||
Bootloader permanently disable JTAG (across entire chip) when enabling secure boot. This happens on first boot of the bootloader.
|
||||
If not set (default), bootloader permanently disables ROM BASIC (on UART console) as a fallback if the bootloader image becomes invalid. This happens on first boot.
|
||||
|
||||
It is recommended this option remains set for production environments.
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_DISABLE_ROM_BASIC
|
||||
bool "First boot: Permanently disable ROM BASIC fallback"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default Y
|
||||
config SECURE_BOOT_ALLOW_JTAG
|
||||
bool "Allow JTAG Debugging"
|
||||
depends on SECURE_BOOT_INSECURE || FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
Bootloader permanently disables ROM BASIC (on UART console) as a fallback if the bootloader image becomes invalid. This happens on first boot.
|
||||
If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot when either secure boot or flash encryption is enabled.
|
||||
|
||||
It is recommended this option remains set in production environments.
|
||||
Setting this option leaves JTAG on for debugging, which negates all protections of flash encryption and some of the protections of secure boot.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
bool "Leave UART bootloader encryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader encryption access on first boot. If set, the UART bootloader will still be able to access hardware encryption.
|
||||
|
||||
It is recommended to only set this option in testing environments.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT
|
||||
bool "Leave UART bootloader decryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader decryption access on first boot. If set, the UART bootloader will still be able to access hardware decryption.
|
||||
|
||||
Only set this option in testing environments. Setting this option allows complete bypass of flash encryption.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE
|
||||
bool "Leave UART bootloader flash cache enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader flash cache access on first boot. If set, the UART bootloader will still be able to access the flash cache.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_TEST_MODE
|
||||
bool "Test mode: don't actually enable secure boot"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
bool "Secure boot test mode: don't permanently set any efuses"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
default N
|
||||
help
|
||||
If this option is set, all permanent secure boot changes (via Efuse) are disabled.
|
||||
|
||||
This option is for testing purposes only - it effectively completely disables secure boot protection.
|
||||
Log output will state changes which would be applied, but they will not be.
|
||||
|
||||
config SECURE_BOOTLOADER_ENABLED
|
||||
bool
|
||||
default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE
|
||||
This option is for testing purposes only - it completely disables secure boot protection.
|
||||
|
||||
|
||||
endmenu # potentially insecure
|
||||
|
||||
endmenu
|
@ -18,6 +18,9 @@ BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||
SECURE_BOOT_SIGNING_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOT_SIGNING_KEY)))
|
||||
export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component
|
||||
|
||||
# Has a matching value in bootloader_support esp_flash_partitions.h
|
||||
BOOTLOADER_OFFSET := 0x1000
|
||||
|
||||
# Custom recursive make for bootloader sub-project
|
||||
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
||||
V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) TEST_COMPONENTS=
|
||||
@ -29,66 +32,56 @@ $(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE)
|
||||
|
||||
clean: bootloader-clean
|
||||
|
||||
ifdef CONFIG_SECURE_BOOTLOADER_DISABLED
|
||||
ifndef CONFIG_SECURE_BOOT_ENABLED
|
||||
# If secure boot disabled, bootloader flashing is integrated
|
||||
# with 'make flash' and no warnings are printed.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. Default flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $^"
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)
|
||||
|
||||
bootloader-flash: $(BOOTLOADER_BIN)
|
||||
bootloader-flash: $(BOOTLOADER_BIN) $(call prereq_if_explicit,erase_flash)
|
||||
$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^
|
||||
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
#### TEMPORARILY DISABLE THIS OPTION
|
||||
ifneq ("$(IDF_INSECURE_SECURE_BOOT)","1")
|
||||
bootloader:
|
||||
@echo "Secure boot features are not yet mature, so the current secure bootloader will not properly secure the device"
|
||||
@echo "If you flash this bootloader, you will be left with an non-updateable bootloader that is missing features."
|
||||
@echo "If you really want to do this, set the environment variable IDF_INSECURE_SECURE_BOOT=1 and rerun make."
|
||||
exit 1
|
||||
else
|
||||
|
||||
# One time flashing requires user to run esptool.py command themselves,
|
||||
# and warning is printed about inability to reflash.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. One-time flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)"
|
||||
@echo $(SEPARATOR)
|
||||
@echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||
|
||||
endif # IDF_INSECURE_SECURE_BOOT
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE
|
||||
# Reflashable secure bootloader
|
||||
# generates a digest binary (bootloader + digest)
|
||||
|
||||
#### TEMPORARILY DISABLE THIS OPTION
|
||||
ifneq ("$(IDF_INSECURE_SECURE_BOOT)","1")
|
||||
bootloader:
|
||||
@echo "Secure boot features are not yet mature, so the current secure bootloader will not properly secure the device."
|
||||
@echo "If using this feature, expect to reflash the bootloader at least one more time."
|
||||
@echo "If you really want to do this, set the environment variable IDF_INSECURE_SECURE_BOOT=1 and rerun make."
|
||||
exit 1
|
||||
else
|
||||
|
||||
BOOTLOADER_DIGEST_BIN := $(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin
|
||||
SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin
|
||||
|
||||
ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
$(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY)
|
||||
$(Q) $(ESPSECUREPY) digest_private_key -k $< $@
|
||||
$(ESPSECUREPY) digest_private_key -k $< $@
|
||||
else
|
||||
$(SECURE_BOOTLOADER_KEY):
|
||||
@echo "No pre-generated key for a reflashable secure bootloader is available, due to signing configuration."
|
||||
@echo "To generate one, you can use this command:"
|
||||
@echo "espsecure.py generate_flash_encryption_key $@"
|
||||
@echo "then re-run make."
|
||||
exit 1
|
||||
endif
|
||||
|
||||
bootloader: $(BOOTLOADER_DIGEST_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built and secure digest generated. First time flash command is:"
|
||||
@echo "$(ESPEFUSEPY) burn_key secure_boot $(SECURE_BOOTLOADER_KEY)"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)"
|
||||
@echo $(SEPARATOR)
|
||||
@echo "To reflash the bootloader after initial flash:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x0 $(BOOTLOADER_DIGEST_BIN)"
|
||||
@ -100,14 +93,16 @@ $(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY)
|
||||
@echo "DIGEST $(notdir $@)"
|
||||
$(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
|
||||
|
||||
endif # IDF_INSECURE_SECURE_BOOT
|
||||
else
|
||||
bootloader:
|
||||
@echo "Invalid bootloader target: bad sdkconfig?"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SECURE_BOOT_ENABLED
|
||||
# don't build bootloader by default is secure boot is enabled
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
endif
|
||||
|
||||
bootloader-clean:
|
||||
$(BOOTLOADER_MAKE) app-clean
|
||||
|
@ -34,20 +34,6 @@ extern "C"
|
||||
#define RTC_DATA_LOW 0x50000000
|
||||
#define RTC_DATA_HIGH 0x50002000
|
||||
|
||||
#define PART_TYPE_APP 0x00
|
||||
#define PART_SUBTYPE_FACTORY 0x00
|
||||
#define PART_SUBTYPE_OTA_FLAG 0x10
|
||||
#define PART_SUBTYPE_OTA_MASK 0x0f
|
||||
#define PART_SUBTYPE_TEST 0x20
|
||||
|
||||
#define PART_TYPE_DATA 0x01
|
||||
#define PART_SUBTYPE_DATA_OTA 0x00
|
||||
#define PART_SUBTYPE_DATA_RF 0x01
|
||||
#define PART_SUBTYPE_DATA_WIFI 0x02
|
||||
|
||||
#define PART_TYPE_END 0xff
|
||||
#define PART_SUBTYPE_END 0xff
|
||||
|
||||
#define SPI_ERROR_LOG "spi flash error"
|
||||
|
||||
typedef struct {
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/gpio.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
@ -31,10 +33,13 @@
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "bootloader_flash.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
@ -54,7 +59,7 @@ extern void Cache_Flush(int);
|
||||
void bootloader_main();
|
||||
static void unpack_load_app(const esp_partition_pos_t *app_node);
|
||||
void print_flash_info(const esp_image_header_t* pfhdr);
|
||||
void set_cache_and_start_app(uint32_t drom_addr,
|
||||
static void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
uint32_t irom_addr,
|
||||
@ -62,7 +67,7 @@ void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
static void uart_console_configure(void);
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
@ -117,7 +122,7 @@ bool load_partition_table(bootloader_state_t* bs)
|
||||
ESP_LOGI(TAG, "Partition Table:");
|
||||
ESP_LOGI(TAG, "## Label Usage Type ST Offset Length");
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
if(esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "Verifying partition table signature...");
|
||||
esp_err_t err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
@ -224,8 +229,11 @@ static bool ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
|
||||
void bootloader_main()
|
||||
{
|
||||
uart_console_configure();
|
||||
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||
esp_err_t err;
|
||||
#endif
|
||||
esp_image_header_t fhdr;
|
||||
bootloader_state_t bs;
|
||||
SpiFlashOpResult spiRet1,spiRet2;
|
||||
@ -240,7 +248,7 @@ void bootloader_main()
|
||||
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||
SPIUnlock();
|
||||
|
||||
if(esp_image_load_header(0x1000, &fhdr) != ESP_OK) {
|
||||
if(esp_image_load_header(0x1000, true, &fhdr) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||
return;
|
||||
}
|
||||
@ -258,7 +266,7 @@ void bootloader_main()
|
||||
|
||||
if (bs.ota_info.offset != 0) { // check if partition table has OTA info partition
|
||||
//ESP_LOGE("OTA info sector handling is not implemented");
|
||||
if (bs.ota_info.size < 2 * sizeof(esp_ota_select_entry_t)) {
|
||||
if (bs.ota_info.size < 2 * SPI_SEC_SIZE) {
|
||||
ESP_LOGE(TAG, "ERROR: ota_info partition size %d is too small (minimum %d bytes)", bs.ota_info.size, sizeof(esp_ota_select_entry_t));
|
||||
return;
|
||||
}
|
||||
@ -267,10 +275,9 @@ void bootloader_main()
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", bs.ota_info.offset, bs.ota_info.size);
|
||||
return;
|
||||
}
|
||||
sa = ota_select_map[0];
|
||||
sb = ota_select_map[1];
|
||||
memcpy(&sa, ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&sb, (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
|
||||
if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) {
|
||||
// init status flash
|
||||
if (bs.factory.offset != 0) { // if have factory bin,boot factory bin
|
||||
@ -319,12 +326,11 @@ void bootloader_main()
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos);
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* Generate secure digest from this bootloader to protect future
|
||||
modifications */
|
||||
esp_err_t err = esp_secure_boot_permanently_enable();
|
||||
ESP_LOGI(TAG, "Checking secure boot...");
|
||||
err = esp_secure_boot_permanently_enable();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
|
||||
/* Allow booting to continue, as the failure is probably
|
||||
@ -333,19 +339,31 @@ void bootloader_main()
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fhdr.encrypt_flag == 0x01) {
|
||||
/* encrypt flash */
|
||||
if (false == flash_encrypt(&bs)) {
|
||||
ESP_LOGE(TAG, "flash encrypt failed");
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
/* encrypt flash */
|
||||
ESP_LOGI(TAG, "Checking flash encryption...");
|
||||
bool flash_encryption_enabled = esp_flash_encryption_enabled();
|
||||
err = esp_flash_encrypt_check_and_update();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Flash encryption check failed (%d).", err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
|
||||
/* Flash encryption was just enabled for the first time,
|
||||
so issue a system reset to ensure flash encryption
|
||||
cache resets properly */
|
||||
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||
ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos);
|
||||
unpack_load_app(&load_part_pos);
|
||||
}
|
||||
|
||||
|
||||
static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
{
|
||||
esp_err_t err;
|
||||
@ -353,13 +371,13 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
uint32_t image_length;
|
||||
|
||||
/* TODO: verify the app image as part of OTA boot decision, so can have fallbacks */
|
||||
err = esp_image_basic_verify(partition->offset, &image_length);
|
||||
err = esp_image_basic_verify(partition->offset, true, &image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "Verifying app signature @ 0x%x (length 0x%x)", partition->offset, image_length);
|
||||
err = esp_secure_boot_verify_signature(partition->offset, image_length);
|
||||
@ -371,7 +389,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (esp_image_load_header(partition->offset, &image_header) != ESP_OK) {
|
||||
if (esp_image_load_header(partition->offset, true, &image_header) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset);
|
||||
return;
|
||||
}
|
||||
@ -393,12 +411,15 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
image_header.spi_size,
|
||||
(unsigned)image_header.entry_addr);
|
||||
|
||||
/* Important: From here on this function cannot access any global data (bss/data segments),
|
||||
as loading the app image may overwrite these.
|
||||
*/
|
||||
for (int segment = 0; segment < image_header.segment_count; segment++) {
|
||||
esp_image_segment_header_t segment_header;
|
||||
uint32_t data_offs;
|
||||
if(esp_image_load_segment_header(segment, partition->offset,
|
||||
&image_header, &segment_header,
|
||||
&data_offs) != ESP_OK) {
|
||||
&image_header, true,
|
||||
&segment_header, &data_offs) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load segment header #%d", segment);
|
||||
return;
|
||||
}
|
||||
@ -448,6 +469,31 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
segment_header.load_addr, segment_header.data_len, segment_header.data_len, (load)?"load":(map)?"map":"");
|
||||
|
||||
if (load) {
|
||||
intptr_t sp, start_addr, end_addr;
|
||||
ESP_LOGV(TAG, "bootloader_mmap data_offs=%08x data_len=%08x", data_offs, segment_header.data_len);
|
||||
|
||||
start_addr = segment_header.load_addr;
|
||||
end_addr = start_addr + segment_header.data_len;
|
||||
|
||||
/* Before loading segment, check it doesn't clobber
|
||||
bootloader RAM... */
|
||||
|
||||
if (end_addr < 0x40000000) {
|
||||
sp = (intptr_t)get_sp();
|
||||
if (end_addr > sp) {
|
||||
ESP_LOGE(TAG, "Segment %d end address %08x overlaps bootloader stack %08x - can't load",
|
||||
segment, end_addr, sp);
|
||||
return;
|
||||
}
|
||||
if (end_addr > sp - 256) {
|
||||
/* We don't know for sure this is the stack high water mark, so warn if
|
||||
it seems like we may overflow.
|
||||
*/
|
||||
ESP_LOGW(TAG, "Segment %d end address %08x close to stack pointer %08x",
|
||||
segment, end_addr, sp);
|
||||
}
|
||||
}
|
||||
|
||||
const void *data = bootloader_mmap(data_offs, segment_header.data_len);
|
||||
if(!data) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%xc, 0x%x) failed",
|
||||
@ -468,7 +514,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
image_header.entry_addr);
|
||||
}
|
||||
|
||||
void set_cache_and_start_app(
|
||||
static void set_cache_and_start_app(
|
||||
uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
@ -616,3 +662,65 @@ void print_flash_info(const esp_image_header_t* phdr)
|
||||
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_CONSOLE_UART_CUSTOM
|
||||
static uint32_t get_apb_freq(void)
|
||||
{
|
||||
// Get the value of APB clock from RTC memory.
|
||||
// The value is initialized in ROM code, and updated by librtc.a
|
||||
// when APB clock is changed.
|
||||
// This value is stored in RTC_CNTL_STORE5_REG as follows:
|
||||
// RTC_CNTL_STORE5_REG = (freq >> 12) | ((freq >> 12) << 16)
|
||||
uint32_t apb_freq_reg = REG_READ(RTC_CNTL_STORE5_REG);
|
||||
uint32_t apb_freq_l = apb_freq_reg & 0xffff;
|
||||
uint32_t apb_freq_h = apb_freq_reg >> 16;
|
||||
if (apb_freq_l == apb_freq_h && apb_freq_l != 0) {
|
||||
return apb_freq_l << 12;
|
||||
} else {
|
||||
// fallback value
|
||||
return APB_CLK_FREQ_ROM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void uart_console_configure(void)
|
||||
{
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
#if CONFIG_CONSOLE_UART_CUSTOM
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_num = CONFIG_CONSOLE_UART_NUM;
|
||||
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
|
||||
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
|
||||
// ROM bootloader may have put a lot of text into UART0 FIFO.
|
||||
// Wait for it to be printed.
|
||||
uart_tx_wait_idle(0);
|
||||
// Switch to the new UART (this just changes UART number used for
|
||||
// ets_printf in ROM code).
|
||||
uart_tx_switch(uart_num);
|
||||
// Set new baud rate
|
||||
uart_div_modify(uart_num, (((uint64_t) get_apb_freq()) << 4) / uart_baud);
|
||||
// If console is attached to UART1 or if non-default pins are used,
|
||||
// need to reconfigure pins using GPIO matrix
|
||||
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
|
||||
// Change pin mode for GPIO1/3 from UART to GPIO
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
|
||||
// Route GPIO signals to/from pins
|
||||
// (arrays should be optimized away by the compiler)
|
||||
const uint32_t tx_idx_list[3] = { U0TXD_OUT_IDX, U1TXD_OUT_IDX, U2TXD_OUT_IDX };
|
||||
const uint32_t rx_idx_list[3] = { U0RXD_IN_IDX, U1RXD_IN_IDX, U2RXD_IN_IDX };
|
||||
const uint32_t tx_idx = tx_idx_list[uart_num];
|
||||
const uint32_t rx_idx = rx_idx_list[uart_num];
|
||||
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
|
||||
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
|
||||
}
|
||||
#endif // CONFIG_CONSOLE_UART_CUSTOM
|
||||
#endif // CONFIG_CONSOLE_UART_NONE
|
||||
}
|
||||
|
@ -5,5 +5,8 @@
|
||||
# we pull in bootloader-specific linker arguments.
|
||||
#
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld
|
||||
LINKER_SCRIPTS := esp32.bootloader.ld $(IDF_PATH)/components/esp32/ld/esp32.rom.ld
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SCRIPTS))
|
||||
|
||||
COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS)
|
||||
|
@ -1,188 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
#include "esp_image_format.h"
|
||||
|
||||
static const char* TAG = "flash_encrypt";
|
||||
|
||||
/**
|
||||
* @function : bitcount
|
||||
* @description: calculate bit 1 in flash_crypt_cnt
|
||||
* if it's even number, need encrypt flash data, and burn efuse
|
||||
*
|
||||
* @inputs: n flash_crypt_cnt
|
||||
* @return: number of 1 in flash_crypt_cnt
|
||||
*
|
||||
*/
|
||||
int bitcount(int n){
|
||||
int count = 0;
|
||||
while (n > 0) {
|
||||
count += n & 1;
|
||||
n >>= 1;
|
||||
}
|
||||
return count;
|
||||
|
||||
}
|
||||
/**
|
||||
* @function : flash_encrypt_write
|
||||
* @description: write encrypted data in flash
|
||||
*
|
||||
* @inputs: pos address in flash
|
||||
* len size of data need encrypt
|
||||
* @return: return true, if the write flash success
|
||||
*
|
||||
*/
|
||||
bool flash_encrypt_write(uint32_t pos, uint32_t len)
|
||||
{
|
||||
SpiFlashOpResult spiRet;
|
||||
uint32_t buf[1024];
|
||||
int i = 0;
|
||||
Cache_Read_Disable(0);
|
||||
for (i = 0;i<((len-1)/0x1000 + 1);i++) {
|
||||
spiRet = SPIRead(pos, buf, SPI_SEC_SIZE);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
Cache_Read_Enable(0);
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
spiRet = SPIEraseSector(pos/SPI_SEC_SIZE);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
Cache_Read_Enable(0);
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
spiRet = SPI_Encrypt_Write(pos, buf, SPI_SEC_SIZE);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
Cache_Read_Enable(0);
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
pos += SPI_SEC_SIZE;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @function : flash_encrypt
|
||||
* @description: encrypt 2nd boot ,partition table ,factory bin <EFBFBD><EFBFBD>test bin (if use)<EFBFBD><EFBFBD>ota bin
|
||||
* <EFBFBD><EFBFBD>OTA info sector.
|
||||
*
|
||||
* @inputs: bs bootloader state structure used to save the data
|
||||
*
|
||||
* @return: return true, if the encrypt flash success
|
||||
*
|
||||
*/
|
||||
bool flash_encrypt(bootloader_state_t *bs)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t image_len = 0;
|
||||
uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_FLASH_CRYPT_CNT);
|
||||
uint8_t count = bitcount(flash_crypt_cnt);
|
||||
ESP_LOGD(TAG, "flash encrypt cnt %x, bitcount %d", flash_crypt_cnt, count);
|
||||
|
||||
if ((count % 2) == 0) {
|
||||
/* encrypt iv and abstract */
|
||||
if (false == flash_encrypt_write(0, SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt iv and abstract error");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* encrypt bootloader image */
|
||||
err = esp_image_basic_verify(0x1000, &image_len);
|
||||
if(err == ESP_OK && image_len != 0) {
|
||||
if (false == flash_encrypt_write(0x1000, image_len)) {
|
||||
ESP_LOGE(TAG, "encrypt 2nd boot error");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "2nd boot len error");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* encrypt partition table */
|
||||
if (false == flash_encrypt_write(ESP_PARTITION_TABLE_ADDR, SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt partition table error");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* encrypt write factory bin */
|
||||
if(bs->factory.offset != 0 && bs->factory.size != 0) {
|
||||
ESP_LOGD(TAG, "have factory bin");
|
||||
if (false == flash_encrypt_write(bs->factory.offset, bs->factory.size)) {
|
||||
ESP_LOGE(TAG, "encrypt factory bin error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt write test bin */
|
||||
if(bs->test.offset != 0 && bs->test.size != 0) {
|
||||
ESP_LOGD(TAG, "have test bin");
|
||||
if (false == flash_encrypt_write(bs->test.offset, bs->test.size)) {
|
||||
ESP_LOGE(TAG, "encrypt test bin error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt write ota bin */
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if(bs->ota[i].offset != 0 && bs->ota[i].size != 0) {
|
||||
ESP_LOGD(TAG, "have ota[%d] bin",i);
|
||||
if (false == flash_encrypt_write(bs->ota[i].offset, bs->ota[i].size)) {
|
||||
ESP_LOGE(TAG, "encrypt ota bin error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt write ota info bin */
|
||||
if (false == flash_encrypt_write(bs->ota_info.offset, 2*SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt ota info error");
|
||||
return false;
|
||||
}
|
||||
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, 0x04);
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
|
||||
ESP_LOGW(TAG, "burn flash_crypt_cnt");
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
|
||||
return true;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "flash already encrypted.");
|
||||
return true;
|
||||
}
|
||||
}
|
7
components/bootloader_support/Makefile.projbuild
Normal file
7
components/bootloader_support/Makefile.projbuild
Normal file
@ -0,0 +1,7 @@
|
||||
$(SECURE_BOOT_SIGNING_KEY):
|
||||
@echo "Need to generate secure boot signing key."
|
||||
@echo "One way is to run this command:"
|
||||
@echo "$(ESPSECUREPY) generate_signing_key $@"
|
||||
@echo "Keep key file safe after generating."
|
||||
@echo "(See secure boot documentation for risks & alternatives.)"
|
||||
@exit 1
|
@ -12,21 +12,31 @@ COMPONENT_SRCDIRS := src
|
||||
#
|
||||
# Secure boot signing key support
|
||||
#
|
||||
ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
|
||||
# this path is created relative to the component build directory
|
||||
SECURE_BOOT_VERIFICATION_KEY := $(abspath signature_verification_key.bin)
|
||||
|
||||
$(SECURE_BOOT_SIGNING_KEY):
|
||||
@echo "Need to generate secure boot signing key."
|
||||
@echo "One way is to run this command:"
|
||||
@echo "$(ESPSECUREPY) generate_signing_key $@"
|
||||
@echo "Keep key file safe after generating."
|
||||
@echo "(See secure boot documentation for risks & alternatives.)"
|
||||
@exit 1
|
||||
|
||||
$(SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_SIGNING_KEY)
|
||||
ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
# verification key derived from signing key.
|
||||
$(SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_SIGNING_KEY) $(SDKCONFIG_MAKEFILE)
|
||||
$(ESPSECUREPY) extract_public_key --keyfile $< $@
|
||||
else
|
||||
# find the configured public key file
|
||||
ORIG_SECURE_BOOT_VERIFICATION_KEY := $(call resolvepath,$(call dequote,$(CONFIG_SECURE_BOOT_VERIFICATION_KEY)),$(PROJECT_PATH))
|
||||
|
||||
$(ORIG_SECURE_BOOT_VERIFICATION_KEY):
|
||||
@echo "Secure boot verification public key '$@' missing."
|
||||
@echo "This can be extracted from the private signing key, see"
|
||||
@echo "docs/security/secure-boot.rst for details."
|
||||
exit 1
|
||||
|
||||
# copy it into the build dir, so the secure boot verification key has
|
||||
# a predictable file name
|
||||
$(SECURE_BOOT_VERIFICATION_KEY): $(ORIG_SECURE_BOOT_VERIFICATION_KEY) $(SDKCONFIG_MAKEFILE)
|
||||
$(summary) CP $< $@
|
||||
cp $< $@
|
||||
endif
|
||||
|
||||
COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY)
|
||||
|
||||
|
56
components/bootloader_support/include/esp_efuse.h
Normal file
56
components/bootloader_support/include/esp_efuse.h
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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_EFUSE_H
|
||||
#define _ESP_EFUSE_H
|
||||
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* @brief Permanently update values written to the efuse write registers
|
||||
*
|
||||
* After updating EFUSE_BLKx_WDATAx_REG registers with new values to
|
||||
* write, call this function to permanently write them to efuse.
|
||||
*
|
||||
* @note Setting bits in efuse is permanent, they cannot be unset.
|
||||
*
|
||||
* @note Due to this restriction you don't need to copy values to
|
||||
* Efuse write registers from the matching read registers, bits which
|
||||
* are set in the read register but unset in the matching write
|
||||
* register will be unchanged when new values are burned.
|
||||
*
|
||||
* @note This function is not threadsafe, if calling code updates
|
||||
* efuse values from multiple tasks then this is caller's
|
||||
* responsibility to serialise.
|
||||
*
|
||||
* After burning new efuses, the read registers are updated to match
|
||||
* the new efuse values.
|
||||
*/
|
||||
void esp_efuse_burn_new_values(void);
|
||||
|
||||
/* @brief Reset efuse write registers
|
||||
*
|
||||
* Efuse write registers are written to zero, to negate
|
||||
* any changes that have been staged here.
|
||||
*/
|
||||
void esp_efuse_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_EFUSE_H */
|
||||
|
91
components/bootloader_support/include/esp_flash_encrypt.h
Normal file
91
components/bootloader_support/include/esp_flash_encrypt.h
Normal file
@ -0,0 +1,91 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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 __ESP32_FLASH_ENCRYPT_H
|
||||
#define __ESP32_FLASH_ENCRYPT_H
|
||||
|
||||
#include <stdbool.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.
|
||||
*/
|
||||
|
||||
/** @brief Is flash encryption currently enabled in hardware?
|
||||
*
|
||||
* Flash encryption is enabled if the FLASH_CRYPT_CNT efuse has an odd number of bits set.
|
||||
*
|
||||
* @return true if flash encryption is enabled.
|
||||
*/
|
||||
static inline 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;
|
||||
}
|
||||
|
||||
/* @brief Update on-device flash encryption
|
||||
*
|
||||
* Intended to be called as part of the bootloader process if flash
|
||||
* encryption is enabled in device menuconfig.
|
||||
*
|
||||
* If FLASH_CRYPT_CNT efuse parity is 1 (ie odd number of bits set),
|
||||
* then return ESP_OK immediately (indicating flash encryption is enabled
|
||||
* and functional).
|
||||
*
|
||||
* If FLASH_CRYPT_CNT efuse parity is 0 (ie even number of bits set),
|
||||
* assume the flash has just been written with plaintext that needs encrypting.
|
||||
*
|
||||
* The following regions of flash are encrypted in place:
|
||||
*
|
||||
* - The bootloader image, if a valid plaintext image is found.[*]
|
||||
* - The partition table, if a valid plaintext table is found.
|
||||
* - Any app partition that contains a valid plaintext app image.
|
||||
* - Any other partitions with the "encrypt" flag set. [**]
|
||||
*
|
||||
* After the re-encryption process completes, a '1' bit is added to the
|
||||
* FLASH_CRYPT_CNT value (setting the parity to 1) and the EFUSE is re-burned.
|
||||
*
|
||||
* [*] If reflashing bootloader with secure boot enabled, pre-encrypt
|
||||
* the bootloader before writing it to flash or secure boot will fail.
|
||||
*
|
||||
* [**] For this reason, if serial re-flashing a previous flashed
|
||||
* device with secure boot enabled and using FLASH_CRYPT_CNT to
|
||||
* trigger re-encryption, you must simultaneously re-flash plaintext
|
||||
* content to all partitions with the "encrypt" flag set or this
|
||||
* data will be corrupted (encrypted twice).
|
||||
*
|
||||
* @note The post-condition of this function is that all
|
||||
* partitions that should be encrypted are encrypted.
|
||||
*
|
||||
* @note Take care not to power off the device while this function
|
||||
* is running, or the partition currently being encrypted will be lost.
|
||||
*
|
||||
* @return ESP_OK if all operations succeeded, ESP_ERR_INVALID_STATE
|
||||
* if a fatal error occured during encryption of all partitions.
|
||||
*/
|
||||
esp_err_t esp_flash_encrypt_check_and_update(void);
|
||||
|
||||
|
||||
/** @brief Encrypt-in-place a block of flash sectors
|
||||
*
|
||||
* @param src_addr Source offset in flash. Should be multiple of 4096 bytes.
|
||||
* @param data_length Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.
|
||||
*
|
||||
* @return ESP_OK if all operations succeeded, ESP_ERR_FLASH_OP_FAIL
|
||||
* if SPI flash fails, ESP_ERR_FLASH_OP_TIMEOUT if flash times out.
|
||||
*/
|
||||
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
|
||||
|
||||
#endif
|
39
components/bootloader_support/include/esp_flash_partitions.h
Normal file
39
components/bootloader_support/include/esp_flash_partitions.h
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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_FLASH_PARTITIONS_H
|
||||
#define __ESP_FLASH_PARTITIONS_H
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Pre-partition table fixed flash offsets */
|
||||
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
|
||||
#define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
|
||||
#define ESP_PARTITION_TABLE_OFFSET 0x8000 /* Offset of partition table. Has matching value in partition_table Kconfig.projbuild file. */
|
||||
|
||||
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
|
||||
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
|
||||
|
||||
/* @brief Verify the partition table (does not include verifying secure boot cryptographic signature)
|
||||
*
|
||||
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
|
||||
* @param log_errors Log errors if the partition table is invalid.
|
||||
* @param num_partitions If result is ESP_OK, num_partitions is updated with total number of partitions (not including terminating entry).
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
|
||||
*/
|
||||
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
|
||||
|
||||
#endif
|
@ -77,33 +77,40 @@ typedef struct {
|
||||
/**
|
||||
* @brief Read an ESP image header from flash.
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param src_addr Address in flash to load image header. Must be 4 byte aligned.
|
||||
* @param log_errors Log error output if image header appears invalid.
|
||||
* @param[out] image_header Pointer to an esp_image_header_t struture to be filled with data. If the function fails, contents are undefined.
|
||||
*
|
||||
* @return ESP_OK if image header was loaded, ESP_ERR_IMAGE_FLASH_FAIL
|
||||
* if a SPI flash error occurs, ESP_ERR_IMAGE_INVALID if the image header
|
||||
* appears invalid.
|
||||
*/
|
||||
esp_err_t esp_image_load_header(uint32_t src_addr, esp_image_header_t *image_header);
|
||||
esp_err_t esp_image_load_header(uint32_t src_addr, bool log_errors, esp_image_header_t *image_header);
|
||||
|
||||
/**
|
||||
* @brief Read the segment header and data offset of a segment in the image.
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param index Index of the segment to load information for.
|
||||
* @param src_addr Base address in flash of the image.
|
||||
* @param[in] image_header Pointer to the flash image header, already loaded by @ref esp_image_load_header().
|
||||
* @param log_errors Log errors reading the segment header.
|
||||
* @param[out] segment_header Pointer to a segment header structure to be filled with data. If the function fails, contents are undefined.
|
||||
* @param[out] segment_data_offset Pointer to the data offset of the segment.
|
||||
*
|
||||
* @return ESP_OK if segment_header & segment_data_offset were loaded successfully, ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs, ESP_ERR_IMAGE_INVALID if the image header appears invalid, ESP_ERR_INVALID_ARG if the index is invalid.
|
||||
*/
|
||||
esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset);
|
||||
esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, bool log_errors, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return length of an image in flash. Non-cryptographically validates image integrity in the process.
|
||||
* @brief Non-cryptographically validate app image integrity. On success, length of image is provided to caller.
|
||||
*
|
||||
* If the image has a secure boot signature appended, the signature is not checked and this length is not included in the result.
|
||||
* If the image has a secure boot signature appended, the signature is not checked and this length is not included in the
|
||||
* output value.
|
||||
*
|
||||
* Image validation checks:
|
||||
* - Magic byte
|
||||
@ -111,13 +118,17 @@ esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const
|
||||
* - Total image no longer than 16MB
|
||||
* - 8 bit image checksum is valid
|
||||
*
|
||||
* If flash encryption is enabled, the image will be tranpsarently decrypted.
|
||||
*
|
||||
* @param src_addr Offset of the start of the image in flash. Must be 4 byte aligned.
|
||||
* @param allow_decrypt If true and flash encryption is enabled, the image will be transparently decrypted.
|
||||
* @param log_errors Log errors verifying the image.
|
||||
* @param[out] length Length of the image, set to a value if the image is valid. Can be null.
|
||||
*
|
||||
* @return ESP_OK if image is valid, ESP_FAIL or ESP_ERR_IMAGE_INVALID on errors.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *length);
|
||||
esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *length);
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -67,9 +67,25 @@ esp_err_t esp_secure_boot_permanently_enable(void);
|
||||
* @param src_addr Starting offset of the data in flash.
|
||||
* @param length Length of data in bytes. Signature is appended -after- length bytes.
|
||||
*
|
||||
* If flash encryption is enabled, the image will be transparently decrypted while being verified.
|
||||
*
|
||||
* @return ESP_OK if signature is valid, ESP_ERR_INVALID_STATE if
|
||||
* signature fails, ESP_FAIL for other failures (ie can't read flash).
|
||||
*/
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length);
|
||||
|
||||
/** @brief Secure boot verification block, on-flash data format. */
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint8_t signature[64];
|
||||
} esp_secure_boot_sig_block_t;
|
||||
|
||||
#define FLASH_OFFS_SECURE_BOOT_IV_DIGEST 0
|
||||
|
||||
/** @brief Secure boot IV+digest header */
|
||||
typedef struct {
|
||||
uint8_t iv[128];
|
||||
uint8_t digest[64];
|
||||
} esp_secure_boot_iv_digest_t;
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <esp_err.h>
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
|
||||
/* Provide a Flash API for bootloader_support code,
|
||||
that can be used from bootloader or app code.
|
||||
@ -56,14 +59,45 @@ void bootloader_munmap(const void *mapping);
|
||||
/**
|
||||
* @brief Read data from Flash.
|
||||
*
|
||||
* @note Both src and dest have to be 4-byte aligned.
|
||||
*
|
||||
* @note All of src, dest and size have to be 4-byte aligned.
|
||||
*
|
||||
* @param src source address of the data in Flash.
|
||||
* @param dest pointer to the destination buffer
|
||||
* @param size length of data
|
||||
* @param allow_decrypt If true and flash encryption is enabled, data on flash
|
||||
* will be decrypted transparently as part of the read.
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure,
|
||||
* ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout.
|
||||
*/
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write data to Flash.
|
||||
*
|
||||
* @note All of dest_addr, src and size have to be 4-byte aligned. If write_encrypted is set, dest_addr and size must be 32-byte aligned.
|
||||
*
|
||||
* Note: In bootloader, when write_encrypted == true, the src buffer is encrypted in place.
|
||||
*
|
||||
* @param dest_addr Destination address to write in Flash.
|
||||
* @param src Pointer to the data to write to flash
|
||||
* @param size Length of data in bytes.
|
||||
* @param write_encrypted If true, data will be written encrypted on flash.
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure,
|
||||
* ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout.
|
||||
*/
|
||||
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted);
|
||||
|
||||
/**
|
||||
* @brief Erase the Flash sector.
|
||||
*
|
||||
* @param sector Sector number, the count starts at sector 0, 4KB per sector.
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size);
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector);
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,25 @@
|
||||
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief Fill buffer with 'length' random bytes
|
||||
*
|
||||
* @param buffer Pointer to buffer
|
||||
* @param length This many bytes of random data will be copied to buffer
|
||||
*/
|
||||
void bootloader_fill_random(void *buffer, size_t length);
|
@ -46,38 +46,68 @@ void bootloader_munmap(const void *mapping)
|
||||
map = 0;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size)
|
||||
esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_decrypt)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (write_encrypted) {
|
||||
return spi_flash_write_encrypted(dest_addr, src, size);
|
||||
} else {
|
||||
return spi_flash_write(dest_addr, src, size);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
{
|
||||
return spi_flash_erase_sector(sector);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Bootloader version, uses ROM functions only */
|
||||
#include <soc/dport_reg.h>
|
||||
#include <rom/spi_flash.h>
|
||||
#include <rom/cache.h>
|
||||
|
||||
static const char *TAG = "bootloader_flash";
|
||||
|
||||
/* Use first 50 blocks in MMU for bootloader_mmap,
|
||||
50th block for bootloader_flash_read
|
||||
*/
|
||||
#define MMU_BLOCK0_VADDR 0x3f400000
|
||||
#define MMU_BLOCK50_VADDR 0x3f720000
|
||||
#define MMU_FLASH_MASK 0xffff0000
|
||||
#define MMU_BLOCK_SIZE 0x00010000
|
||||
|
||||
static bool mapped;
|
||||
|
||||
static uint32_t current_read_mapping = UINT32_MAX;
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (mapped) {
|
||||
ESP_LOGE(TAG, "tried to bootloader_mmap twice");
|
||||
return NULL; /* can't map twice */
|
||||
}
|
||||
if (size > 0x320000) {
|
||||
/* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads) */
|
||||
ESP_LOGE(TAG, "bootloader_mmap excess size %x", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t src_addr_aligned = src_addr & 0xffff0000;
|
||||
uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / 0x10000;
|
||||
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
|
||||
uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / MMU_BLOCK_SIZE;
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count );
|
||||
cache_flash_mmu_set( 0, 0, 0x3f400000, src_addr_aligned, 64, count );
|
||||
cache_flash_mmu_set( 0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count );
|
||||
Cache_Read_Enable( 0 );
|
||||
|
||||
mapped = true;
|
||||
|
||||
return (void *)(0x3f400000 + (src_addr - src_addr_aligned));
|
||||
return (void *)(MMU_BLOCK0_VADDR + (src_addr - src_addr_aligned));
|
||||
}
|
||||
|
||||
void bootloader_munmap(const void *mapping)
|
||||
@ -88,25 +118,12 @@ void bootloader_munmap(const void *mapping)
|
||||
Cache_Flush(0);
|
||||
mmu_init(0);
|
||||
mapped = false;
|
||||
current_read_mapping = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size)
|
||||
static esp_err_t spi_to_esp_err(SpiFlashOpResult r)
|
||||
{
|
||||
if(src_addr & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if((intptr_t)dest & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
SpiFlashOpResult r = SPIRead(src_addr, dest, size);
|
||||
Cache_Read_Enable(0);
|
||||
|
||||
switch(r) {
|
||||
case SPI_FLASH_RESULT_OK:
|
||||
return ESP_OK;
|
||||
@ -119,4 +136,101 @@ esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, size_t size)
|
||||
{
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
SpiFlashOpResult r = SPIRead(src_addr, dest, size);
|
||||
Cache_Read_Enable(0);
|
||||
|
||||
return spi_to_esp_err(r);
|
||||
}
|
||||
|
||||
static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest, size_t size)
|
||||
{
|
||||
uint32_t *dest_words = (uint32_t *)dest;
|
||||
|
||||
/* Use the 51st MMU mapping to read from flash in 64KB blocks.
|
||||
(MMU will transparently decrypt if encryption is enabled.)
|
||||
*/
|
||||
for (int word = 0; word < size / 4; word++) {
|
||||
uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */
|
||||
uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */
|
||||
uint32_t *map_ptr;
|
||||
if (map_at != current_read_mapping) {
|
||||
/* Move the 64KB mmu mapping window to fit map_at */
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
|
||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1);
|
||||
if (e != 0) {
|
||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||
Cache_Read_Enable(0);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
current_read_mapping = map_at;
|
||||
Cache_Read_Enable(0);
|
||||
}
|
||||
map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at));
|
||||
dest_words[word] = *map_ptr;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt)
|
||||
{
|
||||
if (src_addr & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (size & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read size 0x%x not 4-byte aligned", size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if ((intptr_t)dest & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (allow_decrypt) {
|
||||
return bootloader_flash_read_allow_decrypt(src_addr, dest, size);
|
||||
} else {
|
||||
return bootloader_flash_read_no_decrypt(src_addr, dest, size);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)
|
||||
{
|
||||
esp_err_t err;
|
||||
size_t alignment = write_encrypted ? 32 : 4;
|
||||
if ((dest_addr % alignment) != 0) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_write dest_addr 0x%x not %d-byte aligned", dest_addr, alignment);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if ((size % alignment) != 0) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_write size 0x%x not %d-byte aligned", size, alignment);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (((intptr_t)src % 4) != 0) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_write src 0x%x not 4 byte aligned", (intptr_t)src);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
err = spi_to_esp_err(SPIUnlock());
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (write_encrypted) {
|
||||
return spi_to_esp_err(SPI_Encrypt_Write(dest_addr, src, size));
|
||||
} else {
|
||||
return spi_to_esp_err(SPIWrite(dest_addr, src, size));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
{
|
||||
return spi_to_esp_err(SPIEraseSector(sector));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
53
components/bootloader_support/src/bootloader_random.c
Normal file
53
components/bootloader_support/src/bootloader_random.c
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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.
|
||||
#include "bootloader_random.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "esp_system.h"
|
||||
#endif
|
||||
|
||||
void bootloader_fill_random(void *buffer, size_t length)
|
||||
{
|
||||
uint8_t *buffer_bytes = (uint8_t *)buffer;
|
||||
uint32_t random;
|
||||
|
||||
/* TODO: enable HW RNG clock
|
||||
|
||||
Until this clock is enabled, this is not secure
|
||||
*/
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i == 0 || i % 4 == 0) { /* redundant check is for a compiler warning */
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
/* HW RNG generates 32 bits entropy per 16 APB cycles,
|
||||
in bootloader CPU clock == APB clock.
|
||||
|
||||
We are being conservative here and waiting at least
|
||||
that long, as loop shift overhead, etc will add more
|
||||
cycles.
|
||||
*/
|
||||
asm volatile("nop; nop; nop; nop;");
|
||||
asm volatile("nop; nop; nop; nop;");
|
||||
asm volatile("nop; nop; nop; nop;");
|
||||
asm volatile("nop; nop; nop; nop;");
|
||||
random = REG_READ(WDEV_RND_REG);
|
||||
#else
|
||||
random = esp_random();
|
||||
#endif
|
||||
}
|
||||
|
||||
buffer_bytes[i] = random >> ((i % 4) * 8);
|
||||
}
|
||||
}
|
47
components/bootloader_support/src/efuse.c
Normal file
47
components/bootloader_support/src/efuse.c
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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.
|
||||
#include "esp_efuse.h"
|
||||
|
||||
#define EFUSE_CONF_WRITE 0x5A5A /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
#define EFUSE_CONF_READ 0x5AA5 /* efuse_read_op_ena, release force */
|
||||
|
||||
#define EFUSE_CMD_PGM 0x02
|
||||
#define EFUSE_CMD_READ 0x01
|
||||
|
||||
void esp_efuse_burn_new_values(void)
|
||||
{
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_WRITE);
|
||||
REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_PGM);
|
||||
while (REG_READ(EFUSE_CMD_REG) != 0) {
|
||||
}
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ);
|
||||
REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_READ);
|
||||
while (REG_READ(EFUSE_CMD_REG) != 0) {
|
||||
}
|
||||
esp_efuse_reset();
|
||||
}
|
||||
|
||||
void esp_efuse_reset(void)
|
||||
{
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ);
|
||||
const uint32_t block_start[4] = { EFUSE_BLK0_WDATA0_REG, EFUSE_BLK1_WDATA0_REG,
|
||||
EFUSE_BLK2_WDATA0_REG, EFUSE_BLK3_WDATA0_REG };
|
||||
const uint32_t block_end[4] = { EFUSE_BLK0_WDATA6_REG, EFUSE_BLK1_WDATA7_REG,
|
||||
EFUSE_BLK2_WDATA7_REG, EFUSE_BLK3_WDATA7_REG };
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (uint32_t r = block_start[i]; r <= block_end[i]; r+= 4) {
|
||||
REG_WRITE(r, 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,26 +22,30 @@ static const char *TAG = "esp_image";
|
||||
#define SIXTEEN_MB 0x1000000
|
||||
#define ESP_ROM_CHECKSUM_INITIAL 0xEF
|
||||
|
||||
esp_err_t esp_image_load_header(uint32_t src_addr, esp_image_header_t *image_header)
|
||||
esp_err_t esp_image_load_header(uint32_t src_addr, bool log_errors, esp_image_header_t *image_header)
|
||||
{
|
||||
esp_err_t err;
|
||||
ESP_LOGD(TAG, "reading image header @ 0x%x", src_addr);
|
||||
|
||||
err = bootloader_flash_read(src_addr, image_header, sizeof(esp_image_header_t));
|
||||
err = bootloader_flash_read(src_addr, image_header, sizeof(esp_image_header_t), true);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
if (image_header->magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (image_header->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image_header->spi_mode);
|
||||
}
|
||||
if (image_header->spi_speed > ESP_IMAGE_SPI_SPEED_80M) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI speed %d", src_addr, image_header->spi_speed);
|
||||
}
|
||||
if (image_header->spi_size > ESP_IMAGE_FLASH_SIZE_MAX) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image_header->spi_size);
|
||||
if (log_errors) {
|
||||
if (image_header->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image_header->spi_mode);
|
||||
}
|
||||
if (image_header->spi_speed > ESP_IMAGE_SPI_SPEED_80M) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI speed %d", src_addr, image_header->spi_speed);
|
||||
}
|
||||
if (image_header->spi_size > ESP_IMAGE_FLASH_SIZE_MAX) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image_header->spi_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,23 +55,27 @@ esp_err_t esp_image_load_header(uint32_t src_addr, esp_image_header_t *image_hea
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset)
|
||||
esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, bool log_errors, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t next_addr = src_addr + sizeof(esp_image_header_t);
|
||||
|
||||
if(index >= image_header->segment_count) {
|
||||
ESP_LOGE(TAG, "index %d higher than segment count %d", index, image_header->segment_count);
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "index %d higher than segment count %d", index, image_header->segment_count);
|
||||
}
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
for(int i = 0; i <= index && err == ESP_OK; i++) {
|
||||
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
|
||||
err = bootloader_flash_read(next_addr, segment_header, sizeof(esp_image_segment_header_t));
|
||||
err = bootloader_flash_read(next_addr, segment_header, sizeof(esp_image_segment_header_t), true);
|
||||
if (err == ESP_OK) {
|
||||
if ((segment_header->data_len & 3) != 0
|
||||
|| segment_header->data_len >= SIXTEEN_MB) {
|
||||
ESP_LOGE(TAG, "invalid segment length 0x%x", segment_header->data_len);
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "invalid segment length 0x%x", segment_header->data_len);
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
next_addr += sizeof(esp_image_segment_header_t);
|
||||
@ -85,15 +93,14 @@ esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length)
|
||||
esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *p_length)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t buf[16];
|
||||
uint8_t buf[128];
|
||||
uint8_t checksum = ESP_ROM_CHECKSUM_INITIAL;
|
||||
esp_image_header_t image_header;
|
||||
esp_image_segment_header_t segment_header = { 0 };
|
||||
uint32_t segment_data_offs = 0;
|
||||
const uint8_t *segment_data;
|
||||
uint32_t end_addr;
|
||||
uint32_t length;
|
||||
|
||||
@ -101,7 +108,7 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length)
|
||||
*p_length = 0;
|
||||
}
|
||||
|
||||
err = esp_image_load_header(src_addr, &image_header);
|
||||
err = esp_image_load_header(src_addr, log_errors, &image_header);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
@ -110,34 +117,38 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length)
|
||||
|
||||
/* Checksum each segment's data */
|
||||
for (int i = 0; i < image_header.segment_count; i++) {
|
||||
err = esp_image_load_segment_header(i, src_addr, &image_header,
|
||||
err = esp_image_load_segment_header(i, src_addr, &image_header, log_errors,
|
||||
&segment_header, &segment_data_offs);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
segment_data = bootloader_mmap(segment_data_offs, segment_header.data_len);
|
||||
if (segment_data == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", segment_data_offs, segment_header.data_len);
|
||||
return ESP_FAIL;
|
||||
for (int i = 0; i < segment_header.data_len; i += sizeof(buf)) {
|
||||
err = bootloader_flash_read(segment_data_offs + i, buf, sizeof(buf), true);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
for (int j = 0; j < sizeof(buf) && i + j < segment_header.data_len; j++) {
|
||||
checksum ^= buf[j];
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < segment_header.data_len; i++) {
|
||||
checksum ^= segment_data[i];
|
||||
}
|
||||
bootloader_munmap(segment_data);
|
||||
}
|
||||
|
||||
/* End of image, verify checksum */
|
||||
end_addr = segment_data_offs + segment_header.data_len;
|
||||
|
||||
if (end_addr < src_addr) {
|
||||
ESP_LOGE(TAG, "image offset has wrapped");
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "image offset has wrapped");
|
||||
}
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
length = end_addr - src_addr;
|
||||
if (length >= SIXTEEN_MB) {
|
||||
ESP_LOGE(TAG, "invalid total length 0x%x", length);
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "invalid total length 0x%x", length);
|
||||
}
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
@ -147,10 +158,12 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, uint32_t *p_length)
|
||||
length = length - (length % 16);
|
||||
ESP_LOGV(TAG, "padded image length 0x%x", length);
|
||||
ESP_LOGD(TAG, "reading checksum block at 0x%x", src_addr + length - 16);
|
||||
bootloader_flash_read(src_addr + length - 16, buf, 16);
|
||||
bootloader_flash_read(src_addr + length - 16, buf, 16, true);
|
||||
if (checksum != buf[15]) {
|
||||
ESP_LOGE(TAG, "checksum failed. Calculated 0x%x read 0x%x",
|
||||
checksum, buf[15]);
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "checksum failed. Calculated 0x%x read 0x%x",
|
||||
checksum, buf[15]);
|
||||
}
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
|
329
components/bootloader_support/src/flash_encrypt.c
Normal file
329
components/bootloader_support/src/flash_encrypt.c
Normal file
@ -0,0 +1,329 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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.
|
||||
|
||||
#include <strings.h>
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/spi_flash.h" /* TODO: Remove this */
|
||||
|
||||
static const char *TAG = "flash_encrypt";
|
||||
|
||||
/* Static functions for stages of flash encryption */
|
||||
static esp_err_t initialise_flash_encryption(void);
|
||||
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis);
|
||||
static esp_err_t encrypt_bootloader();
|
||||
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
|
||||
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
|
||||
|
||||
esp_err_t esp_flash_encrypt_check_and_update(void)
|
||||
{
|
||||
uint32_t efuse_blk0 = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
ESP_LOGV(TAG, "efuse_blk0 raw value %08x", efuse_blk0);
|
||||
uint32_t flash_crypt_cnt = (efuse_blk0 & EFUSE_RD_FLASH_CRYPT_CNT_M) >> EFUSE_RD_FLASH_CRYPT_CNT_S;
|
||||
bool flash_crypt_wr_dis = efuse_blk0 & EFUSE_WR_DIS_FLASH_CRYPT_CNT;
|
||||
ESP_LOGV(TAG, "efuse FLASH_CRYPT_CNT 0x%x WR_DIS_FLASH_CRYPT_CNT 0x%x", flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
|
||||
if (__builtin_parity(flash_crypt_cnt) == 1) {
|
||||
/* Flash is already encrypted */
|
||||
int left = (7 - __builtin_popcount(flash_crypt_cnt)) / 2;
|
||||
if (flash_crypt_wr_dis) {
|
||||
left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
|
||||
}
|
||||
ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
|
||||
return ESP_OK;
|
||||
}
|
||||
else {
|
||||
/* Flash is not encrypted, so encrypt it! */
|
||||
return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t initialise_flash_encryption(void)
|
||||
{
|
||||
/* Before first flash encryption pass, need to initialise key & crypto config */
|
||||
|
||||
/* Generate key */
|
||||
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK1;
|
||||
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK1;
|
||||
if (efuse_key_read_protected == false
|
||||
&& efuse_key_write_protected == false
|
||||
&& REG_READ(EFUSE_BLK1_RDATA0_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA1_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA2_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA3_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA4_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA5_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA6_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA7_REG) == 0) {
|
||||
|
||||
/* On-device key generation is temporarily disabled, until
|
||||
* RNG operation during bootloader is qualified.
|
||||
* See docs/security/flash-encryption.rst for details. */
|
||||
ESP_LOGE(TAG, "On-device key generation is not yet available.");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
} else {
|
||||
|
||||
if(!(efuse_key_read_protected && efuse_key_write_protected)) {
|
||||
ESP_LOGE(TAG, "Flash encryption key has to be either unset or both read and write protected");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ESP_LOGW(TAG, "Using pre-loaded flash encryption key in EFUSE block 1");
|
||||
}
|
||||
/* CRYPT_CONFIG determines which bits of the AES block key are XORed
|
||||
with bits from the flash address, to provide the key tweak.
|
||||
|
||||
CRYPT_CONFIG == 0 is effectively AES ECB mode (NOT SUPPORTED)
|
||||
|
||||
For now this is hardcoded to XOR all 256 bits of the key.
|
||||
|
||||
If you need to override it, you can pre-burn this efuse to the
|
||||
desired value and then write-protect it, in which case this
|
||||
operation does nothing. Please note this is not recommended!
|
||||
*/
|
||||
ESP_LOGI(TAG, "Setting CRYPT_CONFIG efuse to 0xF");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA5_REG, EFUSE_FLASH_CRYPT_CONFIG_M);
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
uint32_t new_wdata6 = 0;
|
||||
#ifndef CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
ESP_LOGI(TAG, "Disable UART bootloader encryption...");
|
||||
new_wdata6 |= EFUSE_DISABLE_DL_ENCRYPT;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
|
||||
#endif
|
||||
#ifndef CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT
|
||||
ESP_LOGI(TAG, "Disable UART bootloader decryption...");
|
||||
new_wdata6 |= EFUSE_DISABLE_DL_DECRYPT;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader decryption - SECURITY COMPROMISED");
|
||||
#endif
|
||||
#ifndef CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE
|
||||
ESP_LOGI(TAG, "Disable UART bootloader MMU cache...");
|
||||
new_wdata6 |= EFUSE_DISABLE_DL_CACHE;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader MMU cache - SECURITY COMPROMISED");
|
||||
#endif
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable JTAG...");
|
||||
new_wdata6 |= EFUSE_RD_DISABLE_JTAG;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
if (new_wdata6 != 0) {
|
||||
REG_WRITE(EFUSE_BLK0_WDATA6_REG, new_wdata6);
|
||||
esp_efuse_burn_new_values();
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Encrypt all flash data that should be encrypted */
|
||||
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis)
|
||||
{
|
||||
esp_err_t err;
|
||||
esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES];
|
||||
int num_partitions;
|
||||
|
||||
/* If the last flash_crypt_cnt bit is burned or write-disabled, the
|
||||
device can't re-encrypt itself. */
|
||||
if (flash_crypt_wr_dis || flash_crypt_cnt == 0xFF) {
|
||||
ESP_LOGE(TAG, "Cannot re-encrypt data (FLASH_CRYPT_CNT 0x%02x write disabled %d", flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (flash_crypt_cnt == 0) {
|
||||
/* Very first flash of encrypted data: generate keys, etc. */
|
||||
err = initialise_flash_encryption();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = encrypt_bootloader();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = encrypt_and_load_partition_table(partition_table, &num_partitions);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Now iterate the just-loaded partition table, looking for entries to encrypt
|
||||
*/
|
||||
|
||||
/* Go through each partition and encrypt if necessary */
|
||||
for (int i = 0; i < num_partitions; i++) {
|
||||
err = encrypt_partition(i, &partition_table[i]);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "All flash regions checked for encryption pass");
|
||||
|
||||
/* Set least significant 0-bit in flash_crypt_cnt */
|
||||
int ffs_inv = __builtin_ffs((~flash_crypt_cnt) & 0xFF);
|
||||
/* ffs_inv shouldn't be zero, as zero implies flash_crypt_cnt == 0xFF */
|
||||
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, new_flash_crypt_cnt);
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
ESP_LOGI(TAG, "Flash encryption completed");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t encrypt_bootloader()
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t image_length;
|
||||
/* Check for plaintext bootloader */
|
||||
if (esp_image_basic_verify(ESP_BOOTLOADER_OFFSET, false, &image_length) == ESP_OK) {
|
||||
ESP_LOGD(TAG, "bootloader is plaintext. Encrypting...");
|
||||
err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (esp_secure_boot_enabled()) {
|
||||
/* If secure boot is enabled and bootloader was plaintext, also
|
||||
need to encrypt secure boot IV+digest.
|
||||
*/
|
||||
ESP_LOGD(TAG, "Encrypting secure bootloader IV & digest...");
|
||||
err = esp_flash_encrypt_region(FLASH_OFFS_SECURE_BOOT_IV_DIGEST,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader IV & digest in place: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG, "no valid bootloader was found");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions)
|
||||
{
|
||||
esp_err_t err;
|
||||
/* Check for plaintext partition table */
|
||||
err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read partition table data");
|
||||
return err;
|
||||
}
|
||||
if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) {
|
||||
ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
|
||||
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* Valid partition table loded */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t image_len = partition->pos.size;
|
||||
bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED);
|
||||
|
||||
if (partition->type == PART_TYPE_APP) {
|
||||
/* check if the partition holds an unencrypted app */
|
||||
if (esp_image_basic_verify(partition->pos.offset, false, &image_len) == ESP_OK) {
|
||||
if(image_len > partition->pos.size) {
|
||||
ESP_LOGE(TAG, "partition entry %d has image longer than partition (%d vs %d)", index, image_len, partition->pos.size);
|
||||
should_encrypt = false;
|
||||
} else {
|
||||
should_encrypt = true;
|
||||
}
|
||||
} else {
|
||||
should_encrypt = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!should_encrypt) {
|
||||
return ESP_OK;
|
||||
}
|
||||
else {
|
||||
/* should_encrypt */
|
||||
ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x...", index, partition->pos.offset);
|
||||
|
||||
err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt partition %d", index);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
|
||||
|
||||
if (src_addr % FLASH_SECTOR_SIZE != 0) {
|
||||
ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x",src_addr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
|
||||
uint32_t sec_start = i + src_addr;
|
||||
err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false);
|
||||
if (err != ESP_OK) {
|
||||
goto flash_failed;
|
||||
}
|
||||
err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
goto flash_failed;
|
||||
}
|
||||
err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
|
||||
if (err != ESP_OK) {
|
||||
goto flash_failed;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
|
||||
flash_failed:
|
||||
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
||||
return err;
|
||||
}
|
49
components/bootloader_support/src/flash_partitions.c
Normal file
49
components/bootloader_support/src/flash_partitions.c
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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.
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char *TAG = "flash_parts";
|
||||
|
||||
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
|
||||
{
|
||||
int num_parts;
|
||||
*num_partitions = 0;
|
||||
|
||||
for(num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) {
|
||||
const esp_partition_info_t *part = &partition_table[num_parts];
|
||||
|
||||
if(part->magic == 0xFFFF
|
||||
&& part->type == PART_TYPE_END
|
||||
&& part->subtype == PART_SUBTYPE_END) {
|
||||
/* TODO: check md5 */
|
||||
ESP_LOGD(TAG, "partition table verified, %d entries", num_parts);
|
||||
*num_partitions = num_parts;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if(part->magic != ESP_PARTITION_MAGIC) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic);
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition table has no terminating entry, not valid");
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
@ -31,15 +30,14 @@
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
#define HASH_BLOCK_SIZE 128
|
||||
#define IV_LEN HASH_BLOCK_SIZE
|
||||
#define DIGEST_LEN 64
|
||||
|
||||
/**
|
||||
* @function : secure_boot_generate
|
||||
* @description: generate boot digest (aka "abstract") & iv
|
||||
@ -47,39 +45,26 @@ static const char* TAG = "secure_boot";
|
||||
* @inputs: image_len - length of image to calculate digest for
|
||||
*/
|
||||
static bool secure_boot_generate(uint32_t image_len){
|
||||
SpiFlashOpResult spiRet;
|
||||
/* buffer is uint32_t not uint8_t to meet ROM SPI API signature */
|
||||
uint32_t buf[IV_LEN / sizeof(uint32_t)];
|
||||
const void *image;
|
||||
esp_err_t err;
|
||||
esp_secure_boot_iv_digest_t digest;
|
||||
const uint32_t *image;
|
||||
|
||||
/* hardware secure boot engine only takes full blocks, so round up the
|
||||
image length. The additional data should all be 0xFF.
|
||||
*/
|
||||
if (image_len % HASH_BLOCK_SIZE != 0) {
|
||||
image_len = (image_len / HASH_BLOCK_SIZE + 1) * HASH_BLOCK_SIZE;
|
||||
if (image_len % sizeof(digest.iv) != 0) {
|
||||
image_len = (image_len / sizeof(digest.iv) + 1) * sizeof(digest.iv);
|
||||
}
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv(buf);
|
||||
ets_secure_boot_rd_iv((uint32_t *)digest.iv);
|
||||
ets_secure_boot_hash(NULL);
|
||||
Cache_Read_Disable(0);
|
||||
/* iv stored in sec 0 */
|
||||
spiRet = SPIEraseSector(0);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
err = bootloader_flash_erase_sector(0);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "SPI erase failed %d", spiRet);
|
||||
ESP_LOGE(TAG, "SPI erase failed: 0x%x", err);
|
||||
return false;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
|
||||
/* write iv to flash, 0x0000, 128 bytes (1024 bits) */
|
||||
ESP_LOGD(TAG, "write iv to flash.");
|
||||
spiRet = SPIWrite(0, buf, IV_LEN);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "SPI write failed %d", spiRet);
|
||||
return false;
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
|
||||
/* generate digest from image contents */
|
||||
image = bootloader_mmap(0x1000, image_len);
|
||||
@ -87,22 +72,22 @@ static bool secure_boot_generate(uint32_t image_len){
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%x) failed", image_len);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < image_len; i+= HASH_BLOCK_SIZE) {
|
||||
ets_secure_boot_hash(image + i/sizeof(void *));
|
||||
for (int i = 0; i < image_len; i+= sizeof(digest.iv)) {
|
||||
ets_secure_boot_hash(&image[i/sizeof(uint32_t)]);
|
||||
}
|
||||
bootloader_munmap(image);
|
||||
|
||||
ets_secure_boot_obtain();
|
||||
ets_secure_boot_rd_abstract(buf);
|
||||
ets_secure_boot_rd_abstract((uint32_t *)digest.digest);
|
||||
ets_secure_boot_finish();
|
||||
|
||||
ESP_LOGD(TAG, "write digest to flash.");
|
||||
spiRet = SPIWrite(0x80, buf, DIGEST_LEN);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
ESP_LOGE(TAG, "SPI write failed %d", spiRet);
|
||||
ESP_LOGD(TAG, "write iv+digest to flash");
|
||||
err = bootloader_flash_write(FLASH_OFFS_SECURE_BOOT_IV_DIGEST, &digest,
|
||||
sizeof(digest), esp_flash_encryption_enabled());
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "SPI write failed: 0x%x", err);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "write digest to flash.");
|
||||
Cache_Read_Enable(0);
|
||||
return true;
|
||||
}
|
||||
@ -111,14 +96,9 @@ static bool secure_boot_generate(uint32_t image_len){
|
||||
static inline void burn_efuses()
|
||||
{
|
||||
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
ESP_LOGE(TAG, "SECURE BOOT TEST MODE. Not really burning any efuses!");
|
||||
ESP_LOGE(TAG, "SECURE BOOT TEST MODE. Not really burning any efuses! NOT SECURE");
|
||||
#else
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
|
||||
esp_efuse_burn_new_values();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -131,7 +111,7 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
err = esp_image_basic_verify(0x1000, &image_len);
|
||||
err = esp_image_basic_verify(0x1000, true, &image_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err);
|
||||
return err;
|
||||
@ -150,25 +130,12 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
&& REG_READ(EFUSE_BLK2_RDATA5_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA6_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA7_REG) == 0) {
|
||||
ESP_LOGI(TAG, "Generating new secure boot key...");
|
||||
/* reuse the secure boot IV generation function to generate
|
||||
the key, as this generator uses the hardware RNG. */
|
||||
uint32_t buf[32];
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv(buf);
|
||||
ets_secure_boot_finish();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
burn_efuses();
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2);
|
||||
burn_efuses();
|
||||
efuse_key_read_protected = true;
|
||||
efuse_key_write_protected = true;
|
||||
|
||||
/* On-device key generation is temporarily disabled, until
|
||||
* RNG operation during bootloader is qualified.
|
||||
* See docs/security/secure-boot.rst for details. */
|
||||
ESP_LOGE(TAG, "On-device key generation is not yet available.");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Using pre-loaded secure boot key in EFUSE block 2");
|
||||
}
|
||||
@ -180,6 +147,7 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
}
|
||||
ESP_LOGI(TAG, "Digest generation complete.");
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
if (!efuse_key_read_protected) {
|
||||
ESP_LOGE(TAG, "Pre-loaded key is not read protected. Refusing to blow secure boot efuse.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
@ -188,21 +156,26 @@ esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
ESP_LOGE(TAG, "Pre-loaded key is not write protected. Refusing to blow secure boot efuse.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "blowing secure boot efuse...");
|
||||
ESP_LOGD(TAG, "before updating, EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG));
|
||||
|
||||
uint32_t new_wdata6 = EFUSE_RD_ABS_DONE_0;
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_DISABLE_JTAG
|
||||
ESP_LOGI(TAG, "disabling JTAG...");
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable JTAG...");
|
||||
new_wdata6 |= EFUSE_RD_DISABLE_JTAG;
|
||||
#endif
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_DISABLE_UART_BOOTLOADER
|
||||
ESP_LOGI(TAG, "disabling UART bootloader...");
|
||||
new_wdata6 |= EFUSE_RD_CONSOLE_DEBUG_DISABLE_S;
|
||||
#endif
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC
|
||||
ESP_LOGI(TAG, "Disable ROM BASIC interpreter fallback...");
|
||||
new_wdata6 |= EFUSE_RD_CONSOLE_DEBUG_DISABLE;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling ROM BASIC fallback - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
REG_WRITE(EFUSE_BLK0_WDATA6_REG, new_wdata6);
|
||||
burn_efuses();
|
||||
|
@ -27,11 +27,6 @@ typedef SHA_CTX sha_context;
|
||||
#include "hwcrypto/sha.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint8_t signature[64];
|
||||
} signature_block_t;
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start");
|
||||
@ -47,7 +42,7 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
uint8_t digest[32];
|
||||
ptrdiff_t keylen;
|
||||
const uint8_t *data;
|
||||
const signature_block_t *sigblock;
|
||||
const esp_secure_boot_sig_block_t *sigblock;
|
||||
bool is_valid;
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
const uint8_t *digest_data;
|
||||
@ -56,13 +51,13 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
|
||||
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
|
||||
|
||||
data = bootloader_mmap(src_addr, length + sizeof(signature_block_t));
|
||||
data = bootloader_mmap(src_addr, length + sizeof(esp_secure_boot_sig_block_t));
|
||||
if(data == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(signature_block_t));
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(esp_secure_boot_sig_block_t));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
sigblock = (const signature_block_t *)(data + length);
|
||||
sigblock = (const esp_secure_boot_sig_block_t *)(data + length);
|
||||
|
||||
if (sigblock->version != 0) {
|
||||
ESP_LOGE(TAG, "src 0x%x has invalid signature version field 0x%08x", src_addr, sigblock->version);
|
||||
|
@ -10,10 +10,16 @@ config BT_ENABLED
|
||||
|
||||
config BTC_TASK_STACK_SIZE
|
||||
int "BT event (callback to application) task stack size"
|
||||
default 2048
|
||||
default 3072
|
||||
help
|
||||
This select btc task stack size
|
||||
|
||||
config BLUEDROID_MEM_DEBUG
|
||||
bool "Bluedroid memory debug"
|
||||
default no
|
||||
help
|
||||
Bluedroid memory debug
|
||||
|
||||
#config BT_BTLE
|
||||
# bool "Enable BTLE"
|
||||
# depends on BT_ENABLED
|
||||
|
@ -84,7 +84,6 @@ esp_err_t esp_ble_gap_start_scanning(uint32_t duration)
|
||||
esp_err_t esp_ble_gap_stop_scanning(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
|
@ -340,7 +340,7 @@ esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gatt_if,
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_REG_FOR_NOTIFY;
|
||||
arg.reg_for_notify.gatt_if = gatt_if;
|
||||
memcpy(&arg.reg_for_notify.remote_bda, &server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(arg.reg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(&arg.reg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.reg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
|
||||
@ -359,7 +359,7 @@ esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gatt_if,
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_UNREG_FOR_NOTIFY;
|
||||
arg.unreg_for_notify.gatt_if = gatt_if;
|
||||
memcpy(&arg.unreg_for_notify.remote_bda, &server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(arg.unreg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(&arg.unreg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.unreg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
|
||||
|
@ -15,12 +15,14 @@
|
||||
#ifndef __ESP_BLUFI_API_H__
|
||||
#define __ESP_BLUFI_API_H__
|
||||
|
||||
#include "bt_types.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_BLUFI_RECV_DATA_LEN_MAX (64+1)
|
||||
|
||||
#define ESP_BLUFI_EVENT_INIT_FINISH 0
|
||||
@ -112,6 +114,8 @@ esp_err_t esp_blufi_profile_init(void);
|
||||
*/
|
||||
esp_err_t esp_blufi_profile_deinit(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLUFI_API_ */
|
||||
|
@ -18,6 +18,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Status Return Value
|
||||
typedef enum {
|
||||
ESP_BT_STATUS_SUCCESS = 0, /* Successful operation. */
|
||||
@ -99,4 +103,8 @@ typedef enum {
|
||||
*/
|
||||
typedef void (* esp_profile_cb_t)(uint32_t event, void *param);
|
||||
|
||||
#endif ///__ESP_BT_DEFS_H__
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_DEFS_H__ */
|
||||
|
@ -15,9 +15,12 @@
|
||||
#ifndef __ESP_BT_MAIN_H__
|
||||
#define __ESP_BT_MAIN_H__
|
||||
|
||||
#include "btc_main.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable bluetooth, must after esp_init_bluetooth()
|
||||
*
|
||||
@ -54,5 +57,8 @@ esp_err_t esp_init_bluetooth(void);
|
||||
*/
|
||||
esp_err_t esp_deinit_bluetooth(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_MAIN_H__ */
|
||||
|
@ -21,6 +21,10 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GAP BLE callback event type
|
||||
typedef enum {
|
||||
ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT = 0, /*!< When advertising data set complete, the event comes */
|
||||
@ -421,4 +425,8 @@ esp_err_t esp_ble_gap_set_device_name(const char *name);
|
||||
*/
|
||||
uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GAP_BLE_API_H__ */
|
||||
|
@ -17,6 +17,107 @@
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GATT INVALID UUID
|
||||
#define ESP_GATT_ILLEGAL_UUID 0
|
||||
|
||||
/**@{
|
||||
* All "ESP_GATT_UUID_xxx" is attribute types
|
||||
*/
|
||||
#define ESP_GATT_UUID_PRI_SERVICE 0x2800
|
||||
#define ESP_GATT_UUID_SEC_SERVICE 0x2801
|
||||
#define ESP_GATT_UUID_INCLUDE_SERVICE 0x2802
|
||||
#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/
|
||||
|
||||
#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */
|
||||
#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/
|
||||
#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
|
||||
#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */
|
||||
#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/
|
||||
#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/
|
||||
#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */
|
||||
#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907
|
||||
#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908
|
||||
|
||||
/* GAP Profile Attributes */
|
||||
#define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00
|
||||
#define ESP_GATT_UUID_GAP_ICON 0x2A01
|
||||
#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04
|
||||
#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6
|
||||
|
||||
/* Attribute Profile Attribute UUID */
|
||||
#define ESP_GATT_UUID_GATT_SRV_CHGD 0x2A05
|
||||
|
||||
/* Link ESP_Loss Service */
|
||||
#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */
|
||||
#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */
|
||||
|
||||
/* Current Time Service */
|
||||
#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */
|
||||
#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */
|
||||
#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */
|
||||
|
||||
/* Network availability Profile */
|
||||
#define ESP_GATT_UUID_NW_STATUS 0x2A18 /* network availability status */
|
||||
#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */
|
||||
|
||||
/* Phone alert */
|
||||
#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */
|
||||
#define ESP_GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */
|
||||
#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */
|
||||
|
||||
/* Glucose Service */
|
||||
#define ESP_GATT_UUID_GM_MEASUREMENT 0x2A18
|
||||
#define ESP_GATT_UUID_GM_CONTEXT 0x2A34
|
||||
#define ESP_GATT_UUID_GM_CONTROL_POINT 0x2A52
|
||||
#define ESP_GATT_UUID_GM_FEATURE 0x2A51
|
||||
|
||||
/* device information characteristic */
|
||||
#define ESP_GATT_UUID_SYSTEM_ID 0x2A23
|
||||
#define ESP_GATT_UUID_MODEL_NUMBER_STR 0x2A24
|
||||
#define ESP_GATT_UUID_SERIAL_NUMBER_STR 0x2A25
|
||||
#define ESP_GATT_UUID_FW_VERSION_STR 0x2A26
|
||||
#define ESP_GATT_UUID_HW_VERSION_STR 0x2A27
|
||||
#define ESP_GATT_UUID_SW_VERSION_STR 0x2A28
|
||||
#define ESP_GATT_UUID_MANU_NAME 0x2A29
|
||||
#define ESP_GATT_UUID_IEEE_DATA 0x2A2A
|
||||
#define ESP_GATT_UUID_PNP_ID 0x2A50
|
||||
|
||||
/* HID characteristics */
|
||||
#define ESP_GATT_UUID_HID_INFORMATION 0x2A4A
|
||||
#define ESP_GATT_UUID_HID_REPORT_MAP 0x2A4B
|
||||
#define ESP_GATT_UUID_HID_CONTROL_POINT 0x2A4C
|
||||
#define ESP_GATT_UUID_HID_REPORT 0x2A4D
|
||||
#define ESP_GATT_UUID_HID_PROTO_MODE 0x2A4E
|
||||
#define ESP_GATT_UUID_HID_BT_KB_INPUT 0x2A22
|
||||
#define ESP_GATT_UUID_HID_BT_KB_OUTPUT 0x2A32
|
||||
#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33
|
||||
|
||||
/* Battery Service characteristics */
|
||||
#define ESP_GATT_UUID_BATTERY_LEVEL 0x2A19
|
||||
|
||||
/* Sensor Service */
|
||||
#define ESP_GATT_UUID_SC_CONTROL_POINT 0x2A55
|
||||
#define ESP_GATT_UUID_SENSOR_LOCATION 0x2A5D
|
||||
|
||||
/* Runners speed and cadence service */
|
||||
#define ESP_GATT_UUID_RSC_MEASUREMENT 0x2A53
|
||||
#define ESP_GATT_UUID_RSC_FEATURE 0x2A54
|
||||
|
||||
/* Cycling speed and cadence service */
|
||||
#define ESP_GATT_UUID_CSC_MEASUREMENT 0x2A5B
|
||||
#define ESP_GATT_UUID_CSC_FEATURE 0x2A5C
|
||||
|
||||
/* Scan ESP_Parameter characteristics */
|
||||
#define ESP_GATT_UUID_SCAN_INT_WINDOW 0x2A4F
|
||||
#define ESP_GATT_UUID_SCAN_REFRESH 0x2A31
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/// Attribute write data type from the client
|
||||
typedef enum {
|
||||
ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */
|
||||
@ -109,15 +210,11 @@ typedef struct {
|
||||
* @brief Gatt authentication request type
|
||||
*/
|
||||
typedef enum {
|
||||
AUTH_REQ_NO_SCATTERNET, /* Device doesn't support scatternet, it might
|
||||
support "role switch during connection" for
|
||||
an incoming connection, when it already has
|
||||
another connection in master role */
|
||||
AUTH_REQ_PARTIAL_SCATTERNET, /* Device supports partial scatternet. It can have
|
||||
simulateous connection in Master and Slave roles
|
||||
for short period of time */
|
||||
AUTH_REQ_FULL_SCATTERNET /* Device can have simultaneous connection in master
|
||||
and slave roles */
|
||||
ESP_GATT_AUTH_REQ_NONE = 0,
|
||||
ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */
|
||||
ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */
|
||||
ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3,
|
||||
ESP_GATT_AUTH_REQ_SIGNED_MITM = 4,
|
||||
} esp_gatt_auth_req_t;
|
||||
|
||||
/**
|
||||
@ -174,4 +271,8 @@ typedef enum {
|
||||
|
||||
typedef uint32_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATT_DEFS_H__ */
|
||||
|
8
components/bt/bluedroid/api/include/esp_gattc_api.h
Executable file → Normal file
8
components/bt/bluedroid/api/include/esp_gattc_api.h
Executable file → Normal file
@ -15,11 +15,14 @@
|
||||
#ifndef __ESP_GATTC_API_H__
|
||||
#define __ESP_GATTC_API_H__
|
||||
|
||||
#include "bt_types.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GATT Client callback function events
|
||||
typedef enum {
|
||||
ESP_GATTC_REG_EVT = 0, /*!< When GATT client is registered, the event comes */
|
||||
@ -572,5 +575,8 @@ esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gatt_if,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATTC_API_H__ */
|
||||
|
@ -15,12 +15,14 @@
|
||||
#ifndef __ESP_GATTS_API_H__
|
||||
#define __ESP_GATTS_API_H__
|
||||
|
||||
#include "bt_types.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GATT Server callback function events
|
||||
typedef enum {
|
||||
ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */
|
||||
@ -458,5 +460,8 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatt_if, esp_bd_addr_t remote_bda, bo
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_close(uint16_t conn_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATTS_API_H__ */
|
||||
|
@ -2058,7 +2058,7 @@ void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data)
|
||||
BT_HDR *p_buf;
|
||||
UINT8 policy = HCI_ENABLE_SNIFF_MODE;
|
||||
|
||||
APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %x",
|
||||
APPL_TRACE_ERROR("bta_av_str_stopped:audio_open_cnt=%d, p_data %p",
|
||||
bta_av_cb.audio_open_cnt, p_data);
|
||||
|
||||
bta_sys_idle(BTA_ID_AV, bta_av_cb.audio_open_cnt, p_scb->peer_addr);
|
||||
|
@ -62,18 +62,6 @@ static BOOLEAN bta_dm_check_av(UINT16 event);
|
||||
static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data);
|
||||
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
static void bta_dm_acl_change_cback(BD_ADDR p_bda, DEV_CLASS p_dc,
|
||||
BD_NAME p_bdn, UINT8 *features,
|
||||
BOOLEAN is_new, UINT16 handle,
|
||||
tBT_TRANSPORT transport);
|
||||
#else
|
||||
static void bta_dm_acl_change_cback(BD_ADDR p_bda, DEV_CLASS p_dc,
|
||||
BD_NAME p_bdn, UINT8 *features,
|
||||
BOOLEAN is_new);
|
||||
#endif
|
||||
|
||||
|
||||
static void bta_dm_policy_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
|
||||
/* Extended Inquiry Response */
|
||||
@ -443,6 +431,10 @@ void bta_dm_disable (tBTA_DM_MSG *p_data)
|
||||
bta_sys_start_timer(&bta_dm_cb.disable_timer, 0, 5000);
|
||||
}
|
||||
|
||||
#if BLE_PRIVACY_SPT == TRUE
|
||||
btm_ble_resolving_list_cleanup (); //by TH, because cmn_ble_vsc_cb.max_filter has something mistake as btm_ble_adv_filter_cleanup
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -1647,7 +1639,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
|
||||
if ( bta_dm_search_cb.p_sdp_db != NULL && bta_dm_search_cb.p_sdp_db->raw_used != 0 &&
|
||||
bta_dm_search_cb.p_sdp_db->raw_data != NULL) {
|
||||
APPL_TRACE_DEBUG(
|
||||
"%s raw_data used = 0x%x raw_data_ptr = 0x%x", __func__,
|
||||
"%s raw_data used = 0x%x raw_data_ptr = %p", __func__,
|
||||
bta_dm_search_cb.p_sdp_db->raw_used,
|
||||
bta_dm_search_cb.p_sdp_db->raw_data);
|
||||
|
||||
@ -1991,7 +1983,6 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
|
||||
{
|
||||
|
||||
tSDP_UUID uuid;
|
||||
UINT16 num_attrs = 1;
|
||||
tBTA_DM_MSG *p_msg;
|
||||
|
||||
memset (&uuid, 0, sizeof(tSDP_UUID));
|
||||
@ -2169,7 +2160,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
|
||||
|
||||
bdcpy(bta_dm_search_cb.peer_bdaddr, remote_bd_addr);
|
||||
|
||||
APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info 0x%x state = %d, transport=%d",
|
||||
APPL_TRACE_DEBUG("%s name_discover_done = %d p_btm_inq_info %p state = %d, transport=%d",
|
||||
__func__,
|
||||
bta_dm_search_cb.name_discover_done,
|
||||
bta_dm_search_cb.p_btm_inq_info,
|
||||
@ -2231,7 +2222,7 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
|
||||
|
||||
#if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
|
||||
if ( bta_dm_search_cb.p_btm_inq_info ) {
|
||||
APPL_TRACE_DEBUG("%s p_btm_inq_info 0x%x results.device_type 0x%x services_to_search 0x%x",
|
||||
APPL_TRACE_DEBUG("%s p_btm_inq_info %p results.device_type 0x%x services_to_search 0x%x",
|
||||
__func__,
|
||||
bta_dm_search_cb.p_btm_inq_info,
|
||||
bta_dm_search_cb.p_btm_inq_info->results.device_type,
|
||||
@ -2956,48 +2947,6 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_acl_change_cback
|
||||
**
|
||||
** Description Callback from btm when acl connection goes up or down
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if BLE_INCLUDED == TRUE
|
||||
static void bta_dm_acl_change_cback(BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn,
|
||||
UINT8 *features, BOOLEAN is_new, UINT16 handle,
|
||||
tBT_TRANSPORT transport)
|
||||
#else
|
||||
static void bta_dm_acl_change_cback(BD_ADDR p_bda, DEV_CLASS p_dc, BD_NAME p_bdn,
|
||||
UINT8 *features, BOOLEAN is_new)
|
||||
#endif
|
||||
{
|
||||
tBTA_DM_ACL_CHANGE *p_msg = (tBTA_DM_ACL_CHANGE *) GKI_getbuf(sizeof(tBTA_DM_ACL_CHANGE));
|
||||
if (p_msg != NULL) {
|
||||
memset(p_msg, 0, sizeof(tBTA_DM_ACL_CHANGE));
|
||||
|
||||
bdcpy(p_msg->bd_addr, p_bda);
|
||||
p_msg->is_new = is_new;
|
||||
#if BLE_INCLUDED == TRUE
|
||||
p_msg->handle = handle;
|
||||
p_msg->transport = transport;
|
||||
#endif
|
||||
/* This is collision case */
|
||||
if (features != NULL) {
|
||||
if ((features[0] == 0xFF) && !is_new) {
|
||||
p_msg->event = BTM_BL_COLLISION_EVT;
|
||||
}
|
||||
}
|
||||
|
||||
p_msg->hdr.event = BTA_DM_ACL_CHANGE_EVT;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_rs_cback
|
||||
@ -4018,7 +3967,7 @@ void bta_dm_encrypt_cback(BD_ADDR bd_addr, tBT_TRANSPORT transport, void *p_ref_
|
||||
break;
|
||||
}
|
||||
|
||||
APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=0x%x", bta_status, p_callback);
|
||||
APPL_TRACE_DEBUG("bta_dm_encrypt_cback status =%d p_callback=%p", bta_status, p_callback);
|
||||
|
||||
if (p_callback) {
|
||||
(*p_callback)(bd_addr, transport, bta_status);
|
||||
@ -4150,8 +4099,6 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
|
||||
tBTM_STATUS status = BTM_SUCCESS;
|
||||
tBTA_DM_SEC sec_event;
|
||||
char *p_name = NULL;
|
||||
UINT8 i;
|
||||
tBT_DEVICE_TYPE dev_type;
|
||||
|
||||
if (!bta_dm_cb.p_sec_cback) {
|
||||
return BTM_NOT_AUTHORIZED;
|
||||
@ -5255,7 +5202,7 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
|
||||
|
||||
|
||||
if ( bta_dm_search_cb.ble_raw_used + sizeof(tBTA_GATT_ID) < bta_dm_search_cb.ble_raw_size ) {
|
||||
APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = 0x%x, ble_raw_used = 0x%x",
|
||||
APPL_TRACE_DEBUG("ADDING BLE SERVICE uuid=0x%x, ble_ptr = %p, ble_raw_used = 0x%x",
|
||||
service_id.uuid.uu.uuid16, bta_dm_search_cb.p_ble_rawdata, bta_dm_search_cb.ble_raw_used);
|
||||
|
||||
if (bta_dm_search_cb.p_ble_rawdata) {
|
||||
|
@ -2168,12 +2168,16 @@ void BTA_VendorCleanup (void)
|
||||
BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);
|
||||
|
||||
#if (BLE_INCLUDED == TRUE && BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE)
|
||||
btm_ble_adv_filter_cleanup(); // when BLE_VND_INCLUDED is false, this function will be ignore, so move it out of "if"
|
||||
|
||||
#if 0 //by TH, comment out temporarily
|
||||
if (cmn_ble_vsc_cb.max_filter > 0) {
|
||||
btm_ble_adv_filter_cleanup();
|
||||
#if BLE_PRIVACY_SPT == TRUE
|
||||
btm_ble_resolving_list_cleanup ();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cmn_ble_vsc_cb.tot_scan_results_strg > 0) {
|
||||
btm_ble_batchscan_cleanup();
|
||||
|
@ -337,7 +337,6 @@ static void bta_dm_pm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id,
|
||||
{
|
||||
|
||||
UINT8 i, j;
|
||||
UINT16 policy_setting;
|
||||
UINT8 *p = NULL;
|
||||
tBTA_DM_PEER_DEVICE *p_dev;
|
||||
|
||||
|
@ -298,7 +298,6 @@ static void bta_create_ops_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_RE
|
||||
|
||||
static void bta_create_sap_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
@ -598,6 +598,8 @@ void bta_alarm_cb(void *data)
|
||||
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
|
||||
|
||||
fixed_queue_enqueue(btu_bta_alarm_queue, p_tle);
|
||||
|
||||
btu_task_post(SIG_BTU_WORK);
|
||||
}
|
||||
|
||||
void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)
|
||||
|
@ -39,14 +39,18 @@ static void btc_sec_callback(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data)
|
||||
}
|
||||
}
|
||||
|
||||
static bt_status_t btc_enable_bluetooth(void)
|
||||
static void btc_enable_bluetooth(void)
|
||||
{
|
||||
BTA_EnableBluetooth(btc_sec_callback);
|
||||
if (BTA_EnableBluetooth(btc_sec_callback) != BTA_SUCCESS) {
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE), FUTURE_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static bt_status_t btc_disable_bluetooth(void)
|
||||
static void btc_disable_bluetooth(void)
|
||||
{
|
||||
BTA_DisableBluetooth();
|
||||
if (BTA_DisableBluetooth() != BTA_SUCCESS) {
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE), FUTURE_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
void btc_init_callback(void)
|
||||
@ -54,7 +58,7 @@ void btc_init_callback(void)
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_INIT_FUTURE), FUTURE_SUCCESS);
|
||||
}
|
||||
|
||||
static bt_status_t btc_init_bluetooth(void)
|
||||
static void btc_init_bluetooth(void)
|
||||
{
|
||||
bte_main_boot_entry(btc_init_callback);
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ static void btc_task(void *arg)
|
||||
|
||||
for (;;) {
|
||||
if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
|
||||
LOG_DEBUG("%s msg %u %u %u %08x\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
|
||||
LOG_DEBUG("%s msg %u %u %u %p\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
|
||||
switch (msg.sig) {
|
||||
case BTC_SIG_API_CALL:
|
||||
profile_tab[msg.pid].btc_call(&msg);
|
||||
|
@ -34,8 +34,8 @@
|
||||
#include "blufi_adv.h"
|
||||
#include "blufi_int.h"
|
||||
|
||||
static uint8_t *success_msg = "BLUFI_CONFIG_OK";
|
||||
static uint8_t *failed_msg = "BLUFI_CONFIG_FAILED";
|
||||
const char success_msg[] = "BLUFI_CONFIG_OK";
|
||||
const char failed_msg[] = "BLUFI_CONFIG_FAILED";
|
||||
|
||||
#define BTC_BLUFI_CB_TO_APP(_event, _param) ((esp_profile_cb_t)btc_profile_cb_get(BTC_PID_BLUFI))(_event, _param)
|
||||
|
||||
@ -145,7 +145,6 @@ static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
{
|
||||
tBTA_GATTS_RSP rsp;
|
||||
tBT_UUID uuid = {LEN_UUID_16, {SVC_BLUFI_UUID}};
|
||||
UINT8 len = 0;
|
||||
UINT8 *p_rec_data = NULL;
|
||||
tBTA_GATT_STATUS status;
|
||||
|
||||
@ -323,13 +322,13 @@ static void blufi_msg_notify(UINT8 *blufi_msg, UINT8 len)
|
||||
static void btc_blufi_config_success(void)
|
||||
{
|
||||
LOG_DEBUG("config success\n");
|
||||
blufi_msg_notify(success_msg, strlen(success_msg));
|
||||
blufi_msg_notify((uint8_t *)success_msg, strlen(success_msg));
|
||||
}
|
||||
|
||||
static void btc_blufi_config_failed(void)
|
||||
{
|
||||
LOG_DEBUG("config faield\n");
|
||||
blufi_msg_notify(failed_msg, strlen(failed_msg));
|
||||
blufi_msg_notify((uint8_t *)failed_msg, strlen(failed_msg));
|
||||
}
|
||||
|
||||
void btc_blufi_cb_handler(btc_msg_t *msg)
|
||||
|
@ -287,7 +287,7 @@ static void btc_scan_rsp_data_callback(tBTA_STATUS status)
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT;
|
||||
param.adv_data_cmpl.status = status;
|
||||
param.scan_rsp_data_cmpl.status = status;
|
||||
|
||||
ret = btc_transfer_context(&msg, ¶m,
|
||||
sizeof(esp_ble_gap_cb_param_t), NULL);
|
||||
@ -297,76 +297,24 @@ static void btc_scan_rsp_data_callback(tBTA_STATUS status)
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_set_scan_param_callback(tGATT_IF client_if, 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_SCAN_PARAM_SET_COMPLETE_EVT;
|
||||
param.adv_data_cmpl.status = status;
|
||||
|
||||
ret = btc_transfer_context(&msg, ¶m,
|
||||
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_set_adv_data(esp_ble_adv_data_t *adv_data,
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK p_adv_data_cback)
|
||||
{
|
||||
tBTA_BLE_AD_MASK data_mask = 0;
|
||||
|
||||
btc_to_bta_adv_data(adv_data, &gl_bta_adv_data, &data_mask);
|
||||
|
||||
if (!adv_data->set_scan_rsp) {
|
||||
btc_to_bta_adv_data(adv_data, &gl_bta_adv_data, &data_mask);
|
||||
BTA_DmBleSetAdvConfig(data_mask, &gl_bta_adv_data, p_adv_data_cback);
|
||||
} else {
|
||||
BTA_DmBleSetScanRsp(data_mask, &gl_bta_adv_data, p_adv_data_cback);
|
||||
btc_to_bta_adv_data(adv_data, &gl_bta_scan_rsp_data, &data_mask);
|
||||
BTA_DmBleSetScanRsp(data_mask, &gl_bta_scan_rsp_data, p_adv_data_cback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void btc_ble_set_scan_param(esp_ble_scan_params_t *ble_scan_params,
|
||||
tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback)
|
||||
static void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params)
|
||||
{
|
||||
//tBTA_BLE_AD_MASK data_mask = 0;
|
||||
BTA_DmSetBleScanParams (ESP_DEFAULT_GATT_IF,
|
||||
ble_scan_params->scan_interval,
|
||||
ble_scan_params->scan_window,
|
||||
ble_scan_params->scan_type,
|
||||
scan_param_setup_cback);
|
||||
//btc_to_bta_adv_data(scan_rsp_data, &gl_bta_scan_rsp_data, &data_mask);
|
||||
//BTA_DmBleSetScanRsp(data_mask, &gl_bta_scan_rsp_data, p_scan_rsp_data_cback);
|
||||
}
|
||||
|
||||
void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params)
|
||||
{
|
||||
tBTA_DM_DISC disc_mode = 0;
|
||||
tBTA_DM_CONN conn_mode = 0;
|
||||
tBLE_BD_ADDR peer_addr;
|
||||
|
||||
if (ble_adv_params->adv_type == ADV_TYPE_NONCONN_IND) {
|
||||
conn_mode = BTA_DM_BLE_NON_CONNECTABLE;
|
||||
} else {
|
||||
conn_mode = BTA_DM_BLE_CONNECTABLE;
|
||||
}
|
||||
|
||||
if (ble_adv_params->adv_filter_policy == ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY) {
|
||||
disc_mode = BTA_DM_BLE_GENERAL_DISCOVERABLE;
|
||||
} else if (ble_adv_params->adv_filter_policy == ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY
|
||||
|| ble_adv_params->adv_filter_policy == ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST) {
|
||||
disc_mode = BTA_DM_BLE_LIMITED_DISCOVERABLE;
|
||||
} else if (ble_adv_params->adv_filter_policy == ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST) {
|
||||
disc_mode = BTA_DM_BLE_NON_DISCOVERABLE;
|
||||
}
|
||||
|
||||
if (!BLE_ISVALID_PARAM(ble_adv_params->adv_int_min, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX) ||
|
||||
!BLE_ISVALID_PARAM(ble_adv_params->adv_int_max, BTM_BLE_ADV_INT_MIN, BTM_BLE_ADV_INT_MAX)) {
|
||||
LOG_ERROR("Invalid advertisting interval parameters.\n");
|
||||
@ -386,7 +334,6 @@ void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params)
|
||||
}
|
||||
LOG_DEBUG("API_Ble_AppStartAdvertising\n");
|
||||
|
||||
///
|
||||
memcpy(peer_addr.bda, ble_adv_params->peer_addr, ESP_BD_ADDR_LEN);
|
||||
peer_addr.type = ble_adv_params->peer_addr_type;
|
||||
BTA_DmSetBleAdvParamsAll(ble_adv_params->adv_int_min,
|
||||
@ -396,9 +343,6 @@ void btc_ble_start_advertising (esp_ble_adv_params_t *ble_adv_params)
|
||||
ble_adv_params->channel_map,
|
||||
ble_adv_params->adv_filter_policy,
|
||||
&peer_addr);
|
||||
|
||||
/*set connectable,discoverable, pairable and paired only modes of local device*/
|
||||
BTA_DmSetVisibility(disc_mode, conn_mode, (UINT8)BTA_DM_NON_PAIRABLE, (UINT8)BTA_DM_CONN_ALL);
|
||||
}
|
||||
|
||||
|
||||
@ -421,20 +365,21 @@ static void btc_scan_params_callback(tGATT_IF gatt_if, tBTM_STATUS status)
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_ble_set_scan_params(esp_ble_scan_params_t *scan_params,
|
||||
tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback)
|
||||
static void btc_ble_set_scan_params(esp_ble_scan_params_t *scan_params, tBLE_SCAN_PARAM_SETUP_CBACK scan_param_setup_cback)
|
||||
{
|
||||
if (BLE_ISVALID_PARAM(scan_params->scan_interval, BTM_BLE_SCAN_INT_MIN, BTM_BLE_SCAN_INT_MAX) &&
|
||||
BLE_ISVALID_PARAM(scan_params->scan_window, BTM_BLE_SCAN_WIN_MIN, BTM_BLE_SCAN_WIN_MAX) &&
|
||||
(scan_params->scan_type == BTM_BLE_SCAN_MODE_ACTI || scan_params->scan_type == BTM_BLE_SCAN_MODE_PASS)) {
|
||||
BTA_DmSetBleScanFilterParams(0 /*client_if*/,
|
||||
BTA_DmSetBleScanFilterParams(ESP_DEFAULT_GATT_IF, /*client_if*/
|
||||
scan_params->scan_interval,
|
||||
scan_params->scan_window,
|
||||
scan_params->scan_type,
|
||||
scan_params->own_addr_type,
|
||||
scan_params->scan_filter_policy,
|
||||
scan_param_setup_cback);
|
||||
}
|
||||
} else {
|
||||
btc_scan_params_callback(ESP_DEFAULT_GATT_IF, BTM_ILLEGAL_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
|
||||
@ -647,7 +592,7 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
|
||||
break;
|
||||
}
|
||||
case BTC_GAP_BLE_ACT_SET_SCAN_PARAM:
|
||||
btc_ble_set_scan_param(&arg->set_scan_param.scan_params, btc_set_scan_param_callback);
|
||||
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);
|
||||
|
@ -59,7 +59,7 @@ int uuidType(unsigned char *p_uuid)
|
||||
return LEN_UUID_128;
|
||||
}
|
||||
|
||||
int btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src)
|
||||
void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
@ -584,7 +584,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
|
||||
case BTA_GATTC_NOTIF_EVT: {
|
||||
tBTA_GATTC_NOTIFY *notify = &arg->notify;
|
||||
param.notify.conn_id = notify->conn_id;
|
||||
memcpy(¶m.notify.remote_bda, ¬ify->bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(param.notify.remote_bda, notify->bda, sizeof(esp_bd_addr_t));
|
||||
bta_to_btc_srvc_id(¶m.notify.srvc_id, ¬ify->char_id.srvc_id);
|
||||
bta_to_btc_gatt_id(¶m.notify.char_id, ¬ify->char_id.char_id);
|
||||
bta_to_btc_gatt_id(¶m.notify.descr_id, ¬ify->descr_type);
|
||||
@ -605,7 +605,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
|
||||
param.open.status = open->status;
|
||||
param.open.conn_id = open->conn_id;
|
||||
param.open.gatt_if = open->client_if;
|
||||
memcpy(¶m.open.remote_bda, &open->remote_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(param.open.remote_bda, open->remote_bda, sizeof(esp_bd_addr_t));
|
||||
param.open.mtu = open->mtu;
|
||||
BTC_GATTC_CB_TO_APP(ESP_GATTC_OPEN_EVT, ¶m);
|
||||
break;
|
||||
@ -615,7 +615,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
|
||||
param.close.status = close->status;
|
||||
param.close.conn_id = close->conn_id;
|
||||
param.close.gatt_if = close->client_if;
|
||||
memcpy(¶m.close.remote_bda, &close->remote_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(param.close.remote_bda, close->remote_bda, sizeof(esp_bd_addr_t));
|
||||
param.close.reason = close->reason;
|
||||
BTC_GATTC_CB_TO_APP(ESP_GATTC_CLOSE_EVT, ¶m);
|
||||
break;
|
||||
@ -646,7 +646,7 @@ void btc_gattc_cb_handler(btc_msg_t *msg)
|
||||
break;
|
||||
}
|
||||
case BTA_GATTC_SRVC_CHG_EVT: {
|
||||
memcpy(¶m.srvc_chg.remote_bda, &arg->remote_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(param.srvc_chg.remote_bda, arg->remote_bda, sizeof(esp_bd_addr_t));
|
||||
BTC_GATTC_CB_TO_APP(ESP_GATTC_SRVC_CHG_EVT, ¶m);
|
||||
break;
|
||||
}
|
||||
|
@ -232,8 +232,6 @@ void btc_gatts_call_handler(btc_msg_t *msg)
|
||||
}
|
||||
case BTC_GATTS_ACT_OPEN: {
|
||||
// Ensure device is in inquiry database
|
||||
int addr_type = 0;
|
||||
int device_type = 0;
|
||||
tBTA_GATT_TRANSPORT transport = BTA_GATT_TRANSPORT_LE;
|
||||
|
||||
//TODO : implement address type and device type
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_gattc_api.h"
|
||||
|
||||
int btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src);
|
||||
void btc128_to_bta_uuid(tBT_UUID *p_dest, uint8_t *p_src);
|
||||
void btc_to_bta_uuid(tBT_UUID *p_dest, esp_bt_uuid_t *p_src);
|
||||
void btc_to_bta_gatt_id(tBTA_GATT_ID *p_dest, esp_gatt_id_t *p_src);
|
||||
void btc_to_bta_srvc_id(tBTA_GATT_SRVC_ID *p_dest, esp_gatt_srvc_id_t *p_src);
|
||||
|
@ -896,6 +896,7 @@ esp_err_t esp_a2d_register_callback(esp_profile_cb_t callback)
|
||||
{
|
||||
// TODO: need protection against race
|
||||
bt_av_sink_callback = callback;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -294,6 +294,7 @@ esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t cb)
|
||||
{
|
||||
// TODO: need protection against race
|
||||
bt_av_sink_data_callback = cb;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// TODO: need protection against race
|
||||
|
@ -70,7 +70,7 @@ static const size_t MAX_REASONABLE_REQUESTS = 10;
|
||||
static void queue_int_add(connect_node_t *p_param)
|
||||
{
|
||||
if (!connect_queue) {
|
||||
connect_queue = list_new(osi_free);
|
||||
connect_queue = list_new(osi_free_func);
|
||||
assert(connect_queue != NULL);
|
||||
}
|
||||
|
||||
|
@ -30,21 +30,21 @@ typedef struct {
|
||||
static const interop_entry_t interop_database[] = {
|
||||
// Nexus Remote (Spike)
|
||||
// Note: May affect other Asus brand devices
|
||||
{{0x08, 0x62, 0x66, 0, 0, 0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{0x38, 0x2c, 0x4a, 0xc9, 0, 0}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{0x38, 0x2c, 0x4a, 0xe6, 0, 0}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{0x54, 0xa0, 0x50, 0xd9, 0, 0}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{0xac, 0x9e, 0x17, 0, 0, 0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{0xf0, 0x79, 0x59, 0, 0, 0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0x08, 0x62, 0x66, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0x38, 0x2c, 0x4a, 0xc9, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0x38, 0x2c, 0x4a, 0xe6, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0x54, 0xa0, 0x50, 0xd9, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0xac, 0x9e, 0x17, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0xf0, 0x79, 0x59, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
|
||||
// Motorola Key Link
|
||||
{{0x1c, 0x96, 0x5a, 0, 0, 0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0x1c, 0x96, 0x5a, 0, 0, 0}}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
|
||||
// Flic smart button
|
||||
{{0x80, 0xe4, 0xda, 0x70, 0, 0}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
{{{0x80, 0xe4, 0xda, 0x70, 0, 0}}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS},
|
||||
|
||||
// BMW car kits (Harman/Becker)
|
||||
{{0x9c, 0xdf, 0x03, 0, 0, 0}, 3, INTEROP_AUTO_RETRY_PAIRING}
|
||||
{{{0x9c, 0xdf, 0x03, 0, 0, 0}}, 3, INTEROP_AUTO_RETRY_PAIRING}
|
||||
};
|
||||
|
||||
#endif /*_INTEROP_DATABASE_H_*/
|
||||
|
@ -20,15 +20,6 @@
|
||||
#include "allocator.h"
|
||||
#include "gki_int.h"
|
||||
|
||||
#define ALIGN_POOL(pl_size) ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
|
||||
#define BUFFER_HDR_SIZE (sizeof(BUFFER_HDR_T)) /* Offset past header */
|
||||
#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
|
||||
#define MAGIC_NO 0xDDBADDBA
|
||||
|
||||
#define BUF_STATUS_FREE 0
|
||||
#define BUF_STATUS_UNLINKED 1
|
||||
#define BUF_STATUS_QUEUED 2
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gki_init_free_queue
|
||||
@ -173,7 +164,7 @@ void GKI_init_q (BUFFER_Q *p_q)
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GKI_getbuf
|
||||
** Function GKI_getbuf_func
|
||||
**
|
||||
** Description Called by an application to get a free buffer which
|
||||
** is of size greater or equal to the requested size.
|
||||
@ -187,7 +178,7 @@ void GKI_init_q (BUFFER_Q *p_q)
|
||||
** Returns A pointer to the buffer, or NULL if none available
|
||||
**
|
||||
*******************************************************************************/
|
||||
void *GKI_getbuf (UINT16 size)
|
||||
void *GKI_getbuf_func(UINT16 size)
|
||||
{
|
||||
BUFFER_HDR_T *header = osi_malloc(size + BUFFER_HDR_SIZE);
|
||||
assert(header != NULL);
|
||||
@ -203,10 +194,9 @@ void *GKI_getbuf (UINT16 size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GKI_getpoolbuf
|
||||
** Function GKI_getpoolbuf_func
|
||||
**
|
||||
** Description Called by an application to get a free buffer from
|
||||
** a specific buffer pool.
|
||||
@ -219,9 +209,9 @@ void *GKI_getbuf (UINT16 size)
|
||||
** Returns A pointer to the buffer, or NULL if none available
|
||||
**
|
||||
*******************************************************************************/
|
||||
void *GKI_getpoolbuf (UINT8 pool_id)
|
||||
void *GKI_getpoolbuf_func(UINT8 pool_id)
|
||||
{
|
||||
return GKI_getbuf(gki_cb.com.pool_size[pool_id]);
|
||||
return GKI_getbuf_func(gki_cb.com.pool_size[pool_id]);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@ -240,7 +230,6 @@ void GKI_freebuf (void *p_buf)
|
||||
osi_free((BUFFER_HDR_T *)p_buf - 1);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function GKI_get_buf_size
|
||||
|
@ -21,8 +21,18 @@
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bt_types.h"
|
||||
#include "gki_common.h"
|
||||
#include "gki_int.h"
|
||||
#include "allocator.h"
|
||||
|
||||
//static const char GKI_MODULE[] = "gki_module";
|
||||
#define ALIGN_POOL(pl_size) ( (((pl_size) + 3) / sizeof(UINT32)) * sizeof(UINT32))
|
||||
#define BUFFER_HDR_SIZE (sizeof(BUFFER_HDR_T)) /* Offset past header */
|
||||
#define BUFFER_PADDING_SIZE (sizeof(BUFFER_HDR_T) + sizeof(UINT32)) /* Header + Magic Number */
|
||||
#define MAGIC_NO 0xDDBADDBA
|
||||
|
||||
#define BUF_STATUS_FREE 0
|
||||
#define BUF_STATUS_UNLINKED 1
|
||||
#define BUF_STATUS_QUEUED 2
|
||||
|
||||
/* Timer list entry callback type
|
||||
*/
|
||||
@ -62,14 +72,37 @@ typedef struct {
|
||||
|
||||
/* To get and release buffers, change owner and get size
|
||||
*/
|
||||
void GKI_freebuf (void *);
|
||||
void *GKI_getbuf (UINT16);
|
||||
void *GKI_getbuf_func(UINT16);
|
||||
void *GKI_getpoolbuf_func(UINT8);
|
||||
void GKI_freebuf(void *);
|
||||
UINT16 GKI_get_buf_size (void *);
|
||||
void *GKI_getpoolbuf (UINT8);
|
||||
UINT16 GKI_poolcount (UINT8);
|
||||
UINT16 GKI_poolfreecount (UINT8);
|
||||
UINT16 GKI_poolutilization (UINT8);
|
||||
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
|
||||
#define GKI_getbuf(_size) \
|
||||
({ \
|
||||
BUFFER_HDR_T *header = osi_malloc((_size) + BUFFER_HDR_SIZE); \
|
||||
header->status = BUF_STATUS_UNLINKED; \
|
||||
header->p_next = NULL; \
|
||||
header->Type = 0; \
|
||||
header->size = (_size); \
|
||||
(void *)(header + 1); \
|
||||
})
|
||||
|
||||
#define GKI_getpoolbuf(_pool_id) \
|
||||
({ \
|
||||
(void *)GKI_getbuf(gki_cb.com.pool_size[(_pool_id)]); \
|
||||
})
|
||||
|
||||
#else
|
||||
#define GKI_getbuf GKI_getbuf_func
|
||||
#define GKI_getpoolbuf GKI_getpoolbuf_func
|
||||
|
||||
#endif /* CONFIG_BLUEDROID_MEM_DEBUG */
|
||||
|
||||
/* User buffer queue management
|
||||
*/
|
||||
|
@ -89,11 +89,6 @@ static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks;
|
||||
static int hci_layer_init_env(void);
|
||||
static void hci_layer_deinit_env(void);
|
||||
static void hci_host_thread_handler(void *arg);
|
||||
static int hci_send_async_command(bt_vendor_opcode_t opcode, void *param);
|
||||
static void event_finish_startup(void *context);
|
||||
static void firmware_config_callback(bool success);
|
||||
static void event_postload(void);
|
||||
static void sco_config_callback(bool success);
|
||||
static void event_command_ready(fixed_queue_t *queue);
|
||||
static void event_packet_ready(fixed_queue_t *queue);
|
||||
static void restart_comamnd_waiting_response_timer(
|
||||
@ -203,7 +198,7 @@ static void hci_layer_deinit_env(void)
|
||||
command_waiting_response_t *cmd_wait_q;
|
||||
|
||||
if (hci_host_env.command_queue) {
|
||||
fixed_queue_free(hci_host_env.command_queue, osi_free);
|
||||
fixed_queue_free(hci_host_env.command_queue, allocator_calloc.free);
|
||||
}
|
||||
if (hci_host_env.packet_queue) {
|
||||
fixed_queue_free(hci_host_env.packet_queue, buffer_allocator->free);
|
||||
@ -318,24 +313,8 @@ static void transmit_downward(uint16_t type, void *data)
|
||||
hci_host_task_post();
|
||||
}
|
||||
|
||||
// Postload functions
|
||||
static void event_postload(void)
|
||||
{
|
||||
if (hci_send_async_command(BT_VND_OP_SCO_CFG, NULL) == -1) {
|
||||
// If couldn't configure sco, we won't get the sco configuration callback
|
||||
// so go pretend to do it now
|
||||
sco_config_callback(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void sco_config_callback(UNUSED_ATTR bool success)
|
||||
{
|
||||
LOG_INFO("%s postload finished.", __func__);
|
||||
}
|
||||
|
||||
// Command/packet transmitting functions
|
||||
|
||||
static void event_command_ready(fixed_queue_t *queue)
|
||||
{
|
||||
waiting_command_t *wait_entry = NULL;
|
||||
@ -423,8 +402,8 @@ static void restart_comamnd_waiting_response_timer(
|
||||
timeout = osi_alarm_time_diff(COMMAND_PENDING_TIMEOUT, timeout);
|
||||
timeout = (timeout <= COMMAND_PENDING_TIMEOUT) ? timeout : COMMAND_PENDING_TIMEOUT;
|
||||
|
||||
osi_alarm_set(cmd_wait_q->command_response_timer, timeout);
|
||||
cmd_wait_q->timer_is_set = true;
|
||||
osi_alarm_set(cmd_wait_q->command_response_timer, timeout);
|
||||
}
|
||||
|
||||
static void command_timed_out(void *context)
|
||||
@ -506,6 +485,8 @@ static bool filter_incoming_event(BT_HDR *packet)
|
||||
|
||||
return false;
|
||||
intercepted:
|
||||
restart_comamnd_waiting_response_timer(&hci_host_env.cmd_waiting_q, false);
|
||||
|
||||
/*Tell HCI Host Task to continue TX Pending commands*/
|
||||
if (hci_host_env.command_credits &&
|
||||
!fixed_queue_is_empty(hci_host_env.command_queue)) {
|
||||
@ -513,8 +494,6 @@ intercepted:
|
||||
}
|
||||
//ke_event_set(KE_EVENT_HCI_HOST_THREAD);
|
||||
|
||||
restart_comamnd_waiting_response_timer(&hci_host_env.cmd_waiting_q, false);
|
||||
|
||||
if (wait_entry) {
|
||||
// If it has a callback, it's responsible for freeing the packet
|
||||
if (event_code == HCI_COMMAND_STATUS_EVT ||
|
||||
@ -591,10 +570,6 @@ static waiting_command_t *get_waiting_command(command_opcode_t opcode)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int hci_send_async_command(bt_vendor_opcode_t opcode, void *param)
|
||||
{
|
||||
}
|
||||
|
||||
static void init_layer_interface()
|
||||
{
|
||||
if (!interface_created) {
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "hash_functions.h"
|
||||
#include "controller.h"
|
||||
#include "hci_layer.h"
|
||||
#include "bta_api.h"
|
||||
|
||||
//#include "bluedroid_test.h"
|
||||
/*
|
||||
@ -104,6 +105,7 @@ fixed_queue_t *btu_hci_msg_queue;
|
||||
|
||||
bluedroid_init_done_cb_t bluedroid_init_done_cb;
|
||||
|
||||
extern void osi_mem_dbg_init(void);
|
||||
/******************************************************************************
|
||||
**
|
||||
** Function bte_main_boot_entry
|
||||
@ -115,6 +117,10 @@ bluedroid_init_done_cb_t bluedroid_init_done_cb;
|
||||
******************************************************************************/
|
||||
int bte_main_boot_entry(bluedroid_init_done_cb_t cb)
|
||||
{
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
osi_mem_dbg_init();
|
||||
#endif
|
||||
|
||||
if (gki_init()) {
|
||||
LOG_ERROR("%s: Init GKI Module Failure.\n", __func__);
|
||||
return -1;
|
||||
@ -163,6 +169,7 @@ void bte_main_shutdown(void)
|
||||
{
|
||||
//data_dispatcher_register_default(hci_layer_get_interface()->event_dispatcher, NULL);
|
||||
hci->set_data_queue(NULL);
|
||||
fixed_queue_unregister_dequeue(btu_hci_msg_queue);
|
||||
fixed_queue_free(btu_hci_msg_queue, NULL);
|
||||
|
||||
btu_hci_msg_queue = NULL;
|
||||
@ -174,9 +181,11 @@ void bte_main_shutdown(void)
|
||||
module_clean_up(get_module(GKI_MODULE));
|
||||
*/
|
||||
|
||||
gki_clean_up();
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
BTA_VendorCleanup();
|
||||
#endif
|
||||
bte_main_disable();
|
||||
gki_clean_up();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#define RTC_TIMER_TICKS_TO_MS(ticks) ((ticks/625)<<1 + (ticks-(ticks/625)*625)/312)
|
||||
#define RTC_TIMER_TICKS_TO_MS(ticks) (((ticks/625)<<1) + (ticks-(ticks/625)*625)/312)
|
||||
|
||||
|
||||
#define BT_ALARM_START_WAIT_TICKS 100
|
||||
@ -49,7 +49,7 @@ static struct alarm_t *alarm_cbs_lookfor_available(void)
|
||||
|
||||
for (i = 0; i < ALARM_CBS_NUM; i++) {
|
||||
if (alarm_cbs[i].alarm_hdl == NULL) { //available
|
||||
LOG_DEBUG(">>>> %d %08x<<<<\n", i, &alarm_cbs[i]);
|
||||
LOG_DEBUG("%s %d %p\n", __func__, i, &alarm_cbs[i]);
|
||||
return &alarm_cbs[i];
|
||||
}
|
||||
}
|
||||
@ -62,12 +62,12 @@ static void alarm_cb_handler(TimerHandle_t xTimer)
|
||||
struct alarm_t *alarm;
|
||||
|
||||
if (!xTimer) {
|
||||
LOG_DEBUG("TimerName: NULL\n");
|
||||
LOG_ERROR("TimerName: NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
alarm = pvTimerGetTimerID(xTimer);
|
||||
LOG_DEBUG("TimerID %08x, Name %s\n", alarm, pcTimerGetTimerName(xTimer));
|
||||
LOG_DEBUG("TimerID %p, Name %s\n", alarm, pcTimerGetTimerName(xTimer));
|
||||
if (alarm->cb) {
|
||||
alarm->cb(alarm->cb_data);
|
||||
}
|
||||
|
@ -24,6 +24,97 @@
|
||||
extern void *pvPortZalloc(size_t size);
|
||||
extern void vPortFree(void *pv);
|
||||
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
|
||||
#define OSI_MEM_DBG_INFO_MAX 1024
|
||||
typedef struct {
|
||||
void *p;
|
||||
int size;
|
||||
const char *func;
|
||||
int line;
|
||||
} osi_mem_dbg_info_t;
|
||||
|
||||
static uint32_t mem_dbg_count = 0;
|
||||
static uint32_t mem_dbg_count2 = 0;
|
||||
static osi_mem_dbg_info_t mem_dbg_info[OSI_MEM_DBG_INFO_MAX];
|
||||
|
||||
void osi_mem_dbg_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
mem_dbg_info[i].p = NULL;
|
||||
mem_dbg_info[i].size = 0;
|
||||
mem_dbg_info[i].func = NULL;
|
||||
mem_dbg_info[i].line = 0;
|
||||
}
|
||||
mem_dbg_count = 0;
|
||||
mem_dbg_count2 = 0;
|
||||
}
|
||||
|
||||
void osi_mem_dbg_record(void *p, int size, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p || size == 0) {
|
||||
LOG_ERROR("%s invalid !!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
if (mem_dbg_info[i].p == NULL) {
|
||||
mem_dbg_info[i].p = p;
|
||||
mem_dbg_info[i].size = size;
|
||||
mem_dbg_info[i].func = func;
|
||||
mem_dbg_info[i].line = line;
|
||||
mem_dbg_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= OSI_MEM_DBG_INFO_MAX) {
|
||||
LOG_ERROR("%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
}
|
||||
|
||||
void osi_mem_dbg_clean(void *p, const char *func, int line)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!p) {
|
||||
LOG_ERROR("%s invalid\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
if (mem_dbg_info[i].p == p) {
|
||||
mem_dbg_info[i].p = NULL;
|
||||
mem_dbg_info[i].size = 0;
|
||||
mem_dbg_info[i].func = NULL;
|
||||
mem_dbg_info[i].line = 0;
|
||||
mem_dbg_count--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= OSI_MEM_DBG_INFO_MAX) {
|
||||
LOG_ERROR("%s full %s %d !!\n", __func__, func, line);
|
||||
}
|
||||
}
|
||||
|
||||
void osi_mem_dbg_show(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < OSI_MEM_DBG_INFO_MAX; i++) {
|
||||
if (mem_dbg_info[i].p || mem_dbg_info[i].size != 0 ) {
|
||||
LOG_ERROR("--> p %p, s %d, f %s, l %d\n", mem_dbg_info[i].p, mem_dbg_info[i].size, mem_dbg_info[i].func, mem_dbg_info[i].line);
|
||||
}
|
||||
}
|
||||
LOG_ERROR("--> count %d\n", mem_dbg_count);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *osi_strdup(const char *str)
|
||||
{
|
||||
size_t size = strlen(str) + 1; // + 1 for the null terminator
|
||||
@ -37,27 +128,46 @@ char *osi_strdup(const char *str)
|
||||
return new_string;
|
||||
}
|
||||
|
||||
void *osi_malloc(size_t size)
|
||||
void *osi_malloc_func(size_t size)
|
||||
{
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
void *p;
|
||||
|
||||
p = calloc(1, size);
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
||||
return p;
|
||||
#else
|
||||
return calloc(1, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *osi_calloc(size_t size)
|
||||
void *osi_calloc_func(size_t size)
|
||||
{
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
void *p;
|
||||
|
||||
p = calloc(1, size);
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__);
|
||||
return p;
|
||||
#else
|
||||
return calloc(1, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void osi_free(void *ptr)
|
||||
void osi_free_func(void *ptr)
|
||||
{
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
osi_mem_dbg_clean(ptr, __func__, __LINE__);
|
||||
#endif
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
const allocator_t allocator_malloc = {
|
||||
osi_malloc,
|
||||
osi_free
|
||||
osi_malloc_func,
|
||||
osi_free_func
|
||||
};
|
||||
|
||||
const allocator_t allocator_calloc = {
|
||||
osi_calloc,
|
||||
osi_free
|
||||
osi_calloc_func,
|
||||
osi_free_func
|
||||
};
|
||||
|
@ -16,22 +16,13 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
// #define LOG_TAG "bt_osi_future"
|
||||
// #include <assert.h>
|
||||
#include "bt_trace.h"
|
||||
|
||||
#include "allocator.h"
|
||||
#include "future.h"
|
||||
#include "osi.h"
|
||||
//#include "osi/include/log.h"
|
||||
#include "osi_arch.h"
|
||||
|
||||
struct future_t {
|
||||
bool ready_can_be_called;
|
||||
osi_sem_t semaphore; // NULL semaphore means immediate future
|
||||
void *result;
|
||||
};
|
||||
|
||||
static void future_free(future_t *future);
|
||||
|
||||
future_t *future_new(void)
|
||||
@ -100,7 +91,7 @@ static void future_free(future_t *future)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!future->semaphore) {
|
||||
if (future->semaphore) {
|
||||
osi_sem_free(&future->semaphore);
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,47 @@ extern const allocator_t allocator_calloc;
|
||||
|
||||
char *osi_strdup(const char *str);
|
||||
|
||||
void *osi_malloc(size_t size);
|
||||
void *osi_calloc(size_t size);
|
||||
void osi_free(void *ptr);
|
||||
void *osi_malloc_func(size_t size);
|
||||
void *osi_calloc_func(size_t size);
|
||||
void osi_free_func(void *ptr);
|
||||
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
|
||||
void osi_mem_dbg_init(void);
|
||||
void osi_mem_dbg_record(void *p, int size, const char *func, int line);
|
||||
void osi_mem_dbg_clean(void *p, const char *func, int line);
|
||||
void osi_mem_dbg_show(void);
|
||||
|
||||
#define osi_malloc(size) \
|
||||
({ \
|
||||
void *p; \
|
||||
\
|
||||
p = calloc(1, (size)); \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
})
|
||||
|
||||
#define osi_calloc(size) \
|
||||
({ \
|
||||
void *p; \
|
||||
\
|
||||
p = calloc(1, (size)); \
|
||||
osi_mem_dbg_record(p, size, __func__, __LINE__); \
|
||||
(void *)p; \
|
||||
})
|
||||
|
||||
#define osi_free(ptr) \
|
||||
({ \
|
||||
osi_mem_dbg_clean(ptr, __func__, __LINE__); \
|
||||
free((ptr)); \
|
||||
})
|
||||
|
||||
#else
|
||||
|
||||
#define osi_malloc(size) calloc(1, (size))
|
||||
#define osi_calloc(size) calloc(1, (size))
|
||||
#define osi_free(p) free((p))
|
||||
|
||||
#endif /* CONFIG_BLUEDROID_MEM_DEBUG */
|
||||
|
||||
#endif /* _ALLOCATOR_H_ */
|
||||
|
@ -20,7 +20,14 @@
|
||||
#define __FUTURE_H__
|
||||
// #pragma once
|
||||
|
||||
typedef struct future_t future_t;
|
||||
#include "osi_arch.h"
|
||||
|
||||
struct future {
|
||||
bool ready_can_be_called;
|
||||
osi_sem_t semaphore; // NULL semaphore means immediate future
|
||||
void *result;
|
||||
};
|
||||
typedef struct future future_t;
|
||||
|
||||
#define FUTURE_SUCCESS ((void *)1)
|
||||
#define FUTURE_FAIL ((void *)0)
|
||||
|
@ -43,18 +43,18 @@ enum {
|
||||
// SIG_BTIF_WORK = 0xff
|
||||
};
|
||||
|
||||
#define HCI_HOST_TASK_STACK_SIZE 1024
|
||||
#define HCI_HOST_TASK_PRIO (configMAX_PRIORITIES - 3)
|
||||
#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 30
|
||||
#define HCI_HOST_QUEUE_NUM 40
|
||||
|
||||
#define HCI_H4_TASK_STACK_SIZE 1024
|
||||
#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 30
|
||||
#define HCI_H4_QUEUE_NUM 60
|
||||
|
||||
#define BTU_TASK_STACK_SIZE 4096
|
||||
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 1)
|
||||
#define BTU_TASK_PRIO (configMAX_PRIORITIES - 4)
|
||||
#define BTU_TASK_NAME "btuT"
|
||||
#define BTU_QUEUE_NUM 50
|
||||
|
||||
|
@ -459,7 +459,7 @@ BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
|
||||
AVCT_TRACE_WARNING("avct_lcb_last_ccb");
|
||||
for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
|
||||
{
|
||||
AVCT_TRACE_WARNING("%x: aloc:%d, lcb:0x%x/0x%x, ccb:0x%x/0x%x",
|
||||
AVCT_TRACE_WARNING("%x: aloc:%d, lcb:%p/%p, ccb:%p/%p",
|
||||
i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
|
||||
if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last))
|
||||
{
|
||||
|
@ -1203,7 +1203,7 @@ extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len,
|
||||
|| p_scb->curr_cfg.mux_tsid_media == 0)
|
||||
{
|
||||
result = AVDT_ERR_BAD_STATE;
|
||||
AVDT_TRACE_WARNING("p_scb->p_pkt=%x, p_scb->p_ccb=%x, IsQueueEmpty=%x, p_scb->frag_off=%x\n",
|
||||
AVDT_TRACE_WARNING("p_scb->p_pkt=%p, p_scb->p_ccb=%p, IsQueueEmpty=%x, p_scb->frag_off=%x\n",
|
||||
p_scb->p_pkt, p_scb->p_ccb, GKI_queue_is_empty(&p_scb->frag_q), p_scb->frag_off);
|
||||
break;
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ void avdt_scb_hdl_pkt_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
|
||||
{
|
||||
if (p_end - p < 4) /* length check. maximum length of AL header = 4 */
|
||||
{
|
||||
AVDT_TRACE_WARNING("p_end: 0x%x - p:0x%x < 4\n", p_end, p);
|
||||
AVDT_TRACE_WARNING("p_end: %p - p:%p < 4\n", p_end, p);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -587,7 +587,7 @@ void avdt_scb_hdl_pkt_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
|
||||
{
|
||||
if(p_scb->p_media_buf + p_scb->frag_off - p_payload < 4)
|
||||
{
|
||||
AVDT_TRACE_WARNING("length check frag_off:%d p_media_buf:%d p_payload:%d\n",
|
||||
AVDT_TRACE_WARNING("length check frag_off:%d p_media_buf:%p p_payload:%p\n",
|
||||
p_scb->frag_off, p_scb->p_media_buf, p_payload);
|
||||
break;/* length check */
|
||||
}
|
||||
@ -598,7 +598,7 @@ void avdt_scb_hdl_pkt_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
|
||||
|
||||
if(p_payload >= p_scb->p_media_buf + p_scb->frag_off)
|
||||
{
|
||||
AVDT_TRACE_WARNING("length check2 frag_off:%d p_media_buf:%d p_payload:%d\n",
|
||||
AVDT_TRACE_WARNING("length check2 frag_off:%d p_media_buf:%p p_payload:%p\n",
|
||||
p_scb->frag_off, p_scb->p_media_buf, p_payload);
|
||||
break;/* length check */
|
||||
}
|
||||
|
@ -651,7 +651,6 @@ void BTM_ReadDevInfo (BD_ADDR remote_bda, tBT_DEVICE_TYPE *p_dev_type, tBLE_ADDR
|
||||
BOOLEAN BTM_ReadConnectedTransportAddress(BD_ADDR remote_bda, tBT_TRANSPORT transport)
|
||||
{
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_dev(remote_bda);
|
||||
tACL_CONN *p = btm_bda_to_acl(remote_bda, transport);
|
||||
|
||||
/* if no device can be located, return */
|
||||
if (p_dev_rec == NULL) {
|
||||
@ -1392,58 +1391,6 @@ void btm_ble_link_encrypted(BD_ADDR bd_addr, UINT8 encr_enable)
|
||||
gatt_notify_enc_cmpl(p_dev_rec->ble.pseudo_addr);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** Function btm_enc_proc_ltk
|
||||
** Description send LTK reply when it's ready.
|
||||
*******************************************************************************/
|
||||
static void btm_enc_proc_ltk(tSMP_ENC *p)
|
||||
{
|
||||
UINT8 i;
|
||||
BTM_TRACE_DEBUG ("btm_enc_proc_ltk");
|
||||
if (p && p->param_len == BT_OCTET16_LEN) {
|
||||
for (i = 0; i < (BT_OCTET16_LEN - btm_cb.key_size); i ++) {
|
||||
p->param_buf[BT_OCTET16_LEN - i - 1] = 0;
|
||||
}
|
||||
btsnd_hcic_ble_ltk_req_reply(btm_cb.enc_handle, p->param_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
** Function btm_enc_proc_slave_y
|
||||
** Description calculate LTK when Y is ready
|
||||
*******************************************************************************/
|
||||
static void btm_enc_proc_slave_y(tSMP_ENC *p)
|
||||
{
|
||||
UINT16 div, y;
|
||||
UINT8 *pp = p->param_buf;
|
||||
tBTM_CB *p_cb = &btm_cb;
|
||||
tSMP_ENC output;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
|
||||
BTM_TRACE_DEBUG ("btm_enc_proc_slave_y");
|
||||
if (p != NULL) {
|
||||
STREAM_TO_UINT16(y, pp);
|
||||
|
||||
div = p_cb->ediv ^ y;
|
||||
p_dev_rec = btm_find_dev_by_handle (p_cb->enc_handle);
|
||||
|
||||
if ( p_dev_rec &&
|
||||
p_dev_rec->ble.keys.div == div ) {
|
||||
BTM_TRACE_DEBUG ("LTK request OK");
|
||||
/* calculating LTK , LTK = E er(div) */
|
||||
SMP_Encrypt(p_cb->devcb.ble_encryption_key_value, BT_OCTET16_LEN, (UINT8 *)&div, 2, &output);
|
||||
btm_enc_proc_ltk(&output);
|
||||
} else {
|
||||
BTM_TRACE_DEBUG ("LTK request failed - send negative reply");
|
||||
btsnd_hcic_ble_ltk_req_neg_reply(p_cb->enc_handle);
|
||||
if (p_dev_rec) {
|
||||
btm_ble_link_encrypted(p_dev_rec->bd_addr, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btm_ble_ltk_request_reply
|
||||
@ -1458,7 +1405,6 @@ void btm_ble_ltk_request_reply(BD_ADDR bda, BOOLEAN use_stk, BT_OCTET16 stk)
|
||||
{
|
||||
tBTM_SEC_DEV_REC *p_rec = btm_find_dev (bda);
|
||||
tBTM_CB *p_cb = &btm_cb;
|
||||
tSMP_ENC output;
|
||||
|
||||
if (p_rec == NULL) {
|
||||
BTM_TRACE_ERROR("btm_ble_ltk_request_reply received for unknown device");
|
||||
@ -1855,7 +1801,7 @@ UINT8 btm_proc_smp_cback(tSMP_EVT event, BD_ADDR bd_addr, tSMP_EVT_DATA *p_data)
|
||||
case SMP_COMPLT_EVT:
|
||||
if (btm_cb.api.p_le_callback) {
|
||||
/* the callback function implementation may change the IO capability... */
|
||||
BTM_TRACE_DEBUG ("btm_cb.api.p_le_callback=0x%x", btm_cb.api.p_le_callback );
|
||||
BTM_TRACE_DEBUG ("btm_cb.api.p_le_callback=%p", btm_cb.api.p_le_callback );
|
||||
(*btm_cb.api.p_le_callback) (event, bd_addr, (tBTM_LE_EVT_DATA *)p_data);
|
||||
}
|
||||
|
||||
@ -1975,7 +1921,7 @@ BOOLEAN BTM_BleDataSignature (BD_ADDR bd_addr, UINT8 *p_text, UINT16 len,
|
||||
btm_ble_increment_sign_ctr(bd_addr, TRUE);
|
||||
}
|
||||
|
||||
BTM_TRACE_DEBUG("%s p_mac = %d", __func__, p_mac);
|
||||
BTM_TRACE_DEBUG("%s p_mac = %p", __func__, p_mac);
|
||||
BTM_TRACE_DEBUG("p_mac[0] = 0x%02x p_mac[1] = 0x%02x p_mac[2] = 0x%02x p_mac[3] = 0x%02x",
|
||||
*p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3));
|
||||
BTM_TRACE_DEBUG("p_mac[4] = 0x%02x p_mac[5] = 0x%02x p_mac[6] = 0x%02x p_mac[7] = 0x%02x",
|
||||
|
@ -118,7 +118,7 @@ void btm_ble_advfilt_enq_op_q(UINT8 action, UINT8 ocf, tBTM_BLE_FILT_CB_EVT cb_e
|
||||
btm_ble_adv_filt_cb.op_q.p_scan_cfg_cback[btm_ble_adv_filt_cb.op_q.next_idx] = p_cmpl_cback;
|
||||
btm_ble_adv_filt_cb.op_q.p_filt_param_cback[btm_ble_adv_filt_cb.op_q.next_idx]
|
||||
= p_filt_param_cback;
|
||||
BTM_TRACE_DEBUG("btm_ble_advfilt_enq_op_q: act_ocf:%d, action:%d, ocf:%d,cb_evt;%d, cback:%x",
|
||||
BTM_TRACE_DEBUG("btm_ble_advfilt_enq_op_q: act_ocf:%d, action:%d, ocf:%d,cb_evt;%d, cback:%p",
|
||||
btm_ble_adv_filt_cb.op_q.action_ocf[btm_ble_adv_filt_cb.op_q.next_idx], action,
|
||||
ocf, cb_evt, p_cmpl_cback);
|
||||
btm_ble_adv_filt_cb.op_q.next_idx = (btm_ble_adv_filt_cb.op_q.next_idx + 1)
|
||||
|
@ -64,7 +64,7 @@ static void background_connections_lazy_init()
|
||||
{
|
||||
if (!background_connections) {
|
||||
background_connections = hash_map_new(background_connection_buckets,
|
||||
hash_function_bdaddr, NULL, osi_free, bdaddr_equality_fn);
|
||||
hash_function_bdaddr, NULL, allocator_calloc.free, bdaddr_equality_fn);
|
||||
assert(background_connections);
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void btm_ble_cont_energy_cmpl_cback (tBTM_VSC_CMPL *p_params)
|
||||
STREAM_TO_UINT32(total_idle_time, p);
|
||||
STREAM_TO_UINT32(total_energy_used, p);
|
||||
|
||||
BTM_TRACE_DEBUG("energy_info status=%d,tx_t=%ld, rx_t=%ld, ener_used=%ld, idle_t=%ld",
|
||||
BTM_TRACE_DEBUG("energy_info status=%d,tx_t=%u, rx_t=%u, ener_used=%u, idle_t=%u",
|
||||
status, total_tx_time, total_rx_time, total_energy_used, total_idle_time);
|
||||
|
||||
if (NULL != ble_energy_info_cb.p_ener_cback)
|
||||
|
@ -474,6 +474,7 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
|
||||
return status;
|
||||
}
|
||||
|
||||
#if BLE_VND_INCLUDED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btm_vsc_brcm_features_complete
|
||||
@ -485,7 +486,6 @@ tBTM_STATUS BTM_BleBroadcast(BOOLEAN start)
|
||||
*******************************************************************************/
|
||||
static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_params)
|
||||
{
|
||||
#if BLE_VND_INCLUDED == TRUE
|
||||
UINT8 status = 0xFF;
|
||||
UINT8 *p;
|
||||
|
||||
@ -549,8 +549,8 @@ static void btm_ble_vendor_capability_vsc_cmpl_cback (tBTM_VSC_CMPL *p_vcs_cplt_
|
||||
if (p_ctrl_le_feature_rd_cmpl_cback != NULL) {
|
||||
p_ctrl_le_feature_rd_cmpl_cback(status);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@ -1064,7 +1064,6 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max,
|
||||
{
|
||||
tBTM_LE_RANDOM_CB *p_addr_cb = &btm_cb.ble_ctr_cb.addr_mgnt_cb;
|
||||
tBTM_BLE_INQ_CB *p_cb = &btm_cb.ble_ctr_cb.inq_var;
|
||||
tBTM_STATUS status = BTM_SUCCESS;
|
||||
|
||||
BTM_TRACE_EVENT ("BTM_BleSetAdvParamsStartAdv\n");
|
||||
|
||||
@ -1077,6 +1076,14 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max,
|
||||
return BTM_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if(adv_type == BTM_BLE_CONNECT_DIR_EVT){
|
||||
btm_ble_set_topology_mask(BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT);
|
||||
}else if(adv_type == BTM_BLE_CONNECT_LO_DUTY_DIR_EVT){
|
||||
btm_ble_set_topology_mask(BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT);
|
||||
}else if(adv_type == BTM_BLE_CONNECT_LO_DUTY_DIR_EVT){
|
||||
btm_ble_set_topology_mask(BTM_BLE_STATE_NON_CONN_ADV_BIT);
|
||||
}
|
||||
|
||||
p_cb->adv_interval_min = adv_int_min;
|
||||
p_cb->adv_interval_max = adv_int_max;
|
||||
p_cb->adv_chnl_map = chnl_map;
|
||||
@ -1103,7 +1110,7 @@ tBTM_STATUS BTM_BleSetAdvParamsStartAdv(UINT16 adv_int_min, UINT16 adv_int_max,
|
||||
chnl_map,
|
||||
p_cb->afp);
|
||||
|
||||
btm_ble_start_adv();
|
||||
return btm_ble_start_adv();
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,7 +462,6 @@ void btm_consolidate_dev(tBTM_SEC_DEV_REC *p_target_rec)
|
||||
#if BLE_INCLUDED == TRUE
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = &btm_cb.sec_dev_rec[0];
|
||||
tBTM_SEC_DEV_REC temp_rec = *p_target_rec;
|
||||
BD_ADDR dummy_bda = {0};
|
||||
|
||||
BTM_TRACE_DEBUG("%s\n", __func__);
|
||||
|
||||
|
@ -261,9 +261,6 @@ void btm_dev_timeout (TIMER_LIST_ENT *p_tle)
|
||||
*******************************************************************************/
|
||||
static void btm_decode_ext_features_page (UINT8 page_number, const UINT8 *p_features)
|
||||
{
|
||||
UINT8 last;
|
||||
UINT8 first;
|
||||
|
||||
BTM_TRACE_DEBUG ("btm_decode_ext_features_page page: %d", page_number);
|
||||
switch (page_number) {
|
||||
/* Extended (Legacy) Page 0 */
|
||||
|
@ -103,10 +103,8 @@ static UINT16 btm_sec_set_serv_level4_flags (UINT16 cur_security, BOOLEAN is_or
|
||||
|
||||
static BOOLEAN btm_sec_queue_encrypt_request (BD_ADDR bd_addr, tBT_TRANSPORT transport,
|
||||
tBTM_SEC_CALLBACK *p_callback, void *p_ref_data);
|
||||
static void btm_sec_clean_pending_req_queue (BD_ADDR remote_bda, tBT_TRANSPORT transport) ;
|
||||
static void btm_sec_check_pending_enc_req (tBTM_SEC_DEV_REC *p_dev_rec, tBT_TRANSPORT transport,
|
||||
UINT8 encr_enable);
|
||||
static BOOLEAN btm_sec_acceptor_rejects_bonding (tBTM_SEC_DEV_REC *p_dev_rec);
|
||||
|
||||
static BOOLEAN btm_sec_use_smp_br_chnl(tBTM_SEC_DEV_REC *p_dev_rec);
|
||||
static BOOLEAN btm_sec_is_master(tBTM_SEC_DEV_REC *p_dev_rec);
|
||||
@ -2050,11 +2048,11 @@ tBTM_STATUS btm_sec_l2cap_access_req (BD_ADDR bd_addr, UINT16 psm, UINT16 handle
|
||||
is_originator = FALSE;
|
||||
}
|
||||
|
||||
BTM_TRACE_DEBUG ("%s() conn_type: 0x%x, 0x%x\n", __func__, conn_type, p_ref_data);
|
||||
BTM_TRACE_DEBUG ("%s() conn_type: 0x%x, %p\n", __func__, conn_type, p_ref_data);
|
||||
#else
|
||||
is_originator = conn_type;
|
||||
|
||||
BTM_TRACE_DEBUG ("%s() is_originator:%d, 0x%x\n", __func__, is_originator, p_ref_data);
|
||||
BTM_TRACE_DEBUG ("%s() is_originator:%d, %p\n", __func__, is_originator, p_ref_data);
|
||||
#endif
|
||||
|
||||
/* Find or get oldest record */
|
||||
@ -2932,7 +2930,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
|
||||
}
|
||||
|
||||
if (p_dev_rec) {
|
||||
BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s RemName: %s status: %d State:%d p_dev_rec: 0x%08x \n",
|
||||
BTM_TRACE_EVENT ("Security Manager: rmt_name_complete PairState: %s RemName: %s status: %d State:%d p_dev_rec: %p \n",
|
||||
btm_pair_state_descr (btm_cb.pairing_state), p_bd_name,
|
||||
status, p_dev_rec->sec_state, p_dev_rec);
|
||||
} else {
|
||||
@ -2981,7 +2979,7 @@ void btm_sec_rmt_name_request_complete (UINT8 *p_bd_addr, UINT8 *p_bd_name, UINT
|
||||
/* If we were delaying asking UI for a PIN because name was not resolved, ask now */
|
||||
if ( (btm_cb.pairing_state == BTM_PAIR_STATE_WAIT_LOCAL_PIN) && p_bd_addr
|
||||
&& (memcmp (btm_cb.pairing_bda, p_bd_addr, BD_ADDR_LEN) == 0) ) {
|
||||
BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() delayed pin now being requested flags:0x%x, (p_pin_callback=0x%p)\n", btm_cb.pairing_flags, btm_cb.api.p_pin_callback);
|
||||
BTM_TRACE_EVENT ("btm_sec_rmt_name_request_complete() delayed pin now being requested flags:0x%x, (p_pin_callback=%p)\n", btm_cb.pairing_flags, btm_cb.api.p_pin_callback);
|
||||
|
||||
if (((btm_cb.pairing_flags & BTM_PAIR_FLAGS_WE_STARTED_DD) == 0) &&
|
||||
((btm_cb.pairing_flags & BTM_PAIR_FLAGS_PIN_REQD) == 0) &&
|
||||
@ -3194,7 +3192,7 @@ void btm_io_capabilities_req (UINT8 *p)
|
||||
|
||||
p_dev_rec->sm4 |= BTM_SM4_TRUE;
|
||||
|
||||
BTM_TRACE_EVENT("%s: State: %s Flags: 0x%04x p_cur_service: 0x%08x\n",
|
||||
BTM_TRACE_EVENT("%s: State: %s Flags: 0x%04x p_cur_service: %p\n",
|
||||
__FUNCTION__, btm_pair_state_descr(btm_cb.pairing_state),
|
||||
btm_cb.pairing_flags, p_dev_rec->p_cur_service);
|
||||
|
||||
@ -4939,7 +4937,7 @@ void btm_sec_pin_code_request (UINT8 *p_bda)
|
||||
|| (!p_dev_rec->is_originator
|
||||
&& ((p_dev_rec->dev_class[1] & BTM_COD_MAJOR_CLASS_MASK) == BTM_COD_MAJOR_PERIPHERAL)
|
||||
&& (p_dev_rec->dev_class[2] & BTM_COD_MINOR_KEYBOARD)) ) {
|
||||
BTM_TRACE_WARNING("btm_sec_pin_code_request(): Pairing disabled:%d; PIN callback:%x, Dev Rec:%x!\n",
|
||||
BTM_TRACE_WARNING("btm_sec_pin_code_request(): Pairing disabled:%d; PIN callback:%p, Dev Rec:%p!\n",
|
||||
p_cb->pairing_disabled, p_cb->api.p_pin_callback, p_dev_rec);
|
||||
|
||||
btsnd_hcic_pin_code_neg_reply (p_bda);
|
||||
@ -5821,36 +5819,6 @@ void btm_sec_set_peer_sec_caps(tACL_CONN *p_acl_cb, tBTM_SEC_DEV_REC *p_dev_rec)
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btm_sec_clean_pending_req_queue
|
||||
**
|
||||
** Description This function cleans up the pending security request when the
|
||||
** link to the target device dropped.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void btm_sec_clean_pending_req_queue (BD_ADDR remote_bda, tBT_TRANSPORT transport)
|
||||
{
|
||||
tBTM_SEC_QUEUE_ENTRY *p_e;
|
||||
BUFFER_Q *bq = &btm_cb.sec_pending_q;
|
||||
|
||||
p_e = (tBTM_SEC_QUEUE_ENTRY *)GKI_getfirst(bq);
|
||||
|
||||
if (p_e != NULL) {
|
||||
if (memcmp(p_e->bd_addr, remote_bda, BD_ADDR_LEN) == 0
|
||||
#if BLE_INCLUDED == TRUE
|
||||
&& p_e->transport == transport
|
||||
#endif
|
||||
) {
|
||||
(*p_e->p_callback) (remote_bda, transport, p_e->p_ref_data, BTM_ERR_PROCESSING);
|
||||
GKI_remove_from_queue(bq, (void *)p_e);
|
||||
}
|
||||
p_e = (tBTM_SEC_QUEUE_ENTRY *) GKI_getnext ((void *)p_e);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function btm_sec_is_serv_level0
|
||||
|
@ -217,9 +217,9 @@ error_exit:;
|
||||
void BTU_ShutDown(void)
|
||||
{
|
||||
btu_task_shut_down();
|
||||
/*
|
||||
fixed_queue_free(btu_bta_msg_queue, NULL);
|
||||
*/
|
||||
|
||||
fixed_queue_free(btu_bta_msg_queue, NULL);
|
||||
|
||||
hash_map_free(btu_general_alarm_hash_map);
|
||||
pthread_mutex_destroy(&btu_general_alarm_lock);
|
||||
fixed_queue_free(btu_general_alarm_queue, NULL);
|
||||
|
@ -378,7 +378,6 @@ void btu_task_start_up(void)
|
||||
|
||||
void btu_task_shut_down(void)
|
||||
{
|
||||
fixed_queue_unregister_dequeue(btu_hci_msg_queue);
|
||||
fixed_queue_unregister_dequeue(btu_general_alarm_queue);
|
||||
fixed_queue_unregister_dequeue(btu_oneshot_alarm_queue);
|
||||
fixed_queue_unregister_dequeue(btu_l2cap_alarm_queue);
|
||||
|
@ -127,7 +127,7 @@ UINT16 GAP_ConnOpen (char *p_serv_name, UINT8 service_id, BOOLEAN is_server,
|
||||
{
|
||||
tGAP_CCB *p_ccb;
|
||||
UINT16 cid;
|
||||
tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}};
|
||||
//tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}};
|
||||
|
||||
GAP_TRACE_EVENT ("GAP_CONN - Open Request");
|
||||
|
||||
@ -718,7 +718,7 @@ static void gap_connect_ind (BD_ADDR bd_addr, UINT16 l2cap_cid, UINT16 psm, UIN
|
||||
{
|
||||
UINT16 xx;
|
||||
tGAP_CCB *p_ccb;
|
||||
tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}};
|
||||
//tBT_UUID bt_uuid = {2, {GAP_PROTOCOL_ID}};
|
||||
|
||||
/* See if we have a CCB listening for the connection */
|
||||
for (xx = 0, p_ccb = gap_cb.conn.ccb_pool; xx < GAP_MAX_CONNECTIONS; xx++, p_ccb++) {
|
||||
|
@ -477,7 +477,6 @@ static void gatt_cl_start_config_ccc(tGATT_PROFILE_CLCB *p_clcb)
|
||||
*******************************************************************************/
|
||||
void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSPORT transport)
|
||||
{
|
||||
UINT16 conn_id = GATT_INVALID_CONN_ID;
|
||||
tGATT_PROFILE_CLCB *p_clcb = gatt_profile_find_clcb_by_bd_addr (remote_bda, transport);
|
||||
|
||||
if (p_clcb == NULL) {
|
||||
|
@ -920,7 +920,7 @@ void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
|
||||
gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p_clcb->p_attr_buf);
|
||||
}
|
||||
} else { /* exception, should not happen */
|
||||
GATT_TRACE_ERROR("attr offset = %d p_attr_buf = %d ", offset, p_clcb->p_attr_buf);
|
||||
GATT_TRACE_ERROR("attr offset = %d p_attr_buf = %p ", offset, p_clcb->p_attr_buf);
|
||||
gatt_end_operation(p_clcb, GATT_NO_RESOURCES, (void *)p_clcb->p_attr_buf);
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ void gatt_dequeue_sr_cmd (tGATT_TCB *p_tcb)
|
||||
/* Double check in case any buffers are queued */
|
||||
GATT_TRACE_DEBUG("gatt_dequeue_sr_cmd" );
|
||||
if (p_tcb->sr_cmd.p_rsp_msg) {
|
||||
GATT_TRACE_ERROR("free p_tcb->sr_cmd.p_rsp_msg = %d", p_tcb->sr_cmd.p_rsp_msg);
|
||||
GATT_TRACE_ERROR("%s free msg %p", __func__, p_tcb->sr_cmd.p_rsp_msg);
|
||||
|
||||
GKI_freebuf (p_tcb->sr_cmd.p_rsp_msg);
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
|
||||
tL2C_RCB *p_rcb;
|
||||
|
||||
//counter_add("l2cap.conn.req", 1);
|
||||
L2CAP_TRACE_API ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info: 0x%08x allowed:0x%x preferred:%d", psm,
|
||||
L2CAP_TRACE_API ("L2CA_ErtmConnectReq() PSM: 0x%04x BDA: %08x%04x p_ertm_info: %p allowed:0x%x preferred:%d", psm,
|
||||
(p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) + p_bd_addr[3],
|
||||
(p_bd_addr[4] << 8) + p_bd_addr[5], p_ertm_info,
|
||||
(p_ertm_info) ? p_ertm_info->allowed_modes : 0,
|
||||
@ -252,7 +252,7 @@ UINT16 L2CA_ErtmConnectReq (UINT16 psm, BD_ADDR p_bd_addr, tL2CAP_ERTM_INFO *p_e
|
||||
if ( ((p_lcb = l2cu_allocate_lcb (p_bd_addr, FALSE, BT_TRANSPORT_BR_EDR)) == NULL)
|
||||
/* currently use BR/EDR for ERTM mode l2cap connection */
|
||||
|| (l2cu_create_conn(p_lcb, BT_TRANSPORT_BR_EDR) == FALSE) ) {
|
||||
L2CAP_TRACE_WARNING ("L2CAP - conn not started for PSM: 0x%04x p_lcb: 0x%08x", psm, p_lcb);
|
||||
L2CAP_TRACE_WARNING ("L2CAP - conn not started for PSM: 0x%04x p_lcb: %p", psm, p_lcb);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -390,7 +390,7 @@ BOOLEAN L2CA_ErtmConnectRsp (BD_ADDR p_bd_addr, UINT8 id, UINT16 lcid, UINT16 re
|
||||
tL2C_CCB *p_ccb;
|
||||
|
||||
//counter_add("l2cap.conn.rsp", 1);
|
||||
L2CAP_TRACE_API ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x p_ertm_info:0x%08x",
|
||||
L2CAP_TRACE_API ("L2CA_ErtmConnectRsp() CID: 0x%04x Result: %d Status: %d BDA: %08x%04x p_ertm_info:%p",
|
||||
lcid, result, status,
|
||||
(p_bd_addr[0] << 24) + (p_bd_addr[1] << 16) + (p_bd_addr[2] << 8) + p_bd_addr[3],
|
||||
(p_bd_addr[4] << 8) + p_bd_addr[5], p_ertm_info);
|
||||
@ -1824,7 +1824,7 @@ UINT16 L2CA_FlushChannel (UINT16 lcid, UINT16 num_to_flush)
|
||||
}
|
||||
|
||||
if (num_to_flush != L2CAP_FLUSH_CHANS_GET) {
|
||||
L2CAP_TRACE_API ("L2CA_FlushChannel (FLUSH) CID: 0x%04x NumToFlush: %d QC: %u pFirst: 0x%08x",
|
||||
L2CAP_TRACE_API ("L2CA_FlushChannel (FLUSH) CID: 0x%04x NumToFlush: %d QC: %u pFirst: %p",
|
||||
lcid, num_to_flush, GKI_queue_length(&p_ccb->xmit_hold_q), GKI_getfirst(&p_ccb->xmit_hold_q));
|
||||
} else {
|
||||
L2CAP_TRACE_API ("L2CA_FlushChannel (QUERY) CID: 0x%04x", lcid);
|
||||
|
@ -257,7 +257,6 @@ void l2cble_notify_le_connection (BD_ADDR bda)
|
||||
void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
|
||||
UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
|
||||
{
|
||||
int i;
|
||||
tL2C_LCB *p_lcb;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev (bda);
|
||||
|
||||
@ -358,7 +357,6 @@ void l2cble_scanner_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
|
||||
void l2cble_advertiser_conn_comp (UINT16 handle, BD_ADDR bda, tBLE_ADDR_TYPE type,
|
||||
UINT16 conn_interval, UINT16 conn_latency, UINT16 conn_timeout)
|
||||
{
|
||||
int i;
|
||||
tL2C_LCB *p_lcb;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec;
|
||||
UNUSED(type);
|
||||
@ -456,7 +454,6 @@ void l2cble_conn_comp(UINT16 handle, UINT8 role, BD_ADDR bda, tBLE_ADDR_TYPE typ
|
||||
static void l2cble_start_conn_update (tL2C_LCB *p_lcb)
|
||||
{
|
||||
UINT16 min_conn_int, max_conn_int, slave_latency, supervision_tout;
|
||||
tBTM_SEC_DEV_REC *p_dev_rec = btm_find_or_alloc_dev(p_lcb->remote_bd_addr);
|
||||
tACL_CONN *p_acl_cb = btm_bda_to_acl(p_lcb->remote_bd_addr, BT_TRANSPORT_LE);
|
||||
|
||||
if (p_lcb->conn_update_mask & L2C_BLE_UPDATE_PENDING) {
|
||||
|
@ -1255,7 +1255,7 @@ static void process_stream_frame (tL2C_CCB *p_ccb, BT_HDR *p_buf)
|
||||
|
||||
/* Check if tx-sequence is the expected one */
|
||||
if (tx_seq != p_ccb->fcrb.next_seq_expected) {
|
||||
L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x Lost frames Exp: %u Got: %u p_rx_sdu: 0x%08x",
|
||||
L2CAP_TRACE_WARNING ("Rx L2CAP PDU: CID: 0x%04x Lost frames Exp: %u Got: %u p_rx_sdu: %p",
|
||||
p_ccb->local_cid, p_ccb->fcrb.next_seq_expected, tx_seq, p_ccb->fcrb.p_rx_sdu);
|
||||
|
||||
/* Lost one or more packets, so flush the SAR queue */
|
||||
|
@ -280,7 +280,7 @@ void l2c_link_sec_comp (BD_ADDR p_bda, tBT_TRANSPORT transport, void *p_ref_data
|
||||
|
||||
UNUSED(transport);
|
||||
|
||||
L2CAP_TRACE_DEBUG ("l2c_link_sec_comp: %d, 0x%x", status, p_ref_data);
|
||||
L2CAP_TRACE_DEBUG ("l2c_link_sec_comp: %d, %p", status, p_ref_data);
|
||||
|
||||
if (status == BTM_SUCCESS_NO_SECURITY) {
|
||||
status = BTM_SUCCESS;
|
||||
|
@ -1192,7 +1192,7 @@ void l2cu_enqueue_ccb (tL2C_CCB *p_ccb)
|
||||
}
|
||||
|
||||
if ( (!p_ccb->in_use) || (p_q == NULL) ) {
|
||||
L2CAP_TRACE_ERROR ("l2cu_enqueue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x",
|
||||
L2CAP_TRACE_ERROR ("l2cu_enqueue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: %p",
|
||||
p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb);
|
||||
return;
|
||||
}
|
||||
@ -1278,7 +1278,7 @@ void l2cu_dequeue_ccb (tL2C_CCB *p_ccb)
|
||||
}
|
||||
|
||||
if ( (!p_ccb->in_use) || (p_q == NULL) || (p_q->p_first_ccb == NULL) ) {
|
||||
L2CAP_TRACE_ERROR ("l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: 0x%08x p_q: 0x%08x p_q->p_first_ccb: 0x%08x",
|
||||
L2CAP_TRACE_ERROR ("l2cu_dequeue_ccb CID: 0x%04x ERROR in_use: %u p_lcb: %p p_q: %p p_q->p_first_ccb: %p",
|
||||
p_ccb->local_cid, p_ccb->in_use, p_ccb->p_lcb, p_q, p_q ? p_q->p_first_ccb : 0);
|
||||
return;
|
||||
}
|
||||
@ -2423,7 +2423,7 @@ void l2cu_resubmit_pending_sec_req (BD_ADDR p_bda)
|
||||
tL2C_CCB *p_next_ccb;
|
||||
int xx;
|
||||
|
||||
L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req p_bda: 0x%08x", p_bda);
|
||||
L2CAP_TRACE_DEBUG ("l2cu_resubmit_pending_sec_req p_bda: %p", p_bda);
|
||||
|
||||
/* If we are called with a BDA, only resubmit for that BDA */
|
||||
if (p_bda) {
|
||||
|
@ -398,6 +398,8 @@ BOOLEAN SDP_FindServiceUUIDInRec(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid)
|
||||
p_attr = p_attr->p_next_attr;
|
||||
}
|
||||
return FALSE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -451,6 +453,8 @@ BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID *p_uuid)
|
||||
p_attr = p_attr->p_next_attr;
|
||||
}
|
||||
return FALSE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -935,6 +939,7 @@ UINT8 SDP_GetNumDiRecords( tSDP_DISCOVERY_DB *p_db )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SDP_CLIENT_ENABLED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function SDP_AttrStringCopy
|
||||
@ -960,6 +965,7 @@ static void SDP_AttrStringCopy(char *dst, tSDP_DISC_ATTR *p_attr, UINT16 dst_siz
|
||||
dst[0] = '\0';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
|
@ -914,9 +914,9 @@ BOOLEAN SDP_DeleteAttribute (UINT32 handle, UINT16 attr_id)
|
||||
#if (SDP_RAW_DATA_INCLUDED == TRUE)
|
||||
INT32 SDP_ReadRecord(UINT32 handle, UINT8 *p_data, INT32 *p_data_len)
|
||||
{
|
||||
INT32 len = 0; /* Number of bytes in the entry */
|
||||
INT32 offset = -1; /* default to not found */
|
||||
#if SDP_SERVER_ENABLED == TRUE
|
||||
INT32 len = 0; /* Number of bytes in the entry */
|
||||
tSDP_RECORD *p_rec;
|
||||
UINT16 start = 0;
|
||||
UINT16 end = 0xffff;
|
||||
|
@ -154,7 +154,7 @@ static BOOLEAN cmac_aes_k_calculate(BT_OCTET16 key, UINT8 *p_signature, UINT16 t
|
||||
p_mac = output.param_buf + (BT_OCTET16_LEN - tlen);
|
||||
memcpy(p_signature, p_mac, tlen);
|
||||
|
||||
SMP_TRACE_DEBUG("tlen = %d p_mac = %d", tlen, p_mac);
|
||||
SMP_TRACE_DEBUG("tlen = %d p_mac = %p", tlen, p_mac);
|
||||
SMP_TRACE_DEBUG("p_mac[0] = 0x%02x p_mac[1] = 0x%02x p_mac[2] = 0x%02x p_mac[3] = 0x%02x",
|
||||
*p_mac, *(p_mac + 1), *(p_mac + 2), *(p_mac + 3));
|
||||
SMP_TRACE_DEBUG("p_mac[4] = 0x%02x p_mac[5] = 0x%02x p_mac[6] = 0x%02x p_mac[7] = 0x%02x",
|
||||
|
@ -38,13 +38,13 @@ COMPONENT_ADD_INCLUDEDIRS := bluedroid/bta/include \
|
||||
bluedroid/include \
|
||||
include
|
||||
|
||||
CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses -Wno-error=format
|
||||
|
||||
LIBS := btdm_app
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -lbt -L $(COMPONENT_PATH)/lib \
|
||||
$(addprefix -l,$(LIBS)) \
|
||||
$(LINKER_SCRIPTS)
|
||||
$(addprefix -l,$(LIBS))
|
||||
|
||||
# re-link program if BT binary libs change
|
||||
COMPONENT_ADD_LINKER_DEPS := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
|
||||
|
||||
COMPONENT_SRCDIRS := bluedroid/bta/dm \
|
||||
bluedroid/bta/gatt \
|
||||
@ -86,9 +86,4 @@ COMPONENT_SRCDIRS := bluedroid/bta/dm \
|
||||
bluedroid \
|
||||
.
|
||||
|
||||
#include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
|
||||
$(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
|
||||
|
||||
COMPONENT_SUBMODULES += lib
|
||||
|
@ -14,17 +14,20 @@
|
||||
#include <esp_types.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "soc/soc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static const char* GPIO_TAG = "GPIO";
|
||||
#define GPIO_CHECK(a, str, ret_val) if (!(a)) { \
|
||||
ESP_LOGE(GPIO_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
static const char* GPIO_TAG = "gpio";
|
||||
#define GPIO_CHECK(a, str, ret_val) \
|
||||
if (!(a)) { \
|
||||
ESP_LOGE(GPIO_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
|
||||
return (ret_val); \
|
||||
}
|
||||
|
||||
const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
|
||||
GPIO_PIN_REG_0,
|
||||
@ -69,74 +72,45 @@ const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
|
||||
GPIO_PIN_REG_39
|
||||
};
|
||||
|
||||
const gpio_pu_pd_desc_t gpio_pu_pd_desc[GPIO_PIN_COUNT]={
|
||||
{RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M},
|
||||
{PERIPHS_IO_MUX_U0TXD_U, FUN_PU, FUN_PD},
|
||||
{RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M},
|
||||
{PERIPHS_IO_MUX_U0RXD_U, FUN_PU, FUN_PD},
|
||||
{RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M},
|
||||
{PERIPHS_IO_MUX_GPIO5_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_SD_CLK_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_SD_DATA0_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_SD_DATA1_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_SD_DATA2_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_SD_DATA3_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_SD_CMD_U, FUN_PU, FUN_PD},
|
||||
{RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M},
|
||||
{RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M},
|
||||
{RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M},
|
||||
{RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M},
|
||||
{PERIPHS_IO_MUX_GPIO16_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO17_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO18_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO19_U, FUN_PU, FUN_PD},
|
||||
{0,0,0},
|
||||
{PERIPHS_IO_MUX_GPIO21_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO22_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO23_U, FUN_PU, FUN_PD},
|
||||
{0,0,0},
|
||||
{RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M},
|
||||
{RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M},
|
||||
{RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M},
|
||||
{0,0,0},
|
||||
{0,0,0},
|
||||
{0,0,0},
|
||||
{0,0,0},
|
||||
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M},
|
||||
{RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M},
|
||||
{PERIPHS_IO_MUX_GPIO34_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO35_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO36_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO37_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO38_U, FUN_PU, FUN_PD},
|
||||
{PERIPHS_IO_MUX_GPIO39_U, FUN_PU, FUN_PD}
|
||||
};
|
||||
|
||||
|
||||
esp_err_t gpio_pullup_en(gpio_num_t gpio_num) {
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
|
||||
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
|
||||
rtc_gpio_pullup_en(gpio_num);
|
||||
}else{
|
||||
REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_pullup_dis(gpio_num_t gpio_num) {
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
|
||||
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
|
||||
rtc_gpio_pullup_dis(gpio_num);
|
||||
}else{
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_pulldown_en(gpio_num_t gpio_num) {
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
|
||||
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
|
||||
rtc_gpio_pulldown_en(gpio_num);
|
||||
}else{
|
||||
REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num) {
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
|
||||
if(RTC_GPIO_IS_VALID_GPIO(gpio_num)){
|
||||
rtc_gpio_pulldown_dis(gpio_num);
|
||||
}else{
|
||||
REG_CLR_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
@ -148,7 +122,7 @@ esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
|
||||
esp_err_t gpio_intr_enable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
if(xPortGetCoreID() == 0) {
|
||||
if (xPortGetCoreID() == 0) {
|
||||
GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr
|
||||
} else {
|
||||
GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr
|
||||
@ -166,7 +140,7 @@ esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
|
||||
static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
if(gpio_num < 32) {
|
||||
if (gpio_num < 32) {
|
||||
GPIO.enable_w1tc = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
|
||||
@ -177,7 +151,7 @@ static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
|
||||
static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "GPIO output gpio_num error", ESP_ERR_INVALID_ARG);
|
||||
if(gpio_num < 32) {
|
||||
if (gpio_num < 32) {
|
||||
GPIO.enable_w1ts = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
|
||||
@ -188,14 +162,14 @@ static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
|
||||
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
if(level) {
|
||||
if(gpio_num < 32) {
|
||||
if (level) {
|
||||
if (gpio_num < 32) {
|
||||
GPIO.out_w1ts = (1 << gpio_num);
|
||||
} else {
|
||||
GPIO.out1_w1ts.data = (1 << (gpio_num - 32));
|
||||
}
|
||||
} else {
|
||||
if(gpio_num < 32) {
|
||||
if (gpio_num < 32) {
|
||||
GPIO.out_w1tc = (1 << gpio_num);
|
||||
} else {
|
||||
GPIO.out1_w1tc.data = (1 << (gpio_num - 32));
|
||||
@ -206,7 +180,7 @@ esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
|
||||
|
||||
int gpio_get_level(gpio_num_t gpio_num)
|
||||
{
|
||||
if(gpio_num < 32) {
|
||||
if (gpio_num < 32) {
|
||||
return (GPIO.in >> gpio_num) & 0x1;
|
||||
} else {
|
||||
return (GPIO.in1.data >> (gpio_num - 32)) & 0x1;
|
||||
@ -218,27 +192,27 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
GPIO_CHECK(pull <= GPIO_FLOATING, "GPIO pull mode error", ESP_ERR_INVALID_ARG);
|
||||
esp_err_t ret = ESP_OK;
|
||||
switch(pull) {
|
||||
case GPIO_PULLUP_ONLY:
|
||||
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
|
||||
break;
|
||||
case GPIO_PULLDOWN_ONLY:
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
|
||||
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
|
||||
break;
|
||||
case GPIO_PULLUP_PULLDOWN:
|
||||
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
|
||||
REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
|
||||
break;
|
||||
case GPIO_FLOATING:
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu);
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pd);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u",gpio_num,pull);
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
break;
|
||||
switch (pull) {
|
||||
case GPIO_PULLUP_ONLY:
|
||||
gpio_pulldown_dis(gpio_num);
|
||||
gpio_pullup_en(gpio_num);
|
||||
break;
|
||||
case GPIO_PULLDOWN_ONLY:
|
||||
gpio_pulldown_en(gpio_num);
|
||||
gpio_pullup_dis(gpio_num);
|
||||
break;
|
||||
case GPIO_PULLUP_PULLDOWN:
|
||||
gpio_pulldown_en(gpio_num);
|
||||
gpio_pullup_en(gpio_num);
|
||||
break;
|
||||
case GPIO_FLOATING:
|
||||
gpio_pulldown_dis(gpio_num);
|
||||
gpio_pullup_dis(gpio_num);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(GPIO_TAG, "Unknown pull up/down mode,gpio_num=%u,pull=%u", gpio_num, pull);
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -246,30 +220,30 @@ esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
|
||||
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) {
|
||||
ESP_LOGE(GPIO_TAG, "io_num=%d can only be input",gpio_num);
|
||||
if (gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) {
|
||||
ESP_LOGE(GPIO_TAG, "io_num=%d can only be input", gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
if(mode & GPIO_MODE_DEF_INPUT) {
|
||||
if (mode & GPIO_MODE_DEF_INPUT) {
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
} else {
|
||||
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
if(mode & GPIO_MODE_DEF_OUTPUT) {
|
||||
if(gpio_num < 32) {
|
||||
if (mode & GPIO_MODE_DEF_OUTPUT) {
|
||||
if (gpio_num < 32) {
|
||||
GPIO.enable_w1ts = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
} else {
|
||||
if(gpio_num < 32) {
|
||||
if (gpio_num < 32) {
|
||||
GPIO.enable_w1tc = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
if(mode & GPIO_MODE_DEF_OD) {
|
||||
if (mode & GPIO_MODE_DEF_OD) {
|
||||
GPIO.pin[gpio_num].pad_driver = 1;
|
||||
} else {
|
||||
GPIO.pin[gpio_num].pad_driver = 0;
|
||||
@ -287,53 +261,57 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig)
|
||||
uint8_t od_en = 0;
|
||||
uint8_t pu_en = 0;
|
||||
uint8_t pd_en = 0;
|
||||
if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) {
|
||||
if (pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) {
|
||||
ESP_LOGE(GPIO_TAG, "GPIO_PIN mask error ");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) {
|
||||
if ((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) {
|
||||
//GPIO 34/35/36/37/38/39 can only be used as input mode;
|
||||
if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) {
|
||||
if ((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) {
|
||||
ESP_LOGE(GPIO_TAG, "GPIO34-39 can only be used as input mode");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
do {
|
||||
io_reg = GPIO_PIN_MUX_REG[io_num];
|
||||
if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) {
|
||||
if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
|
||||
if (((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) {
|
||||
if(RTC_GPIO_IS_VALID_GPIO(io_num)){
|
||||
rtc_gpio_deinit(io_num);
|
||||
}
|
||||
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
|
||||
input_en = 1;
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]);
|
||||
} else {
|
||||
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]);
|
||||
}
|
||||
if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
|
||||
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
|
||||
od_en = 1;
|
||||
GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */
|
||||
} else {
|
||||
GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */
|
||||
}
|
||||
if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
|
||||
if ((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
|
||||
output_en = 1;
|
||||
gpio_matrix_out(io_num, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
gpio_output_enable(io_num);
|
||||
} else {
|
||||
gpio_output_disable(io_num);
|
||||
}
|
||||
if(pGPIOConfig->pull_up_en) {
|
||||
if (pGPIOConfig->pull_up_en) {
|
||||
pu_en = 1;
|
||||
REG_SET_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pu);
|
||||
gpio_pullup_en(io_num);
|
||||
} else {
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pu);
|
||||
gpio_pullup_dis(io_num);
|
||||
}
|
||||
if(pGPIOConfig->pull_down_en) {
|
||||
if (pGPIOConfig->pull_down_en) {
|
||||
pd_en = 1;
|
||||
REG_SET_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd);
|
||||
gpio_pulldown_en(io_num);
|
||||
} else {
|
||||
REG_CLR_BIT(gpio_pu_pd_desc[io_num].reg, gpio_pu_pd_desc[io_num].pd);
|
||||
gpio_pulldown_dis(io_num);
|
||||
}
|
||||
ESP_LOGI(GPIO_TAG, "GPIO[%d]| InputEn: %d| OutputEn: %d| OpenDrain: %d| Pullup: %d| Pulldown: %d| Intr:%d ", io_num, input_en, output_en, od_en, pu_en, pd_en, pGPIOConfig->intr_type);
|
||||
gpio_set_intr_type(io_num, pGPIOConfig->intr_type);
|
||||
if(pGPIOConfig->intr_type) {
|
||||
if (pGPIOConfig->intr_type) {
|
||||
gpio_intr_enable(io_num);
|
||||
} else {
|
||||
gpio_intr_disable(io_num);
|
||||
@ -341,18 +319,14 @@ esp_err_t gpio_config(gpio_config_t *pGPIOConfig)
|
||||
PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */
|
||||
}
|
||||
io_num++;
|
||||
} while(io_num < GPIO_PIN_COUNT);
|
||||
} while (io_num < GPIO_PIN_COUNT);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg)
|
||||
esp_err_t gpio_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, gpio_isr_handle_t *handle)
|
||||
{
|
||||
GPIO_CHECK(fn, "GPIO ISR null", ESP_ERR_INVALID_ARG);
|
||||
ESP_INTR_DISABLE(gpio_intr_num);
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, gpio_intr_num);
|
||||
xt_set_interrupt_handler(gpio_intr_num, fn, arg);
|
||||
ESP_INTR_ENABLE(gpio_intr_num);
|
||||
return ESP_OK;
|
||||
return esp_intr_alloc(ETS_GPIO_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
|
||||
}
|
||||
|
||||
/*only level interrupt can be used for wake-up function*/
|
||||
@ -360,11 +334,11 @@ esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
GPIO_CHECK(GPIO_IS_VALID_GPIO(gpio_num), "GPIO number error", ESP_ERR_INVALID_ARG);
|
||||
esp_err_t ret = ESP_OK;
|
||||
if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
|
||||
if ((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
|
||||
GPIO.pin[gpio_num].int_type = intr_type;
|
||||
GPIO.pin[gpio_num].wakeup_enable = 0x1;
|
||||
} else {
|
||||
ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u",gpio_num);
|
||||
ESP_LOGE(GPIO_TAG, "GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u", gpio_num);
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return ret;
|
||||
|
122
components/driver/include/driver/adc.h
Normal file
122
components/driver/include/driver/adc.h
Normal file
@ -0,0 +1,122 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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 _DRIVER_ADC_H_
|
||||
#define _DRIVER_ADC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
typedef enum {
|
||||
ADC_ATTEN_0db = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
|
||||
ADC_ATTEN_2_5db = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
|
||||
ADC_ATTEN_6db = 2, /*!<The input voltage of ADC will be reduced to about 1/2 */
|
||||
ADC_ATTEN_11db = 3, /*!<The input voltage of ADC will be reduced to about 1/3.6*/
|
||||
} adc_atten_t;
|
||||
|
||||
typedef enum {
|
||||
ADC_WIDTH_9Bit = 0, /*!< ADC capture width is 9Bit*/
|
||||
ADC_WIDTH_10Bit = 1, /*!< ADC capture width is 10Bit*/
|
||||
ADC_WIDTH_11Bit = 2, /*!< ADC capture width is 11Bit*/
|
||||
ADC_WIDTH_12Bit = 3, /*!< ADC capture width is 12Bit*/
|
||||
} adc_bits_width_t;
|
||||
|
||||
typedef enum {
|
||||
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */
|
||||
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 */
|
||||
ADC1_CHANNEL_2, /*!< ADC1 channel 2 is GPIO38 */
|
||||
ADC1_CHANNEL_3, /*!< ADC1 channel 3 is GPIO39 */
|
||||
ADC1_CHANNEL_4, /*!< ADC1 channel 4 is GPIO32 */
|
||||
ADC1_CHANNEL_5, /*!< ADC1 channel 5 is GPIO33 */
|
||||
ADC1_CHANNEL_6, /*!< ADC1 channel 6 is GPIO34 */
|
||||
ADC1_CHANNEL_7, /*!< ADC1 channel 7 is GPIO35 */
|
||||
ADC1_CHANNEL_MAX,
|
||||
} adc1_channel_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration ADC1 capture width.
|
||||
*
|
||||
* The configuration is in effect for all channels of ADC1
|
||||
*
|
||||
* @param width_bit ADC1
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
|
||||
|
||||
/**
|
||||
* @brief Configuration ADC1 capture attenuation of channels.
|
||||
*
|
||||
* @param channel the ADC1 channel
|
||||
* @param atten attenuation
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten);
|
||||
|
||||
/**
|
||||
* @brief ADC1 get the value of the voltage.
|
||||
*
|
||||
* @param channel the ADC1 channel
|
||||
*
|
||||
* @return
|
||||
* - -1 Parameter error
|
||||
* - Other the value of ADC1 channel
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @return the value of hall sensor
|
||||
*/
|
||||
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
|
||||
|
||||
#endif /*_DRIVER_ADC_H_*/
|
||||
|
57
components/driver/include/driver/dac.h
Normal file
57
components/driver/include/driver/dac.h
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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 _DRIVER_DAC_H_
|
||||
#define _DRIVER_DAC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
typedef enum {
|
||||
DAC_CHANNEL_1 = 1, /*!< DAC channel 1 is GPIO25 */
|
||||
DAC_CHANNEL_2, /*!< DAC channel 2 is GPIO26 */
|
||||
DAC_CHANNEL_MAX,
|
||||
} dac_channel_t;
|
||||
|
||||
/**
|
||||
* @brief Set Dac output voltage.
|
||||
*
|
||||
* Dac width is 8bit ,and the voltage max is vdd
|
||||
*
|
||||
* @param channel dac channel
|
||||
* @param dac_value dac output value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
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
|
||||
|
||||
#endif /*_DRIVER_DAC_H_*/
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -117,32 +118,6 @@ extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT];
|
||||
#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) //to decide whether it is a valid GPIO number
|
||||
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode
|
||||
|
||||
/**
|
||||
* @brief Pullup/pulldown information for a single GPIO pad
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t reg; /*!< Register to modify to enable or disable pullups or pulldowns */
|
||||
uint32_t pu; /*!< Bit to set or clear in the above register to enable or disable the pullup, respectively */
|
||||
uint32_t pd; /*!< Bit to set or clear in the above register to enable or disable the pulldown, respectively */
|
||||
} gpio_pu_pd_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
* Per-GPIO pullup/pulldown information
|
||||
* On the ESP32, some GPIOs need their pullups and pulldowns enabled and disabled in the RTC
|
||||
* peripheral instead of in the GPIO peripheral. This array documents for every GPIO what bit
|
||||
* to set or clear.
|
||||
*
|
||||
* This array is non-static, so if you need a very quick way of toggling the pull-up/downs, you can just
|
||||
* do e.g. REG_SET_BIT(gpio_pu_pd_desc[gpio_num].reg, gpio_pu_pd_desc[gpio_num].pu); inline.
|
||||
*
|
||||
* ToDo: Functions using the contents of this array will do a read/modify/write on GPIO as well as RTC
|
||||
* registers. We may need to look into muxes/locks for other code that accesses these RTC registers when we
|
||||
* write drivers for the RTC stuff.
|
||||
*/
|
||||
extern const gpio_pu_pd_desc_t gpio_pu_pd_desc[GPIO_PIN_COUNT];
|
||||
|
||||
|
||||
typedef enum {
|
||||
GPIO_NUM_0 = 0, /*!< GPIO0, input and output */
|
||||
GPIO_NUM_1 = 1, /*!< GPIO1, input and output */
|
||||
@ -229,6 +204,9 @@ typedef enum {
|
||||
GPIO_FLOATING, /*!< Pad floating */
|
||||
} gpio_pull_mode_t;
|
||||
|
||||
|
||||
|
||||
typedef intr_handle_t gpio_isr_handle_t;
|
||||
typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num);
|
||||
|
||||
/**
|
||||
@ -365,23 +343,19 @@ esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
|
||||
/**
|
||||
* @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.
|
||||
* @note
|
||||
* 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 gpio_intr_num GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param fn Interrupt handler function.
|
||||
*
|
||||
* @note
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success ;
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
*/
|
||||
esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg);
|
||||
esp_err_t gpio_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, gpio_isr_handle_t *handle);
|
||||
|
||||
|
||||
|
||||
@ -441,7 +415,7 @@ esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
|
||||
*/
|
||||
|
||||
/**
|
||||
*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
|
||||
*----------EXAMPLE TO CONFIGURE GPIO AS OUTPUT ------------ *
|
||||
* @code{c}
|
||||
* gpio_config_t io_conf;
|
||||
* io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
@ -454,7 +428,7 @@ esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
|
||||
**/
|
||||
|
||||
/**
|
||||
*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ *
|
||||
*----------EXAMPLE TO CONFIGURE GPIO AS OUTPUT ------------ *
|
||||
* @code{c}
|
||||
* io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
|
||||
* io_conf.mode = GPIO_MODE_INPUT; //set as input
|
||||
@ -467,13 +441,8 @@ esp_err_t gpio_pulldown_dis(gpio_num_t gpio_num);
|
||||
/**
|
||||
*----------EXAMPLE TO SET ISR HANDLER ----------------------
|
||||
* @code{c}
|
||||
* //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt
|
||||
* gpio_isr_register(gpio_intr_test, 0, NULL); //hook the isr handler for GPIO interrupt
|
||||
* @endcode
|
||||
* @note
|
||||
* 1. user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
|
||||
* 2. do not pick the INUM that already occupied by the system.
|
||||
* 3. refer to soc.h to check which INUMs that can be used.
|
||||
*/
|
||||
/**
|
||||
*-------------EXAMPLE OF HANDLER FUNCTION-------------------*
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -100,6 +101,7 @@ typedef struct {
|
||||
uint32_t freq_hz; /*!< LEDC timer frequency(Hz)*/
|
||||
} ledc_timer_config_t;
|
||||
|
||||
typedef intr_handle_t ledc_isr_handle_t;
|
||||
|
||||
/**
|
||||
* @brief LEDC channel configuration
|
||||
@ -257,20 +259,20 @@ esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty,
|
||||
/**
|
||||
* @brief register LEDC interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* 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 ledc_intr_num LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
*
|
||||
* @param fn Interrupt handler function.
|
||||
* @note
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @param arg User-supplied argument passed to the 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.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
*/
|
||||
esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg);
|
||||
esp_err_t ledc_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, ledc_isr_handle_t *handle);
|
||||
|
||||
/**
|
||||
* @brief configure LEDC settings
|
||||
@ -398,13 +400,8 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint
|
||||
* ----------------EXAMPLE OF LEDC INTERRUPT ------------------
|
||||
* @code{c}
|
||||
* //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here.
|
||||
* ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt
|
||||
* ledc_isr_register(ledc_isr_handler, NULL, 0); //hook the isr handler for LEDC interrupt
|
||||
* @endcode
|
||||
* @note
|
||||
* 1. the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* 2. user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
|
||||
* 3. do not pick the INUM that already occupied by the system.
|
||||
* 4. refer to soc.h to check which INUMs that can be used.
|
||||
*
|
||||
* ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
|
||||
* @code{c}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "soc/pcnt_struct.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -27,9 +28,9 @@ typedef enum {
|
||||
} pcnt_ctrl_mode_t;
|
||||
|
||||
typedef enum {
|
||||
PCNT_COUNT_DIS = 0, /*!< Counter mode: Decrease counter value*/
|
||||
PCNT_COUNT_DIS = 0, /*!< Counter mode: Inhibit counter(counter value will not change in this condition)*/
|
||||
PCNT_COUNT_INC = 1, /*!< Counter mode: Increase counter value*/
|
||||
PCNT_COUNT_DEC = 2, /*!< Counter mode: Inhibit counter(counter value will not change in this condition)*/
|
||||
PCNT_COUNT_DEC = 2, /*!< Counter mode: Decrease counter value*/
|
||||
PCNT_COUNT_MAX
|
||||
} pcnt_count_mode_t;
|
||||
|
||||
@ -45,7 +46,7 @@ typedef enum {
|
||||
PCNT_UNIT_MAX,
|
||||
} pcnt_unit_t;
|
||||
|
||||
typedef enum{
|
||||
typedef enum {
|
||||
PCNT_CHANNEL_0 = 0x00, /*!< PCNT channel0 */
|
||||
PCNT_CHANNEL_1 = 0x01, /*!< PCNT channel1 */
|
||||
PCNT_CHANNEL_MAX,
|
||||
@ -76,6 +77,8 @@ typedef struct {
|
||||
pcnt_channel_t channel; /*!< the PCNT channel */
|
||||
} pcnt_config_t;
|
||||
|
||||
typedef intr_handle_t pcnt_isr_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Configure Pulse Counter unit
|
||||
*
|
||||
@ -213,21 +216,19 @@ esp_err_t pcnt_get_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16
|
||||
/**
|
||||
* @brief Register PCNT interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* 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 pcnt_intr_num PCNT interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param fn Interrupt handler function.
|
||||
* @note
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @param arg Parameter for 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 handle Pointer to return handle. If non-NULL, a handle for the interrupt will
|
||||
* be returned here.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
*/
|
||||
esp_err_t pcnt_isr_register(uint32_t pcnt_intr_num, void (*fn)(void*), void * arg);
|
||||
esp_err_t pcnt_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, pcnt_isr_handle_t *handle);
|
||||
|
||||
/**
|
||||
* @brief Configure PCNT pulse signal input pin and control input pin
|
||||
|
@ -117,6 +117,8 @@ typedef struct {
|
||||
};
|
||||
} rmt_config_t;
|
||||
|
||||
typedef intr_handle_t rmt_isr_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Set RMT clock divider, channel clock is divided from source clock.
|
||||
*
|
||||
@ -566,27 +568,32 @@ esp_err_t rmt_config(rmt_config_t* rmt_param);
|
||||
* @brief register RMT interrupt handler, the handler is an ISR.
|
||||
*
|
||||
* The 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.
|
||||
* @note
|
||||
* If you already called rmt_driver_install to use system RMT driver,
|
||||
* @note If you already called rmt_driver_install to use system RMT driver,
|
||||
* please do not register ISR handler again.
|
||||
*
|
||||
* @param rmt_intr_num RMT interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
*
|
||||
* @param fn Interrupt handler function.
|
||||
*
|
||||
* @note
|
||||
* the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
*
|
||||
* @param arg Parameter for 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 handle If non-zero, a handle to later clean up the ISR gets stored here.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
* - ESP_FAIL System driver installed, can not register ISR handler for RMT
|
||||
*/
|
||||
esp_err_t rmt_isr_register(uint8_t rmt_intr_num, void (* fn)(void* ), void * arg);
|
||||
esp_err_t rmt_isr_register(void (* fn)(void* ), void * arg, int intr_alloc_flags, rmt_isr_handle_t *handle);
|
||||
|
||||
/**
|
||||
* @brief Deregister previously registered RMT interrupt handler
|
||||
*
|
||||
* @param handle Handle obtained from rmt_isr_register
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Handle invalid
|
||||
*/
|
||||
esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Fill memory data of channel with given RMT items.
|
||||
@ -727,7 +734,7 @@ esp_err_t rmt_get_ringbuf_handler(rmt_channel_t channel, RingbufHandle_t* buf_ha
|
||||
* rmt_config(&rmt_tx);
|
||||
*
|
||||
* //install system RMT driver, disable rx ringbuffer for transmitter.
|
||||
* rmt_driver_install(rmt_tx.channel, 0, RMT_INTR_NUM);
|
||||
* rmt_driver_install(rmt_tx.channel, 0, 0);
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
@ -747,25 +754,20 @@ esp_err_t rmt_get_ringbuf_handler(rmt_channel_t channel, RingbufHandle_t* buf_ha
|
||||
* rmt_config(&rmt_rx);
|
||||
*
|
||||
* //install system RMT driver.
|
||||
* rmt_driver_install(rmt_rx.channel, 1000, RMT_INTR_NUM);
|
||||
* rmt_driver_install(rmt_rx.channel, 1000, 0);
|
||||
* }
|
||||
*
|
||||
* ----------------EXAMPLE OF RMT INTERRUPT ------------------
|
||||
* @code{c}
|
||||
*
|
||||
* rmt_isr_register(RMT_INTR_NUM, rmt_isr, NULL); //hook the ISR handler for RMT interrupt
|
||||
* rmt_isr_register(rmt_isr, NULL, 0); //hook the ISR handler for RMT interrupt
|
||||
* @endcode
|
||||
* @note
|
||||
* 0. If you have called rmt_driver_install, you don't need to set ISR handler any more.
|
||||
* 1. the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* 2. user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
|
||||
* 3. do not pick the INUM that already occupied by the system.
|
||||
* 4. refer to soc.h to check which INUMs that can be used.
|
||||
*
|
||||
* ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
|
||||
* @code{c}
|
||||
* #include "esp_attr.h"
|
||||
* //we should add 'IRAM_ATTR' attribution when we declare the isr function
|
||||
* void IRAM_ATTR rmt_isr_handler(void* arg)
|
||||
* {
|
||||
* //read RMT interrupt status.
|
||||
|
188
components/driver/include/driver/rtc_io.h
Normal file
188
components/driver/include/driver/rtc_io.h
Normal file
@ -0,0 +1,188 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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 _DRIVER_RTC_GPIO_H_
|
||||
#define _DRIVER_RTC_GPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Pullup/pulldown information for a single GPIO pad
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t reg; /*!< Register of RTC pad, or 0 if not an RTC GPIO */
|
||||
uint32_t mux; /*!< Bit mask for selecting digital pad or RTC pad */
|
||||
uint32_t func; /*!< Shift of pad function (FUN_SEL) field */
|
||||
uint32_t ie; /*!< Mask of input enable */
|
||||
uint32_t pullup; /*!< Mask of pullup enable */
|
||||
uint32_t pulldown; /*!< Mask of pulldown enable */
|
||||
uint32_t slpsel; /*!< If slpsel bit is set, slpie will be used as pad input enabled signal in sleep mode */
|
||||
uint32_t slpie; /*!< Mask of input enable in sleep mode */
|
||||
uint32_t hold; /*!< Mask of hold_force bit for RTC IO in RTC_CNTL_HOLD_FORCE_REG */
|
||||
int rtc_num; /*!< RTC IO number, or -1 if not an RTC GPIO */
|
||||
} rtc_gpio_desc_t;
|
||||
|
||||
typedef enum {
|
||||
RTC_GPIO_MODE_INPUT_ONLY , /*!< Pad output */
|
||||
RTC_GPIO_MODE_OUTPUT_ONLY, /*!< Pad input */
|
||||
RTC_GPIO_MODE_INPUT_OUTUT, /*!< Pad pull output + input */
|
||||
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
|
||||
|
||||
extern const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT];
|
||||
|
||||
/**
|
||||
* @brief Init a GPIO as RTC GPIO
|
||||
*
|
||||
* This function must be called when initializing a pad for an analog function.
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_init(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Init a GPIO as digital GPIO
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Get the RTC IO input level
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - 1 High level
|
||||
* - 0 Low level
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
uint32_t rtc_gpio_get_level(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Set the RTC IO output level
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
* @param level output level
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level);
|
||||
|
||||
/**
|
||||
* @brief RTC GPIO set direction
|
||||
*
|
||||
* Configure RTC GPIO direction, such as output only, input only,
|
||||
* output and input.
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
* @param mode GPIO direction
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief RTC GPIO pullup enable
|
||||
*
|
||||
* This function only works for RTC IOs. In general, call gpio_pullup_en,
|
||||
* which will work both for normal GPIOs and RTC IOs.
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief RTC GPIO pulldown enable
|
||||
*
|
||||
* This function only works for RTC IOs. In general, call gpio_pulldown_en,
|
||||
* which will work both for normal GPIOs and RTC IOs.
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief RTC GPIO pullup disable
|
||||
*
|
||||
* This function only works for RTC IOs. In general, call gpio_pullup_dis,
|
||||
* which will work both for normal GPIOs and RTC IOs.
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief RTC GPIO pulldown disable
|
||||
*
|
||||
* This function only works for RTC IOs. In general, call gpio_pulldown_dis,
|
||||
* which will work both for normal GPIOs and RTC IOs.
|
||||
*
|
||||
* @param gpio_num GPIO number (e.g. GPIO_NUM_12)
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG GPIO is not an RTC IO
|
||||
*/
|
||||
esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Disable "hold" signal for all RTC IOs
|
||||
*
|
||||
* Each RTC pad has a "hold" input signal from the RTC controller.
|
||||
* If hold signal is set, pad latches current values of input enable,
|
||||
* function, output enable, and other signals which come from the RTC mux.
|
||||
* Hold signal is enabled before going into deep sleep for pins which
|
||||
* are used for EXT1 wakeup.
|
||||
*/
|
||||
void rtc_gpio_unhold_all();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
108
components/driver/include/driver/sigmadelta.h
Normal file
108
components/driver/include/driver/sigmadelta.h
Normal file
@ -0,0 +1,108 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// 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 __DRIVER_SIGMADELTA_H__
|
||||
#define __DRIVER_SIGMADELTA_H__
|
||||
#include <esp_types.h>
|
||||
#include "soc/gpio_sd_struct.h"
|
||||
#include "soc/gpio_sd_reg.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#ifdef _cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Sigma-delta channel list
|
||||
*/
|
||||
typedef enum{
|
||||
SIGMADELTA_CHANNEL_0 = 0, /*!< Sigma-delta channel0 */
|
||||
SIGMADELTA_CHANNEL_1 = 1, /*!< Sigma-delta channel1 */
|
||||
SIGMADELTA_CHANNEL_2 = 2, /*!< Sigma-delta channel2 */
|
||||
SIGMADELTA_CHANNEL_3 = 3, /*!< Sigma-delta channel3 */
|
||||
SIGMADELTA_CHANNEL_4 = 4, /*!< Sigma-delta channel4 */
|
||||
SIGMADELTA_CHANNEL_5 = 5, /*!< Sigma-delta channel5 */
|
||||
SIGMADELTA_CHANNEL_6 = 6, /*!< Sigma-delta channel6 */
|
||||
SIGMADELTA_CHANNEL_7 = 7, /*!< Sigma-delta channel7 */
|
||||
SIGMADELTA_CHANNEL_MAX,
|
||||
} sigmadelta_channel_t;
|
||||
|
||||
/**
|
||||
* @brief Sigma-delta configure struct
|
||||
*/
|
||||
typedef struct {
|
||||
sigmadelta_channel_t channel; /*!< Sigma-delta channel number */
|
||||
int8_t sigmadelta_duty; /*!< Sigma-delta duty, duty ranges from -128 to 127. */
|
||||
uint8_t sigmadelta_prescale; /*!< Sigma-delta prescale, prescale ranges from 0 to 255. */
|
||||
uint8_t sigmadelta_gpio; /*!< Sigma-delta output io number, refer to gpio.h for more details. */
|
||||
} sigmadelta_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure Sigma-delta channel
|
||||
*
|
||||
* @param config Pointer of Sigma-delta channel configuration struct
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t sigmadelta_config(sigmadelta_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta channel duty.
|
||||
*
|
||||
* This function is used to set Sigma-delta channel duty,
|
||||
* If you add a capacitor between the output pin and ground,
|
||||
* the average output voltage Vdc = VDDIO / 256 * duty + VDDIO/2, VDDIO is power supply voltage.
|
||||
*
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param duty Sigma-delta duty of one channel, the value ranges from -128 to 127, recommended range is -90 ~ 90.
|
||||
* The waveform is more like a random one in this range.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t sigmadelta_set_duty(sigmadelta_channel_t channel, int8_t duty);
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta channel's clock pre-scale value.
|
||||
* The source clock is APP_CLK, 80MHz. The clock frequency of the sigma-delta channel is APP_CLK / pre_scale
|
||||
*
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param prescale The divider of source clock, ranges from 0 to 255
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t sigmadelta_set_prescale(sigmadelta_channel_t channel, uint8_t prescale);
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta signal output pin
|
||||
*
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param gpio_num GPIO number of output pin.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t sigmadelta_set_pin(sigmadelta_channel_t channel, gpio_num_t gpio_num);
|
||||
|
||||
#ifdef _cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
#include "soc/soc.h"
|
||||
#include "soc/timer_group_reg.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -94,12 +95,19 @@ typedef enum {
|
||||
typedef struct {
|
||||
bool alarm_en; /*!< Timer alarm enable */
|
||||
bool counter_en; /*!< Counter enable */
|
||||
timer_count_dir_t counter_dir; /*!< Counter direction */
|
||||
timer_intr_mode_t intr_type; /*!< Interrupt mode */
|
||||
timer_count_dir_t counter_dir; /*!< Counter direction */
|
||||
bool auto_reload; /*!< Timer auto-reload */
|
||||
uint16_t divider; /*!< Counter clock divider*/
|
||||
} timer_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interrupt handle, used in order to free the isr after use.
|
||||
* Aliases to an int handle for now.
|
||||
*/
|
||||
typedef intr_handle_t timer_isr_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Read the counter value of hardware timer.
|
||||
*
|
||||
@ -245,21 +253,20 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_
|
||||
/**
|
||||
* @brief register Timer interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @note
|
||||
* 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 group_num Timer group number
|
||||
* @param timer_num Timer index of timer group
|
||||
* @param timer_intr_num TIMER interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param intr_type Timer interrupt type
|
||||
* @param fn Interrupt handler function.
|
||||
* @note
|
||||
* Code inside the handler function can only call functions in IRAM, so cannot call other timer APIs.
|
||||
* Use direct register access to access timers from inside the ISR.
|
||||
* In case the this is called with the INIRAM flag, code inside the handler function can
|
||||
* only call functions in IRAM, so it cannot call other timer APIs.
|
||||
* Use direct register access to access timers from inside the ISR in this case.
|
||||
*
|
||||
* @param arg Parameter for 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 handle Pointer to return handle. If non-NULL, a handle for the interrupt will
|
||||
* be returned here.
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Function pointer error.
|
||||
@ -268,7 +275,7 @@ esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Parameter error
|
||||
*/
|
||||
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, int timer_intr_num, timer_intr_mode_t intr_type, void (*fn)(void*), void * arg);
|
||||
esp_err_t timer_isr_register(timer_group_t group_num, timer_idx_t timer_num, void (*fn)(void*), void * arg, int intr_alloc_flags, timer_isr_handle_t *handle);
|
||||
|
||||
/** @brief Initializes and configure the timer.
|
||||
*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user