diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 703e011c35..065b0512a6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -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 + diff --git a/README.md b/README.md index c01e314f11..f3007fdb88 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 0c1a413370..e95937256f 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -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; } diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 50165d0e58..798fcf0b23 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -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 \ No newline at end of file diff --git a/components/bootloader/Makefile.projbuild b/components/bootloader/Makefile.projbuild index a49f3d8686..35be94e4a3 100644 --- a/components/bootloader/Makefile.projbuild +++ b/components/bootloader/Makefile.projbuild @@ -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 diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index 4559d5f816..d097083d2a 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -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 { diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index 8dd163fe33..7dd753b3f8 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -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 +} diff --git a/components/bootloader/src/main/component.mk b/components/bootloader/src/main/component.mk index 01b07b9498..e98545fc47 100644 --- a/components/bootloader/src/main/component.mk +++ b/components/bootloader/src/main/component.mk @@ -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) diff --git a/components/bootloader/src/main/flash_encrypt.c b/components/bootloader/src/main/flash_encrypt.c deleted file mode 100644 index 2b1479097d..0000000000 --- a/components/bootloader/src/main/flash_encrypt.c +++ /dev/null @@ -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 - -#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 ��test bin (if use)��ota bin - * ��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; - } -} diff --git a/components/bootloader_support/Makefile.projbuild b/components/bootloader_support/Makefile.projbuild new file mode 100644 index 0000000000..ee62930c60 --- /dev/null +++ b/components/bootloader_support/Makefile.projbuild @@ -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 diff --git a/components/bootloader_support/component.mk b/components/bootloader_support/component.mk index a7e5b849dc..6db815afff 100755 --- a/components/bootloader_support/component.mk +++ b/components/bootloader_support/component.mk @@ -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) diff --git a/components/bootloader_support/include/esp_efuse.h b/components/bootloader_support/include/esp_efuse.h new file mode 100644 index 0000000000..41588396c4 --- /dev/null +++ b/components/bootloader_support/include/esp_efuse.h @@ -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 */ + diff --git a/components/bootloader_support/include/esp_flash_encrypt.h b/components/bootloader_support/include/esp_flash_encrypt.h new file mode 100644 index 0000000000..015dea030a --- /dev/null +++ b/components/bootloader_support/include/esp_flash_encrypt.h @@ -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 +#include +#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 diff --git a/components/bootloader_support/include/esp_flash_partitions.h b/components/bootloader_support/include/esp_flash_partitions.h new file mode 100644 index 0000000000..63ee822126 --- /dev/null +++ b/components/bootloader_support/include/esp_flash_partitions.h @@ -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 + +/* 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 diff --git a/components/bootloader_support/include/esp_image_format.h b/components/bootloader_support/include/esp_image_format.h index a32a50a4a5..e0759c3c0e 100644 --- a/components/bootloader_support/include/esp_image_format.h +++ b/components/bootloader_support/include/esp_image_format.h @@ -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 { diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index f9fc57708d..8e33a8b460 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -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 diff --git a/components/bootloader_support/include_priv/bootloader_flash.h b/components/bootloader_support/include_priv/bootloader_flash.h index 769c47b904..763136e03c 100644 --- a/components/bootloader_support/include_priv/bootloader_flash.h +++ b/components/bootloader_support/include_priv/bootloader_flash.h @@ -18,6 +18,9 @@ #include #include #include +#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 diff --git a/components/bootloader_support/include_priv/bootloader_random.h b/components/bootloader_support/include_priv/bootloader_random.h new file mode 100644 index 0000000000..86d42e31d9 --- /dev/null +++ b/components/bootloader_support/include_priv/bootloader_random.h @@ -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 + +/** + * @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); diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index 3fd107dea8..405da732b3 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -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 #include #include 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 diff --git a/components/bootloader_support/src/bootloader_random.c b/components/bootloader_support/src/bootloader_random.c new file mode 100644 index 0000000000..fd780c4b7b --- /dev/null +++ b/components/bootloader_support/src/bootloader_random.c @@ -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); + } +} diff --git a/components/bootloader_support/src/efuse.c b/components/bootloader_support/src/efuse.c new file mode 100644 index 0000000000..e90ba1b7f6 --- /dev/null +++ b/components/bootloader_support/src/efuse.c @@ -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); + } + } +} diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index ca75f6ae45..8b156680c6 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -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; } diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c new file mode 100644 index 0000000000..f4fd7e783d --- /dev/null +++ b/components/bootloader_support/src/flash_encrypt.c @@ -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 + +#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; +} diff --git a/components/bootloader_support/src/flash_partitions.c b/components/bootloader_support/src/flash_partitions.c new file mode 100644 index 0000000000..ed427df1a6 --- /dev/null +++ b/components/bootloader_support/src/flash_partitions.c @@ -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; +} + diff --git a/components/bootloader_support/src/secure_boot.c b/components/bootloader_support/src/secure_boot.c index d908d39c38..c5ae1f19ea 100644 --- a/components/bootloader_support/src/secure_boot.c +++ b/components/bootloader_support/src/secure_boot.c @@ -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(); diff --git a/components/bootloader_support/src/secure_boot_signatures.c b/components/bootloader_support/src/secure_boot_signatures.c index 076dfb335c..3ca2f2e919 100644 --- a/components/bootloader_support/src/secure_boot_signatures.c +++ b/components/bootloader_support/src/secure_boot_signatures.c @@ -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); diff --git a/components/bt/Kconfig b/components/bt/Kconfig index c2f8a86504..9a8014fa66 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -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 diff --git a/components/bt/bluedroid/api/esp_gap_ble_api.c b/components/bt/bluedroid/api/esp_gap_ble_api.c index ebe1d81947..0770fcfed5 100644 --- a/components/bt/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/bluedroid/api/esp_gap_ble_api.c @@ -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; diff --git a/components/bt/bluedroid/api/esp_gattc_api.c b/components/bt/bluedroid/api/esp_gattc_api.c index 3c17f73371..c856947f01 100644 --- a/components/bt/bluedroid/api/esp_gattc_api.c +++ b/components/bt/bluedroid/api/esp_gattc_api.c @@ -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)); diff --git a/components/bt/bluedroid/api/include/esp_blufi_api.h b/components/bt/bluedroid/api/include/esp_blufi_api.h index b8ba382d0e..609d9c1c59 100644 --- a/components/bt/bluedroid/api/include/esp_blufi_api.h +++ b/components/bt/bluedroid/api/include/esp_blufi_api.h @@ -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_ */ diff --git a/components/bt/bluedroid/api/include/esp_bt_defs.h b/components/bt/bluedroid/api/include/esp_bt_defs.h index a19d89e856..65de8df5ee 100644 --- a/components/bt/bluedroid/api/include/esp_bt_defs.h +++ b/components/bt/bluedroid/api/include/esp_bt_defs.h @@ -18,6 +18,10 @@ #include #include +#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__ */ diff --git a/components/bt/bluedroid/api/include/esp_bt_main.h b/components/bt/bluedroid/api/include/esp_bt_main.h index 2bb7b8977b..859da092dd 100644 --- a/components/bt/bluedroid/api/include/esp_bt_main.h +++ b/components/bt/bluedroid/api/include/esp_bt_main.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__ */ diff --git a/components/bt/bluedroid/api/include/esp_gap_ble_api.h b/components/bt/bluedroid/api/include/esp_gap_ble_api.h index 29ffbe38ff..d01595d595 100644 --- a/components/bt/bluedroid/api/include/esp_gap_ble_api.h +++ b/components/bt/bluedroid/api/include/esp_gap_ble_api.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__ */ diff --git a/components/bt/bluedroid/api/include/esp_gatt_defs.h b/components/bt/bluedroid/api/include/esp_gatt_defs.h index 479be983b7..931733e402 100644 --- a/components/bt/bluedroid/api/include/esp_gatt_defs.h +++ b/components/bt/bluedroid/api/include/esp_gatt_defs.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__ */ diff --git a/components/bt/bluedroid/api/include/esp_gattc_api.h b/components/bt/bluedroid/api/include/esp_gattc_api.h old mode 100755 new mode 100644 index 4cf5113eb1..4407975a0d --- a/components/bt/bluedroid/api/include/esp_gattc_api.h +++ b/components/bt/bluedroid/api/include/esp_gattc_api.h @@ -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__ */ diff --git a/components/bt/bluedroid/api/include/esp_gatts_api.h b/components/bt/bluedroid/api/include/esp_gatts_api.h index 3d858d5b7e..30aa3ecf56 100644 --- a/components/bt/bluedroid/api/include/esp_gatts_api.h +++ b/components/bt/bluedroid/api/include/esp_gatts_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__ */ diff --git a/components/bt/bluedroid/bta/av/bta_av_aact.c b/components/bt/bluedroid/bta/av/bta_av_aact.c index d3f813aebe..a47d7d3320 100755 --- a/components/bt/bluedroid/bta/av/bta_av_aact.c +++ b/components/bt/bluedroid/bta/av/bta_av_aact.c @@ -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); diff --git a/components/bt/bluedroid/bta/dm/bta_dm_act.c b/components/bt/bluedroid/bta/dm/bta_dm_act.c index 155602fac7..67af7f03bf 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_act.c @@ -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) { diff --git a/components/bt/bluedroid/bta/dm/bta_dm_api.c b/components/bt/bluedroid/bta/dm/bta_dm_api.c index d218911903..1709880555 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_api.c @@ -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(); diff --git a/components/bt/bluedroid/bta/dm/bta_dm_pm.c b/components/bt/bluedroid/bta/dm/bta_dm_pm.c index 1acb0f46ce..10521ee075 100644 --- a/components/bt/bluedroid/bta/dm/bta_dm_pm.c +++ b/components/bt/bluedroid/bta/dm/bta_dm_pm.c @@ -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; diff --git a/components/bt/bluedroid/bta/sdp/bta_sdp_act.c b/components/bt/bluedroid/bta/sdp/bta_sdp_act.c index 944a3ee213..1281b50ab2 100644 --- a/components/bt/bluedroid/bta/sdp/bta_sdp_act.c +++ b/components/bt/bluedroid/bta/sdp/bta_sdp_act.c @@ -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; diff --git a/components/bt/bluedroid/bta/sys/bta_sys_main.c b/components/bt/bluedroid/bta/sys/bta_sys_main.c index ca8e26ad0c..56c1d051f5 100644 --- a/components/bt/bluedroid/bta/sys/bta_sys_main.c +++ b/components/bt/bluedroid/bta/sys/bta_sys_main.c @@ -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) diff --git a/components/bt/bluedroid/btc/core/btc_main.c b/components/bt/bluedroid/btc/core/btc_main.c index 2ca4b5b39b..6fae3af435 100644 --- a/components/bt/bluedroid/btc/core/btc_main.c +++ b/components/bt/bluedroid/btc/core/btc_main.c @@ -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); } diff --git a/components/bt/bluedroid/btc/core/btc_task.c b/components/bt/bluedroid/btc/core/btc_task.c index 842fdd10fe..b4ce0d95ca 100644 --- a/components/bt/bluedroid/btc/core/btc_task.c +++ b/components/bt/bluedroid/btc/core/btc_task.c @@ -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); diff --git a/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c b/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c index c869c0b0f7..8acb9565c8 100644 --- a/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c +++ b/components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c @@ -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) diff --git a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c index ba9e962238..f458cb4ced 100644 --- a/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -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); diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatt_util.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatt_util.c index c19ace2f78..938d2dc409 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatt_util.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatt_util.c @@ -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; diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c index 92cd5001db..b5da7ed249 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c @@ -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; } diff --git a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c index 8a844f6258..8ef1e9aefd 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c +++ b/components/bt/bluedroid/btc/profile/std/gatt/btc_gatts.c @@ -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 diff --git a/components/bt/bluedroid/btc/profile/std/gatt/include/btc_gatt_util.h b/components/bt/bluedroid/btc/profile/std/gatt/include/btc_gatt_util.h index 1fa7b59f50..540e118d59 100644 --- a/components/bt/bluedroid/btc/profile/std/gatt/include/btc_gatt_util.h +++ b/components/bt/bluedroid/btc/profile/std/gatt/include/btc_gatt_util.h @@ -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); diff --git a/components/bt/bluedroid/btif/btif_avk.c b/components/bt/bluedroid/btif/btif_avk.c index e14cdfd86c..2ce6b481f1 100644 --- a/components/bt/bluedroid/btif/btif_avk.c +++ b/components/bt/bluedroid/btif/btif_avk.c @@ -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; } /******************************************************************************* diff --git a/components/bt/bluedroid/btif/btif_media_task.c b/components/bt/bluedroid/btif/btif_media_task.c index 99c4711887..f7b552cf1f 100644 --- a/components/bt/bluedroid/btif/btif_media_task.c +++ b/components/bt/bluedroid/btif/btif_media_task.c @@ -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 diff --git a/components/bt/bluedroid/btif/btif_profile_queue.c b/components/bt/bluedroid/btif/btif_profile_queue.c index 2b445279fc..fb6aa5f430 100644 --- a/components/bt/bluedroid/btif/btif_profile_queue.c +++ b/components/bt/bluedroid/btif/btif_profile_queue.c @@ -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); } diff --git a/components/bt/bluedroid/device/include/interop_database.h b/components/bt/bluedroid/device/include/interop_database.h index 7bc2e8875f..5b9bc934a7 100644 --- a/components/bt/bluedroid/device/include/interop_database.h +++ b/components/bt/bluedroid/device/include/interop_database.h @@ -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_*/ diff --git a/components/bt/bluedroid/gki/gki_buffer.c b/components/bt/bluedroid/gki/gki_buffer.c index 9ae20df903..bb7ccd17db 100644 --- a/components/bt/bluedroid/gki/gki_buffer.c +++ b/components/bt/bluedroid/gki/gki_buffer.c @@ -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 diff --git a/components/bt/bluedroid/gki/include/gki.h b/components/bt/bluedroid/gki/include/gki.h index 9efd211991..4e5f3c2b61 100644 --- a/components/bt/bluedroid/gki/include/gki.h +++ b/components/bt/bluedroid/gki/include/gki.h @@ -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 */ diff --git a/components/bt/bluedroid/hci/hci_layer.c b/components/bt/bluedroid/hci/hci_layer.c index 8fc55d08d3..cafd794942 100644 --- a/components/bt/bluedroid/hci/hci_layer.c +++ b/components/bt/bluedroid/hci/hci_layer.c @@ -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) { diff --git a/components/bt/bluedroid/main/bte_main.c b/components/bt/bluedroid/main/bte_main.c index 1cb3f31004..1ca3946d62 100644 --- a/components/bt/bluedroid/main/bte_main.c +++ b/components/bt/bluedroid/main/bte_main.c @@ -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(); } /****************************************************************************** diff --git a/components/bt/bluedroid/osi/alarm.c b/components/bt/bluedroid/osi/alarm.c index 7eed98e7c6..1815705d59 100644 --- a/components/bt/bluedroid/osi/alarm.c +++ b/components/bt/bluedroid/osi/alarm.c @@ -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); } diff --git a/components/bt/bluedroid/osi/allocator.c b/components/bt/bluedroid/osi/allocator.c index ded28f2a31..9dc3ee910d 100644 --- a/components/bt/bluedroid/osi/allocator.c +++ b/components/bt/bluedroid/osi/allocator.c @@ -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 }; diff --git a/components/bt/bluedroid/osi/future.c b/components/bt/bluedroid/osi/future.c index b2dc404659..23c207f4df 100644 --- a/components/bt/bluedroid/osi/future.c +++ b/components/bt/bluedroid/osi/future.c @@ -16,22 +16,13 @@ * ******************************************************************************/ -// #define LOG_TAG "bt_osi_future" -// #include #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); } diff --git a/components/bt/bluedroid/osi/include/allocator.h b/components/bt/bluedroid/osi/include/allocator.h index d7df1f2053..17a3a24634 100644 --- a/components/bt/bluedroid/osi/include/allocator.h +++ b/components/bt/bluedroid/osi/include/allocator.h @@ -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_ */ diff --git a/components/bt/bluedroid/osi/include/future.h b/components/bt/bluedroid/osi/include/future.h index d4601a93f1..d54f237851 100644 --- a/components/bt/bluedroid/osi/include/future.h +++ b/components/bt/bluedroid/osi/include/future.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) diff --git a/components/bt/bluedroid/osi/include/thread.h b/components/bt/bluedroid/osi/include/thread.h index f29a525d81..c9bd3c6db4 100644 --- a/components/bt/bluedroid/osi/include/thread.h +++ b/components/bt/bluedroid/osi/include/thread.h @@ -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 diff --git a/components/bt/bluedroid/stack/avct/avct_lcb.c b/components/bt/bluedroid/stack/avct/avct_lcb.c index eabb8aa2b7..2c5e316a31 100755 --- a/components/bt/bluedroid/stack/avct/avct_lcb.c +++ b/components/bt/bluedroid/stack/avct/avct_lcb.c @@ -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)) { diff --git a/components/bt/bluedroid/stack/avdt/avdt_api.c b/components/bt/bluedroid/stack/avdt/avdt_api.c index 029c891a88..8c274f32c6 100755 --- a/components/bt/bluedroid/stack/avdt/avdt_api.c +++ b/components/bt/bluedroid/stack/avdt/avdt_api.c @@ -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; } diff --git a/components/bt/bluedroid/stack/avdt/avdt_scb_act.c b/components/bt/bluedroid/stack/avdt/avdt_scb_act.c index fa57f0f2a0..eb2227c6be 100755 --- a/components/bt/bluedroid/stack/avdt/avdt_scb_act.c +++ b/components/bt/bluedroid/stack/avdt/avdt_scb_act.c @@ -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 */ } diff --git a/components/bt/bluedroid/stack/btm/btm_ble.c b/components/bt/bluedroid/stack/btm/btm_ble.c index 4e1f151957..17f1d43e24 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble.c +++ b/components/bt/bluedroid/stack/btm/btm_ble.c @@ -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", diff --git a/components/bt/bluedroid/stack/btm/btm_ble_adv_filter.c b/components/bt/bluedroid/stack/btm/btm_ble_adv_filter.c index 1190643f32..78b4a8ed2c 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_adv_filter.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_adv_filter.c @@ -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) diff --git a/components/bt/bluedroid/stack/btm/btm_ble_bgconn.c b/components/bt/bluedroid/stack/btm/btm_ble_bgconn.c index af89677ee2..e846ef5b92 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_bgconn.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_bgconn.c @@ -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); } } diff --git a/components/bt/bluedroid/stack/btm/btm_ble_cont_energy.c b/components/bt/bluedroid/stack/btm/btm_ble_cont_energy.c index 5a9629d875..7125100749 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_cont_energy.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_cont_energy.c @@ -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) diff --git a/components/bt/bluedroid/stack/btm/btm_ble_gap.c b/components/bt/bluedroid/stack/btm/btm_ble_gap.c index b7311dfd63..4ded30de83 100644 --- a/components/bt/bluedroid/stack/btm/btm_ble_gap.c +++ b/components/bt/bluedroid/stack/btm/btm_ble_gap.c @@ -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(); } diff --git a/components/bt/bluedroid/stack/btm/btm_dev.c b/components/bt/bluedroid/stack/btm/btm_dev.c index 72a1739025..fc78e1e1bf 100644 --- a/components/bt/bluedroid/stack/btm/btm_dev.c +++ b/components/bt/bluedroid/stack/btm/btm_dev.c @@ -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__); diff --git a/components/bt/bluedroid/stack/btm/btm_devctl.c b/components/bt/bluedroid/stack/btm/btm_devctl.c index 91851decc2..fe5fca55cc 100644 --- a/components/bt/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/bluedroid/stack/btm/btm_devctl.c @@ -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 */ diff --git a/components/bt/bluedroid/stack/btm/btm_sec.c b/components/bt/bluedroid/stack/btm/btm_sec.c index c0eee569d6..364c03f624 100644 --- a/components/bt/bluedroid/stack/btm/btm_sec.c +++ b/components/bt/bluedroid/stack/btm/btm_sec.c @@ -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 diff --git a/components/bt/bluedroid/stack/btu/btu_init.c b/components/bt/bluedroid/stack/btu/btu_init.c index 150073c005..0f13e318a4 100644 --- a/components/bt/bluedroid/stack/btu/btu_init.c +++ b/components/bt/bluedroid/stack/btu/btu_init.c @@ -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); diff --git a/components/bt/bluedroid/stack/btu/btu_task.c b/components/bt/bluedroid/stack/btu/btu_task.c index f6f6aeb64f..8aaeb2492d 100644 --- a/components/bt/bluedroid/stack/btu/btu_task.c +++ b/components/bt/bluedroid/stack/btu/btu_task.c @@ -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); diff --git a/components/bt/bluedroid/stack/gap/gap_conn.c b/components/bt/bluedroid/stack/gap/gap_conn.c index 5ae8a81dc9..7f5e0be39f 100644 --- a/components/bt/bluedroid/stack/gap/gap_conn.c +++ b/components/bt/bluedroid/stack/gap/gap_conn.c @@ -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++) { diff --git a/components/bt/bluedroid/stack/gatt/gatt_attr.c b/components/bt/bluedroid/stack/gatt/gatt_attr.c index b0aa3f71d1..4968828394 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_attr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_attr.c @@ -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) { diff --git a/components/bt/bluedroid/stack/gatt/gatt_cl.c b/components/bt/bluedroid/stack/gatt/gatt_cl.c index 095b87deee..fab35d5f03 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_cl.c +++ b/components/bt/bluedroid/stack/gatt/gatt_cl.c @@ -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); } } diff --git a/components/bt/bluedroid/stack/gatt/gatt_sr.c b/components/bt/bluedroid/stack/gatt/gatt_sr.c index 49ad3a2305..4846d4ad3e 100644 --- a/components/bt/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/bluedroid/stack/gatt/gatt_sr.c @@ -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); } diff --git a/components/bt/bluedroid/stack/l2cap/l2c_api.c b/components/bt/bluedroid/stack/l2cap/l2c_api.c index 6aef4afc08..156757d01d 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_api.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_api.c @@ -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); diff --git a/components/bt/bluedroid/stack/l2cap/l2c_ble.c b/components/bt/bluedroid/stack/l2cap/l2c_ble.c index 3888feb47e..70d2ba75a8 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_ble.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_ble.c @@ -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) { diff --git a/components/bt/bluedroid/stack/l2cap/l2c_fcr.c b/components/bt/bluedroid/stack/l2cap/l2c_fcr.c index 4ce718f3b0..788d841e15 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_fcr.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_fcr.c @@ -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 */ diff --git a/components/bt/bluedroid/stack/l2cap/l2c_link.c b/components/bt/bluedroid/stack/l2cap/l2c_link.c index e97b13ec8c..ed1787c426 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_link.c @@ -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; diff --git a/components/bt/bluedroid/stack/l2cap/l2c_utils.c b/components/bt/bluedroid/stack/l2cap/l2c_utils.c index 7c5bd8d206..e910d3cfb7 100644 --- a/components/bt/bluedroid/stack/l2cap/l2c_utils.c +++ b/components/bt/bluedroid/stack/l2cap/l2c_utils.c @@ -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) { diff --git a/components/bt/bluedroid/stack/sdp/sdp_api.c b/components/bt/bluedroid/stack/sdp/sdp_api.c index 241fb9598c..1f5715913d 100644 --- a/components/bt/bluedroid/stack/sdp/sdp_api.c +++ b/components/bt/bluedroid/stack/sdp/sdp_api.c @@ -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 /******************************************************************************* ** diff --git a/components/bt/bluedroid/stack/sdp/sdp_db.c b/components/bt/bluedroid/stack/sdp/sdp_db.c index 264a0d25cf..2d3308ebfe 100644 --- a/components/bt/bluedroid/stack/sdp/sdp_db.c +++ b/components/bt/bluedroid/stack/sdp/sdp_db.c @@ -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; diff --git a/components/bt/bluedroid/stack/smp/smp_cmac.c b/components/bt/bluedroid/stack/smp/smp_cmac.c index 21939435dd..46f6ab73ea 100644 --- a/components/bt/bluedroid/stack/smp/smp_cmac.c +++ b/components/bt/bluedroid/stack/smp/smp_cmac.c @@ -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", diff --git a/components/bt/component.mk b/components/bt/component.mk index ae5c721579..a0ddd598f5 100644 --- a/components/bt/component.mk +++ b/components/bt/component.mk @@ -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 diff --git a/components/driver/gpio.c b/components/driver/gpio.c index d5d4d9d40a..1a38620dbb 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -14,17 +14,20 @@ #include #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; diff --git a/components/driver/include/driver/adc.h b/components/driver/include/driver/adc.h new file mode 100644 index 0000000000..56bdbc1790 --- /dev/null +++ b/components/driver/include/driver/adc.h @@ -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 +#include "esp_err.h" + +typedef enum { + ADC_ATTEN_0db = 0, /*! +#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_*/ + diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index de34ac4e35..83d3806834 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.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-------------------* diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h index e07787b2b1..fb97c6c011 100644 --- a/components/driver/include/driver/ledc.h +++ b/components/driver/include/driver/ledc.h @@ -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} diff --git a/components/driver/include/driver/pcnt.h b/components/driver/include/driver/pcnt.h index deff781839..f5a10581c0 100644 --- a/components/driver/include/driver/pcnt.h +++ b/components/driver/include/driver/pcnt.h @@ -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 diff --git a/components/driver/include/driver/rmt.h b/components/driver/include/driver/rmt.h index 50a5c743dd..24df1ac8ed 100644 --- a/components/driver/include/driver/rmt.h +++ b/components/driver/include/driver/rmt.h @@ -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. diff --git a/components/driver/include/driver/rtc_io.h b/components/driver/include/driver/rtc_io.h new file mode 100644 index 0000000000..3fc3287646 --- /dev/null +++ b/components/driver/include/driver/rtc_io.h @@ -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 +#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 diff --git a/components/driver/include/driver/sigmadelta.h b/components/driver/include/driver/sigmadelta.h new file mode 100644 index 0000000000..db167837b8 --- /dev/null +++ b/components/driver/include/driver/sigmadelta.h @@ -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 +#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 diff --git a/components/driver/include/driver/timer.h b/components/driver/include/driver/timer.h index c0ad7116e4..134fd504fb 100644 --- a/components/driver/include/driver/timer.h +++ b/components/driver/include/driver/timer.h @@ -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. * diff --git a/components/driver/include/driver/touch_pad.h b/components/driver/include/driver/touch_pad.h new file mode 100644 index 0000000000..4f78b2351b --- /dev/null +++ b/components/driver/include/driver/touch_pad.h @@ -0,0 +1,160 @@ +// 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_TOUCH_PAD_H_ +#define _DRIVER_TOUCH_PAD_H_ +#ifdef __cplusplus +extern "C" { +#endif +#include "esp_intr.h" +#include "esp_err.h" +#include "esp_intr_alloc.h" +#define TOUCH_PAD_SLEEP_CYCLE_CONFIG (0x1000)//The Time is 150Khz,the Max value is 0xffff +#define TOUCH_PAD_MEASURE_CYCLE_CONFIG (0xffff)//The Time is 8Mhz,the Max value is 0xffff +typedef enum { + TOUCH_PAD_NUM0 = 0, /*!< Touch pad channel 0 is GPIO4 */ + TOUCH_PAD_NUM1, /*!< Touch pad channel 0 is GPIO0 */ + TOUCH_PAD_NUM2, /*!< Touch pad channel 0 is GPIO2 */ + TOUCH_PAD_NUM3, /*!< Touch pad channel 0 is GPIO15 */ + TOUCH_PAD_NUM4, /*!< Touch pad channel 0 is GPIO13 */ + TOUCH_PAD_NUM5, /*!< Touch pad channel 0 is GPIO12 */ + TOUCH_PAD_NUM6, /*!< Touch pad channel 0 is GPIO14 */ + TOUCH_PAD_NUM7, /*!< Touch pad channel 0 is GPIO27*/ + TOUCH_PAD_NUM8, /*!< Touch pad channel 0 is GPIO33*/ + TOUCH_PAD_NUM9, /*!< Touch pad channel 0 is GPIO32*/ + TOUCH_PAD_MAX, +} touch_pad_t; + +typedef intr_handle_t touch_isr_handle_t; + +/** + * @brief Initialize touch module. + * + *This function int touch pad module ,enable touch module + * + * @return None + * + */ +void touch_pad_init(); + +/** + * @brief Configure touch pad interrupt threshold. + * + * + * @param[in] touch_num : config touch num + * + * @param[in] threshold : interrupt threshold ,When the touch_pad_register less than threshold, + * will trigger the touch interrupt.User can use touch_pad_read function + * to determine the threshold. + * + * @return - ESP_OK Success + * - ESP_ERR_INVALID_ARG Touch pad error + * + */ +esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold); + +/** + * @brief get touch pad touch_pad_register counter. + * + *User can use this function to determine the the interrupt threshold .When you do not touch the + *pad ,read the touch_pad_read number(NumNotTouch) by the touch_pad_register.When you touch the pad ,read the touch_pad_register + *number(NumTouch) by the touch_pad_read.Normal NumNotTouch>NumTouch,so you can select a interrupt threshold. + * + * @param[in] touch_num : touch num + * @param[out] touch_value : touch output value + * + * @return - ESP_OK Success + * - ESP_ERR_INVALID_ARG Touch pad error + * + */ +esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t * touch_value); + +/** + * @brief register TouchPad interrupt handler, the handler is an ISR. + * The handler will be attached to the same CPU core that this function is running on. + * + * @param fn Interrupt handler function. + * @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 GPIO error + */ +esp_err_t touch_pad_isr_handler_register(void(*fn)(void *), void *arg, int intr_alloc_flags, touch_isr_handle_t *handle); + + +/** + * *************** ATTENTION ********************/ +/** + *@attention + *Touch button is through the body's capacitive characteristics, + *there is a charge discharge circuit inside the. When the hands touch, + *the charge and discharge time will be slow. + *Because of the different hardware, each pad needs to be calibrated at the factory. + *We use touch_pad_read to determine factory parameters. + */ +/** + *----------EXAMPLE TO CONFIGURE GPIO AS OUTPUT ------------ * + * @code{c} + * touch_pad_init(); + * void taskA(void* arg) + * { + * for(;;){ + * vtaskDelay(20/portTICK_PERIOD_MS); + * ets_printf("touch pad value %u\n",touch_pad_read(0));//Take the touched status and untouched status value + * } + * } + * @endcode + **/ +/** + *----------EXAMPLE TO SET ISR HANDLER ---------------------- + * @code{c} + * touch_pad_isr_handler_register(rtc_intr,NULL, 0, NULL) //hook the isr handler for TouchPad interrupt + * @endcode + */ +/** + *----------EXAMPLE TO USE TOUCH_PAD------------ * + * @code{c} + * touch_pad_init();//only init one time + * touch_pad_config(0,300);//set the intr threshold,use touch_pad_read to determine this threshold + * touch_pad_isr_handler_register(rtc_intr,NULL, 0, NULL) + * #include "esp_attr.h" + * void rtc_intr(void * arg) + * { + * uint32_t pad_intr = READ_PERI_REG(SARADC_SAR_TOUCH_CTRL2_REG) & 0x3ff; + * uint8_t i = 0; + * uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG); + * WRITE_PERI_REG(RTC_CNTL_INT_CLR_REG, rtc_intr); + * SET_PERI_REG_MASK(SARADC_SAR_TOUCH_CTRL2_REG, SARADC_TOUCH_MEAS_EN_CLR); + * if (rtc_intr & RTC_CNTL_TOUCH_INT_ST) { + * for (i = 0; i < TOUCH_PAD_MAX; ++i) { + * if ((pad_intr >> i) & 0x01) { + * ets_printf("touch pad intr %u\n",i); + * } + * } + * } + * } + * @endcode + **/ + +#ifdef __cplusplus +} +#endif + +#endif/*_DRIVER_TOUCH_PAD_H_*/ + diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 1ddfcad9fa..c193fb0ef8 100644 --- a/components/driver/include/driver/uart.h +++ b/components/driver/include/driver/uart.h @@ -1,748 +1,806 @@ -// 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_UART_H_ -#define _DRIVER_UART_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include "soc/uart_reg.h" -#include "soc/uart_struct.h" -#include "esp_err.h" -#include "driver/periph_ctrl.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/xtensa_api.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/ringbuf.h" -#include - -#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */ -#define UART_INTR_MASK 0x1ff /*!< mask of all UART interrupts */ -#define UART_LINE_INV_MASK (0x3f << 19) /*!< TBD */ -#define UART_BITRATE_MAX 5000000 /*!< Max bit rate supported by UART */ -#define UART_PIN_NO_CHANGE (-1) /*!< Constant for uart_set_pin function which indicates that UART pin should not be changed */ - -#define UART_INVERSE_DISABLE (0x0) /*!< Disable UART signal inverse*/ -#define UART_INVERSE_RXD (UART_RXD_INV_M) /*!< UART RXD input inverse*/ -#define UART_INVERSE_CTS (UART_CTS_INV_M) /*!< UART CTS input inverse*/ -#define UART_INVERSE_TXD (UART_TXD_INV_M) /*!< UART TXD output inverse*/ -#define UART_INVERSE_RTS (UART_RTS_INV_M) /*!< UART RTS output inverse*/ - -/** - * @brief UART word length constants - */ -typedef enum { - UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/ - UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/ - UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/ - UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/ - UART_DATA_BITS_MAX = 0X4, -} uart_word_length_t; - -/** - * @brief UART stop bits number - */ -typedef enum { - UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/ - UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/ - UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/ - UART_STOP_BITS_MAX = 0x4, -} uart_stop_bits_t; - -/** - * @brief UART peripheral number - */ -typedef enum { - UART_NUM_0 = 0x0, /*!< UART base address 0x3ff40000*/ - UART_NUM_1 = 0x1, /*!< UART base address 0x3ff50000*/ - UART_NUM_2 = 0x2, /*!< UART base address 0x3ff6E000*/ - UART_NUM_MAX, -} uart_port_t; - -/** - * @brief UART parity constants - */ -typedef enum { - UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/ - UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/ - UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/ -} uart_parity_t; - -/** - * @brief UART hardware flow control modes - */ -typedef enum { - UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/ - UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/ - UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/ - UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/ - UART_HW_FLOWCTRL_MAX = 0x4, -} uart_hw_flowcontrol_t; - -/** - * @brief UART configuration parameters for uart_param_config function - */ -typedef struct { - int baud_rate; /*!< UART baudrate*/ - uart_word_length_t data_bits; /*!< UART byte size*/ - uart_parity_t parity; /*!< UART parity mode*/ - uart_stop_bits_t stop_bits; /*!< UART stop bits*/ - uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode(cts/rts)*/ - uint8_t rx_flow_ctrl_thresh ; /*!< UART HW RTS threshold*/ -} uart_config_t; - -/** - * @brief UART interrupt configuration parameters for uart_intr_config function - */ -typedef struct { - uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/ - uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold(unit: time of sending one byte)*/ - uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/ - uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/ -} uart_intr_config_t; - -/** - * @brief UART event types used in the ringbuffer - */ -typedef enum { - UART_DATA, /*!< UART data event*/ - UART_BREAK, /*!< UART break event*/ - UART_BUFFER_FULL, /*!< UART RX buffer full event*/ - UART_FIFO_OVF, /*!< UART FIFO overflow event*/ - UART_FRAME_ERR, /*!< UART RX frame error event*/ - UART_PARITY_ERR, /*!< UART RX parity event*/ - UART_DATA_BREAK, /*!< UART TX data and break event*/ - UART_EVENT_MAX, /*!< UART event max index*/ -} uart_event_type_t; - -/** - * @brief Event structure used in UART event queue - */ -typedef struct { - uart_event_type_t type; /*!< UART event type */ - size_t size; /*!< UART data size for UART_DATA event*/ -} uart_event_t; - -/** - * @brief Set UART data bits. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param data_bit UART data bits - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit); - -/** - * @brief Get UART data bits. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param data_bit Pointer to accept value of UART data bits. - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success, result will be put in (*data_bit) - */ -esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit); - -/** - * @brief Set UART stop bits. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param stop_bits UART stop bits - * - * @return - * - ESP_OK Success - * - ESP_FAIL Fail - */ -esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits); - -/** - * @brief Set UART stop bits. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param stop_bits Pointer to accept value of UART stop bits. - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success, result will be put in (*stop_bit) - */ -esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bits); - -/** - * @brief Set UART parity. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param parity_mode the enum of uart parity configuration - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success - */ -esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode); - -/** - * @brief Get UART parity mode. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param parity_mode Pointer to accept value of UART parity mode. - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success, result will be put in (*parity_mode) - * - */ -esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); - -/** - * @brief Set UART baud rate. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param baudrate UART baud rate. - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success - */ -esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate); - -/** - * @brief Get UART bit-rate. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param baudrate Pointer to accept value of UART baud rate - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success, result will be put in (*baudrate) - * - */ -esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate); - -/** - * @brief Set UART line inverse mode - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param inverse_mask Choose the wires that need to be inverted. - * Inverse_mask should be chosen from UART_INVERSE_RXD/UART_INVERSE_TXD/UART_INVERSE_RTS/UART_INVERSE_CTS, combine with OR operation. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask); - -/** - * @brief Set hardware flow control. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param flow_ctrl Hardware flow control mode - * @param rx_thresh Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN). - * Only when UART_HW_FLOWCTRL_RTS is set, will the rx_thresh value be set. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh); - -/** - * @brief Get hardware flow control mode - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param flow_ctrl Option for different flow control mode. - * - * @return - * - ESP_FAIL Parameter error - * - ESP_OK Success, result will be put in (*flow_ctrl) - */ -esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl); - -/** - * @brief Clear UART interrupt status - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param clr_mask Bit mask of the status that to be cleared. - * enable_mask should be chosen from the fields of register UART_INT_CLR_REG. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask); - -/** - * @brief Set UART interrupt enable - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param enable_mask Bit mask of the enable bits. - * enable_mask should be chosen from the fields of register UART_INT_ENA_REG. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask); - -/** - * @brief Clear UART interrupt enable bits - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param disable_mask Bit mask of the disable bits. - * disable_mask should be chosen from the fields of register UART_INT_ENA_REG. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask); - - -/** - * @brief Enable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_enable_rx_intr(uart_port_t uart_num); - -/** - * @brief Disable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_disable_rx_intr(uart_port_t uart_num); - -/** - * @brief Disable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_disable_tx_intr(uart_port_t uart_num); - -/** - * @brief Enable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param enable 1: enable; 0: disable - * @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); - -/** - * @brief register UART interrupt handler(ISR). - * - * @note UART ISR handler will be attached to the same CPU core that this function is running on. - * Users should know that which CPU is running and then pick a INUM that is not used by system. - * We can find the information of INUM and interrupt level in soc.h. - * - * @attention The ISR handler function MUST be defined with attribution of "IRAM_ATTR" for now. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details - * @param fn Interrupt handler function. - * @param arg parameter for handler function - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (*fn)(void*), void * arg); - -/** - * @brief Set UART pin number - * - * @note Internal signal can be output to multiple GPIO pads. - * Only one GPIO pad can connect with input signal. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param tx_io_num UART TX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. - * @param rx_io_num UART RX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. - * @param rts_io_num UART RTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. - * @param cts_io_num UART CTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num); - -/** - * @brief UART set RTS level (before inverse) - * UART rx hardware flow control should not be set. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param level 1: RTS output low(active); 0: RTS output high(block) - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_set_rts(uart_port_t uart_num, int level); - -/** - * @brief UART set DTR level (before inverse) - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param level 1: DTR output low; 0: DTR output high - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_set_dtr(uart_port_t uart_num, int level); - -/** -* @brief UART parameter configure - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param uart_config UART parameter settings - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config); - -/** -* @brief UART interrupt configure - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param intr_conf UART interrupt settings - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf); - -/** - * @brief Install UART driver. - * - * UART ISR handler will be attached to the same CPU core that this function is running on. - * Users should know that which CPU is running and then pick a INUM that is not used by system. - * We can find the information of INUM and interrupt level in soc.h. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param rx_buffer_size UART RX ring buffer size - * @param tx_buffer_size UART TX ring buffer size. - * If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.. - * @param queue_size UART event queue size/depth. - * @param uart_intr_num UART interrupt number,check the info in soc.h, and please refer to core-isa.h for more details - * @param uart_queue UART event queue handle, if set NULL, driver will not use an event queue. - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue); - -/** - * @brief Uninstall UART driver. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_driver_delete(uart_port_t uart_num); - -/** - * @brief Wait UART TX FIFO empty - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param ticks_to_wait Timeout, count in RTOS ticks - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - * - ESP_ERR_TIMEOUT Timeout - */ -esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait); - -/** - * @brief Send data to the UART port from a given buffer and length. - * - * This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full. - * @note This function should only be used when UART TX buffer is not enabled. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param buffer data buffer address - * @param len data length to send - * - * @return - * - (-1) Parameter error - * - OTHERS(>=0) The number of data that pushed to the TX FIFO - */ -int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len); - -/** - * @brief Send data to the UART port from a given buffer and length, - * - * If parameter tx_buffer_size is set to zero: - * This function will not return until all the data have been sent out, or at least pushed into TX FIFO. - * - * Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer, - * then, UART ISR will move data from ring buffer to TX FIFO gradually. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param src data buffer address - * @param size data length to send - * - * @return - * - (-1) Parameter error - * - OTHERS(>=0) The number of data that pushed to the TX FIFO - */ -int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size); - -/** - * @brief Send data to the UART port from a given buffer and length, - * - * If parameter tx_buffer_size is set to zero: - * This function will not return until all the data and the break signal have been sent out. - * After all data send out, send a break signal. - * - * Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer, - * then, UART ISR will move data from ring buffer to TX FIFO gradually. - * After all data send out, send a break signal. - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param src data buffer address - * @param size data length to send - * @param brk_len break signal length (unit: time of one data bit at current_baudrate) - * - * @return - * - (-1) Parameter error - * - OTHERS(>=0) The number of data that pushed to the TX FIFO - */ - -int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); - -/** - * @brief UART read bytes from UART buffer - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * @param buf pointer to the buffer. - * @param length data length - * @param ticks_to_wait sTimeout, count in RTOS ticks - * - * @return - * - (-1) Error - * - Others return a char data from uart fifo. - */ -int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); - -/** - * @brief UART ring buffer flush - * - * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 - * - * @return - * - ESP_OK Success - * - ESP_FAIL Parameter error - */ -esp_err_t uart_flush(uart_port_t uart_num); - -/***************************EXAMPLE********************************** - * - * - * ----------------EXAMPLE OF UART SETTING --------------------- - * @code{c} - * //1. Setup UART - * #include "freertos/queue.h" - * #define UART_INTR_NUM 17 //choose one interrupt number from soc.h - * //a. Set UART parameter - * int uart_num = 0; //uart port number - * uart_config_t uart_config = { - * .baud_rate = UART_BITRATE_115200, //baudrate - * .data_bits = UART_DATA_8_BITS, //data bit mode - * .parity = UART_PARITY_DISABLE, //parity mode - * .stop_bits = UART_STOP_BITS_1, //stop bit mode - * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //hardware flow control(cts/rts) - * .rx_flow_ctrl_thresh = 120, //flow control threshold - * }; - * uart_param_config(uart_num, &uart_config); - * //b1. Setup UART driver(with UART queue) - * QueueHandle_t uart_queue; - * //parameters here are just an example, tx buffer size is 2048 - * uart_driver_install(uart_num, 1024 * 2, 1024 * 2, 10, UART_INTR_NUM, &uart_queue); - * //b2. Setup UART driver(without UART queue) - * //parameters here are just an example, tx buffer size is 0 - * uart_driver_install(uart_num, 1024 * 2, 0, 10, UART_INTR_NUM, NULL); - *@endcode - *-----------------------------------------------------------------------------* - * @code{c} - * //2. Set UART pin - * //set UART pin, not needed if use default pins. - * uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 15, 13); - * @endcode - *-----------------------------------------------------------------------------* - * @code{c} - * //3. Read data from UART. - * uint8_t data[128]; - * int length = 0; - * length = uart_read_bytes(uart_num, data, sizeof(data), 100); - * @endcode - *-----------------------------------------------------------------------------* - * @code{c} - * //4. Write data to UART. - * char* test_str = "This is a test string.\n" - * uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str)); - * @endcode - *-----------------------------------------------------------------------------* - * @code{c} - * //5. Write data to UART, end with a break signal. - * uart_write_bytes_with_break(0, "test break\n",strlen("test break\n"), 100); - * @endcode - *-----------------------------------------------------------------------------* - * @code{c} - * //6. an example of echo test with hardware flow control on UART1 - * void uart_loop_back_test() - * { - * int uart_num = 1; - * uart_config_t uart_config = { - * .baud_rate = 115200, - * .data_bits = UART_DATA_8_BITS, - * .parity = UART_PARITY_DISABLE, - * .stop_bits = UART_STOP_BITS_1, - * .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, - * .rx_flow_ctrl_thresh = 122, - * }; - * //Configure UART1 parameters - * uart_param_config(uart_num, &uart_config); - * //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) - * uart_set_pin(uart_num, 16, 17, 18, 19); - * //Install UART driver( We don't need an event queue here) - * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, NULL, RINGBUF_TYPE_BYTEBUF); - * uint8_t data[1000]; - * while(1) { - * //Read data from UART - * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); - * //Write data back to UART - * uart_write_bytes(uart_num, (const char*)data, len); - * } - * } - * @endcode - *-----------------------------------------------------------------------------* - * @code{c} - * //7. An example of using UART event queue on UART0. - * #include "freertos/queue.h" - * //A queue to handle UART event. - * QueueHandle_t uart0_queue; - * static const char *TAG = "uart_example"; - * void uart_task(void *pvParameters) - * { - * int uart_num = (int)pvParameters; - * uart_event_t event; - * size_t size = 1024; - * uint8_t* dtmp = (uint8_t*)malloc(size); - * for(;;) { - * //Waiting for UART event. - * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { - * ESP_LOGI(TAG, "uart[%d] event:", uart_num); - * switch(event.type) { - * memset(dtmp, 0, size); - * //Event of UART receving data - * case UART_DATA: - * ESP_LOGI(TAG,"data, len: %d", event.size); - * int len = uart_read_bytes(uart_num, dtmp, event.size, 10); - * ESP_LOGI(TAG, "uart read: %d", len); - uart_write_bytes(uart_num, (const char*)dtmp, len); - * break; - * //Event of HW FIFO overflow detected - * case UART_FIFO_OVF: - * ESP_LOGI(TAG, "hw fifo overflow\n"); - * break; - * //Event of UART ring buffer full - * case UART_BUFFER_FULL: - * ESP_LOGI(TAG, "ring buffer full\n"); - * break; - * //Event of UART RX break detected - * case UART_BREAK: - * ESP_LOGI(TAG, "uart rx break\n"); - * break; - * //Event of UART parity check error - * case UART_PARITY_ERR: - * ESP_LOGI(TAG, "uart parity error\n"); - * break; - * //Event of UART frame error - * case UART_FRAME_ERR: - * ESP_LOGI(TAG, "uart frame error\n"); - * break; - * //Others - * default: - * ESP_LOGI(TAG, "uart event type: %d\n", event.type); - * break; - * } - * } - * } - * free(dtmp); - * dtmp = NULL; - * vTaskDelete(NULL); - * } - * - * void uart_queue_test() - * { - * int uart_num = 0; - * uart_config_t uart_config = { - * .baud_rate = 115200, - * .data_bits = UART_DATA_8_BITS, - * .parity = UART_PARITY_DISABLE, - * .stop_bits = UART_STOP_BITS_1, - * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, - * .rx_flow_ctrl_thresh = 122, - * }; - * //Set UART parameters - * uart_param_config(uart_num, &uart_config); - * //Set UART pins,(-1: default pin, no change.) - * uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); - * //Set UART log level - * esp_log_level_set(TAG, ESP_LOG_INFO); - * //Install UART driver, and get the queue. - * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, 17, &uart0_queue); - * //Create a task to handler UART event from ISR - * xTaskCreate(uart_task, "uTask", 1024, (void*)uart_num, 10, NULL); - * } - * @endcode - * - ***************************END OF EXAMPLE**********************************/ - -#ifdef __cplusplus -} -#endif - -#endif /*_DRIVER_UART_H_*/ +// 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_UART_H_ +#define _DRIVER_UART_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/uart_reg.h" +#include "soc/uart_struct.h" +#include "esp_err.h" +#include "esp_intr_alloc.h" +#include "driver/periph_ctrl.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/xtensa_api.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#include "freertos/ringbuf.h" +#include + +#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */ +#define UART_INTR_MASK 0x1ff /*!< mask of all UART interrupts */ +#define UART_LINE_INV_MASK (0x3f << 19) /*!< TBD */ +#define UART_BITRATE_MAX 5000000 /*!< Max bit rate supported by UART */ +#define UART_PIN_NO_CHANGE (-1) /*!< Constant for uart_set_pin function which indicates that UART pin should not be changed */ + +#define UART_INVERSE_DISABLE (0x0) /*!< Disable UART signal inverse*/ +#define UART_INVERSE_RXD (UART_RXD_INV_M) /*!< UART RXD input inverse*/ +#define UART_INVERSE_CTS (UART_CTS_INV_M) /*!< UART CTS input inverse*/ +#define UART_INVERSE_TXD (UART_TXD_INV_M) /*!< UART TXD output inverse*/ +#define UART_INVERSE_RTS (UART_RTS_INV_M) /*!< UART RTS output inverse*/ + +/** + * @brief UART word length constants + */ +typedef enum { + UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/ + UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/ + UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/ + UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/ + UART_DATA_BITS_MAX = 0X4, +} uart_word_length_t; + +/** + * @brief UART stop bits number + */ +typedef enum { + UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/ + UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/ + UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/ + UART_STOP_BITS_MAX = 0x4, +} uart_stop_bits_t; + +/** + * @brief UART peripheral number + */ +typedef enum { + UART_NUM_0 = 0x0, /*!< UART base address 0x3ff40000*/ + UART_NUM_1 = 0x1, /*!< UART base address 0x3ff50000*/ + UART_NUM_2 = 0x2, /*!< UART base address 0x3ff6E000*/ + UART_NUM_MAX, +} uart_port_t; + +/** + * @brief UART parity constants + */ +typedef enum { + UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/ + UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/ + UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/ +} uart_parity_t; + +/** + * @brief UART hardware flow control modes + */ +typedef enum { + UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/ + UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/ + UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/ + UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/ + UART_HW_FLOWCTRL_MAX = 0x4, +} uart_hw_flowcontrol_t; + +/** + * @brief UART configuration parameters for uart_param_config function + */ +typedef struct { + int baud_rate; /*!< UART baudrate*/ + uart_word_length_t data_bits; /*!< UART byte size*/ + uart_parity_t parity; /*!< UART parity mode*/ + uart_stop_bits_t stop_bits; /*!< UART stop bits*/ + uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode(cts/rts)*/ + uint8_t rx_flow_ctrl_thresh ; /*!< UART HW RTS threshold*/ +} uart_config_t; + +/** + * @brief UART interrupt configuration parameters for uart_intr_config function + */ +typedef struct { + uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/ + uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold(unit: time of sending one byte)*/ + uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/ + uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/ +} uart_intr_config_t; + +/** + * @brief UART event types used in the ringbuffer + */ +typedef enum { + UART_DATA, /*!< UART data event*/ + UART_BREAK, /*!< UART break event*/ + UART_BUFFER_FULL, /*!< UART RX buffer full event*/ + UART_FIFO_OVF, /*!< UART FIFO overflow event*/ + UART_FRAME_ERR, /*!< UART RX frame error event*/ + UART_PARITY_ERR, /*!< UART RX parity event*/ + UART_DATA_BREAK, /*!< UART TX data and break event*/ + UART_EVENT_MAX, /*!< UART event max index*/ + UART_PATTERN_DET, /*!< UART pattern detected */ +} uart_event_type_t; + +/** + * @brief Event structure used in UART event queue + */ +typedef struct { + uart_event_type_t type; /*!< UART event type */ + size_t size; /*!< UART data size for UART_DATA event*/ +} uart_event_t; + +typedef intr_handle_t uart_isr_handle_t; + +/** + * @brief Set UART data bits. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param data_bit UART data bits + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit); + +/** + * @brief Get UART data bits. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param data_bit Pointer to accept value of UART data bits. + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*data_bit) + */ +esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit); + +/** + * @brief Set UART stop bits. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param stop_bits UART stop bits + * + * @return + * - ESP_OK Success + * - ESP_FAIL Fail + */ +esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits); + +/** + * @brief Set UART stop bits. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param stop_bits Pointer to accept value of UART stop bits. + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*stop_bit) + */ +esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bits); + +/** + * @brief Set UART parity. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param parity_mode the enum of uart parity configuration + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode); + +/** + * @brief Get UART parity mode. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param parity_mode Pointer to accept value of UART parity mode. + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*parity_mode) + * + */ +esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode); + +/** + * @brief Set UART baud rate. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param baudrate UART baud rate. + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success + */ +esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate); + +/** + * @brief Get UART bit-rate. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param baudrate Pointer to accept value of UART baud rate + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*baudrate) + * + */ +esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate); + +/** + * @brief Set UART line inverse mode + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param inverse_mask Choose the wires that need to be inverted. + * Inverse_mask should be chosen from UART_INVERSE_RXD/UART_INVERSE_TXD/UART_INVERSE_RTS/UART_INVERSE_CTS, combine with OR operation. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask); + +/** + * @brief Set hardware flow control. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param flow_ctrl Hardware flow control mode + * @param rx_thresh Threshold of Hardware RX flow control(0 ~ UART_FIFO_LEN). + * Only when UART_HW_FLOWCTRL_RTS is set, will the rx_thresh value be set. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh); + +/** + * @brief Get hardware flow control mode + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param flow_ctrl Option for different flow control mode. + * + * @return + * - ESP_FAIL Parameter error + * - ESP_OK Success, result will be put in (*flow_ctrl) + */ +esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl); + +/** + * @brief Clear UART interrupt status + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param clr_mask Bit mask of the status that to be cleared. + * enable_mask should be chosen from the fields of register UART_INT_CLR_REG. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask); + +/** + * @brief Set UART interrupt enable + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param enable_mask Bit mask of the enable bits. + * enable_mask should be chosen from the fields of register UART_INT_ENA_REG. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask); + +/** + * @brief Clear UART interrupt enable bits + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param disable_mask Bit mask of the disable bits. + * disable_mask should be chosen from the fields of register UART_INT_ENA_REG. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask); + + +/** + * @brief Enable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_enable_rx_intr(uart_port_t uart_num); + +/** + * @brief Disable UART RX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_disable_rx_intr(uart_port_t uart_num); + +/** + * @brief Disable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_disable_tx_intr(uart_port_t uart_num); + +/** + * @brief Enable UART TX interrupt(RX_FULL & RX_TIMEOUT INTERRUPT) + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param enable 1: enable; 0: disable + * @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh); + +/** + * @brief register UART interrupt handler(ISR). + * + * @note UART ISR handler will be attached to the same CPU core that this function is running on. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param fn Interrupt handler function. + * @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_FAIL Parameter error + */ +esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags, uart_isr_handle_t *handle); + + +/** + * @brief Free UART interrupt handler registered by uart_isr_register. Must be called on the same core as + * uart_isr_register was called. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_isr_free(uart_port_t uart_num); + +/** + * @brief Set UART pin number + * + * @note Internal signal can be output to multiple GPIO pads. + * Only one GPIO pad can connect with input signal. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param tx_io_num UART TX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. + * @param rx_io_num UART RX pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. + * @param rts_io_num UART RTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. + * @param cts_io_num UART CTS pin GPIO number, if set to UART_PIN_NO_CHANGE, use the current pin. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num); + +/** + * @brief UART set RTS level (before inverse) + * UART rx hardware flow control should not be set. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param level 1: RTS output low(active); 0: RTS output high(block) + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_set_rts(uart_port_t uart_num, int level); + +/** + * @brief UART set DTR level (before inverse) + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param level 1: DTR output low; 0: DTR output high + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_set_dtr(uart_port_t uart_num, int level); + +/** +* @brief UART parameter configure + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param uart_config UART parameter settings + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config); + +/** +* @brief UART interrupt configure + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param intr_conf UART interrupt settings + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf); + +/** + * @brief Install UART driver. + * + * UART ISR handler will be attached to the same CPU core that this function is running on. + * Users should know that which CPU is running and then pick a INUM that is not used by system. + * We can find the information of INUM and interrupt level in soc.h. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param rx_buffer_size UART RX ring buffer size, rx_buffer_size should be greater than UART_FIFO_LEN. + * @param tx_buffer_size UART TX ring buffer size. + * If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.. + * @param queue_size UART event queue size/depth. + * @param uart_queue UART event queue handle, if set NULL, driver will not use an event queue. + * @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. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, void* uart_queue, int intr_alloc_flags); + +/** + * @brief Uninstall UART driver. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_driver_delete(uart_port_t uart_num); + +/** + * @brief Wait UART TX FIFO empty + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param ticks_to_wait Timeout, count in RTOS ticks + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + * - ESP_ERR_TIMEOUT Timeout + */ +esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait); + +/** + * @brief Send data to the UART port from a given buffer and length. + * + * This function will not wait for the space in TX FIFO, just fill the TX FIFO and return when the FIFO is full. + * @note This function should only be used when UART TX buffer is not enabled. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param buffer data buffer address + * @param len data length to send + * + * @return + * - (-1) Parameter error + * - OTHERS(>=0) The number of data that pushed to the TX FIFO + */ +int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len); + +/** + * @brief Send data to the UART port from a given buffer and length, + * + * If parameter tx_buffer_size is set to zero: + * This function will not return until all the data have been sent out, or at least pushed into TX FIFO. + * + * Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer, + * then, UART ISR will move data from ring buffer to TX FIFO gradually. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param src data buffer address + * @param size data length to send + * + * @return + * - (-1) Parameter error + * - OTHERS(>=0) The number of data that pushed to the TX FIFO + */ +int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size); + +/** + * @brief Send data to the UART port from a given buffer and length, + * + * If parameter tx_buffer_size is set to zero: + * This function will not return until all the data and the break signal have been sent out. + * After all data send out, send a break signal. + * + * Otherwise, if tx_buffer_size > 0, this function will return after copying all the data to tx ringbuffer, + * then, UART ISR will move data from ring buffer to TX FIFO gradually. + * After all data send out, send a break signal. + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param src data buffer address + * @param size data length to send + * @param brk_len break signal length (unit: time of one data bit at current_baudrate) + * + * @return + * - (-1) Parameter error + * - OTHERS(>=0) The number of data that pushed to the TX FIFO + */ + +int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len); + +/** + * @brief UART read bytes from UART buffer + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * @param buf pointer to the buffer. + * @param length data length + * @param ticks_to_wait sTimeout, count in RTOS ticks + * + * @return + * - (-1) Error + * - Others return a char data from uart fifo. + */ +int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait); + +/** + * @brief UART ring buffer flush + * + * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2 + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_flush(uart_port_t uart_num); + +/** + * @brief UART get RX ring buffer cached data length + * + * @param uart_num UART port number. + * @param size Pointer of size_t to accept cached data length + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size); + +/** + * @brief UART disable pattern detect function. + * Designed for applications like 'AT commands'. + * When the hardware detect a series of one same character, the interrupt will be triggered. + * + * @param uart_num UART port number. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num); + +/** + * @brief UART enable pattern detect function. + * Designed for applications like 'AT commands'. + * When the hardware detect a series of one same character, the interrupt will be triggered. + * + * @param uart_num UART port number. + * @param pattern_chr character of the pattern + * @param chr_num number of the character, 8bit value. + * @param chr_tout timeout of the interval between each pattern characters, 24bit value, unit is APB(80Mhz) clock cycle. + * @param post_idle idle time after the last pattern character, 24bit value, unit is APB(80Mhz) clock cycle. + * @param pre_idle idle time before the first pattern character, 24bit value, unit is APB(80Mhz) clock cycle. + * + * @return + * - ESP_OK Success + * - ESP_FAIL Parameter error + */ +esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle); +/***************************EXAMPLE********************************** + * + * + * ----------------EXAMPLE OF UART SETTING --------------------- + * @code{c} + * //1. Setup UART + * #include "freertos/queue.h" + * #define UART_INTR_NUM 17 //choose one interrupt number from soc.h + * //a. Set UART parameter + * int uart_num = 0; //uart port number + * uart_config_t uart_config = { + * .baud_rate = UART_BITRATE_115200, //baudrate + * .data_bits = UART_DATA_8_BITS, //data bit mode + * .parity = UART_PARITY_DISABLE, //parity mode + * .stop_bits = UART_STOP_BITS_1, //stop bit mode + * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, //hardware flow control(cts/rts) + * .rx_flow_ctrl_thresh = 120, //flow control threshold + * }; + * uart_param_config(uart_num, &uart_config); + * //b1. Setup UART driver(with UART queue) + * QueueHandle_t uart_queue; + * //parameters here are just an example, tx buffer size is 2048 + * uart_driver_install(uart_num, 1024 * 2, 1024 * 2, 10, &uart_queue, 0); + * //b2. Setup UART driver(without UART queue) + * //parameters here are just an example, tx buffer size is 0 + * uart_driver_install(uart_num, 1024 * 2, 0, 10, NULL, 0); + *@endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //2. Set UART pin + * //set UART pin, not needed if use default pins. + * uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, 15, 13); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //3. Read data from UART. + * uint8_t data[128]; + * int length = 0; + * length = uart_read_bytes(uart_num, data, sizeof(data), 100); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //4. Write data to UART. + * char* test_str = "This is a test string.\n" + * uart_write_bytes(uart_num, (const char*)test_str, strlen(test_str)); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //5. Write data to UART, end with a break signal. + * uart_write_bytes_with_break(0, "test break\n",strlen("test break\n"), 100); + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //6. an example of echo test with hardware flow control on UART1 + * void uart_loop_back_test() + * { + * int uart_num = 1; + * uart_config_t uart_config = { + * .baud_rate = 115200, + * .data_bits = UART_DATA_8_BITS, + * .parity = UART_PARITY_DISABLE, + * .stop_bits = UART_STOP_BITS_1, + * .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + * .rx_flow_ctrl_thresh = 122, + * }; + * //Configure UART1 parameters + * uart_param_config(uart_num, &uart_config); + * //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19) + * uart_set_pin(uart_num, 16, 17, 18, 19); + * //Install UART driver( We don't need an event queue here) + * uart_driver_install(uart_num, 1024 * 2, 1024*4, 0, NULL, 0); + * uint8_t data[1000]; + * while(1) { + * //Read data from UART + * int len = uart_read_bytes(uart_num, data, sizeof(data), 10); + * //Write data back to UART + * uart_write_bytes(uart_num, (const char*)data, len); + * } + * } + * @endcode + *-----------------------------------------------------------------------------* + * @code{c} + * //7. An example of using UART event queue on UART0. + * #include "freertos/queue.h" + * //A queue to handle UART event. + * QueueHandle_t uart0_queue; + * static const char *TAG = "uart_example"; + * void uart_task(void *pvParameters) + * { + * int uart_num = (int)pvParameters; + * uart_event_t event; + * size_t size = 1024; + * uint8_t* dtmp = (uint8_t*)malloc(size); + * for(;;) { + * //Waiting for UART event. + * if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + * ESP_LOGI(TAG, "uart[%d] event:", uart_num); + * switch(event.type) { + * memset(dtmp, 0, size); + * //Event of UART receving data + * case UART_DATA: + * ESP_LOGI(TAG,"data, len: %d", event.size); + * int len = uart_read_bytes(uart_num, dtmp, event.size, 10); + * ESP_LOGI(TAG, "uart read: %d", len); + * break; + * //Event of HW FIFO overflow detected + * case UART_FIFO_OVF: + * ESP_LOGI(TAG, "hw fifo overflow\n"); + * break; + * //Event of UART ring buffer full + * case UART_BUFFER_FULL: + * ESP_LOGI(TAG, "ring buffer full\n"); + * break; + * //Event of UART RX break detected + * case UART_BREAK: + * ESP_LOGI(TAG, "uart rx break\n"); + * break; + * //Event of UART parity check error + * case UART_PARITY_ERR: + * ESP_LOGI(TAG, "uart parity error\n"); + * break; + * //Event of UART frame error + * case UART_FRAME_ERR: + * ESP_LOGI(TAG, "uart frame error\n"); + * break; + * //Others + * default: + * ESP_LOGI(TAG, "uart event type: %d\n", event.type); + * break; + * } + * } + * } + * free(dtmp); + * dtmp = NULL; + * vTaskDelete(NULL); + * } + * + * void uart_queue_test() + * { + * int uart_num = 0; + * uart_config_t uart_config = { + * .baud_rate = 115200, + * .data_bits = UART_DATA_8_BITS, + * .parity = UART_PARITY_DISABLE, + * .stop_bits = UART_STOP_BITS_1, + * .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + * .rx_flow_ctrl_thresh = 122, + * }; + * //Set UART parameters + * uart_param_config(uart_num, &uart_config); + * //Set UART pins,(-1: default pin, no change.) + * uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + * //Set UART log level + * esp_log_level_set(TAG, ESP_LOG_INFO); + * //Install UART driver, and get the queue. + * uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, &uart0_queue, 0); + * //Create a task to handler UART event from ISR + * xTaskCreate(uart_task, "uTask", 1024, (void*)uart_num, 10, NULL); + * } + * @endcode + * + ***************************END OF EXAMPLE**********************************/ + +#ifdef __cplusplus +} +#endif + +#endif /*_DRIVER_UART_H_*/ diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 893c78a6be..77ca975969 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -13,6 +13,7 @@ // limitations under the License. #include #include "esp_intr.h" +#include "esp_intr_alloc.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "freertos/xtensa_api.h" @@ -20,12 +21,13 @@ #include "driver/ledc.h" #include "esp_log.h" -static const char* LEDC_TAG = "LEDC"; +static const char* LEDC_TAG = "ledc"; static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED; -#define LEDC_CHECK(a, str, ret_val) if (!(a)) { \ - ESP_LOGE(LEDC_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ - return (ret_val); \ - } +#define LEDC_CHECK(a, str, ret_val) \ + if (!(a)) { \ + ESP_LOGE(LEDC_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ + return (ret_val); \ + } esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src) { @@ -113,16 +115,14 @@ static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, return ESP_OK; } -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) { + esp_err_t ret; LEDC_CHECK(fn, "ledc isr null", ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); - ESP_INTR_DISABLE(ledc_intr_num); - intr_matrix_set(xPortGetCoreID(), ETS_LEDC_INTR_SOURCE, ledc_intr_num); - xt_set_interrupt_handler(ledc_intr_num, fn, arg); - ESP_INTR_ENABLE(ledc_intr_num); + ret=esp_intr_alloc(ETS_LEDC_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); portEXIT_CRITICAL(&ledc_spinlock); - return ESP_OK; + return ret; } esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf) diff --git a/components/driver/pcnt.c b/components/driver/pcnt.c index b39d53a800..ac40898897 100644 --- a/components/driver/pcnt.c +++ b/components/driver/pcnt.c @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "esp_log.h" +#include "esp_intr_alloc.h" #include "driver/pcnt.h" #include "driver/periph_ctrl.h" @@ -23,12 +24,14 @@ #define PCNT_COUNT_MODE_ERR_STR "PCNT COUNTER MODE ERROR" #define PCNT_CTRL_MODE_ERR_STR "PCNT CTRL MODE ERROR" #define PCNT_EVT_TYPE_ERR_STR "PCNT value type error" -#define PCNT_CHECK(a,str,ret_val) if(!(a)) { \ - ESP_LOGE(PCNT_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ - return (ret_val); \ - } -static const char* PCNT_TAG = "PCNT"; +static const char* PCNT_TAG = "pcnt"; +#define PCNT_CHECK(a, str, ret_val) \ + if (!(a)) { \ + ESP_LOGE(PCNT_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ + return (ret_val); \ + } + static portMUX_TYPE pcnt_spinlock = portMUX_INITIALIZER_UNLOCKED; #define PCNT_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) @@ -38,8 +41,8 @@ static portMUX_TYPE pcnt_spinlock = portMUX_INITIALIZER_UNLOCKED; esp_err_t pcnt_unit_config(pcnt_config_t *pcnt_config) { - uint8_t unit = pcnt_config->channel; - uint8_t channel = pcnt_config->unit; + uint8_t unit = pcnt_config->unit; + uint8_t channel = pcnt_config->channel; int input_io = pcnt_config->pulse_gpio_num; int ctrl_io = pcnt_config->ctrl_gpio_num; @@ -266,13 +269,9 @@ esp_err_t pcnt_filter_disable(pcnt_unit_t unit) return ESP_OK; } -esp_err_t pcnt_isr_register(uint32_t pcnt_intr_num, void (*fun)(void*), void * arg) +esp_err_t pcnt_isr_register(void (*fun)(void*), void * arg, int intr_alloc_flags, pcnt_isr_handle_t *handle) { PCNT_CHECK(fun != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG); - ESP_INTR_DISABLE(pcnt_intr_num); - intr_matrix_set(xPortGetCoreID(), ETS_PCNT_INTR_SOURCE, pcnt_intr_num); - xt_set_interrupt_handler(pcnt_intr_num, fun, arg); - ESP_INTR_ENABLE(pcnt_intr_num); - return ESP_OK; + return esp_intr_alloc(ETS_PCNT_INTR_SOURCE, intr_alloc_flags, fun, arg, handle); } diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 9fc36d49c2..e29f190024 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -21,6 +21,7 @@ #include "esp_intr.h" #include "esp_log.h" #include "esp_err.h" +#include "esp_intr_alloc.h" #include "soc/gpio_sig_map.h" #include "soc/rmt_struct.h" #include "driver/periph_ctrl.h" @@ -43,13 +44,16 @@ #define RMT_DRIVER_ERROR_STR "RMT DRIVER ERR" #define RMT_DRIVER_LENGTH_ERROR_STR "RMT PARAM LEN ERROR" -static const char* RMT_TAG = "RMT"; +static const char* RMT_TAG = "rmt"; static bool s_rmt_driver_installed = false; +static rmt_isr_handle_t s_rmt_driver_intr_handle; + +#define RMT_CHECK(a, str, ret_val) \ + if (!(a)) { \ + ESP_LOGE(RMT_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ + return (ret_val); \ + } -#define RMT_CHECK(a, str, ret) if (!(a)) { \ - ESP_LOGE(RMT_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ - return (ret); \ - } static portMUX_TYPE rmt_spinlock = portMUX_INITIALIZER_UNLOCKED; typedef struct { @@ -472,17 +476,21 @@ esp_err_t rmt_fill_tx_items(rmt_channel_t channel, rmt_item32_t* item, uint16_t return ESP_OK; } -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) { + esp_err_t ret; RMT_CHECK((fn != NULL), RMT_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG); RMT_CHECK(s_rmt_driver_installed == false, "RMT DRIVER INSTALLED, CAN NOT REG ISR HANDLER", ESP_FAIL); portENTER_CRITICAL(&rmt_spinlock); - ESP_INTR_DISABLE(rmt_intr_num); - intr_matrix_set(xPortGetCoreID(), ETS_RMT_INTR_SOURCE, rmt_intr_num); - xt_set_interrupt_handler(rmt_intr_num, fn, arg); - ESP_INTR_ENABLE(rmt_intr_num); + ret=esp_intr_alloc(ETS_RMT_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); portEXIT_CRITICAL(&rmt_spinlock); - return ESP_OK; + return ret; +} + + +esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle) +{ + return esp_intr_free(handle); } static int IRAM_ATTR rmt_get_mem_len(rmt_channel_t channel) @@ -515,7 +523,7 @@ static void IRAM_ATTR rmt_driver_isr_default(void* arg) switch(i % 3) { //TX END case 0: - ESP_EARLY_LOGD(RMT_TAG, "RMT INTR : TX END\n"); + ESP_EARLY_LOGD(RMT_TAG, "RMT INTR : TX END"); xSemaphoreGiveFromISR(p_rmt->tx_sem, &HPTaskAwoken); if(HPTaskAwoken == pdTRUE) { portYIELD_FROM_ISR(); @@ -616,10 +624,10 @@ esp_err_t rmt_driver_uninstall(rmt_channel_t channel) free(p_rmt_obj[channel]); p_rmt_obj[channel] = NULL; s_rmt_driver_installed = false; - return ESP_OK; + return rmt_isr_deregister(s_rmt_driver_intr_handle); } -esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_intr_num) +esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr_alloc_flags) { RMT_CHECK(channel < RMT_CHANNEL_MAX, RMT_CHANNEL_ERROR_STR, ESP_ERR_INVALID_ARG); if(p_rmt_obj[channel] != NULL) { @@ -627,7 +635,6 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_ return ESP_FAIL; } - ESP_INTR_DISABLE(rmt_intr_num); p_rmt_obj[channel] = (rmt_obj_t*) malloc(sizeof(rmt_obj_t)); if(p_rmt_obj[channel] == NULL) { @@ -652,11 +659,10 @@ esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int rmt_ rmt_set_err_intr_en(channel, 1); } if(s_rmt_driver_installed == false) { - rmt_isr_register(rmt_intr_num, rmt_driver_isr_default, NULL); + rmt_isr_register(rmt_driver_isr_default, NULL, intr_alloc_flags, &s_rmt_driver_intr_handle); s_rmt_driver_installed = true; } rmt_set_tx_intr_en(channel, 1); - ESP_INTR_ENABLE(rmt_intr_num); return ESP_OK; } diff --git a/components/driver/rtc_module.c b/components/driver/rtc_module.c new file mode 100644 index 0000000000..19fd3123a9 --- /dev/null +++ b/components/driver/rtc_module.c @@ -0,0 +1,672 @@ +// 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 +#include +#include +#include "rom/ets_sys.h" +#include "esp_log.h" +#include "soc/rtc_io_reg.h" +#include "soc/sens_reg.h" +#include "soc/rtc_cntl_reg.h" +#include "rtc_io.h" +#include "touch_pad.h" +#include "adc.h" +#include "dac.h" +#include "freertos/FreeRTOS.h" +#include "freertos/xtensa_api.h" + +static const char *RTC_MODULE_TAG = "RTC_MODULE"; + +#define RTC_MODULE_CHECK(a, str, ret_val) if (!(a)) { \ + ESP_LOGE(RTC_MODULE_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ + return (ret_val); \ +} + +#define ADC1_CHECK_FUNCTION_RET(fun_ret) if(fun_ret!=ESP_OK){\ + ESP_LOGE(RTC_MODULE_TAG,"%s:%d\n",__FUNCTION__,__LINE__);\ + return ESP_FAIL;\ +} + +portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED; + +//Reg,Mux,Fun,IE,Up,Down,Rtc_number +const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = { + {RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, RTC_IO_TOUCH_PAD1_SLP_SEL_M, RTC_IO_TOUCH_PAD1_SLP_IE_M, RTC_CNTL_TOUCH_PAD1_HOLD_FORCE_M, 11}, //0 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //1 + {RTC_IO_TOUCH_PAD2_REG, RTC_IO_TOUCH_PAD2_MUX_SEL_M, RTC_IO_TOUCH_PAD2_FUN_SEL_S, RTC_IO_TOUCH_PAD2_FUN_IE_M, RTC_IO_TOUCH_PAD2_RUE_M, RTC_IO_TOUCH_PAD2_RDE_M, RTC_IO_TOUCH_PAD2_SLP_SEL_M, RTC_IO_TOUCH_PAD2_SLP_IE_M, RTC_CNTL_TOUCH_PAD2_HOLD_FORCE_M, 12}, //2 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //3 + {RTC_IO_TOUCH_PAD0_REG, RTC_IO_TOUCH_PAD0_MUX_SEL_M, RTC_IO_TOUCH_PAD0_FUN_SEL_S, RTC_IO_TOUCH_PAD0_FUN_IE_M, RTC_IO_TOUCH_PAD0_RUE_M, RTC_IO_TOUCH_PAD0_RDE_M, RTC_IO_TOUCH_PAD0_SLP_SEL_M, RTC_IO_TOUCH_PAD0_SLP_IE_M, RTC_CNTL_TOUCH_PAD0_HOLD_FORCE_M, 10}, //4 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //5 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //6 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //7 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //8 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //9 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //10 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //11 + {RTC_IO_TOUCH_PAD5_REG, RTC_IO_TOUCH_PAD5_MUX_SEL_M, RTC_IO_TOUCH_PAD5_FUN_SEL_S, RTC_IO_TOUCH_PAD5_FUN_IE_M, RTC_IO_TOUCH_PAD5_RUE_M, RTC_IO_TOUCH_PAD5_RDE_M, RTC_IO_TOUCH_PAD5_SLP_SEL_M, RTC_IO_TOUCH_PAD5_SLP_IE_M, RTC_CNTL_TOUCH_PAD5_HOLD_FORCE_M, 15}, //12 + {RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_MUX_SEL_M, RTC_IO_TOUCH_PAD4_FUN_SEL_S, RTC_IO_TOUCH_PAD4_FUN_IE_M, RTC_IO_TOUCH_PAD4_RUE_M, RTC_IO_TOUCH_PAD4_RDE_M, RTC_IO_TOUCH_PAD4_SLP_SEL_M, RTC_IO_TOUCH_PAD4_SLP_IE_M, RTC_CNTL_TOUCH_PAD4_HOLD_FORCE_M, 14}, //13 + {RTC_IO_TOUCH_PAD6_REG, RTC_IO_TOUCH_PAD6_MUX_SEL_M, RTC_IO_TOUCH_PAD6_FUN_SEL_S, RTC_IO_TOUCH_PAD6_FUN_IE_M, RTC_IO_TOUCH_PAD6_RUE_M, RTC_IO_TOUCH_PAD6_RDE_M, RTC_IO_TOUCH_PAD6_SLP_SEL_M, RTC_IO_TOUCH_PAD6_SLP_IE_M, RTC_CNTL_TOUCH_PAD6_HOLD_FORCE_M, 16}, //14 + {RTC_IO_TOUCH_PAD3_REG, RTC_IO_TOUCH_PAD3_MUX_SEL_M, RTC_IO_TOUCH_PAD3_FUN_SEL_S, RTC_IO_TOUCH_PAD3_FUN_IE_M, RTC_IO_TOUCH_PAD3_RUE_M, RTC_IO_TOUCH_PAD3_RDE_M, RTC_IO_TOUCH_PAD3_SLP_SEL_M, RTC_IO_TOUCH_PAD3_SLP_IE_M, RTC_CNTL_TOUCH_PAD3_HOLD_FORCE_M, 13}, //15 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //16 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //17 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //18 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //19 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //20 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //21 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //22 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //23 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //24 + {RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_MUX_SEL_M, RTC_IO_PDAC1_FUN_SEL_S, RTC_IO_PDAC1_FUN_IE_M, RTC_IO_PDAC1_RUE_M, RTC_IO_PDAC1_RDE_M, RTC_IO_PDAC1_SLP_SEL_M, RTC_IO_PDAC1_SLP_IE_M, RTC_CNTL_PDAC1_HOLD_FORCE_M, 6}, //25 + {RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_MUX_SEL_M, RTC_IO_PDAC2_FUN_SEL_S, RTC_IO_PDAC2_FUN_IE_M, RTC_IO_PDAC2_RUE_M, RTC_IO_PDAC2_RDE_M, RTC_IO_PDAC2_SLP_SEL_M, RTC_IO_PDAC2_SLP_IE_M, RTC_CNTL_PDAC1_HOLD_FORCE_M, 7}, //26 + {RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_MUX_SEL_M, RTC_IO_TOUCH_PAD7_FUN_SEL_S, RTC_IO_TOUCH_PAD7_FUN_IE_M, RTC_IO_TOUCH_PAD7_RUE_M, RTC_IO_TOUCH_PAD7_RDE_M, RTC_IO_TOUCH_PAD7_SLP_SEL_M, RTC_IO_TOUCH_PAD7_SLP_IE_M, RTC_CNTL_TOUCH_PAD7_HOLD_FORCE_M, 17}, //27 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //28 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //29 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //30 + {0, 0, 0, 0, 0, 0, 0, 0, 0, -1}, //31 + {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32P_MUX_SEL_M, RTC_IO_X32P_FUN_SEL_S, RTC_IO_X32P_FUN_IE_M, RTC_IO_X32P_RUE_M, RTC_IO_X32P_RDE_M, RTC_IO_X32P_SLP_SEL_M, RTC_IO_X32P_SLP_IE_M, RTC_CNTL_X32P_HOLD_FORCE_M, 9}, //32 + {RTC_IO_XTAL_32K_PAD_REG, RTC_IO_X32N_MUX_SEL_M, RTC_IO_X32N_FUN_SEL_S, RTC_IO_X32N_FUN_IE_M, RTC_IO_X32N_RUE_M, RTC_IO_X32N_RDE_M, RTC_IO_X32N_SLP_SEL_M, RTC_IO_X32N_SLP_IE_M, RTC_CNTL_X32N_HOLD_FORCE_M, 8}, //33 + {RTC_IO_ADC_PAD_REG, RTC_IO_ADC1_MUX_SEL_M, RTC_IO_ADC1_FUN_SEL_S, RTC_IO_ADC1_FUN_IE_M, 0, 0, RTC_IO_ADC1_SLP_SEL_M, RTC_IO_ADC1_SLP_IE_M, RTC_CNTL_ADC1_HOLD_FORCE_M, 4}, //34 + {RTC_IO_ADC_PAD_REG, RTC_IO_ADC2_MUX_SEL_M, RTC_IO_ADC2_FUN_SEL_S, RTC_IO_ADC2_FUN_IE_M, 0, 0, RTC_IO_ADC2_SLP_SEL_M, RTC_IO_ADC2_SLP_IE_M, RTC_CNTL_ADC2_HOLD_FORCE_M, 5}, //35 + {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE1_MUX_SEL_M, RTC_IO_SENSE1_FUN_SEL_S, RTC_IO_SENSE1_FUN_IE_M, 0, 0, RTC_IO_SENSE1_SLP_SEL_M, RTC_IO_SENSE1_SLP_IE_M, RTC_CNTL_SENSE1_HOLD_FORCE_M, 0}, //36 + {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE2_MUX_SEL_M, RTC_IO_SENSE2_FUN_SEL_S, RTC_IO_SENSE2_FUN_IE_M, 0, 0, RTC_IO_SENSE2_SLP_SEL_M, RTC_IO_SENSE2_SLP_IE_M, RTC_CNTL_SENSE2_HOLD_FORCE_M, 1}, //37 + {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE3_MUX_SEL_M, RTC_IO_SENSE3_FUN_SEL_S, RTC_IO_SENSE3_FUN_IE_M, 0, 0, RTC_IO_SENSE3_SLP_SEL_M, RTC_IO_SENSE3_SLP_IE_M, RTC_CNTL_SENSE3_HOLD_FORCE_M, 2}, //38 + {RTC_IO_SENSOR_PADS_REG, RTC_IO_SENSE4_MUX_SEL_M, RTC_IO_SENSE4_FUN_SEL_S, RTC_IO_SENSE4_FUN_IE_M, 0, 0, RTC_IO_SENSE4_SLP_SEL_M, RTC_IO_SENSE4_SLP_IE_M, RTC_CNTL_SENSE4_HOLD_FORCE_M, 3}, //39 +}; + +/*--------------------------------------------------------------- + RTC IO +---------------------------------------------------------------*/ +esp_err_t rtc_gpio_init(gpio_num_t gpio_num) +{ + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + // 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module. + SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux)); + //0:RTC FUNCIOTN 1,2,3:Reserved + SET_PERI_REG_BITS(rtc_gpio_desc[gpio_num].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0x0, rtc_gpio_desc[gpio_num].func); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num) +{ + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + //Select Gpio as Digital Gpio + CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, (rtc_gpio_desc[gpio_num].mux)); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +static esp_err_t rtc_gpio_output_enable(gpio_num_t gpio_num) +{ + int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num; + RTC_MODULE_CHECK(rtc_gpio_num != -1, "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + SET_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TS_S))); + CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TC_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TC_S))); + + return ESP_OK; +} + +static esp_err_t rtc_gpio_output_disable(gpio_num_t gpio_num) +{ + int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num; + RTC_MODULE_CHECK(rtc_gpio_num != -1, "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_ENABLE_W1TS_S))); + SET_PERI_REG_MASK(RTC_GPIO_ENABLE_W1TC_REG, (1 << ( rtc_gpio_num + RTC_GPIO_ENABLE_W1TC_S))); + + return ESP_OK; +} + +static esp_err_t rtc_gpio_input_enable(gpio_num_t gpio_num) +{ + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +static esp_err_t rtc_gpio_input_disable(gpio_num_t gpio_num) +{ + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].ie); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level) +{ + int rtc_gpio_num = rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;; + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + + if (level) { + WRITE_PERI_REG(RTC_GPIO_OUT_W1TS_REG, (1 << (rtc_gpio_num + RTC_GPIO_OUT_DATA_W1TS_S))); + } else { + WRITE_PERI_REG(RTC_GPIO_OUT_W1TC_REG, (1 << (rtc_gpio_num + RTC_GPIO_OUT_DATA_W1TC_S))); + } + + return ESP_OK; +} + +uint32_t rtc_gpio_get_level(gpio_num_t gpio_num) +{ + uint32_t level = 0; + int rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num; + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + + portENTER_CRITICAL(&rtc_spinlock); + level = READ_PERI_REG(RTC_GPIO_IN_REG); + portEXIT_CRITICAL(&rtc_spinlock); + return ((level >> (RTC_GPIO_IN_NEXT_S + rtc_gpio_num)) & 0x01); +} + +esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode) +{ + RTC_MODULE_CHECK(RTC_GPIO_IS_VALID_GPIO(gpio_num), "RTC_GPIO number error", ESP_ERR_INVALID_ARG); + + switch (mode) { + case RTC_GPIO_MODE_INPUT_ONLY: + rtc_gpio_output_disable(gpio_num); + rtc_gpio_input_enable(gpio_num); + break; + case RTC_GPIO_MODE_OUTPUT_ONLY: + rtc_gpio_output_enable(gpio_num); + rtc_gpio_input_disable(gpio_num); + break; + case RTC_GPIO_MODE_INPUT_OUTUT: + rtc_gpio_output_enable(gpio_num); + rtc_gpio_input_enable(gpio_num); + break; + case RTC_GPIO_MODE_DISABLED: + rtc_gpio_output_disable(gpio_num); + rtc_gpio_input_disable(gpio_num); + break; + } + + return ESP_OK; +} + +esp_err_t rtc_gpio_pullup_en(gpio_num_t gpio_num) +{ + //this is a digital pad + if (rtc_gpio_desc[gpio_num].pullup == 0) { + return ESP_FAIL; + } + + //this is a rtc pad + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t rtc_gpio_pulldown_en(gpio_num_t gpio_num) +{ + //this is a digital pad + if (rtc_gpio_desc[gpio_num].pulldown == 0) { + return ESP_FAIL; + } + + //this is a rtc pad + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t rtc_gpio_pullup_dis(gpio_num_t gpio_num) +{ + //this is a digital pad + if ( rtc_gpio_desc[gpio_num].pullup == 0 ) { + return ESP_FAIL; + } + + //this is a rtc pad + portENTER_CRITICAL(&rtc_spinlock); + CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pullup); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num) +{ + //this is a digital pad + if (rtc_gpio_desc[gpio_num].pulldown == 0) { + return ESP_FAIL; + } + + //this is a rtc pad + portENTER_CRITICAL(&rtc_spinlock); + CLEAR_PERI_REG_MASK(rtc_gpio_desc[gpio_num].reg, rtc_gpio_desc[gpio_num].pulldown); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +void rtc_gpio_unhold_all() +{ + for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { + const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio]; + if (desc->hold != 0) { + REG_CLR_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold); + } + } +} + + +/*--------------------------------------------------------------- + Touch Pad +---------------------------------------------------------------*/ +esp_err_t touch_pad_isr_handler_register(void(*fn)(void *), void *arg, int intr_alloc_flags, touch_isr_handle_t *handle) +{ + RTC_MODULE_CHECK(fn, "Touch_Pad ISR null", ESP_ERR_INVALID_ARG); + return esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); +} + +static esp_err_t touch_pad_get_io_num(touch_pad_t touch_num, gpio_num_t *gpio_num) +{ + switch (touch_num) { + case TOUCH_PAD_NUM0: + *gpio_num = 4; + break; + case TOUCH_PAD_NUM1: + *gpio_num = 0; + break; + case TOUCH_PAD_NUM2: + *gpio_num = 2; + break; + case TOUCH_PAD_NUM3: + *gpio_num = 15; + break; + case TOUCH_PAD_NUM4: + *gpio_num = 13; + break; + case TOUCH_PAD_NUM5: + *gpio_num = 12; + break; + case TOUCH_PAD_NUM6: + *gpio_num = 14; + break; + case TOUCH_PAD_NUM7: + *gpio_num = 27; + break; + case TOUCH_PAD_NUM8: + *gpio_num = 33; + break; + case TOUCH_PAD_NUM9: + *gpio_num = 32; + break; + default: + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; +} + +static esp_err_t touch_pad_init_config(uint16_t sleep_cycle, uint16_t sample_cycle_num) +{ + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S); + SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR); + //clear touch enable + WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0); + //enable Rtc Touch pad Timer + SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN); + //config pad module sleep time and sample num + //Touch pad SleepCycle Time = 150Khz + SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_SLEEP_CYCLES, sleep_cycle, SENS_TOUCH_SLEEP_CYCLES_S);//150kHZ + //Touch Pad Measure Time= 8Mhz + SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, sample_cycle_num, SENS_TOUCH_MEAS_DELAY_S); //8Mhz + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +void touch_pad_init() +{ + touch_pad_init_config(TOUCH_PAD_SLEEP_CYCLE_CONFIG, TOUCH_PAD_MEASURE_CYCLE_CONFIG); +} + +static void touch_pad_counter_init(touch_pad_t touch_num) +{ + portENTER_CRITICAL(&rtc_spinlock); + //Enable Tie,Init Level(Counter) + SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_TIE_OPT_M); + //Touch Set Slop(Counter) + SET_PERI_REG_BITS(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_DAC_V, 7, RTC_IO_TOUCH_PAD0_DAC_S); + //Enable Touch Pad IO + SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_START_M); + portEXIT_CRITICAL(&rtc_spinlock); +} + +static void touch_pad_power_on(touch_pad_t touch_num) +{ + portENTER_CRITICAL(&rtc_spinlock); + //Enable Touch Pad Power on + SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + touch_num * 4, RTC_IO_TOUCH_PAD0_XPD_M); + portEXIT_CRITICAL(&rtc_spinlock); +} + +static void toch_pad_io_init(touch_pad_t touch_num) +{ + gpio_num_t gpio_num = GPIO_NUM_0; + touch_pad_get_io_num(touch_num, &gpio_num); + rtc_gpio_init(gpio_num); + rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED); + rtc_gpio_pulldown_dis(gpio_num); + rtc_gpio_pullup_dis(gpio_num); +} + +static esp_err_t touch_start(touch_pad_t touch_num) +{ + RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + + //Enable Digital rtc control :work mode and out mode + SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num + SENS_TOUCH_PAD_WORKEN_S)) | \ + (1 << (touch_num + SENS_TOUCH_PAD_OUTEN2_S)) | \ + (1 << (touch_num + SENS_TOUCH_PAD_OUTEN1_S))); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold) +{ + RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + //clear touch force ,select the Touch mode is Timer + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M); + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M); + //set threshold + uint8_t shift; + shift = (touch_num & 1) ? SENS_TOUCH_OUT_TH1_S : SENS_TOUCH_OUT_TH0_S; + SET_PERI_REG_BITS((SENS_SAR_TOUCH_THRES1_REG + (touch_num / 2) * 4), SENS_TOUCH_OUT_TH0, threshold, shift); + //When touch value < threshold ,the Intr will give + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_SEL); + //Intr will give ,when SET0 < threshold + SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_OUT_1EN); + //Enable Rtc Touch Module Intr,the Interrupt need Rtc out Enable + SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_TOUCH_INT_ENA); + portEXIT_CRITICAL(&rtc_spinlock); + touch_pad_power_on(touch_num); + toch_pad_io_init(touch_num); + touch_pad_counter_init(touch_num); + touch_start(touch_num); + + return ESP_OK; +} + +esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value) +{ + RTC_MODULE_CHECK(touch_num < TOUCH_PAD_MAX, "Touch_Pad Num Err", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(touch_value!=NULL, "touch_value", ESP_ERR_INVALID_ARG); + uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG); + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num))); + //Disable Intr + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_ENABLE_REG, (1 << (touch_num + SENS_TOUCH_PAD_OUTEN2_S)) | \ + ((1 << (touch_num + SENS_TOUCH_PAD_OUTEN1_S)))); + toch_pad_io_init(touch_num); + touch_pad_counter_init(touch_num); + touch_pad_power_on(touch_num); + //force oneTime test start + SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M); + SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M); + SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_XPD_WAIT, 10, SENS_TOUCH_XPD_WAIT_S); + while (GET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_DONE) == 0) {}; + uint8_t shift = (touch_num & 1) ? SENS_TOUCH_MEAS_OUT1_S : SENS_TOUCH_MEAS_OUT0_S; + *touch_value = READ_PERI_REG(SENS_SAR_TOUCH_OUT1_REG + (touch_num / 2) * 4) >> shift; + WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0); + //force oneTime test end + //clear touch force ,select the Touch mode is Timer + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M); + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_FORCE_M); + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +/*--------------------------------------------------------------- + ADC +---------------------------------------------------------------*/ +static esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_num) +{ + RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); + + switch (channel) { + case ADC1_CHANNEL_0: + *gpio_num = 36; + break; + case ADC1_CHANNEL_1: + *gpio_num = 37; + break; + case ADC1_CHANNEL_2: + *gpio_num = 38; + break; + case ADC1_CHANNEL_3: + *gpio_num = 39; + break; + case ADC1_CHANNEL_4: + *gpio_num = 32; + break; + case ADC1_CHANNEL_5: + *gpio_num = 33; + break; + case ADC1_CHANNEL_6: + *gpio_num = 34; + break; + case ADC1_CHANNEL_7: + *gpio_num = 35; + break; + default: + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; +} + +static esp_err_t adc1_pad_init(adc1_channel_t channel) +{ + gpio_num_t gpio_num = 0; + ADC1_CHECK_FUNCTION_RET(adc1_pad_get_io_num(channel, &gpio_num)); + ADC1_CHECK_FUNCTION_RET(rtc_gpio_init(gpio_num)); + ADC1_CHECK_FUNCTION_RET(rtc_gpio_output_disable(gpio_num)); + ADC1_CHECK_FUNCTION_RET(rtc_gpio_input_disable(gpio_num)); + ADC1_CHECK_FUNCTION_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING)); + + return ESP_OK; +} + +esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten) +{ + RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); + RTC_MODULE_CHECK(atten <= ADC_ATTEN_11db, "ADC Atten Err", ESP_ERR_INVALID_ARG); + adc1_pad_init(channel); + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, atten, (channel * 2)); //SAR1_atten + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +esp_err_t adc1_config_width(adc_bits_width_t width_bit) +{ + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH_V, width_bit, SENS_SAR1_BIT_WIDTH_S); //SAR2_BIT_WIDTH[1:0]=0x3, SAR1_BIT_WIDTH[1:0]=0x3 + //Invert the adc value,the Output value is invert + SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV); + //Set The adc sample width,invert adc value,must + SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT_V, width_bit, SENS_SAR1_SAMPLE_BIT_S); //digital sar1_bit_width[1:0]=3 + portEXIT_CRITICAL(&rtc_spinlock); + + return ESP_OK; +} + +int adc1_get_voltage(adc1_channel_t channel) +{ + uint16_t adc_value; + + RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + //Adc Controler is Rtc module,not ulp coprocessor + SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_MEAS1_START_FORCE_S); //force pad mux and force start + //Bit1=0:Fsm Bit1=1(Bit0=0:PownDown Bit10=1:Powerup) + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); //force XPD_SAR=0, use XPD_FSM + //Disable Amp Bit1=0:Fsm Bit1=1(Bit0=0:PownDown Bit10=1:Powerup) + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0 + //Open the ADC1 Data port Not ulp coprocessor + SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_SAR1_EN_PAD_FORCE_S); //open the ADC1 data port + //Select channel + SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S); //pad enable + SET_PERI_REG_BITS(SENS_SAR_MEAS_CTRL_REG, 0xfff, 0x0, SENS_AMP_RST_FB_FSM_S); //[11:8]:short ref ground, [7:4]:short ref, [3:0]:rst fb + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S); + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S); + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S); + while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==0 + SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 0, SENS_MEAS1_START_SAR_S); //start force 0 + SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_MEAS1_START_SAR_S); //start force 1 + while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0) {}; //read done + adc_value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S); + portEXIT_CRITICAL(&rtc_spinlock); + + return adc_value; +} + +/*--------------------------------------------------------------- + DAC +---------------------------------------------------------------*/ +static esp_err_t dac_pad_get_io_num(dac_channel_t channel, gpio_num_t *gpio_num) +{ + RTC_MODULE_CHECK(channel < DAC_CHANNEL_MAX, "DAC Channel Err", ESP_ERR_INVALID_ARG); + + switch (channel) { + case DAC_CHANNEL_1: + *gpio_num = 25; + break; + case DAC_CHANNEL_2: + *gpio_num = 26; + break; + default: + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; +} + +static esp_err_t dac_rtc_pad_init(dac_channel_t channel) +{ + RTC_MODULE_CHECK(channel < DAC_CHANNEL_MAX, "DAC Channel Err", ESP_ERR_INVALID_ARG); + gpio_num_t gpio_num = 0; + dac_pad_get_io_num(channel, &gpio_num); + rtc_gpio_init(gpio_num); + rtc_gpio_output_disable(gpio_num); + rtc_gpio_input_disable(gpio_num); + rtc_gpio_pullup_dis(gpio_num); + rtc_gpio_pulldown_dis(gpio_num); + + return ESP_OK; +} + +static esp_err_t dac_out_enable(dac_channel_t channel) +{ + if (channel == DAC_CHANNEL_1) { + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE); + portEXIT_CRITICAL(&rtc_spinlock); + } else if (channel == DAC_CHANNEL_2) { + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE); + portEXIT_CRITICAL(&rtc_spinlock); + } else { + return ESP_ERR_INVALID_ARG; + } + + return ESP_OK; +} + +esp_err_t dac_out_voltage(dac_channel_t channel, uint8_t dac_value) +{ + RTC_MODULE_CHECK(channel < DAC_CHANNEL_MAX, "DAC Channel Err", ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&rtc_spinlock); + //Disable Tone + CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN); + + //Disable Channel Tone + if (channel == DAC_CHANNEL_1) { + CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M); + } else if (channel == DAC_CHANNEL_2) { + CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN2_M); + } + + //Set the Dac value + if (channel == DAC_CHANNEL_1) { + SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, dac_value, RTC_IO_PDAC1_DAC_S); //dac_output + } else if (channel == DAC_CHANNEL_2) { + SET_PERI_REG_BITS(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_DAC, dac_value, RTC_IO_PDAC2_DAC_S); //dac_output + } + + portEXIT_CRITICAL(&rtc_spinlock); + //dac pad init + dac_rtc_pad_init(channel); + dac_out_enable(channel); + + return ESP_OK; +} + +/*--------------------------------------------------------------- + HALL SENSOR +---------------------------------------------------------------*/ +static int hall_sensor_get_value() //hall sensor without LNA +{ + int Sens_Vp0; + int Sens_Vn0; + int Sens_Vp1; + int Sens_Vn1; + int hall_value; + + portENTER_CRITICAL(&rtc_spinlock); + SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_XPD_HALL_FORCE_M); // hall sens force enable + SET_PERI_REG_MASK(RTC_IO_HALL_SENS_REG, RTC_IO_XPD_HALL); // xpd hall + SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_HALL_PHASE_FORCE_M); // phase force + CLEAR_PERI_REG_MASK(RTC_IO_HALL_SENS_REG, RTC_IO_HALL_PHASE); // hall phase + Sens_Vp0 = adc1_get_voltage(ADC1_CHANNEL_0); + Sens_Vn0 = adc1_get_voltage(ADC1_CHANNEL_3); + SET_PERI_REG_MASK(RTC_IO_HALL_SENS_REG, RTC_IO_HALL_PHASE); + Sens_Vp1 = adc1_get_voltage(ADC1_CHANNEL_0); + Sens_Vn1 = adc1_get_voltage(ADC1_CHANNEL_3); + SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_XPD_HALL_FORCE); + CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_HALL_PHASE_FORCE); + portEXIT_CRITICAL(&rtc_spinlock); + hall_value = (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0); + + return hall_value; +} + +int hall_sensor_read() +{ + adc1_pad_init(ADC1_CHANNEL_0); + adc1_pad_init(ADC1_CHANNEL_3); + adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_0db); + adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_0db); + return hall_sensor_get_value(); +} diff --git a/components/driver/sigmadelta.c b/components/driver/sigmadelta.c new file mode 100644 index 0000000000..09969e6631 --- /dev/null +++ b/components/driver/sigmadelta.c @@ -0,0 +1,61 @@ +// 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_log.h" +#include "soc/soc.h" +#include "driver/periph_ctrl.h" +#include "driver/sigmadelta.h" + +static const char* SIGMADELTA_TAG = "SIGMADELTA"; +#define SIGMADELTA_CHANNEL_ERR_STR "SIGMADELTA CHANNEL ERROR" +#define SIGMADELTA_IO_ERR_STR "SIGMADELTA GPIO NUM ERROR" + +#define SIGMADELTA_CHECK(a,str,ret_val) if(!(a)) { \ + ESP_LOGE(SIGMADELTA_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ + return (ret_val); \ + } + +esp_err_t sigmadelta_config(sigmadelta_config_t *config) +{ + SIGMADELTA_CHECK(config->channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG); + SIGMADELTA_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(config->sigmadelta_gpio), SIGMADELTA_IO_ERR_STR, ESP_ERR_INVALID_ARG); + sigmadelta_set_duty(config->channel, config->sigmadelta_duty); + sigmadelta_set_prescale(config->channel, config->sigmadelta_prescale); + sigmadelta_set_pin(config->channel, config->sigmadelta_gpio); + return ESP_OK; +} + +esp_err_t sigmadelta_set_duty(sigmadelta_channel_t channel, int8_t duty) +{ + SIGMADELTA_CHECK(channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG); + SIGMADELTA.channel[channel].duty = duty; + return ESP_OK; +} + +esp_err_t sigmadelta_set_prescale(sigmadelta_channel_t channel, uint8_t prescale) +{ + SIGMADELTA_CHECK(channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG); + SIGMADELTA.channel[channel].prescale = prescale; + return ESP_OK; +} + +esp_err_t sigmadelta_set_pin(sigmadelta_channel_t channel, gpio_num_t gpio_num) +{ + SIGMADELTA_CHECK(channel < SIGMADELTA_CHANNEL_MAX, SIGMADELTA_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG); + SIGMADELTA_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), SIGMADELTA_IO_ERR_STR, ESP_ERR_INVALID_ARG); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO); + gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT); + gpio_matrix_out(gpio_num, GPIO_SD0_OUT_IDX + channel, 0, 0); + return ESP_OK; +} + diff --git a/components/driver/timer.c b/components/driver/timer.c index b305a41468..de968c5e2a 100644 --- a/components/driver/timer.c +++ b/components/driver/timer.c @@ -1,275 +1,280 @@ -// 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 -#include "esp_log.h" -#include "esp_err.h" -#include "esp_intr.h" -#include "freertos/FreeRTOS.h" -#include "freertos/xtensa_api.h" -#include "driver/timer.h" -#include "driver/periph_ctrl.h" - -static const char* TIMER_TAG = "TIMER_GROUP"; -#define TIMER_CHECK(a, str, ret_val) if (!(a)) { \ - ESP_LOGE(TIMER_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ - return (ret_val); \ - } -#define TIMER_GROUP_NUM_ERROR "TIMER GROUP NUM ERROR" -#define TIMER_NUM_ERROR "HW TIMER NUM ERROR" -#define TIMER_PARAM_ADDR_ERROR "HW TIMER PARAM ADDR ERROR" -#define TIMER_COUNT_DIR_ERROR "HW TIMER COUNTER DIR ERROR" -#define TIMER_AUTORELOAD_ERROR "HW TIMER AUTORELOAD ERROR" -#define TIMER_SCALE_ERROR "HW TIMER SCALE ERROR" -#define TIMER_ALARM_ERROR "HW TIMER ALARM ERROR" -static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; -static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; - -#define TIMER_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux); -#define TIMER_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux); - -esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* timer_val) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_val != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); - portENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].update = 1; - *timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32) - | (TG[group_num]->hw_timer[timer_num].cnt_low); - portEXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double* time) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(time != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); - - uint64_t timer_val; - esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val); - if (err == ESP_OK) { - uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider; - *time = (double)timer_val * div / TIMER_BASE_CLK; - } - return err; -} - -esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].load_high = (uint32_t) (load_val >> 32); - TG[group_num]->hw_timer[timer_num].load_low = (uint32_t) load_val; - TG[group_num]->hw_timer[timer_num].reload = 1; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].config.enable = 1; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].config.enable = 0; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(counter_dir < TIMER_COUNT_MAX, TIMER_COUNT_DIR_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].config.increase = counter_dir; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(reload < TIMER_AUTORELOAD_MAX, TIMER_AUTORELOAD_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].config.autoreload = reload; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint16_t divider) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - int timer_en = TG[group_num]->hw_timer[timer_num].config.enable; - TG[group_num]->hw_timer[timer_num].config.enable = 0; - TG[group_num]->hw_timer[timer_num].config.divider = divider; - TG[group_num]->hw_timer[timer_num].config.enable = timer_en; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].alarm_high = (uint32_t) (alarm_value >> 32); - TG[group_num]->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* alarm_value) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(alarm_value != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); - portENTER_CRITICAL(&timer_spinlock[group_num]); - *alarm_value = ((uint64_t) TG[group_num]->hw_timer[timer_num].alarm_high << 32) - | (TG[group_num]->hw_timer[timer_num].alarm_low); - portEXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(alarm_en < TIMER_ALARM_MAX, TIMER_ALARM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].config.alarm_en = alarm_en; - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -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) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(fn != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); - - ESP_INTR_DISABLE(timer_intr_num); - int intr_source = 0; - switch(group_num) { - case TIMER_GROUP_0: - default: - if(intr_type == TIMER_INTR_LEVEL) { - intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer_num; - } else { - intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer_num; - } - break; - case TIMER_GROUP_1: - if(intr_type == TIMER_INTR_LEVEL) { - intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer_num; - } else { - intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer_num; - } - break; - } - intr_matrix_set(xPortGetCoreID(), intr_source, timer_intr_num); - xt_set_interrupt_handler(timer_intr_num, fn, arg); - ESP_INTR_ENABLE(timer_intr_num); - return ESP_OK; -} - -esp_err_t timer_init(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(config != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); - - if(group_num == 0) { - periph_module_enable(PERIPH_TIMG0_MODULE); - } else if(group_num == 1) { - periph_module_enable(PERIPH_TIMG1_MODULE); - } - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->hw_timer[timer_num].config.autoreload = config->auto_reload; - TG[group_num]->hw_timer[timer_num].config.divider = config->divider; - TG[group_num]->hw_timer[timer_num].config.enable = config->counter_en; - TG[group_num]->hw_timer[timer_num].config.increase = config->counter_dir; - TG[group_num]->hw_timer[timer_num].config.alarm_en = config->alarm_en; - TG[group_num]->hw_timer[timer_num].config.level_int_en = (config->intr_type == TIMER_INTR_LEVEL ? 1 : 0); - TG[group_num]->hw_timer[timer_num].config.edge_int_en = (config->intr_type == TIMER_INTR_LEVEL ? 0 : 1); - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(config != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); - TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); - config->alarm_en = TG[group_num]->hw_timer[timer_num].config.alarm_en; - config->auto_reload = TG[group_num]->hw_timer[timer_num].config.autoreload; - config->counter_dir = TG[group_num]->hw_timer[timer_num].config.increase; - config->counter_dir = TG[group_num]->hw_timer[timer_num].config.divider; - config->counter_en = TG[group_num]->hw_timer[timer_num].config.enable; - if(TG[group_num]->hw_timer[timer_num].config.level_int_en) { - config->intr_type =TIMER_INTR_LEVEL; - } - TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - portENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->int_ena.val |= en_mask; - portEXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mask) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - portENTER_CRITICAL(&timer_spinlock[group_num]); - TG[group_num]->int_ena.val &= (~disable_mask); - portEXIT_CRITICAL(&timer_spinlock[group_num]); - return ESP_OK; -} - -esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - return timer_group_intr_enable(group_num, BIT(timer_num)); -} - -esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num) -{ - TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); - TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); - return timer_group_intr_disable(group_num, BIT(timer_num)); -} - - +// 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 +#include "esp_log.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/timer.h" +#include "driver/periph_ctrl.h" + +static const char* TIMER_TAG = "timer_group"; +#define TIMER_CHECK(a, str, ret_val) \ + if (!(a)) { \ + ESP_LOGE(TIMER_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ + return (ret_val); \ + } + +#define TIMER_GROUP_NUM_ERROR "TIMER GROUP NUM ERROR" +#define TIMER_NUM_ERROR "HW TIMER NUM ERROR" +#define TIMER_PARAM_ADDR_ERROR "HW TIMER PARAM ADDR ERROR" +#define TIMER_COUNT_DIR_ERROR "HW TIMER COUNTER DIR ERROR" +#define TIMER_AUTORELOAD_ERROR "HW TIMER AUTORELOAD ERROR" +#define TIMER_SCALE_ERROR "HW TIMER SCALE ERROR" +#define TIMER_ALARM_ERROR "HW TIMER ALARM ERROR" +static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1}; +static portMUX_TYPE timer_spinlock[TIMER_GROUP_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; + +#define TIMER_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux); +#define TIMER_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux); + +esp_err_t timer_get_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* timer_val) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_val != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].update = 1; + *timer_val = ((uint64_t) TG[group_num]->hw_timer[timer_num].cnt_high << 32) + | (TG[group_num]->hw_timer[timer_num].cnt_low); + portEXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_get_counter_time_sec(timer_group_t group_num, timer_idx_t timer_num, double* time) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(time != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); + + uint64_t timer_val; + esp_err_t err = timer_get_counter_value(group_num, timer_num, &timer_val); + if (err == ESP_OK) { + uint16_t div = TG[group_num]->hw_timer[timer_num].config.divider; + *time = (double)timer_val * div / TIMER_BASE_CLK; + } + return err; +} + +esp_err_t timer_set_counter_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t load_val) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].load_high = (uint32_t) (load_val >> 32); + TG[group_num]->hw_timer[timer_num].load_low = (uint32_t) load_val; + TG[group_num]->hw_timer[timer_num].reload = 1; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_start(timer_group_t group_num, timer_idx_t timer_num) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].config.enable = 1; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_pause(timer_group_t group_num, timer_idx_t timer_num) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].config.enable = 0; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_set_counter_mode(timer_group_t group_num, timer_idx_t timer_num, timer_count_dir_t counter_dir) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(counter_dir < TIMER_COUNT_MAX, TIMER_COUNT_DIR_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].config.increase = counter_dir; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_set_auto_reload(timer_group_t group_num, timer_idx_t timer_num, timer_autoreload_t reload) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(reload < TIMER_AUTORELOAD_MAX, TIMER_AUTORELOAD_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].config.autoreload = reload; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_set_divider(timer_group_t group_num, timer_idx_t timer_num, uint16_t divider) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + int timer_en = TG[group_num]->hw_timer[timer_num].config.enable; + TG[group_num]->hw_timer[timer_num].config.enable = 0; + TG[group_num]->hw_timer[timer_num].config.divider = divider; + TG[group_num]->hw_timer[timer_num].config.enable = timer_en; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_set_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t alarm_value) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].alarm_high = (uint32_t) (alarm_value >> 32); + TG[group_num]->hw_timer[timer_num].alarm_low = (uint32_t) alarm_value; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_get_alarm_value(timer_group_t group_num, timer_idx_t timer_num, uint64_t* alarm_value) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(alarm_value != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&timer_spinlock[group_num]); + *alarm_value = ((uint64_t) TG[group_num]->hw_timer[timer_num].alarm_high << 32) + | (TG[group_num]->hw_timer[timer_num].alarm_low); + portEXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_set_alarm(timer_group_t group_num, timer_idx_t timer_num, timer_alarm_t alarm_en) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(alarm_en < TIMER_ALARM_MAX, TIMER_ALARM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->hw_timer[timer_num].config.alarm_en = alarm_en; + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +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) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(fn != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); + + int intr_source = 0; + uint32_t status_reg = 0; + int mask = 0; + switch(group_num) { + case TIMER_GROUP_0: + default: + if((intr_alloc_flags & ESP_INTR_FLAG_EDGE) == 0) { + intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer_num; + } else { + intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer_num; + } + status_reg = TIMG_INT_ST_TIMERS_REG(0); + mask = 1<hw_timer[timer_num].config.autoreload = config->auto_reload; + TG[group_num]->hw_timer[timer_num].config.divider = config->divider; + TG[group_num]->hw_timer[timer_num].config.enable = config->counter_en; + TG[group_num]->hw_timer[timer_num].config.increase = config->counter_dir; + TG[group_num]->hw_timer[timer_num].config.alarm_en = config->alarm_en; + TG[group_num]->hw_timer[timer_num].config.level_int_en = (config->intr_type == TIMER_INTR_LEVEL ? 1 : 0); + TG[group_num]->hw_timer[timer_num].config.edge_int_en = (config->intr_type == TIMER_INTR_LEVEL ? 0 : 1); + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_get_config(timer_group_t group_num, timer_idx_t timer_num, timer_config_t *config) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(config != NULL, TIMER_PARAM_ADDR_ERROR, ESP_ERR_INVALID_ARG); + TIMER_ENTER_CRITICAL(&timer_spinlock[group_num]); + config->alarm_en = TG[group_num]->hw_timer[timer_num].config.alarm_en; + config->auto_reload = TG[group_num]->hw_timer[timer_num].config.autoreload; + config->counter_dir = TG[group_num]->hw_timer[timer_num].config.increase; + config->counter_dir = TG[group_num]->hw_timer[timer_num].config.divider; + config->counter_en = TG[group_num]->hw_timer[timer_num].config.enable; + if(TG[group_num]->hw_timer[timer_num].config.level_int_en) { + config->intr_type =TIMER_INTR_LEVEL; + } + TIMER_EXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_group_intr_enable(timer_group_t group_num, uint32_t en_mask) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->int_ena.val |= en_mask; + portEXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_group_intr_disable(timer_group_t group_num, uint32_t disable_mask) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + portENTER_CRITICAL(&timer_spinlock[group_num]); + TG[group_num]->int_ena.val &= (~disable_mask); + portEXIT_CRITICAL(&timer_spinlock[group_num]); + return ESP_OK; +} + +esp_err_t timer_enable_intr(timer_group_t group_num, timer_idx_t timer_num) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + return timer_group_intr_enable(group_num, BIT(timer_num)); +} + +esp_err_t timer_disable_intr(timer_group_t group_num, timer_idx_t timer_num) +{ + TIMER_CHECK(group_num < TIMER_GROUP_MAX, TIMER_GROUP_NUM_ERROR, ESP_ERR_INVALID_ARG); + TIMER_CHECK(timer_num < TIMER_MAX, TIMER_NUM_ERROR, ESP_ERR_INVALID_ARG); + return timer_group_intr_disable(group_num, BIT(timer_num)); +} + + diff --git a/components/driver/uart.c b/components/driver/uart.c index 59b4904dcd..e85c54d8c4 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -1,1028 +1,1067 @@ -// 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 -#include "esp_types.h" -#include "esp_attr.h" -#include "esp_intr.h" -#include "esp_log.h" -#include "malloc.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/xtensa_api.h" -#include "freertos/task.h" -#include "freertos/ringbuf.h" -#include "soc/dport_reg.h" -#include "soc/uart_struct.h" -#include "driver/uart.h" -#include "driver/gpio.h" - -static const char* UART_TAG = "UART"; -#define UART_CHECK(a, str, ret) if (!(a)) { \ - ESP_LOGE(UART_TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ - return (ret); \ - } -#define UART_EMPTY_THRESH_DEFAULT (10) -#define UART_FULL_THRESH_DEFAULT (120) -#define UART_TOUT_THRESH_DEFAULT (10) -#define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux) -#define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux) -#define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) -#define UART_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) - -typedef struct { - uart_event_type_t type; /*!< UART TX data type */ - struct { - int brk_len; - size_t size; - uint8_t data[0]; - } tx_data; -} uart_tx_data_t; - -typedef struct { - uart_port_t uart_num; /*!< UART port number*/ - int queue_size; /*!< UART event queue size*/ - QueueHandle_t xQueueUart; /*!< UART queue handler*/ - int intr_num; /*!< UART interrupt number*/ - //rx parameters - SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/ - int rx_buf_size; /*!< RX ring buffer size */ - RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/ - bool rx_buffer_full_flg; /*!< RX ring buffer full flag. */ - int rx_cur_remain; /*!< Data number that waiting to be read out in ring buffer item*/ - uint8_t* rx_ptr; /*!< pointer to the current data in ring buffer*/ - uint8_t* rx_head_ptr; /*!< pointer to the head of RX item*/ - uint8_t rx_data_buf[UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/ - uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */ - //tx parameters - SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/ - SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/ - SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/ - SemaphoreHandle_t tx_brk_sem; /*!< UART TX send break done semaphore*/ - int tx_buf_size; /*!< TX ring buffer size */ - RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/ - bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/ - uint8_t* tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/ - uart_tx_data_t* tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/ - uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/ - uint32_t tx_len_cur; - uint8_t tx_brk_flg; /*!< Flag to indicate to send a break signal in the end of the item sending procedure */ - uint8_t tx_brk_len; /*!< TX break signal cycle length/number */ - uint8_t tx_waiting_brk; /*!< Flag to indicate that TX FIFO is ready to send break signal after FIFO is empty, do not push data into TX FIFO right now.*/ -} uart_obj_t; - - - -static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; -/* DRAM_ATTR is required to avoid UART array placed in flash, due to accessed from ISR */ -static DRAM_ATTR uart_dev_t* const UART[UART_NUM_MAX] = {&UART0, &UART1, &UART2}; -static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; - -esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((data_bit < UART_DATA_BITS_MAX), "data bit error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->conf0.bit_num = data_bit; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - *(data_bit) = UART[uart_num]->conf0.bit_num; - return ESP_OK; -} - -esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->conf0.stop_bit_num = stop_bit; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - (*stop_bit) = UART[uart_num]->conf0.stop_bit_num; - return ESP_OK; -} - -esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->conf0.parity = parity_mode & 0x1; - UART[uart_num]->conf0.parity_en = (parity_mode >> 1) & 0x1; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - int val = UART[uart_num]->conf0.val; - if(val & UART_PARITY_EN_M) { - if(val & UART_PARITY_M) { - (*parity_mode) = UART_PARITY_ODD; - } else { - (*parity_mode) = UART_PARITY_EVEN; - } - } else { - (*parity_mode) = UART_PARITY_DISABLE; - } - return ESP_OK; -} - -esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((baud_rate < UART_BITRATE_MAX), "baud_rate error", ESP_FAIL); - uint32_t clk_div = (((UART_CLK_FREQ) << 4) / baud_rate); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->clk_div.div_int = clk_div >> 4; - UART[uart_num]->clk_div.div_frag = clk_div & 0xf; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - uint32_t clk_div = (UART[uart_num]->clk_div.div_int << 4) | UART[uart_num]->clk_div.div_frag; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - (*baudrate) = ((UART_CLK_FREQ) << 4) / clk_div; - return ESP_OK; -} - -esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((((inverse_mask & UART_LINE_INV_MASK) == 0) && (inverse_mask != 0)), "inverse_mask error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - CLEAR_PERI_REG_MASK(UART_CONF0_REG(uart_num), UART_LINE_INV_MASK); - SET_PERI_REG_MASK(UART_CONF0_REG(uart_num), inverse_mask); - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. -esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((rx_thresh < UART_FIFO_LEN), "rx flow thresh error", ESP_FAIL); - UART_CHECK((flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - if(flow_ctrl & UART_HW_FLOWCTRL_RTS) { - UART[uart_num]->conf1.rx_flow_thrhd = rx_thresh; - UART[uart_num]->conf1.rx_flow_en = 1; - } else { - UART[uart_num]->conf1.rx_flow_en = 0; - } - if(flow_ctrl & UART_HW_FLOWCTRL_CTS) { - UART[uart_num]->conf0.tx_flow_en = 1; - } else { - UART[uart_num]->conf0.tx_flow_en = 0; - } - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - uart_hw_flowcontrol_t val = UART_HW_FLOWCTRL_DISABLE; - if(UART[uart_num]->conf1.rx_flow_en) { - val |= UART_HW_FLOWCTRL_RTS; - } - if(UART[uart_num]->conf0.tx_flow_en) { - val |= UART_HW_FLOWCTRL_CTS; - } - (*flow_ctrl) = val; - return ESP_OK; -} - -static esp_err_t uart_reset_fifo(uart_port_t uart_num) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->conf0.rxfifo_rst = 1; - UART[uart_num]->conf0.rxfifo_rst = 0; - UART[uart_num]->conf0.txfifo_rst = 1; - UART[uart_num]->conf0.txfifo_rst = 0; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - //intr_clr register is write-only - UART[uart_num]->int_clr.val = clr_mask; - return ESP_OK; -} - -esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - SET_PERI_REG_MASK(UART_INT_CLR_REG(uart_num), enable_mask); - SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), enable_mask); - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), disable_mask); - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_enable_rx_intr(uart_port_t uart_num) -{ - uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); - return ESP_OK; -} - -esp_err_t uart_disable_rx_intr(uart_port_t uart_num) -{ - uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); - return ESP_OK; -} - -esp_err_t uart_disable_tx_intr(uart_port_t uart_num) -{ - uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA); - return ESP_OK; -} - -esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((thresh < UART_FIFO_LEN), "empty intr threshold error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->int_clr.txfifo_empty = 1; - UART[uart_num]->conf1.txfifo_empty_thrhd = thresh & UART_TXFIFO_EMPTY_THRHD_V; - UART[uart_num]->int_ena.txfifo_empty = enable & 0x1; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - ESP_INTR_ENABLE(p_uart_obj[uart_num]->intr_num); - return ESP_OK; -} - -esp_err_t uart_isr_register(uart_port_t uart_num, uint8_t uart_intr_num, void (*fn)(void*), void * arg) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - ESP_INTR_DISABLE(uart_intr_num); - switch(uart_num) { - case UART_NUM_1: - intr_matrix_set(xPortGetCoreID(), ETS_UART1_INTR_SOURCE, uart_intr_num); - break; - case UART_NUM_2: - intr_matrix_set(xPortGetCoreID(), ETS_UART2_INTR_SOURCE, uart_intr_num); - break; - case UART_NUM_0: - default: - intr_matrix_set(xPortGetCoreID(), ETS_UART0_INTR_SOURCE, uart_intr_num); - break; - } - xt_set_interrupt_handler(uart_intr_num, fn, arg); - ESP_INTR_ENABLE(uart_intr_num); - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -//internal signal can be output to multiple GPIO pads -//only one GPIO pad can connect with input signal -esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error", ESP_FAIL); - UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error", ESP_FAIL); - UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error", ESP_FAIL); - UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error", ESP_FAIL); - - int tx_sig, rx_sig, rts_sig, cts_sig; - switch(uart_num) { - case UART_NUM_0: - tx_sig = U0TXD_OUT_IDX; - rx_sig = U0RXD_IN_IDX; - rts_sig = U0RTS_OUT_IDX; - cts_sig = U0CTS_IN_IDX; - break; - case UART_NUM_1: - tx_sig = U1TXD_OUT_IDX; - rx_sig = U1RXD_IN_IDX; - rts_sig = U1RTS_OUT_IDX; - cts_sig = U1CTS_IN_IDX; - break; - case UART_NUM_2: - tx_sig = U2TXD_OUT_IDX; - rx_sig = U2RXD_IN_IDX; - rts_sig = U2RTS_OUT_IDX; - cts_sig = U2CTS_IN_IDX; - break; - case UART_NUM_MAX: - default: - tx_sig = U0TXD_OUT_IDX; - rx_sig = U0RXD_IN_IDX; - rts_sig = U0RTS_OUT_IDX; - cts_sig = U0CTS_IN_IDX; - break; - } - if(tx_io_num >= 0) { - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO); - gpio_set_direction(tx_io_num, GPIO_MODE_OUTPUT); - gpio_matrix_out(tx_io_num, tx_sig, 0, 0); - } - - if(rx_io_num >= 0) { - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO); - gpio_set_direction(rx_io_num, GPIO_MODE_INPUT); - gpio_matrix_in(rx_io_num, rx_sig, 0); - } - if(rts_io_num >= 0) { - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[rts_io_num], PIN_FUNC_GPIO); - gpio_set_direction(rts_io_num, GPIO_MODE_OUTPUT); - gpio_matrix_out(rts_io_num, rts_sig, 0, 0); - } - if(cts_io_num >= 0) { - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cts_io_num], PIN_FUNC_GPIO); - gpio_set_direction(cts_io_num, GPIO_MODE_INPUT); - gpio_matrix_in(cts_io_num, cts_sig, 0); - } - return ESP_OK; -} - -esp_err_t uart_set_rts(uart_port_t uart_num, int level) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->conf0.sw_rts = level & 0x1; - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_set_dtr(uart_port_t uart_num, int level) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->conf0.sw_dtr = level & 0x1; - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((uart_config), "param null", ESP_FAIL); - if(uart_num == UART_NUM_0) { - periph_module_enable(PERIPH_UART0_MODULE); - } else if(uart_num == UART_NUM_1) { - periph_module_enable(PERIPH_UART1_MODULE); - } else if(uart_num == UART_NUM_2) { - periph_module_enable(PERIPH_UART2_MODULE); - } - uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); - uart_set_baudrate(uart_num, uart_config->baud_rate); - UART[uart_num]->conf0.val = ( - (uart_config->parity << UART_PARITY_S) - | (uart_config->stop_bits << UART_STOP_BIT_NUM_S) - | (uart_config->data_bits << UART_BIT_NUM_S) - | ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0) - | UART_TICK_REF_ALWAYS_ON_M); - return ESP_OK; -} - -esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((intr_conf), "param null", ESP_FAIL); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->int_clr.val = UART_INTR_MASK; - if(intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { - UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V); - UART[uart_num]->conf1.rx_tout_en = 1; - } else { - UART[uart_num]->conf1.rx_tout_en = 0; - } - if(intr_conf->intr_enable_mask & UART_RXFIFO_FULL_INT_ENA_M) { - UART[uart_num]->conf1.rxfifo_full_thrhd = intr_conf->rxfifo_full_thresh; - } - if(intr_conf->intr_enable_mask & UART_TXFIFO_EMPTY_INT_ENA_M) { - UART[uart_num]->conf1.txfifo_empty_thrhd = intr_conf->txfifo_empty_intr_thresh; - } - UART[uart_num]->int_ena.val = intr_conf->intr_enable_mask; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_FAIL; -} - -//internal isr handler for default driver code. -static void IRAM_ATTR uart_rx_intr_handler_default(void *param) -{ - uart_obj_t *p_uart = (uart_obj_t*) param; - uint8_t uart_num = p_uart->uart_num; - uart_dev_t* uart_reg = UART[uart_num]; - uint8_t buf_idx = 0; - uint32_t uart_intr_status = UART[uart_num]->int_st.val; - int rx_fifo_len = 0; - uart_event_t uart_event; - portBASE_TYPE HPTaskAwoken = 0; - - while(uart_intr_status != 0x0) { - buf_idx = 0; - uart_event.type = UART_EVENT_MAX; - if(uart_intr_status & UART_TXFIFO_EMPTY_INT_ST_M) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.txfifo_empty = 0; - uart_reg->int_clr.txfifo_empty = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - if(p_uart->tx_waiting_brk) { - continue; - } - //TX semaphore will only be used when tx_buf_size is zero. - if(p_uart->tx_waiting_fifo == true && p_uart->tx_buf_size == 0) { - p_uart->tx_waiting_fifo = false; - xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - } - else { - //We don't use TX ring buffer, because the size is zero. - if(p_uart->tx_buf_size == 0) { - continue; - } - int tx_fifo_rem = UART_FIFO_LEN - UART[uart_num]->status.txfifo_cnt; - bool en_tx_flg = false; - //We need to put a loop here, in case all the buffer items are very short. - //That would cause a watch_dog reset because empty interrupt happens so often. - //Although this is a loop in ISR, this loop will execute at most 128 turns. - while(tx_fifo_rem) { - if(p_uart->tx_len_tot == 0 || p_uart->tx_ptr == NULL || p_uart->tx_len_cur == 0) { - size_t size; - p_uart->tx_head = (uart_tx_data_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); - if(p_uart->tx_head) { - //The first item is the data description - //Get the first item to get the data information - if(p_uart->tx_len_tot == 0) { - p_uart->tx_ptr = NULL; - p_uart->tx_len_tot = p_uart->tx_head->tx_data.size; - if(p_uart->tx_head->type == UART_DATA_BREAK) { - p_uart->tx_len_tot = p_uart->tx_head->tx_data.size; - p_uart->tx_brk_flg = 1; - p_uart->tx_brk_len = p_uart->tx_head->tx_data.brk_len; - } - //We have saved the data description from the 1st item, return buffer. - vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - }else if(p_uart->tx_ptr == NULL) { - //Update the TX item pointer, we will need this to return item to buffer. - p_uart->tx_ptr = (uint8_t*) p_uart->tx_head; - en_tx_flg = true; - p_uart->tx_len_cur = size; - } - } - else { - //Can not get data from ring buffer, return; - break; - } - } - if(p_uart->tx_len_tot > 0 && p_uart->tx_ptr && p_uart->tx_len_cur > 0) { - //To fill the TX FIFO. - int send_len = p_uart->tx_len_cur > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_cur; - for(buf_idx = 0; buf_idx < send_len; buf_idx++) { - WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(p_uart->tx_ptr++) & 0xff); - } - p_uart->tx_len_tot -= send_len; - p_uart->tx_len_cur -= send_len; - tx_fifo_rem -= send_len; - if(p_uart->tx_len_cur == 0) { - //Return item to ring buffer. - vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - p_uart->tx_head = NULL; - p_uart->tx_ptr = NULL; - //Sending item done, now we need to send break if there is a record. - //Set TX break signal after FIFO is empty - if(p_uart->tx_brk_flg == 1 && p_uart->tx_len_tot == 0) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.tx_brk_done = 0; - uart_reg->idle_conf.tx_brk_num = p_uart->tx_brk_len; - uart_reg->conf0.txd_brk = 1; - uart_reg->int_clr.tx_brk_done = 1; - uart_reg->int_ena.tx_brk_done = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - p_uart->tx_waiting_brk = 1; - } else { - //enable TX empty interrupt - en_tx_flg = true; - } - } else { - //enable TX empty interrupt - en_tx_flg = true; - } - } - } - if(en_tx_flg) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_clr.txfifo_empty = 1; - uart_reg->int_ena.txfifo_empty = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - } - } - } - else if((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)) { - if(p_uart->rx_buffer_full_flg == false) { - //Get the buffer from the FIFO - rx_fifo_len = uart_reg->status.rxfifo_cnt; - p_uart->rx_stash_len = rx_fifo_len; - //We have to read out all data in RX FIFO to clear the interrupt signal - while(buf_idx < rx_fifo_len) { - p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte; - } - //After Copying the Data From FIFO ,Clear intr_status - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_clr.rxfifo_tout = 1; - uart_reg->int_clr.rxfifo_full = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_event.type = UART_DATA; - uart_event.size = rx_fifo_len; - //If we fail to push data to ring buffer, we will have to stash the data, and send next time. - //Mainly for applications that uses flow control or small ring buffer. - if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &HPTaskAwoken)) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.rxfifo_full = 0; - uart_reg->int_ena.rxfifo_tout = 0; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - p_uart->rx_buffer_full_flg = true; - uart_event.type = UART_BUFFER_FULL; - } else { - uart_event.type = UART_DATA; - } - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - } else { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.rxfifo_full = 0; - uart_reg->int_ena.rxfifo_tout = 0; - uart_reg->int_clr.val = UART_RXFIFO_FULL_INT_CLR_M | UART_RXFIFO_TOUT_INT_CLR_M; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_event.type = UART_BUFFER_FULL; - } - } else if(uart_intr_status & UART_RXFIFO_OVF_INT_ST_M) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->conf0.rxfifo_rst = 1; - uart_reg->conf0.rxfifo_rst = 0; - uart_reg->int_clr.rxfifo_ovf = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_event.type = UART_FIFO_OVF; - } else if(uart_intr_status & UART_BRK_DET_INT_ST_M) { - uart_reg->int_clr.brk_det = 1; - uart_event.type = UART_BREAK; - } else if(uart_intr_status & UART_PARITY_ERR_INT_ST_M ) { - uart_reg->int_clr.parity_err = 1; - uart_event.type = UART_FRAME_ERR; - } else if(uart_intr_status & UART_FRM_ERR_INT_ST_M) { - uart_reg->int_clr.frm_err = 1; - uart_event.type = UART_PARITY_ERR; - } else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->conf0.txd_brk = 0; - uart_reg->int_ena.tx_brk_done = 0; - uart_reg->int_clr.tx_brk_done = 1; - if(p_uart->tx_brk_flg == 1) { - uart_reg->int_ena.txfifo_empty = 1; - } - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - if(p_uart->tx_brk_flg == 1) { - p_uart->tx_brk_flg = 0; - p_uart->tx_waiting_brk = 0; - } else { - xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - } - } else if(uart_intr_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.tx_brk_idle_done = 0; - uart_reg->int_clr.tx_brk_idle_done = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - } else if(uart_intr_status & UART_TX_DONE_INT_ST_M) { - UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); - uart_reg->int_ena.tx_done = 0; - uart_reg->int_clr.tx_done = 1; - UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); - xSemaphoreGiveFromISR(p_uart_obj[uart_num]->tx_done_sem, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - } - else { - uart_reg->int_clr.val = uart_intr_status; /*simply clear all other intr status*/ - uart_event.type = UART_EVENT_MAX; - } - - if(uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart) { - xQueueSendFromISR(p_uart->xQueueUart, (void * )&uart_event, &HPTaskAwoken); - if(HPTaskAwoken == pdTRUE) { - portYIELD_FROM_ISR() ; - } - } - uart_intr_status = uart_reg->int_st.val; - } -} - -/**************************************************************/ -esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); - BaseType_t res; - portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; - //Take tx_mux - res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)ticks_to_wait); - if(res == pdFALSE) { - return ESP_ERR_TIMEOUT; - } - ticks_to_wait = ticks_end - xTaskGetTickCount(); - xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, 0); - ticks_to_wait = ticks_end - xTaskGetTickCount(); - if(UART[uart_num]->status.txfifo_cnt == 0) { - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - return ESP_OK; - } - uart_enable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); - //take 2nd tx_done_sem, wait given from ISR - res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); - if(res == pdFALSE) { - uart_disable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - return ESP_ERR_TIMEOUT; - } - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - return ESP_OK; -} - -static esp_err_t uart_set_break(uart_port_t uart_num, int break_num) -{ - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->idle_conf.tx_brk_num = break_num; - UART[uart_num]->conf0.txd_brk = 1; - UART[uart_num]->int_clr.tx_brk_done = 1; - UART[uart_num]->int_ena.tx_brk_done = 1; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - return ESP_OK; -} - -//Fill UART tx_fifo and return a number, -//This function by itself is not thread-safe, always call from within a muxed section. -static int uart_fill_fifo(uart_port_t uart_num, const char* buffer, uint32_t len) -{ - uint8_t i = 0; - uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt; - uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt); - uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len); - for(i = 0; i < copy_cnt; i++) { - WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), buffer[i]); - } - return copy_cnt; -} - -int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); - UART_CHECK(buffer, "buffer null", (-1)); - if(len == 0) { - return 0; - } - xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); - int tx_len = uart_fill_fifo(uart_num, (const char*) buffer, len); - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - return tx_len; -} - -static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool brk_en, int brk_len) -{ - if(size == 0) { - return 0; - } - size_t original_size = size; - - //lock for uart_tx - xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); - if(p_uart_obj[uart_num]->tx_buf_size > 0) { - int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); - int offset = 0; - uart_tx_data_t evt; - evt.tx_data.size = size; - evt.tx_data.brk_len = brk_len; - if(brk_en) { - evt.type = UART_DATA_BREAK; - } else { - evt.type = UART_DATA; - } - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_tx_data_t), portMAX_DELAY); - while(size > 0) { - int send_size = size > max_size / 2 ? max_size / 2 : size; - xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) (src + offset), send_size, portMAX_DELAY); - size -= send_size; - offset += send_size; - } - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - } else { - while(size) { - //semaphore for tx_fifo available - if(pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { - size_t sent = uart_fill_fifo(uart_num, (char*) src, size); - if(sent < size) { - p_uart_obj[uart_num]->tx_waiting_fifo = true; - uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); - } - size -= sent; - src += sent; - } - } - if(brk_en) { - uart_set_break(uart_num, brk_len); - xSemaphoreTake(p_uart_obj[uart_num]->tx_brk_sem, (portTickType)portMAX_DELAY); - } - xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); - } - xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); - return original_size; -} - -int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); - UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error", (-1)); - UART_CHECK(src, "buffer null", (-1)); - return uart_tx_all(uart_num, src, size, 0, 0); -} - -int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); - UART_CHECK((size > 0), "uart size error", (-1)); - UART_CHECK((src), "uart data null", (-1)); - UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error", (-1)); - return uart_tx_all(uart_num, src, size, 1, brk_len); -} - -int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); - UART_CHECK((buf), "uart_num error", (-1)); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); - uint8_t* data = NULL; - size_t size; - size_t copy_len = 0; - int len_tmp; - if(xSemaphoreTake(p_uart_obj[uart_num]->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) { - return -1; - } - while(length) { - if(p_uart_obj[uart_num]->rx_cur_remain == 0) { - data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); - if(data) { - p_uart_obj[uart_num]->rx_head_ptr = data; - p_uart_obj[uart_num]->rx_ptr = data; - p_uart_obj[uart_num]->rx_cur_remain = size; - } else { - xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); - return copy_len; - } - } - if(p_uart_obj[uart_num]->rx_cur_remain > length) { - len_tmp = length; - } else { - len_tmp = p_uart_obj[uart_num]->rx_cur_remain; - } - memcpy(buf + copy_len, p_uart_obj[uart_num]->rx_ptr, len_tmp); - p_uart_obj[uart_num]->rx_ptr += len_tmp; - p_uart_obj[uart_num]->rx_cur_remain -= len_tmp; - copy_len += len_tmp; - length -= len_tmp; - if(p_uart_obj[uart_num]->rx_cur_remain == 0) { - vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr); - p_uart_obj[uart_num]->rx_head_ptr = NULL; - p_uart_obj[uart_num]->rx_ptr = NULL; - if(p_uart_obj[uart_num]->rx_buffer_full_flg) { - BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); - if(res == pdTRUE) { - p_uart_obj[uart_num]->rx_buffer_full_flg = false; - uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); - } - } - } - } - xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); - return copy_len; -} - -esp_err_t uart_flush(uart_port_t uart_num) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); - uart_obj_t* p_uart = p_uart_obj[uart_num]; - uint8_t* data; - size_t size; - - //rx sem protect the ring buffer read related functions - xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY); - ESP_INTR_DISABLE(p_uart->intr_num); - while(true) { - if(p_uart->rx_head_ptr) { - vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr); - p_uart->rx_ptr = NULL; - p_uart->rx_cur_remain = 0; - p_uart->rx_head_ptr = NULL; - } - data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0); - if(data == NULL) { - break; - } - vRingbufferReturnItem(p_uart->rx_ring_buf, data); - } - p_uart->rx_ptr = NULL; - p_uart->rx_cur_remain = 0; - p_uart->rx_head_ptr = NULL; - ESP_INTR_ENABLE(p_uart->intr_num); - xSemaphoreGive(p_uart->rx_mux); - - if(p_uart->tx_buf_size > 0) { - xSemaphoreTake(p_uart->tx_mux, (portTickType)portMAX_DELAY); - ESP_INTR_DISABLE(p_uart->intr_num); - UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); - UART[uart_num]->int_ena.txfifo_empty = 0; - UART[uart_num]->int_clr.txfifo_empty = 1; - UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); - do { - data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0); - if(data == NULL) { - break; - } - vRingbufferReturnItem(p_uart->rx_ring_buf, data); - } while(1); - p_uart->tx_brk_flg = 0; - p_uart->tx_brk_len = 0; - p_uart->tx_head = NULL; - p_uart->tx_len_cur = 0; - p_uart->tx_len_tot = 0; - p_uart->tx_ptr = NULL; - p_uart->tx_waiting_brk = 0; - p_uart->tx_waiting_fifo = false; - ESP_INTR_ENABLE(p_uart->intr_num); - xSemaphoreGive(p_uart->tx_mux); - } - uart_reset_fifo(uart_num); - return ESP_OK; -} - -esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void* uart_queue) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error", ESP_FAIL); - if(p_uart_obj[uart_num] == NULL) { - ESP_INTR_DISABLE(uart_intr_num); - p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); - if(p_uart_obj[uart_num] == NULL) { - ESP_LOGE(UART_TAG, "UART driver malloc error"); - return ESP_FAIL; - } - p_uart_obj[uart_num]->uart_num = uart_num; - p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary(); - xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); - p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary(); - p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary(); - p_uart_obj[uart_num]->tx_mux = xSemaphoreCreateMutex(); - p_uart_obj[uart_num]->rx_mux = xSemaphoreCreateMutex(); - p_uart_obj[uart_num]->intr_num = uart_intr_num; - p_uart_obj[uart_num]->queue_size = queue_size; - p_uart_obj[uart_num]->tx_ptr = NULL; - p_uart_obj[uart_num]->tx_head = NULL; - p_uart_obj[uart_num]->tx_len_tot = 0; - p_uart_obj[uart_num]->tx_brk_flg = 0; - p_uart_obj[uart_num]->tx_brk_len = 0; - p_uart_obj[uart_num]->tx_waiting_brk = 0; - - if(uart_queue) { - p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); - *((QueueHandle_t*) uart_queue) = p_uart_obj[uart_num]->xQueueUart; - ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); - } else { - p_uart_obj[uart_num]->xQueueUart = NULL; - } - p_uart_obj[uart_num]->rx_buffer_full_flg = false; - p_uart_obj[uart_num]->tx_waiting_fifo = false; - p_uart_obj[uart_num]->rx_ptr = NULL; - p_uart_obj[uart_num]->rx_cur_remain = 0; - p_uart_obj[uart_num]->rx_head_ptr = NULL; - p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF); - if(tx_buffer_size > 0) { - p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT); - p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; - } else { - p_uart_obj[uart_num]->tx_ring_buf = NULL; - p_uart_obj[uart_num]->tx_buf_size = 0; - } - } else { - ESP_LOGE(UART_TAG, "UART driver already installed"); - return ESP_FAIL; - } - uart_isr_register(uart_num, uart_intr_num, uart_rx_intr_handler_default, p_uart_obj[uart_num]); - uart_intr_config_t uart_intr = { - .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M - | UART_RXFIFO_TOUT_INT_ENA_M - | UART_FRM_ERR_INT_ENA_M - | UART_RXFIFO_OVF_INT_ENA_M - | UART_BRK_DET_INT_ENA_M - | UART_PARITY_ERR_INT_ENA_M, - .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT, - .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT, - .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT - }; - uart_intr_config(uart_num, &uart_intr); - ESP_INTR_ENABLE(uart_intr_num); - return ESP_OK; -} - -//Make sure no other tasks are still using UART before you call this function -esp_err_t uart_driver_delete(uart_port_t uart_num) -{ - UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); - if(p_uart_obj[uart_num] == NULL) { - ESP_LOGI(UART_TAG, "ALREADY NULL"); - return ESP_OK; - } - ESP_INTR_DISABLE(p_uart_obj[uart_num]->intr_num); - uart_disable_rx_intr(uart_num); - uart_disable_tx_intr(uart_num); - uart_isr_register(uart_num, p_uart_obj[uart_num]->intr_num, NULL, NULL); - - if(p_uart_obj[uart_num]->tx_fifo_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem); - p_uart_obj[uart_num]->tx_fifo_sem = NULL; - } - if(p_uart_obj[uart_num]->tx_done_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem); - p_uart_obj[uart_num]->tx_done_sem = NULL; - } - if(p_uart_obj[uart_num]->tx_brk_sem) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem); - p_uart_obj[uart_num]->tx_brk_sem = NULL; - } - if(p_uart_obj[uart_num]->tx_mux) { - vSemaphoreDelete(p_uart_obj[uart_num]->tx_mux); - p_uart_obj[uart_num]->tx_mux = NULL; - } - if(p_uart_obj[uart_num]->rx_mux) { - vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux); - p_uart_obj[uart_num]->rx_mux = NULL; - } - if(p_uart_obj[uart_num]->xQueueUart) { - vQueueDelete(p_uart_obj[uart_num]->xQueueUart); - p_uart_obj[uart_num]->xQueueUart = NULL; - } - if(p_uart_obj[uart_num]->rx_ring_buf) { - vRingbufferDelete(p_uart_obj[uart_num]->rx_ring_buf); - p_uart_obj[uart_num]->rx_ring_buf = NULL; - } - if(p_uart_obj[uart_num]->tx_ring_buf) { - vRingbufferDelete(p_uart_obj[uart_num]->tx_ring_buf); - p_uart_obj[uart_num]->tx_ring_buf = NULL; - } - - free(p_uart_obj[uart_num]); - p_uart_obj[uart_num] = NULL; - return ESP_OK; -} +// 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 +#include "esp_types.h" +#include "esp_attr.h" +#include "esp_intr.h" +#include "esp_intr_alloc.h" +#include "esp_log.h" +#include "esp_err.h" +#include "malloc.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" +#include "freertos/xtensa_api.h" +#include "freertos/task.h" +#include "freertos/ringbuf.h" +#include "soc/dport_reg.h" +#include "soc/uart_struct.h" +#include "driver/uart.h" +#include "driver/gpio.h" + +static const char* UART_TAG = "uart"; +#define UART_CHECK(a, str, ret_val) \ + if (!(a)) { \ + ESP_LOGE(UART_TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ + return (ret_val); \ + } + +#define UART_EMPTY_THRESH_DEFAULT (10) +#define UART_FULL_THRESH_DEFAULT (120) +#define UART_TOUT_THRESH_DEFAULT (10) +#define UART_ENTER_CRITICAL_ISR(mux) portENTER_CRITICAL_ISR(mux) +#define UART_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(mux) +#define UART_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) +#define UART_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) + +typedef struct { + uart_event_type_t type; /*!< UART TX data type */ + struct { + int brk_len; + size_t size; + uint8_t data[0]; + } tx_data; +} uart_tx_data_t; + +typedef struct { + uart_port_t uart_num; /*!< UART port number*/ + int queue_size; /*!< UART event queue size*/ + QueueHandle_t xQueueUart; /*!< UART queue handler*/ + intr_handle_t intr_handle; /*!< UART interrupt handle*/ + //rx parameters + int rx_buffered_len; /*!< UART cached data length */ + SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/ + int rx_buf_size; /*!< RX ring buffer size */ + RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/ + bool rx_buffer_full_flg; /*!< RX ring buffer full flag. */ + int rx_cur_remain; /*!< Data number that waiting to be read out in ring buffer item*/ + uint8_t* rx_ptr; /*!< pointer to the current data in ring buffer*/ + uint8_t* rx_head_ptr; /*!< pointer to the head of RX item*/ + uint8_t rx_data_buf[UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/ + uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */ + //tx parameters + SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/ + SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/ + SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/ + SemaphoreHandle_t tx_brk_sem; /*!< UART TX send break done semaphore*/ + int tx_buf_size; /*!< TX ring buffer size */ + RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/ + bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/ + uint8_t* tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/ + uart_tx_data_t* tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/ + uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/ + uint32_t tx_len_cur; + uint8_t tx_brk_flg; /*!< Flag to indicate to send a break signal in the end of the item sending procedure */ + uint8_t tx_brk_len; /*!< TX break signal cycle length/number */ + uint8_t tx_waiting_brk; /*!< Flag to indicate that TX FIFO is ready to send break signal after FIFO is empty, do not push data into TX FIFO right now.*/ +} uart_obj_t; + + + +static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0}; +/* DRAM_ATTR is required to avoid UART array placed in flash, due to accessed from ISR */ +static DRAM_ATTR uart_dev_t* const UART[UART_NUM_MAX] = {&UART0, &UART1, &UART2}; +static portMUX_TYPE uart_spinlock[UART_NUM_MAX] = {portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED, portMUX_INITIALIZER_UNLOCKED}; + +esp_err_t uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((data_bit < UART_DATA_BITS_MAX), "data bit error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.bit_num = data_bit; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_get_word_length(uart_port_t uart_num, uart_word_length_t* data_bit) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + *(data_bit) = UART[uart_num]->conf0.bit_num; + return ESP_OK; +} + +esp_err_t uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.stop_bit_num = stop_bit; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t* stop_bit) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + (*stop_bit) = UART[uart_num]->conf0.stop_bit_num; + return ESP_OK; +} + +esp_err_t uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.parity = parity_mode & 0x1; + UART[uart_num]->conf0.parity_en = (parity_mode >> 1) & 0x1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_get_parity(uart_port_t uart_num, uart_parity_t* parity_mode) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + int val = UART[uart_num]->conf0.val; + if(val & UART_PARITY_EN_M) { + if(val & UART_PARITY_M) { + (*parity_mode) = UART_PARITY_ODD; + } else { + (*parity_mode) = UART_PARITY_EVEN; + } + } else { + (*parity_mode) = UART_PARITY_DISABLE; + } + return ESP_OK; +} + +esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((baud_rate < UART_BITRATE_MAX), "baud_rate error", ESP_FAIL); + uint32_t clk_div = (((UART_CLK_FREQ) << 4) / baud_rate); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->clk_div.div_int = clk_div >> 4; + UART[uart_num]->clk_div.div_frag = clk_div & 0xf; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t* baudrate) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + uint32_t clk_div = (UART[uart_num]->clk_div.div_int << 4) | UART[uart_num]->clk_div.div_frag; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + (*baudrate) = ((UART_CLK_FREQ) << 4) / clk_div; + return ESP_OK; +} + +esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((((inverse_mask & UART_LINE_INV_MASK) == 0) && (inverse_mask != 0)), "inverse_mask error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + CLEAR_PERI_REG_MASK(UART_CONF0_REG(uart_num), UART_LINE_INV_MASK); + SET_PERI_REG_MASK(UART_CONF0_REG(uart_num), inverse_mask); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +//only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. +esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((rx_thresh < UART_FIFO_LEN), "rx flow thresh error", ESP_FAIL); + UART_CHECK((flow_ctrl < UART_HW_FLOWCTRL_MAX), "hw_flowctrl mode error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + if(flow_ctrl & UART_HW_FLOWCTRL_RTS) { + UART[uart_num]->conf1.rx_flow_thrhd = rx_thresh; + UART[uart_num]->conf1.rx_flow_en = 1; + } else { + UART[uart_num]->conf1.rx_flow_en = 0; + } + if(flow_ctrl & UART_HW_FLOWCTRL_CTS) { + UART[uart_num]->conf0.tx_flow_en = 1; + } else { + UART[uart_num]->conf0.tx_flow_en = 0; + } + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t* flow_ctrl) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + uart_hw_flowcontrol_t val = UART_HW_FLOWCTRL_DISABLE; + if(UART[uart_num]->conf1.rx_flow_en) { + val |= UART_HW_FLOWCTRL_RTS; + } + if(UART[uart_num]->conf0.tx_flow_en) { + val |= UART_HW_FLOWCTRL_CTS; + } + (*flow_ctrl) = val; + return ESP_OK; +} + +static esp_err_t uart_reset_fifo(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.rxfifo_rst = 1; + UART[uart_num]->conf0.rxfifo_rst = 0; + UART[uart_num]->conf0.txfifo_rst = 1; + UART[uart_num]->conf0.txfifo_rst = 0; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_clear_intr_status(uart_port_t uart_num, uint32_t clr_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + //intr_clr register is write-only + UART[uart_num]->int_clr.val = clr_mask; + return ESP_OK; +} + +esp_err_t uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + SET_PERI_REG_MASK(UART_INT_CLR_REG(uart_num), enable_mask); + SET_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), enable_mask); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + CLEAR_PERI_REG_MASK(UART_INT_ENA_REG(uart_num), disable_mask); + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK(chr_tout >= 0 && chr_tout <= UART_RX_GAP_TOUT_V, "uart pattern set error\n", ESP_FAIL); + UART_CHECK(post_idle >= 0 && post_idle <= UART_POST_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL); + UART_CHECK(pre_idle >= 0 && pre_idle <= UART_PRE_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL); + UART[uart_num]->at_cmd_char.data = pattern_chr; + UART[uart_num]->at_cmd_char.char_num = chr_num; + UART[uart_num]->at_cmd_gaptout.rx_gap_tout = chr_tout; + UART[uart_num]->at_cmd_postcnt.post_idle_num = post_idle; + UART[uart_num]->at_cmd_precnt.pre_idle_num = pre_idle; + return uart_enable_intr_mask(uart_num, UART_AT_CMD_CHAR_DET_INT_ENA_M); +} + +esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num) +{ + return uart_disable_intr_mask(uart_num, UART_AT_CMD_CHAR_DET_INT_ENA_M); +} + +esp_err_t uart_enable_rx_intr(uart_port_t uart_num) +{ + return uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); +} + +esp_err_t uart_disable_rx_intr(uart_port_t uart_num) +{ + return uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA); +} + +esp_err_t uart_disable_tx_intr(uart_port_t uart_num) +{ + return uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA); +} + +esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((thresh < UART_FIFO_LEN), "empty intr threshold error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->int_clr.txfifo_empty = 1; + UART[uart_num]->conf1.txfifo_empty_thrhd = thresh & UART_TXFIFO_EMPTY_THRHD_V; + UART[uart_num]->int_ena.txfifo_empty = enable & 0x1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags, uart_isr_handle_t *handle) +{ + int ret; + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + switch(uart_num) { + case UART_NUM_1: + ret=esp_intr_alloc(ETS_UART1_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); + break; + case UART_NUM_2: + ret=esp_intr_alloc(ETS_UART2_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); + break; + case UART_NUM_0: + default: + ret=esp_intr_alloc(ETS_UART0_INTR_SOURCE, intr_alloc_flags, fn, arg, handle); + break; + } + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ret; +} + + +esp_err_t uart_isr_free(uart_port_t uart_num) +{ + esp_err_t ret; + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + if (p_uart_obj[uart_num]->intr_handle==NULL) return ESP_ERR_INVALID_ARG; + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + ret=esp_intr_free(p_uart_obj[uart_num]->intr_handle); + p_uart_obj[uart_num]->intr_handle=NULL; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ret; +} + +//internal signal can be output to multiple GPIO pads +//only one GPIO pad can connect with input signal +esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), "tx_io_num error", ESP_FAIL); + UART_CHECK((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), "rx_io_num error", ESP_FAIL); + UART_CHECK((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), "rts_io_num error", ESP_FAIL); + UART_CHECK((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), "cts_io_num error", ESP_FAIL); + + int tx_sig, rx_sig, rts_sig, cts_sig; + switch(uart_num) { + case UART_NUM_0: + tx_sig = U0TXD_OUT_IDX; + rx_sig = U0RXD_IN_IDX; + rts_sig = U0RTS_OUT_IDX; + cts_sig = U0CTS_IN_IDX; + break; + case UART_NUM_1: + tx_sig = U1TXD_OUT_IDX; + rx_sig = U1RXD_IN_IDX; + rts_sig = U1RTS_OUT_IDX; + cts_sig = U1CTS_IN_IDX; + break; + case UART_NUM_2: + tx_sig = U2TXD_OUT_IDX; + rx_sig = U2RXD_IN_IDX; + rts_sig = U2RTS_OUT_IDX; + cts_sig = U2CTS_IN_IDX; + break; + case UART_NUM_MAX: + default: + tx_sig = U0TXD_OUT_IDX; + rx_sig = U0RXD_IN_IDX; + rts_sig = U0RTS_OUT_IDX; + cts_sig = U0CTS_IN_IDX; + break; + } + if(tx_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[tx_io_num], PIN_FUNC_GPIO); + gpio_set_direction(tx_io_num, GPIO_MODE_OUTPUT); + gpio_matrix_out(tx_io_num, tx_sig, 0, 0); + } + + if(rx_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[rx_io_num], PIN_FUNC_GPIO); + gpio_set_direction(rx_io_num, GPIO_MODE_INPUT); + gpio_matrix_in(rx_io_num, rx_sig, 0); + } + if(rts_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[rts_io_num], PIN_FUNC_GPIO); + gpio_set_direction(rts_io_num, GPIO_MODE_OUTPUT); + gpio_matrix_out(rts_io_num, rts_sig, 0, 0); + } + if(cts_io_num >= 0) { + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cts_io_num], PIN_FUNC_GPIO); + gpio_set_direction(cts_io_num, GPIO_MODE_INPUT); + gpio_matrix_in(cts_io_num, cts_sig, 0); + } + return ESP_OK; +} + +esp_err_t uart_set_rts(uart_port_t uart_num, int level) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((UART[uart_num]->conf1.rx_flow_en != 1), "disable hw flowctrl before using sw control", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.sw_rts = level & 0x1; + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_set_dtr(uart_port_t uart_num, int level) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->conf0.sw_dtr = level & 0x1; + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((uart_config), "param null", ESP_FAIL); + if(uart_num == UART_NUM_0) { + periph_module_enable(PERIPH_UART0_MODULE); + } else if(uart_num == UART_NUM_1) { + periph_module_enable(PERIPH_UART1_MODULE); + } else if(uart_num == UART_NUM_2) { + periph_module_enable(PERIPH_UART2_MODULE); + } + uart_set_hw_flow_ctrl(uart_num, uart_config->flow_ctrl, uart_config->rx_flow_ctrl_thresh); + uart_set_baudrate(uart_num, uart_config->baud_rate); + UART[uart_num]->conf0.val = ( + (uart_config->parity << UART_PARITY_S) + | (uart_config->stop_bits << UART_STOP_BIT_NUM_S) + | (uart_config->data_bits << UART_BIT_NUM_S) + | ((uart_config->flow_ctrl & UART_HW_FLOWCTRL_CTS) ? UART_TX_FLOW_EN : 0x0) + | UART_TICK_REF_ALWAYS_ON_M); + return ESP_OK; +} + +esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_conf) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((intr_conf), "param null", ESP_FAIL); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->int_clr.val = UART_INTR_MASK; + if(intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M) { + UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & UART_RX_TOUT_THRHD_V); + UART[uart_num]->conf1.rx_tout_en = 1; + } else { + UART[uart_num]->conf1.rx_tout_en = 0; + } + if(intr_conf->intr_enable_mask & UART_RXFIFO_FULL_INT_ENA_M) { + UART[uart_num]->conf1.rxfifo_full_thrhd = intr_conf->rxfifo_full_thresh; + } + if(intr_conf->intr_enable_mask & UART_TXFIFO_EMPTY_INT_ENA_M) { + UART[uart_num]->conf1.txfifo_empty_thrhd = intr_conf->txfifo_empty_intr_thresh; + } + UART[uart_num]->int_ena.val = intr_conf->intr_enable_mask; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_FAIL; +} + +//internal isr handler for default driver code. +static void IRAM_ATTR uart_rx_intr_handler_default(void *param) +{ + uart_obj_t *p_uart = (uart_obj_t*) param; + uint8_t uart_num = p_uart->uart_num; + uart_dev_t* uart_reg = UART[uart_num]; + uint8_t buf_idx = 0; + uint32_t uart_intr_status = UART[uart_num]->int_st.val; + int rx_fifo_len = 0; + uart_event_t uart_event; + portBASE_TYPE HPTaskAwoken = 0; + + while(uart_intr_status != 0x0) { + buf_idx = 0; + uart_event.type = UART_EVENT_MAX; + if(uart_intr_status & UART_TXFIFO_EMPTY_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.txfifo_empty = 0; + uart_reg->int_clr.txfifo_empty = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + if(p_uart->tx_waiting_brk) { + continue; + } + //TX semaphore will only be used when tx_buf_size is zero. + if(p_uart->tx_waiting_fifo == true && p_uart->tx_buf_size == 0) { + p_uart->tx_waiting_fifo = false; + xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + } + else { + //We don't use TX ring buffer, because the size is zero. + if(p_uart->tx_buf_size == 0) { + continue; + } + int tx_fifo_rem = UART_FIFO_LEN - UART[uart_num]->status.txfifo_cnt; + bool en_tx_flg = false; + //We need to put a loop here, in case all the buffer items are very short. + //That would cause a watch_dog reset because empty interrupt happens so often. + //Although this is a loop in ISR, this loop will execute at most 128 turns. + while(tx_fifo_rem) { + if(p_uart->tx_len_tot == 0 || p_uart->tx_ptr == NULL || p_uart->tx_len_cur == 0) { + size_t size; + p_uart->tx_head = (uart_tx_data_t*) xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size); + if(p_uart->tx_head) { + //The first item is the data description + //Get the first item to get the data information + if(p_uart->tx_len_tot == 0) { + p_uart->tx_ptr = NULL; + p_uart->tx_len_tot = p_uart->tx_head->tx_data.size; + if(p_uart->tx_head->type == UART_DATA_BREAK) { + p_uart->tx_len_tot = p_uart->tx_head->tx_data.size; + p_uart->tx_brk_flg = 1; + p_uart->tx_brk_len = p_uart->tx_head->tx_data.brk_len; + } + //We have saved the data description from the 1st item, return buffer. + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + }else if(p_uart->tx_ptr == NULL) { + //Update the TX item pointer, we will need this to return item to buffer. + p_uart->tx_ptr = (uint8_t*) p_uart->tx_head; + en_tx_flg = true; + p_uart->tx_len_cur = size; + } + } + else { + //Can not get data from ring buffer, return; + break; + } + } + if(p_uart->tx_len_tot > 0 && p_uart->tx_ptr && p_uart->tx_len_cur > 0) { + //To fill the TX FIFO. + int send_len = p_uart->tx_len_cur > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_cur; + for(buf_idx = 0; buf_idx < send_len; buf_idx++) { + WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), *(p_uart->tx_ptr++) & 0xff); + } + p_uart->tx_len_tot -= send_len; + p_uart->tx_len_cur -= send_len; + tx_fifo_rem -= send_len; + if(p_uart->tx_len_cur == 0) { + //Return item to ring buffer. + vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + p_uart->tx_head = NULL; + p_uart->tx_ptr = NULL; + //Sending item done, now we need to send break if there is a record. + //Set TX break signal after FIFO is empty + if(p_uart->tx_brk_flg == 1 && p_uart->tx_len_tot == 0) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_brk_done = 0; + uart_reg->idle_conf.tx_brk_num = p_uart->tx_brk_len; + uart_reg->conf0.txd_brk = 1; + uart_reg->int_clr.tx_brk_done = 1; + uart_reg->int_ena.tx_brk_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + p_uart->tx_waiting_brk = 1; + } else { + //enable TX empty interrupt + en_tx_flg = true; + } + } else { + //enable TX empty interrupt + en_tx_flg = true; + } + } + } + if(en_tx_flg) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_clr.txfifo_empty = 1; + uart_reg->int_ena.txfifo_empty = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + } + } + } + else if((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M)) { + if(p_uart->rx_buffer_full_flg == false) { + //Get the buffer from the FIFO + rx_fifo_len = uart_reg->status.rxfifo_cnt; + p_uart->rx_stash_len = rx_fifo_len; + //We have to read out all data in RX FIFO to clear the interrupt signal + while(buf_idx < rx_fifo_len) { + p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte; + } + //After Copying the Data From FIFO ,Clear intr_status + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_clr.rxfifo_tout = 1; + uart_reg->int_clr.rxfifo_full = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_DATA; + uart_event.size = rx_fifo_len; + //If we fail to push data to ring buffer, we will have to stash the data, and send next time. + //Mainly for applications that uses flow control or small ring buffer. + if(pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &HPTaskAwoken)) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.rxfifo_full = 0; + uart_reg->int_ena.rxfifo_tout = 0; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + p_uart->rx_buffer_full_flg = true; + uart_event.type = UART_BUFFER_FULL; + } else { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + p_uart->rx_buffered_len += p_uart->rx_stash_len; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_DATA; + } + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + } else { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.rxfifo_full = 0; + uart_reg->int_ena.rxfifo_tout = 0; + uart_reg->int_clr.val = UART_RXFIFO_FULL_INT_CLR_M | UART_RXFIFO_TOUT_INT_CLR_M; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_BUFFER_FULL; + } + } else if(uart_intr_status & UART_RXFIFO_OVF_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->conf0.rxfifo_rst = 1; + uart_reg->conf0.rxfifo_rst = 0; + uart_reg->int_clr.rxfifo_ovf = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_event.type = UART_FIFO_OVF; + } else if(uart_intr_status & UART_BRK_DET_INT_ST_M) { + uart_reg->int_clr.brk_det = 1; + uart_event.type = UART_BREAK; + } else if(uart_intr_status & UART_FRM_ERR_INT_ST_M) { + uart_reg->int_clr.parity_err = 1; + uart_event.type = UART_FRAME_ERR; + } else if(uart_intr_status & UART_PARITY_ERR_INT_ST_M) { + uart_reg->int_clr.frm_err = 1; + uart_event.type = UART_PARITY_ERR; + } else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->conf0.txd_brk = 0; + uart_reg->int_ena.tx_brk_done = 0; + uart_reg->int_clr.tx_brk_done = 1; + if(p_uart->tx_brk_flg == 1) { + uart_reg->int_ena.txfifo_empty = 1; + } + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + if(p_uart->tx_brk_flg == 1) { + p_uart->tx_brk_flg = 0; + p_uart->tx_waiting_brk = 0; + } else { + xSemaphoreGiveFromISR(p_uart->tx_brk_sem, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + } + } else if(uart_intr_status & UART_TX_BRK_IDLE_DONE_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_brk_idle_done = 0; + uart_reg->int_clr.tx_brk_idle_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + } else if(uart_intr_status & UART_AT_CMD_CHAR_DET_INT_ST_M) { + uart_reg->int_clr.at_cmd_char_det = 1; + uart_event.type = UART_PATTERN_DET; + } else if(uart_intr_status & UART_TX_DONE_INT_ST_M) { + UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]); + uart_reg->int_ena.tx_done = 0; + uart_reg->int_clr.tx_done = 1; + UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]); + xSemaphoreGiveFromISR(p_uart_obj[uart_num]->tx_done_sem, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + } else { + uart_reg->int_clr.val = uart_intr_status; /*simply clear all other intr status*/ + uart_event.type = UART_EVENT_MAX; + } + + if(uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart) { + xQueueSendFromISR(p_uart->xQueueUart, (void * )&uart_event, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR() ; + } + } + uart_intr_status = uart_reg->int_st.val; + } +} + +/**************************************************************/ +esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); + BaseType_t res; + portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait; + //Take tx_mux + res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)ticks_to_wait); + if(res == pdFALSE) { + return ESP_ERR_TIMEOUT; + } + ticks_to_wait = ticks_end - xTaskGetTickCount(); + xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, 0); + ticks_to_wait = ticks_end - xTaskGetTickCount(); + if(UART[uart_num]->status.txfifo_cnt == 0) { + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + return ESP_OK; + } + uart_enable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); + //take 2nd tx_done_sem, wait given from ISR + res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); + if(res == pdFALSE) { + uart_disable_intr_mask(uart_num, UART_TX_DONE_INT_ENA_M); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + return ESP_ERR_TIMEOUT; + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + return ESP_OK; +} + +static esp_err_t uart_set_break(uart_port_t uart_num, int break_num) +{ + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + UART[uart_num]->idle_conf.tx_brk_num = break_num; + UART[uart_num]->conf0.txd_brk = 1; + UART[uart_num]->int_clr.tx_brk_done = 1; + UART[uart_num]->int_ena.tx_brk_done = 1; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return ESP_OK; +} + +//Fill UART tx_fifo and return a number, +//This function by itself is not thread-safe, always call from within a muxed section. +static int uart_fill_fifo(uart_port_t uart_num, const char* buffer, uint32_t len) +{ + uint8_t i = 0; + uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt; + uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt); + uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len); + for(i = 0; i < copy_cnt; i++) { + WRITE_PERI_REG(UART_FIFO_AHB_REG(uart_num), buffer[i]); + } + return copy_cnt; +} + +int uart_tx_chars(uart_port_t uart_num, const char* buffer, uint32_t len) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); + UART_CHECK(buffer, "buffer null", (-1)); + if(len == 0) { + return 0; + } + xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); + int tx_len = uart_fill_fifo(uart_num, (const char*) buffer, len); + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + return tx_len; +} + +static int uart_tx_all(uart_port_t uart_num, const char* src, size_t size, bool brk_en, int brk_len) +{ + if(size == 0) { + return 0; + } + size_t original_size = size; + + //lock for uart_tx + xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY); + if(p_uart_obj[uart_num]->tx_buf_size > 0) { + int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf); + int offset = 0; + uart_tx_data_t evt; + evt.tx_data.size = size; + evt.tx_data.brk_len = brk_len; + if(brk_en) { + evt.type = UART_DATA_BREAK; + } else { + evt.type = UART_DATA; + } + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) &evt, sizeof(uart_tx_data_t), portMAX_DELAY); + while(size > 0) { + int send_size = size > max_size / 2 ? max_size / 2 : size; + xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void*) (src + offset), send_size, portMAX_DELAY); + size -= send_size; + offset += send_size; + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); + } else { + while(size) { + //semaphore for tx_fifo available + if(pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY)) { + size_t sent = uart_fill_fifo(uart_num, (char*) src, size); + if(sent < size) { + p_uart_obj[uart_num]->tx_waiting_fifo = true; + uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT); + } + size -= sent; + src += sent; + } + } + if(brk_en) { + uart_set_break(uart_num, brk_len); + xSemaphoreTake(p_uart_obj[uart_num]->tx_brk_sem, (portTickType)portMAX_DELAY); + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); + } + xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); + return original_size; +} + +int uart_write_bytes(uart_port_t uart_num, const char* src, size_t size) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num] != NULL), "uart driver error", (-1)); + UART_CHECK(src, "buffer null", (-1)); + return uart_tx_all(uart_num, src, size, 0, 0); +} + +int uart_write_bytes_with_break(uart_port_t uart_num, const char* src, size_t size, int brk_len) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); + UART_CHECK((size > 0), "uart size error", (-1)); + UART_CHECK((src), "uart data null", (-1)); + UART_CHECK((brk_len > 0 && brk_len < 256), "break_num error", (-1)); + return uart_tx_all(uart_num, src, size, 1, brk_len); +} + +int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickType_t ticks_to_wait) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1)); + UART_CHECK((buf), "uart_num error", (-1)); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1)); + uint8_t* data = NULL; + size_t size; + size_t copy_len = 0; + int len_tmp; + if(xSemaphoreTake(p_uart_obj[uart_num]->rx_mux,(portTickType)ticks_to_wait) != pdTRUE) { + return -1; + } + while(length) { + if(p_uart_obj[uart_num]->rx_cur_remain == 0) { + data = (uint8_t*) xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType) ticks_to_wait); + if(data) { + p_uart_obj[uart_num]->rx_head_ptr = data; + p_uart_obj[uart_num]->rx_ptr = data; + p_uart_obj[uart_num]->rx_cur_remain = size; + } else { + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffered_len -= copy_len; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return copy_len; + } + } + if(p_uart_obj[uart_num]->rx_cur_remain > length) { + len_tmp = length; + } else { + len_tmp = p_uart_obj[uart_num]->rx_cur_remain; + } + memcpy(buf + copy_len, p_uart_obj[uart_num]->rx_ptr, len_tmp); + p_uart_obj[uart_num]->rx_ptr += len_tmp; + p_uart_obj[uart_num]->rx_cur_remain -= len_tmp; + copy_len += len_tmp; + length -= len_tmp; + if(p_uart_obj[uart_num]->rx_cur_remain == 0) { + vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr); + p_uart_obj[uart_num]->rx_head_ptr = NULL; + p_uart_obj[uart_num]->rx_ptr = NULL; + if(p_uart_obj[uart_num]->rx_buffer_full_flg) { + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); + if(res == pdTRUE) { + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffer_full_flg = false; + uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); + } + } + } + } + xSemaphoreGive(p_uart_obj[uart_num]->rx_mux); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffered_len -= copy_len; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + return copy_len; +} + +esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); + *size = p_uart_obj[uart_num]->rx_buffered_len; + return ESP_OK; +} + +esp_err_t uart_flush(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL); + uart_obj_t* p_uart = p_uart_obj[uart_num]; + uint8_t* data; + size_t size; + + //rx sem protect the ring buffer read related functions + xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY); + uart_disable_rx_intr(p_uart_obj[uart_num]->uart_num); + while(true) { + if(p_uart->rx_head_ptr) { + vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr); + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffered_len -= p_uart->rx_cur_remain; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + p_uart->rx_ptr = NULL; + p_uart->rx_cur_remain = 0; + p_uart->rx_head_ptr = NULL; + } + data = (uint8_t*) xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType) 0); + if(data == NULL) { + break; + } + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffered_len -= size; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + vRingbufferReturnItem(p_uart->rx_ring_buf, data); + if(p_uart_obj[uart_num]->rx_buffer_full_flg) { + BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1); + if(res == pdTRUE) { + UART_ENTER_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len; + UART_EXIT_CRITICAL(&uart_spinlock[uart_num]); + p_uart_obj[uart_num]->rx_buffer_full_flg = false; + } + } + } + p_uart->rx_ptr = NULL; + p_uart->rx_cur_remain = 0; + p_uart->rx_head_ptr = NULL; + uart_reset_fifo(uart_num); + uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num); + xSemaphoreGive(p_uart->rx_mux); + return ESP_OK; +} + +esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, void* uart_queue, int intr_alloc_flags) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + UART_CHECK((rx_buffer_size > UART_FIFO_LEN), "uart rx buffer length error(>128)", ESP_FAIL); + if(p_uart_obj[uart_num] == NULL) { + p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t)); + if(p_uart_obj[uart_num] == NULL) { + ESP_LOGE(UART_TAG, "UART driver malloc error"); + return ESP_FAIL; + } + p_uart_obj[uart_num]->uart_num = uart_num; + p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary(); + xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem); + p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary(); + p_uart_obj[uart_num]->tx_brk_sem = xSemaphoreCreateBinary(); + p_uart_obj[uart_num]->tx_mux = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->rx_mux = xSemaphoreCreateMutex(); + p_uart_obj[uart_num]->queue_size = queue_size; + p_uart_obj[uart_num]->tx_ptr = NULL; + p_uart_obj[uart_num]->tx_head = NULL; + p_uart_obj[uart_num]->tx_len_tot = 0; + p_uart_obj[uart_num]->tx_brk_flg = 0; + p_uart_obj[uart_num]->tx_brk_len = 0; + p_uart_obj[uart_num]->tx_waiting_brk = 0; + p_uart_obj[uart_num]->rx_buffered_len = 0; + + if(uart_queue) { + p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t)); + *((QueueHandle_t*) uart_queue) = p_uart_obj[uart_num]->xQueueUart; + ESP_LOGI(UART_TAG, "queue free spaces: %d", uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart)); + } else { + p_uart_obj[uart_num]->xQueueUart = NULL; + } + p_uart_obj[uart_num]->rx_buffer_full_flg = false; + p_uart_obj[uart_num]->tx_waiting_fifo = false; + p_uart_obj[uart_num]->rx_ptr = NULL; + p_uart_obj[uart_num]->rx_cur_remain = 0; + p_uart_obj[uart_num]->rx_head_ptr = NULL; + p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF); + if(tx_buffer_size > 0) { + p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT); + p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size; + } else { + p_uart_obj[uart_num]->tx_ring_buf = NULL; + p_uart_obj[uart_num]->tx_buf_size = 0; + } + } else { + ESP_LOGE(UART_TAG, "UART driver already installed"); + return ESP_FAIL; + } + uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num], intr_alloc_flags, &p_uart_obj[uart_num]->intr_handle); + uart_intr_config_t uart_intr = { + .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M + | UART_RXFIFO_TOUT_INT_ENA_M + | UART_FRM_ERR_INT_ENA_M + | UART_RXFIFO_OVF_INT_ENA_M + | UART_BRK_DET_INT_ENA_M + | UART_PARITY_ERR_INT_ENA_M, + .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT, + .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT, + .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT + }; + uart_intr_config(uart_num, &uart_intr); + return ESP_OK; +} + +//Make sure no other tasks are still using UART before you call this function +esp_err_t uart_driver_delete(uart_port_t uart_num) +{ + UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL); + if(p_uart_obj[uart_num] == NULL) { + ESP_LOGI(UART_TAG, "ALREADY NULL"); + return ESP_OK; + } + esp_intr_free(p_uart_obj[uart_num]->intr_handle); + uart_disable_rx_intr(uart_num); + uart_disable_tx_intr(uart_num); + + if(p_uart_obj[uart_num]->tx_fifo_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem); + p_uart_obj[uart_num]->tx_fifo_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_done_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem); + p_uart_obj[uart_num]->tx_done_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_brk_sem) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_brk_sem); + p_uart_obj[uart_num]->tx_brk_sem = NULL; + } + if(p_uart_obj[uart_num]->tx_mux) { + vSemaphoreDelete(p_uart_obj[uart_num]->tx_mux); + p_uart_obj[uart_num]->tx_mux = NULL; + } + if(p_uart_obj[uart_num]->rx_mux) { + vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux); + p_uart_obj[uart_num]->rx_mux = NULL; + } + if(p_uart_obj[uart_num]->xQueueUart) { + vQueueDelete(p_uart_obj[uart_num]->xQueueUart); + p_uart_obj[uart_num]->xQueueUart = NULL; + } + if(p_uart_obj[uart_num]->rx_ring_buf) { + vRingbufferDelete(p_uart_obj[uart_num]->rx_ring_buf); + p_uart_obj[uart_num]->rx_ring_buf = NULL; + } + if(p_uart_obj[uart_num]->tx_ring_buf) { + vRingbufferDelete(p_uart_obj[uart_num]->tx_ring_buf); + p_uart_obj[uart_num]->tx_ring_buf = NULL; + } + + free(p_uart_obj[uart_num]); + p_uart_obj[uart_num] = NULL; + return ESP_OK; +} diff --git a/components/esp32/Kconfig b/components/esp32/Kconfig index 8300b444c5..6ee5313b9b 100644 --- a/components/esp32/Kconfig +++ b/components/esp32/Kconfig @@ -138,6 +138,85 @@ config NEWLIB_STDOUT_ADDCR is usually done by an added CR character. Enabling this will make the standard output code automatically add a CR character before a LF. +config NEWLIB_NANO_FORMAT + bool "Enable 'nano' formatting options for printf/scanf family" + default n + help + ESP32 ROM contains parts of newlib C library, including printf/scanf family + of functions. These functions have been compiled with so-called "nano" + formatting option. This option doesn't support 64-bit integer formats and C99 + features, such as positional arguments. + + For more details about "nano" formatting option, please see newlib readme file, + search for '--enable-newlib-nano-formatted-io': + https://sourceware.org/newlib/README + + If this option is enabled, build system will use functions available in + ROM, reducing the application binary size. Functions available in ROM run + faster than functions which run from flash. Functions available in ROM can + also run when flash instruction cache is disabled. + + If you need 64-bit integer formatting support or C99 features, keep this + option disabled. + +choice CONSOLE_UART + prompt "UART for console output" + default CONSOLE_UART_DEFAULT + help + Select whether to use UART for console output (through stdout and stderr). + - Default is to use UART0 on pins GPIO1(TX) and GPIO3(RX). + - If "Custom" is selected, UART0 or UART1 can be chosen, + and any pins can be selected. + - If "None" is selected, there will be no console output on any UART, except + for initial output from ROM bootloader. This output can be further suppressed by + bootstrapping GPIO13 pin to low logic level. + +config CONSOLE_UART_DEFAULT + bool "Default: UART0, TX=GPIO1, RX=GPIO3" +config CONSOLE_UART_CUSTOM + bool "Custom" +config CONSOLE_UART_NONE + bool "None" +endchoice + +choice CONSOLE_UART_NUM + prompt "UART peripheral to use for console output (0-1)" + depends on CONSOLE_UART_CUSTOM + default CONSOLE_UART_CUSTOM_NUM_0 + help + Due of a ROM bug, UART2 is not supported for console output + via ets_printf. + +config CONSOLE_UART_CUSTOM_NUM_0 + bool "UART0" +config CONSOLE_UART_CUSTOM_NUM_1 + bool "UART1" +endchoice + +config CONSOLE_UART_NUM + int + default 0 if CONSOLE_UART_DEFAULT || CONSOLE_UART_NONE + default 0 if CONSOLE_UART_CUSTOM_NUM_0 + default 1 if CONSOLE_UART_CUSTOM_NUM_1 + +config CONSOLE_UART_TX_GPIO + int "UART TX on GPIO#" + depends on CONSOLE_UART_CUSTOM + range 0 33 + default 19 + +config CONSOLE_UART_RX_GPIO + int "UART RX on GPIO#" + depends on CONSOLE_UART_CUSTOM + range 0 39 + default 21 + +config CONSOLE_UART_BAUDRATE + int "UART console baud rate" + depends on !CONSOLE_UART_NONE + default 115200 + range 1200 4000000 + config ULP_COPROC_ENABLED bool "Enable Ultra Low Power (ULP) Coprocessor" default "n" @@ -373,6 +452,25 @@ config ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL endchoice +config ESP32_DEEP_SLEEP_WAKEUP_DELAY + int "Extra delay in deep sleep wake stub (in us)" + default 0 + range 0 5000 + help + When ESP32 exits deep sleep, the CPU and the flash chip are powered on + at the same time. CPU will run deep sleep stub first, and then + proceed to load code from flash. Some flash chips need sufficient + time to pass between power on and first read operation. By default, + without any extra delay, this time is approximately 900us. + + If you are using a flash chip which needs more than 900us to become + ready after power on, set this parameter to add extra delay + to the default deep sleep stub. + + If you are seeing "flash read err, 1000" message printed to the + console after deep sleep reset, try increasing this value. + + config ESP32_PHY_AUTO_INIT bool "Initialize PHY in startup code" default y diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 6c0d65d9c5..4ceb13e837 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -6,27 +6,27 @@ COMPONENT_SRCDIRS := . hwcrypto LIBS := core net80211 phy rtc pp wpa smartconfig coexist wps wpa2 -LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld +LINKER_SCRIPTS += esp32.common.ld esp32.rom.ld esp32.peripherals.ld + +ifeq ("$(CONFIG_NEWLIB_NANO_FORMAT)","y") +LINKER_SCRIPTS += esp32.rom.nanofmt.ld +endif COMPONENT_ADD_LDFLAGS := -lesp32 \ - $(COMPONENT_PATH)/libhal.a \ - -L$(COMPONENT_PATH)/lib \ - $(addprefix -l,$(LIBS)) \ - -L $(COMPONENT_PATH)/ld \ - $(LINKER_SCRIPTS) + $(COMPONENT_PATH)/libhal.a \ + -L$(COMPONENT_PATH)/lib \ + $(addprefix -l,$(LIBS)) \ + -L $(COMPONENT_PATH)/ld \ + -T esp32_out.ld \ + $(addprefix -T ,$(LINKER_SCRIPTS)) ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS)) COMPONENT_SUBMODULES += lib -# this is a hack to make sure the app is re-linked if the binary -# libraries change or are updated. If they change, the main esp32 -# library will be rebuild by AR andthis will trigger a re-linking of -# the entire app. -# -# It would be better for components to be able to expose any of these -# non-standard dependencies via get_variable, but this will do for now. -$(COMPONENT_LIBRARY): $(ALL_LIB_FILES) +# final linking of project ELF depends on all binary libraries, and +# all linker scripts (except esp32_out.ld, as this is code generated here.) +COMPONENT_ADD_LINKER_DEPS := $(ALL_LIB_FILES) $(addprefix ld/,$(LINKER_SCRIPTS)) # Preprocess esp32.ld linker script into esp32_out.ld # diff --git a/components/esp32/cpu_freq.c b/components/esp32/cpu_freq.c index c68dd4f078..257639cf90 100644 --- a/components/esp32/cpu_freq.c +++ b/components/esp32/cpu_freq.c @@ -18,6 +18,8 @@ #include "sdkconfig.h" #include "phy.h" #include "rtc.h" +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" /* * This function is not exposed as an API at this point, @@ -33,9 +35,13 @@ void esp_set_cpu_freq(void) // freq will be changed to 40MHz in rtc_init_lite, // wait uart tx finish, otherwise some uart output will be lost - uart_tx_wait_idle(0); + uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM); rtc_init_lite(XTAL_AUTO); + // work around a bug that RTC fast memory may be isolated + // from the system after rtc_init_lite + SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_NOISO_M); + cpu_freq_t freq = CPU_80M; switch(freq_mhz) { case 240: @@ -54,7 +60,7 @@ void esp_set_cpu_freq(void) // freq will be changed to freq in rtc_set_cpu_freq, // wait uart tx finish, otherwise some uart output will be lost - uart_tx_wait_idle(0); + uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM); rtc_set_cpu_freq(freq); ets_update_cpu_frequency(freq_mhz); diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 1641ab3f0a..864a17a1b6 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -26,6 +26,9 @@ #include "soc/dport_reg.h" #include "soc/io_mux_reg.h" #include "soc/rtc_cntl_reg.h" +#include "soc/timer_group_reg.h" + +#include "driver/rtc_io.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -54,6 +57,9 @@ #include "esp_coexist.h" #include "trax.h" +#define STRINGIFY(s) STRINGIFY2(s) +#define STRINGIFY2(s) #s + void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))); void start_cpu0_default(void) IRAM_ATTR; #if !CONFIG_FREERTOS_UNICORE @@ -86,10 +92,6 @@ static const char* TAG = "cpu_start"; void IRAM_ATTR call_start_cpu0() { - //Kill wdt - REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN); - REG_CLR_BIT(0x6001f048, BIT(14)); //DR_REG_BB_BASE+48 - cpu_configure_region_protection(); //Move exception vectors to IRAM @@ -97,9 +99,6 @@ void IRAM_ATTR call_start_cpu0() "wsr %0, vecbase\n" \ ::"r"(&_init_start)); - uartAttach(); - ets_install_uart_printf(); - memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start)); /* Unless waking from deep sleep (implying RTC memory is intact), clear RTC bss */ @@ -145,6 +144,15 @@ void IRAM_ATTR call_start_cpu1() cpu_configure_region_protection(); +#if CONFIG_CONSOLE_UART_NONE + ets_install_putc1(NULL); + ets_install_putc2(NULL); +#else // CONFIG_CONSOLE_UART_NONE + uartAttach(); + ets_install_uart_printf(); + uart_tx_switch(CONFIG_CONSOLE_UART_NUM); +#endif + ESP_EARLY_LOGI(TAG, "App cpu up."); app_cpu_started = 1; start_cpu1(); @@ -164,24 +172,31 @@ void start_cpu0_default(void) trax_start_trace(TRAX_DOWNCOUNT_WORDS); #endif esp_set_cpu_freq(); // set CPU frequency configured in menuconfig - uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200); + uart_div_modify(CONFIG_CONSOLE_UART_NUM, (APB_CLK_FREQ << 4) / CONFIG_CONSOLE_UART_BAUDRATE); #if CONFIG_BROWNOUT_DET esp_brownout_init(); #endif + rtc_gpio_unhold_all(); + esp_setup_time_syscalls(); + esp_vfs_dev_uart_register(); + esp_reent_init(_GLOBAL_REENT); +#ifndef CONFIG_CONSOLE_UART_NONE + const char* default_uart_dev = "/dev/uart/" STRINGIFY(CONFIG_CONSOLE_UART_NUM); + _GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r"); + _GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w"); + _GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w"); +#else + _GLOBAL_REENT->_stdin = (FILE*) &__sf_fake_stdin; + _GLOBAL_REENT->_stdout = (FILE*) &__sf_fake_stdout; + _GLOBAL_REENT->_stderr = (FILE*) &__sf_fake_stderr; +#endif + do_global_ctors(); #if CONFIG_INT_WDT esp_int_wdt_init(); #endif #if CONFIG_TASK_WDT esp_task_wdt_init(); #endif - esp_setup_time_syscalls(); - esp_vfs_dev_uart_register(); - esp_reent_init(_GLOBAL_REENT); - const char* default_uart_dev = "/dev/uart/0"; - _GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r"); - _GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w"); - _GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w"); - do_global_ctors(); #if !CONFIG_FREERTOS_UNICORE esp_crosscore_int_init(); #endif @@ -194,9 +209,9 @@ void start_cpu0_default(void) #endif #if CONFIG_SW_COEXIST_ENABLE - if (coex_init() == ESP_OK) { + if (coex_init() == ESP_OK) { coexist_set_enable(true); - } + } #endif xTaskCreatePinnedToCore(&main_task, "main", @@ -216,8 +231,11 @@ void start_cpu1_default(void) while (port_xSchedulerRunning[0] == 0) { ; } + //Take care putting stuff here: if asked, FreeRTOS will happily tell you the scheduler + //has started, but it isn't active *on this CPU* yet. esp_crosscore_int_init(); - ESP_LOGI(TAG, "Starting scheduler on APP CPU."); + + ESP_EARLY_LOGI(TAG, "Starting scheduler on APP CPU."); xPortStartScheduler(); } #endif //!CONFIG_FREERTOS_UNICORE @@ -232,6 +250,9 @@ static void do_global_ctors(void) static void main_task(void* args) { + // Now that the application is about to start, disable boot watchdogs + REG_CLR_BIT(TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN_S); + REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN); app_main(); vTaskDelete(NULL); } diff --git a/components/esp32/crosscore_int.c b/components/esp32/crosscore_int.c index 60f972a2a2..f7ea4f6a74 100644 --- a/components/esp32/crosscore_int.c +++ b/components/esp32/crosscore_int.c @@ -17,6 +17,7 @@ #include "esp_attr.h" #include "esp_err.h" #include "esp_intr.h" +#include "esp_intr_alloc.h" #include "rom/ets_sys.h" #include "rom/uart.h" @@ -72,14 +73,11 @@ void esp_crosscore_int_init() { portENTER_CRITICAL(&reasonSpinlock); reason[xPortGetCoreID()]=0; portEXIT_CRITICAL(&reasonSpinlock); - ESP_INTR_DISABLE(ETS_FROM_CPU_INUM); if (xPortGetCoreID()==0) { - intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR0_SOURCE, ETS_FROM_CPU_INUM); + esp_intr_alloc(ETS_FROM_CPU_INTR0_SOURCE, ESP_INTR_FLAG_IRAM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()], NULL); } else { - intr_matrix_set(xPortGetCoreID(), ETS_FROM_CPU_INTR1_SOURCE, ETS_FROM_CPU_INUM); + esp_intr_alloc(ETS_FROM_CPU_INTR1_SOURCE, ESP_INTR_FLAG_IRAM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()], NULL); } - xt_set_interrupt_handler(ETS_FROM_CPU_INUM, esp_crosscore_isr, (void*)&reason[xPortGetCoreID()]); - ESP_INTR_ENABLE(ETS_FROM_CPU_INUM); } void esp_crosscore_int_send_yield(int coreId) { diff --git a/components/esp32/deep_sleep.c b/components/esp32/deep_sleep.c new file mode 100644 index 0000000000..7f59c21635 --- /dev/null +++ b/components/esp32/deep_sleep.c @@ -0,0 +1,350 @@ +// 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 +#include +#include "esp_attr.h" +#include "esp_deep_sleep.h" +#include "esp_log.h" +#include "rom/cache.h" +#include "rom/rtc.h" +#include "rom/uart.h" +#include "soc/cpu.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/dport_reg.h" +#include "driver/rtc_io.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "rtc.h" +#include "sdkconfig.h" + +/** + * Internal structure which holds all requested deep sleep parameters + */ +typedef struct { + esp_deep_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX]; + uint64_t sleep_duration; + uint32_t wakeup_triggers : 11; + uint32_t ext1_trigger_mode : 1; + uint32_t ext1_rtc_gpio_mask : 18; + uint32_t ext0_trigger_level : 1; + uint32_t ext0_rtc_gpio_num : 5; +} deep_sleep_config_t; + +static deep_sleep_config_t s_config = { + .pd_options = { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO }, + .wakeup_triggers = 0 +}; + +/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() + is not thread-safe. */ +static _lock_t lock_rtc_memory_crc; + +static const char* TAG = "deepsleep"; + +static uint32_t get_power_down_flags(); +static void ext0_wakeup_prepare(); +static void ext1_wakeup_prepare(); + +/* Wake from deep sleep stub + See esp_deepsleep.h esp_wake_deep_sleep() comments for details. +*/ +esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void) +{ + _lock_acquire(&lock_rtc_memory_crc); + uint32_t stored_crc = REG_READ(RTC_MEMORY_CRC_REG); + set_rtc_memory_crc(); + uint32_t calc_crc = REG_READ(RTC_MEMORY_CRC_REG); + REG_WRITE(RTC_MEMORY_CRC_REG, stored_crc); + _lock_release(&lock_rtc_memory_crc); + + if(stored_crc == calc_crc) { + return (esp_deep_sleep_wake_stub_fn_t)REG_READ(RTC_ENTRY_ADDR_REG); + } else { + return NULL; + } +} + +void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) +{ + _lock_acquire(&lock_rtc_memory_crc); + REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); + set_rtc_memory_crc(); + _lock_release(&lock_rtc_memory_crc); +} + +void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { + /* Clear MMU for CPU 0 */ + REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); + REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); +#if CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY > 0 + // ROM code has not started yet, so we need to set delay factor + // used by ets_delay_us first. + ets_update_cpu_frequency(ets_get_detected_xtal_freq() / 1000000); + // This delay is configured in menuconfig, it can be used to give + // the flash chip some time to become ready. + ets_delay_us(CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY); +#endif +} + +void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); + +void esp_deep_sleep(uint64_t time_in_us) +{ + esp_deep_sleep_enable_timer_wakeup(time_in_us); + esp_deep_sleep_start(); +} + +void IRAM_ATTR esp_deep_sleep_start() +{ + // Decide which power domains can be powered down + uint32_t pd_flags = get_power_down_flags(); + + // Configure pins for external wakeup + if (s_config.wakeup_triggers & EXT_EVENT0_TRIG_EN) { + ext0_wakeup_prepare(); + } + if (s_config.wakeup_triggers & EXT_EVENT1_TRIG_EN) { + ext1_wakeup_prepare(); + } + // TODO: move timer wakeup configuration into a similar function + // once rtc_sleep is opensourced. + + // Flush UARTs so that output is not lost due to APB frequency change + uart_tx_wait_idle(0); + uart_tx_wait_idle(1); + uart_tx_wait_idle(2); + + if (esp_get_deep_sleep_wake_stub() == NULL) { + esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep); + } + + rtc_set_cpu_freq(CPU_XTAL); + uint32_t cycle_h = 0; + uint32_t cycle_l = 0; + // For timer wakeup, calibrate clock source against main XTAL + // This is hardcoded to use 150kHz internal oscillator for now + if (s_config.sleep_duration > 0) { + uint32_t period = rtc_slowck_cali(CALI_RTC_MUX, 128); + rtc_usec2rtc(s_config.sleep_duration >> 32, s_config.sleep_duration & UINT32_MAX, + period, &cycle_h, &cycle_l); + } + // Enter deep sleep + rtc_slp_prep_lite(pd_flags, 0); + rtc_sleep(cycle_h, cycle_l, s_config.wakeup_triggers, 0); + // Because RTC is in a slower clock domain than the CPU, it + // can take several CPU cycles for the sleep mode to start. + while (1) { + ; + } +} + +void system_deep_sleep(uint64_t) __attribute__((alias("esp_deep_sleep"))); + +esp_err_t esp_deep_sleep_enable_ulp_wakeup() +{ +#ifdef CONFIG_ULP_COPROC_ENABLED + s_config.wakeup_triggers |= RTC_SAR_TRIG_EN; + return ESP_OK; +#else + return ESP_ERR_INVALID_STATE; +#endif +} + +esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us) +{ + s_config.wakeup_triggers |= RTC_TIMER_EXPIRE_EN; + s_config.sleep_duration = time_in_us; + return ESP_OK; +} + +esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level) +{ + if (level < 0 || level > 1) { + return ESP_ERR_INVALID_ARG; + } + if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) { + return ESP_ERR_INVALID_ARG; + } + s_config.ext0_rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num; + s_config.ext0_trigger_level = level; + s_config.wakeup_triggers |= RTC_EXT_EVENT0_TRIG_EN; + return ESP_OK; +} + +static void ext0_wakeup_prepare() +{ + int rtc_gpio_num = s_config.ext0_rtc_gpio_num; + // Set GPIO to be used for wakeup + REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtc_gpio_num); + // Set level which will trigger wakeup + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + s_config.ext0_trigger_level, RTC_CNTL_EXT_WAKEUP0_LV_S); + // Find GPIO descriptor in the rtc_gpio_desc table and configure the pad + for (size_t gpio_num = 0; gpio_num < GPIO_PIN_COUNT; ++gpio_num) { + const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio_num]; + if (desc->rtc_num == rtc_gpio_num) { + REG_SET_BIT(desc->reg, desc->mux); + SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); + REG_SET_BIT(desc->reg, desc->slpsel); + REG_SET_BIT(desc->reg, desc->slpie); + break; + } + } +} + +esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode) +{ + if (mode > ESP_EXT1_WAKEUP_ANY_HIGH) { + return ESP_ERR_INVALID_ARG; + } + // Translate bit map of GPIO numbers into the bit map of RTC IO numbers + uint32_t rtc_gpio_mask = 0; + for (int gpio = 0; mask; ++gpio, mask >>= 1) { + if ((mask & 1) == 0) { + continue; + } + if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { + ESP_LOGE(TAG, "Not an RTC IO: GPIO%d", gpio); + return ESP_ERR_INVALID_ARG; + } + rtc_gpio_mask |= BIT(rtc_gpio_desc[gpio].rtc_num); + } + s_config.ext1_rtc_gpio_mask = rtc_gpio_mask; + s_config.ext1_trigger_mode = mode; + s_config.wakeup_triggers |= RTC_EXT_EVENT1_TRIG_EN; + return ESP_OK; +} + +static void ext1_wakeup_prepare() +{ + // Configure all RTC IOs selected as ext1 wakeup inputs + uint32_t rtc_gpio_mask = s_config.ext1_rtc_gpio_mask; + for (int gpio = 0; gpio < GPIO_PIN_COUNT && rtc_gpio_mask != 0; ++gpio) { + int rtc_pin = rtc_gpio_desc[gpio].rtc_num; + if ((rtc_gpio_mask & BIT(rtc_pin)) == 0) { + continue; + } + const rtc_gpio_desc_t* desc = &rtc_gpio_desc[gpio]; + // Route pad to RTC + REG_SET_BIT(desc->reg, desc->mux); + SET_PERI_REG_BITS(desc->reg, 0x3, 0, desc->func); + // Pad configuration depends on RTC_PERIPH state in sleep mode + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_ON) { + // set input enable in sleep mode + REG_SET_BIT(desc->reg, desc->slpie); + // allow sleep status signal to control IE/SLPIE mux + REG_SET_BIT(desc->reg, desc->slpsel); + } else { + // RTC_PERIPH will be disabled, so need to enable input and + // lock pad configuration. Pullups/pulldowns also need to be disabled. + REG_SET_BIT(desc->reg, desc->ie); + REG_CLR_BIT(desc->reg, desc->pulldown); + REG_CLR_BIT(desc->reg, desc->pullup); + REG_SET_BIT(RTC_CNTL_HOLD_FORCE_REG, desc->hold); + } + // Keep track of pins which are processed to bail out early + rtc_gpio_mask &= ~BIT(rtc_pin); + } + // Clear state from previous wakeup + REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR); + // Set pins to be used for wakeup + REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, s_config.ext1_rtc_gpio_mask); + // Set logic function (any low, all high) + SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1, + s_config.ext1_trigger_mode, RTC_CNTL_EXT_WAKEUP1_LV_S); +} + +uint64_t esp_deep_sleep_get_ext1_wakeup_status() +{ + int wakeup_reason = REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE); + if (wakeup_reason != RTC_EXT_EVENT1_TRIG) { + return 0; + } + uint32_t status = REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS); + // Translate bit map of RTC IO numbers into the bit map of GPIO numbers + uint64_t gpio_mask = 0; + for (int gpio = 0; gpio < GPIO_PIN_COUNT; ++gpio) { + if (!RTC_GPIO_IS_VALID_GPIO(gpio)) { + continue; + } + int rtc_pin = rtc_gpio_desc[gpio].rtc_num; + if ((status & BIT(rtc_pin)) == 0) { + continue; + } + gpio_mask |= BIT(gpio); + } + return gpio_mask; +} + +esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain, + esp_deep_sleep_pd_option_t option) +{ + if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) { + return ESP_ERR_INVALID_ARG; + } + s_config.pd_options[domain] = option; + return ESP_OK; +} + +static uint32_t get_power_down_flags() +{ + // Where needed, convert AUTO options to ON. Later interpret AUTO as OFF. + + // RTC_SLOW_MEM is needed only for the ULP. + // If RTC_SLOW_MEM is Auto, and ULP wakeup isn't enabled, power down RTC_SLOW_MEM. + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) { + if (s_config.wakeup_triggers & RTC_SAR_TRIG_EN) { + s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON; + } + } + + // RTC_FAST_MEM is needed for deep sleep stub. + // If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub + // can run. + // In the new chip revision, deep sleep stub will be optional, + // and this can be changed. + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) { + s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; + } + + // RTC_PERIPH is needed for EXT0 wakeup and for ULP. + // If RTC_PERIPH is auto, and both EXT0 and ULP aren't enabled, + // power down RTC_PERIPH. + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) { + if (s_config.wakeup_triggers & + (RTC_SAR_TRIG_EN | RTC_EXT_EVENT0_TRIG_EN)) { + s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON; + } + } + + const char* option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; + ESP_LOGD(TAG, "RTC_PERIPH: %s, RTC_SLOW_MEM: %s, RTC_FAST_MEM: %s", + option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]], + option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]], + option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]); + + // Prepare flags based on the selected options + uint32_t pd_flags = DEEP_SLEEP_PD_NORMAL; + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) { + pd_flags |= DEEP_SLEEP_PD_RTC_FAST_MEM; + } + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) { + pd_flags |= DEEP_SLEEP_PD_RTC_SLOW_MEM; + } + if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { + pd_flags |= DEEP_SLEEP_PD_RTC_PERIPH; + } + return pd_flags; +} diff --git a/components/esp32/deepsleep.c b/components/esp32/deepsleep.c deleted file mode 100644 index b8b73a3b1f..0000000000 --- a/components/esp32/deepsleep.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Wake from deep sleep stub - - See esp_deepsleep.h esp_wake_deep_sleep() comments for details. -*/ -#include -#include -#include "rom/cache.h" -#include "rom/rtc.h" -#include "soc/rtc_cntl_reg.h" -#include "soc/dport_reg.h" -#include "esp_attr.h" -#include "esp_deepsleep.h" -#include "rtc.h" - -/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() - is not thread-safe. */ -static _lock_t lock_rtc_memory_crc; - -esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void) -{ - _lock_acquire(&lock_rtc_memory_crc); - uint32_t stored_crc = REG_READ(RTC_MEMORY_CRC_REG); - set_rtc_memory_crc(); - uint32_t calc_crc = REG_READ(RTC_MEMORY_CRC_REG); - REG_WRITE(RTC_MEMORY_CRC_REG, stored_crc); - _lock_release(&lock_rtc_memory_crc); - - if(stored_crc == calc_crc) { - return (esp_deep_sleep_wake_stub_fn_t)REG_READ(RTC_ENTRY_ADDR_REG); - } else { - return NULL; - } -} - -void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub) -{ - _lock_acquire(&lock_rtc_memory_crc); - REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub); - set_rtc_memory_crc(); - _lock_release(&lock_rtc_memory_crc); -} - -void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) { - /* Clear MMU for CPU 0 */ - REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); - REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR); -} - -void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void); - -void esp_deep_sleep(uint64_t time_in_us) -{ - rtc_set_cpu_freq(CPU_XTAL); - if (esp_get_deep_sleep_wake_stub() == NULL) { - esp_set_deep_sleep_wake_stub(esp_wake_deep_sleep); - } - uint32_t period = rtc_slowck_cali(CALI_RTC_MUX, 128); - uint32_t cycle_l, cycle_h; - rtc_usec2rtc(time_in_us >> 32, time_in_us, period, &cycle_h, &cycle_l); - rtc_slp_prep_lite(1, 0); - rtc_sleep(cycle_h, cycle_l, TIMER_EXPIRE_EN, 0); - while (1) { - ; - } -} - -void system_deep_sleep(uint64_t) __attribute__((alias("esp_deep_sleep"))); diff --git a/components/esp32/gdbstub.c b/components/esp32/gdbstub.c index 819944a902..757725aad6 100644 --- a/components/esp32/gdbstub.c +++ b/components/esp32/gdbstub.c @@ -18,12 +18,9 @@ * it allows inspecting the ESP32 state *******************************************************************************/ -//ToDo: Clean up includes and sync to real rtos #include "rom/ets_sys.h" - #include "soc/uart_reg.h" #include "soc/io_mux_reg.h" - #include "esp_gdbstub.h" #include "driver/gpio.h" @@ -36,17 +33,10 @@ static char chsum; //Running checksum of the output packet #define ATTR_GDBFN -static void ATTR_GDBFN keepWDTalive() { - //ToDo for esp31/32 -} - - //Receive a char from the uart. Uses polling and feeds the watchdog. static int ATTR_GDBFN gdbRecvChar() { int i; - while (((READ_PERI_REG(UART_STATUS_REG(0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT)==0) { - keepWDTalive(); - } + while (((READ_PERI_REG(UART_STATUS_REG(0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT)==0) ; i=READ_PERI_REG(UART_FIFO_REG(0)); return i; } @@ -260,7 +250,11 @@ static void sendReason() { gdbPacketStart(); gdbPacketChar('T'); i=gdbRegFile.expstate&0x7f; - if (i static const char* TAG = "heap_alloc_caps"; @@ -35,28 +36,35 @@ hardwiring addresses. //Amount of priority slots for the tag descriptors. #define NO_PRIOS 3 +typedef struct { + const char *name; + uint32_t prio[NO_PRIOS]; + bool aliasedIram; +} tag_desc_t; + /* Tag descriptors. These describe the capabilities of a bit of memory that's tagged with the index into this table. Each tag contains NO_PRIOS entries; later entries are only taken if earlier ones can't fulfill the memory request. +Make sure there are never more than HEAPREGIONS_MAX_TAGCOUNT (in heap_regions.h) tags (ex the last empty marker) */ -static const uint32_t tagDesc[][NO_PRIOS]={ - { MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT, 0 }, //Tag 0: Plain ole D-port RAM - { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, //Tag 1: Plain ole D-port RAM which has an alias on the I-port - { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT, 0, 0 }, //Tag 2: IRAM - { MALLOC_CAP_PID2, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, //Tag 3-8: PID 2-7 IRAM - { MALLOC_CAP_PID3, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID4, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID5, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID6, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID7, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID2, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, //Tag 9-14: PID 2-7 DRAM - { MALLOC_CAP_PID3, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID4, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID5, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID6, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_PID7, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, // - { MALLOC_CAP_SPISRAM, 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, //Tag 15: SPI SRAM data - { MALLOC_CAP_INVALID, MALLOC_CAP_INVALID, MALLOC_CAP_INVALID } //End +static const tag_desc_t tag_desc[]={ + { "DRAM", { MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT, 0 }, false}, //Tag 0: Plain ole D-port RAM + { "D/IRAM", { 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT, MALLOC_CAP_32BIT|MALLOC_CAP_EXEC }, true}, //Tag 1: Plain ole D-port RAM which has an alias on the I-port + { "IRAM", { MALLOC_CAP_EXEC|MALLOC_CAP_32BIT, 0, 0 }, false}, //Tag 2: IRAM + { "PID2IRAM", { MALLOC_CAP_PID2, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false}, //Tag 3-8: PID 2-7 IRAM + { "PID3IRAM", { MALLOC_CAP_PID3, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false}, // + { "PID4IRAM", { MALLOC_CAP_PID4, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false}, // + { "PID5IRAM", { MALLOC_CAP_PID5, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false}, // + { "PID6IRAM", { MALLOC_CAP_PID6, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false}, // + { "PID7IRAM", { MALLOC_CAP_PID7, 0, MALLOC_CAP_EXEC|MALLOC_CAP_32BIT }, false}, // + { "PID2DRAM", { MALLOC_CAP_PID2, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false}, //Tag 9-14: PID 2-7 DRAM + { "PID3DRAM", { MALLOC_CAP_PID3, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false}, // + { "PID4DRAM", { MALLOC_CAP_PID4, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false}, // + { "PID5DRAM", { MALLOC_CAP_PID5, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false}, // + { "PID6DRAM", { MALLOC_CAP_PID6, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false}, // + { "PID7DRAM", { MALLOC_CAP_PID7, MALLOC_CAP_8BIT, MALLOC_CAP_32BIT }, false}, // + { "SPISRAM", { MALLOC_CAP_SPISRAM, 0, MALLOC_CAP_DMA|MALLOC_CAP_8BIT|MALLOC_CAP_32BIT}, false}, //Tag 15: SPI SRAM data + { "", { MALLOC_CAP_INVALID, MALLOC_CAP_INVALID, MALLOC_CAP_INVALID }, false} //End }; /* @@ -158,10 +166,11 @@ static void disable_mem_region(void *from, void *to) { /* -ToDo: These are very dependent on the linker script, and the logic involving this works only -because we're not using the SPI flash yet! If we enable that, this will break. ToDo: Rewrite by then. +Warning: These variables are assumed to have the start and end of the data and iram +area used statically by the program, respectively. These variables are defined in the ld +file. */ -extern int _bss_start, _heap_start; +extern int _bss_start, _heap_start, _init_start, _iram_text_end; /* Initialize the heap allocator. We pass it a bunch of region descriptors, but we need to modify those first to accommodate for @@ -171,12 +180,14 @@ Same with loading of apps. Same with using SPI RAM. */ void heap_alloc_caps_init() { int i; + //Compile-time assert to see if we don't have more tags than is set in heap_regions.h + _Static_assert((sizeof(tag_desc)/sizeof(tag_desc[0]))-1 <= HEAPREGIONS_MAX_TAGCOUNT, "More than HEAPREGIONS_MAX_TAGCOUNT tags defined!"); //Disable the bits of memory where this code is loaded. - disable_mem_region(&_bss_start, &_heap_start); + disable_mem_region(&_bss_start, &_heap_start); //DRAM used by bss/data static variables + disable_mem_region(&_init_start, &_iram_text_end); //IRAM used by code disable_mem_region((void*)0x3ffae000, (void*)0x3ffb0000); //knock out ROM data region disable_mem_region((void*)0x40070000, (void*)0x40078000); //CPU0 cache region disable_mem_region((void*)0x40078000, (void*)0x40080000); //CPU1 cache region - disable_mem_region((void*)0x40080000, (void*)0x400a0000); //pool 2-5 // TODO: this region should be checked, since we don't need to knock out all region finally disable_mem_region((void*)0x3ffe0000, (void*)0x3ffe8000); //knock out ROM data region @@ -211,25 +222,72 @@ void heap_alloc_caps_init() { } } - ESP_EARLY_LOGI(TAG, "Initializing heap allocator:"); + ESP_EARLY_LOGI(TAG, "Initializing. RAM available for dynamic allocation:"); for (i=0; regions[i].xSizeInBytes!=0; i++) { if (regions[i].xTag != -1) { - ESP_EARLY_LOGI(TAG, "Region %02d: %08X len %08X tag %d", i, - (int)regions[i].pucStartAddress, regions[i].xSizeInBytes, regions[i].xTag); + ESP_EARLY_LOGI(TAG, "At %08X len %08X (%d KiB): %s", + (int)regions[i].pucStartAddress, regions[i].xSizeInBytes, regions[i].xSizeInBytes/1024, tag_desc[regions[i].xTag].name); } } //Initialize the malloc implementation. vPortDefineHeapRegionsTagged( regions ); } +//First and last words of the D/IRAM region, for both the DRAM address as well as the IRAM alias. +#define DIRAM_IRAM_START 0x400A0000 +#define DIRAM_IRAM_END 0x400BFFFC +#define DIRAM_DRAM_START 0x3FFE0000 +#define DIRAM_DRAM_END 0x3FFFFFFC + /* -Standard malloc() implementation. Will return ho-hum byte-accessible data memory. + This takes a memory chunk in a region that can be addressed as both DRAM as well as IRAM. It will convert it to + IRAM in such a way that it can be later freed. It assumes both the address as wel as the length to be word-aligned. + It returns a region that's 1 word smaller than the region given because it stores the original Dram address there. + + In theory, we can also make this work by prepending a struct that looks similar to the block link struct used by the + heap allocator itself, which will allow inspection tools relying on any block returned from any sort of malloc to + have such a block in front of it, work. We may do this later, if/when there is demand for it. For now, a simple + pointer is used. +*/ +static void *dram_alloc_to_iram_addr(void *addr, size_t len) +{ + uint32_t dstart=(int)addr; //First word + uint32_t dend=((int)addr)+len-4; //Last word + configASSERT(dstart>=DIRAM_DRAM_START); + configASSERT(dend<=DIRAM_DRAM_END); + configASSERT((dstart&3)==0); + configASSERT((dend&3)==0); + uint32_t istart=DIRAM_IRAM_START+(DIRAM_DRAM_END-dend); + uint32_t *iptr=(uint32_t*)istart; + *iptr=dstart; + return (void*)(iptr+1); +} + +/* +Standard malloc() implementation. Will return standard no-frills byte-accessible data memory. */ void *pvPortMalloc( size_t xWantedSize ) { return pvPortMallocCaps( xWantedSize, MALLOC_CAP_8BIT ); } +/* + Standard free() implementation. Will pass memory on to the allocator unless it's an IRAM address where the + actual meory is allocated in DRAM, it will convert to the DRAM address then. + */ +void vPortFree( void *pv ) +{ + if (((int)pv>=DIRAM_IRAM_START) && ((int)pv<=DIRAM_IRAM_END)) { + //Memory allocated here is actually allocated in the DRAM alias region and + //cannot be de-allocated as usual. dram_alloc_to_iram_addr stores a pointer to + //the equivalent DRAM address, though; free that. + uint32_t* dramAddrPtr=(uint32_t*)pv; + return vPortFreeTagged((void*)dramAddrPtr[-1]); + } + + return vPortFreeTagged(pv); +} + /* Routine to allocate a bit of memory with certain capabilities. caps is a bitfield of MALLOC_CAP_* bits. */ @@ -239,22 +297,42 @@ void *pvPortMallocCaps( size_t xWantedSize, uint32_t caps ) int tag, j; void *ret=NULL; uint32_t remCaps; + if (caps & MALLOC_CAP_EXEC) { + //MALLOC_CAP_EXEC forces an alloc from IRAM. There is a region which has both this + //as well as the following caps, but the following caps are not possible for IRAM. + //Thus, the combination is impossible and we return NULL directly, even although our tag_desc + //table would indicate there is a tag for this. + if ((caps & MALLOC_CAP_8BIT) || (caps & MALLOC_CAP_DMA)) { + return NULL; + } + //If any, EXEC memory should be 32-bit aligned, so round up to the next multiple of 4. + xWantedSize=(xWantedSize+3)&(~3); + } for (prio=0; prio +#include "esp_err.h" +#include "driver/gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief Logic function used for EXT1 wakeup mode. + */ +typedef enum { + ESP_EXT1_WAKEUP_ALL_LOW = 0, //!< Wake the chip when all selected GPIOs go low + ESP_EXT1_WAKEUP_ANY_HIGH = 1 //!< Wake the chip when any of the selected GPIOs go high +} esp_ext1_wakeup_mode_t; + +/** + * @brief Power domains which can be powered down in deep sleep + */ +typedef enum { + ESP_PD_DOMAIN_RTC_PERIPH, //!< RTC IO, sensors and ULP co-processor + ESP_PD_DOMAIN_RTC_SLOW_MEM, //!< RTC slow memory + ESP_PD_DOMAIN_RTC_FAST_MEM, //!< RTC fast memory + ESP_PD_DOMAIN_MAX //!< Number of domains +} esp_deep_sleep_pd_domain_t; + +/** + * @brief Power down options + */ +typedef enum { + ESP_PD_OPTION_OFF, //!< Power down the power domain in deep sleep + ESP_PD_OPTION_ON, //!< Keep power domain enabled during deep sleep + ESP_PD_OPTION_AUTO //!< Keep power domain enabled in deep sleep, if it is needed by one of the wakeup options. Otherwise power it down. +} esp_deep_sleep_pd_option_t; + + +/** + * @brief Enable wakeup by ULP coprocessor + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_STATE if ULP co-processor is not enabled. + */ +esp_err_t esp_deep_sleep_enable_ulp_wakeup(); + +/** + * @brief Enable wakeup by timer + * @param time_in_us time before wakeup, in microseconds + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if value is out of range (TBD) + */ +esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us); + +/** + * @brief Enable wakeup using a pin + * + * This function uses external wakeup feature of RTC_IO peripheral. + * It will work only if RTC peripherals are kept on during deep sleep. + * + * This feature can monitor any pin which is an RTC IO. Once the pin transitions + * into the state given by level argument, the chip will be woken up. + * + * @note This function does not modify pin configuration. The pin is + * configured in esp_deep_sleep_start, immediately before + * entering deep sleep. + * + * @param gpio_num GPIO number used as wakeup source. Only GPIOs which are have RTC + * functionality can be used: 0,2,4,12-15,25-27,32-39. + * @param level input level which will trigger wakeup (0=low, 1=high) + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if the selected GPIO is not an RTC GPIO, + * or the mode is invalid + */ +esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level); + +/** + * @brief Enable wakeup using multiple pins + * + * This function uses external wakeup feature of RTC controller. + * It will work even if RTC peripherals are shut down during deep sleep. + * + * This feature can monitor any number of pins which are in RTC IOs. + * Once any of the selected pins goes into the state given by mode argument, + * the chip will be woken up. + * + * @note This function does not modify pin configuration. The pins are + * configured in esp_deep_sleep_start, immediately before + * entering deep sleep. + * + * @note internal pullups and pulldowns don't work when RTC peripherals are + * shut down. In this case, external resistors need to be added. + * Alternatively, RTC peripherals (and pullups/pulldowns) may be + * kept enabled using esp_deep_sleep_pd_config function. + * + * @param mask bit mask of GPIO numbers which will cause wakeup. Only GPIOs + * which are have RTC functionality can be used in this bit map: + * 0,2,4,12-15,25-27,32-39. + * @param mode select logic function used to determine wakeup condition: + * - ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low + * - ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO, + * or mode is invalid + */ +esp_err_t esp_deep_sleep_enable_ext1_wakeup(uint64_t mask, esp_ext1_wakeup_mode_t mode); + + +/** + * @brief Get the bit mask of GPIOs which caused wakeup (ext1) + * + * If wakeup was caused by another source, this function will return 0. + * + * @return bit mask, if GPIOn caused wakeup, BIT(n) will be set + */ +uint64_t esp_deep_sleep_get_ext1_wakeup_status(); + +/** + * @brief Set power down mode for an RTC power domain in deep sleep + * + * If not set set using this API, all power domains default to ESP_PD_OPTION_AUTO. + * + * @param domain power domain to configure + * @param option power down option (ESP_PD_OPTION_OFF, ESP_PD_OPTION_ON, or ESP_PD_OPTION_AUTO) + * @return + * - ESP_OK on success + * - ESP_ERR_INVALID_ARG if either of the arguments is out of range + */ +esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain, + esp_deep_sleep_pd_option_t option); + +/** + * @brief Enter deep sleep with the configured wakeup options + * + * This function does not return. + */ +void esp_deep_sleep_start() __attribute__((noreturn)); + +/** + * @brief Enter deep-sleep mode + * + * The device will automatically wake up after the deep-sleep time + * Upon waking up, the device calls deep sleep wake stub, and then proceeds + * to load application. + * + * Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup + * followed by a call to esp_deep_sleep_start. + * + * This function does not return. + * + * @param time_in_us deep-sleep time, unit: microsecond + */ +void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn)); + +/** + * @brief Enter deep-sleep mode + * + * Function has been renamed to esp_deep_sleep. + * This name is deprecated and will be removed in a future version. + * + * @param time_in_us deep-sleep time, unit: microsecond + */ +void system_deep_sleep(uint64_t time_in_us) __attribute__((noreturn, deprecated)); + +/** + * @brief Default stub to run on wake from deep sleep. + * + * Allows for executing code immediately on wake from sleep, before + * the software bootloader or ESP-IDF app has started up. + * + * This function is weak-linked, so you can implement your own version + * to run code immediately when the chip wakes from + * sleep. + * + * See docs/deep-sleep-stub.rst for details. + */ +void esp_wake_deep_sleep(void); + +/** + * @brief Function type for stub to run on wake from sleep. + * + */ +typedef void (*esp_deep_sleep_wake_stub_fn_t)(void); + +/** + * @brief Install a new stub at runtime to run on wake from deep sleep + * + * If implementing esp_wake_deep_sleep() then it is not necessary to + * call this function. + * + * However, it is possible to call this function to substitute a + * different deep sleep stub. Any function used as a deep sleep stub + * must be marked RTC_IRAM_ATTR, and must obey the same rules given + * for esp_wake_deep_sleep(). + */ +void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub); + +/** + * @brief Get current wake from deep sleep stub + * @return Return current wake from deep sleep stub, or NULL if + * no stub is installed. + */ +esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void); + +/** + * @brief The default esp-idf-provided esp_wake_deep_sleep() stub. + * + * See docs/deep-sleep-stub.rst for details. + */ +void esp_default_wake_deep_sleep(void); + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp32/include/esp_deepsleep.h b/components/esp32/include/esp_deepsleep.h index 051ad14c3c..fe5364996a 100644 --- a/components/esp32/include/esp_deepsleep.h +++ b/components/esp32/include/esp_deepsleep.h @@ -1,114 +1,2 @@ -// 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_DEEPSLEEP_H__ -#define __ESP_DEEPSLEEP_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** \defgroup Deep_Sleep_API Deep Sleep API - * @brief API for putting device into deep sleep - */ - -/** @addtogroup Deep_Sleep_API - * @{ - */ - -/** - * @brief Enter deep-sleep mode - * - * The device will automatically wake up after the deep-sleep time - * Upon waking up, the device calls deep sleep wake stub, and then proceeds - * to load application. - * - * This function does not return. - * - * @param time_in_us deep-sleep time, unit: microsecond - */ -void esp_deep_sleep(uint64_t time_in_us) __attribute__((noreturn)); - - -/** - * @brief Enter deep-sleep mode - * - * Function has been renamed to esp_deep_sleep. - * This name is deprecated and will be removed in a future version. - * - * @param time_in_us deep-sleep time, unit: microsecond - */ -void system_deep_sleep(uint64_t time_in_us) __attribute__((noreturn, deprecated)); - -/** - * @brief Default stub to run on wake from deep sleep. - * - * Allows for executing code immediately on wake from sleep, before - * the software bootloader or ESP-IDF app has started up. - * - * This function is weak-linked, so you can implement your own version - * to run code immediately when the chip wakes from - * sleep. - * - * See docs/deep-sleep-stub.rst for details. - */ -void esp_wake_deep_sleep(void); - -/** - * @brief Function type for stub to run on wake from sleep. - * - */ -typedef void (*esp_deep_sleep_wake_stub_fn_t)(void); - -/** - * @brief Install a new stub at runtime to run on wake from deep sleep - * - * If implementing esp_wake_deep_sleep() then it is not necessary to - * call this function. - * - * However, it is possible to call this function to substitute a - * different deep sleep stub. Any function used as a deep sleep stub - * must be marked RTC_IRAM_ATTR, and must obey the same rules given - * for esp_wake_deep_sleep(). - */ -void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub); - -/** - * @brief Return current wake from deep sleep stub, or NULL if - * no stub is installed. - */ -esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void); - -/* The default esp-idf-provided esp_wake_deep_sleep() stub. - - See docs/deep-sleep-stub.rst for details. -*/ -void esp_default_wake_deep_sleep(void); - -/** - * @} - */ - - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __ESP_SYSTEM_H__ */ +#warning esp_deepsleep.h has been renamed to esp_deep_sleep.h, please update include directives +#include "esp_deep_sleep.h" diff --git a/components/esp32/include/esp_flash_data_types.h b/components/esp32/include/esp_flash_data_types.h index 783f2c59bb..cb6dfc3a1f 100644 --- a/components/esp32/include/esp_flash_data_types.h +++ b/components/esp32/include/esp_flash_data_types.h @@ -47,9 +47,24 @@ typedef struct { uint8_t subtype; esp_partition_pos_t pos; uint8_t label[16]; - uint8_t reserved[4]; + uint32_t flags; } esp_partition_info_t; +#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 PART_FLAG_ENCRYPTED (1<<0) #ifdef __cplusplus } diff --git a/components/esp32/include/esp_heap_alloc_caps.h b/components/esp32/include/esp_heap_alloc_caps.h index d371ca5ed8..21c24de6bf 100644 --- a/components/esp32/include/esp_heap_alloc_caps.h +++ b/components/esp32/include/esp_heap_alloc_caps.h @@ -14,21 +14,65 @@ #ifndef HEAP_ALLOC_CAPS_H #define HEAP_ALLOC_CAPS_H -#define MALLOC_CAP_EXEC (1<<0) //Memory must be able to run executable code -#define MALLOC_CAP_32BIT (1<<1) //Memory must allow for aligned 32-bit data accesses -#define MALLOC_CAP_8BIT (1<<2) //Memory must allow for 8/16/...-bit data accesses -#define MALLOC_CAP_DMA (1<<3) //Memory must be able to accessed by DMA -#define MALLOC_CAP_PID2 (1<<4) //Memory must be mapped to PID2 memory space -#define MALLOC_CAP_PID3 (1<<5) //Memory must be mapped to PID3 memory space -#define MALLOC_CAP_PID4 (1<<6) //Memory must be mapped to PID4 memory space -#define MALLOC_CAP_PID5 (1<<7) //Memory must be mapped to PID5 memory space -#define MALLOC_CAP_PID6 (1<<8) //Memory must be mapped to PID6 memory space -#define MALLOC_CAP_PID7 (1<<9) //Memory must be mapped to PID7 memory space -#define MALLOC_CAP_SPISRAM (1<<10) //Memory must be in SPI SRAM -#define MALLOC_CAP_INVALID (1<<31) //Memory can't be used / list end marker +/** + * @brief Flags to indicate the capabilities of the various memory systems + */ +#define MALLOC_CAP_EXEC (1<<0) ///< Memory must be able to run executable code +#define MALLOC_CAP_32BIT (1<<1) ///< Memory must allow for aligned 32-bit data accesses +#define MALLOC_CAP_8BIT (1<<2) ///< Memory must allow for 8/16/...-bit data accesses +#define MALLOC_CAP_DMA (1<<3) ///< Memory must be able to accessed by DMA +#define MALLOC_CAP_PID2 (1<<4) ///< Memory must be mapped to PID2 memory space +#define MALLOC_CAP_PID3 (1<<5) ///< Memory must be mapped to PID3 memory space +#define MALLOC_CAP_PID4 (1<<6) ///< Memory must be mapped to PID4 memory space +#define MALLOC_CAP_PID5 (1<<7) ///< Memory must be mapped to PID5 memory space +#define MALLOC_CAP_PID6 (1<<8) ///< Memory must be mapped to PID6 memory space +#define MALLOC_CAP_PID7 (1<<9) ///< Memory must be mapped to PID7 memory space +#define MALLOC_CAP_SPISRAM (1<<10) ///< Memory must be in SPI SRAM +#define MALLOC_CAP_INVALID (1<<31) ///< Memory can't be used / list end marker +/** + * @brief Initialize the capability-aware heap allocator. + * + * For the ESP32, this is called once in the startup code. + */ void heap_alloc_caps_init(); + +/** + * @brief Allocate a chunk of memory which has the given capabilities + * + * @param xWantedSize Size, in bytes, of the amount of memory to allocate + * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type + * of memory to be returned + * + * @return A pointer to the memory allocated on success, NULL on failure + */ void *pvPortMallocCaps(size_t xWantedSize, uint32_t caps); +/** + * @brief Get the total free size of all the regions that have the given capabilities + * + * This function takes all regions capable of having the given capabilities allocated in them + * and adds up the free space they have. + * + * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type + * of memory + * + * @return Amount of free bytes in the regions + */ +size_t xPortGetFreeHeapSizeCaps( uint32_t caps ); + +/** + * @brief Get the total minimum free memory of all regions with the given capabilities + * + * This adds all the lowmarks of the regions capable of delivering the memory with the + * given capabilities + * + * @param caps Bitwise OR of MALLOC_CAP_* flags indicating the type + * of memory + * + * @return Amount of free bytes in the regions + */ +size_t xPortGetMinimumEverFreeHeapSizeCaps( uint32_t caps ); + #endif \ No newline at end of file diff --git a/components/esp32/include/esp_intr_alloc.h b/components/esp32/include/esp_intr_alloc.h new file mode 100644 index 0000000000..c1f91dd2e3 --- /dev/null +++ b/components/esp32/include/esp_intr_alloc.h @@ -0,0 +1,267 @@ +// 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_INTR_ALLOC_H__ +#define __ESP_INTR_ALLOC_H__ + +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @addtogroup Intr_Alloc + * @{ + */ + + +/** @brief Interrupt allocation flags + * + * These flags can be used to specify which interrupt qualities the + * code calling esp_intr_alloc* needs. + * + */ + +//Keep the LEVELx values as they are here; they match up with (1<3 + * is requested, because these types of interrupts aren't C-callable. + * @param arg Optional argument for passed to the interrupt handler + * @param ret_handle Pointer to an intr_handle_t to store a handle that can later be + * used to request details or free the interrupt. Can be NULL if no handle + * is required. + * + * @return ESP_ERR_INVALID_ARG if the combination of arguments is invalid. + * ESP_ERR_NOT_FOUND No free interrupt found with the specified flags + * ESP_OK otherwise + */ +esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *arg, intr_handle_t *ret_handle); + + +/** + * @brief Allocate an interrupt with the given parameters. + * + * + * This essentially does the same as esp_intr_alloc, but allows specifying a register and mask + * combo. For shared interrupts, the handler is only called if a read from the specified + * register, ANDed with the mask, returns non-zero. By passing an interrupt status register + * address and a fitting mask, this can be used to accelerate interrupt handling in the case + * a shared interrupt is triggered; by checking the interrupt statuses first, the code can + * decide which ISRs can be skipped + * + * @param source The interrupt source. One of the ETS_*_INTR_SOURCE interrupt mux + * sources, as defined in soc/soc.h, or one of the internal + * ETS_INTERNAL_*_INTR_SOURCE sources as defined in this header. + * @param flags An ORred mask of the ESP_INTR_FLAG_* defines. These restrict the + * choice of interrupts that this routine can choose from. If this value + * is 0, it will default to allocating a non-shared interrupt of level + * 1, 2 or 3. If this is ESP_INTR_FLAG_SHARED, it will allocate a shared + * interrupt of level 1. Setting ESP_INTR_FLAG_INTRDISABLED will return + * from this function with the interrupt disabled. + * @param intrstatusreg The address of an interrupt status register + * @param intrstatusmask A mask. If a read of address intrstatusreg has any of the bits + * that are 1 in the mask set, the ISR will be called. If not, it will be + * skipped. + * @param handler The interrupt handler. Must be NULL when an interrupt of level >3 + * is requested, because these types of interrupts aren't C-callable. + * @param arg Optional argument for passed to the interrupt handler + * @param ret_handle Pointer to an intr_handle_t to store a handle that can later be + * used to request details or free the interrupt. Can be NULL if no handle + * is required. + * + * @return ESP_ERR_INVALID_ARG if the combination of arguments is invalid. + * ESP_ERR_NOT_FOUND No free interrupt found with the specified flags + * ESP_OK otherwise + */ +esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusreg, uint32_t intrstatusmask, intr_handler_t handler, void *arg, intr_handle_t *ret_handle); + + +/** + * @brief Disable and free an interrupt. + * + * Use an interrupt handle to disable the interrupt and release the resources + * associated with it. + * + * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus + * + * @return ESP_ERR_INVALID_ARG if handle is invalid, or esp_intr_free runs on another core than + * where the interrupt is allocated on. + * ESP_OK otherwise + */ +esp_err_t esp_intr_free(intr_handle_t handle); + + +/** + * @brief Get CPU number an interrupt is tied to + * + * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus + * + * @return The core number where the interrupt is allocated + */ +int esp_intr_get_cpu(intr_handle_t handle); + +/** + * @brief Get the allocated interrupt for a certain handle + * + * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus + * + * @return The interrupt number + */ +int esp_intr_get_intno(intr_handle_t handle); + + +/** + * @brief Disable the interrupt associated with the handle + * + * @note For local interrupts (ESP_INTERNAL_* sources), this function has to be called on the + * CPU the interrupt is allocated on. Other interrupts have no such restriction. + * + * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus + * + * @return ESP_ERR_INVALID_ARG if the combination of arguments is invalid. + * ESP_OK otherwise + */ +esp_err_t esp_intr_disable(intr_handle_t handle); + +/** + * @brief Ensable the interrupt associated with the handle + * + * @note For local interrupts (ESP_INTERNAL_* sources), this function has to be called on the + * CPU the interrupt is allocated on. Other interrupts have no such restriction. + * + * @param handle The handle, as obtained by esp_intr_alloc or esp_intr_alloc_intrstatus + * + * @return ESP_ERR_INVALID_ARG if the combination of arguments is invalid. + * ESP_OK otherwise + */ +esp_err_t esp_intr_enable(intr_handle_t handle); + + +/** + * @brief Disable interrupts that aren't specifically marked as running from IRAM + */ +void esp_intr_noniram_disable(); + + +/** + * @brief Re-enable interrupts disabled by esp_intr_noniram_disable + */ +void esp_intr_noniram_enable(); + +/**@}*/ + + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/components/esp32/include/esp_smartconfig.h b/components/esp32/include/esp_smartconfig.h index b30ce1a111..916c4c1706 100644 --- a/components/esp32/include/esp_smartconfig.h +++ b/components/esp32/include/esp_smartconfig.h @@ -3,7 +3,7 @@ // 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 @@ -11,10 +11,12 @@ // 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_SMARTCONFIG_H__ #define __ESP_SMARTCONFIG_H__ + #include -#include +#include #include "esp_err.h" #ifdef __cplusplus @@ -22,11 +24,11 @@ extern "C" { #endif typedef enum { - SC_STATUS_WAIT = 0, /**< waiting, do not start connection in this phase */ - SC_STATUS_FIND_CHANNEL, /**< find target channel, start connection by APP in this phase */ - SC_STATUS_GETTING_SSID_PSWD, /**< getting SSID and password of target AP */ - SC_STATUS_LINK, /**< connecting to target AP */ - SC_STATUS_LINK_OVER, /**< got IP, connect to AP successfully */ + SC_STATUS_WAIT = 0, /**< Waiting to start connect */ + SC_STATUS_FIND_CHANNEL, /**< Finding target channel */ + SC_STATUS_GETTING_SSID_PSWD, /**< Getting SSID and password of target AP */ + SC_STATUS_LINK, /**< Connecting to target AP */ + SC_STATUS_LINK_OVER, /**< Connected to AP successfully */ } smartconfig_status_t; typedef enum { @@ -38,48 +40,38 @@ typedef enum { /** * @brief The callback of SmartConfig, executed when smart-config status changed. * - * @param smartconfig_status_t status : status of SmartConfig: - * - if status == SC_STATUS_GETTING_SSID_PSWD, parameter void *pdata is a pointer - of smartconfig_type_t, means SmartConfig type: AirKiss or ESP-TOUCH. - * - if status == SC_STATUS_LINK, parameter void *pdata is a pointer of struct station_config; - * - if status == SC_STATUS_LINK_OVER, parameter void *pdata is a pointer of mobile - * phone's IP address, 4 bytes. This is only available in ESPTOUCH, otherwise, - * it is NULL. - * - otherwise, parameter void *pdata is NULL. - * @param void *pdata : data of SmartConfig + * @param status Status of SmartConfig: + * - SC_STATUS_GETTING_SSID_PSWD : pdata is a pointer of smartconfig_type_t, means config type. + * - SC_STATUS_LINK : pdata is a pointer of struct station_config. + * - SC_STATUS_LINK_OVER : pdata is a pointer of phone's IP address(4 bytes) if pdata unequal NULL. + * - otherwise : parameter void *pdata is NULL. + * @param pdata According to the different status have different values. * - * @return null */ typedef void (*sc_callback_t)(smartconfig_status_t status, void *pdata); /** * @brief Get the version of SmartConfig. * - * @param null - * - * @return SmartConfig version + * @return + * - SmartConfig version const char. */ const char *esp_smartconfig_get_version(void); /** - * @brief Start SmartConfig mode. + * @brief Start SmartConfig, config ESP device to connect AP. You need to broadcast information by phone APP. + * Device sniffer special packets from the air that containing SSID and password of target AP. * - * Start SmartConfig mode, to connect ESP32 station to AP, by sniffing - * for special packets from the air, containing SSID and password of desired AP. - * You need to broadcast the SSID and password (e.g. from mobile device or computer) - * with the SSID and password encoded. - * - * @attention 1. This API can only be called in station mode. - * @attention 2. During SmartConfig, ESP32 station and soft-AP are disabled. - * @attention 3. Can not call esp_smartconfig_start twice before it finish, please call + * @attention 1. This API can be called in station or softAP-station mode. + * @attention 2. Can not call esp_smartconfig_start twice before it finish, please call * esp_smartconfig_stop first. - * @attention 4. Don't call any other APIs during SmartConfig, please call esp_smartconfig_stop first. * - * @param sc_callback_t cb : SmartConfig callback; executed when SmartConfig status changed; - * @param uint8 log : 1, UART output logs; otherwise, UART only outputs the result. + * @param cb SmartConfig callback function. + * @param ... log 1: UART output logs; 0: UART only outputs the result. * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK: succeed + * - others: fail */ esp_err_t esp_smartconfig_start(sc_callback_t cb, ...); @@ -89,23 +81,22 @@ esp_err_t esp_smartconfig_start(sc_callback_t cb, ...); * @attention Whether connect to AP succeed or not, this API should be called to free * memory taken by smartconfig_start. * - * @param null - * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK: succeed + * - others: fail */ esp_err_t esp_smartconfig_stop(void); /** - * @brief Set timeout of SmartConfig. + * @brief Set timeout of SmartConfig process. * - * @attention SmartConfig timeout start at SC_STATUS_FIND_CHANNEL, SmartConfig will - * restart if timeout. + * @attention Timing starts from SC_STATUS_FIND_CHANNEL status. SmartConfig will restart if timeout. * - * @param uint8 time_s : range 15s~255s, offset:45s. + * @param time_s range 15s~255s, offset:45s. * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK: succeed + * - others: fail */ esp_err_t esp_esptouch_set_timeout(uint8_t time_s); @@ -115,27 +106,29 @@ esp_err_t esp_esptouch_set_timeout(uint8_t time_s); * @attention If users need to set the SmartConfig type, please set it before calling * esp_smartconfig_start. * - * @param smartconfig_type_t type : AirKiss, ESP-TOUCH or both. + * @param type Choose from the smartconfig_type_t. * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK: succeed + * - others: fail */ esp_err_t esp_smartconfig_set_type(smartconfig_type_t type); /** * @brief Set mode of SmartConfig. default normal mode. * - * @attention If users need to set the SmartConfig mode, please set it before calling - * esp_smartconfig_start. Different mode should match different APP(phone). + * @attention 1. Please call it before API esp_smartconfig_start. + * @attention 2. Fast mode have corresponding APP(phone). + * @attention 3. Two mode is compatible. * - * @param bool enable : false-disable(default); true-enable; + * @param enable false-disable(default); true-enable; * - * @return ESP_OK : succeed - * @return others : fail + * @return + * - ESP_OK: succeed + * - others: fail */ esp_err_t esp_smartconfig_fast_mode(bool enable); - #ifdef __cplusplus } #endif diff --git a/components/esp32/include/esp_system.h b/components/esp32/include/esp_system.h index 40ebd8403c..e1f46de803 100644 --- a/components/esp32/include/esp_system.h +++ b/components/esp32/include/esp_system.h @@ -18,7 +18,7 @@ #include #include #include "esp_err.h" -#include "esp_deepsleep.h" +#include "esp_deep_sleep.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h old mode 100644 new mode 100755 index 00e9ec1d6e..68d06aae52 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -507,16 +507,14 @@ esp_err_t esp_wifi_set_mac(wifi_interface_t ifx, uint8_t mac[6]); esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]); /** - * @brief The RX callback function in the promiscuous mode. + * @brief The RX callback function in the promiscuous mode. + * Each time a packet is received, the callback function will be called. * - * Each time a packet is received, the callback function will be called. + * @param buf Data received. Type of data in buffer (wifi_promiscuous_pkt_t or wifi_pkt_rx_ctrl_t) indicated by 'type' parameter. + * @param type promiscuous packet type. * - * @param buf the data received - * @param len data length - * - * @return none */ -typedef void (* wifi_promiscuous_cb_t)(void *buf, uint16_t len); +typedef void (* wifi_promiscuous_cb_t)(void *buf, wifi_promiscuous_pkt_type_t type); /** * @brief Register the RX callback function in the promiscuous mode. diff --git a/components/esp32/include/esp_wifi_types.h b/components/esp32/include/esp_wifi_types.h old mode 100644 new mode 100755 index c5dd021fe7..583d7a6a91 --- a/components/esp32/include/esp_wifi_types.h +++ b/components/esp32/include/esp_wifi_types.h @@ -150,13 +150,14 @@ typedef union { typedef struct { uint8_t mac[6]; /**< mac address of sta that associated with ESP32 soft-AP */ -}wifi_sta_info_t; +} wifi_sta_info_t; #define ESP_WIFI_MAX_CONN_NUM (10) /**< max number of stations which can connect to ESP32 soft-AP */ + typedef struct { wifi_sta_info_t sta[ESP_WIFI_MAX_CONN_NUM]; /**< station list */ int num; /**< number of station that associated with ESP32 soft-AP */ -}wifi_sta_list_t; +} wifi_sta_list_t; typedef enum { WIFI_STORAGE_FLASH, /**< all configuration will strore in both memory and flash */ @@ -184,10 +185,52 @@ typedef enum { WIFI_VND_IE_ID_1, } wifi_vendor_ie_id_t; +typedef struct { + signed rssi:8; /**< signal intensity of packet */ + unsigned rate:5; /**< data rate */ + unsigned :1; /**< reserve */ + unsigned sig_mode:2; /**< 0:is not 11n packet; 1:is 11n packet */ + unsigned :16; /**< reserve */ + unsigned mcs:7; /**< if is 11n packet, shows the modulation(range from 0 to 76) */ + unsigned cwb:1; /**< if is 11n packet, shows if is HT40 packet or not */ + unsigned :16; /**< reserve */ + unsigned smoothing:1; /**< reserve */ + unsigned not_sounding:1; /**< reserve */ + unsigned :1; /**< reserve */ + unsigned aggregation:1; /**< Aggregation */ + unsigned stbc:2; /**< STBC */ + unsigned fec_coding:1; /**< if is 11n packet, shows if is LDPC packet or not */ + unsigned sgi:1; /**< SGI */ + unsigned noise_floor:8; /**< noise floor */ + unsigned ampdu_cnt:8; /**< ampdu cnt */ + unsigned channel:4; /**< which channel this packet in */ + unsigned :12; /**< reserve */ + unsigned timestamp:32; /**< timestamp */ + unsigned :32; /**< reserve */ + unsigned :32; /**< reserve */ + unsigned sig_len:12; /**< It is really lenth of packet */ + unsigned :12; /**< reserve */ + unsigned rx_state:8; /**< rx state */ +} wifi_pkt_rx_ctrl_t; + +typedef struct { + wifi_pkt_rx_ctrl_t rx_ctrl; + char payload[0]; /**< ieee80211 packet buff, The length of payload is described by sig_len */ +} wifi_promiscuous_pkt_t; + +/** + * @brief Promiscuous frame type + * + */ +typedef enum { + WIFI_PKT_CTRL, /**< control type, receive packet buf is wifi_pkt_rx_ctrl_t */ + WIFI_PKT_MGMT, /**< management type, receive packet buf is wifi_promiscuous_pkt_t */ + WIFI_PKT_DATA, /**< data type, receive packet buf is wifi_promiscuous_pkt_t */ + WIFI_PKT_MISC, /**< other type, receive packet buf is wifi_promiscuous_pkt_t */ +} wifi_promiscuous_pkt_type_t; #ifdef __cplusplus } #endif - #endif /* __ESP_WIFI_TYPES_H__ */ diff --git a/components/esp32/include/rom/spi_flash.h b/components/esp32/include/rom/spi_flash.h index 32f018477a..44098475d6 100644 --- a/components/esp32/include/rom/spi_flash.h +++ b/components/esp32/include/rom/spi_flash.h @@ -3,7 +3,7 @@ // 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 @@ -384,8 +384,8 @@ SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t blo SpiFlashOpResult SPIEraseChip(void); /** - * @brief Erase a 32KB block of flash - * Uses SPI flash command 52h. + * @brief Erase a 64KB block of flash + * Uses SPI flash command D8H. * Please do not call this function in SDK. * * @param uint32_t block_num : Which block to erase. @@ -398,6 +398,7 @@ SpiFlashOpResult SPIEraseBlock(uint32_t block_num); /** * @brief Erase a sector of flash. + * Uses SPI flash command 20H. * Please do not call this function in SDK. * * @param uint32_t sector_num : Which sector to erase. @@ -412,12 +413,6 @@ SpiFlashOpResult SPIEraseSector(uint32_t sector_num); * @brief Erase some sectors. * Please do not call this function in SDK. * - * @note If calling this function, first set - * g_rom_flashchip.block_size = 32768; or call SPIParamCfg() - * with appropriate parameters. This is due to a ROM bug, the - * block erase command in use is a 32KB erase but after reset - * the block_size field is incorrectly set to 65536. - * * @param uint32_t start_addr : Start addr to erase, should be sector aligned. * * @param uint32_t area_len : Length to erase, should be sector aligned. @@ -495,16 +490,20 @@ SpiFlashOpResult SPI_Prepare_Encrypt_Data(uint32_t flash_addr, uint32_t *data); void SPI_Write_Encrypt_Disable(void); /** - * @brief Encrpto writing data to flash, you should Erase it yourself if need. - * Please do not call this function in SDK. + * @brief Write data to flash with transparent encryption. + * @note Sectors to be written should already be erased. * - * @param uint32_t flash_addr : Address to write, should be 32 bytes aligned. + * @note Please do not call this function in SDK. * - * @param uint32_t *data : The pointer to data which is to write. + * @param uint32_t flash_addr : Address to write, should be 32 byte aligned. + * + * @param uint32_t *data : The pointer to data to write. Note, this pointer must + * be 32 bit aligned and the content of the data will be + * modified by the encryption function. * * @param uint32_t len : Length to write, should be 32 bytes aligned. * - * @return SPI_FLASH_RESULT_OK : Encrypto write OK. + * @return SPI_FLASH_RESULT_OK : Data written successfully. * SPI_FLASH_RESULT_ERR : Encrypto write error. * SPI_FLASH_RESULT_TIMEOUT : Encrypto write timeout. */ diff --git a/components/esp32/include/rom/uart.h b/components/esp32/include/rom/uart.h index aa3cf59217..81fa26c238 100644 --- a/components/esp32/include/rom/uart.h +++ b/components/esp32/include/rom/uart.h @@ -18,6 +18,8 @@ #include "esp_types.h" #include "esp_attr.h" #include "ets_sys.h" +#include "soc/soc.h" +#include "soc/uart_reg.h" #ifdef __cplusplus extern "C" { @@ -260,11 +262,16 @@ void uart_tx_flush(uint8_t uart_no); /** * @brief Wait until uart tx full empty and the last char send ok. * - * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * @param uart_no : 0 for UART0, 1 for UART1, 2 for UART2 * - * @return None. + * The function defined in ROM code has a bug, so we define the correct version + * here for compatibility. */ -void uart_tx_wait_idle(uint8_t uart_no); +static inline void uart_tx_wait_idle(uint8_t uart_no) { + while(REG_GET_FIELD(UART_STATUS_REG(uart_no), UART_ST_UTX_OUT)) { + ; + } +} /** * @brief Get an input char from message channel. diff --git a/components/esp32/include/soc/cpu.h b/components/esp32/include/soc/cpu.h index 4457c81a22..aa471a1739 100644 --- a/components/esp32/include/soc/cpu.h +++ b/components/esp32/include/soc/cpu.h @@ -26,6 +26,16 @@ #define WSR(reg, newval) asm volatile ("wsr %0, " #reg : : "r" (newval)); #define XSR(reg, swapval) asm volatile ("xsr %0, " #reg : "+r" (swapval)); +/** @brief Read current stack pointer address + * + */ +static inline void *get_sp() +{ + void *sp; + asm volatile ("mov %0, sp;" : "=r" (sp)); + return sp; +} + /* Return true if the CPU is in an interrupt context (PS.UM == 0) */ diff --git a/components/esp32/include/soc/gpio_sig_map.h b/components/esp32/include/soc/gpio_sig_map.h index dad22f92f8..4d2943fb9f 100644 --- a/components/esp32/include/soc/gpio_sig_map.h +++ b/components/esp32/include/soc/gpio_sig_map.h @@ -418,5 +418,5 @@ #define SIG_IN_FUNC226_IDX 226 #define SIG_IN_FUNC227_IDX 227 #define SIG_IN_FUNC228_IDX 228 - +#define SIG_GPIO_OUT_IDX 256 #endif /* _SOC_GPIO_SIG_MAP_H_ */ diff --git a/components/esp32/include/soc/rtc_io_reg.h b/components/esp32/include/soc/rtc_io_reg.h index 086e8b7674..345bb8045c 100644 --- a/components/esp32/include/soc/rtc_io_reg.h +++ b/components/esp32/include/soc/rtc_io_reg.h @@ -1,1951 +1,1951 @@ -// 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 _SOC_RTC_IO_REG_H_ -#define _SOC_RTC_IO_REG_H_ - - -#include "soc.h" -#define RTC_GPIO_OUT_REG (DR_REG_RTCIO_BASE + 0x0) -/* RTC_GPIO_OUT_DATA : R/W ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 output value*/ -#define RTC_GPIO_OUT_DATA 0x0003FFFF -#define RTC_GPIO_OUT_DATA_M ((RTC_GPIO_OUT_DATA_V)<<(RTC_GPIO_OUT_DATA_S)) -#define RTC_GPIO_OUT_DATA_V 0x3FFFF -#define RTC_GPIO_OUT_DATA_S 14 - -#define RTC_GPIO_OUT_W1TS_REG (DR_REG_RTCIO_BASE + 0x4) -/* RTC_GPIO_OUT_DATA_W1TS : WO ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 output value write 1 to set*/ -#define RTC_GPIO_OUT_DATA_W1TS 0x0003FFFF -#define RTC_GPIO_OUT_DATA_W1TS_M ((RTC_GPIO_OUT_DATA_W1TS_V)<<(RTC_GPIO_OUT_DATA_W1TS_S)) -#define RTC_GPIO_OUT_DATA_W1TS_V 0x3FFFF -#define RTC_GPIO_OUT_DATA_W1TS_S 14 - -#define RTC_GPIO_OUT_W1TC_REG (DR_REG_RTCIO_BASE + 0x8) -/* RTC_GPIO_OUT_DATA_W1TC : WO ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 output value write 1 to clear*/ -#define RTC_GPIO_OUT_DATA_W1TC 0x0003FFFF -#define RTC_GPIO_OUT_DATA_W1TC_M ((RTC_GPIO_OUT_DATA_W1TC_V)<<(RTC_GPIO_OUT_DATA_W1TC_S)) -#define RTC_GPIO_OUT_DATA_W1TC_V 0x3FFFF -#define RTC_GPIO_OUT_DATA_W1TC_S 14 - -#define RTC_GPIO_ENABLE_REG (DR_REG_RTCIO_BASE + 0xc) -/* RTC_GPIO_ENABLE : R/W ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 output enable*/ -#define RTC_GPIO_ENABLE 0x0003FFFF -#define RTC_GPIO_ENABLE_M ((RTC_GPIO_ENABLE_V)<<(RTC_GPIO_ENABLE_S)) -#define RTC_GPIO_ENABLE_V 0x3FFFF -#define RTC_GPIO_ENABLE_S 14 - -#define RTC_GPIO_ENABLE_W1TS_REG (DR_REG_RTCIO_BASE + 0x10) -/* RTC_GPIO_ENABLE_W1TS : WO ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 output enable write 1 to set*/ -#define RTC_GPIO_ENABLE_W1TS 0x0003FFFF -#define RTC_GPIO_ENABLE_W1TS_M ((RTC_GPIO_ENABLE_W1TS_V)<<(RTC_GPIO_ENABLE_W1TS_S)) -#define RTC_GPIO_ENABLE_W1TS_V 0x3FFFF -#define RTC_GPIO_ENABLE_W1TS_S 14 - -#define RTC_GPIO_ENABLE_W1TC_REG (DR_REG_RTCIO_BASE + 0x14) -/* RTC_GPIO_ENABLE_W1TC : WO ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 output enable write 1 to clear*/ -#define RTC_GPIO_ENABLE_W1TC 0x0003FFFF -#define RTC_GPIO_ENABLE_W1TC_M ((RTC_GPIO_ENABLE_W1TC_V)<<(RTC_GPIO_ENABLE_W1TC_S)) -#define RTC_GPIO_ENABLE_W1TC_V 0x3FFFF -#define RTC_GPIO_ENABLE_W1TC_S 14 - -#define RTC_GPIO_STATUS_REG (DR_REG_RTCIO_BASE + 0x18) -/* RTC_GPIO_STATUS_INT : R/W ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 interrupt status*/ -#define RTC_GPIO_STATUS_INT 0x0003FFFF -#define RTC_GPIO_STATUS_INT_M ((RTC_GPIO_STATUS_INT_V)<<(RTC_GPIO_STATUS_INT_S)) -#define RTC_GPIO_STATUS_INT_V 0x3FFFF -#define RTC_GPIO_STATUS_INT_S 14 - -#define RTC_GPIO_STATUS_W1TS_REG (DR_REG_RTCIO_BASE + 0x1c) -/* RTC_GPIO_STATUS_INT_W1TS : WO ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 interrupt status write 1 to set*/ -#define RTC_GPIO_STATUS_INT_W1TS 0x0003FFFF -#define RTC_GPIO_STATUS_INT_W1TS_M ((RTC_GPIO_STATUS_INT_W1TS_V)<<(RTC_GPIO_STATUS_INT_W1TS_S)) -#define RTC_GPIO_STATUS_INT_W1TS_V 0x3FFFF -#define RTC_GPIO_STATUS_INT_W1TS_S 14 - -#define RTC_GPIO_STATUS_W1TC_REG (DR_REG_RTCIO_BASE + 0x20) -/* RTC_GPIO_STATUS_INT_W1TC : WO ;bitpos:[31:14] ;default: 0 ; */ -/*description: GPIO0~17 interrupt status write 1 to clear*/ -#define RTC_GPIO_STATUS_INT_W1TC 0x0003FFFF -#define RTC_GPIO_STATUS_INT_W1TC_M ((RTC_GPIO_STATUS_INT_W1TC_V)<<(RTC_GPIO_STATUS_INT_W1TC_S)) -#define RTC_GPIO_STATUS_INT_W1TC_V 0x3FFFF -#define RTC_GPIO_STATUS_INT_W1TC_S 14 - -#define RTC_GPIO_IN_REG (DR_REG_RTCIO_BASE + 0x24) -/* RTC_GPIO_IN_NEXT : RO ;bitpos:[31:14] ;default: ; */ -/*description: GPIO0~17 input value*/ -#define RTC_GPIO_IN_NEXT 0x0003FFFF -#define RTC_GPIO_IN_NEXT_M ((RTC_GPIO_IN_NEXT_V)<<(RTC_GPIO_IN_NEXT_S)) -#define RTC_GPIO_IN_NEXT_V 0x3FFFF -#define RTC_GPIO_IN_NEXT_S 14 - -#define RTC_GPIO_PIN0_REG (DR_REG_RTCIO_BASE + 0x28) -/* RTC_GPIO_PIN0_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN0_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN0_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN0_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN0_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN0_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN0_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN0_INT_TYPE_M ((RTC_GPIO_PIN0_INT_TYPE_V)<<(RTC_GPIO_PIN0_INT_TYPE_S)) -#define RTC_GPIO_PIN0_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN0_INT_TYPE_S 7 -/* RTC_GPIO_PIN0_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN0_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN0_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN0_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN0_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN1_REG (DR_REG_RTCIO_BASE + 0x2c) -/* RTC_GPIO_PIN1_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN1_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN1_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN1_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN1_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN1_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN1_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN1_INT_TYPE_M ((RTC_GPIO_PIN1_INT_TYPE_V)<<(RTC_GPIO_PIN1_INT_TYPE_S)) -#define RTC_GPIO_PIN1_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN1_INT_TYPE_S 7 -/* RTC_GPIO_PIN1_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN1_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN1_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN1_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN1_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN2_REG (DR_REG_RTCIO_BASE + 0x30) -/* RTC_GPIO_PIN2_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN2_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN2_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN2_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN2_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN2_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN2_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN2_INT_TYPE_M ((RTC_GPIO_PIN2_INT_TYPE_V)<<(RTC_GPIO_PIN2_INT_TYPE_S)) -#define RTC_GPIO_PIN2_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN2_INT_TYPE_S 7 -/* RTC_GPIO_PIN2_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN2_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN2_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN2_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN2_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN3_REG (DR_REG_RTCIO_BASE + 0x34) -/* RTC_GPIO_PIN3_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN3_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN3_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN3_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN3_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN3_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN3_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN3_INT_TYPE_M ((RTC_GPIO_PIN3_INT_TYPE_V)<<(RTC_GPIO_PIN3_INT_TYPE_S)) -#define RTC_GPIO_PIN3_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN3_INT_TYPE_S 7 -/* RTC_GPIO_PIN3_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN3_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN3_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN3_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN3_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN4_REG (DR_REG_RTCIO_BASE + 0x38) -/* RTC_GPIO_PIN4_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN4_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN4_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN4_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN4_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN4_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN4_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN4_INT_TYPE_M ((RTC_GPIO_PIN4_INT_TYPE_V)<<(RTC_GPIO_PIN4_INT_TYPE_S)) -#define RTC_GPIO_PIN4_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN4_INT_TYPE_S 7 -/* RTC_GPIO_PIN4_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN4_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN4_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN4_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN4_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN5_REG (DR_REG_RTCIO_BASE + 0x3c) -/* RTC_GPIO_PIN5_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN5_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN5_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN5_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN5_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN5_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN5_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN5_INT_TYPE_M ((RTC_GPIO_PIN5_INT_TYPE_V)<<(RTC_GPIO_PIN5_INT_TYPE_S)) -#define RTC_GPIO_PIN5_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN5_INT_TYPE_S 7 -/* RTC_GPIO_PIN5_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN5_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN5_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN5_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN5_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN6_REG (DR_REG_RTCIO_BASE + 0x40) -/* RTC_GPIO_PIN6_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN6_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN6_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN6_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN6_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN6_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN6_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN6_INT_TYPE_M ((RTC_GPIO_PIN6_INT_TYPE_V)<<(RTC_GPIO_PIN6_INT_TYPE_S)) -#define RTC_GPIO_PIN6_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN6_INT_TYPE_S 7 -/* RTC_GPIO_PIN6_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN6_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN6_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN6_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN6_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN7_REG (DR_REG_RTCIO_BASE + 0x44) -/* RTC_GPIO_PIN7_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN7_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN7_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN7_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN7_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN7_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN7_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN7_INT_TYPE_M ((RTC_GPIO_PIN7_INT_TYPE_V)<<(RTC_GPIO_PIN7_INT_TYPE_S)) -#define RTC_GPIO_PIN7_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN7_INT_TYPE_S 7 -/* RTC_GPIO_PIN7_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN7_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN7_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN7_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN7_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN8_REG (DR_REG_RTCIO_BASE + 0x48) -/* RTC_GPIO_PIN8_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN8_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN8_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN8_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN8_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN8_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN8_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN8_INT_TYPE_M ((RTC_GPIO_PIN8_INT_TYPE_V)<<(RTC_GPIO_PIN8_INT_TYPE_S)) -#define RTC_GPIO_PIN8_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN8_INT_TYPE_S 7 -/* RTC_GPIO_PIN8_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN8_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN8_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN8_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN8_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN9_REG (DR_REG_RTCIO_BASE + 0x4c) -/* RTC_GPIO_PIN9_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN9_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN9_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN9_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN9_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN9_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN9_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN9_INT_TYPE_M ((RTC_GPIO_PIN9_INT_TYPE_V)<<(RTC_GPIO_PIN9_INT_TYPE_S)) -#define RTC_GPIO_PIN9_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN9_INT_TYPE_S 7 -/* RTC_GPIO_PIN9_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN9_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN9_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN9_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN9_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN10_REG (DR_REG_RTCIO_BASE + 0x50) -/* RTC_GPIO_PIN10_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN10_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN10_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN10_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN10_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN10_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN10_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN10_INT_TYPE_M ((RTC_GPIO_PIN10_INT_TYPE_V)<<(RTC_GPIO_PIN10_INT_TYPE_S)) -#define RTC_GPIO_PIN10_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN10_INT_TYPE_S 7 -/* RTC_GPIO_PIN10_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN10_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN10_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN10_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN10_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN11_REG (DR_REG_RTCIO_BASE + 0x54) -/* RTC_GPIO_PIN11_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN11_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN11_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN11_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN11_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN11_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN11_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN11_INT_TYPE_M ((RTC_GPIO_PIN11_INT_TYPE_V)<<(RTC_GPIO_PIN11_INT_TYPE_S)) -#define RTC_GPIO_PIN11_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN11_INT_TYPE_S 7 -/* RTC_GPIO_PIN11_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN11_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN11_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN11_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN11_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN12_REG (DR_REG_RTCIO_BASE + 0x58) -/* RTC_GPIO_PIN12_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN12_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN12_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN12_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN12_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN12_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN12_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN12_INT_TYPE_M ((RTC_GPIO_PIN12_INT_TYPE_V)<<(RTC_GPIO_PIN12_INT_TYPE_S)) -#define RTC_GPIO_PIN12_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN12_INT_TYPE_S 7 -/* RTC_GPIO_PIN12_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN12_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN12_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN12_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN12_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN13_REG (DR_REG_RTCIO_BASE + 0x5c) -/* RTC_GPIO_PIN13_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN13_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN13_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN13_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN13_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN13_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN13_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN13_INT_TYPE_M ((RTC_GPIO_PIN13_INT_TYPE_V)<<(RTC_GPIO_PIN13_INT_TYPE_S)) -#define RTC_GPIO_PIN13_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN13_INT_TYPE_S 7 -/* RTC_GPIO_PIN13_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN13_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN13_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN13_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN13_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN14_REG (DR_REG_RTCIO_BASE + 0x60) -/* RTC_GPIO_PIN14_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN14_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN14_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN14_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN14_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN14_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN14_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN14_INT_TYPE_M ((RTC_GPIO_PIN14_INT_TYPE_V)<<(RTC_GPIO_PIN14_INT_TYPE_S)) -#define RTC_GPIO_PIN14_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN14_INT_TYPE_S 7 -/* RTC_GPIO_PIN14_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN14_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN14_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN14_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN14_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN15_REG (DR_REG_RTCIO_BASE + 0x64) -/* RTC_GPIO_PIN15_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN15_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN15_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN15_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN15_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN15_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN15_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN15_INT_TYPE_M ((RTC_GPIO_PIN15_INT_TYPE_V)<<(RTC_GPIO_PIN15_INT_TYPE_S)) -#define RTC_GPIO_PIN15_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN15_INT_TYPE_S 7 -/* RTC_GPIO_PIN15_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN15_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN15_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN15_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN15_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN16_REG (DR_REG_RTCIO_BASE + 0x68) -/* RTC_GPIO_PIN16_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN16_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN16_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN16_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN16_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN16_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN16_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN16_INT_TYPE_M ((RTC_GPIO_PIN16_INT_TYPE_V)<<(RTC_GPIO_PIN16_INT_TYPE_S)) -#define RTC_GPIO_PIN16_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN16_INT_TYPE_S 7 -/* RTC_GPIO_PIN16_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN16_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN16_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN16_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN16_PAD_DRIVER_S 2 - -#define RTC_GPIO_PIN17_REG (DR_REG_RTCIO_BASE + 0x6c) -/* RTC_GPIO_PIN17_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ -/*description: GPIO wake up enable only available in light sleep*/ -#define RTC_GPIO_PIN17_WAKEUP_ENABLE (BIT(10)) -#define RTC_GPIO_PIN17_WAKEUP_ENABLE_M (BIT(10)) -#define RTC_GPIO_PIN17_WAKEUP_ENABLE_V 0x1 -#define RTC_GPIO_PIN17_WAKEUP_ENABLE_S 10 -/* RTC_GPIO_PIN17_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ -/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge - trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ -#define RTC_GPIO_PIN17_INT_TYPE 0x00000007 -#define RTC_GPIO_PIN17_INT_TYPE_M ((RTC_GPIO_PIN17_INT_TYPE_V)<<(RTC_GPIO_PIN17_INT_TYPE_S)) -#define RTC_GPIO_PIN17_INT_TYPE_V 0x7 -#define RTC_GPIO_PIN17_INT_TYPE_S 7 -/* RTC_GPIO_PIN17_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ -/*description: if set to 0: normal output if set to 1: open drain*/ -#define RTC_GPIO_PIN17_PAD_DRIVER (BIT(2)) -#define RTC_GPIO_PIN17_PAD_DRIVER_M (BIT(2)) -#define RTC_GPIO_PIN17_PAD_DRIVER_V 0x1 -#define RTC_GPIO_PIN17_PAD_DRIVER_S 2 - -#define RTC_IO_RTC_DEBUG_SEL_REG (DR_REG_RTCIO_BASE + 0x70) -/* RTC_IO_DEBUG_12M_NO_GATING : R/W ;bitpos:[25] ;default: 1'd0 ; */ -/*description: */ -#define RTC_IO_DEBUG_12M_NO_GATING (BIT(25)) -#define RTC_IO_DEBUG_12M_NO_GATING_M (BIT(25)) -#define RTC_IO_DEBUG_12M_NO_GATING_V 0x1 -#define RTC_IO_DEBUG_12M_NO_GATING_S 25 -/* RTC_IO_DEBUG_SEL4 : R/W ;bitpos:[24:20] ;default: 5'd0 ; */ -/*description: */ -#define RTC_IO_DEBUG_SEL4 0x0000001F -#define RTC_IO_DEBUG_SEL4_M ((RTC_IO_DEBUG_SEL4_V)<<(RTC_IO_DEBUG_SEL4_S)) -#define RTC_IO_DEBUG_SEL4_V 0x1F -#define RTC_IO_DEBUG_SEL4_S 20 -/* RTC_IO_DEBUG_SEL3 : R/W ;bitpos:[19:15] ;default: 5'd0 ; */ -/*description: */ -#define RTC_IO_DEBUG_SEL3 0x0000001F -#define RTC_IO_DEBUG_SEL3_M ((RTC_IO_DEBUG_SEL3_V)<<(RTC_IO_DEBUG_SEL3_S)) -#define RTC_IO_DEBUG_SEL3_V 0x1F -#define RTC_IO_DEBUG_SEL3_S 15 -/* RTC_IO_DEBUG_SEL2 : R/W ;bitpos:[14:10] ;default: 5'd0 ; */ -/*description: */ -#define RTC_IO_DEBUG_SEL2 0x0000001F -#define RTC_IO_DEBUG_SEL2_M ((RTC_IO_DEBUG_SEL2_V)<<(RTC_IO_DEBUG_SEL2_S)) -#define RTC_IO_DEBUG_SEL2_V 0x1F -#define RTC_IO_DEBUG_SEL2_S 10 -/* RTC_IO_DEBUG_SEL1 : R/W ;bitpos:[9:5] ;default: 5'd0 ; */ -/*description: */ -#define RTC_IO_DEBUG_SEL1 0x0000001F -#define RTC_IO_DEBUG_SEL1_M ((RTC_IO_DEBUG_SEL1_V)<<(RTC_IO_DEBUG_SEL1_S)) -#define RTC_IO_DEBUG_SEL1_V 0x1F -#define RTC_IO_DEBUG_SEL1_S 5 -/* RTC_IO_DEBUG_SEL0 : R/W ;bitpos:[4:0] ;default: 5'd0 ; */ -/*description: */ -#define RTC_IO_DEBUG_SEL0 0x0000001F -#define RTC_IO_DEBUG_SEL0_M ((RTC_IO_DEBUG_SEL0_V)<<(RTC_IO_DEBUG_SEL0_S)) -#define RTC_IO_DEBUG_SEL0_V 0x1F -#define RTC_IO_DEBUG_SEL0_S 0 - -#define RTC_IO_DIG_PAD_HOLD_REG (DR_REG_RTCIO_BASE + 0x74) -/* RTC_IO_DIG_PAD_HOLD : R/W ;bitpos:[31:0] ;default: 1'd0 ; */ -/*description: select the digital pad hold value.*/ -#define RTC_IO_DIG_PAD_HOLD 0xFFFFFFFF -#define RTC_IO_DIG_PAD_HOLD_M ((RTC_IO_DIG_PAD_HOLD_V)<<(RTC_IO_DIG_PAD_HOLD_S)) -#define RTC_IO_DIG_PAD_HOLD_V 0xFFFFFFFF -#define RTC_IO_DIG_PAD_HOLD_S 0 - -#define RTC_IO_HALL_SENS_REG (DR_REG_RTCIO_BASE + 0x78) -/* RTC_IO_XPD_HALL : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: Power on hall sensor and connect to VP and VN*/ -#define RTC_IO_XPD_HALL (BIT(31)) -#define RTC_IO_XPD_HALL_M (BIT(31)) -#define RTC_IO_XPD_HALL_V 0x1 -#define RTC_IO_XPD_HALL_S 31 -/* RTC_IO_HALL_PHASE : R/W ;bitpos:[30] ;default: 1'd0 ; */ -/*description: Reverse phase of hall sensor*/ -#define RTC_IO_HALL_PHASE (BIT(30)) -#define RTC_IO_HALL_PHASE_M (BIT(30)) -#define RTC_IO_HALL_PHASE_V 0x1 -#define RTC_IO_HALL_PHASE_S 30 - -#define RTC_IO_SENSOR_PADS_REG (DR_REG_RTCIO_BASE + 0x7c) -/* RTC_IO_SENSE1_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_SENSE1_HOLD (BIT(31)) -#define RTC_IO_SENSE1_HOLD_M (BIT(31)) -#define RTC_IO_SENSE1_HOLD_V 0x1 -#define RTC_IO_SENSE1_HOLD_S 31 -/* RTC_IO_SENSE2_HOLD : R/W ;bitpos:[30] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_SENSE2_HOLD (BIT(30)) -#define RTC_IO_SENSE2_HOLD_M (BIT(30)) -#define RTC_IO_SENSE2_HOLD_V 0x1 -#define RTC_IO_SENSE2_HOLD_S 30 -/* RTC_IO_SENSE3_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_SENSE3_HOLD (BIT(29)) -#define RTC_IO_SENSE3_HOLD_M (BIT(29)) -#define RTC_IO_SENSE3_HOLD_V 0x1 -#define RTC_IO_SENSE3_HOLD_S 29 -/* RTC_IO_SENSE4_HOLD : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_SENSE4_HOLD (BIT(28)) -#define RTC_IO_SENSE4_HOLD_M (BIT(28)) -#define RTC_IO_SENSE4_HOLD_V 0x1 -#define RTC_IO_SENSE4_HOLD_S 28 -/* RTC_IO_SENSE1_MUX_SEL : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_SENSE1_MUX_SEL (BIT(27)) -#define RTC_IO_SENSE1_MUX_SEL_M (BIT(27)) -#define RTC_IO_SENSE1_MUX_SEL_V 0x1 -#define RTC_IO_SENSE1_MUX_SEL_S 27 -/* RTC_IO_SENSE2_MUX_SEL : R/W ;bitpos:[26] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_SENSE2_MUX_SEL (BIT(26)) -#define RTC_IO_SENSE2_MUX_SEL_M (BIT(26)) -#define RTC_IO_SENSE2_MUX_SEL_V 0x1 -#define RTC_IO_SENSE2_MUX_SEL_S 26 -/* RTC_IO_SENSE3_MUX_SEL : R/W ;bitpos:[25] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_SENSE3_MUX_SEL (BIT(25)) -#define RTC_IO_SENSE3_MUX_SEL_M (BIT(25)) -#define RTC_IO_SENSE3_MUX_SEL_V 0x1 -#define RTC_IO_SENSE3_MUX_SEL_S 25 -/* RTC_IO_SENSE4_MUX_SEL : R/W ;bitpos:[24] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_SENSE4_MUX_SEL (BIT(24)) -#define RTC_IO_SENSE4_MUX_SEL_M (BIT(24)) -#define RTC_IO_SENSE4_MUX_SEL_V 0x1 -#define RTC_IO_SENSE4_MUX_SEL_S 24 -/* RTC_IO_SENSE1_FUN_SEL : R/W ;bitpos:[23:22] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_SENSE1_FUN_SEL 0x00000003 -#define RTC_IO_SENSE1_FUN_SEL_M ((RTC_IO_SENSE1_FUN_SEL_V)<<(RTC_IO_SENSE1_FUN_SEL_S)) -#define RTC_IO_SENSE1_FUN_SEL_V 0x3 -#define RTC_IO_SENSE1_FUN_SEL_S 22 -/* RTC_IO_SENSE1_SLP_SEL : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_SENSE1_SLP_SEL (BIT(21)) -#define RTC_IO_SENSE1_SLP_SEL_M (BIT(21)) -#define RTC_IO_SENSE1_SLP_SEL_V 0x1 -#define RTC_IO_SENSE1_SLP_SEL_S 21 -/* RTC_IO_SENSE1_SLP_IE : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_SENSE1_SLP_IE (BIT(20)) -#define RTC_IO_SENSE1_SLP_IE_M (BIT(20)) -#define RTC_IO_SENSE1_SLP_IE_V 0x1 -#define RTC_IO_SENSE1_SLP_IE_S 20 -/* RTC_IO_SENSE1_FUN_IE : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_SENSE1_FUN_IE (BIT(19)) -#define RTC_IO_SENSE1_FUN_IE_M (BIT(19)) -#define RTC_IO_SENSE1_FUN_IE_V 0x1 -#define RTC_IO_SENSE1_FUN_IE_S 19 -/* RTC_IO_SENSE2_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_SENSE2_FUN_SEL 0x00000003 -#define RTC_IO_SENSE2_FUN_SEL_M ((RTC_IO_SENSE2_FUN_SEL_V)<<(RTC_IO_SENSE2_FUN_SEL_S)) -#define RTC_IO_SENSE2_FUN_SEL_V 0x3 -#define RTC_IO_SENSE2_FUN_SEL_S 17 -/* RTC_IO_SENSE2_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_SENSE2_SLP_SEL (BIT(16)) -#define RTC_IO_SENSE2_SLP_SEL_M (BIT(16)) -#define RTC_IO_SENSE2_SLP_SEL_V 0x1 -#define RTC_IO_SENSE2_SLP_SEL_S 16 -/* RTC_IO_SENSE2_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_SENSE2_SLP_IE (BIT(15)) -#define RTC_IO_SENSE2_SLP_IE_M (BIT(15)) -#define RTC_IO_SENSE2_SLP_IE_V 0x1 -#define RTC_IO_SENSE2_SLP_IE_S 15 -/* RTC_IO_SENSE2_FUN_IE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_SENSE2_FUN_IE (BIT(14)) -#define RTC_IO_SENSE2_FUN_IE_M (BIT(14)) -#define RTC_IO_SENSE2_FUN_IE_V 0x1 -#define RTC_IO_SENSE2_FUN_IE_S 14 -/* RTC_IO_SENSE3_FUN_SEL : R/W ;bitpos:[13:12] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_SENSE3_FUN_SEL 0x00000003 -#define RTC_IO_SENSE3_FUN_SEL_M ((RTC_IO_SENSE3_FUN_SEL_V)<<(RTC_IO_SENSE3_FUN_SEL_S)) -#define RTC_IO_SENSE3_FUN_SEL_V 0x3 -#define RTC_IO_SENSE3_FUN_SEL_S 12 -/* RTC_IO_SENSE3_SLP_SEL : R/W ;bitpos:[11] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_SENSE3_SLP_SEL (BIT(11)) -#define RTC_IO_SENSE3_SLP_SEL_M (BIT(11)) -#define RTC_IO_SENSE3_SLP_SEL_V 0x1 -#define RTC_IO_SENSE3_SLP_SEL_S 11 -/* RTC_IO_SENSE3_SLP_IE : R/W ;bitpos:[10] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_SENSE3_SLP_IE (BIT(10)) -#define RTC_IO_SENSE3_SLP_IE_M (BIT(10)) -#define RTC_IO_SENSE3_SLP_IE_V 0x1 -#define RTC_IO_SENSE3_SLP_IE_S 10 -/* RTC_IO_SENSE3_FUN_IE : R/W ;bitpos:[9] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_SENSE3_FUN_IE (BIT(9)) -#define RTC_IO_SENSE3_FUN_IE_M (BIT(9)) -#define RTC_IO_SENSE3_FUN_IE_V 0x1 -#define RTC_IO_SENSE3_FUN_IE_S 9 -/* RTC_IO_SENSE4_FUN_SEL : R/W ;bitpos:[8:7] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_SENSE4_FUN_SEL 0x00000003 -#define RTC_IO_SENSE4_FUN_SEL_M ((RTC_IO_SENSE4_FUN_SEL_V)<<(RTC_IO_SENSE4_FUN_SEL_S)) -#define RTC_IO_SENSE4_FUN_SEL_V 0x3 -#define RTC_IO_SENSE4_FUN_SEL_S 7 -/* RTC_IO_SENSE4_SLP_SEL : R/W ;bitpos:[6] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_SENSE4_SLP_SEL (BIT(6)) -#define RTC_IO_SENSE4_SLP_SEL_M (BIT(6)) -#define RTC_IO_SENSE4_SLP_SEL_V 0x1 -#define RTC_IO_SENSE4_SLP_SEL_S 6 -/* RTC_IO_SENSE4_SLP_IE : R/W ;bitpos:[5] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_SENSE4_SLP_IE (BIT(5)) -#define RTC_IO_SENSE4_SLP_IE_M (BIT(5)) -#define RTC_IO_SENSE4_SLP_IE_V 0x1 -#define RTC_IO_SENSE4_SLP_IE_S 5 -/* RTC_IO_SENSE4_FUN_IE : R/W ;bitpos:[4] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_SENSE4_FUN_IE (BIT(4)) -#define RTC_IO_SENSE4_FUN_IE_M (BIT(4)) -#define RTC_IO_SENSE4_FUN_IE_V 0x1 -#define RTC_IO_SENSE4_FUN_IE_S 4 - -#define RTC_IO_ADC_PAD_REG (DR_REG_RTCIO_BASE + 0x80) -/* RTC_IO_ADC1_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_ADC1_HOLD (BIT(31)) -#define RTC_IO_ADC1_HOLD_M (BIT(31)) -#define RTC_IO_ADC1_HOLD_V 0x1 -#define RTC_IO_ADC1_HOLD_S 31 -/* RTC_IO_ADC2_HOLD : R/W ;bitpos:[30] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_ADC2_HOLD (BIT(30)) -#define RTC_IO_ADC2_HOLD_M (BIT(30)) -#define RTC_IO_ADC2_HOLD_V 0x1 -#define RTC_IO_ADC2_HOLD_S 30 -/* RTC_IO_ADC1_MUX_SEL : R/W ;bitpos:[29] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_ADC1_MUX_SEL (BIT(29)) -#define RTC_IO_ADC1_MUX_SEL_M (BIT(29)) -#define RTC_IO_ADC1_MUX_SEL_V 0x1 -#define RTC_IO_ADC1_MUX_SEL_S 29 -/* RTC_IO_ADC2_MUX_SEL : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_ADC2_MUX_SEL (BIT(28)) -#define RTC_IO_ADC2_MUX_SEL_M (BIT(28)) -#define RTC_IO_ADC2_MUX_SEL_V 0x1 -#define RTC_IO_ADC2_MUX_SEL_S 28 -/* RTC_IO_ADC1_FUN_SEL : R/W ;bitpos:[27:26] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_ADC1_FUN_SEL 0x00000003 -#define RTC_IO_ADC1_FUN_SEL_M ((RTC_IO_ADC1_FUN_SEL_V)<<(RTC_IO_ADC1_FUN_SEL_S)) -#define RTC_IO_ADC1_FUN_SEL_V 0x3 -#define RTC_IO_ADC1_FUN_SEL_S 26 -/* RTC_IO_ADC1_SLP_SEL : R/W ;bitpos:[25] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_ADC1_SLP_SEL (BIT(25)) -#define RTC_IO_ADC1_SLP_SEL_M (BIT(25)) -#define RTC_IO_ADC1_SLP_SEL_V 0x1 -#define RTC_IO_ADC1_SLP_SEL_S 25 -/* RTC_IO_ADC1_SLP_IE : R/W ;bitpos:[24] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_ADC1_SLP_IE (BIT(24)) -#define RTC_IO_ADC1_SLP_IE_M (BIT(24)) -#define RTC_IO_ADC1_SLP_IE_V 0x1 -#define RTC_IO_ADC1_SLP_IE_S 24 -/* RTC_IO_ADC1_FUN_IE : R/W ;bitpos:[23] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_ADC1_FUN_IE (BIT(23)) -#define RTC_IO_ADC1_FUN_IE_M (BIT(23)) -#define RTC_IO_ADC1_FUN_IE_V 0x1 -#define RTC_IO_ADC1_FUN_IE_S 23 -/* RTC_IO_ADC2_FUN_SEL : R/W ;bitpos:[22:21] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_ADC2_FUN_SEL 0x00000003 -#define RTC_IO_ADC2_FUN_SEL_M ((RTC_IO_ADC2_FUN_SEL_V)<<(RTC_IO_ADC2_FUN_SEL_S)) -#define RTC_IO_ADC2_FUN_SEL_V 0x3 -#define RTC_IO_ADC2_FUN_SEL_S 21 -/* RTC_IO_ADC2_SLP_SEL : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_ADC2_SLP_SEL (BIT(20)) -#define RTC_IO_ADC2_SLP_SEL_M (BIT(20)) -#define RTC_IO_ADC2_SLP_SEL_V 0x1 -#define RTC_IO_ADC2_SLP_SEL_S 20 -/* RTC_IO_ADC2_SLP_IE : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_ADC2_SLP_IE (BIT(19)) -#define RTC_IO_ADC2_SLP_IE_M (BIT(19)) -#define RTC_IO_ADC2_SLP_IE_V 0x1 -#define RTC_IO_ADC2_SLP_IE_S 19 -/* RTC_IO_ADC2_FUN_IE : R/W ;bitpos:[18] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_ADC2_FUN_IE (BIT(18)) -#define RTC_IO_ADC2_FUN_IE_M (BIT(18)) -#define RTC_IO_ADC2_FUN_IE_V 0x1 -#define RTC_IO_ADC2_FUN_IE_S 18 - -#define RTC_IO_PAD_DAC1_REG (DR_REG_RTCIO_BASE + 0x84) -/* RTC_IO_PDAC1_DRV : R/W ;bitpos:[31:30] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_PDAC1_DRV 0x00000003 -#define RTC_IO_PDAC1_DRV_M ((RTC_IO_PDAC1_DRV_V)<<(RTC_IO_PDAC1_DRV_S)) -#define RTC_IO_PDAC1_DRV_V 0x3 -#define RTC_IO_PDAC1_DRV_S 30 -/* RTC_IO_PDAC1_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_PDAC1_HOLD (BIT(29)) -#define RTC_IO_PDAC1_HOLD_M (BIT(29)) -#define RTC_IO_PDAC1_HOLD_V 0x1 -#define RTC_IO_PDAC1_HOLD_S 29 -/* RTC_IO_PDAC1_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_PDAC1_RDE (BIT(28)) -#define RTC_IO_PDAC1_RDE_M (BIT(28)) -#define RTC_IO_PDAC1_RDE_V 0x1 -#define RTC_IO_PDAC1_RDE_S 28 -/* RTC_IO_PDAC1_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_PDAC1_RUE (BIT(27)) -#define RTC_IO_PDAC1_RUE_M (BIT(27)) -#define RTC_IO_PDAC1_RUE_V 0x1 -#define RTC_IO_PDAC1_RUE_S 27 -/* RTC_IO_PDAC1_DAC : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ -/*description: PAD DAC1 control code.*/ -#define RTC_IO_PDAC1_DAC 0x000000FF -#define RTC_IO_PDAC1_DAC_M ((RTC_IO_PDAC1_DAC_V)<<(RTC_IO_PDAC1_DAC_S)) -#define RTC_IO_PDAC1_DAC_V 0xFF -#define RTC_IO_PDAC1_DAC_S 19 -/* RTC_IO_PDAC1_XPD_DAC : R/W ;bitpos:[18] ;default: 1'd0 ; */ -/*description: Power on DAC1. Usually we need to tristate PDAC1 if we power - on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ -#define RTC_IO_PDAC1_XPD_DAC (BIT(18)) -#define RTC_IO_PDAC1_XPD_DAC_M (BIT(18)) -#define RTC_IO_PDAC1_XPD_DAC_V 0x1 -#define RTC_IO_PDAC1_XPD_DAC_S 18 -/* RTC_IO_PDAC1_MUX_SEL : R/W ;bitpos:[17] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_PDAC1_MUX_SEL (BIT(17)) -#define RTC_IO_PDAC1_MUX_SEL_M (BIT(17)) -#define RTC_IO_PDAC1_MUX_SEL_V 0x1 -#define RTC_IO_PDAC1_MUX_SEL_S 17 -/* RTC_IO_PDAC1_FUN_SEL : R/W ;bitpos:[16:15] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_PDAC1_FUN_SEL 0x00000003 -#define RTC_IO_PDAC1_FUN_SEL_M ((RTC_IO_PDAC1_FUN_SEL_V)<<(RTC_IO_PDAC1_FUN_SEL_S)) -#define RTC_IO_PDAC1_FUN_SEL_V 0x3 -#define RTC_IO_PDAC1_FUN_SEL_S 15 -/* RTC_IO_PDAC1_SLP_SEL : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_PDAC1_SLP_SEL (BIT(14)) -#define RTC_IO_PDAC1_SLP_SEL_M (BIT(14)) -#define RTC_IO_PDAC1_SLP_SEL_V 0x1 -#define RTC_IO_PDAC1_SLP_SEL_S 14 -/* RTC_IO_PDAC1_SLP_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_PDAC1_SLP_IE (BIT(13)) -#define RTC_IO_PDAC1_SLP_IE_M (BIT(13)) -#define RTC_IO_PDAC1_SLP_IE_V 0x1 -#define RTC_IO_PDAC1_SLP_IE_S 13 -/* RTC_IO_PDAC1_SLP_OE : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_PDAC1_SLP_OE (BIT(12)) -#define RTC_IO_PDAC1_SLP_OE_M (BIT(12)) -#define RTC_IO_PDAC1_SLP_OE_V 0x1 -#define RTC_IO_PDAC1_SLP_OE_S 12 -/* RTC_IO_PDAC1_FUN_IE : R/W ;bitpos:[11] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_PDAC1_FUN_IE (BIT(11)) -#define RTC_IO_PDAC1_FUN_IE_M (BIT(11)) -#define RTC_IO_PDAC1_FUN_IE_V 0x1 -#define RTC_IO_PDAC1_FUN_IE_S 11 -/* RTC_IO_PDAC1_DAC_XPD_FORCE : R/W ;bitpos:[10] ;default: 1'd0 ; */ -/*description: Power on DAC1. Usually we need to tristate PDAC1 if we power - on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ -#define RTC_IO_PDAC1_DAC_XPD_FORCE (BIT(10)) -#define RTC_IO_PDAC1_DAC_XPD_FORCE_M (BIT(10)) -#define RTC_IO_PDAC1_DAC_XPD_FORCE_V 0x1 -#define RTC_IO_PDAC1_DAC_XPD_FORCE_S 10 - -#define RTC_IO_PAD_DAC2_REG (DR_REG_RTCIO_BASE + 0x88) -/* RTC_IO_PDAC2_DRV : R/W ;bitpos:[31:30] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_PDAC2_DRV 0x00000003 -#define RTC_IO_PDAC2_DRV_M ((RTC_IO_PDAC2_DRV_V)<<(RTC_IO_PDAC2_DRV_S)) -#define RTC_IO_PDAC2_DRV_V 0x3 -#define RTC_IO_PDAC2_DRV_S 30 -/* RTC_IO_PDAC2_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_PDAC2_HOLD (BIT(29)) -#define RTC_IO_PDAC2_HOLD_M (BIT(29)) -#define RTC_IO_PDAC2_HOLD_V 0x1 -#define RTC_IO_PDAC2_HOLD_S 29 -/* RTC_IO_PDAC2_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_PDAC2_RDE (BIT(28)) -#define RTC_IO_PDAC2_RDE_M (BIT(28)) -#define RTC_IO_PDAC2_RDE_V 0x1 -#define RTC_IO_PDAC2_RDE_S 28 -/* RTC_IO_PDAC2_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_PDAC2_RUE (BIT(27)) -#define RTC_IO_PDAC2_RUE_M (BIT(27)) -#define RTC_IO_PDAC2_RUE_V 0x1 -#define RTC_IO_PDAC2_RUE_S 27 -/* RTC_IO_PDAC2_DAC : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ -/*description: PAD DAC2 control code.*/ -#define RTC_IO_PDAC2_DAC 0x000000FF -#define RTC_IO_PDAC2_DAC_M ((RTC_IO_PDAC2_DAC_V)<<(RTC_IO_PDAC2_DAC_S)) -#define RTC_IO_PDAC2_DAC_V 0xFF -#define RTC_IO_PDAC2_DAC_S 19 -/* RTC_IO_PDAC2_XPD_DAC : R/W ;bitpos:[18] ;default: 1'd0 ; */ -/*description: Power on DAC2. Usually we need to tristate PDAC1 if we power - on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ -#define RTC_IO_PDAC2_XPD_DAC (BIT(18)) -#define RTC_IO_PDAC2_XPD_DAC_M (BIT(18)) -#define RTC_IO_PDAC2_XPD_DAC_V 0x1 -#define RTC_IO_PDAC2_XPD_DAC_S 18 -/* RTC_IO_PDAC2_MUX_SEL : R/W ;bitpos:[17] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_PDAC2_MUX_SEL (BIT(17)) -#define RTC_IO_PDAC2_MUX_SEL_M (BIT(17)) -#define RTC_IO_PDAC2_MUX_SEL_V 0x1 -#define RTC_IO_PDAC2_MUX_SEL_S 17 -/* RTC_IO_PDAC2_FUN_SEL : R/W ;bitpos:[16:15] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_PDAC2_FUN_SEL 0x00000003 -#define RTC_IO_PDAC2_FUN_SEL_M ((RTC_IO_PDAC2_FUN_SEL_V)<<(RTC_IO_PDAC2_FUN_SEL_S)) -#define RTC_IO_PDAC2_FUN_SEL_V 0x3 -#define RTC_IO_PDAC2_FUN_SEL_S 15 -/* RTC_IO_PDAC2_SLP_SEL : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_PDAC2_SLP_SEL (BIT(14)) -#define RTC_IO_PDAC2_SLP_SEL_M (BIT(14)) -#define RTC_IO_PDAC2_SLP_SEL_V 0x1 -#define RTC_IO_PDAC2_SLP_SEL_S 14 -/* RTC_IO_PDAC2_SLP_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_PDAC2_SLP_IE (BIT(13)) -#define RTC_IO_PDAC2_SLP_IE_M (BIT(13)) -#define RTC_IO_PDAC2_SLP_IE_V 0x1 -#define RTC_IO_PDAC2_SLP_IE_S 13 -/* RTC_IO_PDAC2_SLP_OE : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_PDAC2_SLP_OE (BIT(12)) -#define RTC_IO_PDAC2_SLP_OE_M (BIT(12)) -#define RTC_IO_PDAC2_SLP_OE_V 0x1 -#define RTC_IO_PDAC2_SLP_OE_S 12 -/* RTC_IO_PDAC2_FUN_IE : R/W ;bitpos:[11] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_PDAC2_FUN_IE (BIT(11)) -#define RTC_IO_PDAC2_FUN_IE_M (BIT(11)) -#define RTC_IO_PDAC2_FUN_IE_V 0x1 -#define RTC_IO_PDAC2_FUN_IE_S 11 -/* RTC_IO_PDAC2_DAC_XPD_FORCE : R/W ;bitpos:[10] ;default: 1'd0 ; */ -/*description: Power on DAC2. Usually we need to tristate PDAC2 if we power - on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ -#define RTC_IO_PDAC2_DAC_XPD_FORCE (BIT(10)) -#define RTC_IO_PDAC2_DAC_XPD_FORCE_M (BIT(10)) -#define RTC_IO_PDAC2_DAC_XPD_FORCE_V 0x1 -#define RTC_IO_PDAC2_DAC_XPD_FORCE_S 10 - -#define RTC_IO_XTAL_32K_PAD_REG (DR_REG_RTCIO_BASE + 0x8c) -/* RTC_IO_X32N_DRV : R/W ;bitpos:[31:30] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_X32N_DRV 0x00000003 -#define RTC_IO_X32N_DRV_M ((RTC_IO_X32N_DRV_V)<<(RTC_IO_X32N_DRV_S)) -#define RTC_IO_X32N_DRV_V 0x3 -#define RTC_IO_X32N_DRV_S 30 -/* RTC_IO_X32N_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_X32N_HOLD (BIT(29)) -#define RTC_IO_X32N_HOLD_M (BIT(29)) -#define RTC_IO_X32N_HOLD_V 0x1 -#define RTC_IO_X32N_HOLD_S 29 -/* RTC_IO_X32N_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_X32N_RDE (BIT(28)) -#define RTC_IO_X32N_RDE_M (BIT(28)) -#define RTC_IO_X32N_RDE_V 0x1 -#define RTC_IO_X32N_RDE_S 28 -/* RTC_IO_X32N_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_X32N_RUE (BIT(27)) -#define RTC_IO_X32N_RUE_M (BIT(27)) -#define RTC_IO_X32N_RUE_V 0x1 -#define RTC_IO_X32N_RUE_S 27 -/* RTC_IO_X32P_DRV : R/W ;bitpos:[26:25] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_X32P_DRV 0x00000003 -#define RTC_IO_X32P_DRV_M ((RTC_IO_X32P_DRV_V)<<(RTC_IO_X32P_DRV_S)) -#define RTC_IO_X32P_DRV_V 0x3 -#define RTC_IO_X32P_DRV_S 25 -/* RTC_IO_X32P_HOLD : R/W ;bitpos:[24] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_X32P_HOLD (BIT(24)) -#define RTC_IO_X32P_HOLD_M (BIT(24)) -#define RTC_IO_X32P_HOLD_V 0x1 -#define RTC_IO_X32P_HOLD_S 24 -/* RTC_IO_X32P_RDE : R/W ;bitpos:[23] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_X32P_RDE (BIT(23)) -#define RTC_IO_X32P_RDE_M (BIT(23)) -#define RTC_IO_X32P_RDE_V 0x1 -#define RTC_IO_X32P_RDE_S 23 -/* RTC_IO_X32P_RUE : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_X32P_RUE (BIT(22)) -#define RTC_IO_X32P_RUE_M (BIT(22)) -#define RTC_IO_X32P_RUE_V 0x1 -#define RTC_IO_X32P_RUE_S 22 -/* RTC_IO_DAC_XTAL_32K : R/W ;bitpos:[21:20] ;default: 2'b01 ; */ -/*description: 32K XTAL bias current DAC.*/ -#define RTC_IO_DAC_XTAL_32K 0x00000003 -#define RTC_IO_DAC_XTAL_32K_M ((RTC_IO_DAC_XTAL_32K_V)<<(RTC_IO_DAC_XTAL_32K_S)) -#define RTC_IO_DAC_XTAL_32K_V 0x3 -#define RTC_IO_DAC_XTAL_32K_S 20 -/* RTC_IO_XPD_XTAL_32K : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Power up 32kHz crystal oscillator*/ -#define RTC_IO_XPD_XTAL_32K (BIT(19)) -#define RTC_IO_XPD_XTAL_32K_M (BIT(19)) -#define RTC_IO_XPD_XTAL_32K_V 0x1 -#define RTC_IO_XPD_XTAL_32K_S 19 -/* RTC_IO_X32N_MUX_SEL : R/W ;bitpos:[18] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_X32N_MUX_SEL (BIT(18)) -#define RTC_IO_X32N_MUX_SEL_M (BIT(18)) -#define RTC_IO_X32N_MUX_SEL_V 0x1 -#define RTC_IO_X32N_MUX_SEL_S 18 -/* RTC_IO_X32P_MUX_SEL : R/W ;bitpos:[17] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_X32P_MUX_SEL (BIT(17)) -#define RTC_IO_X32P_MUX_SEL_M (BIT(17)) -#define RTC_IO_X32P_MUX_SEL_V 0x1 -#define RTC_IO_X32P_MUX_SEL_S 17 -/* RTC_IO_X32N_FUN_SEL : R/W ;bitpos:[16:15] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_X32N_FUN_SEL 0x00000003 -#define RTC_IO_X32N_FUN_SEL_M ((RTC_IO_X32N_FUN_SEL_V)<<(RTC_IO_X32N_FUN_SEL_S)) -#define RTC_IO_X32N_FUN_SEL_V 0x3 -#define RTC_IO_X32N_FUN_SEL_S 15 -/* RTC_IO_X32N_SLP_SEL : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_X32N_SLP_SEL (BIT(14)) -#define RTC_IO_X32N_SLP_SEL_M (BIT(14)) -#define RTC_IO_X32N_SLP_SEL_V 0x1 -#define RTC_IO_X32N_SLP_SEL_S 14 -/* RTC_IO_X32N_SLP_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_X32N_SLP_IE (BIT(13)) -#define RTC_IO_X32N_SLP_IE_M (BIT(13)) -#define RTC_IO_X32N_SLP_IE_V 0x1 -#define RTC_IO_X32N_SLP_IE_S 13 -/* RTC_IO_X32N_SLP_OE : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_X32N_SLP_OE (BIT(12)) -#define RTC_IO_X32N_SLP_OE_M (BIT(12)) -#define RTC_IO_X32N_SLP_OE_V 0x1 -#define RTC_IO_X32N_SLP_OE_S 12 -/* RTC_IO_X32N_FUN_IE : R/W ;bitpos:[11] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_X32N_FUN_IE (BIT(11)) -#define RTC_IO_X32N_FUN_IE_M (BIT(11)) -#define RTC_IO_X32N_FUN_IE_V 0x1 -#define RTC_IO_X32N_FUN_IE_S 11 -/* RTC_IO_X32P_FUN_SEL : R/W ;bitpos:[10:9] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_X32P_FUN_SEL 0x00000003 -#define RTC_IO_X32P_FUN_SEL_M ((RTC_IO_X32P_FUN_SEL_V)<<(RTC_IO_X32P_FUN_SEL_S)) -#define RTC_IO_X32P_FUN_SEL_V 0x3 -#define RTC_IO_X32P_FUN_SEL_S 9 -/* RTC_IO_X32P_SLP_SEL : R/W ;bitpos:[8] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_X32P_SLP_SEL (BIT(8)) -#define RTC_IO_X32P_SLP_SEL_M (BIT(8)) -#define RTC_IO_X32P_SLP_SEL_V 0x1 -#define RTC_IO_X32P_SLP_SEL_S 8 -/* RTC_IO_X32P_SLP_IE : R/W ;bitpos:[7] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_X32P_SLP_IE (BIT(7)) -#define RTC_IO_X32P_SLP_IE_M (BIT(7)) -#define RTC_IO_X32P_SLP_IE_V 0x1 -#define RTC_IO_X32P_SLP_IE_S 7 -/* RTC_IO_X32P_SLP_OE : R/W ;bitpos:[6] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_X32P_SLP_OE (BIT(6)) -#define RTC_IO_X32P_SLP_OE_M (BIT(6)) -#define RTC_IO_X32P_SLP_OE_V 0x1 -#define RTC_IO_X32P_SLP_OE_S 6 -/* RTC_IO_X32P_FUN_IE : R/W ;bitpos:[5] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_X32P_FUN_IE (BIT(5)) -#define RTC_IO_X32P_FUN_IE_M (BIT(5)) -#define RTC_IO_X32P_FUN_IE_V 0x1 -#define RTC_IO_X32P_FUN_IE_S 5 -/* RTC_IO_DRES_XTAL_32K : R/W ;bitpos:[4:3] ;default: 2'b10 ; */ -/*description: 32K XTAL resistor bias control.*/ -#define RTC_IO_DRES_XTAL_32K 0x00000003 -#define RTC_IO_DRES_XTAL_32K_M ((RTC_IO_DRES_XTAL_32K_V)<<(RTC_IO_DRES_XTAL_32K_S)) -#define RTC_IO_DRES_XTAL_32K_V 0x3 -#define RTC_IO_DRES_XTAL_32K_S 3 -/* RTC_IO_DBIAS_XTAL_32K : R/W ;bitpos:[2:1] ;default: 2'b00 ; */ -/*description: 32K XTAL self-bias reference control.*/ -#define RTC_IO_DBIAS_XTAL_32K 0x00000003 -#define RTC_IO_DBIAS_XTAL_32K_M ((RTC_IO_DBIAS_XTAL_32K_V)<<(RTC_IO_DBIAS_XTAL_32K_S)) -#define RTC_IO_DBIAS_XTAL_32K_V 0x3 -#define RTC_IO_DBIAS_XTAL_32K_S 1 - -#define RTC_IO_TOUCH_CFG_REG (DR_REG_RTCIO_BASE + 0x90) -/* RTC_IO_TOUCH_XPD_BIAS : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: touch sensor bias power on.*/ -#define RTC_IO_TOUCH_XPD_BIAS (BIT(31)) -#define RTC_IO_TOUCH_XPD_BIAS_M (BIT(31)) -#define RTC_IO_TOUCH_XPD_BIAS_V 0x1 -#define RTC_IO_TOUCH_XPD_BIAS_S 31 -/* RTC_IO_TOUCH_DREFH : R/W ;bitpos:[30:29] ;default: 2'b11 ; */ -/*description: touch sensor saw wave top voltage.*/ -#define RTC_IO_TOUCH_DREFH 0x00000003 -#define RTC_IO_TOUCH_DREFH_M ((RTC_IO_TOUCH_DREFH_V)<<(RTC_IO_TOUCH_DREFH_S)) -#define RTC_IO_TOUCH_DREFH_V 0x3 -#define RTC_IO_TOUCH_DREFH_S 29 -/* RTC_IO_TOUCH_DREFL : R/W ;bitpos:[28:27] ;default: 2'b00 ; */ -/*description: touch sensor saw wave bottom voltage.*/ -#define RTC_IO_TOUCH_DREFL 0x00000003 -#define RTC_IO_TOUCH_DREFL_M ((RTC_IO_TOUCH_DREFL_V)<<(RTC_IO_TOUCH_DREFL_S)) -#define RTC_IO_TOUCH_DREFL_V 0x3 -#define RTC_IO_TOUCH_DREFL_S 27 -/* RTC_IO_TOUCH_DRANGE : R/W ;bitpos:[26:25] ;default: 2'b11 ; */ -/*description: touch sensor saw wave voltage range.*/ -#define RTC_IO_TOUCH_DRANGE 0x00000003 -#define RTC_IO_TOUCH_DRANGE_M ((RTC_IO_TOUCH_DRANGE_V)<<(RTC_IO_TOUCH_DRANGE_S)) -#define RTC_IO_TOUCH_DRANGE_V 0x3 -#define RTC_IO_TOUCH_DRANGE_S 25 -/* RTC_IO_TOUCH_DCUR : R/W ;bitpos:[24:23] ;default: 2'b00 ; */ -/*description: touch sensor bias current. Should have option to tie with BIAS_SLEEP(When - BIAS_SLEEP this setting is available*/ -#define RTC_IO_TOUCH_DCUR 0x00000003 -#define RTC_IO_TOUCH_DCUR_M ((RTC_IO_TOUCH_DCUR_V)<<(RTC_IO_TOUCH_DCUR_S)) -#define RTC_IO_TOUCH_DCUR_V 0x3 -#define RTC_IO_TOUCH_DCUR_S 23 - -#define RTC_IO_TOUCH_PAD0_REG (DR_REG_RTCIO_BASE + 0x94) -/* RTC_IO_TOUCH_PAD0_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD0_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD0_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD0_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD0_HOLD_S 31 -/* RTC_IO_TOUCH_PAD0_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD0_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD0_DRV_M ((RTC_IO_TOUCH_PAD0_DRV_V)<<(RTC_IO_TOUCH_PAD0_DRV_S)) -#define RTC_IO_TOUCH_PAD0_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD0_DRV_S 29 -/* RTC_IO_TOUCH_PAD0_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD0_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD0_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD0_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD0_RDE_S 28 -/* RTC_IO_TOUCH_PAD0_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD0_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD0_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD0_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD0_RUE_S 27 -/* RTC_IO_TOUCH_PAD0_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD0_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD0_DAC_M ((RTC_IO_TOUCH_PAD0_DAC_V)<<(RTC_IO_TOUCH_PAD0_DAC_S)) -#define RTC_IO_TOUCH_PAD0_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD0_DAC_S 23 -/* RTC_IO_TOUCH_PAD0_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD0_START (BIT(22)) -#define RTC_IO_TOUCH_PAD0_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD0_START_V 0x1 -#define RTC_IO_TOUCH_PAD0_START_S 22 -/* RTC_IO_TOUCH_PAD0_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD0_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD0_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD0_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD0_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD0_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD0_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD0_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD0_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD0_XPD_S 20 -/* RTC_IO_TOUCH_PAD0_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD0_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD0_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD0_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD0_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD0_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD0_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD0_FUN_SEL_M ((RTC_IO_TOUCH_PAD0_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD0_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD0_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD0_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD0_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD0_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD0_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD0_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD0_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD0_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD0_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD0_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD0_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD0_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD0_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD0_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD0_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD0_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD0_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD0_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD0_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD0_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD0_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD0_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD0_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale GPIO4*/ -#define RTC_IO_TOUCH_PAD0_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD0_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD0_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD0_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD1_REG (DR_REG_RTCIO_BASE + 0x98) -/* RTC_IO_TOUCH_PAD1_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: */ -#define RTC_IO_TOUCH_PAD1_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD1_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD1_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD1_HOLD_S 31 -/* RTC_IO_TOUCH_PAD1_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD1_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD1_DRV_M ((RTC_IO_TOUCH_PAD1_DRV_V)<<(RTC_IO_TOUCH_PAD1_DRV_S)) -#define RTC_IO_TOUCH_PAD1_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD1_DRV_S 29 -/* RTC_IO_TOUCH_PAD1_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD1_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD1_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD1_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD1_RDE_S 28 -/* RTC_IO_TOUCH_PAD1_RUE : R/W ;bitpos:[27] ;default: 1'd1 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD1_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD1_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD1_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD1_RUE_S 27 -/* RTC_IO_TOUCH_PAD1_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD1_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD1_DAC_M ((RTC_IO_TOUCH_PAD1_DAC_V)<<(RTC_IO_TOUCH_PAD1_DAC_S)) -#define RTC_IO_TOUCH_PAD1_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD1_DAC_S 23 -/* RTC_IO_TOUCH_PAD1_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD1_START (BIT(22)) -#define RTC_IO_TOUCH_PAD1_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD1_START_V 0x1 -#define RTC_IO_TOUCH_PAD1_START_S 22 -/* RTC_IO_TOUCH_PAD1_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD1_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD1_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD1_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD1_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD1_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD1_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD1_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD1_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD1_XPD_S 20 -/* RTC_IO_TOUCH_PAD1_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD1_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD1_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD1_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD1_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD1_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD1_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD1_FUN_SEL_M ((RTC_IO_TOUCH_PAD1_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD1_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD1_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD1_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD1_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD1_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD1_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD1_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD1_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD1_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD1_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD1_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD1_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD1_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD1_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD1_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD1_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD1_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD1_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD1_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD1_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD1_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD1_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD1_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD1_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO0*/ -#define RTC_IO_TOUCH_PAD1_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD1_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD1_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD1_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD2_REG (DR_REG_RTCIO_BASE + 0x9c) -/* RTC_IO_TOUCH_PAD2_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD2_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD2_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD2_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD2_HOLD_S 31 -/* RTC_IO_TOUCH_PAD2_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD2_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD2_DRV_M ((RTC_IO_TOUCH_PAD2_DRV_V)<<(RTC_IO_TOUCH_PAD2_DRV_S)) -#define RTC_IO_TOUCH_PAD2_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD2_DRV_S 29 -/* RTC_IO_TOUCH_PAD2_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD2_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD2_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD2_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD2_RDE_S 28 -/* RTC_IO_TOUCH_PAD2_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD2_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD2_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD2_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD2_RUE_S 27 -/* RTC_IO_TOUCH_PAD2_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD2_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD2_DAC_M ((RTC_IO_TOUCH_PAD2_DAC_V)<<(RTC_IO_TOUCH_PAD2_DAC_S)) -#define RTC_IO_TOUCH_PAD2_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD2_DAC_S 23 -/* RTC_IO_TOUCH_PAD2_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD2_START (BIT(22)) -#define RTC_IO_TOUCH_PAD2_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD2_START_V 0x1 -#define RTC_IO_TOUCH_PAD2_START_S 22 -/* RTC_IO_TOUCH_PAD2_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD2_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD2_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD2_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD2_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD2_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD2_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD2_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD2_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD2_XPD_S 20 -/* RTC_IO_TOUCH_PAD2_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD2_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD2_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD2_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD2_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD2_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD2_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD2_FUN_SEL_M ((RTC_IO_TOUCH_PAD2_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD2_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD2_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD2_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD2_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD2_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD2_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD2_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD2_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD2_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD2_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD2_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD2_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD2_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD2_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD2_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD2_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD2_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD2_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD2_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD2_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD2_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD2_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD2_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD2_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO2*/ -#define RTC_IO_TOUCH_PAD2_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD2_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD2_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD2_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD3_REG (DR_REG_RTCIO_BASE + 0xa0) -/* RTC_IO_TOUCH_PAD3_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD3_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD3_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD3_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD3_HOLD_S 31 -/* RTC_IO_TOUCH_PAD3_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD3_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD3_DRV_M ((RTC_IO_TOUCH_PAD3_DRV_V)<<(RTC_IO_TOUCH_PAD3_DRV_S)) -#define RTC_IO_TOUCH_PAD3_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD3_DRV_S 29 -/* RTC_IO_TOUCH_PAD3_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD3_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD3_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD3_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD3_RDE_S 28 -/* RTC_IO_TOUCH_PAD3_RUE : R/W ;bitpos:[27] ;default: 1'd1 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD3_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD3_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD3_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD3_RUE_S 27 -/* RTC_IO_TOUCH_PAD3_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD3_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD3_DAC_M ((RTC_IO_TOUCH_PAD3_DAC_V)<<(RTC_IO_TOUCH_PAD3_DAC_S)) -#define RTC_IO_TOUCH_PAD3_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD3_DAC_S 23 -/* RTC_IO_TOUCH_PAD3_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD3_START (BIT(22)) -#define RTC_IO_TOUCH_PAD3_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD3_START_V 0x1 -#define RTC_IO_TOUCH_PAD3_START_S 22 -/* RTC_IO_TOUCH_PAD3_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD3_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD3_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD3_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD3_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD3_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD3_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD3_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD3_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD3_XPD_S 20 -/* RTC_IO_TOUCH_PAD3_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD3_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD3_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD3_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD3_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD3_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD3_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD3_FUN_SEL_M ((RTC_IO_TOUCH_PAD3_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD3_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD3_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD3_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD3_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD3_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD3_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD3_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD3_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD3_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD3_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD3_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD3_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD3_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD3_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD3_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD3_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD3_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD3_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD3_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD3_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD3_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD3_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD3_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD3_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDO*/ -#define RTC_IO_TOUCH_PAD3_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD3_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD3_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD3_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD4_REG (DR_REG_RTCIO_BASE + 0xa4) -/* RTC_IO_TOUCH_PAD4_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD4_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD4_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD4_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD4_HOLD_S 31 -/* RTC_IO_TOUCH_PAD4_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD4_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD4_DRV_M ((RTC_IO_TOUCH_PAD4_DRV_V)<<(RTC_IO_TOUCH_PAD4_DRV_S)) -#define RTC_IO_TOUCH_PAD4_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD4_DRV_S 29 -/* RTC_IO_TOUCH_PAD4_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD4_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD4_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD4_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD4_RDE_S 28 -/* RTC_IO_TOUCH_PAD4_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD4_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD4_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD4_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD4_RUE_S 27 -/* RTC_IO_TOUCH_PAD4_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD4_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD4_DAC_M ((RTC_IO_TOUCH_PAD4_DAC_V)<<(RTC_IO_TOUCH_PAD4_DAC_S)) -#define RTC_IO_TOUCH_PAD4_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD4_DAC_S 23 -/* RTC_IO_TOUCH_PAD4_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD4_START (BIT(22)) -#define RTC_IO_TOUCH_PAD4_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD4_START_V 0x1 -#define RTC_IO_TOUCH_PAD4_START_S 22 -/* RTC_IO_TOUCH_PAD4_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD4_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD4_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD4_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD4_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD4_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD4_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD4_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD4_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD4_XPD_S 20 -/* RTC_IO_TOUCH_PAD4_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD4_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD4_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD4_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD4_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD4_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD4_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD4_FUN_SEL_M ((RTC_IO_TOUCH_PAD4_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD4_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD4_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD4_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD4_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD4_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD4_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD4_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD4_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD4_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD4_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD4_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD4_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD4_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD4_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD4_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD4_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD4_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD4_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD4_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD4_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD4_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD4_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD4_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD4_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTCK*/ -#define RTC_IO_TOUCH_PAD4_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD4_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD4_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD4_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD5_REG (DR_REG_RTCIO_BASE + 0xa8) -/* RTC_IO_TOUCH_PAD5_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD5_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD5_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD5_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD5_HOLD_S 31 -/* RTC_IO_TOUCH_PAD5_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD5_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD5_DRV_M ((RTC_IO_TOUCH_PAD5_DRV_V)<<(RTC_IO_TOUCH_PAD5_DRV_S)) -#define RTC_IO_TOUCH_PAD5_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD5_DRV_S 29 -/* RTC_IO_TOUCH_PAD5_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD5_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD5_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD5_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD5_RDE_S 28 -/* RTC_IO_TOUCH_PAD5_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD5_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD5_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD5_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD5_RUE_S 27 -/* RTC_IO_TOUCH_PAD5_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD5_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD5_DAC_M ((RTC_IO_TOUCH_PAD5_DAC_V)<<(RTC_IO_TOUCH_PAD5_DAC_S)) -#define RTC_IO_TOUCH_PAD5_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD5_DAC_S 23 -/* RTC_IO_TOUCH_PAD5_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD5_START (BIT(22)) -#define RTC_IO_TOUCH_PAD5_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD5_START_V 0x1 -#define RTC_IO_TOUCH_PAD5_START_S 22 -/* RTC_IO_TOUCH_PAD5_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD5_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD5_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD5_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD5_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD5_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD5_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD5_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD5_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD5_XPD_S 20 -/* RTC_IO_TOUCH_PAD5_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD5_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD5_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD5_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD5_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD5_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD5_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD5_FUN_SEL_M ((RTC_IO_TOUCH_PAD5_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD5_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD5_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD5_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD5_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD5_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD5_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD5_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD5_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD5_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD5_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD5_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD5_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD5_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD5_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD5_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD5_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD5_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD5_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD5_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD5_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD5_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD5_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD5_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD5_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDI*/ -#define RTC_IO_TOUCH_PAD5_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD5_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD5_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD5_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD6_REG (DR_REG_RTCIO_BASE + 0xac) -/* RTC_IO_TOUCH_PAD6_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD6_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD6_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD6_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD6_HOLD_S 31 -/* RTC_IO_TOUCH_PAD6_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD6_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD6_DRV_M ((RTC_IO_TOUCH_PAD6_DRV_V)<<(RTC_IO_TOUCH_PAD6_DRV_S)) -#define RTC_IO_TOUCH_PAD6_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD6_DRV_S 29 -/* RTC_IO_TOUCH_PAD6_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD6_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD6_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD6_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD6_RDE_S 28 -/* RTC_IO_TOUCH_PAD6_RUE : R/W ;bitpos:[27] ;default: 1'd1 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD6_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD6_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD6_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD6_RUE_S 27 -/* RTC_IO_TOUCH_PAD6_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD6_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD6_DAC_M ((RTC_IO_TOUCH_PAD6_DAC_V)<<(RTC_IO_TOUCH_PAD6_DAC_S)) -#define RTC_IO_TOUCH_PAD6_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD6_DAC_S 23 -/* RTC_IO_TOUCH_PAD6_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD6_START (BIT(22)) -#define RTC_IO_TOUCH_PAD6_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD6_START_V 0x1 -#define RTC_IO_TOUCH_PAD6_START_S 22 -/* RTC_IO_TOUCH_PAD6_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD6_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD6_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD6_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD6_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD6_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD6_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD6_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD6_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD6_XPD_S 20 -/* RTC_IO_TOUCH_PAD6_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD6_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD6_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD6_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD6_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD6_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD6_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD6_FUN_SEL_M ((RTC_IO_TOUCH_PAD6_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD6_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD6_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD6_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD6_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD6_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD6_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD6_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD6_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD6_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD6_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD6_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD6_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD6_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD6_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD6_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD6_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD6_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD6_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD6_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD6_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD6_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD6_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD6_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD6_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTMS*/ -#define RTC_IO_TOUCH_PAD6_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD6_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD6_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD6_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD7_REG (DR_REG_RTCIO_BASE + 0xb0) -/* RTC_IO_TOUCH_PAD7_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ -/*description: hold the current value of the output when setting the hold to Ò1Ó*/ -#define RTC_IO_TOUCH_PAD7_HOLD (BIT(31)) -#define RTC_IO_TOUCH_PAD7_HOLD_M (BIT(31)) -#define RTC_IO_TOUCH_PAD7_HOLD_V 0x1 -#define RTC_IO_TOUCH_PAD7_HOLD_S 31 -/* RTC_IO_TOUCH_PAD7_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ -/*description: the driver strength of the pad*/ -#define RTC_IO_TOUCH_PAD7_DRV 0x00000003 -#define RTC_IO_TOUCH_PAD7_DRV_M ((RTC_IO_TOUCH_PAD7_DRV_V)<<(RTC_IO_TOUCH_PAD7_DRV_S)) -#define RTC_IO_TOUCH_PAD7_DRV_V 0x3 -#define RTC_IO_TOUCH_PAD7_DRV_S 29 -/* RTC_IO_TOUCH_PAD7_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: the pull down enable of the pad*/ -#define RTC_IO_TOUCH_PAD7_RDE (BIT(28)) -#define RTC_IO_TOUCH_PAD7_RDE_M (BIT(28)) -#define RTC_IO_TOUCH_PAD7_RDE_V 0x1 -#define RTC_IO_TOUCH_PAD7_RDE_S 28 -/* RTC_IO_TOUCH_PAD7_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: the pull up enable of the pad*/ -#define RTC_IO_TOUCH_PAD7_RUE (BIT(27)) -#define RTC_IO_TOUCH_PAD7_RUE_M (BIT(27)) -#define RTC_IO_TOUCH_PAD7_RUE_V 0x1 -#define RTC_IO_TOUCH_PAD7_RUE_S 27 -/* RTC_IO_TOUCH_PAD7_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD7_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD7_DAC_M ((RTC_IO_TOUCH_PAD7_DAC_V)<<(RTC_IO_TOUCH_PAD7_DAC_S)) -#define RTC_IO_TOUCH_PAD7_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD7_DAC_S 23 -/* RTC_IO_TOUCH_PAD7_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD7_START (BIT(22)) -#define RTC_IO_TOUCH_PAD7_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD7_START_V 0x1 -#define RTC_IO_TOUCH_PAD7_START_S 22 -/* RTC_IO_TOUCH_PAD7_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD7_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD7_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD7_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD7_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD7_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD7_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD7_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD7_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD7_XPD_S 20 -/* RTC_IO_TOUCH_PAD7_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ -#define RTC_IO_TOUCH_PAD7_MUX_SEL (BIT(19)) -#define RTC_IO_TOUCH_PAD7_MUX_SEL_M (BIT(19)) -#define RTC_IO_TOUCH_PAD7_MUX_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD7_MUX_SEL_S 19 -/* RTC_IO_TOUCH_PAD7_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ -/*description: the functional selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD7_FUN_SEL 0x00000003 -#define RTC_IO_TOUCH_PAD7_FUN_SEL_M ((RTC_IO_TOUCH_PAD7_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD7_FUN_SEL_S)) -#define RTC_IO_TOUCH_PAD7_FUN_SEL_V 0x3 -#define RTC_IO_TOUCH_PAD7_FUN_SEL_S 17 -/* RTC_IO_TOUCH_PAD7_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ -/*description: the sleep status selection signal of the pad*/ -#define RTC_IO_TOUCH_PAD7_SLP_SEL (BIT(16)) -#define RTC_IO_TOUCH_PAD7_SLP_SEL_M (BIT(16)) -#define RTC_IO_TOUCH_PAD7_SLP_SEL_V 0x1 -#define RTC_IO_TOUCH_PAD7_SLP_SEL_S 16 -/* RTC_IO_TOUCH_PAD7_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ -/*description: the input enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD7_SLP_IE (BIT(15)) -#define RTC_IO_TOUCH_PAD7_SLP_IE_M (BIT(15)) -#define RTC_IO_TOUCH_PAD7_SLP_IE_V 0x1 -#define RTC_IO_TOUCH_PAD7_SLP_IE_S 15 -/* RTC_IO_TOUCH_PAD7_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ -/*description: the output enable of the pad in sleep status*/ -#define RTC_IO_TOUCH_PAD7_SLP_OE (BIT(14)) -#define RTC_IO_TOUCH_PAD7_SLP_OE_M (BIT(14)) -#define RTC_IO_TOUCH_PAD7_SLP_OE_V 0x1 -#define RTC_IO_TOUCH_PAD7_SLP_OE_S 14 -/* RTC_IO_TOUCH_PAD7_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ -/*description: the input enable of the pad*/ -#define RTC_IO_TOUCH_PAD7_FUN_IE (BIT(13)) -#define RTC_IO_TOUCH_PAD7_FUN_IE_M (BIT(13)) -#define RTC_IO_TOUCH_PAD7_FUN_IE_V 0x1 -#define RTC_IO_TOUCH_PAD7_FUN_IE_S 13 -/* RTC_IO_TOUCH_PAD7_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO27*/ -#define RTC_IO_TOUCH_PAD7_TO_GPIO (BIT(12)) -#define RTC_IO_TOUCH_PAD7_TO_GPIO_M (BIT(12)) -#define RTC_IO_TOUCH_PAD7_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD7_TO_GPIO_S 12 - -#define RTC_IO_TOUCH_PAD8_REG (DR_REG_RTCIO_BASE + 0xb4) -/* RTC_IO_TOUCH_PAD8_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD8_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD8_DAC_M ((RTC_IO_TOUCH_PAD8_DAC_V)<<(RTC_IO_TOUCH_PAD8_DAC_S)) -#define RTC_IO_TOUCH_PAD8_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD8_DAC_S 23 -/* RTC_IO_TOUCH_PAD8_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD8_START (BIT(22)) -#define RTC_IO_TOUCH_PAD8_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD8_START_V 0x1 -#define RTC_IO_TOUCH_PAD8_START_S 22 -/* RTC_IO_TOUCH_PAD8_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD8_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD8_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD8_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD8_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD8_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD8_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD8_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD8_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD8_XPD_S 20 -/* RTC_IO_TOUCH_PAD8_TO_GPIO : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale*/ -#define RTC_IO_TOUCH_PAD8_TO_GPIO (BIT(19)) -#define RTC_IO_TOUCH_PAD8_TO_GPIO_M (BIT(19)) -#define RTC_IO_TOUCH_PAD8_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD8_TO_GPIO_S 19 - -#define RTC_IO_TOUCH_PAD9_REG (DR_REG_RTCIO_BASE + 0xb8) -/* RTC_IO_TOUCH_PAD9_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ -/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ -#define RTC_IO_TOUCH_PAD9_DAC 0x00000007 -#define RTC_IO_TOUCH_PAD9_DAC_M ((RTC_IO_TOUCH_PAD9_DAC_V)<<(RTC_IO_TOUCH_PAD9_DAC_S)) -#define RTC_IO_TOUCH_PAD9_DAC_V 0x7 -#define RTC_IO_TOUCH_PAD9_DAC_S 23 -/* RTC_IO_TOUCH_PAD9_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ -/*description: start touch sensor.*/ -#define RTC_IO_TOUCH_PAD9_START (BIT(22)) -#define RTC_IO_TOUCH_PAD9_START_M (BIT(22)) -#define RTC_IO_TOUCH_PAD9_START_V 0x1 -#define RTC_IO_TOUCH_PAD9_START_S 22 -/* RTC_IO_TOUCH_PAD9_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ -/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ -#define RTC_IO_TOUCH_PAD9_TIE_OPT (BIT(21)) -#define RTC_IO_TOUCH_PAD9_TIE_OPT_M (BIT(21)) -#define RTC_IO_TOUCH_PAD9_TIE_OPT_V 0x1 -#define RTC_IO_TOUCH_PAD9_TIE_OPT_S 21 -/* RTC_IO_TOUCH_PAD9_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ -/*description: touch sensor power on.*/ -#define RTC_IO_TOUCH_PAD9_XPD (BIT(20)) -#define RTC_IO_TOUCH_PAD9_XPD_M (BIT(20)) -#define RTC_IO_TOUCH_PAD9_XPD_V 0x1 -#define RTC_IO_TOUCH_PAD9_XPD_S 20 -/* RTC_IO_TOUCH_PAD9_TO_GPIO : R/W ;bitpos:[19] ;default: 1'd0 ; */ -/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale*/ -#define RTC_IO_TOUCH_PAD9_TO_GPIO (BIT(19)) -#define RTC_IO_TOUCH_PAD9_TO_GPIO_M (BIT(19)) -#define RTC_IO_TOUCH_PAD9_TO_GPIO_V 0x1 -#define RTC_IO_TOUCH_PAD9_TO_GPIO_S 19 - -#define RTC_IO_EXT_WAKEUP0_REG (DR_REG_RTCIO_BASE + 0xbc) -/* RTC_IO_EXT_WAKEUP0_SEL : R/W ;bitpos:[31:27] ;default: 5'd0 ; */ -/*description: select the wakeup source Ó0Ó select GPIO0 Ó1Ó select GPIO2 ...Ò17Ó select GPIO17*/ -#define RTC_IO_EXT_WAKEUP0_SEL 0x0000001F -#define RTC_IO_EXT_WAKEUP0_SEL_M ((RTC_IO_EXT_WAKEUP0_SEL_V)<<(RTC_IO_EXT_WAKEUP0_SEL_S)) -#define RTC_IO_EXT_WAKEUP0_SEL_V 0x1F -#define RTC_IO_EXT_WAKEUP0_SEL_S 27 - -#define RTC_IO_XTL_EXT_CTR_REG (DR_REG_RTCIO_BASE + 0xc0) -/* RTC_IO_XTL_EXT_CTR_SEL : R/W ;bitpos:[31:27] ;default: 5'd0 ; */ -/*description: select the external xtl power source Ó0Ó select GPIO0 Ó1Ó select - GPIO2 ...Ò17Ó select GPIO17*/ -#define RTC_IO_XTL_EXT_CTR_SEL 0x0000001F -#define RTC_IO_XTL_EXT_CTR_SEL_M ((RTC_IO_XTL_EXT_CTR_SEL_V)<<(RTC_IO_XTL_EXT_CTR_SEL_S)) -#define RTC_IO_XTL_EXT_CTR_SEL_V 0x1F -#define RTC_IO_XTL_EXT_CTR_SEL_S 27 - -#define RTC_IO_SAR_I2C_IO_REG (DR_REG_RTCIO_BASE + 0xc4) -/* RTC_IO_SAR_I2C_SDA_SEL : R/W ;bitpos:[31:30] ;default: 2'd0 ; */ -/*description: Ò0Ó using TOUCH_PAD[1] as i2c sda Ò1Ó using TOUCH_PAD[3] as i2c sda*/ -#define RTC_IO_SAR_I2C_SDA_SEL 0x00000003 -#define RTC_IO_SAR_I2C_SDA_SEL_M ((RTC_IO_SAR_I2C_SDA_SEL_V)<<(RTC_IO_SAR_I2C_SDA_SEL_S)) -#define RTC_IO_SAR_I2C_SDA_SEL_V 0x3 -#define RTC_IO_SAR_I2C_SDA_SEL_S 30 -/* RTC_IO_SAR_I2C_SCL_SEL : R/W ;bitpos:[29:28] ;default: 2'd0 ; */ -/*description: Ò0Ó using TOUCH_PAD[0] as i2c clk Ò1Ó using TOUCH_PAD[2] as i2c clk*/ -#define RTC_IO_SAR_I2C_SCL_SEL 0x00000003 -#define RTC_IO_SAR_I2C_SCL_SEL_M ((RTC_IO_SAR_I2C_SCL_SEL_V)<<(RTC_IO_SAR_I2C_SCL_SEL_S)) -#define RTC_IO_SAR_I2C_SCL_SEL_V 0x3 -#define RTC_IO_SAR_I2C_SCL_SEL_S 28 -/* RTC_IO_SAR_DEBUG_BIT_SEL : R/W ;bitpos:[27:23] ;default: 5'h0 ; */ -/*description: */ -#define RTC_IO_SAR_DEBUG_BIT_SEL 0x0000001F -#define RTC_IO_SAR_DEBUG_BIT_SEL_M ((RTC_IO_SAR_DEBUG_BIT_SEL_V)<<(RTC_IO_SAR_DEBUG_BIT_SEL_S)) -#define RTC_IO_SAR_DEBUG_BIT_SEL_V 0x1F -#define RTC_IO_SAR_DEBUG_BIT_SEL_S 23 - -#define RTC_IO_DATE_REG (DR_REG_RTCIO_BASE + 0xc8) -/* RTC_IO_IO_DATE : R/W ;bitpos:[27:0] ;default: 28'h1603160 ; */ -/*description: date*/ -#define RTC_IO_IO_DATE 0x0FFFFFFF -#define RTC_IO_IO_DATE_M ((RTC_IO_IO_DATE_V)<<(RTC_IO_IO_DATE_S)) -#define RTC_IO_IO_DATE_V 0xFFFFFFF -#define RTC_IO_IO_DATE_S 0 -#define RTC_IO_RTC_IO_DATE_VERSION 0x1703160 - - - - -#endif /*_SOC_RTC_IO_REG_H_ */ - - +// 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 _SOC_RTC_IO_REG_H_ +#define _SOC_RTC_IO_REG_H_ + + +#include "soc.h" +#define RTC_GPIO_OUT_REG (DR_REG_RTCIO_BASE + 0x0) +/* RTC_GPIO_OUT_DATA : R/W ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 output value*/ +#define RTC_GPIO_OUT_DATA 0x0003FFFF +#define RTC_GPIO_OUT_DATA_M ((RTC_GPIO_OUT_DATA_V)<<(RTC_GPIO_OUT_DATA_S)) +#define RTC_GPIO_OUT_DATA_V 0x3FFFF +#define RTC_GPIO_OUT_DATA_S 14 + +#define RTC_GPIO_OUT_W1TS_REG (DR_REG_RTCIO_BASE + 0x4) +/* RTC_GPIO_OUT_DATA_W1TS : WO ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 output value write 1 to set*/ +#define RTC_GPIO_OUT_DATA_W1TS 0x0003FFFF +#define RTC_GPIO_OUT_DATA_W1TS_M ((RTC_GPIO_OUT_DATA_W1TS_V)<<(RTC_GPIO_OUT_DATA_W1TS_S)) +#define RTC_GPIO_OUT_DATA_W1TS_V 0x3FFFF +#define RTC_GPIO_OUT_DATA_W1TS_S 14 + +#define RTC_GPIO_OUT_W1TC_REG (DR_REG_RTCIO_BASE + 0x8) +/* RTC_GPIO_OUT_DATA_W1TC : WO ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 output value write 1 to clear*/ +#define RTC_GPIO_OUT_DATA_W1TC 0x0003FFFF +#define RTC_GPIO_OUT_DATA_W1TC_M ((RTC_GPIO_OUT_DATA_W1TC_V)<<(RTC_GPIO_OUT_DATA_W1TC_S)) +#define RTC_GPIO_OUT_DATA_W1TC_V 0x3FFFF +#define RTC_GPIO_OUT_DATA_W1TC_S 14 + +#define RTC_GPIO_ENABLE_REG (DR_REG_RTCIO_BASE + 0xc) +/* RTC_GPIO_ENABLE : R/W ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 output enable*/ +#define RTC_GPIO_ENABLE 0x0003FFFF +#define RTC_GPIO_ENABLE_M ((RTC_GPIO_ENABLE_V)<<(RTC_GPIO_ENABLE_S)) +#define RTC_GPIO_ENABLE_V 0x3FFFF +#define RTC_GPIO_ENABLE_S 14 + +#define RTC_GPIO_ENABLE_W1TS_REG (DR_REG_RTCIO_BASE + 0x10) +/* RTC_GPIO_ENABLE_W1TS : WO ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 output enable write 1 to set*/ +#define RTC_GPIO_ENABLE_W1TS 0x0003FFFF +#define RTC_GPIO_ENABLE_W1TS_M ((RTC_GPIO_ENABLE_W1TS_V)<<(RTC_GPIO_ENABLE_W1TS_S)) +#define RTC_GPIO_ENABLE_W1TS_V 0x3FFFF +#define RTC_GPIO_ENABLE_W1TS_S 14 + +#define RTC_GPIO_ENABLE_W1TC_REG (DR_REG_RTCIO_BASE + 0x14) +/* RTC_GPIO_ENABLE_W1TC : WO ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 output enable write 1 to clear*/ +#define RTC_GPIO_ENABLE_W1TC 0x0003FFFF +#define RTC_GPIO_ENABLE_W1TC_M ((RTC_GPIO_ENABLE_W1TC_V)<<(RTC_GPIO_ENABLE_W1TC_S)) +#define RTC_GPIO_ENABLE_W1TC_V 0x3FFFF +#define RTC_GPIO_ENABLE_W1TC_S 14 + +#define RTC_GPIO_STATUS_REG (DR_REG_RTCIO_BASE + 0x18) +/* RTC_GPIO_STATUS_INT : R/W ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 interrupt status*/ +#define RTC_GPIO_STATUS_INT 0x0003FFFF +#define RTC_GPIO_STATUS_INT_M ((RTC_GPIO_STATUS_INT_V)<<(RTC_GPIO_STATUS_INT_S)) +#define RTC_GPIO_STATUS_INT_V 0x3FFFF +#define RTC_GPIO_STATUS_INT_S 14 + +#define RTC_GPIO_STATUS_W1TS_REG (DR_REG_RTCIO_BASE + 0x1c) +/* RTC_GPIO_STATUS_INT_W1TS : WO ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 interrupt status write 1 to set*/ +#define RTC_GPIO_STATUS_INT_W1TS 0x0003FFFF +#define RTC_GPIO_STATUS_INT_W1TS_M ((RTC_GPIO_STATUS_INT_W1TS_V)<<(RTC_GPIO_STATUS_INT_W1TS_S)) +#define RTC_GPIO_STATUS_INT_W1TS_V 0x3FFFF +#define RTC_GPIO_STATUS_INT_W1TS_S 14 + +#define RTC_GPIO_STATUS_W1TC_REG (DR_REG_RTCIO_BASE + 0x20) +/* RTC_GPIO_STATUS_INT_W1TC : WO ;bitpos:[31:14] ;default: 0 ; */ +/*description: GPIO0~17 interrupt status write 1 to clear*/ +#define RTC_GPIO_STATUS_INT_W1TC 0x0003FFFF +#define RTC_GPIO_STATUS_INT_W1TC_M ((RTC_GPIO_STATUS_INT_W1TC_V)<<(RTC_GPIO_STATUS_INT_W1TC_S)) +#define RTC_GPIO_STATUS_INT_W1TC_V 0x3FFFF +#define RTC_GPIO_STATUS_INT_W1TC_S 14 + +#define RTC_GPIO_IN_REG (DR_REG_RTCIO_BASE + 0x24) +/* RTC_GPIO_IN_NEXT : RO ;bitpos:[31:14] ;default: ; */ +/*description: GPIO0~17 input value*/ +#define RTC_GPIO_IN_NEXT 0x0003FFFF +#define RTC_GPIO_IN_NEXT_M ((RTC_GPIO_IN_NEXT_V)<<(RTC_GPIO_IN_NEXT_S)) +#define RTC_GPIO_IN_NEXT_V 0x3FFFF +#define RTC_GPIO_IN_NEXT_S 14 + +#define RTC_GPIO_PIN0_REG (DR_REG_RTCIO_BASE + 0x28) +/* RTC_GPIO_PIN0_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN0_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN0_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN0_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN0_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN0_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN0_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN0_INT_TYPE_M ((RTC_GPIO_PIN0_INT_TYPE_V)<<(RTC_GPIO_PIN0_INT_TYPE_S)) +#define RTC_GPIO_PIN0_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN0_INT_TYPE_S 7 +/* RTC_GPIO_PIN0_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN0_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN0_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN0_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN0_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN1_REG (DR_REG_RTCIO_BASE + 0x2c) +/* RTC_GPIO_PIN1_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN1_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN1_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN1_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN1_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN1_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN1_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN1_INT_TYPE_M ((RTC_GPIO_PIN1_INT_TYPE_V)<<(RTC_GPIO_PIN1_INT_TYPE_S)) +#define RTC_GPIO_PIN1_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN1_INT_TYPE_S 7 +/* RTC_GPIO_PIN1_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN1_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN1_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN1_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN1_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN2_REG (DR_REG_RTCIO_BASE + 0x30) +/* RTC_GPIO_PIN2_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN2_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN2_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN2_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN2_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN2_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN2_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN2_INT_TYPE_M ((RTC_GPIO_PIN2_INT_TYPE_V)<<(RTC_GPIO_PIN2_INT_TYPE_S)) +#define RTC_GPIO_PIN2_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN2_INT_TYPE_S 7 +/* RTC_GPIO_PIN2_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN2_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN2_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN2_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN2_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN3_REG (DR_REG_RTCIO_BASE + 0x34) +/* RTC_GPIO_PIN3_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN3_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN3_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN3_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN3_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN3_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN3_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN3_INT_TYPE_M ((RTC_GPIO_PIN3_INT_TYPE_V)<<(RTC_GPIO_PIN3_INT_TYPE_S)) +#define RTC_GPIO_PIN3_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN3_INT_TYPE_S 7 +/* RTC_GPIO_PIN3_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN3_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN3_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN3_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN3_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN4_REG (DR_REG_RTCIO_BASE + 0x38) +/* RTC_GPIO_PIN4_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN4_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN4_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN4_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN4_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN4_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN4_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN4_INT_TYPE_M ((RTC_GPIO_PIN4_INT_TYPE_V)<<(RTC_GPIO_PIN4_INT_TYPE_S)) +#define RTC_GPIO_PIN4_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN4_INT_TYPE_S 7 +/* RTC_GPIO_PIN4_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN4_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN4_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN4_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN4_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN5_REG (DR_REG_RTCIO_BASE + 0x3c) +/* RTC_GPIO_PIN5_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN5_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN5_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN5_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN5_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN5_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN5_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN5_INT_TYPE_M ((RTC_GPIO_PIN5_INT_TYPE_V)<<(RTC_GPIO_PIN5_INT_TYPE_S)) +#define RTC_GPIO_PIN5_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN5_INT_TYPE_S 7 +/* RTC_GPIO_PIN5_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN5_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN5_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN5_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN5_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN6_REG (DR_REG_RTCIO_BASE + 0x40) +/* RTC_GPIO_PIN6_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN6_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN6_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN6_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN6_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN6_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN6_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN6_INT_TYPE_M ((RTC_GPIO_PIN6_INT_TYPE_V)<<(RTC_GPIO_PIN6_INT_TYPE_S)) +#define RTC_GPIO_PIN6_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN6_INT_TYPE_S 7 +/* RTC_GPIO_PIN6_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN6_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN6_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN6_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN6_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN7_REG (DR_REG_RTCIO_BASE + 0x44) +/* RTC_GPIO_PIN7_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN7_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN7_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN7_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN7_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN7_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN7_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN7_INT_TYPE_M ((RTC_GPIO_PIN7_INT_TYPE_V)<<(RTC_GPIO_PIN7_INT_TYPE_S)) +#define RTC_GPIO_PIN7_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN7_INT_TYPE_S 7 +/* RTC_GPIO_PIN7_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN7_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN7_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN7_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN7_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN8_REG (DR_REG_RTCIO_BASE + 0x48) +/* RTC_GPIO_PIN8_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN8_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN8_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN8_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN8_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN8_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN8_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN8_INT_TYPE_M ((RTC_GPIO_PIN8_INT_TYPE_V)<<(RTC_GPIO_PIN8_INT_TYPE_S)) +#define RTC_GPIO_PIN8_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN8_INT_TYPE_S 7 +/* RTC_GPIO_PIN8_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN8_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN8_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN8_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN8_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN9_REG (DR_REG_RTCIO_BASE + 0x4c) +/* RTC_GPIO_PIN9_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN9_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN9_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN9_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN9_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN9_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN9_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN9_INT_TYPE_M ((RTC_GPIO_PIN9_INT_TYPE_V)<<(RTC_GPIO_PIN9_INT_TYPE_S)) +#define RTC_GPIO_PIN9_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN9_INT_TYPE_S 7 +/* RTC_GPIO_PIN9_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN9_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN9_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN9_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN9_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN10_REG (DR_REG_RTCIO_BASE + 0x50) +/* RTC_GPIO_PIN10_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN10_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN10_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN10_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN10_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN10_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN10_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN10_INT_TYPE_M ((RTC_GPIO_PIN10_INT_TYPE_V)<<(RTC_GPIO_PIN10_INT_TYPE_S)) +#define RTC_GPIO_PIN10_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN10_INT_TYPE_S 7 +/* RTC_GPIO_PIN10_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN10_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN10_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN10_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN10_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN11_REG (DR_REG_RTCIO_BASE + 0x54) +/* RTC_GPIO_PIN11_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN11_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN11_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN11_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN11_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN11_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN11_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN11_INT_TYPE_M ((RTC_GPIO_PIN11_INT_TYPE_V)<<(RTC_GPIO_PIN11_INT_TYPE_S)) +#define RTC_GPIO_PIN11_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN11_INT_TYPE_S 7 +/* RTC_GPIO_PIN11_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN11_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN11_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN11_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN11_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN12_REG (DR_REG_RTCIO_BASE + 0x58) +/* RTC_GPIO_PIN12_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN12_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN12_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN12_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN12_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN12_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN12_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN12_INT_TYPE_M ((RTC_GPIO_PIN12_INT_TYPE_V)<<(RTC_GPIO_PIN12_INT_TYPE_S)) +#define RTC_GPIO_PIN12_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN12_INT_TYPE_S 7 +/* RTC_GPIO_PIN12_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN12_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN12_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN12_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN12_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN13_REG (DR_REG_RTCIO_BASE + 0x5c) +/* RTC_GPIO_PIN13_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN13_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN13_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN13_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN13_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN13_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN13_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN13_INT_TYPE_M ((RTC_GPIO_PIN13_INT_TYPE_V)<<(RTC_GPIO_PIN13_INT_TYPE_S)) +#define RTC_GPIO_PIN13_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN13_INT_TYPE_S 7 +/* RTC_GPIO_PIN13_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN13_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN13_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN13_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN13_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN14_REG (DR_REG_RTCIO_BASE + 0x60) +/* RTC_GPIO_PIN14_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN14_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN14_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN14_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN14_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN14_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN14_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN14_INT_TYPE_M ((RTC_GPIO_PIN14_INT_TYPE_V)<<(RTC_GPIO_PIN14_INT_TYPE_S)) +#define RTC_GPIO_PIN14_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN14_INT_TYPE_S 7 +/* RTC_GPIO_PIN14_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN14_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN14_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN14_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN14_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN15_REG (DR_REG_RTCIO_BASE + 0x64) +/* RTC_GPIO_PIN15_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN15_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN15_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN15_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN15_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN15_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN15_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN15_INT_TYPE_M ((RTC_GPIO_PIN15_INT_TYPE_V)<<(RTC_GPIO_PIN15_INT_TYPE_S)) +#define RTC_GPIO_PIN15_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN15_INT_TYPE_S 7 +/* RTC_GPIO_PIN15_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN15_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN15_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN15_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN15_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN16_REG (DR_REG_RTCIO_BASE + 0x68) +/* RTC_GPIO_PIN16_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN16_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN16_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN16_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN16_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN16_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN16_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN16_INT_TYPE_M ((RTC_GPIO_PIN16_INT_TYPE_V)<<(RTC_GPIO_PIN16_INT_TYPE_S)) +#define RTC_GPIO_PIN16_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN16_INT_TYPE_S 7 +/* RTC_GPIO_PIN16_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN16_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN16_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN16_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN16_PAD_DRIVER_S 2 + +#define RTC_GPIO_PIN17_REG (DR_REG_RTCIO_BASE + 0x6c) +/* RTC_GPIO_PIN17_WAKEUP_ENABLE : R/W ;bitpos:[10] ;default: 0 ; */ +/*description: GPIO wake up enable only available in light sleep*/ +#define RTC_GPIO_PIN17_WAKEUP_ENABLE (BIT(10)) +#define RTC_GPIO_PIN17_WAKEUP_ENABLE_M (BIT(10)) +#define RTC_GPIO_PIN17_WAKEUP_ENABLE_V 0x1 +#define RTC_GPIO_PIN17_WAKEUP_ENABLE_S 10 +/* RTC_GPIO_PIN17_INT_TYPE : R/W ;bitpos:[9:7] ;default: 0 ; */ +/*description: if set to 0: GPIO interrupt disable if set to 1: rising edge + trigger if set to 2: falling edge trigger if set to 3: any edge trigger if set to 4: low level trigger if set to 5: high level trigger*/ +#define RTC_GPIO_PIN17_INT_TYPE 0x00000007 +#define RTC_GPIO_PIN17_INT_TYPE_M ((RTC_GPIO_PIN17_INT_TYPE_V)<<(RTC_GPIO_PIN17_INT_TYPE_S)) +#define RTC_GPIO_PIN17_INT_TYPE_V 0x7 +#define RTC_GPIO_PIN17_INT_TYPE_S 7 +/* RTC_GPIO_PIN17_PAD_DRIVER : R/W ;bitpos:[2] ;default: 0 ; */ +/*description: if set to 0: normal output if set to 1: open drain*/ +#define RTC_GPIO_PIN17_PAD_DRIVER (BIT(2)) +#define RTC_GPIO_PIN17_PAD_DRIVER_M (BIT(2)) +#define RTC_GPIO_PIN17_PAD_DRIVER_V 0x1 +#define RTC_GPIO_PIN17_PAD_DRIVER_S 2 + +#define RTC_IO_RTC_DEBUG_SEL_REG (DR_REG_RTCIO_BASE + 0x70) +/* RTC_IO_DEBUG_12M_NO_GATING : R/W ;bitpos:[25] ;default: 1'd0 ; */ +/*description: */ +#define RTC_IO_DEBUG_12M_NO_GATING (BIT(25)) +#define RTC_IO_DEBUG_12M_NO_GATING_M (BIT(25)) +#define RTC_IO_DEBUG_12M_NO_GATING_V 0x1 +#define RTC_IO_DEBUG_12M_NO_GATING_S 25 +/* RTC_IO_DEBUG_SEL4 : R/W ;bitpos:[24:20] ;default: 5'd0 ; */ +/*description: */ +#define RTC_IO_DEBUG_SEL4 0x0000001F +#define RTC_IO_DEBUG_SEL4_M ((RTC_IO_DEBUG_SEL4_V)<<(RTC_IO_DEBUG_SEL4_S)) +#define RTC_IO_DEBUG_SEL4_V 0x1F +#define RTC_IO_DEBUG_SEL4_S 20 +/* RTC_IO_DEBUG_SEL3 : R/W ;bitpos:[19:15] ;default: 5'd0 ; */ +/*description: */ +#define RTC_IO_DEBUG_SEL3 0x0000001F +#define RTC_IO_DEBUG_SEL3_M ((RTC_IO_DEBUG_SEL3_V)<<(RTC_IO_DEBUG_SEL3_S)) +#define RTC_IO_DEBUG_SEL3_V 0x1F +#define RTC_IO_DEBUG_SEL3_S 15 +/* RTC_IO_DEBUG_SEL2 : R/W ;bitpos:[14:10] ;default: 5'd0 ; */ +/*description: */ +#define RTC_IO_DEBUG_SEL2 0x0000001F +#define RTC_IO_DEBUG_SEL2_M ((RTC_IO_DEBUG_SEL2_V)<<(RTC_IO_DEBUG_SEL2_S)) +#define RTC_IO_DEBUG_SEL2_V 0x1F +#define RTC_IO_DEBUG_SEL2_S 10 +/* RTC_IO_DEBUG_SEL1 : R/W ;bitpos:[9:5] ;default: 5'd0 ; */ +/*description: */ +#define RTC_IO_DEBUG_SEL1 0x0000001F +#define RTC_IO_DEBUG_SEL1_M ((RTC_IO_DEBUG_SEL1_V)<<(RTC_IO_DEBUG_SEL1_S)) +#define RTC_IO_DEBUG_SEL1_V 0x1F +#define RTC_IO_DEBUG_SEL1_S 5 +/* RTC_IO_DEBUG_SEL0 : R/W ;bitpos:[4:0] ;default: 5'd0 ; */ +/*description: */ +#define RTC_IO_DEBUG_SEL0 0x0000001F +#define RTC_IO_DEBUG_SEL0_M ((RTC_IO_DEBUG_SEL0_V)<<(RTC_IO_DEBUG_SEL0_S)) +#define RTC_IO_DEBUG_SEL0_V 0x1F +#define RTC_IO_DEBUG_SEL0_S 0 + +#define RTC_IO_DIG_PAD_HOLD_REG (DR_REG_RTCIO_BASE + 0x74) +/* RTC_IO_DIG_PAD_HOLD : R/W ;bitpos:[31:0] ;default: 1'd0 ; */ +/*description: select the digital pad hold value.*/ +#define RTC_IO_DIG_PAD_HOLD 0xFFFFFFFF +#define RTC_IO_DIG_PAD_HOLD_M ((RTC_IO_DIG_PAD_HOLD_V)<<(RTC_IO_DIG_PAD_HOLD_S)) +#define RTC_IO_DIG_PAD_HOLD_V 0xFFFFFFFF +#define RTC_IO_DIG_PAD_HOLD_S 0 + +#define RTC_IO_HALL_SENS_REG (DR_REG_RTCIO_BASE + 0x78) +/* RTC_IO_XPD_HALL : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: Power on hall sensor and connect to VP and VN*/ +#define RTC_IO_XPD_HALL (BIT(31)) +#define RTC_IO_XPD_HALL_M (BIT(31)) +#define RTC_IO_XPD_HALL_V 0x1 +#define RTC_IO_XPD_HALL_S 31 +/* RTC_IO_HALL_PHASE : R/W ;bitpos:[30] ;default: 1'd0 ; */ +/*description: Reverse phase of hall sensor*/ +#define RTC_IO_HALL_PHASE (BIT(30)) +#define RTC_IO_HALL_PHASE_M (BIT(30)) +#define RTC_IO_HALL_PHASE_V 0x1 +#define RTC_IO_HALL_PHASE_S 30 + +#define RTC_IO_SENSOR_PADS_REG (DR_REG_RTCIO_BASE + 0x7c) +/* RTC_IO_SENSE1_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_SENSE1_HOLD (BIT(31)) +#define RTC_IO_SENSE1_HOLD_M (BIT(31)) +#define RTC_IO_SENSE1_HOLD_V 0x1 +#define RTC_IO_SENSE1_HOLD_S 31 +/* RTC_IO_SENSE2_HOLD : R/W ;bitpos:[30] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_SENSE2_HOLD (BIT(30)) +#define RTC_IO_SENSE2_HOLD_M (BIT(30)) +#define RTC_IO_SENSE2_HOLD_V 0x1 +#define RTC_IO_SENSE2_HOLD_S 30 +/* RTC_IO_SENSE3_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_SENSE3_HOLD (BIT(29)) +#define RTC_IO_SENSE3_HOLD_M (BIT(29)) +#define RTC_IO_SENSE3_HOLD_V 0x1 +#define RTC_IO_SENSE3_HOLD_S 29 +/* RTC_IO_SENSE4_HOLD : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_SENSE4_HOLD (BIT(28)) +#define RTC_IO_SENSE4_HOLD_M (BIT(28)) +#define RTC_IO_SENSE4_HOLD_V 0x1 +#define RTC_IO_SENSE4_HOLD_S 28 +/* RTC_IO_SENSE1_MUX_SEL : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_SENSE1_MUX_SEL (BIT(27)) +#define RTC_IO_SENSE1_MUX_SEL_M (BIT(27)) +#define RTC_IO_SENSE1_MUX_SEL_V 0x1 +#define RTC_IO_SENSE1_MUX_SEL_S 27 +/* RTC_IO_SENSE2_MUX_SEL : R/W ;bitpos:[26] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_SENSE2_MUX_SEL (BIT(26)) +#define RTC_IO_SENSE2_MUX_SEL_M (BIT(26)) +#define RTC_IO_SENSE2_MUX_SEL_V 0x1 +#define RTC_IO_SENSE2_MUX_SEL_S 26 +/* RTC_IO_SENSE3_MUX_SEL : R/W ;bitpos:[25] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_SENSE3_MUX_SEL (BIT(25)) +#define RTC_IO_SENSE3_MUX_SEL_M (BIT(25)) +#define RTC_IO_SENSE3_MUX_SEL_V 0x1 +#define RTC_IO_SENSE3_MUX_SEL_S 25 +/* RTC_IO_SENSE4_MUX_SEL : R/W ;bitpos:[24] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_SENSE4_MUX_SEL (BIT(24)) +#define RTC_IO_SENSE4_MUX_SEL_M (BIT(24)) +#define RTC_IO_SENSE4_MUX_SEL_V 0x1 +#define RTC_IO_SENSE4_MUX_SEL_S 24 +/* RTC_IO_SENSE1_FUN_SEL : R/W ;bitpos:[23:22] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_SENSE1_FUN_SEL 0x00000003 +#define RTC_IO_SENSE1_FUN_SEL_M ((RTC_IO_SENSE1_FUN_SEL_V)<<(RTC_IO_SENSE1_FUN_SEL_S)) +#define RTC_IO_SENSE1_FUN_SEL_V 0x3 +#define RTC_IO_SENSE1_FUN_SEL_S 22 +/* RTC_IO_SENSE1_SLP_SEL : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_SENSE1_SLP_SEL (BIT(21)) +#define RTC_IO_SENSE1_SLP_SEL_M (BIT(21)) +#define RTC_IO_SENSE1_SLP_SEL_V 0x1 +#define RTC_IO_SENSE1_SLP_SEL_S 21 +/* RTC_IO_SENSE1_SLP_IE : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_SENSE1_SLP_IE (BIT(20)) +#define RTC_IO_SENSE1_SLP_IE_M (BIT(20)) +#define RTC_IO_SENSE1_SLP_IE_V 0x1 +#define RTC_IO_SENSE1_SLP_IE_S 20 +/* RTC_IO_SENSE1_FUN_IE : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_SENSE1_FUN_IE (BIT(19)) +#define RTC_IO_SENSE1_FUN_IE_M (BIT(19)) +#define RTC_IO_SENSE1_FUN_IE_V 0x1 +#define RTC_IO_SENSE1_FUN_IE_S 19 +/* RTC_IO_SENSE2_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_SENSE2_FUN_SEL 0x00000003 +#define RTC_IO_SENSE2_FUN_SEL_M ((RTC_IO_SENSE2_FUN_SEL_V)<<(RTC_IO_SENSE2_FUN_SEL_S)) +#define RTC_IO_SENSE2_FUN_SEL_V 0x3 +#define RTC_IO_SENSE2_FUN_SEL_S 17 +/* RTC_IO_SENSE2_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_SENSE2_SLP_SEL (BIT(16)) +#define RTC_IO_SENSE2_SLP_SEL_M (BIT(16)) +#define RTC_IO_SENSE2_SLP_SEL_V 0x1 +#define RTC_IO_SENSE2_SLP_SEL_S 16 +/* RTC_IO_SENSE2_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_SENSE2_SLP_IE (BIT(15)) +#define RTC_IO_SENSE2_SLP_IE_M (BIT(15)) +#define RTC_IO_SENSE2_SLP_IE_V 0x1 +#define RTC_IO_SENSE2_SLP_IE_S 15 +/* RTC_IO_SENSE2_FUN_IE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_SENSE2_FUN_IE (BIT(14)) +#define RTC_IO_SENSE2_FUN_IE_M (BIT(14)) +#define RTC_IO_SENSE2_FUN_IE_V 0x1 +#define RTC_IO_SENSE2_FUN_IE_S 14 +/* RTC_IO_SENSE3_FUN_SEL : R/W ;bitpos:[13:12] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_SENSE3_FUN_SEL 0x00000003 +#define RTC_IO_SENSE3_FUN_SEL_M ((RTC_IO_SENSE3_FUN_SEL_V)<<(RTC_IO_SENSE3_FUN_SEL_S)) +#define RTC_IO_SENSE3_FUN_SEL_V 0x3 +#define RTC_IO_SENSE3_FUN_SEL_S 12 +/* RTC_IO_SENSE3_SLP_SEL : R/W ;bitpos:[11] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_SENSE3_SLP_SEL (BIT(11)) +#define RTC_IO_SENSE3_SLP_SEL_M (BIT(11)) +#define RTC_IO_SENSE3_SLP_SEL_V 0x1 +#define RTC_IO_SENSE3_SLP_SEL_S 11 +/* RTC_IO_SENSE3_SLP_IE : R/W ;bitpos:[10] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_SENSE3_SLP_IE (BIT(10)) +#define RTC_IO_SENSE3_SLP_IE_M (BIT(10)) +#define RTC_IO_SENSE3_SLP_IE_V 0x1 +#define RTC_IO_SENSE3_SLP_IE_S 10 +/* RTC_IO_SENSE3_FUN_IE : R/W ;bitpos:[9] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_SENSE3_FUN_IE (BIT(9)) +#define RTC_IO_SENSE3_FUN_IE_M (BIT(9)) +#define RTC_IO_SENSE3_FUN_IE_V 0x1 +#define RTC_IO_SENSE3_FUN_IE_S 9 +/* RTC_IO_SENSE4_FUN_SEL : R/W ;bitpos:[8:7] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_SENSE4_FUN_SEL 0x00000003 +#define RTC_IO_SENSE4_FUN_SEL_M ((RTC_IO_SENSE4_FUN_SEL_V)<<(RTC_IO_SENSE4_FUN_SEL_S)) +#define RTC_IO_SENSE4_FUN_SEL_V 0x3 +#define RTC_IO_SENSE4_FUN_SEL_S 7 +/* RTC_IO_SENSE4_SLP_SEL : R/W ;bitpos:[6] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_SENSE4_SLP_SEL (BIT(6)) +#define RTC_IO_SENSE4_SLP_SEL_M (BIT(6)) +#define RTC_IO_SENSE4_SLP_SEL_V 0x1 +#define RTC_IO_SENSE4_SLP_SEL_S 6 +/* RTC_IO_SENSE4_SLP_IE : R/W ;bitpos:[5] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_SENSE4_SLP_IE (BIT(5)) +#define RTC_IO_SENSE4_SLP_IE_M (BIT(5)) +#define RTC_IO_SENSE4_SLP_IE_V 0x1 +#define RTC_IO_SENSE4_SLP_IE_S 5 +/* RTC_IO_SENSE4_FUN_IE : R/W ;bitpos:[4] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_SENSE4_FUN_IE (BIT(4)) +#define RTC_IO_SENSE4_FUN_IE_M (BIT(4)) +#define RTC_IO_SENSE4_FUN_IE_V 0x1 +#define RTC_IO_SENSE4_FUN_IE_S 4 + +#define RTC_IO_ADC_PAD_REG (DR_REG_RTCIO_BASE + 0x80) +/* RTC_IO_ADC1_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_ADC1_HOLD (BIT(31)) +#define RTC_IO_ADC1_HOLD_M (BIT(31)) +#define RTC_IO_ADC1_HOLD_V 0x1 +#define RTC_IO_ADC1_HOLD_S 31 +/* RTC_IO_ADC2_HOLD : R/W ;bitpos:[30] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_ADC2_HOLD (BIT(30)) +#define RTC_IO_ADC2_HOLD_M (BIT(30)) +#define RTC_IO_ADC2_HOLD_V 0x1 +#define RTC_IO_ADC2_HOLD_S 30 +/* RTC_IO_ADC1_MUX_SEL : R/W ;bitpos:[29] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_ADC1_MUX_SEL (BIT(29)) +#define RTC_IO_ADC1_MUX_SEL_M (BIT(29)) +#define RTC_IO_ADC1_MUX_SEL_V 0x1 +#define RTC_IO_ADC1_MUX_SEL_S 29 +/* RTC_IO_ADC2_MUX_SEL : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_ADC2_MUX_SEL (BIT(28)) +#define RTC_IO_ADC2_MUX_SEL_M (BIT(28)) +#define RTC_IO_ADC2_MUX_SEL_V 0x1 +#define RTC_IO_ADC2_MUX_SEL_S 28 +/* RTC_IO_ADC1_FUN_SEL : R/W ;bitpos:[27:26] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_ADC1_FUN_SEL 0x00000003 +#define RTC_IO_ADC1_FUN_SEL_M ((RTC_IO_ADC1_FUN_SEL_V)<<(RTC_IO_ADC1_FUN_SEL_S)) +#define RTC_IO_ADC1_FUN_SEL_V 0x3 +#define RTC_IO_ADC1_FUN_SEL_S 26 +/* RTC_IO_ADC1_SLP_SEL : R/W ;bitpos:[25] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_ADC1_SLP_SEL (BIT(25)) +#define RTC_IO_ADC1_SLP_SEL_M (BIT(25)) +#define RTC_IO_ADC1_SLP_SEL_V 0x1 +#define RTC_IO_ADC1_SLP_SEL_S 25 +/* RTC_IO_ADC1_SLP_IE : R/W ;bitpos:[24] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_ADC1_SLP_IE (BIT(24)) +#define RTC_IO_ADC1_SLP_IE_M (BIT(24)) +#define RTC_IO_ADC1_SLP_IE_V 0x1 +#define RTC_IO_ADC1_SLP_IE_S 24 +/* RTC_IO_ADC1_FUN_IE : R/W ;bitpos:[23] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_ADC1_FUN_IE (BIT(23)) +#define RTC_IO_ADC1_FUN_IE_M (BIT(23)) +#define RTC_IO_ADC1_FUN_IE_V 0x1 +#define RTC_IO_ADC1_FUN_IE_S 23 +/* RTC_IO_ADC2_FUN_SEL : R/W ;bitpos:[22:21] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_ADC2_FUN_SEL 0x00000003 +#define RTC_IO_ADC2_FUN_SEL_M ((RTC_IO_ADC2_FUN_SEL_V)<<(RTC_IO_ADC2_FUN_SEL_S)) +#define RTC_IO_ADC2_FUN_SEL_V 0x3 +#define RTC_IO_ADC2_FUN_SEL_S 21 +/* RTC_IO_ADC2_SLP_SEL : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_ADC2_SLP_SEL (BIT(20)) +#define RTC_IO_ADC2_SLP_SEL_M (BIT(20)) +#define RTC_IO_ADC2_SLP_SEL_V 0x1 +#define RTC_IO_ADC2_SLP_SEL_S 20 +/* RTC_IO_ADC2_SLP_IE : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_ADC2_SLP_IE (BIT(19)) +#define RTC_IO_ADC2_SLP_IE_M (BIT(19)) +#define RTC_IO_ADC2_SLP_IE_V 0x1 +#define RTC_IO_ADC2_SLP_IE_S 19 +/* RTC_IO_ADC2_FUN_IE : R/W ;bitpos:[18] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_ADC2_FUN_IE (BIT(18)) +#define RTC_IO_ADC2_FUN_IE_M (BIT(18)) +#define RTC_IO_ADC2_FUN_IE_V 0x1 +#define RTC_IO_ADC2_FUN_IE_S 18 + +#define RTC_IO_PAD_DAC1_REG (DR_REG_RTCIO_BASE + 0x84) +/* RTC_IO_PDAC1_DRV : R/W ;bitpos:[31:30] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_PDAC1_DRV 0x00000003 +#define RTC_IO_PDAC1_DRV_M ((RTC_IO_PDAC1_DRV_V)<<(RTC_IO_PDAC1_DRV_S)) +#define RTC_IO_PDAC1_DRV_V 0x3 +#define RTC_IO_PDAC1_DRV_S 30 +/* RTC_IO_PDAC1_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_PDAC1_HOLD (BIT(29)) +#define RTC_IO_PDAC1_HOLD_M (BIT(29)) +#define RTC_IO_PDAC1_HOLD_V 0x1 +#define RTC_IO_PDAC1_HOLD_S 29 +/* RTC_IO_PDAC1_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_PDAC1_RDE (BIT(28)) +#define RTC_IO_PDAC1_RDE_M (BIT(28)) +#define RTC_IO_PDAC1_RDE_V 0x1 +#define RTC_IO_PDAC1_RDE_S 28 +/* RTC_IO_PDAC1_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_PDAC1_RUE (BIT(27)) +#define RTC_IO_PDAC1_RUE_M (BIT(27)) +#define RTC_IO_PDAC1_RUE_V 0x1 +#define RTC_IO_PDAC1_RUE_S 27 +/* RTC_IO_PDAC1_DAC : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ +/*description: PAD DAC1 control code.*/ +#define RTC_IO_PDAC1_DAC 0x000000FF +#define RTC_IO_PDAC1_DAC_M ((RTC_IO_PDAC1_DAC_V)<<(RTC_IO_PDAC1_DAC_S)) +#define RTC_IO_PDAC1_DAC_V 0xFF +#define RTC_IO_PDAC1_DAC_S 19 +/* RTC_IO_PDAC1_XPD_DAC : R/W ;bitpos:[18] ;default: 1'd0 ; */ +/*description: Power on DAC1. Usually we need to tristate PDAC1 if we power + on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ +#define RTC_IO_PDAC1_XPD_DAC (BIT(18)) +#define RTC_IO_PDAC1_XPD_DAC_M (BIT(18)) +#define RTC_IO_PDAC1_XPD_DAC_V 0x1 +#define RTC_IO_PDAC1_XPD_DAC_S 18 +/* RTC_IO_PDAC1_MUX_SEL : R/W ;bitpos:[17] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_PDAC1_MUX_SEL (BIT(17)) +#define RTC_IO_PDAC1_MUX_SEL_M (BIT(17)) +#define RTC_IO_PDAC1_MUX_SEL_V 0x1 +#define RTC_IO_PDAC1_MUX_SEL_S 17 +/* RTC_IO_PDAC1_FUN_SEL : R/W ;bitpos:[16:15] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_PDAC1_FUN_SEL 0x00000003 +#define RTC_IO_PDAC1_FUN_SEL_M ((RTC_IO_PDAC1_FUN_SEL_V)<<(RTC_IO_PDAC1_FUN_SEL_S)) +#define RTC_IO_PDAC1_FUN_SEL_V 0x3 +#define RTC_IO_PDAC1_FUN_SEL_S 15 +/* RTC_IO_PDAC1_SLP_SEL : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_PDAC1_SLP_SEL (BIT(14)) +#define RTC_IO_PDAC1_SLP_SEL_M (BIT(14)) +#define RTC_IO_PDAC1_SLP_SEL_V 0x1 +#define RTC_IO_PDAC1_SLP_SEL_S 14 +/* RTC_IO_PDAC1_SLP_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_PDAC1_SLP_IE (BIT(13)) +#define RTC_IO_PDAC1_SLP_IE_M (BIT(13)) +#define RTC_IO_PDAC1_SLP_IE_V 0x1 +#define RTC_IO_PDAC1_SLP_IE_S 13 +/* RTC_IO_PDAC1_SLP_OE : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_PDAC1_SLP_OE (BIT(12)) +#define RTC_IO_PDAC1_SLP_OE_M (BIT(12)) +#define RTC_IO_PDAC1_SLP_OE_V 0x1 +#define RTC_IO_PDAC1_SLP_OE_S 12 +/* RTC_IO_PDAC1_FUN_IE : R/W ;bitpos:[11] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_PDAC1_FUN_IE (BIT(11)) +#define RTC_IO_PDAC1_FUN_IE_M (BIT(11)) +#define RTC_IO_PDAC1_FUN_IE_V 0x1 +#define RTC_IO_PDAC1_FUN_IE_S 11 +/* RTC_IO_PDAC1_DAC_XPD_FORCE : R/W ;bitpos:[10] ;default: 1'd0 ; */ +/*description: Power on DAC1. Usually we need to tristate PDAC1 if we power + on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ +#define RTC_IO_PDAC1_DAC_XPD_FORCE (BIT(10)) +#define RTC_IO_PDAC1_DAC_XPD_FORCE_M (BIT(10)) +#define RTC_IO_PDAC1_DAC_XPD_FORCE_V 0x1 +#define RTC_IO_PDAC1_DAC_XPD_FORCE_S 10 + +#define RTC_IO_PAD_DAC2_REG (DR_REG_RTCIO_BASE + 0x88) +/* RTC_IO_PDAC2_DRV : R/W ;bitpos:[31:30] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_PDAC2_DRV 0x00000003 +#define RTC_IO_PDAC2_DRV_M ((RTC_IO_PDAC2_DRV_V)<<(RTC_IO_PDAC2_DRV_S)) +#define RTC_IO_PDAC2_DRV_V 0x3 +#define RTC_IO_PDAC2_DRV_S 30 +/* RTC_IO_PDAC2_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_PDAC2_HOLD (BIT(29)) +#define RTC_IO_PDAC2_HOLD_M (BIT(29)) +#define RTC_IO_PDAC2_HOLD_V 0x1 +#define RTC_IO_PDAC2_HOLD_S 29 +/* RTC_IO_PDAC2_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_PDAC2_RDE (BIT(28)) +#define RTC_IO_PDAC2_RDE_M (BIT(28)) +#define RTC_IO_PDAC2_RDE_V 0x1 +#define RTC_IO_PDAC2_RDE_S 28 +/* RTC_IO_PDAC2_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_PDAC2_RUE (BIT(27)) +#define RTC_IO_PDAC2_RUE_M (BIT(27)) +#define RTC_IO_PDAC2_RUE_V 0x1 +#define RTC_IO_PDAC2_RUE_S 27 +/* RTC_IO_PDAC2_DAC : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ +/*description: PAD DAC2 control code.*/ +#define RTC_IO_PDAC2_DAC 0x000000FF +#define RTC_IO_PDAC2_DAC_M ((RTC_IO_PDAC2_DAC_V)<<(RTC_IO_PDAC2_DAC_S)) +#define RTC_IO_PDAC2_DAC_V 0xFF +#define RTC_IO_PDAC2_DAC_S 19 +/* RTC_IO_PDAC2_XPD_DAC : R/W ;bitpos:[18] ;default: 1'd0 ; */ +/*description: Power on DAC2. Usually we need to tristate PDAC1 if we power + on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ +#define RTC_IO_PDAC2_XPD_DAC (BIT(18)) +#define RTC_IO_PDAC2_XPD_DAC_M (BIT(18)) +#define RTC_IO_PDAC2_XPD_DAC_V 0x1 +#define RTC_IO_PDAC2_XPD_DAC_S 18 +/* RTC_IO_PDAC2_MUX_SEL : R/W ;bitpos:[17] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_PDAC2_MUX_SEL (BIT(17)) +#define RTC_IO_PDAC2_MUX_SEL_M (BIT(17)) +#define RTC_IO_PDAC2_MUX_SEL_V 0x1 +#define RTC_IO_PDAC2_MUX_SEL_S 17 +/* RTC_IO_PDAC2_FUN_SEL : R/W ;bitpos:[16:15] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_PDAC2_FUN_SEL 0x00000003 +#define RTC_IO_PDAC2_FUN_SEL_M ((RTC_IO_PDAC2_FUN_SEL_V)<<(RTC_IO_PDAC2_FUN_SEL_S)) +#define RTC_IO_PDAC2_FUN_SEL_V 0x3 +#define RTC_IO_PDAC2_FUN_SEL_S 15 +/* RTC_IO_PDAC2_SLP_SEL : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_PDAC2_SLP_SEL (BIT(14)) +#define RTC_IO_PDAC2_SLP_SEL_M (BIT(14)) +#define RTC_IO_PDAC2_SLP_SEL_V 0x1 +#define RTC_IO_PDAC2_SLP_SEL_S 14 +/* RTC_IO_PDAC2_SLP_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_PDAC2_SLP_IE (BIT(13)) +#define RTC_IO_PDAC2_SLP_IE_M (BIT(13)) +#define RTC_IO_PDAC2_SLP_IE_V 0x1 +#define RTC_IO_PDAC2_SLP_IE_S 13 +/* RTC_IO_PDAC2_SLP_OE : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_PDAC2_SLP_OE (BIT(12)) +#define RTC_IO_PDAC2_SLP_OE_M (BIT(12)) +#define RTC_IO_PDAC2_SLP_OE_V 0x1 +#define RTC_IO_PDAC2_SLP_OE_S 12 +/* RTC_IO_PDAC2_FUN_IE : R/W ;bitpos:[11] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_PDAC2_FUN_IE (BIT(11)) +#define RTC_IO_PDAC2_FUN_IE_M (BIT(11)) +#define RTC_IO_PDAC2_FUN_IE_V 0x1 +#define RTC_IO_PDAC2_FUN_IE_S 11 +/* RTC_IO_PDAC2_DAC_XPD_FORCE : R/W ;bitpos:[10] ;default: 1'd0 ; */ +/*description: Power on DAC2. Usually we need to tristate PDAC2 if we power + on the DAC i.e. IE=0 OE=0 RDE=0 RUE=0*/ +#define RTC_IO_PDAC2_DAC_XPD_FORCE (BIT(10)) +#define RTC_IO_PDAC2_DAC_XPD_FORCE_M (BIT(10)) +#define RTC_IO_PDAC2_DAC_XPD_FORCE_V 0x1 +#define RTC_IO_PDAC2_DAC_XPD_FORCE_S 10 + +#define RTC_IO_XTAL_32K_PAD_REG (DR_REG_RTCIO_BASE + 0x8c) +/* RTC_IO_X32N_DRV : R/W ;bitpos:[31:30] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_X32N_DRV 0x00000003 +#define RTC_IO_X32N_DRV_M ((RTC_IO_X32N_DRV_V)<<(RTC_IO_X32N_DRV_S)) +#define RTC_IO_X32N_DRV_V 0x3 +#define RTC_IO_X32N_DRV_S 30 +/* RTC_IO_X32N_HOLD : R/W ;bitpos:[29] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_X32N_HOLD (BIT(29)) +#define RTC_IO_X32N_HOLD_M (BIT(29)) +#define RTC_IO_X32N_HOLD_V 0x1 +#define RTC_IO_X32N_HOLD_S 29 +/* RTC_IO_X32N_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_X32N_RDE (BIT(28)) +#define RTC_IO_X32N_RDE_M (BIT(28)) +#define RTC_IO_X32N_RDE_V 0x1 +#define RTC_IO_X32N_RDE_S 28 +/* RTC_IO_X32N_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_X32N_RUE (BIT(27)) +#define RTC_IO_X32N_RUE_M (BIT(27)) +#define RTC_IO_X32N_RUE_V 0x1 +#define RTC_IO_X32N_RUE_S 27 +/* RTC_IO_X32P_DRV : R/W ;bitpos:[26:25] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_X32P_DRV 0x00000003 +#define RTC_IO_X32P_DRV_M ((RTC_IO_X32P_DRV_V)<<(RTC_IO_X32P_DRV_S)) +#define RTC_IO_X32P_DRV_V 0x3 +#define RTC_IO_X32P_DRV_S 25 +/* RTC_IO_X32P_HOLD : R/W ;bitpos:[24] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_X32P_HOLD (BIT(24)) +#define RTC_IO_X32P_HOLD_M (BIT(24)) +#define RTC_IO_X32P_HOLD_V 0x1 +#define RTC_IO_X32P_HOLD_S 24 +/* RTC_IO_X32P_RDE : R/W ;bitpos:[23] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_X32P_RDE (BIT(23)) +#define RTC_IO_X32P_RDE_M (BIT(23)) +#define RTC_IO_X32P_RDE_V 0x1 +#define RTC_IO_X32P_RDE_S 23 +/* RTC_IO_X32P_RUE : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_X32P_RUE (BIT(22)) +#define RTC_IO_X32P_RUE_M (BIT(22)) +#define RTC_IO_X32P_RUE_V 0x1 +#define RTC_IO_X32P_RUE_S 22 +/* RTC_IO_DAC_XTAL_32K : R/W ;bitpos:[21:20] ;default: 2'b01 ; */ +/*description: 32K XTAL bias current DAC.*/ +#define RTC_IO_DAC_XTAL_32K 0x00000003 +#define RTC_IO_DAC_XTAL_32K_M ((RTC_IO_DAC_XTAL_32K_V)<<(RTC_IO_DAC_XTAL_32K_S)) +#define RTC_IO_DAC_XTAL_32K_V 0x3 +#define RTC_IO_DAC_XTAL_32K_S 20 +/* RTC_IO_XPD_XTAL_32K : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Power up 32kHz crystal oscillator*/ +#define RTC_IO_XPD_XTAL_32K (BIT(19)) +#define RTC_IO_XPD_XTAL_32K_M (BIT(19)) +#define RTC_IO_XPD_XTAL_32K_V 0x1 +#define RTC_IO_XPD_XTAL_32K_S 19 +/* RTC_IO_X32N_MUX_SEL : R/W ;bitpos:[18] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_X32N_MUX_SEL (BIT(18)) +#define RTC_IO_X32N_MUX_SEL_M (BIT(18)) +#define RTC_IO_X32N_MUX_SEL_V 0x1 +#define RTC_IO_X32N_MUX_SEL_S 18 +/* RTC_IO_X32P_MUX_SEL : R/W ;bitpos:[17] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_X32P_MUX_SEL (BIT(17)) +#define RTC_IO_X32P_MUX_SEL_M (BIT(17)) +#define RTC_IO_X32P_MUX_SEL_V 0x1 +#define RTC_IO_X32P_MUX_SEL_S 17 +/* RTC_IO_X32N_FUN_SEL : R/W ;bitpos:[16:15] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_X32N_FUN_SEL 0x00000003 +#define RTC_IO_X32N_FUN_SEL_M ((RTC_IO_X32N_FUN_SEL_V)<<(RTC_IO_X32N_FUN_SEL_S)) +#define RTC_IO_X32N_FUN_SEL_V 0x3 +#define RTC_IO_X32N_FUN_SEL_S 15 +/* RTC_IO_X32N_SLP_SEL : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_X32N_SLP_SEL (BIT(14)) +#define RTC_IO_X32N_SLP_SEL_M (BIT(14)) +#define RTC_IO_X32N_SLP_SEL_V 0x1 +#define RTC_IO_X32N_SLP_SEL_S 14 +/* RTC_IO_X32N_SLP_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_X32N_SLP_IE (BIT(13)) +#define RTC_IO_X32N_SLP_IE_M (BIT(13)) +#define RTC_IO_X32N_SLP_IE_V 0x1 +#define RTC_IO_X32N_SLP_IE_S 13 +/* RTC_IO_X32N_SLP_OE : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_X32N_SLP_OE (BIT(12)) +#define RTC_IO_X32N_SLP_OE_M (BIT(12)) +#define RTC_IO_X32N_SLP_OE_V 0x1 +#define RTC_IO_X32N_SLP_OE_S 12 +/* RTC_IO_X32N_FUN_IE : R/W ;bitpos:[11] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_X32N_FUN_IE (BIT(11)) +#define RTC_IO_X32N_FUN_IE_M (BIT(11)) +#define RTC_IO_X32N_FUN_IE_V 0x1 +#define RTC_IO_X32N_FUN_IE_S 11 +/* RTC_IO_X32P_FUN_SEL : R/W ;bitpos:[10:9] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_X32P_FUN_SEL 0x00000003 +#define RTC_IO_X32P_FUN_SEL_M ((RTC_IO_X32P_FUN_SEL_V)<<(RTC_IO_X32P_FUN_SEL_S)) +#define RTC_IO_X32P_FUN_SEL_V 0x3 +#define RTC_IO_X32P_FUN_SEL_S 9 +/* RTC_IO_X32P_SLP_SEL : R/W ;bitpos:[8] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_X32P_SLP_SEL (BIT(8)) +#define RTC_IO_X32P_SLP_SEL_M (BIT(8)) +#define RTC_IO_X32P_SLP_SEL_V 0x1 +#define RTC_IO_X32P_SLP_SEL_S 8 +/* RTC_IO_X32P_SLP_IE : R/W ;bitpos:[7] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_X32P_SLP_IE (BIT(7)) +#define RTC_IO_X32P_SLP_IE_M (BIT(7)) +#define RTC_IO_X32P_SLP_IE_V 0x1 +#define RTC_IO_X32P_SLP_IE_S 7 +/* RTC_IO_X32P_SLP_OE : R/W ;bitpos:[6] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_X32P_SLP_OE (BIT(6)) +#define RTC_IO_X32P_SLP_OE_M (BIT(6)) +#define RTC_IO_X32P_SLP_OE_V 0x1 +#define RTC_IO_X32P_SLP_OE_S 6 +/* RTC_IO_X32P_FUN_IE : R/W ;bitpos:[5] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_X32P_FUN_IE (BIT(5)) +#define RTC_IO_X32P_FUN_IE_M (BIT(5)) +#define RTC_IO_X32P_FUN_IE_V 0x1 +#define RTC_IO_X32P_FUN_IE_S 5 +/* RTC_IO_DRES_XTAL_32K : R/W ;bitpos:[4:3] ;default: 2'b10 ; */ +/*description: 32K XTAL resistor bias control.*/ +#define RTC_IO_DRES_XTAL_32K 0x00000003 +#define RTC_IO_DRES_XTAL_32K_M ((RTC_IO_DRES_XTAL_32K_V)<<(RTC_IO_DRES_XTAL_32K_S)) +#define RTC_IO_DRES_XTAL_32K_V 0x3 +#define RTC_IO_DRES_XTAL_32K_S 3 +/* RTC_IO_DBIAS_XTAL_32K : R/W ;bitpos:[2:1] ;default: 2'b00 ; */ +/*description: 32K XTAL self-bias reference control.*/ +#define RTC_IO_DBIAS_XTAL_32K 0x00000003 +#define RTC_IO_DBIAS_XTAL_32K_M ((RTC_IO_DBIAS_XTAL_32K_V)<<(RTC_IO_DBIAS_XTAL_32K_S)) +#define RTC_IO_DBIAS_XTAL_32K_V 0x3 +#define RTC_IO_DBIAS_XTAL_32K_S 1 + +#define RTC_IO_TOUCH_CFG_REG (DR_REG_RTCIO_BASE + 0x90) +/* RTC_IO_TOUCH_XPD_BIAS : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: touch sensor bias power on.*/ +#define RTC_IO_TOUCH_XPD_BIAS (BIT(31)) +#define RTC_IO_TOUCH_XPD_BIAS_M (BIT(31)) +#define RTC_IO_TOUCH_XPD_BIAS_V 0x1 +#define RTC_IO_TOUCH_XPD_BIAS_S 31 +/* RTC_IO_TOUCH_DREFH : R/W ;bitpos:[30:29] ;default: 2'b11 ; */ +/*description: touch sensor saw wave top voltage.*/ +#define RTC_IO_TOUCH_DREFH 0x00000003 +#define RTC_IO_TOUCH_DREFH_M ((RTC_IO_TOUCH_DREFH_V)<<(RTC_IO_TOUCH_DREFH_S)) +#define RTC_IO_TOUCH_DREFH_V 0x3 +#define RTC_IO_TOUCH_DREFH_S 29 +/* RTC_IO_TOUCH_DREFL : R/W ;bitpos:[28:27] ;default: 2'b00 ; */ +/*description: touch sensor saw wave bottom voltage.*/ +#define RTC_IO_TOUCH_DREFL 0x00000003 +#define RTC_IO_TOUCH_DREFL_M ((RTC_IO_TOUCH_DREFL_V)<<(RTC_IO_TOUCH_DREFL_S)) +#define RTC_IO_TOUCH_DREFL_V 0x3 +#define RTC_IO_TOUCH_DREFL_S 27 +/* RTC_IO_TOUCH_DRANGE : R/W ;bitpos:[26:25] ;default: 2'b11 ; */ +/*description: touch sensor saw wave voltage range.*/ +#define RTC_IO_TOUCH_DRANGE 0x00000003 +#define RTC_IO_TOUCH_DRANGE_M ((RTC_IO_TOUCH_DRANGE_V)<<(RTC_IO_TOUCH_DRANGE_S)) +#define RTC_IO_TOUCH_DRANGE_V 0x3 +#define RTC_IO_TOUCH_DRANGE_S 25 +/* RTC_IO_TOUCH_DCUR : R/W ;bitpos:[24:23] ;default: 2'b00 ; */ +/*description: touch sensor bias current. Should have option to tie with BIAS_SLEEP(When + BIAS_SLEEP this setting is available*/ +#define RTC_IO_TOUCH_DCUR 0x00000003 +#define RTC_IO_TOUCH_DCUR_M ((RTC_IO_TOUCH_DCUR_V)<<(RTC_IO_TOUCH_DCUR_S)) +#define RTC_IO_TOUCH_DCUR_V 0x3 +#define RTC_IO_TOUCH_DCUR_S 23 + +#define RTC_IO_TOUCH_PAD0_REG (DR_REG_RTCIO_BASE + 0x94) +/* RTC_IO_TOUCH_PAD0_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD0_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD0_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD0_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD0_HOLD_S 31 +/* RTC_IO_TOUCH_PAD0_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD0_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD0_DRV_M ((RTC_IO_TOUCH_PAD0_DRV_V)<<(RTC_IO_TOUCH_PAD0_DRV_S)) +#define RTC_IO_TOUCH_PAD0_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD0_DRV_S 29 +/* RTC_IO_TOUCH_PAD0_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD0_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD0_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD0_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD0_RDE_S 28 +/* RTC_IO_TOUCH_PAD0_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD0_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD0_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD0_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD0_RUE_S 27 +/* RTC_IO_TOUCH_PAD0_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD0_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD0_DAC_M ((RTC_IO_TOUCH_PAD0_DAC_V)<<(RTC_IO_TOUCH_PAD0_DAC_S)) +#define RTC_IO_TOUCH_PAD0_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD0_DAC_S 23 +/* RTC_IO_TOUCH_PAD0_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD0_START (BIT(22)) +#define RTC_IO_TOUCH_PAD0_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD0_START_V 0x1 +#define RTC_IO_TOUCH_PAD0_START_S 22 +/* RTC_IO_TOUCH_PAD0_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD0_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD0_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD0_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD0_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD0_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD0_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD0_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD0_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD0_XPD_S 20 +/* RTC_IO_TOUCH_PAD0_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD0_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD0_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD0_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD0_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD0_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD0_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD0_FUN_SEL_M ((RTC_IO_TOUCH_PAD0_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD0_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD0_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD0_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD0_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD0_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD0_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD0_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD0_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD0_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD0_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD0_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD0_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD0_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD0_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD0_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD0_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD0_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD0_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD0_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD0_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD0_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD0_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD0_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD0_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale GPIO4*/ +#define RTC_IO_TOUCH_PAD0_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD0_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD0_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD0_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD1_REG (DR_REG_RTCIO_BASE + 0x98) +/* RTC_IO_TOUCH_PAD1_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: */ +#define RTC_IO_TOUCH_PAD1_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD1_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD1_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD1_HOLD_S 31 +/* RTC_IO_TOUCH_PAD1_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD1_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD1_DRV_M ((RTC_IO_TOUCH_PAD1_DRV_V)<<(RTC_IO_TOUCH_PAD1_DRV_S)) +#define RTC_IO_TOUCH_PAD1_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD1_DRV_S 29 +/* RTC_IO_TOUCH_PAD1_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD1_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD1_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD1_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD1_RDE_S 28 +/* RTC_IO_TOUCH_PAD1_RUE : R/W ;bitpos:[27] ;default: 1'd1 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD1_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD1_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD1_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD1_RUE_S 27 +/* RTC_IO_TOUCH_PAD1_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD1_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD1_DAC_M ((RTC_IO_TOUCH_PAD1_DAC_V)<<(RTC_IO_TOUCH_PAD1_DAC_S)) +#define RTC_IO_TOUCH_PAD1_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD1_DAC_S 23 +/* RTC_IO_TOUCH_PAD1_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD1_START (BIT(22)) +#define RTC_IO_TOUCH_PAD1_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD1_START_V 0x1 +#define RTC_IO_TOUCH_PAD1_START_S 22 +/* RTC_IO_TOUCH_PAD1_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD1_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD1_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD1_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD1_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD1_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD1_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD1_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD1_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD1_XPD_S 20 +/* RTC_IO_TOUCH_PAD1_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD1_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD1_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD1_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD1_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD1_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD1_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD1_FUN_SEL_M ((RTC_IO_TOUCH_PAD1_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD1_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD1_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD1_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD1_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD1_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD1_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD1_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD1_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD1_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD1_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD1_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD1_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD1_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD1_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD1_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD1_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD1_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD1_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD1_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD1_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD1_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD1_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD1_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD1_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO0*/ +#define RTC_IO_TOUCH_PAD1_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD1_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD1_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD1_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD2_REG (DR_REG_RTCIO_BASE + 0x9c) +/* RTC_IO_TOUCH_PAD2_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD2_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD2_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD2_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD2_HOLD_S 31 +/* RTC_IO_TOUCH_PAD2_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD2_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD2_DRV_M ((RTC_IO_TOUCH_PAD2_DRV_V)<<(RTC_IO_TOUCH_PAD2_DRV_S)) +#define RTC_IO_TOUCH_PAD2_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD2_DRV_S 29 +/* RTC_IO_TOUCH_PAD2_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD2_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD2_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD2_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD2_RDE_S 28 +/* RTC_IO_TOUCH_PAD2_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD2_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD2_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD2_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD2_RUE_S 27 +/* RTC_IO_TOUCH_PAD2_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD2_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD2_DAC_M ((RTC_IO_TOUCH_PAD2_DAC_V)<<(RTC_IO_TOUCH_PAD2_DAC_S)) +#define RTC_IO_TOUCH_PAD2_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD2_DAC_S 23 +/* RTC_IO_TOUCH_PAD2_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD2_START (BIT(22)) +#define RTC_IO_TOUCH_PAD2_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD2_START_V 0x1 +#define RTC_IO_TOUCH_PAD2_START_S 22 +/* RTC_IO_TOUCH_PAD2_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD2_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD2_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD2_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD2_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD2_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD2_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD2_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD2_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD2_XPD_S 20 +/* RTC_IO_TOUCH_PAD2_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD2_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD2_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD2_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD2_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD2_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD2_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD2_FUN_SEL_M ((RTC_IO_TOUCH_PAD2_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD2_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD2_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD2_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD2_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD2_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD2_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD2_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD2_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD2_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD2_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD2_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD2_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD2_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD2_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD2_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD2_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD2_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD2_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD2_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD2_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD2_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD2_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD2_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD2_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO2*/ +#define RTC_IO_TOUCH_PAD2_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD2_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD2_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD2_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD3_REG (DR_REG_RTCIO_BASE + 0xa0) +/* RTC_IO_TOUCH_PAD3_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD3_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD3_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD3_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD3_HOLD_S 31 +/* RTC_IO_TOUCH_PAD3_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD3_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD3_DRV_M ((RTC_IO_TOUCH_PAD3_DRV_V)<<(RTC_IO_TOUCH_PAD3_DRV_S)) +#define RTC_IO_TOUCH_PAD3_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD3_DRV_S 29 +/* RTC_IO_TOUCH_PAD3_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD3_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD3_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD3_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD3_RDE_S 28 +/* RTC_IO_TOUCH_PAD3_RUE : R/W ;bitpos:[27] ;default: 1'd1 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD3_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD3_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD3_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD3_RUE_S 27 +/* RTC_IO_TOUCH_PAD3_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD3_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD3_DAC_M ((RTC_IO_TOUCH_PAD3_DAC_V)<<(RTC_IO_TOUCH_PAD3_DAC_S)) +#define RTC_IO_TOUCH_PAD3_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD3_DAC_S 23 +/* RTC_IO_TOUCH_PAD3_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD3_START (BIT(22)) +#define RTC_IO_TOUCH_PAD3_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD3_START_V 0x1 +#define RTC_IO_TOUCH_PAD3_START_S 22 +/* RTC_IO_TOUCH_PAD3_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD3_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD3_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD3_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD3_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD3_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD3_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD3_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD3_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD3_XPD_S 20 +/* RTC_IO_TOUCH_PAD3_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD3_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD3_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD3_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD3_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD3_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD3_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD3_FUN_SEL_M ((RTC_IO_TOUCH_PAD3_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD3_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD3_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD3_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD3_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD3_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD3_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD3_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD3_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD3_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD3_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD3_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD3_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD3_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD3_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD3_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD3_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD3_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD3_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD3_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD3_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD3_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD3_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD3_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD3_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDO*/ +#define RTC_IO_TOUCH_PAD3_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD3_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD3_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD3_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD4_REG (DR_REG_RTCIO_BASE + 0xa4) +/* RTC_IO_TOUCH_PAD4_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD4_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD4_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD4_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD4_HOLD_S 31 +/* RTC_IO_TOUCH_PAD4_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD4_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD4_DRV_M ((RTC_IO_TOUCH_PAD4_DRV_V)<<(RTC_IO_TOUCH_PAD4_DRV_S)) +#define RTC_IO_TOUCH_PAD4_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD4_DRV_S 29 +/* RTC_IO_TOUCH_PAD4_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD4_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD4_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD4_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD4_RDE_S 28 +/* RTC_IO_TOUCH_PAD4_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD4_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD4_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD4_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD4_RUE_S 27 +/* RTC_IO_TOUCH_PAD4_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD4_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD4_DAC_M ((RTC_IO_TOUCH_PAD4_DAC_V)<<(RTC_IO_TOUCH_PAD4_DAC_S)) +#define RTC_IO_TOUCH_PAD4_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD4_DAC_S 23 +/* RTC_IO_TOUCH_PAD4_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD4_START (BIT(22)) +#define RTC_IO_TOUCH_PAD4_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD4_START_V 0x1 +#define RTC_IO_TOUCH_PAD4_START_S 22 +/* RTC_IO_TOUCH_PAD4_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD4_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD4_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD4_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD4_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD4_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD4_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD4_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD4_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD4_XPD_S 20 +/* RTC_IO_TOUCH_PAD4_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD4_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD4_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD4_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD4_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD4_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD4_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD4_FUN_SEL_M ((RTC_IO_TOUCH_PAD4_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD4_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD4_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD4_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD4_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD4_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD4_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD4_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD4_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD4_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD4_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD4_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD4_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD4_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD4_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD4_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD4_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD4_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD4_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD4_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD4_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD4_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD4_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD4_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD4_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTCK*/ +#define RTC_IO_TOUCH_PAD4_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD4_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD4_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD4_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD5_REG (DR_REG_RTCIO_BASE + 0xa8) +/* RTC_IO_TOUCH_PAD5_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD5_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD5_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD5_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD5_HOLD_S 31 +/* RTC_IO_TOUCH_PAD5_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD5_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD5_DRV_M ((RTC_IO_TOUCH_PAD5_DRV_V)<<(RTC_IO_TOUCH_PAD5_DRV_S)) +#define RTC_IO_TOUCH_PAD5_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD5_DRV_S 29 +/* RTC_IO_TOUCH_PAD5_RDE : R/W ;bitpos:[28] ;default: 1'd1 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD5_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD5_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD5_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD5_RDE_S 28 +/* RTC_IO_TOUCH_PAD5_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD5_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD5_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD5_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD5_RUE_S 27 +/* RTC_IO_TOUCH_PAD5_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD5_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD5_DAC_M ((RTC_IO_TOUCH_PAD5_DAC_V)<<(RTC_IO_TOUCH_PAD5_DAC_S)) +#define RTC_IO_TOUCH_PAD5_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD5_DAC_S 23 +/* RTC_IO_TOUCH_PAD5_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD5_START (BIT(22)) +#define RTC_IO_TOUCH_PAD5_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD5_START_V 0x1 +#define RTC_IO_TOUCH_PAD5_START_S 22 +/* RTC_IO_TOUCH_PAD5_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD5_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD5_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD5_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD5_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD5_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD5_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD5_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD5_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD5_XPD_S 20 +/* RTC_IO_TOUCH_PAD5_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD5_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD5_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD5_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD5_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD5_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD5_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD5_FUN_SEL_M ((RTC_IO_TOUCH_PAD5_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD5_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD5_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD5_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD5_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD5_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD5_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD5_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD5_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD5_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD5_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD5_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD5_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD5_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD5_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD5_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD5_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD5_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD5_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD5_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD5_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD5_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD5_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD5_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD5_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTDI*/ +#define RTC_IO_TOUCH_PAD5_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD5_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD5_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD5_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD6_REG (DR_REG_RTCIO_BASE + 0xac) +/* RTC_IO_TOUCH_PAD6_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD6_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD6_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD6_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD6_HOLD_S 31 +/* RTC_IO_TOUCH_PAD6_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD6_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD6_DRV_M ((RTC_IO_TOUCH_PAD6_DRV_V)<<(RTC_IO_TOUCH_PAD6_DRV_S)) +#define RTC_IO_TOUCH_PAD6_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD6_DRV_S 29 +/* RTC_IO_TOUCH_PAD6_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD6_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD6_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD6_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD6_RDE_S 28 +/* RTC_IO_TOUCH_PAD6_RUE : R/W ;bitpos:[27] ;default: 1'd1 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD6_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD6_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD6_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD6_RUE_S 27 +/* RTC_IO_TOUCH_PAD6_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD6_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD6_DAC_M ((RTC_IO_TOUCH_PAD6_DAC_V)<<(RTC_IO_TOUCH_PAD6_DAC_S)) +#define RTC_IO_TOUCH_PAD6_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD6_DAC_S 23 +/* RTC_IO_TOUCH_PAD6_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD6_START (BIT(22)) +#define RTC_IO_TOUCH_PAD6_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD6_START_V 0x1 +#define RTC_IO_TOUCH_PAD6_START_S 22 +/* RTC_IO_TOUCH_PAD6_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD6_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD6_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD6_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD6_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD6_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD6_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD6_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD6_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD6_XPD_S 20 +/* RTC_IO_TOUCH_PAD6_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD6_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD6_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD6_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD6_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD6_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD6_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD6_FUN_SEL_M ((RTC_IO_TOUCH_PAD6_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD6_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD6_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD6_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD6_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD6_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD6_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD6_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD6_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD6_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD6_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD6_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD6_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD6_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD6_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD6_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD6_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD6_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD6_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD6_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD6_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD6_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD6_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD6_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD6_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.MTMS*/ +#define RTC_IO_TOUCH_PAD6_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD6_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD6_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD6_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD7_REG (DR_REG_RTCIO_BASE + 0xb0) +/* RTC_IO_TOUCH_PAD7_HOLD : R/W ;bitpos:[31] ;default: 1'd0 ; */ +/*description: hold the current value of the output when setting the hold to Ò1Ó*/ +#define RTC_IO_TOUCH_PAD7_HOLD (BIT(31)) +#define RTC_IO_TOUCH_PAD7_HOLD_M (BIT(31)) +#define RTC_IO_TOUCH_PAD7_HOLD_V 0x1 +#define RTC_IO_TOUCH_PAD7_HOLD_S 31 +/* RTC_IO_TOUCH_PAD7_DRV : R/W ;bitpos:[30:29] ;default: 2'd2 ; */ +/*description: the driver strength of the pad*/ +#define RTC_IO_TOUCH_PAD7_DRV 0x00000003 +#define RTC_IO_TOUCH_PAD7_DRV_M ((RTC_IO_TOUCH_PAD7_DRV_V)<<(RTC_IO_TOUCH_PAD7_DRV_S)) +#define RTC_IO_TOUCH_PAD7_DRV_V 0x3 +#define RTC_IO_TOUCH_PAD7_DRV_S 29 +/* RTC_IO_TOUCH_PAD7_RDE : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: the pull down enable of the pad*/ +#define RTC_IO_TOUCH_PAD7_RDE (BIT(28)) +#define RTC_IO_TOUCH_PAD7_RDE_M (BIT(28)) +#define RTC_IO_TOUCH_PAD7_RDE_V 0x1 +#define RTC_IO_TOUCH_PAD7_RDE_S 28 +/* RTC_IO_TOUCH_PAD7_RUE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: the pull up enable of the pad*/ +#define RTC_IO_TOUCH_PAD7_RUE (BIT(27)) +#define RTC_IO_TOUCH_PAD7_RUE_M (BIT(27)) +#define RTC_IO_TOUCH_PAD7_RUE_V 0x1 +#define RTC_IO_TOUCH_PAD7_RUE_S 27 +/* RTC_IO_TOUCH_PAD7_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD7_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD7_DAC_M ((RTC_IO_TOUCH_PAD7_DAC_V)<<(RTC_IO_TOUCH_PAD7_DAC_S)) +#define RTC_IO_TOUCH_PAD7_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD7_DAC_S 23 +/* RTC_IO_TOUCH_PAD7_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD7_START (BIT(22)) +#define RTC_IO_TOUCH_PAD7_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD7_START_V 0x1 +#define RTC_IO_TOUCH_PAD7_START_S 22 +/* RTC_IO_TOUCH_PAD7_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD7_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD7_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD7_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD7_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD7_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD7_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD7_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD7_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD7_XPD_S 20 +/* RTC_IO_TOUCH_PAD7_MUX_SEL : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: Ò1Ó select the digital function Ó0Óslection the rtc function*/ +#define RTC_IO_TOUCH_PAD7_MUX_SEL (BIT(19)) +#define RTC_IO_TOUCH_PAD7_MUX_SEL_M (BIT(19)) +#define RTC_IO_TOUCH_PAD7_MUX_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD7_MUX_SEL_S 19 +/* RTC_IO_TOUCH_PAD7_FUN_SEL : R/W ;bitpos:[18:17] ;default: 2'd0 ; */ +/*description: the functional selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD7_FUN_SEL 0x00000003 +#define RTC_IO_TOUCH_PAD7_FUN_SEL_M ((RTC_IO_TOUCH_PAD7_FUN_SEL_V)<<(RTC_IO_TOUCH_PAD7_FUN_SEL_S)) +#define RTC_IO_TOUCH_PAD7_FUN_SEL_V 0x3 +#define RTC_IO_TOUCH_PAD7_FUN_SEL_S 17 +/* RTC_IO_TOUCH_PAD7_SLP_SEL : R/W ;bitpos:[16] ;default: 1'd0 ; */ +/*description: the sleep status selection signal of the pad*/ +#define RTC_IO_TOUCH_PAD7_SLP_SEL (BIT(16)) +#define RTC_IO_TOUCH_PAD7_SLP_SEL_M (BIT(16)) +#define RTC_IO_TOUCH_PAD7_SLP_SEL_V 0x1 +#define RTC_IO_TOUCH_PAD7_SLP_SEL_S 16 +/* RTC_IO_TOUCH_PAD7_SLP_IE : R/W ;bitpos:[15] ;default: 1'd0 ; */ +/*description: the input enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD7_SLP_IE (BIT(15)) +#define RTC_IO_TOUCH_PAD7_SLP_IE_M (BIT(15)) +#define RTC_IO_TOUCH_PAD7_SLP_IE_V 0x1 +#define RTC_IO_TOUCH_PAD7_SLP_IE_S 15 +/* RTC_IO_TOUCH_PAD7_SLP_OE : R/W ;bitpos:[14] ;default: 1'd0 ; */ +/*description: the output enable of the pad in sleep status*/ +#define RTC_IO_TOUCH_PAD7_SLP_OE (BIT(14)) +#define RTC_IO_TOUCH_PAD7_SLP_OE_M (BIT(14)) +#define RTC_IO_TOUCH_PAD7_SLP_OE_V 0x1 +#define RTC_IO_TOUCH_PAD7_SLP_OE_S 14 +/* RTC_IO_TOUCH_PAD7_FUN_IE : R/W ;bitpos:[13] ;default: 1'd0 ; */ +/*description: the input enable of the pad*/ +#define RTC_IO_TOUCH_PAD7_FUN_IE (BIT(13)) +#define RTC_IO_TOUCH_PAD7_FUN_IE_M (BIT(13)) +#define RTC_IO_TOUCH_PAD7_FUN_IE_V 0x1 +#define RTC_IO_TOUCH_PAD7_FUN_IE_S 13 +/* RTC_IO_TOUCH_PAD7_TO_GPIO : R/W ;bitpos:[12] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale.GPIO27*/ +#define RTC_IO_TOUCH_PAD7_TO_GPIO (BIT(12)) +#define RTC_IO_TOUCH_PAD7_TO_GPIO_M (BIT(12)) +#define RTC_IO_TOUCH_PAD7_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD7_TO_GPIO_S 12 + +#define RTC_IO_TOUCH_PAD8_REG (DR_REG_RTCIO_BASE + 0xb4) +/* RTC_IO_TOUCH_PAD8_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD8_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD8_DAC_M ((RTC_IO_TOUCH_PAD8_DAC_V)<<(RTC_IO_TOUCH_PAD8_DAC_S)) +#define RTC_IO_TOUCH_PAD8_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD8_DAC_S 23 +/* RTC_IO_TOUCH_PAD8_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD8_START (BIT(22)) +#define RTC_IO_TOUCH_PAD8_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD8_START_V 0x1 +#define RTC_IO_TOUCH_PAD8_START_S 22 +/* RTC_IO_TOUCH_PAD8_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD8_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD8_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD8_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD8_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD8_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD8_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD8_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD8_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD8_XPD_S 20 +/* RTC_IO_TOUCH_PAD8_TO_GPIO : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale*/ +#define RTC_IO_TOUCH_PAD8_TO_GPIO (BIT(19)) +#define RTC_IO_TOUCH_PAD8_TO_GPIO_M (BIT(19)) +#define RTC_IO_TOUCH_PAD8_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD8_TO_GPIO_S 19 + +#define RTC_IO_TOUCH_PAD9_REG (DR_REG_RTCIO_BASE + 0xb8) +/* RTC_IO_TOUCH_PAD9_DAC : R/W ;bitpos:[25:23] ;default: 3'h4 ; */ +/*description: touch sensor slope control. 3-bit for each touch panel default 100.*/ +#define RTC_IO_TOUCH_PAD9_DAC 0x00000007 +#define RTC_IO_TOUCH_PAD9_DAC_M ((RTC_IO_TOUCH_PAD9_DAC_V)<<(RTC_IO_TOUCH_PAD9_DAC_S)) +#define RTC_IO_TOUCH_PAD9_DAC_V 0x7 +#define RTC_IO_TOUCH_PAD9_DAC_S 23 +/* RTC_IO_TOUCH_PAD9_START : R/W ;bitpos:[22] ;default: 1'd0 ; */ +/*description: start touch sensor.*/ +#define RTC_IO_TOUCH_PAD9_START (BIT(22)) +#define RTC_IO_TOUCH_PAD9_START_M (BIT(22)) +#define RTC_IO_TOUCH_PAD9_START_V 0x1 +#define RTC_IO_TOUCH_PAD9_START_S 22 +/* RTC_IO_TOUCH_PAD9_TIE_OPT : R/W ;bitpos:[21] ;default: 1'd0 ; */ +/*description: default touch sensor tie option. 0: tie low 1: tie high.*/ +#define RTC_IO_TOUCH_PAD9_TIE_OPT (BIT(21)) +#define RTC_IO_TOUCH_PAD9_TIE_OPT_M (BIT(21)) +#define RTC_IO_TOUCH_PAD9_TIE_OPT_V 0x1 +#define RTC_IO_TOUCH_PAD9_TIE_OPT_S 21 +/* RTC_IO_TOUCH_PAD9_XPD : R/W ;bitpos:[20] ;default: 1'd0 ; */ +/*description: touch sensor power on.*/ +#define RTC_IO_TOUCH_PAD9_XPD (BIT(20)) +#define RTC_IO_TOUCH_PAD9_XPD_M (BIT(20)) +#define RTC_IO_TOUCH_PAD9_XPD_V 0x1 +#define RTC_IO_TOUCH_PAD9_XPD_S 20 +/* RTC_IO_TOUCH_PAD9_TO_GPIO : R/W ;bitpos:[19] ;default: 1'd0 ; */ +/*description: connect the rtc pad input to digital pad input Ó0Ó is availbale*/ +#define RTC_IO_TOUCH_PAD9_TO_GPIO (BIT(19)) +#define RTC_IO_TOUCH_PAD9_TO_GPIO_M (BIT(19)) +#define RTC_IO_TOUCH_PAD9_TO_GPIO_V 0x1 +#define RTC_IO_TOUCH_PAD9_TO_GPIO_S 19 + +#define RTC_IO_EXT_WAKEUP0_REG (DR_REG_RTCIO_BASE + 0xbc) +/* RTC_IO_EXT_WAKEUP0_SEL : R/W ;bitpos:[31:27] ;default: 5'd0 ; */ +/*description: select the wakeup source Ó0Ó select GPIO0 Ó1Ó select GPIO2 ...Ò17Ó select GPIO17*/ +#define RTC_IO_EXT_WAKEUP0_SEL 0x0000001F +#define RTC_IO_EXT_WAKEUP0_SEL_M ((RTC_IO_EXT_WAKEUP0_SEL_V)<<(RTC_IO_EXT_WAKEUP0_SEL_S)) +#define RTC_IO_EXT_WAKEUP0_SEL_V 0x1F +#define RTC_IO_EXT_WAKEUP0_SEL_S 27 + +#define RTC_IO_XTL_EXT_CTR_REG (DR_REG_RTCIO_BASE + 0xc0) +/* RTC_IO_XTL_EXT_CTR_SEL : R/W ;bitpos:[31:27] ;default: 5'd0 ; */ +/*description: select the external xtl power source Ó0Ó select GPIO0 Ó1Ó select + GPIO2 ...Ò17Ó select GPIO17*/ +#define RTC_IO_XTL_EXT_CTR_SEL 0x0000001F +#define RTC_IO_XTL_EXT_CTR_SEL_M ((RTC_IO_XTL_EXT_CTR_SEL_V)<<(RTC_IO_XTL_EXT_CTR_SEL_S)) +#define RTC_IO_XTL_EXT_CTR_SEL_V 0x1F +#define RTC_IO_XTL_EXT_CTR_SEL_S 27 + +#define RTC_IO_SAR_I2C_IO_REG (DR_REG_RTCIO_BASE + 0xc4) +/* RTC_IO_SAR_I2C_SDA_SEL : R/W ;bitpos:[31:30] ;default: 2'd0 ; */ +/*description: Ò0Ó using TOUCH_PAD[1] as i2c sda Ò1Ó using TOUCH_PAD[3] as i2c sda*/ +#define RTC_IO_SAR_I2C_SDA_SEL 0x00000003 +#define RTC_IO_SAR_I2C_SDA_SEL_M ((RTC_IO_SAR_I2C_SDA_SEL_V)<<(RTC_IO_SAR_I2C_SDA_SEL_S)) +#define RTC_IO_SAR_I2C_SDA_SEL_V 0x3 +#define RTC_IO_SAR_I2C_SDA_SEL_S 30 +/* RTC_IO_SAR_I2C_SCL_SEL : R/W ;bitpos:[29:28] ;default: 2'd0 ; */ +/*description: Ò0Ó using TOUCH_PAD[0] as i2c clk Ò1Ó using TOUCH_PAD[2] as i2c clk*/ +#define RTC_IO_SAR_I2C_SCL_SEL 0x00000003 +#define RTC_IO_SAR_I2C_SCL_SEL_M ((RTC_IO_SAR_I2C_SCL_SEL_V)<<(RTC_IO_SAR_I2C_SCL_SEL_S)) +#define RTC_IO_SAR_I2C_SCL_SEL_V 0x3 +#define RTC_IO_SAR_I2C_SCL_SEL_S 28 +/* RTC_IO_SAR_DEBUG_BIT_SEL : R/W ;bitpos:[27:23] ;default: 5'h0 ; */ +/*description: */ +#define RTC_IO_SAR_DEBUG_BIT_SEL 0x0000001F +#define RTC_IO_SAR_DEBUG_BIT_SEL_M ((RTC_IO_SAR_DEBUG_BIT_SEL_V)<<(RTC_IO_SAR_DEBUG_BIT_SEL_S)) +#define RTC_IO_SAR_DEBUG_BIT_SEL_V 0x1F +#define RTC_IO_SAR_DEBUG_BIT_SEL_S 23 + +#define RTC_IO_DATE_REG (DR_REG_RTCIO_BASE + 0xc8) +/* RTC_IO_IO_DATE : R/W ;bitpos:[27:0] ;default: 28'h1603160 ; */ +/*description: date*/ +#define RTC_IO_IO_DATE 0x0FFFFFFF +#define RTC_IO_IO_DATE_M ((RTC_IO_IO_DATE_V)<<(RTC_IO_IO_DATE_S)) +#define RTC_IO_IO_DATE_V 0xFFFFFFF +#define RTC_IO_IO_DATE_S 0 +#define RTC_IO_RTC_IO_DATE_VERSION 0x1703160 + + + + +#endif /*_SOC_RTC_IO_REG_H_ */ + + diff --git a/components/esp32/include/soc/saradc_reg.h b/components/esp32/include/soc/saradc_reg.h deleted file mode 100644 index 519032973a..0000000000 --- a/components/esp32/include/soc/saradc_reg.h +++ /dev/null @@ -1,1047 +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. -#ifndef _SOC_SARADC_REG_H_ -#define _SOC_SARADC_REG_H_ - - -#include "soc.h" -#define SARADC_SAR_READ_CTRL_REG (DR_REG_SARADC_BASE + 0x0000) -/* SARADC_SAR1_DATA_INV : R/W ;bitpos:[28] ;default: 1'd0 ; */ -/*description: Invert SAR ADC1 data*/ -#define SARADC_SAR1_DATA_INV (BIT(28)) -#define SARADC_SAR1_DATA_INV_M (BIT(28)) -#define SARADC_SAR1_DATA_INV_V 0x1 -#define SARADC_SAR1_DATA_INV_S 28 -/* SARADC_SAR1_DIG_FORCE : R/W ;bitpos:[27] ;default: 1'd0 ; */ -/*description: 1: SAR ADC1 controlled by DIG ADC1 CTRL 0: SAR ADC1 controlled by RTC ADC1 CTRL*/ -#define SARADC_SAR1_DIG_FORCE (BIT(27)) -#define SARADC_SAR1_DIG_FORCE_M (BIT(27)) -#define SARADC_SAR1_DIG_FORCE_V 0x1 -#define SARADC_SAR1_DIG_FORCE_S 27 -/* SARADC_SAR1_SAMPLE_NUM : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ -/*description: */ -#define SARADC_SAR1_SAMPLE_NUM 0x000000FF -#define SARADC_SAR1_SAMPLE_NUM_M ((SARADC_SAR1_SAMPLE_NUM_V)<<(SARADC_SAR1_SAMPLE_NUM_S)) -#define SARADC_SAR1_SAMPLE_NUM_V 0xFF -#define SARADC_SAR1_SAMPLE_NUM_S 19 -/* SARADC_SAR1_CLK_GATED : R/W ;bitpos:[18] ;default: 1'b1 ; */ -/*description: */ -#define SARADC_SAR1_CLK_GATED (BIT(18)) -#define SARADC_SAR1_CLK_GATED_M (BIT(18)) -#define SARADC_SAR1_CLK_GATED_V 0x1 -#define SARADC_SAR1_CLK_GATED_S 18 -/* SARADC_SAR1_SAMPLE_BIT : R/W ;bitpos:[17:16] ;default: 2'd3 ; */ -/*description: 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width - 11: for 12-bit width*/ -#define SARADC_SAR1_SAMPLE_BIT 0x00000003 -#define SARADC_SAR1_SAMPLE_BIT_M ((SARADC_SAR1_SAMPLE_BIT_V)<<(SARADC_SAR1_SAMPLE_BIT_S)) -#define SARADC_SAR1_SAMPLE_BIT_V 0x3 -#define SARADC_SAR1_SAMPLE_BIT_S 16 -/* SARADC_SAR1_SAMPLE_CYCLE : R/W ;bitpos:[15:8] ;default: 8'd9 ; */ -/*description: sample cycles for SAR ADC1*/ -#define SARADC_SAR1_SAMPLE_CYCLE 0x000000FF -#define SARADC_SAR1_SAMPLE_CYCLE_M ((SARADC_SAR1_SAMPLE_CYCLE_V)<<(SARADC_SAR1_SAMPLE_CYCLE_S)) -#define SARADC_SAR1_SAMPLE_CYCLE_V 0xFF -#define SARADC_SAR1_SAMPLE_CYCLE_S 8 -/* SARADC_SAR1_CLK_DIV : R/W ;bitpos:[7:0] ;default: 8'd2 ; */ -/*description: clock divider*/ -#define SARADC_SAR1_CLK_DIV 0x000000FF -#define SARADC_SAR1_CLK_DIV_M ((SARADC_SAR1_CLK_DIV_V)<<(SARADC_SAR1_CLK_DIV_S)) -#define SARADC_SAR1_CLK_DIV_V 0xFF -#define SARADC_SAR1_CLK_DIV_S 0 - -#define SARADC_SAR_READ_STATUS1_REG (DR_REG_SARADC_BASE + 0x0004) -/* SARADC_SAR1_READER_STATUS : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: */ -#define SARADC_SAR1_READER_STATUS 0xFFFFFFFF -#define SARADC_SAR1_READER_STATUS_M ((SARADC_SAR1_READER_STATUS_V)<<(SARADC_SAR1_READER_STATUS_S)) -#define SARADC_SAR1_READER_STATUS_V 0xFFFFFFFF -#define SARADC_SAR1_READER_STATUS_S 0 - -#define SARADC_SAR_MEAS_WAIT1_REG (DR_REG_SARADC_BASE + 0x0008) -/* SARADC_SAR_AMP_WAIT2 : R/W ;bitpos:[31:16] ;default: 16'd10 ; */ -/*description: */ -#define SARADC_SAR_AMP_WAIT2 0x0000FFFF -#define SARADC_SAR_AMP_WAIT2_M ((SARADC_SAR_AMP_WAIT2_V)<<(SARADC_SAR_AMP_WAIT2_S)) -#define SARADC_SAR_AMP_WAIT2_V 0xFFFF -#define SARADC_SAR_AMP_WAIT2_S 16 -/* SARADC_SAR_AMP_WAIT1 : R/W ;bitpos:[15:0] ;default: 16'd10 ; */ -/*description: */ -#define SARADC_SAR_AMP_WAIT1 0x0000FFFF -#define SARADC_SAR_AMP_WAIT1_M ((SARADC_SAR_AMP_WAIT1_V)<<(SARADC_SAR_AMP_WAIT1_S)) -#define SARADC_SAR_AMP_WAIT1_V 0xFFFF -#define SARADC_SAR_AMP_WAIT1_S 0 - -#define SARADC_SAR_MEAS_WAIT2_REG (DR_REG_SARADC_BASE + 0x000c) -/* SARADC_SAR2_RSTB_WAIT : R/W ;bitpos:[27:20] ;default: 8'd2 ; */ -/*description: */ -#define SARADC_SAR2_RSTB_WAIT 0x000000FF -#define SARADC_SAR2_RSTB_WAIT_M ((SARADC_SAR2_RSTB_WAIT_V)<<(SARADC_SAR2_RSTB_WAIT_S)) -#define SARADC_SAR2_RSTB_WAIT_V 0xFF -#define SARADC_SAR2_RSTB_WAIT_S 20 -/* SARADC_FORCE_XPD_SAR : R/W ;bitpos:[19:18] ;default: 2'd0 ; */ -/*description: */ -#define SARADC_FORCE_XPD_SAR 0x00000003 -#define SARADC_FORCE_XPD_SAR_M ((SARADC_FORCE_XPD_SAR_V)<<(SARADC_FORCE_XPD_SAR_S)) -#define SARADC_FORCE_XPD_SAR_V 0x3 -#define SARADC_FORCE_XPD_SAR_S 18 -/* SARADC_FORCE_XPD_AMP : R/W ;bitpos:[17:16] ;default: 2'd0 ; */ -/*description: */ -#define SARADC_FORCE_XPD_AMP 0x00000003 -#define SARADC_FORCE_XPD_AMP_M ((SARADC_FORCE_XPD_AMP_V)<<(SARADC_FORCE_XPD_AMP_S)) -#define SARADC_FORCE_XPD_AMP_V 0x3 -#define SARADC_FORCE_XPD_AMP_S 16 -/* SARADC_SAR_AMP_WAIT3 : R/W ;bitpos:[15:0] ;default: 16'd10 ; */ -/*description: */ -#define SARADC_SAR_AMP_WAIT3 0x0000FFFF -#define SARADC_SAR_AMP_WAIT3_M ((SARADC_SAR_AMP_WAIT3_V)<<(SARADC_SAR_AMP_WAIT3_S)) -#define SARADC_SAR_AMP_WAIT3_V 0xFFFF -#define SARADC_SAR_AMP_WAIT3_S 0 - -#define SARADC_SAR_MEAS_CTRL_REG (DR_REG_SARADC_BASE + 0x0010) -/* SARADC_SAR2_XPD_WAIT : R/W ;bitpos:[31:24] ;default: 8'h7 ; */ -/*description: */ -#define SARADC_SAR2_XPD_WAIT 0x000000FF -#define SARADC_SAR2_XPD_WAIT_M ((SARADC_SAR2_XPD_WAIT_V)<<(SARADC_SAR2_XPD_WAIT_S)) -#define SARADC_SAR2_XPD_WAIT_V 0xFF -#define SARADC_SAR2_XPD_WAIT_S 24 -/* SARADC_SAR_RSTB_FSM : R/W ;bitpos:[23:20] ;default: 4'b0000 ; */ -/*description: */ -#define SARADC_SAR_RSTB_FSM 0x0000000F -#define SARADC_SAR_RSTB_FSM_M ((SARADC_SAR_RSTB_FSM_V)<<(SARADC_SAR_RSTB_FSM_S)) -#define SARADC_SAR_RSTB_FSM_V 0xF -#define SARADC_SAR_RSTB_FSM_S 20 -/* SARADC_XPD_SAR_FSM : R/W ;bitpos:[19:16] ;default: 4'b0111 ; */ -/*description: */ -#define SARADC_XPD_SAR_FSM 0x0000000F -#define SARADC_XPD_SAR_FSM_M ((SARADC_XPD_SAR_FSM_V)<<(SARADC_XPD_SAR_FSM_S)) -#define SARADC_XPD_SAR_FSM_V 0xF -#define SARADC_XPD_SAR_FSM_S 16 -/* SARADC_AMP_SHORT_REF_GND_FSM : R/W ;bitpos:[15:12] ;default: 4'b0011 ; */ -/*description: */ -#define SARADC_AMP_SHORT_REF_GND_FSM 0x0000000F -#define SARADC_AMP_SHORT_REF_GND_FSM_M ((SARADC_AMP_SHORT_REF_GND_FSM_V)<<(SARADC_AMP_SHORT_REF_GND_FSM_S)) -#define SARADC_AMP_SHORT_REF_GND_FSM_V 0xF -#define SARADC_AMP_SHORT_REF_GND_FSM_S 12 -/* SARADC_AMP_SHORT_REF_FSM : R/W ;bitpos:[11:8] ;default: 4'b0011 ; */ -/*description: */ -#define SARADC_AMP_SHORT_REF_FSM 0x0000000F -#define SARADC_AMP_SHORT_REF_FSM_M ((SARADC_AMP_SHORT_REF_FSM_V)<<(SARADC_AMP_SHORT_REF_FSM_S)) -#define SARADC_AMP_SHORT_REF_FSM_V 0xF -#define SARADC_AMP_SHORT_REF_FSM_S 8 -/* SARADC_AMP_RST_FB_FSM : R/W ;bitpos:[7:4] ;default: 4'b1000 ; */ -/*description: */ -#define SARADC_AMP_RST_FB_FSM 0x0000000F -#define SARADC_AMP_RST_FB_FSM_M ((SARADC_AMP_RST_FB_FSM_V)<<(SARADC_AMP_RST_FB_FSM_S)) -#define SARADC_AMP_RST_FB_FSM_V 0xF -#define SARADC_AMP_RST_FB_FSM_S 4 -/* SARADC_XPD_SAR_AMP_FSM : R/W ;bitpos:[3:0] ;default: 4'b1111 ; */ -/*description: */ -#define SARADC_XPD_SAR_AMP_FSM 0x0000000F -#define SARADC_XPD_SAR_AMP_FSM_M ((SARADC_XPD_SAR_AMP_FSM_V)<<(SARADC_XPD_SAR_AMP_FSM_S)) -#define SARADC_XPD_SAR_AMP_FSM_V 0xF -#define SARADC_XPD_SAR_AMP_FSM_S 0 - -#define SARADC_SAR_READ_STATUS2_REG (DR_REG_SARADC_BASE + 0x0014) -/* SARADC_SAR2_READER_STATUS : RO ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: */ -#define SARADC_SAR2_READER_STATUS 0xFFFFFFFF -#define SARADC_SAR2_READER_STATUS_M ((SARADC_SAR2_READER_STATUS_V)<<(SARADC_SAR2_READER_STATUS_S)) -#define SARADC_SAR2_READER_STATUS_V 0xFFFFFFFF -#define SARADC_SAR2_READER_STATUS_S 0 - -#define SARADC_ULP_CP_SLEEP_CYC0_REG (DR_REG_SARADC_BASE + 0x0018) -/* SARADC_SLEEP_CYCLES_S0 : R/W ;bitpos:[31:0] ;default: 32'd200 ; */ -/*description: sleep cycles for ULP-coprocessor timer*/ -#define SARADC_SLEEP_CYCLES_S0 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S0_M ((SARADC_SLEEP_CYCLES_S0_V)<<(SARADC_SLEEP_CYCLES_S0_S)) -#define SARADC_SLEEP_CYCLES_S0_V 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S0_S 0 - -#define SARADC_ULP_CP_SLEEP_CYC1_REG (DR_REG_SARADC_BASE + 0x001c) -/* SARADC_SLEEP_CYCLES_S1 : R/W ;bitpos:[31:0] ;default: 32'd100 ; */ -/*description: */ -#define SARADC_SLEEP_CYCLES_S1 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S1_M ((SARADC_SLEEP_CYCLES_S1_V)<<(SARADC_SLEEP_CYCLES_S1_S)) -#define SARADC_SLEEP_CYCLES_S1_V 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S1_S 0 - -#define SARADC_ULP_CP_SLEEP_CYC2_REG (DR_REG_SARADC_BASE + 0x0020) -/* SARADC_SLEEP_CYCLES_S2 : R/W ;bitpos:[31:0] ;default: 32'd50 ; */ -/*description: */ -#define SARADC_SLEEP_CYCLES_S2 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S2_M ((SARADC_SLEEP_CYCLES_S2_V)<<(SARADC_SLEEP_CYCLES_S2_S)) -#define SARADC_SLEEP_CYCLES_S2_V 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S2_S 0 - -#define SARADC_ULP_CP_SLEEP_CYC3_REG (DR_REG_SARADC_BASE + 0x0024) -/* SARADC_SLEEP_CYCLES_S3 : R/W ;bitpos:[31:0] ;default: 32'd40 ; */ -/*description: */ -#define SARADC_SLEEP_CYCLES_S3 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S3_M ((SARADC_SLEEP_CYCLES_S3_V)<<(SARADC_SLEEP_CYCLES_S3_S)) -#define SARADC_SLEEP_CYCLES_S3_V 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S3_S 0 - -#define SARADC_ULP_CP_SLEEP_CYC4_REG (DR_REG_SARADC_BASE + 0x0028) -/* SARADC_SLEEP_CYCLES_S4 : R/W ;bitpos:[31:0] ;default: 32'd20 ; */ -/*description: */ -#define SARADC_SLEEP_CYCLES_S4 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S4_M ((SARADC_SLEEP_CYCLES_S4_V)<<(SARADC_SLEEP_CYCLES_S4_S)) -#define SARADC_SLEEP_CYCLES_S4_V 0xFFFFFFFF -#define SARADC_SLEEP_CYCLES_S4_S 0 - -#define SARADC_SAR_START_FORCE_REG (DR_REG_SARADC_BASE + 0x002c) -/* SARADC_SAR2_PWDET_EN : R/W ;bitpos:[24] ;default: 1'b0 ; */ -/*description: N/A*/ -#define SARADC_SAR2_PWDET_EN (BIT(24)) -#define SARADC_SAR2_PWDET_EN_M (BIT(24)) -#define SARADC_SAR2_PWDET_EN_V 0x1 -#define SARADC_SAR2_PWDET_EN_S 24 -/* SARADC_SAR1_STOP : R/W ;bitpos:[23] ;default: 1'b0 ; */ -/*description: stop SAR ADC1 conversion*/ -#define SARADC_SAR1_STOP (BIT(23)) -#define SARADC_SAR1_STOP_M (BIT(23)) -#define SARADC_SAR1_STOP_V 0x1 -#define SARADC_SAR1_STOP_S 23 -/* SARADC_SAR2_STOP : R/W ;bitpos:[22] ;default: 1'b0 ; */ -/*description: stop SAR ADC2 conversion*/ -#define SARADC_SAR2_STOP (BIT(22)) -#define SARADC_SAR2_STOP_M (BIT(22)) -#define SARADC_SAR2_STOP_V 0x1 -#define SARADC_SAR2_STOP_S 22 -/* SARADC_PC_INIT : R/W ;bitpos:[21:11] ;default: 11'b0 ; */ -/*description: initialized PC for ULP-coprocessor*/ -#define SARADC_PC_INIT 0x000007FF -#define SARADC_PC_INIT_M ((SARADC_PC_INIT_V)<<(SARADC_PC_INIT_S)) -#define SARADC_PC_INIT_V 0x7FF -#define SARADC_PC_INIT_S 11 -/* SARADC_SARCLK_EN : R/W ;bitpos:[10] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_SARCLK_EN (BIT(10)) -#define SARADC_SARCLK_EN_M (BIT(10)) -#define SARADC_SARCLK_EN_V 0x1 -#define SARADC_SARCLK_EN_S 10 -/* SARADC_ULP_CP_START_TOP : R/W ;bitpos:[9] ;default: 1'b0 ; */ -/*description: Write 1 to start ULP-coprocessor only active when reg_ulp_cp_force_start_top - = 1*/ -#define SARADC_ULP_CP_START_TOP (BIT(9)) -#define SARADC_ULP_CP_START_TOP_M (BIT(9)) -#define SARADC_ULP_CP_START_TOP_V 0x1 -#define SARADC_ULP_CP_START_TOP_S 9 -/* SARADC_ULP_CP_FORCE_START_TOP : R/W ;bitpos:[8] ;default: 1'b0 ; */ -/*description: 1: ULP-coprocessor is started by SW 0: ULP-coprocessor is started by timer*/ -#define SARADC_ULP_CP_FORCE_START_TOP (BIT(8)) -#define SARADC_ULP_CP_FORCE_START_TOP_M (BIT(8)) -#define SARADC_ULP_CP_FORCE_START_TOP_V 0x1 -#define SARADC_ULP_CP_FORCE_START_TOP_S 8 -/* SARADC_SAR2_PWDET_CCT : R/W ;bitpos:[7:5] ;default: 3'b0 ; */ -/*description: SAR2_PWDET_CCT PA power detector capacitance tuning.*/ -#define SARADC_SAR2_PWDET_CCT 0x00000007 -#define SARADC_SAR2_PWDET_CCT_M ((SARADC_SAR2_PWDET_CCT_V)<<(SARADC_SAR2_PWDET_CCT_S)) -#define SARADC_SAR2_PWDET_CCT_V 0x7 -#define SARADC_SAR2_PWDET_CCT_S 5 -/* SARADC_SAR2_EN_TEST : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: SAR2_EN_TEST only active when reg_sar2_dig_force = 0*/ -#define SARADC_SAR2_EN_TEST (BIT(4)) -#define SARADC_SAR2_EN_TEST_M (BIT(4)) -#define SARADC_SAR2_EN_TEST_V 0x1 -#define SARADC_SAR2_EN_TEST_S 4 -/* SARADC_SAR2_BIT_WIDTH : R/W ;bitpos:[3:2] ;default: 2'b11 ; */ -/*description: 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits*/ -#define SARADC_SAR2_BIT_WIDTH 0x00000003 -#define SARADC_SAR2_BIT_WIDTH_M ((SARADC_SAR2_BIT_WIDTH_V)<<(SARADC_SAR2_BIT_WIDTH_S)) -#define SARADC_SAR2_BIT_WIDTH_V 0x3 -#define SARADC_SAR2_BIT_WIDTH_S 2 -/* SARADC_SAR1_BIT_WIDTH : R/W ;bitpos:[1:0] ;default: 2'b11 ; */ -/*description: 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits*/ -#define SARADC_SAR1_BIT_WIDTH 0x00000003 -#define SARADC_SAR1_BIT_WIDTH_M ((SARADC_SAR1_BIT_WIDTH_V)<<(SARADC_SAR1_BIT_WIDTH_S)) -#define SARADC_SAR1_BIT_WIDTH_V 0x3 -#define SARADC_SAR1_BIT_WIDTH_S 0 - -#define SARADC_SAR_MEM_WR_CTRL_REG (DR_REG_SARADC_BASE + 0x0030) -/* SARADC_RTC_MEM_WR_OFFST_CLR : WO ;bitpos:[22] ;default: 1'd0 ; */ -/*description: */ -#define SARADC_RTC_MEM_WR_OFFST_CLR (BIT(22)) -#define SARADC_RTC_MEM_WR_OFFST_CLR_M (BIT(22)) -#define SARADC_RTC_MEM_WR_OFFST_CLR_V 0x1 -#define SARADC_RTC_MEM_WR_OFFST_CLR_S 22 -/* SARADC_MEM_WR_ADDR_SIZE : R/W ;bitpos:[21:11] ;default: 11'd512 ; */ -/*description: */ -#define SARADC_MEM_WR_ADDR_SIZE 0x000007FF -#define SARADC_MEM_WR_ADDR_SIZE_M ((SARADC_MEM_WR_ADDR_SIZE_V)<<(SARADC_MEM_WR_ADDR_SIZE_S)) -#define SARADC_MEM_WR_ADDR_SIZE_V 0x7FF -#define SARADC_MEM_WR_ADDR_SIZE_S 11 -/* SARADC_MEM_WR_ADDR_INIT : R/W ;bitpos:[10:0] ;default: 11'd512 ; */ -/*description: */ -#define SARADC_MEM_WR_ADDR_INIT 0x000007FF -#define SARADC_MEM_WR_ADDR_INIT_M ((SARADC_MEM_WR_ADDR_INIT_V)<<(SARADC_MEM_WR_ADDR_INIT_S)) -#define SARADC_MEM_WR_ADDR_INIT_V 0x7FF -#define SARADC_MEM_WR_ADDR_INIT_S 0 - -#define SARADC_SAR_ATTEN1_REG (DR_REG_SARADC_BASE + 0x0034) -/* SARADC_SAR1_ATTEN : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */ -/*description: 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB*/ -#define SARADC_SAR1_ATTEN 0xFFFFFFFF -#define SARADC_SAR1_ATTEN_M ((SARADC_SAR1_ATTEN_V)<<(SARADC_SAR1_ATTEN_S)) -#define SARADC_SAR1_ATTEN_V 0xFFFFFFFF -#define SARADC_SAR1_ATTEN_S 0 - -#define SARADC_SAR_ATTEN2_REG (DR_REG_SARADC_BASE + 0x0038) -/* SARADC_SAR2_ATTEN : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */ -/*description: 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB*/ -#define SARADC_SAR2_ATTEN 0xFFFFFFFF -#define SARADC_SAR2_ATTEN_M ((SARADC_SAR2_ATTEN_V)<<(SARADC_SAR2_ATTEN_S)) -#define SARADC_SAR2_ATTEN_V 0xFFFFFFFF -#define SARADC_SAR2_ATTEN_S 0 - -#define SARADC_SAR_SLAVE_ADDR1_REG (DR_REG_SARADC_BASE + 0x003c) -/* SARADC_MEAS_STATUS : RO ;bitpos:[29:22] ;default: 8'h0 ; */ -/*description: */ -#define SARADC_MEAS_STATUS 0x000000FF -#define SARADC_MEAS_STATUS_M ((SARADC_MEAS_STATUS_V)<<(SARADC_MEAS_STATUS_S)) -#define SARADC_MEAS_STATUS_V 0xFF -#define SARADC_MEAS_STATUS_S 22 -/* SARADC_I2C_SLAVE_ADDR0 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR0 0x000007FF -#define SARADC_I2C_SLAVE_ADDR0_M ((SARADC_I2C_SLAVE_ADDR0_V)<<(SARADC_I2C_SLAVE_ADDR0_S)) -#define SARADC_I2C_SLAVE_ADDR0_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR0_S 11 -/* SARADC_I2C_SLAVE_ADDR1 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR1 0x000007FF -#define SARADC_I2C_SLAVE_ADDR1_M ((SARADC_I2C_SLAVE_ADDR1_V)<<(SARADC_I2C_SLAVE_ADDR1_S)) -#define SARADC_I2C_SLAVE_ADDR1_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR1_S 0 - -#define SARADC_SAR_SLAVE_ADDR2_REG (DR_REG_SARADC_BASE + 0x0040) -/* SARADC_I2C_SLAVE_ADDR2 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR2 0x000007FF -#define SARADC_I2C_SLAVE_ADDR2_M ((SARADC_I2C_SLAVE_ADDR2_V)<<(SARADC_I2C_SLAVE_ADDR2_S)) -#define SARADC_I2C_SLAVE_ADDR2_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR2_S 11 -/* SARADC_I2C_SLAVE_ADDR3 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR3 0x000007FF -#define SARADC_I2C_SLAVE_ADDR3_M ((SARADC_I2C_SLAVE_ADDR3_V)<<(SARADC_I2C_SLAVE_ADDR3_S)) -#define SARADC_I2C_SLAVE_ADDR3_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR3_S 0 - -#define SARADC_SAR_SLAVE_ADDR3_REG (DR_REG_SARADC_BASE + 0x0044) -/* SARADC_TSENS_RDY_OUT : RO ;bitpos:[30] ;default: 1'h0 ; */ -/*description: indicate temperature sensor out ready*/ -#define SARADC_TSENS_RDY_OUT (BIT(30)) -#define SARADC_TSENS_RDY_OUT_M (BIT(30)) -#define SARADC_TSENS_RDY_OUT_V 0x1 -#define SARADC_TSENS_RDY_OUT_S 30 -/* SARADC_TSENS_OUT : RO ;bitpos:[29:22] ;default: 8'h0 ; */ -/*description: temperature sensor data out*/ -#define SARADC_TSENS_OUT 0x000000FF -#define SARADC_TSENS_OUT_M ((SARADC_TSENS_OUT_V)<<(SARADC_TSENS_OUT_S)) -#define SARADC_TSENS_OUT_V 0xFF -#define SARADC_TSENS_OUT_S 22 -/* SARADC_I2C_SLAVE_ADDR4 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR4 0x000007FF -#define SARADC_I2C_SLAVE_ADDR4_M ((SARADC_I2C_SLAVE_ADDR4_V)<<(SARADC_I2C_SLAVE_ADDR4_S)) -#define SARADC_I2C_SLAVE_ADDR4_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR4_S 11 -/* SARADC_I2C_SLAVE_ADDR5 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR5 0x000007FF -#define SARADC_I2C_SLAVE_ADDR5_M ((SARADC_I2C_SLAVE_ADDR5_V)<<(SARADC_I2C_SLAVE_ADDR5_S)) -#define SARADC_I2C_SLAVE_ADDR5_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR5_S 0 - -#define SARADC_SAR_SLAVE_ADDR4_REG (DR_REG_SARADC_BASE + 0x0048) -/* SARADC_I2C_DONE : RO ;bitpos:[30] ;default: 1'h0 ; */ -/*description: indicate I2C done*/ -#define SARADC_I2C_DONE (BIT(30)) -#define SARADC_I2C_DONE_M (BIT(30)) -#define SARADC_I2C_DONE_V 0x1 -#define SARADC_I2C_DONE_S 30 -/* SARADC_I2C_RDATA : RO ;bitpos:[29:22] ;default: 8'h0 ; */ -/*description: I2C read data*/ -#define SARADC_I2C_RDATA 0x000000FF -#define SARADC_I2C_RDATA_M ((SARADC_I2C_RDATA_V)<<(SARADC_I2C_RDATA_S)) -#define SARADC_I2C_RDATA_V 0xFF -#define SARADC_I2C_RDATA_S 22 -/* SARADC_I2C_SLAVE_ADDR6 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR6 0x000007FF -#define SARADC_I2C_SLAVE_ADDR6_M ((SARADC_I2C_SLAVE_ADDR6_V)<<(SARADC_I2C_SLAVE_ADDR6_S)) -#define SARADC_I2C_SLAVE_ADDR6_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR6_S 11 -/* SARADC_I2C_SLAVE_ADDR7 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ -/*description: */ -#define SARADC_I2C_SLAVE_ADDR7 0x000007FF -#define SARADC_I2C_SLAVE_ADDR7_M ((SARADC_I2C_SLAVE_ADDR7_V)<<(SARADC_I2C_SLAVE_ADDR7_S)) -#define SARADC_I2C_SLAVE_ADDR7_V 0x7FF -#define SARADC_I2C_SLAVE_ADDR7_S 0 - -#define SARADC_SAR_TSENS_CTRL_REG (DR_REG_SARADC_BASE + 0x004c) -/* SARADC_TSENS_DUMP_OUT : R/W ;bitpos:[26] ;default: 1'b0 ; */ -/*description: temperature sensor dump out only active when reg_tsens_power_up_force = 1*/ -#define SARADC_TSENS_DUMP_OUT (BIT(26)) -#define SARADC_TSENS_DUMP_OUT_M (BIT(26)) -#define SARADC_TSENS_DUMP_OUT_V 0x1 -#define SARADC_TSENS_DUMP_OUT_S 26 -/* SARADC_TSENS_POWER_UP_FORCE : R/W ;bitpos:[25] ;default: 1'b0 ; */ -/*description: 1: dump out & power up controlled by SW 0: by FSM*/ -#define SARADC_TSENS_POWER_UP_FORCE (BIT(25)) -#define SARADC_TSENS_POWER_UP_FORCE_M (BIT(25)) -#define SARADC_TSENS_POWER_UP_FORCE_V 0x1 -#define SARADC_TSENS_POWER_UP_FORCE_S 25 -/* SARADC_TSENS_POWER_UP : R/W ;bitpos:[24] ;default: 1'b0 ; */ -/*description: temperature sensor power up*/ -#define SARADC_TSENS_POWER_UP (BIT(24)) -#define SARADC_TSENS_POWER_UP_M (BIT(24)) -#define SARADC_TSENS_POWER_UP_V 0x1 -#define SARADC_TSENS_POWER_UP_S 24 -/* SARADC_TSENS_CLK_DIV : R/W ;bitpos:[23:16] ;default: 8'd6 ; */ -/*description: temperature sensor clock divider*/ -#define SARADC_TSENS_CLK_DIV 0x000000FF -#define SARADC_TSENS_CLK_DIV_M ((SARADC_TSENS_CLK_DIV_V)<<(SARADC_TSENS_CLK_DIV_S)) -#define SARADC_TSENS_CLK_DIV_V 0xFF -#define SARADC_TSENS_CLK_DIV_S 16 -/* SARADC_TSENS_IN_INV : R/W ;bitpos:[15] ;default: 1'b0 ; */ -/*description: invert temperature sensor data*/ -#define SARADC_TSENS_IN_INV (BIT(15)) -#define SARADC_TSENS_IN_INV_M (BIT(15)) -#define SARADC_TSENS_IN_INV_V 0x1 -#define SARADC_TSENS_IN_INV_S 15 -/* SARADC_TSENS_CLK_GATED : R/W ;bitpos:[14] ;default: 1'b1 ; */ -/*description: */ -#define SARADC_TSENS_CLK_GATED (BIT(14)) -#define SARADC_TSENS_CLK_GATED_M (BIT(14)) -#define SARADC_TSENS_CLK_GATED_V 0x1 -#define SARADC_TSENS_CLK_GATED_S 14 -/* SARADC_TSENS_CLK_INV : R/W ;bitpos:[13] ;default: 1'b1 ; */ -/*description: */ -#define SARADC_TSENS_CLK_INV (BIT(13)) -#define SARADC_TSENS_CLK_INV_M (BIT(13)) -#define SARADC_TSENS_CLK_INV_V 0x1 -#define SARADC_TSENS_CLK_INV_S 13 -/* SARADC_TSENS_XPD_FORCE : R/W ;bitpos:[12] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_TSENS_XPD_FORCE (BIT(12)) -#define SARADC_TSENS_XPD_FORCE_M (BIT(12)) -#define SARADC_TSENS_XPD_FORCE_V 0x1 -#define SARADC_TSENS_XPD_FORCE_S 12 -/* SARADC_TSENS_XPD_WAIT : R/W ;bitpos:[11:0] ;default: 12'h2 ; */ -/*description: */ -#define SARADC_TSENS_XPD_WAIT 0x00000FFF -#define SARADC_TSENS_XPD_WAIT_M ((SARADC_TSENS_XPD_WAIT_V)<<(SARADC_TSENS_XPD_WAIT_S)) -#define SARADC_TSENS_XPD_WAIT_V 0xFFF -#define SARADC_TSENS_XPD_WAIT_S 0 - -#define SARADC_SAR_I2C_CTRL_REG (DR_REG_SARADC_BASE + 0x0050) -/* SARADC_SAR_I2C_START_FORCE : R/W ;bitpos:[29] ;default: 1'b0 ; */ -/*description: 1: I2C started by SW 0: I2C started by FSM*/ -#define SARADC_SAR_I2C_START_FORCE (BIT(29)) -#define SARADC_SAR_I2C_START_FORCE_M (BIT(29)) -#define SARADC_SAR_I2C_START_FORCE_V 0x1 -#define SARADC_SAR_I2C_START_FORCE_S 29 -/* SARADC_SAR_I2C_START : R/W ;bitpos:[28] ;default: 1'b0 ; */ -/*description: start I2C only active when reg_sar_i2c_start_force = 1*/ -#define SARADC_SAR_I2C_START (BIT(28)) -#define SARADC_SAR_I2C_START_M (BIT(28)) -#define SARADC_SAR_I2C_START_V 0x1 -#define SARADC_SAR_I2C_START_S 28 -/* SARADC_SAR_I2C_CTRL : R/W ;bitpos:[27:0] ;default: 28'b0 ; */ -/*description: I2C control data only active when reg_sar_i2c_start_force = 1*/ -#define SARADC_SAR_I2C_CTRL 0x0FFFFFFF -#define SARADC_SAR_I2C_CTRL_M ((SARADC_SAR_I2C_CTRL_V)<<(SARADC_SAR_I2C_CTRL_S)) -#define SARADC_SAR_I2C_CTRL_V 0xFFFFFFF -#define SARADC_SAR_I2C_CTRL_S 0 - -#define SARADC_SAR_MEAS_START1_REG (DR_REG_SARADC_BASE + 0x0054) -/* SARADC_SAR1_EN_PAD_FORCE : R/W ;bitpos:[31] ;default: 1'b0 ; */ -/*description: 1: SAR ADC1 pad enable bitmap is controlled by SW 0: SAR ADC1 - pad enable bitmap is controlled by ULP-coprocessor*/ -#define SARADC_SAR1_EN_PAD_FORCE (BIT(31)) -#define SARADC_SAR1_EN_PAD_FORCE_M (BIT(31)) -#define SARADC_SAR1_EN_PAD_FORCE_V 0x1 -#define SARADC_SAR1_EN_PAD_FORCE_S 31 -/* SARADC_SAR1_EN_PAD : R/W ;bitpos:[30:19] ;default: 12'b0 ; */ -/*description: SAR ADC1 pad enable bitmap only active when reg_sar1_en_pad_force = 1*/ -#define SARADC_SAR1_EN_PAD 0x00000FFF -#define SARADC_SAR1_EN_PAD_M ((SARADC_SAR1_EN_PAD_V)<<(SARADC_SAR1_EN_PAD_S)) -#define SARADC_SAR1_EN_PAD_V 0xFFF -#define SARADC_SAR1_EN_PAD_S 19 -/* SARADC_MEAS1_START_FORCE : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: 1: SAR ADC1 controller (in RTC) is started by SW 0: SAR ADC1 - controller is started by ULP-coprocessor*/ -#define SARADC_MEAS1_START_FORCE (BIT(18)) -#define SARADC_MEAS1_START_FORCE_M (BIT(18)) -#define SARADC_MEAS1_START_FORCE_V 0x1 -#define SARADC_MEAS1_START_FORCE_S 18 -/* SARADC_MEAS1_START_SAR : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: SAR ADC1 controller (in RTC) starts conversion only active when - reg_meas1_start_force = 1*/ -#define SARADC_MEAS1_START_SAR (BIT(17)) -#define SARADC_MEAS1_START_SAR_M (BIT(17)) -#define SARADC_MEAS1_START_SAR_V 0x1 -#define SARADC_MEAS1_START_SAR_S 17 -/* SARADC_MEAS1_DONE_SAR : RO ;bitpos:[16] ;default: 1'b0 ; */ -/*description: SAR ADC1 conversion done indication*/ -#define SARADC_MEAS1_DONE_SAR (BIT(16)) -#define SARADC_MEAS1_DONE_SAR_M (BIT(16)) -#define SARADC_MEAS1_DONE_SAR_V 0x1 -#define SARADC_MEAS1_DONE_SAR_S 16 -/* SARADC_MEAS1_DATA_SAR : RO ;bitpos:[15:0] ;default: 16'b0 ; */ -/*description: SAR ADC1 data*/ -#define SARADC_MEAS1_DATA_SAR 0x0000FFFF -#define SARADC_MEAS1_DATA_SAR_M ((SARADC_MEAS1_DATA_SAR_V)<<(SARADC_MEAS1_DATA_SAR_S)) -#define SARADC_MEAS1_DATA_SAR_V 0xFFFF -#define SARADC_MEAS1_DATA_SAR_S 0 - -#define SARADC_SAR_TOUCH_CTRL1_REG (DR_REG_SARADC_BASE + 0x0058) -/* SARADC_HALL_PHASE_FORCE : R/W ;bitpos:[27] ;default: 1'b0 ; */ -/*description: 1: HALL PHASE is controlled by SW 0: HALL PHASE is controlled - by FSM in ULP-coprocessor*/ -#define SARADC_HALL_PHASE_FORCE (BIT(27)) -#define SARADC_HALL_PHASE_FORCE_M (BIT(27)) -#define SARADC_HALL_PHASE_FORCE_V 0x1 -#define SARADC_HALL_PHASE_FORCE_S 27 -/* SARADC_XPD_HALL_FORCE : R/W ;bitpos:[26] ;default: 1'b0 ; */ -/*description: 1: XPD HALL is controlled by SW. 0: XPD HALL is controlled by - FSM in ULP-coprocessor*/ -#define SARADC_XPD_HALL_FORCE (BIT(26)) -#define SARADC_XPD_HALL_FORCE_M (BIT(26)) -#define SARADC_XPD_HALL_FORCE_V 0x1 -#define SARADC_XPD_HALL_FORCE_S 26 -/* SARADC_TOUCH_OUT_1EN : R/W ;bitpos:[25] ;default: 1'b1 ; */ -/*description: 1: wakeup interrupt is generated if SET1 is "touched" 0: - wakeup interrupt is generated only if SET1 & SET2 is both "touched"*/ -#define SARADC_TOUCH_OUT_1EN (BIT(25)) -#define SARADC_TOUCH_OUT_1EN_M (BIT(25)) -#define SARADC_TOUCH_OUT_1EN_V 0x1 -#define SARADC_TOUCH_OUT_1EN_S 25 -/* SARADC_TOUCH_OUT_SEL : R/W ;bitpos:[24] ;default: 1'b0 ; */ -/*description: 1: when the counter is greater then the threshold the touch - pad is considered as "touched" 0: when the counter is less than the threshold the touch pad is considered as "touched"*/ -#define SARADC_TOUCH_OUT_SEL (BIT(24)) -#define SARADC_TOUCH_OUT_SEL_M (BIT(24)) -#define SARADC_TOUCH_OUT_SEL_V 0x1 -#define SARADC_TOUCH_OUT_SEL_S 24 -/* SARADC_TOUCH_XPD_WAIT : R/W ;bitpos:[23:16] ;default: 8'h4 ; */ -/*description: the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD*/ -#define SARADC_TOUCH_XPD_WAIT 0x000000FF -#define SARADC_TOUCH_XPD_WAIT_M ((SARADC_TOUCH_XPD_WAIT_V)<<(SARADC_TOUCH_XPD_WAIT_S)) -#define SARADC_TOUCH_XPD_WAIT_V 0xFF -#define SARADC_TOUCH_XPD_WAIT_S 16 -/* SARADC_TOUCH_MEAS_DELAY : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */ -/*description: the meas length (in 8MHz)*/ -#define SARADC_TOUCH_MEAS_DELAY 0x0000FFFF -#define SARADC_TOUCH_MEAS_DELAY_M ((SARADC_TOUCH_MEAS_DELAY_V)<<(SARADC_TOUCH_MEAS_DELAY_S)) -#define SARADC_TOUCH_MEAS_DELAY_V 0xFFFF -#define SARADC_TOUCH_MEAS_DELAY_S 0 - -#define SARADC_SAR_TOUCH_THRES1_REG (DR_REG_SARADC_BASE + 0x005c) -/* SARADC_TOUCH_OUT_TH0 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 0*/ -#define SARADC_TOUCH_OUT_TH0 0x0000FFFF -#define SARADC_TOUCH_OUT_TH0_M ((SARADC_TOUCH_OUT_TH0_V)<<(SARADC_TOUCH_OUT_TH0_S)) -#define SARADC_TOUCH_OUT_TH0_V 0xFFFF -#define SARADC_TOUCH_OUT_TH0_S 16 -/* SARADC_TOUCH_OUT_TH1 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 1*/ -#define SARADC_TOUCH_OUT_TH1 0x0000FFFF -#define SARADC_TOUCH_OUT_TH1_M ((SARADC_TOUCH_OUT_TH1_V)<<(SARADC_TOUCH_OUT_TH1_S)) -#define SARADC_TOUCH_OUT_TH1_V 0xFFFF -#define SARADC_TOUCH_OUT_TH1_S 0 - -#define SARADC_SAR_TOUCH_THRES2_REG (DR_REG_SARADC_BASE + 0x0060) -/* SARADC_TOUCH_OUT_TH2 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 2*/ -#define SARADC_TOUCH_OUT_TH2 0x0000FFFF -#define SARADC_TOUCH_OUT_TH2_M ((SARADC_TOUCH_OUT_TH2_V)<<(SARADC_TOUCH_OUT_TH2_S)) -#define SARADC_TOUCH_OUT_TH2_V 0xFFFF -#define SARADC_TOUCH_OUT_TH2_S 16 -/* SARADC_TOUCH_OUT_TH3 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 3*/ -#define SARADC_TOUCH_OUT_TH3 0x0000FFFF -#define SARADC_TOUCH_OUT_TH3_M ((SARADC_TOUCH_OUT_TH3_V)<<(SARADC_TOUCH_OUT_TH3_S)) -#define SARADC_TOUCH_OUT_TH3_V 0xFFFF -#define SARADC_TOUCH_OUT_TH3_S 0 - -#define SARADC_SAR_TOUCH_THRES3_REG (DR_REG_SARADC_BASE + 0x0064) -/* SARADC_TOUCH_OUT_TH4 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 4*/ -#define SARADC_TOUCH_OUT_TH4 0x0000FFFF -#define SARADC_TOUCH_OUT_TH4_M ((SARADC_TOUCH_OUT_TH4_V)<<(SARADC_TOUCH_OUT_TH4_S)) -#define SARADC_TOUCH_OUT_TH4_V 0xFFFF -#define SARADC_TOUCH_OUT_TH4_S 16 -/* SARADC_TOUCH_OUT_TH5 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 5*/ -#define SARADC_TOUCH_OUT_TH5 0x0000FFFF -#define SARADC_TOUCH_OUT_TH5_M ((SARADC_TOUCH_OUT_TH5_V)<<(SARADC_TOUCH_OUT_TH5_S)) -#define SARADC_TOUCH_OUT_TH5_V 0xFFFF -#define SARADC_TOUCH_OUT_TH5_S 0 - -#define SARADC_SAR_TOUCH_THRES4_REG (DR_REG_SARADC_BASE + 0x0068) -/* SARADC_TOUCH_OUT_TH6 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 6*/ -#define SARADC_TOUCH_OUT_TH6 0x0000FFFF -#define SARADC_TOUCH_OUT_TH6_M ((SARADC_TOUCH_OUT_TH6_V)<<(SARADC_TOUCH_OUT_TH6_S)) -#define SARADC_TOUCH_OUT_TH6_V 0xFFFF -#define SARADC_TOUCH_OUT_TH6_S 16 -/* SARADC_TOUCH_OUT_TH7 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 7*/ -#define SARADC_TOUCH_OUT_TH7 0x0000FFFF -#define SARADC_TOUCH_OUT_TH7_M ((SARADC_TOUCH_OUT_TH7_V)<<(SARADC_TOUCH_OUT_TH7_S)) -#define SARADC_TOUCH_OUT_TH7_V 0xFFFF -#define SARADC_TOUCH_OUT_TH7_S 0 - -#define SARADC_SAR_TOUCH_THRES5_REG (DR_REG_SARADC_BASE + 0x006c) -/* SARADC_TOUCH_OUT_TH8 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 8*/ -#define SARADC_TOUCH_OUT_TH8 0x0000FFFF -#define SARADC_TOUCH_OUT_TH8_M ((SARADC_TOUCH_OUT_TH8_V)<<(SARADC_TOUCH_OUT_TH8_S)) -#define SARADC_TOUCH_OUT_TH8_V 0xFFFF -#define SARADC_TOUCH_OUT_TH8_S 16 -/* SARADC_TOUCH_OUT_TH9 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the threshold for touch pad 9*/ -#define SARADC_TOUCH_OUT_TH9 0x0000FFFF -#define SARADC_TOUCH_OUT_TH9_M ((SARADC_TOUCH_OUT_TH9_V)<<(SARADC_TOUCH_OUT_TH9_S)) -#define SARADC_TOUCH_OUT_TH9_V 0xFFFF -#define SARADC_TOUCH_OUT_TH9_S 0 - -#define SARADC_SAR_TOUCH_OUT1_REG (DR_REG_SARADC_BASE + 0x0070) -/* SARADC_TOUCH_MEAS_OUT0 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the counter for touch pad 0*/ -#define SARADC_TOUCH_MEAS_OUT0 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT0_M ((SARADC_TOUCH_MEAS_OUT0_V)<<(SARADC_TOUCH_MEAS_OUT0_S)) -#define SARADC_TOUCH_MEAS_OUT0_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT0_S 16 -/* SARADC_TOUCH_MEAS_OUT1 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the counter for touch pad 1*/ -#define SARADC_TOUCH_MEAS_OUT1 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT1_M ((SARADC_TOUCH_MEAS_OUT1_V)<<(SARADC_TOUCH_MEAS_OUT1_S)) -#define SARADC_TOUCH_MEAS_OUT1_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT1_S 0 - -#define SARADC_SAR_TOUCH_OUT2_REG (DR_REG_SARADC_BASE + 0x0074) -/* SARADC_TOUCH_MEAS_OUT2 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the counter for touch pad 2*/ -#define SARADC_TOUCH_MEAS_OUT2 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT2_M ((SARADC_TOUCH_MEAS_OUT2_V)<<(SARADC_TOUCH_MEAS_OUT2_S)) -#define SARADC_TOUCH_MEAS_OUT2_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT2_S 16 -/* SARADC_TOUCH_MEAS_OUT3 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the counter for touch pad 3*/ -#define SARADC_TOUCH_MEAS_OUT3 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT3_M ((SARADC_TOUCH_MEAS_OUT3_V)<<(SARADC_TOUCH_MEAS_OUT3_S)) -#define SARADC_TOUCH_MEAS_OUT3_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT3_S 0 - -#define SARADC_SAR_TOUCH_OUT3_REG (DR_REG_SARADC_BASE + 0x0078) -/* SARADC_TOUCH_MEAS_OUT4 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the counter for touch pad 4*/ -#define SARADC_TOUCH_MEAS_OUT4 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT4_M ((SARADC_TOUCH_MEAS_OUT4_V)<<(SARADC_TOUCH_MEAS_OUT4_S)) -#define SARADC_TOUCH_MEAS_OUT4_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT4_S 16 -/* SARADC_TOUCH_MEAS_OUT5 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the counter for touch pad 5*/ -#define SARADC_TOUCH_MEAS_OUT5 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT5_M ((SARADC_TOUCH_MEAS_OUT5_V)<<(SARADC_TOUCH_MEAS_OUT5_S)) -#define SARADC_TOUCH_MEAS_OUT5_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT5_S 0 - -#define SARADC_SAR_TOUCH_OUT4_REG (DR_REG_SARADC_BASE + 0x007c) -/* SARADC_TOUCH_MEAS_OUT6 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the counter for touch pad 6*/ -#define SARADC_TOUCH_MEAS_OUT6 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT6_M ((SARADC_TOUCH_MEAS_OUT6_V)<<(SARADC_TOUCH_MEAS_OUT6_S)) -#define SARADC_TOUCH_MEAS_OUT6_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT6_S 16 -/* SARADC_TOUCH_MEAS_OUT7 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the counter for touch pad 7*/ -#define SARADC_TOUCH_MEAS_OUT7 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT7_M ((SARADC_TOUCH_MEAS_OUT7_V)<<(SARADC_TOUCH_MEAS_OUT7_S)) -#define SARADC_TOUCH_MEAS_OUT7_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT7_S 0 - -#define SARADC_SAR_TOUCH_OUT5_REG (DR_REG_SARADC_BASE + 0x0080) -/* SARADC_TOUCH_MEAS_OUT8 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ -/*description: the counter for touch pad 8*/ -#define SARADC_TOUCH_MEAS_OUT8 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT8_M ((SARADC_TOUCH_MEAS_OUT8_V)<<(SARADC_TOUCH_MEAS_OUT8_S)) -#define SARADC_TOUCH_MEAS_OUT8_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT8_S 16 -/* SARADC_TOUCH_MEAS_OUT9 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ -/*description: the counter for touch pad 9*/ -#define SARADC_TOUCH_MEAS_OUT9 0x0000FFFF -#define SARADC_TOUCH_MEAS_OUT9_M ((SARADC_TOUCH_MEAS_OUT9_V)<<(SARADC_TOUCH_MEAS_OUT9_S)) -#define SARADC_TOUCH_MEAS_OUT9_V 0xFFFF -#define SARADC_TOUCH_MEAS_OUT9_S 0 - -#define SARADC_SAR_TOUCH_CTRL2_REG (DR_REG_SARADC_BASE + 0x0084) -/* SARADC_TOUCH_MEAS_EN_CLR : WO ;bitpos:[30] ;default: 1'h0 ; */ -/*description: to clear reg_touch_meas_en*/ -#define SARADC_TOUCH_MEAS_EN_CLR (BIT(30)) -#define SARADC_TOUCH_MEAS_EN_CLR_M (BIT(30)) -#define SARADC_TOUCH_MEAS_EN_CLR_V 0x1 -#define SARADC_TOUCH_MEAS_EN_CLR_S 30 -/* SARADC_TOUCH_SLEEP_CYCLES : R/W ;bitpos:[29:14] ;default: 16'h100 ; */ -/*description: sleep cycles for timer*/ -#define SARADC_TOUCH_SLEEP_CYCLES 0x0000FFFF -#define SARADC_TOUCH_SLEEP_CYCLES_M ((SARADC_TOUCH_SLEEP_CYCLES_V)<<(SARADC_TOUCH_SLEEP_CYCLES_S)) -#define SARADC_TOUCH_SLEEP_CYCLES_V 0xFFFF -#define SARADC_TOUCH_SLEEP_CYCLES_S 14 -/* SARADC_TOUCH_START_FORCE : R/W ;bitpos:[13] ;default: 1'h0 ; */ -/*description: 1: to start touch fsm by SW 0: to start touch fsm by timer*/ -#define SARADC_TOUCH_START_FORCE (BIT(13)) -#define SARADC_TOUCH_START_FORCE_M (BIT(13)) -#define SARADC_TOUCH_START_FORCE_V 0x1 -#define SARADC_TOUCH_START_FORCE_S 13 -/* SARADC_TOUCH_START_EN : R/W ;bitpos:[12] ;default: 1'h0 ; */ -/*description: 1: start touch fsm valid when reg_touch_start_force is set*/ -#define SARADC_TOUCH_START_EN (BIT(12)) -#define SARADC_TOUCH_START_EN_M (BIT(12)) -#define SARADC_TOUCH_START_EN_V 0x1 -#define SARADC_TOUCH_START_EN_S 12 -/* SARADC_TOUCH_START_FSM_EN : R/W ;bitpos:[11] ;default: 1'h1 ; */ -/*description: 1: TOUCH_START & TOUCH_XPD is controlled by touch fsm 0: TOUCH_START - & TOUCH_XPD is controlled by registers*/ -#define SARADC_TOUCH_START_FSM_EN (BIT(11)) -#define SARADC_TOUCH_START_FSM_EN_M (BIT(11)) -#define SARADC_TOUCH_START_FSM_EN_V 0x1 -#define SARADC_TOUCH_START_FSM_EN_S 11 -/* SARADC_TOUCH_MEAS_DONE : RO ;bitpos:[10] ;default: 1'h0 ; */ -/*description: fsm set 1 to indicate touch touch meas is done*/ -#define SARADC_TOUCH_MEAS_DONE (BIT(10)) -#define SARADC_TOUCH_MEAS_DONE_M (BIT(10)) -#define SARADC_TOUCH_MEAS_DONE_V 0x1 -#define SARADC_TOUCH_MEAS_DONE_S 10 -/* SARADC_TOUCH_MEAS_EN : RO ;bitpos:[9:0] ;default: 10'h0 ; */ -/*description: 10-bit register to indicate which pads are "touched"*/ -#define SARADC_TOUCH_MEAS_EN 0x000003FF -#define SARADC_TOUCH_MEAS_EN_M ((SARADC_TOUCH_MEAS_EN_V)<<(SARADC_TOUCH_MEAS_EN_S)) -#define SARADC_TOUCH_MEAS_EN_V 0x3FF -#define SARADC_TOUCH_MEAS_EN_S 0 - -#define SARADC_SAR_TOUCH_ENABLE_REG (DR_REG_SARADC_BASE + 0x008c) -/* SARADC_TOUCH_PAD_OUTEN1 : R/W ;bitpos:[29:20] ;default: 10'h3ff ; */ -/*description: Bitmap defining SET1 for generating wakeup interrupt. SET1 is - "touched" only if at least one of touch pad in SET1 is "touched".*/ -#define SARADC_TOUCH_PAD_OUTEN1 0x000003FF -#define SARADC_TOUCH_PAD_OUTEN1_M ((SARADC_TOUCH_PAD_OUTEN1_V)<<(SARADC_TOUCH_PAD_OUTEN1_S)) -#define SARADC_TOUCH_PAD_OUTEN1_V 0x3FF -#define SARADC_TOUCH_PAD_OUTEN1_S 20 -/* SARADC_TOUCH_PAD_OUTEN2 : R/W ;bitpos:[19:10] ;default: 10'h3ff ; */ -/*description: Bitmap defining SET2 for generating wakeup interrupt. SET2 is - "touched" only if at least one of touch pad in SET2 is "touched".*/ -#define SARADC_TOUCH_PAD_OUTEN2 0x000003FF -#define SARADC_TOUCH_PAD_OUTEN2_M ((SARADC_TOUCH_PAD_OUTEN2_V)<<(SARADC_TOUCH_PAD_OUTEN2_S)) -#define SARADC_TOUCH_PAD_OUTEN2_V 0x3FF -#define SARADC_TOUCH_PAD_OUTEN2_S 10 -/* SARADC_TOUCH_PAD_WORKEN : R/W ;bitpos:[9:0] ;default: 10'h3ff ; */ -/*description: Bitmap defining the working set during the measurement.*/ -#define SARADC_TOUCH_PAD_WORKEN 0x000003FF -#define SARADC_TOUCH_PAD_WORKEN_M ((SARADC_TOUCH_PAD_WORKEN_V)<<(SARADC_TOUCH_PAD_WORKEN_S)) -#define SARADC_TOUCH_PAD_WORKEN_V 0x3FF -#define SARADC_TOUCH_PAD_WORKEN_S 0 - -#define SARADC_SAR_READ_CTRL2_REG (DR_REG_SARADC_BASE + 0x0090) -/* SARADC_SAR2_DATA_INV : R/W ;bitpos:[29] ;default: 1'b0 ; */ -/*description: Invert SAR ADC2 data*/ -#define SARADC_SAR2_DATA_INV (BIT(29)) -#define SARADC_SAR2_DATA_INV_M (BIT(29)) -#define SARADC_SAR2_DATA_INV_V 0x1 -#define SARADC_SAR2_DATA_INV_S 29 -/* SARADC_SAR2_DIG_FORCE : R/W ;bitpos:[28] ;default: 1'b0 ; */ -/*description: 1: SAR ADC2 controlled by DIG ADC2 CTRL or PWDET CTRL 0: SAR - ADC2 controlled by RTC ADC2 CTRL*/ -#define SARADC_SAR2_DIG_FORCE (BIT(28)) -#define SARADC_SAR2_DIG_FORCE_M (BIT(28)) -#define SARADC_SAR2_DIG_FORCE_V 0x1 -#define SARADC_SAR2_DIG_FORCE_S 28 -/* SARADC_SAR2_PWDET_FORCE : R/W ;bitpos:[27] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_SAR2_PWDET_FORCE (BIT(27)) -#define SARADC_SAR2_PWDET_FORCE_M (BIT(27)) -#define SARADC_SAR2_PWDET_FORCE_V 0x1 -#define SARADC_SAR2_PWDET_FORCE_S 27 -/* SARADC_SAR2_SAMPLE_NUM : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ -/*description: */ -#define SARADC_SAR2_SAMPLE_NUM 0x000000FF -#define SARADC_SAR2_SAMPLE_NUM_M ((SARADC_SAR2_SAMPLE_NUM_V)<<(SARADC_SAR2_SAMPLE_NUM_S)) -#define SARADC_SAR2_SAMPLE_NUM_V 0xFF -#define SARADC_SAR2_SAMPLE_NUM_S 19 -/* SARADC_SAR2_CLK_GATED : R/W ;bitpos:[18] ;default: 1'b1 ; */ -/*description: */ -#define SARADC_SAR2_CLK_GATED (BIT(18)) -#define SARADC_SAR2_CLK_GATED_M (BIT(18)) -#define SARADC_SAR2_CLK_GATED_V 0x1 -#define SARADC_SAR2_CLK_GATED_S 18 -/* SARADC_SAR2_SAMPLE_BIT : R/W ;bitpos:[17:16] ;default: 2'd3 ; */ -/*description: 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width - 11: for 12-bit width*/ -#define SARADC_SAR2_SAMPLE_BIT 0x00000003 -#define SARADC_SAR2_SAMPLE_BIT_M ((SARADC_SAR2_SAMPLE_BIT_V)<<(SARADC_SAR2_SAMPLE_BIT_S)) -#define SARADC_SAR2_SAMPLE_BIT_V 0x3 -#define SARADC_SAR2_SAMPLE_BIT_S 16 -/* SARADC_SAR2_SAMPLE_CYCLE : R/W ;bitpos:[15:8] ;default: 8'd9 ; */ -/*description: sample cycles for SAR ADC2*/ -#define SARADC_SAR2_SAMPLE_CYCLE 0x000000FF -#define SARADC_SAR2_SAMPLE_CYCLE_M ((SARADC_SAR2_SAMPLE_CYCLE_V)<<(SARADC_SAR2_SAMPLE_CYCLE_S)) -#define SARADC_SAR2_SAMPLE_CYCLE_V 0xFF -#define SARADC_SAR2_SAMPLE_CYCLE_S 8 -/* SARADC_SAR2_CLK_DIV : R/W ;bitpos:[7:0] ;default: 8'd2 ; */ -/*description: clock divider*/ -#define SARADC_SAR2_CLK_DIV 0x000000FF -#define SARADC_SAR2_CLK_DIV_M ((SARADC_SAR2_CLK_DIV_V)<<(SARADC_SAR2_CLK_DIV_S)) -#define SARADC_SAR2_CLK_DIV_V 0xFF -#define SARADC_SAR2_CLK_DIV_S 0 - -#define SARADC_SAR_MEAS_START2_REG (DR_REG_SARADC_BASE + 0x0094) -/* SARADC_SAR2_EN_PAD_FORCE : R/W ;bitpos:[31] ;default: 1'b0 ; */ -/*description: 1: SAR ADC2 pad enable bitmap is controlled by SW 0: SAR ADC2 - pad enable bitmap is controlled by ULP-coprocessor*/ -#define SARADC_SAR2_EN_PAD_FORCE (BIT(31)) -#define SARADC_SAR2_EN_PAD_FORCE_M (BIT(31)) -#define SARADC_SAR2_EN_PAD_FORCE_V 0x1 -#define SARADC_SAR2_EN_PAD_FORCE_S 31 -/* SARADC_SAR2_EN_PAD : R/W ;bitpos:[30:19] ;default: 12'b0 ; */ -/*description: SAR ADC2 pad enable bitmap only active when reg_sar2_en_pad_force = 1*/ -#define SARADC_SAR2_EN_PAD 0x00000FFF -#define SARADC_SAR2_EN_PAD_M ((SARADC_SAR2_EN_PAD_V)<<(SARADC_SAR2_EN_PAD_S)) -#define SARADC_SAR2_EN_PAD_V 0xFFF -#define SARADC_SAR2_EN_PAD_S 19 -/* SARADC_MEAS2_START_FORCE : R/W ;bitpos:[18] ;default: 1'b0 ; */ -/*description: 1: SAR ADC2 controller (in RTC) is started by SW 0: SAR ADC2 - controller is started by ULP-coprocessor*/ -#define SARADC_MEAS2_START_FORCE (BIT(18)) -#define SARADC_MEAS2_START_FORCE_M (BIT(18)) -#define SARADC_MEAS2_START_FORCE_V 0x1 -#define SARADC_MEAS2_START_FORCE_S 18 -/* SARADC_MEAS2_START_SAR : R/W ;bitpos:[17] ;default: 1'b0 ; */ -/*description: SAR ADC2 controller (in RTC) starts conversion only active when - reg_meas2_start_force = 1*/ -#define SARADC_MEAS2_START_SAR (BIT(17)) -#define SARADC_MEAS2_START_SAR_M (BIT(17)) -#define SARADC_MEAS2_START_SAR_V 0x1 -#define SARADC_MEAS2_START_SAR_S 17 -/* SARADC_MEAS2_DONE_SAR : RO ;bitpos:[16] ;default: 1'b0 ; */ -/*description: SAR ADC2 conversion done indication*/ -#define SARADC_MEAS2_DONE_SAR (BIT(16)) -#define SARADC_MEAS2_DONE_SAR_M (BIT(16)) -#define SARADC_MEAS2_DONE_SAR_V 0x1 -#define SARADC_MEAS2_DONE_SAR_S 16 -/* SARADC_MEAS2_DATA_SAR : RO ;bitpos:[15:0] ;default: 16'b0 ; */ -/*description: SAR ADC2 data*/ -#define SARADC_MEAS2_DATA_SAR 0x0000FFFF -#define SARADC_MEAS2_DATA_SAR_M ((SARADC_MEAS2_DATA_SAR_V)<<(SARADC_MEAS2_DATA_SAR_S)) -#define SARADC_MEAS2_DATA_SAR_V 0xFFFF -#define SARADC_MEAS2_DATA_SAR_S 0 - -#define SARADC_SAR_DAC_CTRL1_REG (DR_REG_SARADC_BASE + 0x0098) -/* SARADC_DAC_CLK_INV : R/W ;bitpos:[25] ;default: 1'b0 ; */ -/*description: 1: invert PDAC_CLK*/ -#define SARADC_DAC_CLK_INV (BIT(25)) -#define SARADC_DAC_CLK_INV_M (BIT(25)) -#define SARADC_DAC_CLK_INV_V 0x1 -#define SARADC_DAC_CLK_INV_S 25 -/* SARADC_DAC_CLK_FORCE_HIGH : R/W ;bitpos:[24] ;default: 1'b0 ; */ -/*description: 1: force PDAC_CLK to high*/ -#define SARADC_DAC_CLK_FORCE_HIGH (BIT(24)) -#define SARADC_DAC_CLK_FORCE_HIGH_M (BIT(24)) -#define SARADC_DAC_CLK_FORCE_HIGH_V 0x1 -#define SARADC_DAC_CLK_FORCE_HIGH_S 24 -/* SARADC_DAC_CLK_FORCE_LOW : R/W ;bitpos:[23] ;default: 1'b0 ; */ -/*description: 1: force PDAC_CLK to low*/ -#define SARADC_DAC_CLK_FORCE_LOW (BIT(23)) -#define SARADC_DAC_CLK_FORCE_LOW_M (BIT(23)) -#define SARADC_DAC_CLK_FORCE_LOW_V 0x1 -#define SARADC_DAC_CLK_FORCE_LOW_S 23 -/* SARADC_DAC_DIG_FORCE : R/W ;bitpos:[22] ;default: 1'b0 ; */ -/*description: 1: DAC1 & DAC2 use DMA 0: DAC1 & DAC2 do not use DMA*/ -#define SARADC_DAC_DIG_FORCE (BIT(22)) -#define SARADC_DAC_DIG_FORCE_M (BIT(22)) -#define SARADC_DAC_DIG_FORCE_V 0x1 -#define SARADC_DAC_DIG_FORCE_S 22 -/* SARADC_DEBUG_BIT_SEL : R/W ;bitpos:[21:17] ;default: 5'b0 ; */ -/*description: */ -#define SARADC_DEBUG_BIT_SEL 0x0000001F -#define SARADC_DEBUG_BIT_SEL_M ((SARADC_DEBUG_BIT_SEL_V)<<(SARADC_DEBUG_BIT_SEL_S)) -#define SARADC_DEBUG_BIT_SEL_V 0x1F -#define SARADC_DEBUG_BIT_SEL_S 17 -/* SARADC_SW_TONE_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */ -/*description: 1: enable CW generator 0: disable CW generator*/ -#define SARADC_SW_TONE_EN (BIT(16)) -#define SARADC_SW_TONE_EN_M (BIT(16)) -#define SARADC_SW_TONE_EN_V 0x1 -#define SARADC_SW_TONE_EN_S 16 -/* SARADC_SW_FSTEP : R/W ;bitpos:[15:0] ;default: 16'b0 ; */ -/*description: frequency step for CW generator can be used to adjust the frequency*/ -#define SARADC_SW_FSTEP 0x0000FFFF -#define SARADC_SW_FSTEP_M ((SARADC_SW_FSTEP_V)<<(SARADC_SW_FSTEP_S)) -#define SARADC_SW_FSTEP_V 0xFFFF -#define SARADC_SW_FSTEP_S 0 - -#define SARADC_SAR_DAC_CTRL2_REG (DR_REG_SARADC_BASE + 0x009c) -/* SARADC_DAC_CW_EN2 : R/W ;bitpos:[25] ;default: 1'b1 ; */ -/*description: 1: to select CW generator as source to PDAC2_DAC[7:0] 0: to - select register reg_pdac2_dac[7:0] as source to PDAC2_DAC[7:0]*/ -#define SARADC_DAC_CW_EN2 (BIT(25)) -#define SARADC_DAC_CW_EN2_M (BIT(25)) -#define SARADC_DAC_CW_EN2_V 0x1 -#define SARADC_DAC_CW_EN2_S 25 -/* SARADC_DAC_CW_EN1 : R/W ;bitpos:[24] ;default: 1'b1 ; */ -/*description: 1: to select CW generator as source to PDAC1_DAC[7:0] 0: to - select register reg_pdac1_dac[7:0] as source to PDAC1_DAC[7:0]*/ -#define SARADC_DAC_CW_EN1 (BIT(24)) -#define SARADC_DAC_CW_EN1_M (BIT(24)) -#define SARADC_DAC_CW_EN1_V 0x1 -#define SARADC_DAC_CW_EN1_S 24 -/* SARADC_DAC_INV2 : R/W ;bitpos:[23:22] ;default: 2'b0 ; */ -/*description: 00: do not invert any bits 01: invert all bits 10: invert MSB - 11: invert all bits except MSB*/ -#define SARADC_DAC_INV2 0x00000003 -#define SARADC_DAC_INV2_M ((SARADC_DAC_INV2_V)<<(SARADC_DAC_INV2_S)) -#define SARADC_DAC_INV2_V 0x3 -#define SARADC_DAC_INV2_S 22 -/* SARADC_DAC_INV1 : R/W ;bitpos:[21:20] ;default: 2'b0 ; */ -/*description: 00: do not invert any bits 01: invert all bits 10: invert MSB - 11: invert all bits except MSB*/ -#define SARADC_DAC_INV1 0x00000003 -#define SARADC_DAC_INV1_M ((SARADC_DAC_INV1_V)<<(SARADC_DAC_INV1_S)) -#define SARADC_DAC_INV1_V 0x3 -#define SARADC_DAC_INV1_S 20 -/* SARADC_DAC_SCALE2 : R/W ;bitpos:[19:18] ;default: 2'b0 ; */ -/*description: 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8*/ -#define SARADC_DAC_SCALE2 0x00000003 -#define SARADC_DAC_SCALE2_M ((SARADC_DAC_SCALE2_V)<<(SARADC_DAC_SCALE2_S)) -#define SARADC_DAC_SCALE2_V 0x3 -#define SARADC_DAC_SCALE2_S 18 -/* SARADC_DAC_SCALE1 : R/W ;bitpos:[17:16] ;default: 2'b0 ; */ -/*description: 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8*/ -#define SARADC_DAC_SCALE1 0x00000003 -#define SARADC_DAC_SCALE1_M ((SARADC_DAC_SCALE1_V)<<(SARADC_DAC_SCALE1_S)) -#define SARADC_DAC_SCALE1_V 0x3 -#define SARADC_DAC_SCALE1_S 16 -/* SARADC_DAC_DC2 : R/W ;bitpos:[15:8] ;default: 8'b0 ; */ -/*description: DC offset for DAC2 CW generator*/ -#define SARADC_DAC_DC2 0x000000FF -#define SARADC_DAC_DC2_M ((SARADC_DAC_DC2_V)<<(SARADC_DAC_DC2_S)) -#define SARADC_DAC_DC2_V 0xFF -#define SARADC_DAC_DC2_S 8 -/* SARADC_DAC_DC1 : R/W ;bitpos:[7:0] ;default: 8'b0 ; */ -/*description: DC offset for DAC1 CW generator*/ -#define SARADC_DAC_DC1 0x000000FF -#define SARADC_DAC_DC1_M ((SARADC_DAC_DC1_V)<<(SARADC_DAC_DC1_S)) -#define SARADC_DAC_DC1_V 0xFF -#define SARADC_DAC_DC1_S 0 - -#define SARADC_SAR_MEAS_CTRL2_REG (DR_REG_SARADC_BASE + 0x0a0) -/* SARADC_AMP_SHORT_REF_GND_FORCE : R/W ;bitpos:[18:17] ;default: 2'b0 ; */ -/*description: */ -#define SARADC_AMP_SHORT_REF_GND_FORCE 0x00000003 -#define SARADC_AMP_SHORT_REF_GND_FORCE_M ((SARADC_AMP_SHORT_REF_GND_FORCE_V)<<(SARADC_AMP_SHORT_REF_GND_FORCE_S)) -#define SARADC_AMP_SHORT_REF_GND_FORCE_V 0x3 -#define SARADC_AMP_SHORT_REF_GND_FORCE_S 17 -/* SARADC_AMP_SHORT_REF_FORCE : R/W ;bitpos:[16:15] ;default: 2'b0 ; */ -/*description: */ -#define SARADC_AMP_SHORT_REF_FORCE 0x00000003 -#define SARADC_AMP_SHORT_REF_FORCE_M ((SARADC_AMP_SHORT_REF_FORCE_V)<<(SARADC_AMP_SHORT_REF_FORCE_S)) -#define SARADC_AMP_SHORT_REF_FORCE_V 0x3 -#define SARADC_AMP_SHORT_REF_FORCE_S 15 -/* SARADC_AMP_RST_FB_FORCE : R/W ;bitpos:[14:13] ;default: 2'b0 ; */ -/*description: */ -#define SARADC_AMP_RST_FB_FORCE 0x00000003 -#define SARADC_AMP_RST_FB_FORCE_M ((SARADC_AMP_RST_FB_FORCE_V)<<(SARADC_AMP_RST_FB_FORCE_S)) -#define SARADC_AMP_RST_FB_FORCE_V 0x3 -#define SARADC_AMP_RST_FB_FORCE_S 13 -/* SARADC_SAR2_RSTB_FORCE : R/W ;bitpos:[12:11] ;default: 2'b0 ; */ -/*description: */ -#define SARADC_SAR2_RSTB_FORCE 0x00000003 -#define SARADC_SAR2_RSTB_FORCE_M ((SARADC_SAR2_RSTB_FORCE_V)<<(SARADC_SAR2_RSTB_FORCE_S)) -#define SARADC_SAR2_RSTB_FORCE_V 0x3 -#define SARADC_SAR2_RSTB_FORCE_S 11 -/* SARADC_SAR_RSTB_FSM_IDLE : R/W ;bitpos:[10] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_SAR_RSTB_FSM_IDLE (BIT(10)) -#define SARADC_SAR_RSTB_FSM_IDLE_M (BIT(10)) -#define SARADC_SAR_RSTB_FSM_IDLE_V 0x1 -#define SARADC_SAR_RSTB_FSM_IDLE_S 10 -/* SARADC_XPD_SAR_FSM_IDLE : R/W ;bitpos:[9] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_XPD_SAR_FSM_IDLE (BIT(9)) -#define SARADC_XPD_SAR_FSM_IDLE_M (BIT(9)) -#define SARADC_XPD_SAR_FSM_IDLE_V 0x1 -#define SARADC_XPD_SAR_FSM_IDLE_S 9 -/* SARADC_AMP_SHORT_REF_GND_FSM_IDLE : R/W ;bitpos:[8] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_AMP_SHORT_REF_GND_FSM_IDLE (BIT(8)) -#define SARADC_AMP_SHORT_REF_GND_FSM_IDLE_M (BIT(8)) -#define SARADC_AMP_SHORT_REF_GND_FSM_IDLE_V 0x1 -#define SARADC_AMP_SHORT_REF_GND_FSM_IDLE_S 8 -/* SARADC_AMP_SHORT_REF_FSM_IDLE : R/W ;bitpos:[7] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_AMP_SHORT_REF_FSM_IDLE (BIT(7)) -#define SARADC_AMP_SHORT_REF_FSM_IDLE_M (BIT(7)) -#define SARADC_AMP_SHORT_REF_FSM_IDLE_V 0x1 -#define SARADC_AMP_SHORT_REF_FSM_IDLE_S 7 -/* SARADC_AMP_RST_FB_FSM_IDLE : R/W ;bitpos:[6] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_AMP_RST_FB_FSM_IDLE (BIT(6)) -#define SARADC_AMP_RST_FB_FSM_IDLE_M (BIT(6)) -#define SARADC_AMP_RST_FB_FSM_IDLE_V 0x1 -#define SARADC_AMP_RST_FB_FSM_IDLE_S 6 -/* SARADC_XPD_SAR_AMP_FSM_IDLE : R/W ;bitpos:[5] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_XPD_SAR_AMP_FSM_IDLE (BIT(5)) -#define SARADC_XPD_SAR_AMP_FSM_IDLE_M (BIT(5)) -#define SARADC_XPD_SAR_AMP_FSM_IDLE_V 0x1 -#define SARADC_XPD_SAR_AMP_FSM_IDLE_S 5 -/* SARADC_SAR1_DAC_XPD_FSM_IDLE : R/W ;bitpos:[4] ;default: 1'b0 ; */ -/*description: */ -#define SARADC_SAR1_DAC_XPD_FSM_IDLE (BIT(4)) -#define SARADC_SAR1_DAC_XPD_FSM_IDLE_M (BIT(4)) -#define SARADC_SAR1_DAC_XPD_FSM_IDLE_V 0x1 -#define SARADC_SAR1_DAC_XPD_FSM_IDLE_S 4 -/* SARADC_SAR1_DAC_XPD_FSM : R/W ;bitpos:[3:0] ;default: 4'b0011 ; */ -/*description: */ -#define SARADC_SAR1_DAC_XPD_FSM 0x0000000F -#define SARADC_SAR1_DAC_XPD_FSM_M ((SARADC_SAR1_DAC_XPD_FSM_V)<<(SARADC_SAR1_DAC_XPD_FSM_S)) -#define SARADC_SAR1_DAC_XPD_FSM_V 0xF -#define SARADC_SAR1_DAC_XPD_FSM_S 0 - -#define SARADC_SAR_NOUSE_REG (DR_REG_SARADC_BASE + 0x00F8) -/* SARADC_SAR_NOUSE : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ -/*description: */ -#define SARADC_SAR_NOUSE 0xFFFFFFFF -#define SARADC_SAR_NOUSE_M ((SARADC_SAR_NOUSE_V)<<(SARADC_SAR_NOUSE_S)) -#define SARADC_SAR_NOUSE_V 0xFFFFFFFF -#define SARADC_SAR_NOUSE_S 0 - -#define SARADC_SARDATE_REG (DR_REG_SARADC_BASE + 0x00FC) -/* SARADC_SAR_DATE : R/W ;bitpos:[27:0] ;default: 28'h1605180 ; */ -/*description: */ -#define SARADC_SAR_DATE 0x0FFFFFFF -#define SARADC_SAR_DATE_M ((SARADC_SAR_DATE_V)<<(SARADC_SAR_DATE_S)) -#define SARADC_SAR_DATE_V 0xFFFFFFF -#define SARADC_SAR_DATE_S 0 - - - - -#endif /*_SOC_SARADC_REG_H_ */ - - diff --git a/components/esp32/include/soc/sens_reg.h b/components/esp32/include/soc/sens_reg.h new file mode 100644 index 0000000000..0a032d218e --- /dev/null +++ b/components/esp32/include/soc/sens_reg.h @@ -0,0 +1,1047 @@ +// 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 _SOC_SENS_REG_H_ +#define _SOC_SENS_REG_H_ + + +#include "soc.h" +#define SENS_SAR_READ_CTRL_REG (DR_REG_SENS_BASE + 0x0000) +/* SENS_SAR1_DATA_INV : R/W ;bitpos:[28] ;default: 1'd0 ; */ +/*description: Invert SAR ADC1 data*/ +#define SENS_SAR1_DATA_INV (BIT(28)) +#define SENS_SAR1_DATA_INV_M (BIT(28)) +#define SENS_SAR1_DATA_INV_V 0x1 +#define SENS_SAR1_DATA_INV_S 28 +/* SENS_SAR1_DIG_FORCE : R/W ;bitpos:[27] ;default: 1'd0 ; */ +/*description: 1: SAR ADC1 controlled by DIG ADC1 CTRL 0: SAR ADC1 controlled by RTC ADC1 CTRL*/ +#define SENS_SAR1_DIG_FORCE (BIT(27)) +#define SENS_SAR1_DIG_FORCE_M (BIT(27)) +#define SENS_SAR1_DIG_FORCE_V 0x1 +#define SENS_SAR1_DIG_FORCE_S 27 +/* SENS_SAR1_SAMPLE_NUM : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ +/*description: */ +#define SENS_SAR1_SAMPLE_NUM 0x000000FF +#define SENS_SAR1_SAMPLE_NUM_M ((SENS_SAR1_SAMPLE_NUM_V)<<(SENS_SAR1_SAMPLE_NUM_S)) +#define SENS_SAR1_SAMPLE_NUM_V 0xFF +#define SENS_SAR1_SAMPLE_NUM_S 19 +/* SENS_SAR1_CLK_GATED : R/W ;bitpos:[18] ;default: 1'b1 ; */ +/*description: */ +#define SENS_SAR1_CLK_GATED (BIT(18)) +#define SENS_SAR1_CLK_GATED_M (BIT(18)) +#define SENS_SAR1_CLK_GATED_V 0x1 +#define SENS_SAR1_CLK_GATED_S 18 +/* SENS_SAR1_SAMPLE_BIT : R/W ;bitpos:[17:16] ;default: 2'd3 ; */ +/*description: 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width + 11: for 12-bit width*/ +#define SENS_SAR1_SAMPLE_BIT 0x00000003 +#define SENS_SAR1_SAMPLE_BIT_M ((SENS_SAR1_SAMPLE_BIT_V)<<(SENS_SAR1_SAMPLE_BIT_S)) +#define SENS_SAR1_SAMPLE_BIT_V 0x3 +#define SENS_SAR1_SAMPLE_BIT_S 16 +/* SENS_SAR1_SAMPLE_CYCLE : R/W ;bitpos:[15:8] ;default: 8'd9 ; */ +/*description: sample cycles for SAR ADC1*/ +#define SENS_SAR1_SAMPLE_CYCLE 0x000000FF +#define SENS_SAR1_SAMPLE_CYCLE_M ((SENS_SAR1_SAMPLE_CYCLE_V)<<(SENS_SAR1_SAMPLE_CYCLE_S)) +#define SENS_SAR1_SAMPLE_CYCLE_V 0xFF +#define SENS_SAR1_SAMPLE_CYCLE_S 8 +/* SENS_SAR1_CLK_DIV : R/W ;bitpos:[7:0] ;default: 8'd2 ; */ +/*description: clock divider*/ +#define SENS_SAR1_CLK_DIV 0x000000FF +#define SENS_SAR1_CLK_DIV_M ((SENS_SAR1_CLK_DIV_V)<<(SENS_SAR1_CLK_DIV_S)) +#define SENS_SAR1_CLK_DIV_V 0xFF +#define SENS_SAR1_CLK_DIV_S 0 + +#define SENS_SAR_READ_STATUS1_REG (DR_REG_SENS_BASE + 0x0004) +/* SENS_SAR1_READER_STATUS : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: */ +#define SENS_SAR1_READER_STATUS 0xFFFFFFFF +#define SENS_SAR1_READER_STATUS_M ((SENS_SAR1_READER_STATUS_V)<<(SENS_SAR1_READER_STATUS_S)) +#define SENS_SAR1_READER_STATUS_V 0xFFFFFFFF +#define SENS_SAR1_READER_STATUS_S 0 + +#define SENS_SAR_MEAS_WAIT1_REG (DR_REG_SENS_BASE + 0x0008) +/* SENS_SAR_AMP_WAIT2 : R/W ;bitpos:[31:16] ;default: 16'd10 ; */ +/*description: */ +#define SENS_SAR_AMP_WAIT2 0x0000FFFF +#define SENS_SAR_AMP_WAIT2_M ((SENS_SAR_AMP_WAIT2_V)<<(SENS_SAR_AMP_WAIT2_S)) +#define SENS_SAR_AMP_WAIT2_V 0xFFFF +#define SENS_SAR_AMP_WAIT2_S 16 +/* SENS_SAR_AMP_WAIT1 : R/W ;bitpos:[15:0] ;default: 16'd10 ; */ +/*description: */ +#define SENS_SAR_AMP_WAIT1 0x0000FFFF +#define SENS_SAR_AMP_WAIT1_M ((SENS_SAR_AMP_WAIT1_V)<<(SENS_SAR_AMP_WAIT1_S)) +#define SENS_SAR_AMP_WAIT1_V 0xFFFF +#define SENS_SAR_AMP_WAIT1_S 0 + +#define SENS_SAR_MEAS_WAIT2_REG (DR_REG_SENS_BASE + 0x000c) +/* SENS_SAR2_RSTB_WAIT : R/W ;bitpos:[27:20] ;default: 8'd2 ; */ +/*description: */ +#define SENS_SAR2_RSTB_WAIT 0x000000FF +#define SENS_SAR2_RSTB_WAIT_M ((SENS_SAR2_RSTB_WAIT_V)<<(SENS_SAR2_RSTB_WAIT_S)) +#define SENS_SAR2_RSTB_WAIT_V 0xFF +#define SENS_SAR2_RSTB_WAIT_S 20 +/* SENS_FORCE_XPD_SAR : R/W ;bitpos:[19:18] ;default: 2'd0 ; */ +/*description: */ +#define SENS_FORCE_XPD_SAR 0x00000003 +#define SENS_FORCE_XPD_SAR_M ((SENS_FORCE_XPD_SAR_V)<<(SENS_FORCE_XPD_SAR_S)) +#define SENS_FORCE_XPD_SAR_V 0x3 +#define SENS_FORCE_XPD_SAR_S 18 +/* SENS_FORCE_XPD_AMP : R/W ;bitpos:[17:16] ;default: 2'd0 ; */ +/*description: */ +#define SENS_FORCE_XPD_AMP 0x00000003 +#define SENS_FORCE_XPD_AMP_M ((SENS_FORCE_XPD_AMP_V)<<(SENS_FORCE_XPD_AMP_S)) +#define SENS_FORCE_XPD_AMP_V 0x3 +#define SENS_FORCE_XPD_AMP_S 16 +/* SENS_SAR_AMP_WAIT3 : R/W ;bitpos:[15:0] ;default: 16'd10 ; */ +/*description: */ +#define SENS_SAR_AMP_WAIT3 0x0000FFFF +#define SENS_SAR_AMP_WAIT3_M ((SENS_SAR_AMP_WAIT3_V)<<(SENS_SAR_AMP_WAIT3_S)) +#define SENS_SAR_AMP_WAIT3_V 0xFFFF +#define SENS_SAR_AMP_WAIT3_S 0 + +#define SENS_SAR_MEAS_CTRL_REG (DR_REG_SENS_BASE + 0x0010) +/* SENS_SAR2_XPD_WAIT : R/W ;bitpos:[31:24] ;default: 8'h7 ; */ +/*description: */ +#define SENS_SAR2_XPD_WAIT 0x000000FF +#define SENS_SAR2_XPD_WAIT_M ((SENS_SAR2_XPD_WAIT_V)<<(SENS_SAR2_XPD_WAIT_S)) +#define SENS_SAR2_XPD_WAIT_V 0xFF +#define SENS_SAR2_XPD_WAIT_S 24 +/* SENS_SAR_RSTB_FSM : R/W ;bitpos:[23:20] ;default: 4'b0000 ; */ +/*description: */ +#define SENS_SAR_RSTB_FSM 0x0000000F +#define SENS_SAR_RSTB_FSM_M ((SENS_SAR_RSTB_FSM_V)<<(SENS_SAR_RSTB_FSM_S)) +#define SENS_SAR_RSTB_FSM_V 0xF +#define SENS_SAR_RSTB_FSM_S 20 +/* SENS_XPD_SAR_FSM : R/W ;bitpos:[19:16] ;default: 4'b0111 ; */ +/*description: */ +#define SENS_XPD_SAR_FSM 0x0000000F +#define SENS_XPD_SAR_FSM_M ((SENS_XPD_SAR_FSM_V)<<(SENS_XPD_SAR_FSM_S)) +#define SENS_XPD_SAR_FSM_V 0xF +#define SENS_XPD_SAR_FSM_S 16 +/* SENS_AMP_SHORT_REF_GND_FSM : R/W ;bitpos:[15:12] ;default: 4'b0011 ; */ +/*description: */ +#define SENS_AMP_SHORT_REF_GND_FSM 0x0000000F +#define SENS_AMP_SHORT_REF_GND_FSM_M ((SENS_AMP_SHORT_REF_GND_FSM_V)<<(SENS_AMP_SHORT_REF_GND_FSM_S)) +#define SENS_AMP_SHORT_REF_GND_FSM_V 0xF +#define SENS_AMP_SHORT_REF_GND_FSM_S 12 +/* SENS_AMP_SHORT_REF_FSM : R/W ;bitpos:[11:8] ;default: 4'b0011 ; */ +/*description: */ +#define SENS_AMP_SHORT_REF_FSM 0x0000000F +#define SENS_AMP_SHORT_REF_FSM_M ((SENS_AMP_SHORT_REF_FSM_V)<<(SENS_AMP_SHORT_REF_FSM_S)) +#define SENS_AMP_SHORT_REF_FSM_V 0xF +#define SENS_AMP_SHORT_REF_FSM_S 8 +/* SENS_AMP_RST_FB_FSM : R/W ;bitpos:[7:4] ;default: 4'b1000 ; */ +/*description: */ +#define SENS_AMP_RST_FB_FSM 0x0000000F +#define SENS_AMP_RST_FB_FSM_M ((SENS_AMP_RST_FB_FSM_V)<<(SENS_AMP_RST_FB_FSM_S)) +#define SENS_AMP_RST_FB_FSM_V 0xF +#define SENS_AMP_RST_FB_FSM_S 4 +/* SENS_XPD_SAR_AMP_FSM : R/W ;bitpos:[3:0] ;default: 4'b1111 ; */ +/*description: */ +#define SENS_XPD_SAR_AMP_FSM 0x0000000F +#define SENS_XPD_SAR_AMP_FSM_M ((SENS_XPD_SAR_AMP_FSM_V)<<(SENS_XPD_SAR_AMP_FSM_S)) +#define SENS_XPD_SAR_AMP_FSM_V 0xF +#define SENS_XPD_SAR_AMP_FSM_S 0 + +#define SENS_SAR_READ_STATUS2_REG (DR_REG_SENS_BASE + 0x0014) +/* SENS_SAR2_READER_STATUS : RO ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: */ +#define SENS_SAR2_READER_STATUS 0xFFFFFFFF +#define SENS_SAR2_READER_STATUS_M ((SENS_SAR2_READER_STATUS_V)<<(SENS_SAR2_READER_STATUS_S)) +#define SENS_SAR2_READER_STATUS_V 0xFFFFFFFF +#define SENS_SAR2_READER_STATUS_S 0 + +#define SENS_ULP_CP_SLEEP_CYC0_REG (DR_REG_SENS_BASE + 0x0018) +/* SENS_SLEEP_CYCLES_S0 : R/W ;bitpos:[31:0] ;default: 32'd200 ; */ +/*description: sleep cycles for ULP-coprocessor timer*/ +#define SENS_SLEEP_CYCLES_S0 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S0_M ((SENS_SLEEP_CYCLES_S0_V)<<(SENS_SLEEP_CYCLES_S0_S)) +#define SENS_SLEEP_CYCLES_S0_V 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S0_S 0 + +#define SENS_ULP_CP_SLEEP_CYC1_REG (DR_REG_SENS_BASE + 0x001c) +/* SENS_SLEEP_CYCLES_S1 : R/W ;bitpos:[31:0] ;default: 32'd100 ; */ +/*description: */ +#define SENS_SLEEP_CYCLES_S1 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S1_M ((SENS_SLEEP_CYCLES_S1_V)<<(SENS_SLEEP_CYCLES_S1_S)) +#define SENS_SLEEP_CYCLES_S1_V 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S1_S 0 + +#define SENS_ULP_CP_SLEEP_CYC2_REG (DR_REG_SENS_BASE + 0x0020) +/* SENS_SLEEP_CYCLES_S2 : R/W ;bitpos:[31:0] ;default: 32'd50 ; */ +/*description: */ +#define SENS_SLEEP_CYCLES_S2 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S2_M ((SENS_SLEEP_CYCLES_S2_V)<<(SENS_SLEEP_CYCLES_S2_S)) +#define SENS_SLEEP_CYCLES_S2_V 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S2_S 0 + +#define SENS_ULP_CP_SLEEP_CYC3_REG (DR_REG_SENS_BASE + 0x0024) +/* SENS_SLEEP_CYCLES_S3 : R/W ;bitpos:[31:0] ;default: 32'd40 ; */ +/*description: */ +#define SENS_SLEEP_CYCLES_S3 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S3_M ((SENS_SLEEP_CYCLES_S3_V)<<(SENS_SLEEP_CYCLES_S3_S)) +#define SENS_SLEEP_CYCLES_S3_V 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S3_S 0 + +#define SENS_ULP_CP_SLEEP_CYC4_REG (DR_REG_SENS_BASE + 0x0028) +/* SENS_SLEEP_CYCLES_S4 : R/W ;bitpos:[31:0] ;default: 32'd20 ; */ +/*description: */ +#define SENS_SLEEP_CYCLES_S4 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S4_M ((SENS_SLEEP_CYCLES_S4_V)<<(SENS_SLEEP_CYCLES_S4_S)) +#define SENS_SLEEP_CYCLES_S4_V 0xFFFFFFFF +#define SENS_SLEEP_CYCLES_S4_S 0 + +#define SENS_SAR_START_FORCE_REG (DR_REG_SENS_BASE + 0x002c) +/* SENS_SAR2_PWDET_EN : R/W ;bitpos:[24] ;default: 1'b0 ; */ +/*description: N/A*/ +#define SENS_SAR2_PWDET_EN (BIT(24)) +#define SENS_SAR2_PWDET_EN_M (BIT(24)) +#define SENS_SAR2_PWDET_EN_V 0x1 +#define SENS_SAR2_PWDET_EN_S 24 +/* SENS_SAR1_STOP : R/W ;bitpos:[23] ;default: 1'b0 ; */ +/*description: stop SAR ADC1 conversion*/ +#define SENS_SAR1_STOP (BIT(23)) +#define SENS_SAR1_STOP_M (BIT(23)) +#define SENS_SAR1_STOP_V 0x1 +#define SENS_SAR1_STOP_S 23 +/* SENS_SAR2_STOP : R/W ;bitpos:[22] ;default: 1'b0 ; */ +/*description: stop SAR ADC2 conversion*/ +#define SENS_SAR2_STOP (BIT(22)) +#define SENS_SAR2_STOP_M (BIT(22)) +#define SENS_SAR2_STOP_V 0x1 +#define SENS_SAR2_STOP_S 22 +/* SENS_PC_INIT : R/W ;bitpos:[21:11] ;default: 11'b0 ; */ +/*description: initialized PC for ULP-coprocessor*/ +#define SENS_PC_INIT 0x000007FF +#define SENS_PC_INIT_M ((SENS_PC_INIT_V)<<(SENS_PC_INIT_S)) +#define SENS_PC_INIT_V 0x7FF +#define SENS_PC_INIT_S 11 +/* SENS_SARCLK_EN : R/W ;bitpos:[10] ;default: 1'b0 ; */ +/*description: */ +#define SENS_SARCLK_EN (BIT(10)) +#define SENS_SARCLK_EN_M (BIT(10)) +#define SENS_SARCLK_EN_V 0x1 +#define SENS_SARCLK_EN_S 10 +/* SENS_ULP_CP_START_TOP : R/W ;bitpos:[9] ;default: 1'b0 ; */ +/*description: Write 1 to start ULP-coprocessor only active when reg_ulp_cp_force_start_top + = 1*/ +#define SENS_ULP_CP_START_TOP (BIT(9)) +#define SENS_ULP_CP_START_TOP_M (BIT(9)) +#define SENS_ULP_CP_START_TOP_V 0x1 +#define SENS_ULP_CP_START_TOP_S 9 +/* SENS_ULP_CP_FORCE_START_TOP : R/W ;bitpos:[8] ;default: 1'b0 ; */ +/*description: 1: ULP-coprocessor is started by SW 0: ULP-coprocessor is started by timer*/ +#define SENS_ULP_CP_FORCE_START_TOP (BIT(8)) +#define SENS_ULP_CP_FORCE_START_TOP_M (BIT(8)) +#define SENS_ULP_CP_FORCE_START_TOP_V 0x1 +#define SENS_ULP_CP_FORCE_START_TOP_S 8 +/* SENS_SAR2_PWDET_CCT : R/W ;bitpos:[7:5] ;default: 3'b0 ; */ +/*description: SAR2_PWDET_CCT PA power detector capacitance tuning.*/ +#define SENS_SAR2_PWDET_CCT 0x00000007 +#define SENS_SAR2_PWDET_CCT_M ((SENS_SAR2_PWDET_CCT_V)<<(SENS_SAR2_PWDET_CCT_S)) +#define SENS_SAR2_PWDET_CCT_V 0x7 +#define SENS_SAR2_PWDET_CCT_S 5 +/* SENS_SAR2_EN_TEST : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: SAR2_EN_TEST only active when reg_sar2_dig_force = 0*/ +#define SENS_SAR2_EN_TEST (BIT(4)) +#define SENS_SAR2_EN_TEST_M (BIT(4)) +#define SENS_SAR2_EN_TEST_V 0x1 +#define SENS_SAR2_EN_TEST_S 4 +/* SENS_SAR2_BIT_WIDTH : R/W ;bitpos:[3:2] ;default: 2'b11 ; */ +/*description: 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits*/ +#define SENS_SAR2_BIT_WIDTH 0x00000003 +#define SENS_SAR2_BIT_WIDTH_M ((SENS_SAR2_BIT_WIDTH_V)<<(SENS_SAR2_BIT_WIDTH_S)) +#define SENS_SAR2_BIT_WIDTH_V 0x3 +#define SENS_SAR2_BIT_WIDTH_S 2 +/* SENS_SAR1_BIT_WIDTH : R/W ;bitpos:[1:0] ;default: 2'b11 ; */ +/*description: 00: 9 bit 01: 10 bits 10: 11bits 11: 12bits*/ +#define SENS_SAR1_BIT_WIDTH 0x00000003 +#define SENS_SAR1_BIT_WIDTH_M ((SENS_SAR1_BIT_WIDTH_V)<<(SENS_SAR1_BIT_WIDTH_S)) +#define SENS_SAR1_BIT_WIDTH_V 0x3 +#define SENS_SAR1_BIT_WIDTH_S 0 + +#define SENS_SAR_MEM_WR_CTRL_REG (DR_REG_SENS_BASE + 0x0030) +/* SENS_RTC_MEM_WR_OFFST_CLR : WO ;bitpos:[22] ;default: 1'd0 ; */ +/*description: */ +#define SENS_RTC_MEM_WR_OFFST_CLR (BIT(22)) +#define SENS_RTC_MEM_WR_OFFST_CLR_M (BIT(22)) +#define SENS_RTC_MEM_WR_OFFST_CLR_V 0x1 +#define SENS_RTC_MEM_WR_OFFST_CLR_S 22 +/* SENS_MEM_WR_ADDR_SIZE : R/W ;bitpos:[21:11] ;default: 11'd512 ; */ +/*description: */ +#define SENS_MEM_WR_ADDR_SIZE 0x000007FF +#define SENS_MEM_WR_ADDR_SIZE_M ((SENS_MEM_WR_ADDR_SIZE_V)<<(SENS_MEM_WR_ADDR_SIZE_S)) +#define SENS_MEM_WR_ADDR_SIZE_V 0x7FF +#define SENS_MEM_WR_ADDR_SIZE_S 11 +/* SENS_MEM_WR_ADDR_INIT : R/W ;bitpos:[10:0] ;default: 11'd512 ; */ +/*description: */ +#define SENS_MEM_WR_ADDR_INIT 0x000007FF +#define SENS_MEM_WR_ADDR_INIT_M ((SENS_MEM_WR_ADDR_INIT_V)<<(SENS_MEM_WR_ADDR_INIT_S)) +#define SENS_MEM_WR_ADDR_INIT_V 0x7FF +#define SENS_MEM_WR_ADDR_INIT_S 0 + +#define SENS_SAR_ATTEN1_REG (DR_REG_SENS_BASE + 0x0034) +/* SENS_SAR1_ATTEN : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */ +/*description: 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB*/ +#define SENS_SAR1_ATTEN 0xFFFFFFFF +#define SENS_SAR1_ATTEN_M ((SENS_SAR1_ATTEN_V)<<(SENS_SAR1_ATTEN_S)) +#define SENS_SAR1_ATTEN_V 0xFFFFFFFF +#define SENS_SAR1_ATTEN_S 0 + +#define SENS_SAR_ATTEN2_REG (DR_REG_SENS_BASE + 0x0038) +/* SENS_SAR2_ATTEN : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */ +/*description: 2-bit attenuation for each pad 11:1dB 10:6dB 01:3dB 00:0dB*/ +#define SENS_SAR2_ATTEN 0xFFFFFFFF +#define SENS_SAR2_ATTEN_M ((SENS_SAR2_ATTEN_V)<<(SENS_SAR2_ATTEN_S)) +#define SENS_SAR2_ATTEN_V 0xFFFFFFFF +#define SENS_SAR2_ATTEN_S 0 + +#define SENS_SAR_SLAVE_ADDR1_REG (DR_REG_SENS_BASE + 0x003c) +/* SENS_MEAS_STATUS : RO ;bitpos:[29:22] ;default: 8'h0 ; */ +/*description: */ +#define SENS_MEAS_STATUS 0x000000FF +#define SENS_MEAS_STATUS_M ((SENS_MEAS_STATUS_V)<<(SENS_MEAS_STATUS_S)) +#define SENS_MEAS_STATUS_V 0xFF +#define SENS_MEAS_STATUS_S 22 +/* SENS_I2C_SLAVE_ADDR0 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR0 0x000007FF +#define SENS_I2C_SLAVE_ADDR0_M ((SENS_I2C_SLAVE_ADDR0_V)<<(SENS_I2C_SLAVE_ADDR0_S)) +#define SENS_I2C_SLAVE_ADDR0_V 0x7FF +#define SENS_I2C_SLAVE_ADDR0_S 11 +/* SENS_I2C_SLAVE_ADDR1 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR1 0x000007FF +#define SENS_I2C_SLAVE_ADDR1_M ((SENS_I2C_SLAVE_ADDR1_V)<<(SENS_I2C_SLAVE_ADDR1_S)) +#define SENS_I2C_SLAVE_ADDR1_V 0x7FF +#define SENS_I2C_SLAVE_ADDR1_S 0 + +#define SENS_SAR_SLAVE_ADDR2_REG (DR_REG_SENS_BASE + 0x0040) +/* SENS_I2C_SLAVE_ADDR2 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR2 0x000007FF +#define SENS_I2C_SLAVE_ADDR2_M ((SENS_I2C_SLAVE_ADDR2_V)<<(SENS_I2C_SLAVE_ADDR2_S)) +#define SENS_I2C_SLAVE_ADDR2_V 0x7FF +#define SENS_I2C_SLAVE_ADDR2_S 11 +/* SENS_I2C_SLAVE_ADDR3 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR3 0x000007FF +#define SENS_I2C_SLAVE_ADDR3_M ((SENS_I2C_SLAVE_ADDR3_V)<<(SENS_I2C_SLAVE_ADDR3_S)) +#define SENS_I2C_SLAVE_ADDR3_V 0x7FF +#define SENS_I2C_SLAVE_ADDR3_S 0 + +#define SENS_SAR_SLAVE_ADDR3_REG (DR_REG_SENS_BASE + 0x0044) +/* SENS_TSENS_RDY_OUT : RO ;bitpos:[30] ;default: 1'h0 ; */ +/*description: indicate temperature sensor out ready*/ +#define SENS_TSENS_RDY_OUT (BIT(30)) +#define SENS_TSENS_RDY_OUT_M (BIT(30)) +#define SENS_TSENS_RDY_OUT_V 0x1 +#define SENS_TSENS_RDY_OUT_S 30 +/* SENS_TSENS_OUT : RO ;bitpos:[29:22] ;default: 8'h0 ; */ +/*description: temperature sensor data out*/ +#define SENS_TSENS_OUT 0x000000FF +#define SENS_TSENS_OUT_M ((SENS_TSENS_OUT_V)<<(SENS_TSENS_OUT_S)) +#define SENS_TSENS_OUT_V 0xFF +#define SENS_TSENS_OUT_S 22 +/* SENS_I2C_SLAVE_ADDR4 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR4 0x000007FF +#define SENS_I2C_SLAVE_ADDR4_M ((SENS_I2C_SLAVE_ADDR4_V)<<(SENS_I2C_SLAVE_ADDR4_S)) +#define SENS_I2C_SLAVE_ADDR4_V 0x7FF +#define SENS_I2C_SLAVE_ADDR4_S 11 +/* SENS_I2C_SLAVE_ADDR5 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR5 0x000007FF +#define SENS_I2C_SLAVE_ADDR5_M ((SENS_I2C_SLAVE_ADDR5_V)<<(SENS_I2C_SLAVE_ADDR5_S)) +#define SENS_I2C_SLAVE_ADDR5_V 0x7FF +#define SENS_I2C_SLAVE_ADDR5_S 0 + +#define SENS_SAR_SLAVE_ADDR4_REG (DR_REG_SENS_BASE + 0x0048) +/* SENS_I2C_DONE : RO ;bitpos:[30] ;default: 1'h0 ; */ +/*description: indicate I2C done*/ +#define SENS_I2C_DONE (BIT(30)) +#define SENS_I2C_DONE_M (BIT(30)) +#define SENS_I2C_DONE_V 0x1 +#define SENS_I2C_DONE_S 30 +/* SENS_I2C_RDATA : RO ;bitpos:[29:22] ;default: 8'h0 ; */ +/*description: I2C read data*/ +#define SENS_I2C_RDATA 0x000000FF +#define SENS_I2C_RDATA_M ((SENS_I2C_RDATA_V)<<(SENS_I2C_RDATA_S)) +#define SENS_I2C_RDATA_V 0xFF +#define SENS_I2C_RDATA_S 22 +/* SENS_I2C_SLAVE_ADDR6 : R/W ;bitpos:[21:11] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR6 0x000007FF +#define SENS_I2C_SLAVE_ADDR6_M ((SENS_I2C_SLAVE_ADDR6_V)<<(SENS_I2C_SLAVE_ADDR6_S)) +#define SENS_I2C_SLAVE_ADDR6_V 0x7FF +#define SENS_I2C_SLAVE_ADDR6_S 11 +/* SENS_I2C_SLAVE_ADDR7 : R/W ;bitpos:[10:0] ;default: 11'h0 ; */ +/*description: */ +#define SENS_I2C_SLAVE_ADDR7 0x000007FF +#define SENS_I2C_SLAVE_ADDR7_M ((SENS_I2C_SLAVE_ADDR7_V)<<(SENS_I2C_SLAVE_ADDR7_S)) +#define SENS_I2C_SLAVE_ADDR7_V 0x7FF +#define SENS_I2C_SLAVE_ADDR7_S 0 + +#define SENS_SAR_TSENS_CTRL_REG (DR_REG_SENS_BASE + 0x004c) +/* SENS_TSENS_DUMP_OUT : R/W ;bitpos:[26] ;default: 1'b0 ; */ +/*description: temperature sensor dump out only active when reg_tsens_power_up_force = 1*/ +#define SENS_TSENS_DUMP_OUT (BIT(26)) +#define SENS_TSENS_DUMP_OUT_M (BIT(26)) +#define SENS_TSENS_DUMP_OUT_V 0x1 +#define SENS_TSENS_DUMP_OUT_S 26 +/* SENS_TSENS_POWER_UP_FORCE : R/W ;bitpos:[25] ;default: 1'b0 ; */ +/*description: 1: dump out & power up controlled by SW 0: by FSM*/ +#define SENS_TSENS_POWER_UP_FORCE (BIT(25)) +#define SENS_TSENS_POWER_UP_FORCE_M (BIT(25)) +#define SENS_TSENS_POWER_UP_FORCE_V 0x1 +#define SENS_TSENS_POWER_UP_FORCE_S 25 +/* SENS_TSENS_POWER_UP : R/W ;bitpos:[24] ;default: 1'b0 ; */ +/*description: temperature sensor power up*/ +#define SENS_TSENS_POWER_UP (BIT(24)) +#define SENS_TSENS_POWER_UP_M (BIT(24)) +#define SENS_TSENS_POWER_UP_V 0x1 +#define SENS_TSENS_POWER_UP_S 24 +/* SENS_TSENS_CLK_DIV : R/W ;bitpos:[23:16] ;default: 8'd6 ; */ +/*description: temperature sensor clock divider*/ +#define SENS_TSENS_CLK_DIV 0x000000FF +#define SENS_TSENS_CLK_DIV_M ((SENS_TSENS_CLK_DIV_V)<<(SENS_TSENS_CLK_DIV_S)) +#define SENS_TSENS_CLK_DIV_V 0xFF +#define SENS_TSENS_CLK_DIV_S 16 +/* SENS_TSENS_IN_INV : R/W ;bitpos:[15] ;default: 1'b0 ; */ +/*description: invert temperature sensor data*/ +#define SENS_TSENS_IN_INV (BIT(15)) +#define SENS_TSENS_IN_INV_M (BIT(15)) +#define SENS_TSENS_IN_INV_V 0x1 +#define SENS_TSENS_IN_INV_S 15 +/* SENS_TSENS_CLK_GATED : R/W ;bitpos:[14] ;default: 1'b1 ; */ +/*description: */ +#define SENS_TSENS_CLK_GATED (BIT(14)) +#define SENS_TSENS_CLK_GATED_M (BIT(14)) +#define SENS_TSENS_CLK_GATED_V 0x1 +#define SENS_TSENS_CLK_GATED_S 14 +/* SENS_TSENS_CLK_INV : R/W ;bitpos:[13] ;default: 1'b1 ; */ +/*description: */ +#define SENS_TSENS_CLK_INV (BIT(13)) +#define SENS_TSENS_CLK_INV_M (BIT(13)) +#define SENS_TSENS_CLK_INV_V 0x1 +#define SENS_TSENS_CLK_INV_S 13 +/* SENS_TSENS_XPD_FORCE : R/W ;bitpos:[12] ;default: 1'b0 ; */ +/*description: */ +#define SENS_TSENS_XPD_FORCE (BIT(12)) +#define SENS_TSENS_XPD_FORCE_M (BIT(12)) +#define SENS_TSENS_XPD_FORCE_V 0x1 +#define SENS_TSENS_XPD_FORCE_S 12 +/* SENS_TSENS_XPD_WAIT : R/W ;bitpos:[11:0] ;default: 12'h2 ; */ +/*description: */ +#define SENS_TSENS_XPD_WAIT 0x00000FFF +#define SENS_TSENS_XPD_WAIT_M ((SENS_TSENS_XPD_WAIT_V)<<(SENS_TSENS_XPD_WAIT_S)) +#define SENS_TSENS_XPD_WAIT_V 0xFFF +#define SENS_TSENS_XPD_WAIT_S 0 + +#define SENS_SAR_I2C_CTRL_REG (DR_REG_SENS_BASE + 0x0050) +/* SENS_SAR_I2C_START_FORCE : R/W ;bitpos:[29] ;default: 1'b0 ; */ +/*description: 1: I2C started by SW 0: I2C started by FSM*/ +#define SENS_SAR_I2C_START_FORCE (BIT(29)) +#define SENS_SAR_I2C_START_FORCE_M (BIT(29)) +#define SENS_SAR_I2C_START_FORCE_V 0x1 +#define SENS_SAR_I2C_START_FORCE_S 29 +/* SENS_SAR_I2C_START : R/W ;bitpos:[28] ;default: 1'b0 ; */ +/*description: start I2C only active when reg_sar_i2c_start_force = 1*/ +#define SENS_SAR_I2C_START (BIT(28)) +#define SENS_SAR_I2C_START_M (BIT(28)) +#define SENS_SAR_I2C_START_V 0x1 +#define SENS_SAR_I2C_START_S 28 +/* SENS_SAR_I2C_CTRL : R/W ;bitpos:[27:0] ;default: 28'b0 ; */ +/*description: I2C control data only active when reg_sar_i2c_start_force = 1*/ +#define SENS_SAR_I2C_CTRL 0x0FFFFFFF +#define SENS_SAR_I2C_CTRL_M ((SENS_SAR_I2C_CTRL_V)<<(SENS_SAR_I2C_CTRL_S)) +#define SENS_SAR_I2C_CTRL_V 0xFFFFFFF +#define SENS_SAR_I2C_CTRL_S 0 + +#define SENS_SAR_MEAS_START1_REG (DR_REG_SENS_BASE + 0x0054) +/* SENS_SAR1_EN_PAD_FORCE : R/W ;bitpos:[31] ;default: 1'b0 ; */ +/*description: 1: SAR ADC1 pad enable bitmap is controlled by SW 0: SAR ADC1 + pad enable bitmap is controlled by ULP-coprocessor*/ +#define SENS_SAR1_EN_PAD_FORCE (BIT(31)) +#define SENS_SAR1_EN_PAD_FORCE_M (BIT(31)) +#define SENS_SAR1_EN_PAD_FORCE_V 0x1 +#define SENS_SAR1_EN_PAD_FORCE_S 31 +/* SENS_SAR1_EN_PAD : R/W ;bitpos:[30:19] ;default: 12'b0 ; */ +/*description: SAR ADC1 pad enable bitmap only active when reg_sar1_en_pad_force = 1*/ +#define SENS_SAR1_EN_PAD 0x00000FFF +#define SENS_SAR1_EN_PAD_M ((SENS_SAR1_EN_PAD_V)<<(SENS_SAR1_EN_PAD_S)) +#define SENS_SAR1_EN_PAD_V 0xFFF +#define SENS_SAR1_EN_PAD_S 19 +/* SENS_MEAS1_START_FORCE : R/W ;bitpos:[18] ;default: 1'b0 ; */ +/*description: 1: SAR ADC1 controller (in RTC) is started by SW 0: SAR ADC1 + controller is started by ULP-coprocessor*/ +#define SENS_MEAS1_START_FORCE (BIT(18)) +#define SENS_MEAS1_START_FORCE_M (BIT(18)) +#define SENS_MEAS1_START_FORCE_V 0x1 +#define SENS_MEAS1_START_FORCE_S 18 +/* SENS_MEAS1_START_SAR : R/W ;bitpos:[17] ;default: 1'b0 ; */ +/*description: SAR ADC1 controller (in RTC) starts conversion only active when + reg_meas1_start_force = 1*/ +#define SENS_MEAS1_START_SAR (BIT(17)) +#define SENS_MEAS1_START_SAR_M (BIT(17)) +#define SENS_MEAS1_START_SAR_V 0x1 +#define SENS_MEAS1_START_SAR_S 17 +/* SENS_MEAS1_DONE_SAR : RO ;bitpos:[16] ;default: 1'b0 ; */ +/*description: SAR ADC1 conversion done indication*/ +#define SENS_MEAS1_DONE_SAR (BIT(16)) +#define SENS_MEAS1_DONE_SAR_M (BIT(16)) +#define SENS_MEAS1_DONE_SAR_V 0x1 +#define SENS_MEAS1_DONE_SAR_S 16 +/* SENS_MEAS1_DATA_SAR : RO ;bitpos:[15:0] ;default: 16'b0 ; */ +/*description: SAR ADC1 data*/ +#define SENS_MEAS1_DATA_SAR 0x0000FFFF +#define SENS_MEAS1_DATA_SAR_M ((SENS_MEAS1_DATA_SAR_V)<<(SENS_MEAS1_DATA_SAR_S)) +#define SENS_MEAS1_DATA_SAR_V 0xFFFF +#define SENS_MEAS1_DATA_SAR_S 0 + +#define SENS_SAR_TOUCH_CTRL1_REG (DR_REG_SENS_BASE + 0x0058) +/* SENS_HALL_PHASE_FORCE : R/W ;bitpos:[27] ;default: 1'b0 ; */ +/*description: 1: HALL PHASE is controlled by SW 0: HALL PHASE is controlled + by FSM in ULP-coprocessor*/ +#define SENS_HALL_PHASE_FORCE (BIT(27)) +#define SENS_HALL_PHASE_FORCE_M (BIT(27)) +#define SENS_HALL_PHASE_FORCE_V 0x1 +#define SENS_HALL_PHASE_FORCE_S 27 +/* SENS_XPD_HALL_FORCE : R/W ;bitpos:[26] ;default: 1'b0 ; */ +/*description: 1: XPD HALL is controlled by SW. 0: XPD HALL is controlled by + FSM in ULP-coprocessor*/ +#define SENS_XPD_HALL_FORCE (BIT(26)) +#define SENS_XPD_HALL_FORCE_M (BIT(26)) +#define SENS_XPD_HALL_FORCE_V 0x1 +#define SENS_XPD_HALL_FORCE_S 26 +/* SENS_TOUCH_OUT_1EN : R/W ;bitpos:[25] ;default: 1'b1 ; */ +/*description: 1: wakeup interrupt is generated if SET1 is "touched" 0: + wakeup interrupt is generated only if SET1 & SET2 is both "touched"*/ +#define SENS_TOUCH_OUT_1EN (BIT(25)) +#define SENS_TOUCH_OUT_1EN_M (BIT(25)) +#define SENS_TOUCH_OUT_1EN_V 0x1 +#define SENS_TOUCH_OUT_1EN_S 25 +/* SENS_TOUCH_OUT_SEL : R/W ;bitpos:[24] ;default: 1'b0 ; */ +/*description: 1: when the counter is greater then the threshold the touch + pad is considered as "touched" 0: when the counter is less than the threshold the touch pad is considered as "touched"*/ +#define SENS_TOUCH_OUT_SEL (BIT(24)) +#define SENS_TOUCH_OUT_SEL_M (BIT(24)) +#define SENS_TOUCH_OUT_SEL_V 0x1 +#define SENS_TOUCH_OUT_SEL_S 24 +/* SENS_TOUCH_XPD_WAIT : R/W ;bitpos:[23:16] ;default: 8'h4 ; */ +/*description: the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD*/ +#define SENS_TOUCH_XPD_WAIT 0x000000FF +#define SENS_TOUCH_XPD_WAIT_M ((SENS_TOUCH_XPD_WAIT_V)<<(SENS_TOUCH_XPD_WAIT_S)) +#define SENS_TOUCH_XPD_WAIT_V 0xFF +#define SENS_TOUCH_XPD_WAIT_S 16 +/* SENS_TOUCH_MEAS_DELAY : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */ +/*description: the meas length (in 8MHz)*/ +#define SENS_TOUCH_MEAS_DELAY 0x0000FFFF +#define SENS_TOUCH_MEAS_DELAY_M ((SENS_TOUCH_MEAS_DELAY_V)<<(SENS_TOUCH_MEAS_DELAY_S)) +#define SENS_TOUCH_MEAS_DELAY_V 0xFFFF +#define SENS_TOUCH_MEAS_DELAY_S 0 + +#define SENS_SAR_TOUCH_THRES1_REG (DR_REG_SENS_BASE + 0x005c) +/* SENS_TOUCH_OUT_TH0 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 0*/ +#define SENS_TOUCH_OUT_TH0 0x0000FFFF +#define SENS_TOUCH_OUT_TH0_M ((SENS_TOUCH_OUT_TH0_V)<<(SENS_TOUCH_OUT_TH0_S)) +#define SENS_TOUCH_OUT_TH0_V 0xFFFF +#define SENS_TOUCH_OUT_TH0_S 16 +/* SENS_TOUCH_OUT_TH1 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 1*/ +#define SENS_TOUCH_OUT_TH1 0x0000FFFF +#define SENS_TOUCH_OUT_TH1_M ((SENS_TOUCH_OUT_TH1_V)<<(SENS_TOUCH_OUT_TH1_S)) +#define SENS_TOUCH_OUT_TH1_V 0xFFFF +#define SENS_TOUCH_OUT_TH1_S 0 + +#define SENS_SAR_TOUCH_THRES2_REG (DR_REG_SENS_BASE + 0x0060) +/* SENS_TOUCH_OUT_TH2 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 2*/ +#define SENS_TOUCH_OUT_TH2 0x0000FFFF +#define SENS_TOUCH_OUT_TH2_M ((SENS_TOUCH_OUT_TH2_V)<<(SENS_TOUCH_OUT_TH2_S)) +#define SENS_TOUCH_OUT_TH2_V 0xFFFF +#define SENS_TOUCH_OUT_TH2_S 16 +/* SENS_TOUCH_OUT_TH3 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 3*/ +#define SENS_TOUCH_OUT_TH3 0x0000FFFF +#define SENS_TOUCH_OUT_TH3_M ((SENS_TOUCH_OUT_TH3_V)<<(SENS_TOUCH_OUT_TH3_S)) +#define SENS_TOUCH_OUT_TH3_V 0xFFFF +#define SENS_TOUCH_OUT_TH3_S 0 + +#define SENS_SAR_TOUCH_THRES3_REG (DR_REG_SENS_BASE + 0x0064) +/* SENS_TOUCH_OUT_TH4 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 4*/ +#define SENS_TOUCH_OUT_TH4 0x0000FFFF +#define SENS_TOUCH_OUT_TH4_M ((SENS_TOUCH_OUT_TH4_V)<<(SENS_TOUCH_OUT_TH4_S)) +#define SENS_TOUCH_OUT_TH4_V 0xFFFF +#define SENS_TOUCH_OUT_TH4_S 16 +/* SENS_TOUCH_OUT_TH5 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 5*/ +#define SENS_TOUCH_OUT_TH5 0x0000FFFF +#define SENS_TOUCH_OUT_TH5_M ((SENS_TOUCH_OUT_TH5_V)<<(SENS_TOUCH_OUT_TH5_S)) +#define SENS_TOUCH_OUT_TH5_V 0xFFFF +#define SENS_TOUCH_OUT_TH5_S 0 + +#define SENS_SAR_TOUCH_THRES4_REG (DR_REG_SENS_BASE + 0x0068) +/* SENS_TOUCH_OUT_TH6 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 6*/ +#define SENS_TOUCH_OUT_TH6 0x0000FFFF +#define SENS_TOUCH_OUT_TH6_M ((SENS_TOUCH_OUT_TH6_V)<<(SENS_TOUCH_OUT_TH6_S)) +#define SENS_TOUCH_OUT_TH6_V 0xFFFF +#define SENS_TOUCH_OUT_TH6_S 16 +/* SENS_TOUCH_OUT_TH7 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 7*/ +#define SENS_TOUCH_OUT_TH7 0x0000FFFF +#define SENS_TOUCH_OUT_TH7_M ((SENS_TOUCH_OUT_TH7_V)<<(SENS_TOUCH_OUT_TH7_S)) +#define SENS_TOUCH_OUT_TH7_V 0xFFFF +#define SENS_TOUCH_OUT_TH7_S 0 + +#define SENS_SAR_TOUCH_THRES5_REG (DR_REG_SENS_BASE + 0x006c) +/* SENS_TOUCH_OUT_TH8 : R/W ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 8*/ +#define SENS_TOUCH_OUT_TH8 0x0000FFFF +#define SENS_TOUCH_OUT_TH8_M ((SENS_TOUCH_OUT_TH8_V)<<(SENS_TOUCH_OUT_TH8_S)) +#define SENS_TOUCH_OUT_TH8_V 0xFFFF +#define SENS_TOUCH_OUT_TH8_S 16 +/* SENS_TOUCH_OUT_TH9 : R/W ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the threshold for touch pad 9*/ +#define SENS_TOUCH_OUT_TH9 0x0000FFFF +#define SENS_TOUCH_OUT_TH9_M ((SENS_TOUCH_OUT_TH9_V)<<(SENS_TOUCH_OUT_TH9_S)) +#define SENS_TOUCH_OUT_TH9_V 0xFFFF +#define SENS_TOUCH_OUT_TH9_S 0 + +#define SENS_SAR_TOUCH_OUT1_REG (DR_REG_SENS_BASE + 0x0070) +/* SENS_TOUCH_MEAS_OUT0 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the counter for touch pad 0*/ +#define SENS_TOUCH_MEAS_OUT0 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT0_M ((SENS_TOUCH_MEAS_OUT0_V)<<(SENS_TOUCH_MEAS_OUT0_S)) +#define SENS_TOUCH_MEAS_OUT0_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT0_S 16 +/* SENS_TOUCH_MEAS_OUT1 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the counter for touch pad 1*/ +#define SENS_TOUCH_MEAS_OUT1 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT1_M ((SENS_TOUCH_MEAS_OUT1_V)<<(SENS_TOUCH_MEAS_OUT1_S)) +#define SENS_TOUCH_MEAS_OUT1_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT1_S 0 + +#define SENS_SAR_TOUCH_OUT2_REG (DR_REG_SENS_BASE + 0x0074) +/* SENS_TOUCH_MEAS_OUT2 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the counter for touch pad 2*/ +#define SENS_TOUCH_MEAS_OUT2 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT2_M ((SENS_TOUCH_MEAS_OUT2_V)<<(SENS_TOUCH_MEAS_OUT2_S)) +#define SENS_TOUCH_MEAS_OUT2_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT2_S 16 +/* SENS_TOUCH_MEAS_OUT3 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the counter for touch pad 3*/ +#define SENS_TOUCH_MEAS_OUT3 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT3_M ((SENS_TOUCH_MEAS_OUT3_V)<<(SENS_TOUCH_MEAS_OUT3_S)) +#define SENS_TOUCH_MEAS_OUT3_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT3_S 0 + +#define SENS_SAR_TOUCH_OUT3_REG (DR_REG_SENS_BASE + 0x0078) +/* SENS_TOUCH_MEAS_OUT4 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the counter for touch pad 4*/ +#define SENS_TOUCH_MEAS_OUT4 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT4_M ((SENS_TOUCH_MEAS_OUT4_V)<<(SENS_TOUCH_MEAS_OUT4_S)) +#define SENS_TOUCH_MEAS_OUT4_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT4_S 16 +/* SENS_TOUCH_MEAS_OUT5 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the counter for touch pad 5*/ +#define SENS_TOUCH_MEAS_OUT5 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT5_M ((SENS_TOUCH_MEAS_OUT5_V)<<(SENS_TOUCH_MEAS_OUT5_S)) +#define SENS_TOUCH_MEAS_OUT5_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT5_S 0 + +#define SENS_SAR_TOUCH_OUT4_REG (DR_REG_SENS_BASE + 0x007c) +/* SENS_TOUCH_MEAS_OUT6 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the counter for touch pad 6*/ +#define SENS_TOUCH_MEAS_OUT6 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT6_M ((SENS_TOUCH_MEAS_OUT6_V)<<(SENS_TOUCH_MEAS_OUT6_S)) +#define SENS_TOUCH_MEAS_OUT6_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT6_S 16 +/* SENS_TOUCH_MEAS_OUT7 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the counter for touch pad 7*/ +#define SENS_TOUCH_MEAS_OUT7 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT7_M ((SENS_TOUCH_MEAS_OUT7_V)<<(SENS_TOUCH_MEAS_OUT7_S)) +#define SENS_TOUCH_MEAS_OUT7_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT7_S 0 + +#define SENS_SAR_TOUCH_OUT5_REG (DR_REG_SENS_BASE + 0x0080) +/* SENS_TOUCH_MEAS_OUT8 : RO ;bitpos:[31:16] ;default: 16'h0 ; */ +/*description: the counter for touch pad 8*/ +#define SENS_TOUCH_MEAS_OUT8 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT8_M ((SENS_TOUCH_MEAS_OUT8_V)<<(SENS_TOUCH_MEAS_OUT8_S)) +#define SENS_TOUCH_MEAS_OUT8_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT8_S 16 +/* SENS_TOUCH_MEAS_OUT9 : RO ;bitpos:[15:0] ;default: 16'h0 ; */ +/*description: the counter for touch pad 9*/ +#define SENS_TOUCH_MEAS_OUT9 0x0000FFFF +#define SENS_TOUCH_MEAS_OUT9_M ((SENS_TOUCH_MEAS_OUT9_V)<<(SENS_TOUCH_MEAS_OUT9_S)) +#define SENS_TOUCH_MEAS_OUT9_V 0xFFFF +#define SENS_TOUCH_MEAS_OUT9_S 0 + +#define SENS_SAR_TOUCH_CTRL2_REG (DR_REG_SENS_BASE + 0x0084) +/* SENS_TOUCH_MEAS_EN_CLR : WO ;bitpos:[30] ;default: 1'h0 ; */ +/*description: to clear reg_touch_meas_en*/ +#define SENS_TOUCH_MEAS_EN_CLR (BIT(30)) +#define SENS_TOUCH_MEAS_EN_CLR_M (BIT(30)) +#define SENS_TOUCH_MEAS_EN_CLR_V 0x1 +#define SENS_TOUCH_MEAS_EN_CLR_S 30 +/* SENS_TOUCH_SLEEP_CYCLES : R/W ;bitpos:[29:14] ;default: 16'h100 ; */ +/*description: sleep cycles for timer*/ +#define SENS_TOUCH_SLEEP_CYCLES 0x0000FFFF +#define SENS_TOUCH_SLEEP_CYCLES_M ((SENS_TOUCH_SLEEP_CYCLES_V)<<(SENS_TOUCH_SLEEP_CYCLES_S)) +#define SENS_TOUCH_SLEEP_CYCLES_V 0xFFFF +#define SENS_TOUCH_SLEEP_CYCLES_S 14 +/* SENS_TOUCH_START_FORCE : R/W ;bitpos:[13] ;default: 1'h0 ; */ +/*description: 1: to start touch fsm by SW 0: to start touch fsm by timer*/ +#define SENS_TOUCH_START_FORCE (BIT(13)) +#define SENS_TOUCH_START_FORCE_M (BIT(13)) +#define SENS_TOUCH_START_FORCE_V 0x1 +#define SENS_TOUCH_START_FORCE_S 13 +/* SENS_TOUCH_START_EN : R/W ;bitpos:[12] ;default: 1'h0 ; */ +/*description: 1: start touch fsm valid when reg_touch_start_force is set*/ +#define SENS_TOUCH_START_EN (BIT(12)) +#define SENS_TOUCH_START_EN_M (BIT(12)) +#define SENS_TOUCH_START_EN_V 0x1 +#define SENS_TOUCH_START_EN_S 12 +/* SENS_TOUCH_START_FSM_EN : R/W ;bitpos:[11] ;default: 1'h1 ; */ +/*description: 1: TOUCH_START & TOUCH_XPD is controlled by touch fsm 0: TOUCH_START + & TOUCH_XPD is controlled by registers*/ +#define SENS_TOUCH_START_FSM_EN (BIT(11)) +#define SENS_TOUCH_START_FSM_EN_M (BIT(11)) +#define SENS_TOUCH_START_FSM_EN_V 0x1 +#define SENS_TOUCH_START_FSM_EN_S 11 +/* SENS_TOUCH_MEAS_DONE : RO ;bitpos:[10] ;default: 1'h0 ; */ +/*description: fsm set 1 to indicate touch touch meas is done*/ +#define SENS_TOUCH_MEAS_DONE (BIT(10)) +#define SENS_TOUCH_MEAS_DONE_M (BIT(10)) +#define SENS_TOUCH_MEAS_DONE_V 0x1 +#define SENS_TOUCH_MEAS_DONE_S 10 +/* SENS_TOUCH_MEAS_EN : RO ;bitpos:[9:0] ;default: 10'h0 ; */ +/*description: 10-bit register to indicate which pads are "touched"*/ +#define SENS_TOUCH_MEAS_EN 0x000003FF +#define SENS_TOUCH_MEAS_EN_M ((SENS_TOUCH_MEAS_EN_V)<<(SENS_TOUCH_MEAS_EN_S)) +#define SENS_TOUCH_MEAS_EN_V 0x3FF +#define SENS_TOUCH_MEAS_EN_S 0 + +#define SENS_SAR_TOUCH_ENABLE_REG (DR_REG_SENS_BASE + 0x008c) +/* SENS_TOUCH_PAD_OUTEN1 : R/W ;bitpos:[29:20] ;default: 10'h3ff ; */ +/*description: Bitmap defining SET1 for generating wakeup interrupt. SET1 is + "touched" only if at least one of touch pad in SET1 is "touched".*/ +#define SENS_TOUCH_PAD_OUTEN1 0x000003FF +#define SENS_TOUCH_PAD_OUTEN1_M ((SENS_TOUCH_PAD_OUTEN1_V)<<(SENS_TOUCH_PAD_OUTEN1_S)) +#define SENS_TOUCH_PAD_OUTEN1_V 0x3FF +#define SENS_TOUCH_PAD_OUTEN1_S 20 +/* SENS_TOUCH_PAD_OUTEN2 : R/W ;bitpos:[19:10] ;default: 10'h3ff ; */ +/*description: Bitmap defining SET2 for generating wakeup interrupt. SET2 is + "touched" only if at least one of touch pad in SET2 is "touched".*/ +#define SENS_TOUCH_PAD_OUTEN2 0x000003FF +#define SENS_TOUCH_PAD_OUTEN2_M ((SENS_TOUCH_PAD_OUTEN2_V)<<(SENS_TOUCH_PAD_OUTEN2_S)) +#define SENS_TOUCH_PAD_OUTEN2_V 0x3FF +#define SENS_TOUCH_PAD_OUTEN2_S 10 +/* SENS_TOUCH_PAD_WORKEN : R/W ;bitpos:[9:0] ;default: 10'h3ff ; */ +/*description: Bitmap defining the working set during the measurement.*/ +#define SENS_TOUCH_PAD_WORKEN 0x000003FF +#define SENS_TOUCH_PAD_WORKEN_M ((SENS_TOUCH_PAD_WORKEN_V)<<(SENS_TOUCH_PAD_WORKEN_S)) +#define SENS_TOUCH_PAD_WORKEN_V 0x3FF +#define SENS_TOUCH_PAD_WORKEN_S 0 + +#define SENS_SAR_READ_CTRL2_REG (DR_REG_SENS_BASE + 0x0090) +/* SENS_SAR2_DATA_INV : R/W ;bitpos:[29] ;default: 1'b0 ; */ +/*description: Invert SAR ADC2 data*/ +#define SENS_SAR2_DATA_INV (BIT(29)) +#define SENS_SAR2_DATA_INV_M (BIT(29)) +#define SENS_SAR2_DATA_INV_V 0x1 +#define SENS_SAR2_DATA_INV_S 29 +/* SENS_SAR2_DIG_FORCE : R/W ;bitpos:[28] ;default: 1'b0 ; */ +/*description: 1: SAR ADC2 controlled by DIG ADC2 CTRL or PWDET CTRL 0: SAR + ADC2 controlled by RTC ADC2 CTRL*/ +#define SENS_SAR2_DIG_FORCE (BIT(28)) +#define SENS_SAR2_DIG_FORCE_M (BIT(28)) +#define SENS_SAR2_DIG_FORCE_V 0x1 +#define SENS_SAR2_DIG_FORCE_S 28 +/* SENS_SAR2_PWDET_FORCE : R/W ;bitpos:[27] ;default: 1'b0 ; */ +/*description: */ +#define SENS_SAR2_PWDET_FORCE (BIT(27)) +#define SENS_SAR2_PWDET_FORCE_M (BIT(27)) +#define SENS_SAR2_PWDET_FORCE_V 0x1 +#define SENS_SAR2_PWDET_FORCE_S 27 +/* SENS_SAR2_SAMPLE_NUM : R/W ;bitpos:[26:19] ;default: 8'd0 ; */ +/*description: */ +#define SENS_SAR2_SAMPLE_NUM 0x000000FF +#define SENS_SAR2_SAMPLE_NUM_M ((SENS_SAR2_SAMPLE_NUM_V)<<(SENS_SAR2_SAMPLE_NUM_S)) +#define SENS_SAR2_SAMPLE_NUM_V 0xFF +#define SENS_SAR2_SAMPLE_NUM_S 19 +/* SENS_SAR2_CLK_GATED : R/W ;bitpos:[18] ;default: 1'b1 ; */ +/*description: */ +#define SENS_SAR2_CLK_GATED (BIT(18)) +#define SENS_SAR2_CLK_GATED_M (BIT(18)) +#define SENS_SAR2_CLK_GATED_V 0x1 +#define SENS_SAR2_CLK_GATED_S 18 +/* SENS_SAR2_SAMPLE_BIT : R/W ;bitpos:[17:16] ;default: 2'd3 ; */ +/*description: 00: for 9-bit width 01: for 10-bit width 10: for 11-bit width + 11: for 12-bit width*/ +#define SENS_SAR2_SAMPLE_BIT 0x00000003 +#define SENS_SAR2_SAMPLE_BIT_M ((SENS_SAR2_SAMPLE_BIT_V)<<(SENS_SAR2_SAMPLE_BIT_S)) +#define SENS_SAR2_SAMPLE_BIT_V 0x3 +#define SENS_SAR2_SAMPLE_BIT_S 16 +/* SENS_SAR2_SAMPLE_CYCLE : R/W ;bitpos:[15:8] ;default: 8'd9 ; */ +/*description: sample cycles for SAR ADC2*/ +#define SENS_SAR2_SAMPLE_CYCLE 0x000000FF +#define SENS_SAR2_SAMPLE_CYCLE_M ((SENS_SAR2_SAMPLE_CYCLE_V)<<(SENS_SAR2_SAMPLE_CYCLE_S)) +#define SENS_SAR2_SAMPLE_CYCLE_V 0xFF +#define SENS_SAR2_SAMPLE_CYCLE_S 8 +/* SENS_SAR2_CLK_DIV : R/W ;bitpos:[7:0] ;default: 8'd2 ; */ +/*description: clock divider*/ +#define SENS_SAR2_CLK_DIV 0x000000FF +#define SENS_SAR2_CLK_DIV_M ((SENS_SAR2_CLK_DIV_V)<<(SENS_SAR2_CLK_DIV_S)) +#define SENS_SAR2_CLK_DIV_V 0xFF +#define SENS_SAR2_CLK_DIV_S 0 + +#define SENS_SAR_MEAS_START2_REG (DR_REG_SENS_BASE + 0x0094) +/* SENS_SAR2_EN_PAD_FORCE : R/W ;bitpos:[31] ;default: 1'b0 ; */ +/*description: 1: SAR ADC2 pad enable bitmap is controlled by SW 0: SAR ADC2 + pad enable bitmap is controlled by ULP-coprocessor*/ +#define SENS_SAR2_EN_PAD_FORCE (BIT(31)) +#define SENS_SAR2_EN_PAD_FORCE_M (BIT(31)) +#define SENS_SAR2_EN_PAD_FORCE_V 0x1 +#define SENS_SAR2_EN_PAD_FORCE_S 31 +/* SENS_SAR2_EN_PAD : R/W ;bitpos:[30:19] ;default: 12'b0 ; */ +/*description: SAR ADC2 pad enable bitmap only active when reg_sar2_en_pad_force = 1*/ +#define SENS_SAR2_EN_PAD 0x00000FFF +#define SENS_SAR2_EN_PAD_M ((SENS_SAR2_EN_PAD_V)<<(SENS_SAR2_EN_PAD_S)) +#define SENS_SAR2_EN_PAD_V 0xFFF +#define SENS_SAR2_EN_PAD_S 19 +/* SENS_MEAS2_START_FORCE : R/W ;bitpos:[18] ;default: 1'b0 ; */ +/*description: 1: SAR ADC2 controller (in RTC) is started by SW 0: SAR ADC2 + controller is started by ULP-coprocessor*/ +#define SENS_MEAS2_START_FORCE (BIT(18)) +#define SENS_MEAS2_START_FORCE_M (BIT(18)) +#define SENS_MEAS2_START_FORCE_V 0x1 +#define SENS_MEAS2_START_FORCE_S 18 +/* SENS_MEAS2_START_SAR : R/W ;bitpos:[17] ;default: 1'b0 ; */ +/*description: SAR ADC2 controller (in RTC) starts conversion only active when + reg_meas2_start_force = 1*/ +#define SENS_MEAS2_START_SAR (BIT(17)) +#define SENS_MEAS2_START_SAR_M (BIT(17)) +#define SENS_MEAS2_START_SAR_V 0x1 +#define SENS_MEAS2_START_SAR_S 17 +/* SENS_MEAS2_DONE_SAR : RO ;bitpos:[16] ;default: 1'b0 ; */ +/*description: SAR ADC2 conversion done indication*/ +#define SENS_MEAS2_DONE_SAR (BIT(16)) +#define SENS_MEAS2_DONE_SAR_M (BIT(16)) +#define SENS_MEAS2_DONE_SAR_V 0x1 +#define SENS_MEAS2_DONE_SAR_S 16 +/* SENS_MEAS2_DATA_SAR : RO ;bitpos:[15:0] ;default: 16'b0 ; */ +/*description: SAR ADC2 data*/ +#define SENS_MEAS2_DATA_SAR 0x0000FFFF +#define SENS_MEAS2_DATA_SAR_M ((SENS_MEAS2_DATA_SAR_V)<<(SENS_MEAS2_DATA_SAR_S)) +#define SENS_MEAS2_DATA_SAR_V 0xFFFF +#define SENS_MEAS2_DATA_SAR_S 0 + +#define SENS_SAR_DAC_CTRL1_REG (DR_REG_SENS_BASE + 0x0098) +/* SENS_DAC_CLK_INV : R/W ;bitpos:[25] ;default: 1'b0 ; */ +/*description: 1: invert PDAC_CLK*/ +#define SENS_DAC_CLK_INV (BIT(25)) +#define SENS_DAC_CLK_INV_M (BIT(25)) +#define SENS_DAC_CLK_INV_V 0x1 +#define SENS_DAC_CLK_INV_S 25 +/* SENS_DAC_CLK_FORCE_HIGH : R/W ;bitpos:[24] ;default: 1'b0 ; */ +/*description: 1: force PDAC_CLK to high*/ +#define SENS_DAC_CLK_FORCE_HIGH (BIT(24)) +#define SENS_DAC_CLK_FORCE_HIGH_M (BIT(24)) +#define SENS_DAC_CLK_FORCE_HIGH_V 0x1 +#define SENS_DAC_CLK_FORCE_HIGH_S 24 +/* SENS_DAC_CLK_FORCE_LOW : R/W ;bitpos:[23] ;default: 1'b0 ; */ +/*description: 1: force PDAC_CLK to low*/ +#define SENS_DAC_CLK_FORCE_LOW (BIT(23)) +#define SENS_DAC_CLK_FORCE_LOW_M (BIT(23)) +#define SENS_DAC_CLK_FORCE_LOW_V 0x1 +#define SENS_DAC_CLK_FORCE_LOW_S 23 +/* SENS_DAC_DIG_FORCE : R/W ;bitpos:[22] ;default: 1'b0 ; */ +/*description: 1: DAC1 & DAC2 use DMA 0: DAC1 & DAC2 do not use DMA*/ +#define SENS_DAC_DIG_FORCE (BIT(22)) +#define SENS_DAC_DIG_FORCE_M (BIT(22)) +#define SENS_DAC_DIG_FORCE_V 0x1 +#define SENS_DAC_DIG_FORCE_S 22 +/* SENS_DEBUG_BIT_SEL : R/W ;bitpos:[21:17] ;default: 5'b0 ; */ +/*description: */ +#define SENS_DEBUG_BIT_SEL 0x0000001F +#define SENS_DEBUG_BIT_SEL_M ((SENS_DEBUG_BIT_SEL_V)<<(SENS_DEBUG_BIT_SEL_S)) +#define SENS_DEBUG_BIT_SEL_V 0x1F +#define SENS_DEBUG_BIT_SEL_S 17 +/* SENS_SW_TONE_EN : R/W ;bitpos:[16] ;default: 1'b0 ; */ +/*description: 1: enable CW generator 0: disable CW generator*/ +#define SENS_SW_TONE_EN (BIT(16)) +#define SENS_SW_TONE_EN_M (BIT(16)) +#define SENS_SW_TONE_EN_V 0x1 +#define SENS_SW_TONE_EN_S 16 +/* SENS_SW_FSTEP : R/W ;bitpos:[15:0] ;default: 16'b0 ; */ +/*description: frequency step for CW generator can be used to adjust the frequency*/ +#define SENS_SW_FSTEP 0x0000FFFF +#define SENS_SW_FSTEP_M ((SENS_SW_FSTEP_V)<<(SENS_SW_FSTEP_S)) +#define SENS_SW_FSTEP_V 0xFFFF +#define SENS_SW_FSTEP_S 0 + +#define SENS_SAR_DAC_CTRL2_REG (DR_REG_SENS_BASE + 0x009c) +/* SENS_DAC_CW_EN2 : R/W ;bitpos:[25] ;default: 1'b1 ; */ +/*description: 1: to select CW generator as source to PDAC2_DAC[7:0] 0: to + select register reg_pdac2_dac[7:0] as source to PDAC2_DAC[7:0]*/ +#define SENS_DAC_CW_EN2 (BIT(25)) +#define SENS_DAC_CW_EN2_M (BIT(25)) +#define SENS_DAC_CW_EN2_V 0x1 +#define SENS_DAC_CW_EN2_S 25 +/* SENS_DAC_CW_EN1 : R/W ;bitpos:[24] ;default: 1'b1 ; */ +/*description: 1: to select CW generator as source to PDAC1_DAC[7:0] 0: to + select register reg_pdac1_dac[7:0] as source to PDAC1_DAC[7:0]*/ +#define SENS_DAC_CW_EN1 (BIT(24)) +#define SENS_DAC_CW_EN1_M (BIT(24)) +#define SENS_DAC_CW_EN1_V 0x1 +#define SENS_DAC_CW_EN1_S 24 +/* SENS_DAC_INV2 : R/W ;bitpos:[23:22] ;default: 2'b0 ; */ +/*description: 00: do not invert any bits 01: invert all bits 10: invert MSB + 11: invert all bits except MSB*/ +#define SENS_DAC_INV2 0x00000003 +#define SENS_DAC_INV2_M ((SENS_DAC_INV2_V)<<(SENS_DAC_INV2_S)) +#define SENS_DAC_INV2_V 0x3 +#define SENS_DAC_INV2_S 22 +/* SENS_DAC_INV1 : R/W ;bitpos:[21:20] ;default: 2'b0 ; */ +/*description: 00: do not invert any bits 01: invert all bits 10: invert MSB + 11: invert all bits except MSB*/ +#define SENS_DAC_INV1 0x00000003 +#define SENS_DAC_INV1_M ((SENS_DAC_INV1_V)<<(SENS_DAC_INV1_S)) +#define SENS_DAC_INV1_V 0x3 +#define SENS_DAC_INV1_S 20 +/* SENS_DAC_SCALE2 : R/W ;bitpos:[19:18] ;default: 2'b0 ; */ +/*description: 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8*/ +#define SENS_DAC_SCALE2 0x00000003 +#define SENS_DAC_SCALE2_M ((SENS_DAC_SCALE2_V)<<(SENS_DAC_SCALE2_S)) +#define SENS_DAC_SCALE2_V 0x3 +#define SENS_DAC_SCALE2_S 18 +/* SENS_DAC_SCALE1 : R/W ;bitpos:[17:16] ;default: 2'b0 ; */ +/*description: 00: no scale 01: scale to 1/2 10: scale to 1/4 scale to 1/8*/ +#define SENS_DAC_SCALE1 0x00000003 +#define SENS_DAC_SCALE1_M ((SENS_DAC_SCALE1_V)<<(SENS_DAC_SCALE1_S)) +#define SENS_DAC_SCALE1_V 0x3 +#define SENS_DAC_SCALE1_S 16 +/* SENS_DAC_DC2 : R/W ;bitpos:[15:8] ;default: 8'b0 ; */ +/*description: DC offset for DAC2 CW generator*/ +#define SENS_DAC_DC2 0x000000FF +#define SENS_DAC_DC2_M ((SENS_DAC_DC2_V)<<(SENS_DAC_DC2_S)) +#define SENS_DAC_DC2_V 0xFF +#define SENS_DAC_DC2_S 8 +/* SENS_DAC_DC1 : R/W ;bitpos:[7:0] ;default: 8'b0 ; */ +/*description: DC offset for DAC1 CW generator*/ +#define SENS_DAC_DC1 0x000000FF +#define SENS_DAC_DC1_M ((SENS_DAC_DC1_V)<<(SENS_DAC_DC1_S)) +#define SENS_DAC_DC1_V 0xFF +#define SENS_DAC_DC1_S 0 + +#define SENS_SAR_MEAS_CTRL2_REG (DR_REG_SENS_BASE + 0x0a0) +/* SENS_AMP_SHORT_REF_GND_FORCE : R/W ;bitpos:[18:17] ;default: 2'b0 ; */ +/*description: */ +#define SENS_AMP_SHORT_REF_GND_FORCE 0x00000003 +#define SENS_AMP_SHORT_REF_GND_FORCE_M ((SENS_AMP_SHORT_REF_GND_FORCE_V)<<(SENS_AMP_SHORT_REF_GND_FORCE_S)) +#define SENS_AMP_SHORT_REF_GND_FORCE_V 0x3 +#define SENS_AMP_SHORT_REF_GND_FORCE_S 17 +/* SENS_AMP_SHORT_REF_FORCE : R/W ;bitpos:[16:15] ;default: 2'b0 ; */ +/*description: */ +#define SENS_AMP_SHORT_REF_FORCE 0x00000003 +#define SENS_AMP_SHORT_REF_FORCE_M ((SENS_AMP_SHORT_REF_FORCE_V)<<(SENS_AMP_SHORT_REF_FORCE_S)) +#define SENS_AMP_SHORT_REF_FORCE_V 0x3 +#define SENS_AMP_SHORT_REF_FORCE_S 15 +/* SENS_AMP_RST_FB_FORCE : R/W ;bitpos:[14:13] ;default: 2'b0 ; */ +/*description: */ +#define SENS_AMP_RST_FB_FORCE 0x00000003 +#define SENS_AMP_RST_FB_FORCE_M ((SENS_AMP_RST_FB_FORCE_V)<<(SENS_AMP_RST_FB_FORCE_S)) +#define SENS_AMP_RST_FB_FORCE_V 0x3 +#define SENS_AMP_RST_FB_FORCE_S 13 +/* SENS_SAR2_RSTB_FORCE : R/W ;bitpos:[12:11] ;default: 2'b0 ; */ +/*description: */ +#define SENS_SAR2_RSTB_FORCE 0x00000003 +#define SENS_SAR2_RSTB_FORCE_M ((SENS_SAR2_RSTB_FORCE_V)<<(SENS_SAR2_RSTB_FORCE_S)) +#define SENS_SAR2_RSTB_FORCE_V 0x3 +#define SENS_SAR2_RSTB_FORCE_S 11 +/* SENS_SAR_RSTB_FSM_IDLE : R/W ;bitpos:[10] ;default: 1'b0 ; */ +/*description: */ +#define SENS_SAR_RSTB_FSM_IDLE (BIT(10)) +#define SENS_SAR_RSTB_FSM_IDLE_M (BIT(10)) +#define SENS_SAR_RSTB_FSM_IDLE_V 0x1 +#define SENS_SAR_RSTB_FSM_IDLE_S 10 +/* SENS_XPD_SAR_FSM_IDLE : R/W ;bitpos:[9] ;default: 1'b0 ; */ +/*description: */ +#define SENS_XPD_SAR_FSM_IDLE (BIT(9)) +#define SENS_XPD_SAR_FSM_IDLE_M (BIT(9)) +#define SENS_XPD_SAR_FSM_IDLE_V 0x1 +#define SENS_XPD_SAR_FSM_IDLE_S 9 +/* SENS_AMP_SHORT_REF_GND_FSM_IDLE : R/W ;bitpos:[8] ;default: 1'b0 ; */ +/*description: */ +#define SENS_AMP_SHORT_REF_GND_FSM_IDLE (BIT(8)) +#define SENS_AMP_SHORT_REF_GND_FSM_IDLE_M (BIT(8)) +#define SENS_AMP_SHORT_REF_GND_FSM_IDLE_V 0x1 +#define SENS_AMP_SHORT_REF_GND_FSM_IDLE_S 8 +/* SENS_AMP_SHORT_REF_FSM_IDLE : R/W ;bitpos:[7] ;default: 1'b0 ; */ +/*description: */ +#define SENS_AMP_SHORT_REF_FSM_IDLE (BIT(7)) +#define SENS_AMP_SHORT_REF_FSM_IDLE_M (BIT(7)) +#define SENS_AMP_SHORT_REF_FSM_IDLE_V 0x1 +#define SENS_AMP_SHORT_REF_FSM_IDLE_S 7 +/* SENS_AMP_RST_FB_FSM_IDLE : R/W ;bitpos:[6] ;default: 1'b0 ; */ +/*description: */ +#define SENS_AMP_RST_FB_FSM_IDLE (BIT(6)) +#define SENS_AMP_RST_FB_FSM_IDLE_M (BIT(6)) +#define SENS_AMP_RST_FB_FSM_IDLE_V 0x1 +#define SENS_AMP_RST_FB_FSM_IDLE_S 6 +/* SENS_XPD_SAR_AMP_FSM_IDLE : R/W ;bitpos:[5] ;default: 1'b0 ; */ +/*description: */ +#define SENS_XPD_SAR_AMP_FSM_IDLE (BIT(5)) +#define SENS_XPD_SAR_AMP_FSM_IDLE_M (BIT(5)) +#define SENS_XPD_SAR_AMP_FSM_IDLE_V 0x1 +#define SENS_XPD_SAR_AMP_FSM_IDLE_S 5 +/* SENS_SAR1_DAC_XPD_FSM_IDLE : R/W ;bitpos:[4] ;default: 1'b0 ; */ +/*description: */ +#define SENS_SAR1_DAC_XPD_FSM_IDLE (BIT(4)) +#define SENS_SAR1_DAC_XPD_FSM_IDLE_M (BIT(4)) +#define SENS_SAR1_DAC_XPD_FSM_IDLE_V 0x1 +#define SENS_SAR1_DAC_XPD_FSM_IDLE_S 4 +/* SENS_SAR1_DAC_XPD_FSM : R/W ;bitpos:[3:0] ;default: 4'b0011 ; */ +/*description: */ +#define SENS_SAR1_DAC_XPD_FSM 0x0000000F +#define SENS_SAR1_DAC_XPD_FSM_M ((SENS_SAR1_DAC_XPD_FSM_V)<<(SENS_SAR1_DAC_XPD_FSM_S)) +#define SENS_SAR1_DAC_XPD_FSM_V 0xF +#define SENS_SAR1_DAC_XPD_FSM_S 0 + +#define SENS_SAR_NOUSE_REG (DR_REG_SENS_BASE + 0x00F8) +/* SENS_SAR_NOUSE : R/W ;bitpos:[31:0] ;default: 32'h0 ; */ +/*description: */ +#define SENS_SAR_NOUSE 0xFFFFFFFF +#define SENS_SAR_NOUSE_M ((SENS_SAR_NOUSE_V)<<(SENS_SAR_NOUSE_S)) +#define SENS_SAR_NOUSE_V 0xFFFFFFFF +#define SENS_SAR_NOUSE_S 0 + +#define SENS_SARDATE_REG (DR_REG_SENS_BASE + 0x00FC) +/* SENS_SAR_DATE : R/W ;bitpos:[27:0] ;default: 28'h1605180 ; */ +/*description: */ +#define SENS_SAR_DATE 0x0FFFFFFF +#define SENS_SAR_DATE_M ((SENS_SAR_DATE_V)<<(SENS_SAR_DATE_S)) +#define SENS_SAR_DATE_V 0xFFFFFFF +#define SENS_SAR_DATE_S 0 + + + + +#endif /*_SOC_SENS_REG_H_ */ + + diff --git a/components/esp32/include/soc/soc.h b/components/esp32/include/soc/soc.h index 04551f61fe..b93bae7298 100755 --- a/components/esp32/include/soc/soc.h +++ b/components/esp32/include/soc/soc.h @@ -79,8 +79,8 @@ //set bits of register controlled by mask #define REG_SET_BITS(_r, _b, _m) (*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m))) -//get field from register, used when _f is not left shifted by _f##_S -#define REG_GET_FIELD(_r, _f) ((REG_READ(_r) >> (_f##_S)) & (_f)) +//get field from register, uses field _S & _V to determine mask +#define REG_GET_FIELD(_r, _f) ((REG_READ(_r) >> (_f##_S)) & (_f##_V)) //set field to register, used when _f is not left shifted by _f##_S #define REG_SET_FIELD(_r, _f, _v) (REG_WRITE((_r),((REG_READ(_r) & ~((_f) << (_f##_S)))|(((_v) & (_f))<<(_f##_S))))) @@ -153,7 +153,7 @@ #define DR_REG_FRC_TIMER_BASE 0x3ff47000 #define DR_REG_RTCCNTL_BASE 0x3ff48000 #define DR_REG_RTCIO_BASE 0x3ff48400 -#define DR_REG_SARADC_BASE 0x3ff48800 +#define DR_REG_SENS_BASE 0x3ff48800 #define DR_REG_IO_MUX_BASE 0x3ff49000 #define DR_REG_RTCMEM0_BASE 0x3ff61000 #define DR_REG_RTCMEM1_BASE 0x3ff62000 @@ -264,14 +264,14 @@ * Intr num Level Type PRO CPU usage APP CPU uasge * 0 1 extern level WMAC Reserved * 1 1 extern level BT/BLE Host VHCI Reserved - * 2 1 extern level FROM_CPU FROM_CPU - * 3 1 extern level TG0_WDT Reserved + * 2 1 extern level + * 3 1 extern level * 4 1 extern level WBB * 5 1 extern level BT Controller * 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1) * 7 1 software Reserved Reserved * 8 1 extern level BLE Controller - * 9 1 extern level EMAC + * 9 1 extern level * 10 1 extern edge Internal Timer * 11 3 profiling * 12 1 extern level @@ -300,10 +300,7 @@ //CPU0 Interrupt number reserved, not touch this. #define ETS_WMAC_INUM 0 #define ETS_BT_HOST_INUM 1 -#define ETS_FROM_CPU_INUM 2 -#define ETS_T0_WDT_INUM 3 #define ETS_WBB_INUM 4 -#define ETS_EMAC_INUM 9 #define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/ #define ETS_FRC1_INUM 22 #define ETS_T1_WDT_INUM 24 diff --git a/components/esp32/include/soc/spi_reg.h b/components/esp32/include/soc/spi_reg.h index 34f2f24e1c..d1eeedb9f0 100644 --- a/components/esp32/include/soc/spi_reg.h +++ b/components/esp32/include/soc/spi_reg.h @@ -69,14 +69,14 @@ #define SPI_FLASH_PP_V 0x1 #define SPI_FLASH_PP_S 25 /* SPI_FLASH_SE : R/W ;bitpos:[24] ;default: 1'b0 ; */ -/*description: Sector erase enable(4KB). Sector erase operation will be triggered +/*description: Sector erase enable. A 4KB sector is erased via SPI command 20H. Sector erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/ #define SPI_FLASH_SE (BIT(24)) #define SPI_FLASH_SE_M (BIT(24)) #define SPI_FLASH_SE_V 0x1 #define SPI_FLASH_SE_S 24 /* SPI_FLASH_BE : R/W ;bitpos:[23] ;default: 1'b0 ; */ -/*description: Block erase enable(32KB) . Block erase operation will be triggered +/*description: Block erase enable. A 64KB block is erased via SPI command D8H. Block erase operation will be triggered when the bit is set. The bit will be cleared once the operation done.1: enable 0: disable.*/ #define SPI_FLASH_BE (BIT(23)) #define SPI_FLASH_BE_M (BIT(23)) diff --git a/components/esp32/include/soc/wdev_reg.h b/components/esp32/include/soc/wdev_reg.h index 7189c9ec39..f3217cb0d6 100644 --- a/components/esp32/include/soc/wdev_reg.h +++ b/components/esp32/include/soc/wdev_reg.h @@ -14,5 +14,7 @@ #pragma once +#include "soc.h" + /* Hardware random number generator register */ #define WDEV_RND_REG 0x60035144 diff --git a/components/esp32/intr_alloc.c b/components/esp32/intr_alloc.c new file mode 100644 index 0000000000..9476a433d4 --- /dev/null +++ b/components/esp32/intr_alloc.c @@ -0,0 +1,739 @@ +// 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 "sdkconfig.h" +#include +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include +#include "esp_err.h" +#include "esp_log.h" +#include "esp_intr.h" +#include "esp_attr.h" +#include "esp_intr_alloc.h" +#include +#include + +static const char* TAG = "intr_alloc"; + + +#define ETS_INTERNAL_TIMER0_INTR_NO 6 +#define ETS_INTERNAL_TIMER1_INTR_NO 15 +#define ETS_INTERNAL_TIMER2_INTR_NO 16 +#define ETS_INTERNAL_SW0_INTR_NO 7 +#define ETS_INTERNAL_SW1_INTR_NO 29 +#define ETS_INTERNAL_PROFILING_INTR_NO 11 + + +/* +Define this to debug the choices made when allocating the interrupt. This leads to much debugging +output within a critical region, which can lead to weird effects like e.g. the interrupt watchdog +being triggered, that is why it is separate from the normal LOG* scheme. +*/ +//define DEBUG_INT_ALLOC_DECISIONS +#ifdef DEBUG_INT_ALLOC_DECISIONS +# define ALCHLOG(...) ESP_EARLY_LOGD(TAG, __VA_ARGS__) +#else +# define ALCHLOG(...) do {} while (0) +#endif + + +typedef enum { + INTDESC_NORMAL=0, + INTDESC_RESVD, + INTDESC_SPECIAL //for xtensa timers / software ints +} int_desc_flag_t; + +typedef enum { + INTTP_LEVEL=0, + INTTP_EDGE, + INTTP_NA +} int_type_t; + +typedef struct { + int level; + int_type_t type; + int_desc_flag_t cpuflags[2]; +} int_desc_t; + + +//We should mark the interrupt for the timer used by FreeRTOS as reserved. The specific timer +//is selectable using menuconfig; we use these cpp bits to convert that into something we can use in +//the table below. +#if CONFIG_FREERTOS_CORETIMER_0 +#define INT6RES INTDESC_RESVD +#else +#define INT6RES INTDESC_SPECIAL +#endif + +#if CONFIG_FREERTOS_CORETIMER_1 +#define INT15RES INTDESC_RESVD +#else +#define INT15RES INTDESC_SPECIAL +#endif + +#if CONFIG_FREERTOS_CORETIMER_2 +#define INT16RES INTDESC_RESVD +#else +#define INT16RES INTDESC_SPECIAL +#endif + +//This is basically a software-readable version of the interrupt usage table in include/soc/soc.h +const static int_desc_t int_desc[32]={ + { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //0 + { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //1 + { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //2 + { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //3 + { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //4 + { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //5 + { 1, INTTP_NA, {INT6RES, INT6RES } }, //6 + { 1, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //7 + { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //8 + { 1, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //9 //FRC1 + { 1, INTTP_EDGE , {INTDESC_RESVD, INTDESC_RESVD } }, //10 //FRC2 + { 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //11 + { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //12 + { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //13 + { 7, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //14, NMI + { 3, INTTP_NA, {INT15RES, INT15RES } }, //15 + { 5, INTTP_NA, {INT16RES, INT16RES } }, //16 + { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //17 + { 1, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //18 + { 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //19 + { 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //20 + { 2, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //21 + { 3, INTTP_EDGE, {INTDESC_RESVD, INTDESC_NORMAL} }, //22 + { 3, INTTP_LEVEL, {INTDESC_NORMAL, INTDESC_NORMAL} }, //23 + { 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_NORMAL} }, //24 + { 4, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //25 + { 5, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //26 + { 3, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //27 + { 4, INTTP_EDGE, {INTDESC_NORMAL, INTDESC_NORMAL} }, //28 + { 3, INTTP_NA, {INTDESC_SPECIAL,INTDESC_SPECIAL}}, //29 + { 4, INTTP_EDGE, {INTDESC_RESVD, INTDESC_RESVD } }, //30 + { 5, INTTP_LEVEL, {INTDESC_RESVD, INTDESC_RESVD } }, //31 +}; + +typedef struct shared_vector_desc_t shared_vector_desc_t; +typedef struct vector_desc_t vector_desc_t; + +struct shared_vector_desc_t { + int disabled: 1; + int source: 8; + volatile uint32_t *statusreg; + uint32_t statusmask; + intr_handler_t isr; + void *arg; + shared_vector_desc_t *next; +}; + + +#define VECDESC_FL_RESERVED (1<<0) +#define VECDESC_FL_INIRAM (1<<1) +#define VECDESC_FL_SHARED (1<<2) +#define VECDESC_FL_NONSHARED (1<<3) + +//Pack using bitfields for better memory use +struct vector_desc_t { + int flags: 16; //OR of VECDESC_FLAG_* defines + unsigned int cpu: 1; + unsigned int intno: 5; + int source: 8; //Interrupt mux flags, used when not shared + shared_vector_desc_t *shared_vec_info; //used when VECDESC_FL_SHARED + vector_desc_t *next; +}; + +struct intr_handle_data_t { + vector_desc_t *vector_desc; + shared_vector_desc_t *shared_vector_desc; +}; + + +//Linked list of vector descriptions, sorted by cpu.intno value +static vector_desc_t *vector_desc_head; + +//This bitmask has an 1 if the int should be disabled when the flash is disabled. +static uint32_t non_iram_int_mask[portNUM_PROCESSORS]; +//This bitmask has 1 in it if the int was disabled using esp_intr_noniram_disable. +static uint32_t non_iram_int_disabled[portNUM_PROCESSORS]; +static bool non_iram_int_disabled_flag[portNUM_PROCESSORS]; + + +static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED; + +//Inserts an item into vector_desc list so that the list is sorted +//with an incrementing cpu.intno value. +static void insert_vector_desc(vector_desc_t *to_insert) +{ + vector_desc_t *vd=vector_desc_head; + vector_desc_t *prev=NULL; + while(vd!=NULL) { + if (vd->cpu > to_insert->cpu) break; + if (vd->cpu == to_insert->cpu && vd->intno >= to_insert->intno) break; + prev=vd; + vd=vd->next; + } + if (vd==NULL && prev==NULL) { + //First item + vector_desc_head=to_insert; + vector_desc_head->next=NULL; + } else { + prev->next=to_insert; + to_insert->next=vd; + } +} + +//Returns a vector_desc entry for an intno/cpu, or NULL if none exists. +static vector_desc_t *find_desc_for_int(int intno, int cpu) +{ + vector_desc_t *vd=vector_desc_head; + while(vd!=NULL) { + if (vd->cpu==cpu && vd->intno==intno) break; + vd=vd->next; + } + return vd; +} + +//Returns a vector_desc entry for an intno/cpu. +//Either returns a preexisting one or allocates a new one and inserts +//it into the list. Returns NULL on malloc fail. +static vector_desc_t *get_desc_for_int(int intno, int cpu) +{ + vector_desc_t *vd=find_desc_for_int(intno, cpu); + if (vd==NULL) { + vector_desc_t *newvd=malloc(sizeof(vector_desc_t)); + if (newvd==NULL) return NULL; + memset(newvd, 0, sizeof(vector_desc_t)); + newvd->intno=intno; + newvd->cpu=cpu; + insert_vector_desc(newvd); + return newvd; + } else { + return vd; + } +} + +esp_err_t esp_intr_mark_shared(int intno, int cpu, bool is_int_ram) +{ + if (intno>31) return ESP_ERR_INVALID_ARG; + if (cpu>=portNUM_PROCESSORS) return ESP_ERR_INVALID_ARG; + + portENTER_CRITICAL(&spinlock); + vector_desc_t *vd=get_desc_for_int(intno, cpu); + if (vd==NULL) { + portEXIT_CRITICAL(&spinlock); + return ESP_ERR_NO_MEM; + } + vd->flags=VECDESC_FL_SHARED; + if (is_int_ram) vd->flags|=VECDESC_FL_INIRAM; + portEXIT_CRITICAL(&spinlock); + + return ESP_OK; +} + +esp_err_t esp_intr_reserve(int intno, int cpu) +{ + if (intno>31) return ESP_ERR_INVALID_ARG; + if (cpu>=portNUM_PROCESSORS) return ESP_ERR_INVALID_ARG; + + portENTER_CRITICAL(&spinlock); + vector_desc_t *vd=get_desc_for_int(intno, cpu); + if (vd==NULL) { + portEXIT_CRITICAL(&spinlock); + return ESP_ERR_NO_MEM; + } + vd->flags=VECDESC_FL_RESERVED; + portEXIT_CRITICAL(&spinlock); + + return ESP_OK; +} + +//Interrupt handler table and unhandled uinterrupt routine. Duplicated +//from xtensa_intr.c... it's supposed to be private, but we need to look +//into it in order to see if someone allocated an int using +//xt_set_interrupt_handler. +typedef struct xt_handler_table_entry { + void * handler; + void * arg; +} xt_handler_table_entry; +extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_PROCESSORS]; +extern void xt_unhandled_interrupt(void * arg); + +//Returns true if handler for interrupt is not the default unhandled interrupt handler +static bool int_has_handler(int intr, int cpu) +{ + return (_xt_interrupt_table[intr*portNUM_PROCESSORS+cpu].handler != xt_unhandled_interrupt); +} + + +//Locate a free interrupt compatible with the flags given. +//The 'force' argument can be -1, or 0-31 to force checking a certain interrupt. +//When a CPU is forced, the INTDESC_SPECIAL marked interrupts are also accepted. +static int get_free_int(int flags, int cpu, int force) +{ + int x; + int best=-1; + int bestLevel=9; + int bestSharedCt=INT_MAX; + //Default vector desc, for vectors not in the linked list + vector_desc_t empty_vect_desc; + memset(&empty_vect_desc, 0, sizeof(vector_desc_t)); + //Level defaults to any low/med interrupt + if (!(flags&ESP_INTR_FLAG_LEVELMASK)) flags|=ESP_INTR_FLAG_LOWMED; + + ALCHLOG(TAG, "get_free_int: start looking. Current cpu: %d", cpu); + //Iterate over the 32 possible interrupts + for (x=0; x<32; x++) { + //Grab the vector_desc for this vector. + vector_desc_t *vd=find_desc_for_int(x, cpu); + if (vd==NULL) vd=&empty_vect_desc; + //See if we have a forced interrupt; if so, bail out if this is not it. + if (force!=-1 && force!=x) { + ALCHLOG(TAG, "Ignoring int %d: forced to %d", x, force); + continue; + } + ALCHLOG(TAG, "Int %d reserved %d level %d %s hasIsr %d", + x, int_desc[x].cpuflags[cpu]==INTDESC_RESVD, int_desc[x].level, + int_desc[x].type==INTTP_LEVEL?"LEVEL":"EDGE", int_has_handler(x, cpu)); + //Check if interrupt is not reserved by design + if (int_desc[x].cpuflags[cpu]==INTDESC_RESVD) { + ALCHLOG(TAG, "....Unusable: reserved"); + continue; + } + if (int_desc[x].cpuflags[cpu]==INTDESC_SPECIAL && force==-1) { + ALCHLOG(TAG, "....Unusable: special-purpose int"); + continue; + } + //Check if the interrupt level is acceptable + if (!(flags&(1<flags&VECDESC_FL_SHARED)) { + ALCHLOG(TAG, "....Unusable: already allocated"); + continue; + } + //Ints can't be both shared and non-shared. + assert(!((vd->flags&VECDESC_FL_SHARED)&&(vd->flags&VECDESC_FL_NONSHARED))); + //check if interrupt is reserved at runtime + if (vd->flags&VECDESC_FL_RESERVED) { + ALCHLOG(TAG, "....Unusable: reserved at runtime."); + continue; + } + //check if interrupt already is in use by a non-shared interrupt + if (vd->flags&VECDESC_FL_NONSHARED) { + ALCHLOG(TAG, "....Unusable: already in (non-shared) use."); + continue; + } + if (flags&ESP_INTR_FLAG_SHARED) { + //We're allocating a shared int. + bool in_iram_flag=((flags&ESP_INTR_FLAG_IRAM)!=0); + bool desc_in_iram_flag=((vd->flags&VECDESC_FL_INIRAM)!=0); + //Bail out if int is shared, but iram property doesn't match what we want. + if ((vd->flags&VECDESC_FL_SHARED) && (desc_in_iram_flag!=in_iram_flag)) { + ALCHLOG(TAG, "....Unusable: shared but iram prop doesn't match"); + continue; + } + //See if int already is used as a shared interrupt. + if (vd->flags&VECDESC_FL_SHARED) { + //We can use this already-marked-as-shared interrupt. Count the already attached isrs in order to see + //how useful it is. + int no=0; + shared_vector_desc_t *svdesc=vd->shared_vec_info; + while (svdesc!=NULL) { + no++; + svdesc=svdesc->next; + } + if (noint_desc[x].level) { + //Seems like this shared vector is both okay and has the least amount of ISRs already attached to it. + best=x; + bestSharedCt=no; + bestLevel=int_desc[x].level; + ALCHLOG(TAG, "...int %d more usable as a shared int: has %d existing vectors", x, no); + } else { + ALCHLOG(TAG, "...worse than int %d", best); + } + } else { + if (best==-1) { + //We haven't found a feasible shared interrupt yet. This one is still free and usable, even if + //not marked as shared. + //Remember it in case we don't find any other shared interrupt that qualifies. + if (bestLevel>int_desc[x].level) { + best=x; + bestLevel=int_desc[x].level; + ALCHLOG(TAG, "...int %d usable as a new shared int", x); + } + } else { + ALCHLOG(TAG, "...already have a shared int"); + } + } + } else { + //We need an unshared IRQ; can't use shared ones; bail out if this is shared. + if (vd->flags&VECDESC_FL_SHARED) { + ALCHLOG(TAG, "...Unusable: int is shared, we need non-shared."); + continue; + } + //Seems this interrupt is feasible. Select it and break out of the loop; no need to search further. + if (bestLevel>int_desc[x].level) { + best=x; + bestLevel=int_desc[x].level; + } else { + ALCHLOG(TAG, "...worse than int %d", best); + } + } + } + ALCHLOG(TAG, "get_free_int: using int %d", best); + + //Okay, by now we have looked at all potential interrupts and hopefully have selected the best one in best. + return best; +} + + +//Common shared isr handler. Chain-call all ISRs. +static void IRAM_ATTR shared_intr_isr(void *arg) +{ + vector_desc_t *vd=(vector_desc_t*)arg; + shared_vector_desc_t *sh_vec=vd->shared_vec_info; + portENTER_CRITICAL(&spinlock); + while(sh_vec) { + if (!sh_vec->disabled) { + if ((sh_vec->statusreg == NULL) || (*sh_vec->statusreg & sh_vec->statusmask)) { + sh_vec->isr(sh_vec->arg); + } + } + sh_vec=sh_vec->next; + } + portEXIT_CRITICAL(&spinlock); +} + + +//We use ESP_EARLY_LOG* here because this can be called before the scheduler is running. +esp_err_t esp_intr_alloc_intrstatus(int source, int flags, uint32_t intrstatusreg, uint32_t intrstatusmask, intr_handler_t handler, + void *arg, intr_handle_t *ret_handle) +{ + intr_handle_data_t *ret=NULL; + int force=-1; + ESP_EARLY_LOGV(TAG, "esp_intr_alloc_intrstatus (cpu %d): checking args", xPortGetCoreID()); + //Shared interrupts should be level-triggered. + if ((flags&ESP_INTR_FLAG_SHARED) && (flags&ESP_INTR_FLAG_EDGE)) return ESP_ERR_INVALID_ARG; + //You can't set an handler / arg for a non-C-callable interrupt. + if ((flags&ESP_INTR_FLAG_HIGH) && (handler)) return ESP_ERR_INVALID_ARG; + //Shared ints should have handler and non-processor-local source + if ((flags&ESP_INTR_FLAG_SHARED) && (!handler || source<0)) return ESP_ERR_INVALID_ARG; + //Statusreg should have a mask + if (intrstatusreg && !intrstatusmask) return ESP_ERR_INVALID_ARG; + + //Default to prio 1 for shared interrupts. Default to prio 1, 2 or 3 for non-shared interrupts. + if ((flags&ESP_INTR_FLAG_LEVELMASK)==0) { + if (flags&ESP_INTR_FLAG_SHARED) { + flags|=ESP_INTR_FLAG_LEVEL1; + } else { + flags|=ESP_INTR_FLAG_LOWMED; + } + } + ESP_EARLY_LOGV(TAG, "esp_intr_alloc_intrstatus (cpu %d): Args okay. Resulting flags 0x%X", xPortGetCoreID(), flags); + + //Check 'special' interrupt sources. These are tied to one specific interrupt, so we + //have to force get_free_int to only look at that. + if (source==ETS_INTERNAL_TIMER0_INTR_SOURCE) force=ETS_INTERNAL_TIMER0_INTR_NO; + if (source==ETS_INTERNAL_TIMER1_INTR_SOURCE) force=ETS_INTERNAL_TIMER1_INTR_NO; + if (source==ETS_INTERNAL_TIMER2_INTR_SOURCE) force=ETS_INTERNAL_TIMER2_INTR_NO; + if (source==ETS_INTERNAL_SW0_INTR_SOURCE) force=ETS_INTERNAL_SW0_INTR_NO; + if (source==ETS_INTERNAL_SW1_INTR_SOURCE) force=ETS_INTERNAL_SW1_INTR_NO; + if (source==ETS_INTERNAL_PROFILING_INTR_SOURCE) force=ETS_INTERNAL_PROFILING_INTR_NO; + + //Allocate a return handle. If we end up not needing it, we'll free it later on. + ret=malloc(sizeof(intr_handle_data_t)); + if (ret==NULL) return ESP_ERR_NO_MEM; + + portENTER_CRITICAL(&spinlock); + int cpu=xPortGetCoreID(); + //See if we can find an interrupt that matches the flags. + int intr=get_free_int(flags, cpu, force); + if (intr==-1) { + //None found. Bail out. + portEXIT_CRITICAL(&spinlock); + free(ret); + return ESP_ERR_NOT_FOUND; + } + //Get an int vector desc for int. + vector_desc_t *vd=get_desc_for_int(intr, cpu); + if (vd==NULL) { + portEXIT_CRITICAL(&spinlock); + free(ret); + return ESP_ERR_NO_MEM; + } + + //Allocate that int! + if (flags&ESP_INTR_FLAG_SHARED) { + //Populate vector entry and add to linked list. + shared_vector_desc_t *sh_vec=malloc(sizeof(shared_vector_desc_t)); + if (sh_vec==NULL) { + portEXIT_CRITICAL(&spinlock); + free(ret); + return ESP_ERR_NO_MEM; + } + memset(sh_vec, 0, sizeof(shared_vector_desc_t)); + sh_vec->statusreg=(uint32_t*)intrstatusreg; + sh_vec->statusmask=intrstatusmask; + sh_vec->isr=handler; + sh_vec->arg=arg; + sh_vec->next=vd->shared_vec_info; + sh_vec->source=source; + sh_vec->disabled=0; + vd->shared_vec_info=sh_vec; + vd->flags|=VECDESC_FL_SHARED; + //(Re-)set shared isr handler to new value. + xt_set_interrupt_handler(intr, shared_intr_isr, vd); + } else { + //Mark as unusable for other interrupt sources. This is ours now! + vd->flags=VECDESC_FL_NONSHARED; + if (handler) { + xt_set_interrupt_handler(intr, handler, arg); + } + if (flags&ESP_INTR_FLAG_EDGE) xthal_set_intclear(1 << intr); + vd->source=source; + } + if (flags&ESP_INTR_FLAG_IRAM) { + vd->flags|=VECDESC_FL_INIRAM; + non_iram_int_mask[cpu]&=~(1<flags&=~VECDESC_FL_INIRAM; + non_iram_int_mask[cpu]|=(1<=0) { + intr_matrix_set(cpu, source, intr); + } + + //Fill return handle data. + ret->vector_desc=vd; + ret->shared_vector_desc=vd->shared_vec_info; + + //Enable int at CPU-level; + ESP_INTR_ENABLE(intr); + + //If interrupt has to be started disabled, do that now; ints won't be enabled for real until the end + //of the critical section. + if (flags&ESP_INTR_FLAG_INTRDISABLED) { + esp_intr_disable(ret); + } + + portEXIT_CRITICAL(&spinlock); + + //Fill return handle if needed, otherwise free handle. + if (ret_handle!=NULL) { + *ret_handle=ret; + } else { + free(ret); + } + + ESP_EARLY_LOGD(TAG, "Connected src %d to int %d (cpu %d)", source, intr, cpu); + return ESP_OK; +} + +esp_err_t esp_intr_alloc(int source, int flags, intr_handler_t handler, void *arg, intr_handle_t *ret_handle) +{ + /* + As an optimization, we can create a table with the possible interrupt status registers and masks for every single + source there is. We can then add code here to look up an applicable value and pass that to the + esp_intr_alloc_intrstatus function. + */ + return esp_intr_alloc_intrstatus(source, flags, 0, 0, handler, arg, ret_handle); +} + + +esp_err_t esp_intr_free(intr_handle_t handle) +{ + bool free_shared_vector=false; + if (!handle) return ESP_ERR_INVALID_ARG; + //This routine should be called from the interrupt the task is scheduled on. + if (handle->vector_desc->cpu!=xPortGetCoreID()) return ESP_ERR_INVALID_ARG; + + portENTER_CRITICAL(&spinlock); + esp_intr_disable(handle); + if (handle->vector_desc->flags&VECDESC_FL_SHARED) { + //Find and kill the shared int + shared_vector_desc_t *svd=handle->vector_desc->shared_vec_info; + shared_vector_desc_t *prevsvd=NULL; + assert(svd); //should be something in there for a shared int + while (svd!=NULL) { + if (svd==handle->shared_vector_desc) { + //Found it. Now kill it. + if (prevsvd) { + prevsvd->next=svd->next; + } else { + handle->vector_desc->shared_vec_info=svd->next; + } + free(svd); + break; + } + prevsvd=svd; + svd=svd->next; + } + //If nothing left, disable interrupt. + if (handle->vector_desc->shared_vec_info==NULL) free_shared_vector=true; + ESP_LOGV(TAG, "esp_intr_free: Deleting shared int: %s. Shared int is %s", svd?"not found or last one":"deleted", free_shared_vector?"empty now.":"still in use"); + } + + if ((handle->vector_desc->flags&VECDESC_FL_NONSHARED) || free_shared_vector) { + ESP_LOGV(TAG, "esp_intr_free: Disabling int, killing handler"); + //Reset to normal handler + xt_set_interrupt_handler(handle->vector_desc->intno, xt_unhandled_interrupt, (void*)((int)handle->vector_desc->intno)); + //Theoretically, we could free the vector_desc... not sure if that's worth the few bytes of memory + //we save.(We can also not use the same exit path for empty shared ints anymore if we delete + //the desc.) For now, just mark it as free. + handle->vector_desc->flags&=!(VECDESC_FL_NONSHARED|VECDESC_FL_RESERVED); + //Also kill non_iram mask bit. + non_iram_int_mask[handle->vector_desc->cpu]&=~(1<<(handle->vector_desc->intno)); + } + portEXIT_CRITICAL(&spinlock); + free(handle); + return ESP_OK; +} + +int esp_intr_get_intno(intr_handle_t handle) +{ + return handle->vector_desc->intno; +} + +int esp_intr_get_cpu(intr_handle_t handle) +{ + return handle->vector_desc->cpu; +} + +/* + Interrupt disabling strategy: + If the source is >=0 (meaning a muxed interrupt), we disable it by muxing the interrupt to a non-connected + interrupt. If the source is <0 (meaning an internal, per-cpu interrupt), we disable it using ESP_INTR_DISABLE. + This allows us to, for the muxed CPUs, disable an int from the other core. It also allows disabling shared + interrupts. + */ + +//Muxing an interrupt source to interrupt 6, 7, 11, 15, 16 or 29 cause the interrupt to effectively be disabled. +#define INT_MUX_DISABLED_INTNO 6 + +esp_err_t IRAM_ATTR esp_intr_enable(intr_handle_t handle) +{ + if (!handle) return ESP_ERR_INVALID_ARG; + portENTER_CRITICAL(&spinlock); + int source; + if (handle->shared_vector_desc) { + handle->shared_vector_desc->disabled=0; + source=handle->shared_vector_desc->source; + } else { + source=handle->vector_desc->source; + } + if (source >= 0) { + //Disabled using int matrix; re-connect to enable + intr_matrix_set(handle->vector_desc->cpu, source, handle->vector_desc->intno); + } else { + //Re-enable using cpu int ena reg + if (handle->vector_desc->cpu!=xPortGetCoreID()) return ESP_ERR_INVALID_ARG; //Can only enable these ints on this cpu + ESP_INTR_ENABLE(handle->vector_desc->intno); + } + portEXIT_CRITICAL(&spinlock); + return ESP_OK; +} + +esp_err_t IRAM_ATTR esp_intr_disable(intr_handle_t handle) +{ + if (!handle) return ESP_ERR_INVALID_ARG; + portENTER_CRITICAL(&spinlock); + int source; + if (handle->shared_vector_desc) { + handle->shared_vector_desc->disabled=1; + source=handle->shared_vector_desc->source; + } else { + source=handle->vector_desc->source; + } + if (source >= 0) { + //Disable using int matrix + intr_matrix_set(handle->vector_desc->cpu, source, INT_MUX_DISABLED_INTNO); + } else { + //Disable using per-cpu regs + if (handle->vector_desc->cpu!=xPortGetCoreID()) { + portEXIT_CRITICAL(&spinlock); + return ESP_ERR_INVALID_ARG; //Can only enable these ints on this cpu + } + ESP_INTR_DISABLE(handle->vector_desc->intno); + } + portEXIT_CRITICAL(&spinlock); + return ESP_OK; +} + + +void esp_intr_noniram_disable() +{ + int oldint; + int cpu=xPortGetCoreID(); + int intmask=~non_iram_int_mask[cpu]; + assert(non_iram_int_disabled_flag[cpu]==false); + non_iram_int_disabled_flag[cpu]=true; + asm volatile ( + "movi %0,0\n" + "xsr %0,INTENABLE\n" //disable all ints first + "rsync\n" + "and a3,%0,%1\n" //mask ints that need disabling + "wsr a3,INTENABLE\n" //write back + "rsync\n" + :"=r"(oldint):"r"(intmask):"a3"); + //Save which ints we did disable + non_iram_int_disabled[cpu]=oldint&non_iram_int_mask[cpu]; +} + +void esp_intr_noniram_enable() +{ + int cpu=xPortGetCoreID(); + int intmask=non_iram_int_disabled[cpu]; + assert(non_iram_int_disabled_flag[cpu]==true); + non_iram_int_disabled_flag[cpu]=false; + asm volatile ( + "movi a3,0\n" + "xsr a3,INTENABLE\n" + "rsync\n" + "or a3,a3,%0\n" + "wsr a3,INTENABLE\n" + "rsync\n" + ::"r"(intmask):"a3"); +} + +//These functions are provided in ROM, but the ROM-based functions use non-multicore-capable +//virtualized interrupt levels. Thus, we disable them in the ld file and provide working +//equivalents here. + + +void IRAM_ATTR ets_isr_unmask(unsigned int mask) { + xt_ints_on(mask); +} + +void IRAM_ATTR ets_isr_mask(unsigned int mask) { + xt_ints_off(mask); +} + + + + diff --git a/components/esp32/ld/esp32.rom.ld b/components/esp32/ld/esp32.rom.ld index af9522976b..6241ff840e 100644 --- a/components/esp32/ld/esp32.rom.ld +++ b/components/esp32/ld/esp32.rom.ld @@ -26,14 +26,6 @@ PROVIDE ( asctime = 0x40059588 ); PROVIDE ( asctime_r = 0x40000ec8 ); PROVIDE ( __ashldi3 = 0x4000c818 ); PROVIDE ( __ashrdi3 = 0x4000c830 ); -PROVIDE ( asiprintf = 0x40056d9c ); -PROVIDE ( _asiprintf_r = 0x40056d4c ); -PROVIDE ( asniprintf = 0x40056cd8 ); -PROVIDE ( _asniprintf_r = 0x40056c64 ); -PROVIDE ( asnprintf = 0x40056cd8 ); -PROVIDE ( _asnprintf_r = 0x40056c64 ); -PROVIDE ( asprintf = 0x40056d9c ); -PROVIDE ( _asprintf_r = 0x40056d4c ); PROVIDE ( atoi = 0x400566c4 ); PROVIDE ( _atoi_r = 0x400566d4 ); PROVIDE ( atol = 0x400566ec ); @@ -177,12 +169,6 @@ PROVIDE ( ets_get_xtal_scale = 0x4000856c ); PROVIDE ( ets_install_putc1 = 0x40007d18 ); PROVIDE ( ets_install_putc2 = 0x40007d38 ); PROVIDE ( ets_install_uart_printf = 0x40007d28 ); -PROVIDE ( ets_intr_count = 0x3ffe03fc ); -PROVIDE ( ets_intr_lock = 0x400067b0 ); -PROVIDE ( ets_intr_unlock = 0x400067c4 ); -PROVIDE ( ets_isr_attach = 0x400067ec ); -PROVIDE ( ets_isr_mask = 0x400067fc ); -PROVIDE ( ets_isr_unmask = 0x40006808 ); PROVIDE ( ets_post = 0x4000673c ); PROVIDE ( ets_printf = 0x40007d54 ); PROVIDE ( ets_readySet_ = 0x3ffe01f0 ); @@ -230,10 +216,6 @@ PROVIDE ( __ffssi2 = 0x4000c804 ); PROVIDE ( FilePacketSendDeflatedReqMsgProc = 0x40008b24 ); PROVIDE ( FilePacketSendReqMsgProc = 0x40008860 ); PROVIDE ( _findenv_r = 0x40001f44 ); -PROVIDE ( fiprintf = 0x40056efc ); -PROVIDE ( _fiprintf_r = 0x40056ed8 ); -PROVIDE ( fiscanf = 0x40058884 ); -PROVIDE ( _fiscanf_r = 0x400588b4 ); PROVIDE ( __fixdfdi = 0x40002ac4 ); PROVIDE ( __fixdfsi = 0x40002a78 ); PROVIDE ( __fixsfdi = 0x4000244c ); @@ -255,16 +237,12 @@ PROVIDE ( __floatundisf = 0x4000c8b0 ); PROVIDE ( __floatunsidf = 0x4000c938 ); PROVIDE ( __floatunsisf = 0x4000c864 ); PROVIDE ( __fp_lock_all = 0x40001f1c ); -PROVIDE ( fprintf = 0x40056efc ); -PROVIDE ( _fprintf_r = 0x40056ed8 ); PROVIDE ( __fp_unlock_all = 0x40001f30 ); PROVIDE ( fputwc = 0x40058ea8 ); PROVIDE ( __fputwc = 0x40058da0 ); PROVIDE ( _fputwc_r = 0x40058e4c ); PROVIDE ( free = 0x4000beb8 ); PROVIDE ( _free_r = 0x4000bbcc ); -PROVIDE ( fscanf = 0x40058884 ); -PROVIDE ( _fscanf_r = 0x400588b4 ); PROVIDE ( _fstat_r = 0x4000bccc ); PROVIDE ( _fwalk = 0x4000c738 ); PROVIDE ( _fwalk_reent = 0x4000c770 ); @@ -337,15 +315,11 @@ PROVIDE ( hmac_sha1_vector = 0x400609e4 ); PROVIDE ( hmac_sha256 = 0x40060d58 ); PROVIDE ( hmac_sha256_vector = 0x40060c84 ); PROVIDE ( intr_matrix_set = 0x4000681c ); -PROVIDE ( iprintf = 0x40056978 ); -PROVIDE ( _iprintf_r = 0x40056944 ); PROVIDE ( isalnum = 0x40000f04 ); PROVIDE ( isalpha = 0x40000f18 ); PROVIDE ( isascii = 0x4000c20c ); PROVIDE ( _isatty_r = 0x40000ea0 ); PROVIDE ( isblank = 0x40000f2c ); -PROVIDE ( iscanf = 0x40058760 ); -PROVIDE ( _iscanf_r = 0x4005879c ); PROVIDE ( iscntrl = 0x40000f50 ); PROVIDE ( isdigit = 0x40000f64 ); PROVIDE ( isgraph = 0x40000f94 ); @@ -511,11 +485,6 @@ PROVIDE ( __powidf2 = 0x400638d4 ); PROVIDE ( __powisf2 = 0x4006389c ); PROVIDE ( _Pri_4_HandlerAddress = 0x3ffe0648 ); PROVIDE ( _Pri_5_HandlerAddress = 0x3ffe064c ); -PROVIDE ( printf = 0x40056978 ); -PROVIDE ( _printf_common = 0x40057338 ); -PROVIDE ( _printf_float = 0x4000befc ); -PROVIDE ( _printf_i = 0x40057404 ); -PROVIDE ( _printf_r = 0x40056944 ); PROVIDE ( qsort = 0x40056424 ); PROVIDE ( _raise_r = 0x4000bc70 ); PROVIDE ( rand = 0x40001058 ); @@ -1500,11 +1469,6 @@ PROVIDE ( rwip_rf_p_get = 0x400558f4 ); PROVIDE ( r_XorKey = 0x400112c0 ); PROVIDE ( sbrk = 0x400017f4 ); PROVIDE ( _sbrk_r = 0x4000bce4 ); -PROVIDE ( scanf = 0x40058760 ); -PROVIDE ( _scanf_chars = 0x40058384 ); -PROVIDE ( _scanf_float = 0x4000bf18 ); -PROVIDE ( _scanf_i = 0x4005845c ); -PROVIDE ( _scanf_r = 0x4005879c ); PROVIDE ( __sccl = 0x4000c498 ); PROVIDE ( __sclose = 0x400011b8 ); PROVIDE ( SelectSpiFunction = 0x40061f84 ); @@ -1549,13 +1513,9 @@ PROVIDE ( sip_is_active = 0x4000b3c0 ); PROVIDE ( sip_post_init = 0x4000aed8 ); PROVIDE ( sip_reclaim_from_host_cmd = 0x4000adbc ); PROVIDE ( sip_reclaim_tx_data_pkt = 0x4000ad5c ); -PROVIDE ( siprintf = 0x40056c08 ); -PROVIDE ( _siprintf_r = 0x40056bbc ); PROVIDE ( sip_send = 0x4000af54 ); PROVIDE ( sip_to_host_chain_append = 0x4000aef8 ); PROVIDE ( sip_to_host_evt_send_done = 0x4000ac04 ); -PROVIDE ( siscanf = 0x400587d0 ); -PROVIDE ( _siscanf_r = 0x40058830 ); PROVIDE ( slc_add_credits = 0x4000baf4 ); PROVIDE ( slc_enable = 0x4000b64c ); PROVIDE ( slc_from_host_chain_fetch = 0x4000b7e8 ); @@ -1568,10 +1528,6 @@ PROVIDE ( slc_send_to_host_chain = 0x4000b6a0 ); PROVIDE ( slc_set_host_io_max_window = 0x4000b89c ); PROVIDE ( slc_to_host_chain_recycle = 0x4000b758 ); PROVIDE ( __smakebuf_r = 0x40059108 ); -PROVIDE ( sniprintf = 0x40056b4c ); -PROVIDE ( _sniprintf_r = 0x40056ae4 ); -PROVIDE ( snprintf = 0x40056b4c ); -PROVIDE ( _snprintf_r = 0x40056ae4 ); PROVIDE ( software_reset = 0x4000824c ); PROVIDE ( software_reset_cpu = 0x40008264 ); PROVIDE ( specialModP256 = 0x4001600c ); @@ -1607,20 +1563,13 @@ PROVIDE ( SPI_Write_Encrypt_Disable = 0x40062e60 ); PROVIDE ( SPI_Write_Encrypt_Enable = 0x40062df4 ); /* This is static function, but can be used, not generated by script*/ PROVIDE ( SPI_write_status = 0x400622f0 ); -PROVIDE ( sprintf = 0x40056c08 ); -PROVIDE ( _sprintf_r = 0x40056bbc ); -PROVIDE ( __sprint_r = 0x400577e4 ); PROVIDE ( srand = 0x40001004 ); PROVIDE ( __sread = 0x40001118 ); PROVIDE ( __srefill_r = 0x400593d4 ); -PROVIDE ( sscanf = 0x400587d0 ); -PROVIDE ( _sscanf_r = 0x40058830 ); PROVIDE ( __sseek = 0x40001184 ); PROVIDE ( __ssprint_r = 0x40056ff8 ); PROVIDE ( __ssputs_r = 0x40056f2c ); PROVIDE ( __ssrefill_r = 0x40057fec ); -PROVIDE ( __ssvfiscanf_r = 0x4005802c ); -PROVIDE ( __ssvfscanf_r = 0x4005802c ); PROVIDE ( __stack = 0x3ffe3f20 ); PROVIDE ( __stack_app = 0x3ffe7e30 ); PROVIDE ( _stack_sentry = 0x3ffe1320 ); @@ -1673,11 +1622,6 @@ PROVIDE ( SubtractFromSelfBigHexSign256 = 0x40015dc8 ); PROVIDE ( __subvdi3 = 0x40002d20 ); PROVIDE ( __subvsi3 = 0x40002cf8 ); PROVIDE ( _sungetc_r = 0x40057f6c ); -PROVIDE ( _svfiprintf_r = 0x40057100 ); -PROVIDE ( __svfiscanf_r = 0x40057b08 ); -PROVIDE ( _svfprintf_r = 0x40057100 ); -PROVIDE ( __svfscanf = 0x40057f04 ); -PROVIDE ( __svfscanf_r = 0x40057b08 ); PROVIDE ( __swbuf = 0x40058cb4 ); PROVIDE ( __swbuf_r = 0x40058bec ); PROVIDE ( __swrite = 0x40001150 ); @@ -1756,44 +1700,8 @@ PROVIDE ( user_code_start = 0x3ffe0400 ); PROVIDE ( _UserExceptionVector = 0x40000340 ); PROVIDE ( utoa = 0x40056258 ); PROVIDE ( __utoa = 0x400561f0 ); -PROVIDE ( vasiprintf = 0x40056eb8 ); -PROVIDE ( _vasiprintf_r = 0x40056e80 ); -PROVIDE ( vasniprintf = 0x40056e58 ); -PROVIDE ( _vasniprintf_r = 0x40056df8 ); -PROVIDE ( vasnprintf = 0x40056e58 ); -PROVIDE ( _vasnprintf_r = 0x40056df8 ); -PROVIDE ( vasprintf = 0x40056eb8 ); -PROVIDE ( _vasprintf_r = 0x40056e80 ); PROVIDE ( VerifyFlashMd5Proc = 0x40008c44 ); PROVIDE ( veryBigHexP256 = 0x3ff9736c ); -PROVIDE ( vfiprintf = 0x40057ae8 ); -PROVIDE ( _vfiprintf_r = 0x40057850 ); -PROVIDE ( vfiscanf = 0x40057eb8 ); -PROVIDE ( _vfiscanf_r = 0x40057f24 ); -PROVIDE ( vfprintf = 0x40057ae8 ); -PROVIDE ( _vfprintf_r = 0x40057850 ); -PROVIDE ( vfscanf = 0x40057eb8 ); -PROVIDE ( _vfscanf_r = 0x40057f24 ); -PROVIDE ( viprintf = 0x400569b4 ); -PROVIDE ( _viprintf_r = 0x400569e4 ); -PROVIDE ( viscanf = 0x40058698 ); -PROVIDE ( _viscanf_r = 0x400586c8 ); -PROVIDE ( vprintf = 0x400569b4 ); -PROVIDE ( _vprintf_r = 0x400569e4 ); -PROVIDE ( vscanf = 0x40058698 ); -PROVIDE ( _vscanf_r = 0x400586c8 ); -PROVIDE ( vsiprintf = 0x40056ac4 ); -PROVIDE ( _vsiprintf_r = 0x40056a90 ); -PROVIDE ( vsiscanf = 0x40058740 ); -PROVIDE ( _vsiscanf_r = 0x400586f8 ); -PROVIDE ( vsniprintf = 0x40056a68 ); -PROVIDE ( _vsniprintf_r = 0x40056a14 ); -PROVIDE ( vsnprintf = 0x40056a68 ); -PROVIDE ( _vsnprintf_r = 0x40056a14 ); -PROVIDE ( vsprintf = 0x40056ac4 ); -PROVIDE ( _vsprintf_r = 0x40056a90 ); -PROVIDE ( vsscanf = 0x40058740 ); -PROVIDE ( _vsscanf_r = 0x400586f8 ); PROVIDE ( wcrtomb = 0x40058920 ); PROVIDE ( _wcrtomb_r = 0x400588d8 ); PROVIDE ( __wctomb = 0x3ff96540 ); @@ -1816,6 +1724,13 @@ PROVIDE ( Xthal_intlevel = 0x3ff9c2b4 ); PROVIDE ( xthal_memcpy = 0x4000c0bc ); PROVIDE ( xthal_set_ccompare = 0x4000c058 ); PROVIDE ( xthal_set_intclear = 0x4000c1ec ); +PROVIDE ( _xtos_set_intlevel = 0x4000bfdc ); +/* +These functions are xtos-related (or call xtos-related functions) and do not play well +with multicore FreeRTOS. Where needed, we provide alternatives that are multicore +compatible. +*/ +/* PROVIDE ( _xtos_alloca_handler = 0x40000010 ); PROVIDE ( _xtos_cause3_handler = 0x40000dd8 ); PROVIDE ( _xtos_c_handler_table = 0x3ffe0548 ); @@ -1834,13 +1749,19 @@ PROVIDE ( _xtos_return_from_exc = 0x4000c034 ); PROVIDE ( _xtos_set_exception_handler = 0x4000074c ); PROVIDE ( _xtos_set_interrupt_handler = 0x4000bf78 ); PROVIDE ( _xtos_set_interrupt_handler_arg = 0x4000bf34 ); -PROVIDE ( _xtos_set_intlevel = 0x4000bfdc ); PROVIDE ( _xtos_set_min_intlevel = 0x4000bff8 ); PROVIDE ( _xtos_set_vpri = 0x40000934 ); PROVIDE ( _xtos_syscall_handler = 0x40000790 ); PROVIDE ( _xtos_unhandled_exception = 0x4000c024 ); PROVIDE ( _xtos_unhandled_interrupt = 0x4000c01c ); PROVIDE ( _xtos_vpri_enabled = 0x3ffe0654 ); +PROVIDE ( ets_intr_count = 0x3ffe03fc ); +PROVIDE ( ets_intr_lock = 0x400067b0 ); +PROVIDE ( ets_intr_unlock = 0x400067c4 ); +PROVIDE ( ets_isr_attach = 0x400067ec ); +PROVIDE ( ets_isr_mask = 0x400067fc ); +PROVIDE ( ets_isr_unmask = 0x40006808 ); +*/ /* Following are static data, but can be used, not generated by script <<<<< btdm data */ PROVIDE ( ld_acl_env = 0x3ffb8258 ); PROVIDE ( ld_active_ch_map = 0x3ffb8334 ); diff --git a/components/esp32/ld/esp32.rom.nanofmt.ld b/components/esp32/ld/esp32.rom.nanofmt.ld new file mode 100644 index 0000000000..ae843dff2f --- /dev/null +++ b/components/esp32/ld/esp32.rom.nanofmt.ld @@ -0,0 +1,100 @@ +/* + Address table for printf/scanf family of functions in ESP32 ROM. + These functions are compiled with newlib "nano" format option. + As such, they don's support 64-bit integer formats. + Floating point formats are supported by setting _printf_float and + _scanf_float entries in syscall table. This is done automatically + by startup code. + + Generated for ROM with MD5sum: + ab8282ae908fe9e7a63fb2a4ac2df013 eagle.pro.rom.out +*/ + +PROVIDE ( asiprintf = 0x40056d9c ); +PROVIDE ( _asiprintf_r = 0x40056d4c ); +PROVIDE ( asniprintf = 0x40056cd8 ); +PROVIDE ( _asniprintf_r = 0x40056c64 ); +PROVIDE ( asnprintf = 0x40056cd8 ); +PROVIDE ( _asnprintf_r = 0x40056c64 ); +PROVIDE ( asprintf = 0x40056d9c ); +PROVIDE ( _asprintf_r = 0x40056d4c ); +PROVIDE ( fiprintf = 0x40056efc ); +PROVIDE ( _fiprintf_r = 0x40056ed8 ); +PROVIDE ( fiscanf = 0x40058884 ); +PROVIDE ( _fiscanf_r = 0x400588b4 ); +PROVIDE ( fprintf = 0x40056efc ); +PROVIDE ( _fprintf_r = 0x40056ed8 ); +PROVIDE ( iprintf = 0x40056978 ); +PROVIDE ( _iprintf_r = 0x40056944 ); +PROVIDE ( printf = 0x40056978 ); +PROVIDE ( _printf_common = 0x40057338 ); +PROVIDE ( _printf_float = 0x4000befc ); +PROVIDE ( _printf_i = 0x40057404 ); +PROVIDE ( _printf_r = 0x40056944 ); +PROVIDE ( siprintf = 0x40056c08 ); +PROVIDE ( _siprintf_r = 0x40056bbc ); +PROVIDE ( sniprintf = 0x40056b4c ); +PROVIDE ( _sniprintf_r = 0x40056ae4 ); +PROVIDE ( snprintf = 0x40056b4c ); +PROVIDE ( _snprintf_r = 0x40056ae4 ); +PROVIDE ( sprintf = 0x40056c08 ); +PROVIDE ( _sprintf_r = 0x40056bbc ); +PROVIDE ( __sprint_r = 0x400577e4 ); +PROVIDE ( _svfiprintf_r = 0x40057100 ); +PROVIDE ( __svfiscanf_r = 0x40057b08 ); +PROVIDE ( _svfprintf_r = 0x40057100 ); +PROVIDE ( __svfscanf = 0x40057f04 ); +PROVIDE ( __svfscanf_r = 0x40057b08 ); +PROVIDE ( vasiprintf = 0x40056eb8 ); +PROVIDE ( _vasiprintf_r = 0x40056e80 ); +PROVIDE ( vasniprintf = 0x40056e58 ); +PROVIDE ( _vasniprintf_r = 0x40056df8 ); +PROVIDE ( vasnprintf = 0x40056e58 ); +PROVIDE ( _vasnprintf_r = 0x40056df8 ); +PROVIDE ( vasprintf = 0x40056eb8 ); +PROVIDE ( _vasprintf_r = 0x40056e80 ); +PROVIDE ( vfiprintf = 0x40057ae8 ); +PROVIDE ( _vfiprintf_r = 0x40057850 ); +PROVIDE ( vfiscanf = 0x40057eb8 ); +PROVIDE ( _vfiscanf_r = 0x40057f24 ); +PROVIDE ( vfprintf = 0x40057ae8 ); +PROVIDE ( _vfprintf_r = 0x40057850 ); +PROVIDE ( vfscanf = 0x40057eb8 ); +PROVIDE ( _vfscanf_r = 0x40057f24 ); +PROVIDE ( viprintf = 0x400569b4 ); +PROVIDE ( _viprintf_r = 0x400569e4 ); +PROVIDE ( viscanf = 0x40058698 ); +PROVIDE ( _viscanf_r = 0x400586c8 ); +PROVIDE ( vprintf = 0x400569b4 ); +PROVIDE ( _vprintf_r = 0x400569e4 ); +PROVIDE ( vscanf = 0x40058698 ); +PROVIDE ( _vscanf_r = 0x400586c8 ); +PROVIDE ( vsiprintf = 0x40056ac4 ); +PROVIDE ( _vsiprintf_r = 0x40056a90 ); +PROVIDE ( vsiscanf = 0x40058740 ); +PROVIDE ( _vsiscanf_r = 0x400586f8 ); +PROVIDE ( vsniprintf = 0x40056a68 ); +PROVIDE ( _vsniprintf_r = 0x40056a14 ); +PROVIDE ( vsnprintf = 0x40056a68 ); +PROVIDE ( _vsnprintf_r = 0x40056a14 ); +PROVIDE ( vsprintf = 0x40056ac4 ); +PROVIDE ( _vsprintf_r = 0x40056a90 ); +PROVIDE ( vsscanf = 0x40058740 ); +PROVIDE ( _vsscanf_r = 0x400586f8 ); +PROVIDE ( fscanf = 0x40058884 ); +PROVIDE ( _fscanf_r = 0x400588b4 ); +PROVIDE ( iscanf = 0x40058760 ); +PROVIDE ( _iscanf_r = 0x4005879c ); +PROVIDE ( scanf = 0x40058760 ); +PROVIDE ( _scanf_chars = 0x40058384 ); +PROVIDE ( _scanf_float = 0x4000bf18 ); +PROVIDE ( _scanf_i = 0x4005845c ); +PROVIDE ( _scanf_r = 0x4005879c ); +PROVIDE ( siscanf = 0x400587d0 ); +PROVIDE ( _siscanf_r = 0x40058830 ); +PROVIDE ( sscanf = 0x400587d0 ); +PROVIDE ( _sscanf_r = 0x40058830 ); +PROVIDE ( __ssvfiscanf_r = 0x4005802c ); +PROVIDE ( __ssvfscanf_r = 0x4005802c ); + + diff --git a/components/esp32/lib b/components/esp32/lib index 3a412c08af..02232f974b 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit 3a412c08af1ace47a58d1f8722a8fed5b8d3b944 +Subproject commit 02232f974b0ff1568ddd6d7015a41fb4f4870994 diff --git a/components/esp32/lib_printf.c b/components/esp32/lib_printf.c index a2aff4cf56..417e71bdf7 100644 --- a/components/esp32/lib_printf.c +++ b/components/esp32/lib_printf.c @@ -62,11 +62,8 @@ int phy_printf(const char* format, ...) int rtc_printf(const char* format, ...) { - va_list arg; - va_start(arg, format); - int res = lib_printf("rtc", format, arg); - va_end(arg); - return res; + // librtc.a printf temporary disabled due to UART baud rate switching bug. + return 0; } int wpa_printf(const char* format, ...) diff --git a/components/esp32/panic.c b/components/esp32/panic.c index 8f51994401..0efe56fe01 100644 --- a/components/esp32/panic.c +++ b/components/esp32/panic.c @@ -34,76 +34,88 @@ #include "esp_attr.h" /* -Panic handlers; these get called when an unhandled exception occurs or the assembly-level -task switching / interrupt code runs into an unrecoverable error. The default task stack -overflow handler also is in here. + Panic handlers; these get called when an unhandled exception occurs or the assembly-level + task switching / interrupt code runs into an unrecoverable error. The default task stack + overflow handler also is in here. */ /* -Note: The linker script will put everything in this file in IRAM/DRAM, so it also works with flash cache disabled. + Note: The linker script will put everything in this file in IRAM/DRAM, so it also works with flash cache disabled. */ #if !CONFIG_ESP32_PANIC_SILENT_REBOOT //printf may be broken, so we fix our own printing fns... -inline static void panicPutchar(char c) { - while (((READ_PERI_REG(UART_STATUS_REG(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ; - WRITE_PERI_REG(UART_FIFO_REG(0), c); +inline static void panicPutChar(char c) +{ + while (((READ_PERI_REG(UART_STATUS_REG(0)) >> UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT) >= 126) ; + WRITE_PERI_REG(UART_FIFO_REG(0), c); } -inline static void panicPutStr(const char *c) { - int x=0; - while (c[x]!=0) { - panicPutchar(c[x]); - x++; - } +inline static void panicPutStr(const char *c) +{ + int x = 0; + while (c[x] != 0) { + panicPutChar(c[x]); + x++; + } } -inline static void panicPutHex(int a) { - int x; - int c; - panicPutchar(' '); - for (x=0; x<8; x++) { - c=(a>>28)&0xf; - if (c<10) panicPutchar('0'+c); else panicPutchar('a'+c-10); - a<<=4; - } +inline static void panicPutHex(int a) +{ + int x; + int c; + for (x = 0; x < 8; x++) { + c = (a >> 28) & 0xf; + if (c < 10) { + panicPutChar('0' + c); + } else { + panicPutChar('a' + c - 10); + } + a <<= 4; + } } -inline static void panicPutDec(int a) { - int n1, n2; - n1=a%10; - n2=a/10; - panicPutchar(' '); - if (n2==0) panicPutchar(' '); else panicPutchar(n2+'0'); - panicPutchar(n1+'0'); +inline static void panicPutDec(int a) +{ + int n1, n2; + n1 = a % 10; + n2 = a / 10; + if (n2 == 0) { + panicPutChar(' '); + } else { + panicPutChar(n2 + '0'); + } + panicPutChar(n1 + '0'); } #else //No printing wanted. Stub out these functions. -inline static void panicPutchar(char c) { } +inline static void panicPutChar(char c) { } inline static void panicPutStr(const char *c) { } inline static void panicPutHex(int a) { } inline static void panicPutDec(int a) { } #endif -void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) { - panicPutStr("***ERROR*** A stack overflow in task "); - panicPutStr((char*)pcTaskName); - panicPutStr(" has been detected.\r\n"); +void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) +{ + panicPutStr("***ERROR*** A stack overflow in task "); + panicPutStr((char *)pcTaskName); + panicPutStr(" has been detected.\r\n"); + configASSERT(0); } -static const char *edesc[]={ - "IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError", - "Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue", - "Privileged", "LoadStoreAlignment", "res", "res", - "InstrPDAddrError", "LoadStorePIFDataError", "InstrPIFAddrError", "LoadStorePIFAddrError", - "InstTLBMiss", "InstTLBMultiHit", "InstFetchPrivilege", "res", - "InstrFetchProhibited", "res", "res", "res", - "LoadStoreTLBMiss", "LoadStoreTLBMultihit", "LoadStorePrivilege", "res", - "LoadProhibited", "StoreProhibited", "res", "res", - "Cp0Dis", "Cp1Dis", "Cp2Dis", "Cp3Dis", - "Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis" - }; +static const char *edesc[] = { + "IllegalInstruction", "Syscall", "InstructionFetchError", "LoadStoreError", + "Level1Interrupt", "Alloca", "IntegerDivideByZero", "PCValue", + "Privileged", "LoadStoreAlignment", "res", "res", + "InstrPDAddrError", "LoadStorePIFDataError", "InstrPIFAddrError", "LoadStorePIFAddrError", + "InstTLBMiss", "InstTLBMultiHit", "InstFetchPrivilege", "res", + "InstrFetchProhibited", "res", "res", "res", + "LoadStoreTLBMiss", "LoadStoreTLBMultihit", "LoadStorePrivilege", "res", + "LoadProhibited", "StoreProhibited", "res", "res", + "Cp0Dis", "Cp1Dis", "Cp2Dis", "Cp3Dis", + "Cp4Dis", "Cp5Dis", "Cp6Dis", "Cp7Dis" +}; void commonErrorHandler(XtExcFrame *frame); @@ -116,162 +128,219 @@ static void haltOtherCore() } //Returns true when a debugger is attached using JTAG. -static int inOCDMode() { +static int inOCDMode() +{ #if CONFIG_ESP32_DEBUG_OCDAWARE - int dcr; - int reg=0x10200C; //DSRSET register - asm("rer %0,%1":"=r"(dcr):"r"(reg)); - return (dcr&0x1); + int dcr; + int reg = 0x10200C; //DSRSET register + asm("rer %0,%1":"=r"(dcr):"r"(reg)); + return (dcr & 0x1); #else - return 0; //Always return no debugger is attached. + return 0; //Always return no debugger is attached. #endif } -void panicHandler(XtExcFrame *frame) { - int *regs=(int*)frame; - //Please keep in sync with PANIC_RSN_* defines - const char *reasons[]={ - "Unknown reason", - "Unhandled debug exception", - "Double exception", - "Unhandled kernel exception", - "Coprocessor exception", - "Interrupt wdt timeout on CPU0", - "Interrupt wdt timeout on CPU1", - }; - const char *reason=reasons[0]; - //The panic reason is stored in the EXCCAUSE register. - if (regs[20]<=PANIC_RSN_MAX) reason=reasons[regs[20]]; - haltOtherCore(); - panicPutStr("Guru Meditation Error: Core "); - panicPutDec(xPortGetCoreID()); - panicPutStr(" panic'ed ("); - panicPutStr(reason); - panicPutStr(")\r\n"); +void panicHandler(XtExcFrame *frame) +{ + int *regs = (int *)frame; + //Please keep in sync with PANIC_RSN_* defines + const char *reasons[] = { + "Unknown reason", + "Unhandled debug exception", + "Double exception", + "Unhandled kernel exception", + "Coprocessor exception", + "Interrupt wdt timeout on CPU0", + "Interrupt wdt timeout on CPU1", + }; + const char *reason = reasons[0]; + //The panic reason is stored in the EXCCAUSE register. + if (regs[20] <= PANIC_RSN_MAX) { + reason = reasons[regs[20]]; + } + haltOtherCore(); + panicPutStr("Guru Meditation Error: Core "); + panicPutDec(xPortGetCoreID()); + panicPutStr(" panic'ed ("); + panicPutStr(reason); + panicPutStr(")\r\n"); - if (inOCDMode()) { - asm("break.n 1"); - } - commonErrorHandler(frame); + if (inOCDMode()) { + asm("break.n 1"); + } + commonErrorHandler(frame); } -static void setFirstBreakpoint(uint32_t pc) { - asm( - "wsr.ibreaka0 %0\n" \ - "rsr.ibreakenable a3\n" \ - "movi a4,1\n" \ - "or a4, a4, a3\n" \ - "wsr.ibreakenable a4\n" \ - ::"r"(pc):"a3","a4"); +static void setFirstBreakpoint(uint32_t pc) +{ + asm( + "wsr.ibreaka0 %0\n" \ + "rsr.ibreakenable a3\n" \ + "movi a4,1\n" \ + "or a4, a4, a3\n" \ + "wsr.ibreakenable a4\n" \ + ::"r"(pc):"a3", "a4"); } -void xt_unhandled_exception(XtExcFrame *frame) { - int *regs=(int*)frame; - int x; +void xt_unhandled_exception(XtExcFrame *frame) +{ + int *regs = (int *)frame; + int x; - haltOtherCore(); - panicPutStr("Guru Meditation Error of type "); - x=regs[20]; - if (x<40) panicPutStr(edesc[x]); else panicPutStr("Unknown"); - panicPutStr(" occurred on core "); - panicPutDec(xPortGetCoreID()); - if (inOCDMode()) { - panicPutStr(" at pc="); - panicPutHex(regs[1]); - panicPutStr(". Setting bp and returning..\r\n"); - //Stick a hardware breakpoint on the address the handler returns to. This way, the OCD debugger - //will kick in exactly at the context the error happened. - setFirstBreakpoint(regs[1]); - return; - } - panicPutStr(". Exception was unhandled.\r\n"); - commonErrorHandler(frame); + haltOtherCore(); + panicPutStr("Guru Meditation Error of type "); + x = regs[20]; + if (x < 40) { + panicPutStr(edesc[x]); + } else { + panicPutStr("Unknown"); + } + panicPutStr(" occurred on core "); + panicPutDec(xPortGetCoreID()); + if (inOCDMode()) { + panicPutStr(" at pc="); + panicPutHex(regs[1]); + panicPutStr(". Setting bp and returning..\r\n"); + //Stick a hardware breakpoint on the address the handler returns to. This way, the OCD debugger + //will kick in exactly at the context the error happened. + setFirstBreakpoint(regs[1]); + return; + } + panicPutStr(". Exception was unhandled.\r\n"); + commonErrorHandler(frame); } /* -If watchdogs are enabled, the panic handler runs the risk of getting aborted pre-emptively because -an overzealous watchdog decides to reset it. On the other hand, if we disable all watchdogs, we run -the risk of somehow halting in the panic handler and not resetting. That is why this routine kills -all watchdogs except the timer group 0 watchdog, and it reconfigures that to reset the chip after -one second. + If watchdogs are enabled, the panic handler runs the risk of getting aborted pre-emptively because + an overzealous watchdog decides to reset it. On the other hand, if we disable all watchdogs, we run + the risk of somehow halting in the panic handler and not resetting. That is why this routine kills + all watchdogs except the timer group 0 watchdog, and it reconfigures that to reset the chip after + one second. */ -static void reconfigureAllWdts() { - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_feed=1; - TIMERG0.wdt_config0.sys_reset_length=7; //3.2uS - TIMERG0.wdt_config0.cpu_reset_length=7; //3.2uS - TIMERG0.wdt_config0.stg0=TIMG_WDT_STG_SEL_RESET_SYSTEM; //1st stage timeout: reset system - TIMERG0.wdt_config1.clk_prescale=80*500; //Prescaler: wdt counts in ticks of 0.5mS - TIMERG0.wdt_config2=2000; //1 second before reset - TIMERG0.wdt_config0.en=1; - TIMERG0.wdt_wprotect=0; - //Disable wdt 1 - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config0.en=0; - TIMERG1.wdt_wprotect=0; +static void reconfigureAllWdts() +{ + TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE; + TIMERG0.wdt_feed = 1; + TIMERG0.wdt_config0.sys_reset_length = 7; //3.2uS + TIMERG0.wdt_config0.cpu_reset_length = 7; //3.2uS + TIMERG0.wdt_config0.stg0 = TIMG_WDT_STG_SEL_RESET_SYSTEM; //1st stage timeout: reset system + TIMERG0.wdt_config1.clk_prescale = 80 * 500; //Prescaler: wdt counts in ticks of 0.5mS + TIMERG0.wdt_config2 = 2000; //1 second before reset + TIMERG0.wdt_config0.en = 1; + TIMERG0.wdt_wprotect = 0; + //Disable wdt 1 + TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; + TIMERG1.wdt_config0.en = 0; + TIMERG1.wdt_wprotect = 0; } #if CONFIG_ESP32_PANIC_GDBSTUB || CONFIG_ESP32_PANIC_PRINT_HALT /* -This disables all the watchdogs for when we call the gdbstub. + This disables all the watchdogs for when we call the gdbstub. */ -static void disableAllWdts() { - TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG0.wdt_config0.en=0; - TIMERG0.wdt_wprotect=0; - TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; - TIMERG1.wdt_config0.en=0; - TIMERG0.wdt_wprotect=0; +static void disableAllWdts() +{ + TIMERG0.wdt_wprotect = TIMG_WDT_WKEY_VALUE; + TIMERG0.wdt_config0.en = 0; + TIMERG0.wdt_wprotect = 0; + TIMERG1.wdt_wprotect = TIMG_WDT_WKEY_VALUE; + TIMERG1.wdt_config0.en = 0; + TIMERG0.wdt_wprotect = 0; } #endif +static inline bool stackPointerIsSane(uint32_t sp) +{ + return !(sp < 0x3ffae010 || sp > 0x3ffffff0 || ((sp & 0xf) != 0)); +} +static void putEntry(uint32_t pc, uint32_t sp) +{ + if (pc & 0x80000000) { + pc = (pc & 0x3fffffff) | 0x40000000; + } + panicPutStr(" 0x"); + panicPutHex(pc); + panicPutStr(":0x"); + panicPutHex(sp); +} +void doBacktrace(XtExcFrame *frame) +{ + uint32_t i = 0, pc = frame->pc, sp = frame->a1; + panicPutStr("\nBacktrace:"); + /* Do not check sanity on first entry, PC could be smashed. */ + putEntry(pc, sp); + pc = frame->a0; + while (i++ < 100) { + uint32_t psp = sp; + if (!stackPointerIsSane(sp) || i++ > 100) { + break; + } + sp = *((uint32_t *) (sp - 0x10 + 4)); + putEntry(pc, sp); + pc = *((uint32_t *) (psp - 0x10)); + if (pc < 0x40000000) { + break; + } + } + panicPutStr("\n\n"); +} + /* -We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the -serial port and either jump to the gdb stub, halt the CPU or reboot. + We arrive here after a panic or unhandled exception, when no OCD is detected. Dump the registers to the + serial port and either jump to the gdb stub, halt the CPU or reboot. */ -void commonErrorHandler(XtExcFrame *frame) { - int *regs=(int*)frame; - int x, y; - const char *sdesc[]={ - "PC ","PS ","A0 ","A1 ","A2 ","A3 ","A4 ","A5 ", - "A6 ","A7 ","A8 ","A9 ","A10 ","A11 ","A12 ","A13 ", - "A14 ","A15 ","SAR ","EXCCAUSE","EXCVADDR","LBEG ","LEND ","LCOUNT "}; +void commonErrorHandler(XtExcFrame *frame) +{ + int *regs = (int *)frame; + int x, y; + const char *sdesc[] = { + "PC ", "PS ", "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", + "A6 ", "A7 ", "A8 ", "A9 ", "A10 ", "A11 ", "A12 ", "A13 ", + "A14 ", "A15 ", "SAR ", "EXCCAUSE", "EXCVADDR", "LBEG ", "LEND ", "LCOUNT " + }; - //Feed the watchdogs, so they will give us time to print out debug info - reconfigureAllWdts(); + //Feed the watchdogs, so they will give us time to print out debug info + reconfigureAllWdts(); - panicPutStr("Register dump:\r\n"); + panicPutStr("Register dump:\r\n"); - for (x=0; x<24; x+=4) { - for (y=0; y<4; y++) { - if (sdesc[x+y][0]!=0) { - panicPutStr(sdesc[x+y]); - panicPutStr(": "); - panicPutHex(regs[x+y+1]); - panicPutStr(" "); - } - } - panicPutStr("\r\n"); - } + for (x = 0; x < 24; x += 4) { + for (y = 0; y < 4; y++) { + if (sdesc[x + y][0] != 0) { + panicPutStr(sdesc[x + y]); + panicPutStr(": 0x"); + panicPutHex(regs[x + y + 1]); + panicPutStr(" "); + } + } + panicPutStr("\r\n"); + } + /* With windowed ABI backtracing is easy, let's do it. */ + doBacktrace(frame); #if CONFIG_ESP32_PANIC_GDBSTUB - disableAllWdts(); - panicPutStr("Entering gdb stub now.\r\n"); - esp_gdbstub_panic_handler(frame); + disableAllWdts(); + panicPutStr("Entering gdb stub now.\r\n"); + esp_gdbstub_panic_handler(frame); #elif CONFIG_ESP32_PANIC_PRINT_REBOOT || CONFIG_ESP32_PANIC_SILENT_REBOOT - panicPutStr("Rebooting...\r\n"); - for (x=0; x<100; x++) ets_delay_us(1000); - software_reset(); + panicPutStr("Rebooting...\r\n"); + for (x = 0; x < 100; x++) { + ets_delay_us(1000); + } + software_reset(); #else - disableAllWdts(); - panicPutStr("CPU halted.\r\n"); - while(1); + disableAllWdts(); + panicPutStr("CPU halted.\r\n"); + while (1); #endif } -void esp_set_breakpoint_if_jtag(void *fn) { - if (!inOCDMode()) return; - setFirstBreakpoint((uint32_t)fn); +void esp_set_breakpoint_if_jtag(void *fn) +{ + if (!inOCDMode()) { + return; + } + setFirstBreakpoint((uint32_t)fn); } diff --git a/components/esp32/phy_init_data.h b/components/esp32/phy_init_data.h index 206598f97c..ea6a761b35 100644 --- a/components/esp32/phy_init_data.h +++ b/components/esp32/phy_init_data.h @@ -27,7 +27,7 @@ static const char phy_init_magic_pre[] = PHY_INIT_MAGIC; * @brief Structure containing default recommended PHY initialization parameters. */ static const esp_phy_init_data_t phy_init_data= { - .param_ver_id = 0, + .param_ver_id = 1, .crystal_select = 3, .wifi_rx_gain_swp_step_1 = 0x05, .wifi_rx_gain_swp_step_2 = 0x04, @@ -75,7 +75,7 @@ static const esp_phy_init_data_t phy_init_data= { .target_power_qdb_1 = LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 76), .target_power_qdb_2 = LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 74), .target_power_qdb_3 = LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 68), - .target_power_qdb_4 = LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 64), + .target_power_qdb_4 = LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 60), .target_power_qdb_5 = LIMIT(CONFIG_ESP32_PHY_MAX_TX_POWER * 4, 0, 52), .target_power_index_mcs0 = 0, .target_power_index_mcs1 = 0, diff --git a/components/esp32/system_api.c b/components/esp32/system_api.c index 36a5f806da..e8013441b1 100644 --- a/components/esp32/system_api.c +++ b/components/esp32/system_api.c @@ -105,10 +105,10 @@ void IRAM_ATTR esp_restart(void) Cache_Read_Disable(0); Cache_Read_Disable(1); - // Flush any data left in UART FIFO - uart_tx_flush(0); - uart_tx_flush(1); - uart_tx_flush(2); + // Flush any data left in UART FIFOs + uart_tx_wait_idle(0); + uart_tx_wait_idle(1); + uart_tx_wait_idle(2); // Reset wifi/bluetooth (bb/mac) SET_PERI_REG_MASK(DPORT_WIFI_RST_EN_REG, 0x1f); diff --git a/components/esp32/task_wdt.c b/components/esp32/task_wdt.c index 860556b8c5..8585260e2f 100644 --- a/components/esp32/task_wdt.c +++ b/components/esp32/task_wdt.c @@ -27,6 +27,7 @@ #include #include "esp_err.h" #include "esp_intr.h" +#include "esp_intr_alloc.h" #include "esp_attr.h" #include "esp_freertos_hooks.h" #include "soc/timer_group_struct.h" @@ -51,7 +52,7 @@ static wdt_task_t *wdt_task_list=NULL; static portMUX_TYPE taskwdt_spinlock = portMUX_INITIALIZER_UNLOCKED; -static void IRAM_ATTR task_wdt_isr(void *arg) { +static void task_wdt_isr(void *arg) { wdt_task_t *wdttask; const char *cpu; //Feed the watchdog so we do not reset @@ -71,21 +72,21 @@ static void IRAM_ATTR task_wdt_isr(void *arg) { return; } //Watchdog got triggered because at least one task did not report in. - ets_printf(DRAM_STR("Task watchdog got triggered. The following tasks did not feed the watchdog in time:\n")); + ets_printf("Task watchdog got triggered. The following tasks did not feed the watchdog in time:\n"); for (wdttask=wdt_task_list; wdttask!=NULL; wdttask=wdttask->next) { if (!wdttask->fed_watchdog) { cpu=xTaskGetAffinity(wdttask->task_handle)==0?DRAM_STR("CPU 0"):DRAM_STR("CPU 1"); if (xTaskGetAffinity(wdttask->task_handle)==tskNO_AFFINITY) cpu=DRAM_STR("CPU 0/1"); - ets_printf(DRAM_STR(" - %s (%s)\n"), pcTaskGetTaskName(wdttask->task_handle), cpu); + ets_printf(" - %s (%s)\n", pcTaskGetTaskName(wdttask->task_handle), cpu); } } ets_printf(DRAM_STR("Tasks currently running:\n")); for (int x=0; x +#include +#include "rom/ets_sys.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/xtensa_api.h" +#include "unity.h" +#include "soc/uart_reg.h" +#include "soc/dport_reg.h" +#include "soc/io_mux_reg.h" +#include "esp_intr_alloc.h" +#include "driver/timer.h" + + +#define TIMER_DIVIDER 16 /*!< Hardware timer clock divider */ +#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) /*!< used to calculate counter value */ +#define TIMER_INTERVAL0_SEC (3.4179) /*!< test interval for timer 0 */ +#define TIMER_INTERVAL1_SEC (5.78) /*!< test interval for timer 1 */ + + +static void my_timer_init(int timer_group, int timer_idx, int ival) +{ + timer_config_t config; + config.alarm_en = 1; + config.auto_reload = 1; + config.counter_dir = TIMER_COUNT_UP; + config.divider = TIMER_DIVIDER; + config.intr_type = TIMER_INTR_LEVEL; + config.counter_en = TIMER_PAUSE; + /*Configure timer*/ + timer_init(timer_group, timer_idx, &config); + /*Stop timer counter*/ + timer_pause(timer_group, timer_idx); + /*Load counter value */ + timer_set_counter_value(timer_group, timer_idx, 0x00000000ULL); + /*Set alarm value*/ + timer_set_alarm_value(timer_group, timer_idx, ival); + /*Enable timer interrupt*/ + timer_enable_intr(timer_group, timer_idx); +} + +static volatile int count[4]={0,0,0,0}; + + +static void timer_isr(void *arg) +{ + int timer_idx = (int)arg; + count[timer_idx]++; + if (timer_idx==0) { + TIMERG0.int_clr_timers.t0 = 1; + TIMERG0.hw_timer[0].update=1; + TIMERG0.hw_timer[0].config.alarm_en = 1; + } + if (timer_idx==1) { + TIMERG0.int_clr_timers.t1 = 1; + TIMERG0.hw_timer[1].update=1; + TIMERG0.hw_timer[1].config.alarm_en = 1; + } + if (timer_idx==2) { + TIMERG1.int_clr_timers.t0 = 1; + TIMERG1.hw_timer[0].update=1; + TIMERG1.hw_timer[0].config.alarm_en = 1; + } + if (timer_idx==3) { + TIMERG1.int_clr_timers.t1 = 1; + TIMERG1.hw_timer[1].update=1; + TIMERG1.hw_timer[1].config.alarm_en = 1; + } +// ets_printf("int %d\n", timer_idx); +} + + +static void timer_test(int flags) { + int x; + timer_isr_handle_t inth[4]; + my_timer_init(TIMER_GROUP_0, TIMER_0, 110000); + my_timer_init(TIMER_GROUP_0, TIMER_1, 120000); + my_timer_init(TIMER_GROUP_1, TIMER_0, 130000); + my_timer_init(TIMER_GROUP_1, TIMER_1, 140000); + timer_isr_register(TIMER_GROUP_0, TIMER_0, timer_isr, (void*)0, flags|ESP_INTR_FLAG_INTRDISABLED, &inth[0]); + timer_isr_register(TIMER_GROUP_0, TIMER_1, timer_isr, (void*)1, flags, &inth[1]); + timer_isr_register(TIMER_GROUP_1, TIMER_0, timer_isr, (void*)2, flags, &inth[2]); + timer_isr_register(TIMER_GROUP_1, TIMER_1, timer_isr, (void*)3, flags, &inth[3]); + timer_start(TIMER_GROUP_0, TIMER_0); + timer_start(TIMER_GROUP_0, TIMER_1); + timer_start(TIMER_GROUP_1, TIMER_0); + timer_start(TIMER_GROUP_1, TIMER_1); + + for (x=0; x<4; x++) count[x]=0; + printf("Interrupts allocated: %d (dis) %d %d %d\n", + esp_intr_get_intno(inth[0]), esp_intr_get_intno(inth[1]), + esp_intr_get_intno(inth[2]), esp_intr_get_intno(inth[3])); + printf("Timer values on start: %d %d %d %d\n", count[0], count[1], count[2], count[3]); + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer values after 1 sec: %d %d %d %d\n", count[0], count[1], count[2], count[3]); + TEST_ASSERT(count[0]==0); + TEST_ASSERT(count[1]!=0); + TEST_ASSERT(count[2]!=0); + TEST_ASSERT(count[3]!=0); + + printf("Disabling timers 1 and 2...\n"); + esp_intr_enable(inth[0]); + esp_intr_disable(inth[1]); + esp_intr_disable(inth[2]); + for (x=0; x<4; x++) count[x]=0; + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer values after 1 sec: %d %d %d %d\n", count[0], count[1], count[2], count[3]); + TEST_ASSERT(count[0]!=0); + TEST_ASSERT(count[1]==0); + TEST_ASSERT(count[2]==0); + TEST_ASSERT(count[3]!=0); + printf("Disabling other half...\n"); + esp_intr_enable(inth[1]); + esp_intr_enable(inth[2]); + esp_intr_disable(inth[0]); + esp_intr_disable(inth[3]); + for (x=0; x<4; x++) count[x]=0; + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer values after 1 sec: %d %d %d %d\n", count[0], count[1], count[2], count[3]); + TEST_ASSERT(count[0]==0); + TEST_ASSERT(count[1]!=0); + TEST_ASSERT(count[2]!=0); + TEST_ASSERT(count[3]==0); + printf("Done.\n"); + esp_intr_free(inth[0]); + esp_intr_free(inth[1]); + esp_intr_free(inth[2]); + esp_intr_free(inth[3]); +} + +static volatile int int_timer_ctr; + + +void int_timer_handler(void *arg) { + xthal_set_ccompare(1, xthal_get_ccount()+8000000); + int_timer_ctr++; +} + +void local_timer_test() +{ + intr_handle_t ih; + esp_err_t r; + r=esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, 0, int_timer_handler, NULL, &ih); + TEST_ASSERT(r==ESP_OK); + printf("Int timer 1 intno %d\n", esp_intr_get_intno(ih)); + xthal_set_ccompare(1, xthal_get_ccount()+8000000); + int_timer_ctr=0; + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr!=0); + printf("Disabling int\n"); + esp_intr_disable(ih); + int_timer_ctr=0; + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr==0); + printf("Re-enabling\n"); + esp_intr_enable(ih); + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr!=0); + + printf("Free int, re-alloc disabled\n"); + r=esp_intr_free(ih); + TEST_ASSERT(r==ESP_OK); + r=esp_intr_alloc(ETS_INTERNAL_TIMER1_INTR_SOURCE, ESP_INTR_FLAG_INTRDISABLED, int_timer_handler, NULL, &ih); + TEST_ASSERT(r==ESP_OK); + int_timer_ctr=0; + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr==0); + printf("Re-enabling\n"); + esp_intr_enable(ih); + vTaskDelay(1000 / portTICK_RATE_MS); + printf("Timer val after 1 sec: %d\n", int_timer_ctr); + TEST_ASSERT(int_timer_ctr!=0); + r=esp_intr_free(ih); + TEST_ASSERT(r==ESP_OK); + printf("Done.\n"); +} + + +TEST_CASE("Intr_alloc test, CPU-local int source", "[esp32]") +{ + local_timer_test(); +} + +TEST_CASE("Intr_alloc test, private ints", "[esp32]") +{ + timer_test(0); +} + +TEST_CASE("Intr_alloc test, shared ints", "[esp32]") +{ + timer_test(ESP_INTR_FLAG_SHARED); +} diff --git a/components/esp32/test/test_malloc_caps.c b/components/esp32/test/test_malloc_caps.c new file mode 100644 index 0000000000..0f5129ad20 --- /dev/null +++ b/components/esp32/test/test_malloc_caps.c @@ -0,0 +1,64 @@ +/* + Tests for the capabilities-based memory allocator. +*/ + +#include +#include +#include "unity.h" +#include "rom/ets_sys.h" +#include "esp_heap_alloc_caps.h" +#include + + +TEST_CASE("Capabilities allocator test", "[esp32]") +{ + char *m1, *m2[10]; + int x; + size_t free8start, free32start, free8, free32; + free8start=xPortGetFreeHeapSizeCaps(MALLOC_CAP_8BIT); + free32start=xPortGetFreeHeapSizeCaps(MALLOC_CAP_32BIT); + printf("Free 8bit-capable memory: %dK, 32-bit capable memory %dK\n", free8start, free32start); + TEST_ASSERT(free32start>free8start); + printf("Allocating 10K of 8-bit capable RAM\n"); + m1=pvPortMallocCaps(10*1024, MALLOC_CAP_8BIT); + printf("--> %p\n", m1); + free8=xPortGetFreeHeapSizeCaps(MALLOC_CAP_8BIT); + free32=xPortGetFreeHeapSizeCaps(MALLOC_CAP_32BIT); + printf("Free 8bit-capable memory: %dK, 32-bit capable memory %dK\n", free8, free32); + //Both should have gone down by 10K; 8bit capable ram is also 32-bit capable + TEST_ASSERT(free8<(free8start-10*1024)); + TEST_ASSERT(free32<(free32start-10*1024)); + //Assume we got DRAM back + TEST_ASSERT((((int)m1)&0xFF000000)==0x3F000000); + free(m1); + printf("Freeing; allocating 10K of 32K-capable RAM\n"); + m1=pvPortMallocCaps(10*1024, MALLOC_CAP_32BIT); + printf("--> %p\n", m1); + free8=xPortGetFreeHeapSizeCaps(MALLOC_CAP_8BIT); + free32=xPortGetFreeHeapSizeCaps(MALLOC_CAP_32BIT); + printf("Free 8bit-capable memory: %dK, 32-bit capable memory %dK\n", free8, free32); + //Only 32-bit should have gone down by 10K: 32-bit isn't necessarily 8bit capable + TEST_ASSERT(free32<(free32start-10*1024)); + TEST_ASSERT(free8==free8start); + //Assume we got IRAM back + TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); + free(m1); + printf("Allocating impossible caps\n"); + m1=pvPortMallocCaps(10*1024, MALLOC_CAP_8BIT|MALLOC_CAP_EXEC); + printf("--> %p\n", m1); + TEST_ASSERT(m1==NULL); + printf("Testing changeover iram -> dram"); + for (x=0; x<10; x++) { + m2[x]=pvPortMallocCaps(10*1024, MALLOC_CAP_32BIT); + printf("--> %p\n", m2[x]); + } + TEST_ASSERT((((int)m2[0])&0xFF000000)==0x40000000); + TEST_ASSERT((((int)m2[9])&0xFF000000)==0x3F000000); + printf("Test if allocating executable code still gives IRAM, even with dedicated IRAM region depleted\n"); + m1=pvPortMallocCaps(10*1024, MALLOC_CAP_EXEC); + printf("--> %p\n", m1); + TEST_ASSERT((((int)m1)&0xFF000000)==0x40000000); + free(m1); + for (x=0; x<10; x++) free(m2[x]); + printf("Done.\n"); +} diff --git a/components/esptool_py/Makefile.projbuild b/components/esptool_py/Makefile.projbuild index acbada7244..b5992a4d96 100644 --- a/components/esptool_py/Makefile.projbuild +++ b/components/esptool_py/Makefile.projbuild @@ -28,13 +28,13 @@ ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_CO ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN) -ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES ifndef IS_BOOTLOADER_BUILD -# for secure boot, add a signing step to get from unsiged app to signed app +# for locally signed secure boot image, add a signing step to get from unsigned app to signed app APP_BIN_UNSIGNED := $(APP_BIN:.bin=-unsigned.bin) -$(APP_BIN): $(APP_BIN_UNSIGNED) - $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $^ # signed in-place +$(APP_BIN): $(APP_BIN_UNSIGNED) $(SECURE_BOOT_SIGNING_KEY) $(SDKCONFIG_MAKEFILE) + $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $< endif endif # non-secure boot (or bootloader), both these files are the same @@ -43,17 +43,23 @@ APP_BIN_UNSIGNED ?= $(APP_BIN) $(APP_BIN_UNSIGNED): $(APP_ELF) $(ESPTOOLPY_SRC) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) $(ESPTOOL_ELF2IMAGE_OPTIONS) -o $@ $< -flash: all_binaries $(ESPTOOLPY_SRC) +flash: all_binaries $(ESPTOOLPY_SRC) $(call prereq_if_explicit,erase_flash) @echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..." -ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +ifdef CONFIG_SECURE_BOOT_ENABLED @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" endif $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS) -app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) +app-flash: $(APP_BIN) $(ESPTOOLPY_SRC) $(call prereq_if_explicit,erase_flash) @echo "Flashing app to serial port $(ESPPORT), offset $(CONFIG_APP_OFFSET)..." $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) # Submodules normally added in component.mk, but can be added # at the project level as long as qualified path COMPONENT_SUBMODULES += $(COMPONENT_PATH)/esptool + +erase_flash: + @echo "Erasing entire flash..." + $(ESPTOOLPY_SERIAL) erase_flash + +.PHONY: erase_flash diff --git a/components/esptool_py/esptool b/components/esptool_py/esptool index 5c6962e894..adc914b91a 160000 --- a/components/esptool_py/esptool +++ b/components/esptool_py/esptool @@ -1 +1 @@ -Subproject commit 5c6962e894e0a118c9a4b5760876433493449260 +Subproject commit adc914b91ac6d2cfd1ace56307b4374eb9439e14 diff --git a/components/ethernet/Kconfig b/components/ethernet/Kconfig index cbd3bfbe47..9eb897cbba 100644 --- a/components/ethernet/Kconfig +++ b/components/ethernet/Kconfig @@ -3,18 +3,32 @@ menuconfig ETHERNET default n help Enable this option to enable ethernet driver and show the menu with ethernet features. - config DMA_RX_BUF_NUM - int "Dma Rx Buf Num" + int "DMA Rx Buf Num" default 10 depends on ETHERNET help Dma rx buf num ,can not be 0 . config DMA_TX_BUF_NUM - int "Dma Tx Buf Num" + int "DMA Tx Buf Num" default 10 depends on ETHERNET help Dma tx Buf num ,can not be 0. + +config EMAC_L2_TO_L3_RX_BUF_MODE + bool "L2 To L3 RX BUF COPY MODE" + default n + depends on ETHERNET + help + Receive Buf user copy mode or pointer mode. + +config EMAC_TASK_PRIORITY + int "EMAC_TASK_PRIORITY" + default 20 + depends on ETHERNET + help + Emac task priority ,suggest 3 ~ 23. + diff --git a/components/ethernet/emac_common.h b/components/ethernet/emac_common.h index 48f71fd90f..774c287ad5 100644 --- a/components/ethernet/emac_common.h +++ b/components/ethernet/emac_common.h @@ -19,6 +19,7 @@ #include "esp_err.h" #include "emac_dev.h" +#include "esp_eth.h" #ifdef __cplusplus extern "C" { @@ -32,11 +33,6 @@ typedef struct { emac_par_t par; } emac_event_t; -enum emac_mode { - EMAC_MODE_RMII = 0, - EMAC_MDOE_MII, -}; - enum emac_runtime_status { EMAC_RUNTIME_NOT_INIT = 0, EMAC_RUNTIME_INIT, @@ -45,36 +41,37 @@ enum emac_runtime_status { }; enum { + SIG_EMAC_RX_UNAVAIL, SIG_EMAC_TX_DONE, SIG_EMAC_RX_DONE, - SIG_EMAC_TX, SIG_EMAC_START, SIG_EMAC_STOP, + SIG_EMAC_CHECK_LINK, SIG_EMAC_MAX }; -typedef void (*emac_phy_fun)(void); -typedef esp_err_t (*emac_tcpip_input_fun)(void *buffer, uint16_t len, void *eb); -typedef void (*emac_gpio_config_func)(void); - struct emac_config_data { - unsigned int phy_addr; - enum emac_mode mac_mode; + eth_phy_base_t phy_addr; + eth_mode_t mac_mode; struct dma_extended_desc *dma_etx; - unsigned int cur_tx; - unsigned int dirty_tx; - signed int cnt_tx; + uint32_t cur_tx; + uint32_t dirty_tx; + int32_t cnt_tx; struct dma_extended_desc *dma_erx; - unsigned int cur_rx; - unsigned int dirty_rx; - signed int cnt_rx; - unsigned int rx_need_poll; + uint32_t cur_rx; + uint32_t dirty_rx; + int32_t cnt_rx; + uint32_t rx_need_poll; bool phy_link_up; enum emac_runtime_status emac_status; uint8_t macaddr[6]; - emac_phy_fun phy_init; - emac_tcpip_input_fun emac_tcpip_input; - emac_gpio_config_func emac_gpio_config; + eth_phy_func phy_init; + eth_tcpip_input_func emac_tcpip_input; + eth_gpio_config_func emac_gpio_config; + eth_phy_check_link_func emac_phy_check_link; + eth_phy_check_init_func emac_phy_check_init; + eth_phy_get_speed_mode_func emac_phy_get_speed_mode; + eth_phy_get_duplex_mode_func emac_phy_get_duplex_mode; }; enum emac_post_type { @@ -103,18 +100,15 @@ struct emac_close_cmd { #if CONFIG_ETHERNET #define DMA_RX_BUF_NUM CONFIG_DMA_RX_BUF_NUM #define DMA_TX_BUF_NUM CONFIG_DMA_TX_BUF_NUM +#define EMAC_TASK_PRIORITY CONFIG_EMAC_TASK_PRIORITY #else #define DMA_RX_BUF_NUM 1 #define DMA_TX_BUF_NUM 1 +#define EMAC_TASK_PRIORITY 10 #endif #define DMA_RX_BUF_SIZE 1600 #define DMA_TX_BUF_SIZE 1600 -//lwip err -#define ERR_OK 0 -#define ERR_MEM -1 -#define ERR_IF -16 - #define EMAC_CMD_OK 0 #define EMAC_CMD_FAIL -1 diff --git a/components/ethernet/emac_dev.c b/components/ethernet/emac_dev.c index a8095fecba..244da08432 100644 --- a/components/ethernet/emac_dev.c +++ b/components/ethernet/emac_dev.c @@ -34,18 +34,6 @@ static const char *TAG = "emac"; -void emac_poll_tx_cmd(void) -{ - //write any to wake up dma - REG_WRITE(EMAC_DMATXPOLLDEMAND_REG, 1); -} - -void emac_poll_rx_cmd(void) -{ - //write any to wake up dma - REG_WRITE(EMAC_DMARXPOLLDEMAND_REG, 1); -} - void emac_enable_dma_tx(void) { REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_TRANSMISSION_COMMAND); @@ -66,15 +54,6 @@ void emac_disable_dma_rx(void) REG_CLR_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_RECEIVE); } -uint32_t emac_read_tx_cur_reg(void) -{ - return REG_READ(EMAC_DMATXCURRDESC_REG); -} - -uint32_t emac_read_rx_cur_reg(void) -{ - return REG_READ(EMAC_DMARXCURRDESC_REG); -} uint32_t emac_read_mac_version(void) { @@ -121,16 +100,18 @@ void emac_dma_init(void) REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_FORWARD_UNDERSIZED_GOOD_FRAMES); REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_OPERATE_SECOND_FRAME); REG_SET_FIELD(EMAC_DMABUSMODE_REG, EMAC_PROG_BURST_LEN, 4); + REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG,EMAC_DMAOPERATION_MODE_REG); } void emac_mac_init(void) { - REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACRX); - REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACTX); REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACDUPLEX); REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACMIIGMII); REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED); REG_SET_BIT(EMAC_GMACFRAMEFILTER_REG, EMAC_PROMISCUOUS_MODE); + + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACRX); + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACTX); } void emac_set_clk_rmii(void) diff --git a/components/ethernet/emac_dev.h b/components/ethernet/emac_dev.h index ede15271eb..bc04d8d9e2 100644 --- a/components/ethernet/emac_dev.h +++ b/components/ethernet/emac_dev.h @@ -49,14 +49,52 @@ uint32_t emac_read_mac_version(void); void emac_dma_init(void); void emac_mac_init(void); void emac_enable_dma_tx(void); -void emac_poll_tx_cmd(void); -uint32_t emac_read_tx_cur_reg(void); void emac_enable_dma_rx(void); -uint32_t emac_read_rx_cur_reg(void); -void emac_poll_rx_cmd(void); void emac_disable_dma_tx(void); void emac_disable_dma_rx(void); +uint32_t inline emac_read_tx_cur_reg(void) +{ + return REG_READ(EMAC_DMATXCURRDESC_REG); +} + +uint32_t inline emac_read_rx_cur_reg(void) +{ + return REG_READ(EMAC_DMARXCURRDESC_REG); +} + +void inline emac_poll_tx_cmd(void) +{ + //write any to wake up dma + REG_WRITE(EMAC_DMATXPOLLDEMAND_REG, 1); +} + +void inline emac_poll_rx_cmd(void) +{ + //write any to wake up dma + REG_WRITE(EMAC_DMARXPOLLDEMAND_REG, 1); +} + +void inline emac_disable_rx_intr(void) +{ + REG_CLR_BIT(EMAC_DMAINTERRUPT_EN_REG,EMAC_RECEIVE_INTERRUPT_ENABLE); +} + +void inline emac_enable_rx_intr(void) +{ + REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG,EMAC_RECEIVE_INTERRUPT_ENABLE); +} + +void inline emac_disable_rx_unavail_intr(void) +{ + REG_CLR_BIT(EMAC_DMAINTERRUPT_EN_REG,EMAC_RECEIVE_BUFFER_UNAVAILABLE_ENABLE); +} + +void inline emac_enable_rx_unavail_intr(void) +{ + REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG,EMAC_RECEIVE_BUFFER_UNAVAILABLE_ENABLE); +} + #ifdef __cplusplus } #endif diff --git a/components/ethernet/emac_main.c b/components/ethernet/emac_main.c index cbbab5149e..ab2ca8964c 100644 --- a/components/ethernet/emac_main.c +++ b/components/ethernet/emac_main.c @@ -35,6 +35,7 @@ #include "esp_err.h" #include "esp_log.h" #include "esp_eth.h" +#include "esp_intr_alloc.h" #include "emac_common.h" #include "emac_desc.h" @@ -46,6 +47,8 @@ #include "freertos/semphr.h" #include "freertos/timers.h" +#include "lwip/err.h" + #define EMAC_EVT_QNUM 200 #define EMAC_SIG_MAX 50 @@ -62,7 +65,8 @@ static xTaskHandle emac_task_hdl; static xQueueHandle emac_xqueue; static uint8_t emac_sig_cnt[EMAC_SIG_MAX] = {0}; static TimerHandle_t emac_timer = NULL; - +static SemaphoreHandle_t emac_rx_xMutex = NULL; +static SemaphoreHandle_t emac_tx_xMutex = NULL; static const char *TAG = "emac"; static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par); @@ -81,20 +85,24 @@ void esp_eth_get_mac(uint8_t mac[6]) static void emac_setup_tx_desc(struct dma_extended_desc *tx_desc , uint32_t size) { - tx_desc->basic.desc0 = EMAC_DESC_TX_OWN | EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN; tx_desc->basic.desc1 = size & 0xfff; + tx_desc->basic.desc0 = EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN; + tx_desc->basic.desc0 = EMAC_DESC_TX_OWN | EMAC_DESC_INT_COMPL | EMAC_DESC_LAST_SEGMENT | EMAC_DESC_FIRST_SEGMENT | EMAC_DESC_SECOND_ADDR_CHAIN; } static void emac_clean_tx_desc(struct dma_extended_desc *tx_desc) { - tx_desc->basic.desc0 = 0; tx_desc->basic.desc1 = 0; + tx_desc->basic.desc0 = 0; } -static void emac_clean_rx_desc(struct dma_extended_desc *rx_desc) +static void emac_clean_rx_desc(struct dma_extended_desc *rx_desc ,uint32_t buf_ptr) { - rx_desc->basic.desc0 = EMAC_DESC_RX_OWN; + if(buf_ptr != 0) { + rx_desc->basic.desc2 = buf_ptr; + } rx_desc->basic.desc1 = EMAC_DESC_RX_SECOND_ADDR_CHAIN | DMA_RX_BUF_SIZE; + rx_desc->basic.desc0 = EMAC_DESC_RX_OWN; } static void emac_set_tx_base_reg(void) @@ -155,18 +163,15 @@ static void emac_init_dma_chain(void) dma_phy = (uint32_t)(emac_config.dma_erx); p = emac_config.dma_erx; - for (i = 0; i < (DMA_TX_BUF_NUM - 1); i++ ) { + for (i = 0; i < (DMA_RX_BUF_NUM - 1); i++ ) { dma_phy += sizeof(struct dma_extended_desc); - emac_clean_rx_desc(p); + emac_clean_rx_desc(p, (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE)); p->basic.desc3 = dma_phy; - p->basic.desc2 = (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE); p++; } - p->basic.desc3 = (uint32_t)(emac_config.dma_erx); - p->basic.desc2 = (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE); - //init desc0 desc1 - emac_clean_rx_desc(p); + emac_clean_rx_desc(p, (uint32_t)(&emac_dma_rx_buf[0]) + (i * DMA_RX_BUF_SIZE)); + p->basic.desc3 = (uint32_t)(emac_config.dma_erx); } void esp_eth_smi_write(uint32_t reg_num, uint16_t value) @@ -206,18 +211,32 @@ static void emac_set_user_config_data(eth_config_t *config ) emac_config.phy_init = config->phy_init; emac_config.emac_tcpip_input = config->tcpip_input; emac_config.emac_gpio_config = config->gpio_config; + emac_config.emac_phy_check_link = config->phy_check_link; + emac_config.emac_phy_check_init = config->phy_check_init; + emac_config.emac_phy_get_speed_mode = config->phy_get_speed_mode; + emac_config.emac_phy_get_duplex_mode = config->phy_get_duplex_mode; +} + +static void emac_enable_intr() +{ + REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, EMAC_INTR_ENABLE_BIT); +} + +static void emac_disable_intr() +{ + REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, 0); } static esp_err_t emac_verify_args(void) { esp_err_t ret = ESP_OK; - if (emac_config.phy_addr > 31) { + if (emac_config.phy_addr > PHY31) { ESP_LOGE(TAG, "phy addr err"); ret = ESP_FAIL; } - if (emac_config.mac_mode != EMAC_MODE_RMII) { + if (emac_config.mac_mode != ETH_MODE_RMII) { ESP_LOGE(TAG, "mac mode err,now only support RMII"); ret = ESP_FAIL; } @@ -237,6 +256,26 @@ static esp_err_t emac_verify_args(void) ret = ESP_FAIL; } + if (emac_config.emac_phy_check_link == NULL) { + ESP_LOGE(TAG, "phy check link func is null"); + ret = ESP_FAIL; + } + + if (emac_config.emac_phy_check_init == NULL) { + ESP_LOGE(TAG, "phy check init func is null"); + ret = ESP_FAIL; + } + + if (emac_config.emac_phy_get_speed_mode == NULL) { + ESP_LOGE(TAG, "phy get speed mode func is null"); + ret = ESP_FAIL; + } + + if (emac_config.emac_phy_get_duplex_mode == NULL) { + ESP_LOGE(TAG, "phy get duplex mode func is null"); + ret = ESP_FAIL; + } + return ret; } @@ -254,7 +293,13 @@ static void emac_process_tx(void) { uint32_t cur_tx_desc = emac_read_tx_cur_reg(); - while (((uint32_t) & (emac_config.dma_etx[emac_config.dirty_tx].basic.desc0) != cur_tx_desc)) { + if(emac_config.emac_status == EMAC_RUNTIME_STOP) { + return; + } + + xSemaphoreTakeRecursive( emac_tx_xMutex, ( TickType_t ) portMAX_DELAY ); + + while (((uint32_t) &(emac_config.dma_etx[emac_config.dirty_tx].basic.desc0) != cur_tx_desc)) { emac_clean_tx_desc(&(emac_config.dma_etx[emac_config.dirty_tx])); emac_config.dirty_tx = (emac_config.dirty_tx + 1) % DMA_TX_BUF_NUM; emac_config.cnt_tx --; @@ -262,11 +307,33 @@ static void emac_process_tx(void) if (emac_config.cnt_tx < 0) { ESP_LOGE(TAG, "emac tx chain err"); } + cur_tx_desc = emac_read_tx_cur_reg(); } + + xSemaphoreGiveRecursive( emac_tx_xMutex ); } +void esp_eth_free_rx_buf(void *buf) +{ + xSemaphoreTakeRecursive( emac_rx_xMutex, ( TickType_t ) portMAX_DELAY ); + + emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.cur_rx]),(uint32_t) buf); + emac_config.cur_rx = (emac_config.cur_rx + 1) % DMA_RX_BUF_NUM; + emac_config.cnt_rx--; + if(emac_config.cnt_rx < 0) { + ESP_LOGE(TAG, "emac rx buf err!!\n"); + } + emac_poll_rx_cmd(); + + xSemaphoreGiveRecursive( emac_rx_xMutex ); +} + +#if CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE static void emac_process_rx(void) { + if(emac_config.emac_status == EMAC_RUNTIME_STOP) { + return; + } uint32_t cur_rx_desc = emac_read_rx_cur_reg(); while (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc)) { @@ -274,17 +341,116 @@ static void emac_process_rx(void) emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2), (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL); - emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx])); + emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx]),(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2)); emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM; - if (emac_config.rx_need_poll != 0) { - emac_poll_rx_cmd(); - emac_config.rx_need_poll = 0; - } + //if open this ,one intr can do many intrs ? - //cur_rx_desc = emac_read_rx_cur_reg(); + cur_rx_desc = emac_read_rx_cur_reg(); } + + emac_enable_rx_intr(); } +static void emac_process_rx_unavail(void) +{ + if(emac_config.emac_status == EMAC_RUNTIME_STOP) { + return; + } + + uint32_t dirty_cnt = 0; + while (dirty_cnt < DMA_RX_BUF_NUM) { + + if(emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 == EMAC_DESC_RX_OWN) { + break; + } + + dirty_cnt ++; + //copy data to lwip + emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2), + (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL); + + emac_clean_rx_desc(&(emac_config.dma_erx[emac_config.dirty_rx]),(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2)); + emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM; + } + emac_enable_rx_intr(); + emac_enable_rx_unavail_intr(); + emac_poll_rx_cmd(); +} + +#else +static void emac_process_rx_unavail(void) +{ + if(emac_config.emac_status == EMAC_RUNTIME_STOP) { + return; + } + + xSemaphoreTakeRecursive( emac_rx_xMutex, ( TickType_t ) portMAX_DELAY ); + + while (emac_config.cnt_rx < DMA_RX_BUF_NUM) { + + //copy data to lwip + emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2), + (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL); + emac_config.cnt_rx++; + if(emac_config.cnt_rx > DMA_RX_BUF_NUM) { + ESP_LOGE(TAG, "emac rx unavail buf err !!\n"); + } + emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM; + } + emac_enable_rx_intr(); + emac_enable_rx_unavail_intr(); + xSemaphoreGiveRecursive( emac_rx_xMutex ); +} + +static void emac_process_rx(void) +{ + if(emac_config.emac_status == EMAC_RUNTIME_STOP) { + return; + } + + uint32_t cur_rx_desc = emac_read_rx_cur_reg(); + + xSemaphoreTakeRecursive( emac_rx_xMutex, ( TickType_t ) portMAX_DELAY ); + + if(((uint32_t) &(emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc)) { + + while (((uint32_t) &(emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc) && emac_config.cnt_rx < DMA_RX_BUF_NUM ) { + //copy data to lwip + emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2), + (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL); + + emac_config.cnt_rx++; + + if(emac_config.cnt_rx > DMA_RX_BUF_NUM ) { + ESP_LOGE(TAG, "emac rx buf err!!\n"); + } + emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM; + + cur_rx_desc = emac_read_rx_cur_reg(); + } + } else { + if(emac_config.cnt_rx < DMA_RX_BUF_NUM) { + if((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0 & EMAC_DESC_RX_OWN) == 0) { + while (emac_config.cnt_rx < DMA_RX_BUF_NUM) { + + //copy data to lwip + emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2), + (((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL); + emac_config.cnt_rx++; + if(emac_config.cnt_rx > DMA_RX_BUF_NUM) { + ESP_LOGE(TAG,"emac rx buf err!!!\n"); + } + + emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM; + } + } + } + } + emac_enable_rx_intr(); + xSemaphoreGiveRecursive( emac_rx_xMutex ); +} +#endif + //TODO other events need to do something static void IRAM_ATTR emac_process_intr(void *arg) { @@ -294,38 +460,37 @@ static void IRAM_ATTR emac_process_intr(void *arg) //clr intrs REG_WRITE(EMAC_DMASTATUS_REG, event); - if (event & EMAC_RECV_BUF_UNAVAIL) { - emac_config.rx_need_poll = 1; - } else if (event & EMAC_TRANS_INT) { - emac_post(SIG_EMAC_TX_DONE, 0); - } else if (event & EMAC_RECV_INT) { + if (event & EMAC_RECV_INT) { + emac_disable_rx_intr(); emac_post(SIG_EMAC_RX_DONE, 0); - } else { - //other events + } + + if (event & EMAC_RECV_BUF_UNAVAIL) { + emac_disable_rx_unavail_intr(); + emac_post(SIG_EMAC_RX_UNAVAIL,0); + } + + if (event & EMAC_TRANS_INT) { + emac_post(SIG_EMAC_TX_DONE, 0); } } -static void emac_enable_intr() +static void emac_check_phy_init(void) { - //init emac intr - REG_SET_FIELD(DPORT_PRO_EMAC_INT_MAP_REG, DPORT_PRO_EMAC_INT_MAP, ETS_EMAC_INUM); - xt_set_interrupt_handler(ETS_EMAC_INUM, emac_process_intr, NULL); - xt_ints_on(1 << ETS_EMAC_INUM); + emac_config.emac_phy_check_init(); + if(emac_config.emac_phy_get_duplex_mode() == ETH_MDOE_FULLDUPLEX) { + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACDUPLEX); + } else { + REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACDUPLEX); + } + if(emac_config.emac_phy_get_speed_mode() == ETH_SPEED_MODE_100M) { + REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED); + } else { + REG_CLR_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACFESPEED); + } - REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, EMAC_INTR_ENABLE_BIT); + emac_mac_init(); } - -static void emac_disable_intr() -{ - xt_ints_off(1 << ETS_EMAC_INUM); - REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, 0); -} - -static bool emac_check_phy_link_status(void) -{ - return ((esp_eth_smi_read(1) & 0x4) == 0x4 ); -} - static void emac_process_link_updown(bool link_status) { system_event_t evt; @@ -333,10 +498,10 @@ static void emac_process_link_updown(bool link_status) emac_config.phy_link_up = link_status; if (link_status == true) { + emac_check_phy_init(); ESP_LOGI(TAG, "eth link_up!!!"); emac_enable_dma_tx(); emac_enable_dma_rx(); - ets_delay_us(200000); evt.event_id = SYSTEM_EVENT_ETH_CONNECTED; } else { ESP_LOGI(TAG, "eth link_down!!!"); @@ -358,26 +523,20 @@ static void emac_hw_init(void) //ipc TODO } -static esp_err_t emac_xmit(void *param) +esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size) { - struct emac_post_cmd *post_cmd = (struct emac_post_cmd *)param; - struct emac_tx_cmd *cmd = (struct emac_tx_cmd *)(post_cmd->cmd); esp_err_t ret = ESP_OK; - void *buf = cmd->buf; - uint16_t size = cmd->size; - if (emac_config.emac_status != EMAC_RUNTIME_START || emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) { ESP_LOGI(TAG, "tx netif close"); - cmd->err = ERR_IF; - ret = ESP_FAIL; + ret = ERR_IF; goto _exit; } - if (emac_config.cnt_tx == DMA_TX_BUF_NUM) { - ESP_LOGI(TAG, "tx buf full"); - cmd->err = ERR_MEM; - ret = ESP_FAIL; + xSemaphoreTakeRecursive( emac_tx_xMutex, ( TickType_t ) portMAX_DELAY ); + if (emac_config.cnt_tx == DMA_TX_BUF_NUM -1) { + ESP_LOGD(TAG, "tx buf full"); + ret = ERR_MEM; goto _exit; } @@ -392,26 +551,23 @@ static esp_err_t emac_xmit(void *param) _exit: - if (post_cmd->post_type == EMAC_POST_SYNC) { - xSemaphoreGive(emac_g_sem); - } - + xSemaphoreGiveRecursive( emac_tx_xMutex ); return ret; } static void emac_init_default_data(void) { - emac_config.rx_need_poll = 0; + memset((uint8_t *)&emac_config, 0,sizeof(struct emac_config_data)); } -void emac_link_check_func(void *pv_parameters) +void emac_process_link_check(void) { if (emac_config.emac_status != EMAC_RUNTIME_START || emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) { return; } - if (emac_check_phy_link_status() == true ) { + if (emac_config.emac_phy_check_link() == true ) { if (emac_config.phy_link_up == false) { emac_process_link_updown(true); } @@ -422,9 +578,14 @@ void emac_link_check_func(void *pv_parameters) } } +void emac_link_check_func(void *pv_parameters) +{ + emac_post(SIG_EMAC_CHECK_LINK,0); +} + static bool emac_link_check_timer_init(void) { - emac_timer = xTimerCreate("emac_timer", (1000 / portTICK_RATE_MS), + emac_timer = xTimerCreate("emac_timer", (2000 / portTICK_RATE_MS), pdTRUE, (void *)rand(), emac_link_check_func); if (emac_timer == NULL) { return false; @@ -475,18 +636,11 @@ static void emac_start(void *param) emac_set_tx_base_reg(); emac_set_rx_base_reg(); - emac_mac_init(); emac_config.phy_init(); - //for test - //emac_wait_linkup(); - - //mmc not support - //ptp TODO - //enable emac intr emac_enable_intr(); emac_config.emac_status = EMAC_RUNTIME_START; @@ -575,7 +729,7 @@ esp_err_t esp_eth_disable(void) return close_cmd.err; } - if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) { + if (emac_config.emac_status == EMAC_RUNTIME_START) { if (emac_ioctl(SIG_EMAC_STOP, (emac_par_t)(&post_cmd)) != 0) { close_cmd.err = EMAC_CMD_FAIL; } @@ -610,9 +764,6 @@ static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par) case SIG_EMAC_TX_DONE: emac_process_tx(); break; - case SIG_EMAC_TX: - emac_xmit((void *)par); - break; case SIG_EMAC_START: emac_start((void *)par); break; @@ -628,29 +779,6 @@ static esp_err_t emac_ioctl(emac_sig_t sig, emac_par_t par) return ret; } -esp_err_t esp_eth_tx(uint8_t *buf, uint16_t size) -{ - struct emac_post_cmd post_cmd; - struct emac_tx_cmd tx_cmd; - - post_cmd.cmd = (void *)(&tx_cmd); - - if (emac_check_phy_link_status() == false) { - emac_process_link_updown(false); - tx_cmd.err = ERR_IF; - } else { - tx_cmd.buf = buf; - tx_cmd.size = size; - tx_cmd.err = ERR_OK; - - if (emac_ioctl(SIG_EMAC_TX, (emac_par_t)(&post_cmd)) != 0) { - tx_cmd.err = ERR_MEM; - } - } - - return tx_cmd.err; -} - void emac_task(void *pv) { emac_event_t e; @@ -664,18 +792,21 @@ void emac_task(void *pv) case SIG_EMAC_RX_DONE: emac_process_rx(); break; + case SIG_EMAC_RX_UNAVAIL: + emac_process_rx_unavail(); + break; case SIG_EMAC_TX_DONE: emac_process_tx(); break; - case SIG_EMAC_TX: - emac_xmit((void *)e.par); - break; case SIG_EMAC_START: emac_start((void *)e.par); break; case SIG_EMAC_STOP: emac_stop((void *)e.par); break; + case SIG_EMAC_CHECK_LINK: + emac_process_link_check(); + break; default: ESP_LOGE(TAG, "unexpect sig %d", e.sig); break; @@ -686,27 +817,35 @@ void emac_task(void *pv) esp_err_t IRAM_ATTR emac_post(emac_sig_t sig, emac_par_t par) { - portENTER_CRITICAL(&g_emac_mux); + if(sig <= SIG_EMAC_RX_DONE) { + if (emac_sig_cnt[sig]) { + return ESP_OK; + } else { + emac_sig_cnt[sig]++; + emac_event_t evt; + signed portBASE_TYPE ret; + evt.sig = sig; + evt.par = par; + portBASE_TYPE tmp; - if (emac_sig_cnt[sig] && sig != SIG_EMAC_TX) { - portEXIT_CRITICAL(&g_emac_mux); - return ESP_OK; + ret = xQueueSendFromISR(emac_xqueue, &evt, &tmp); + + if(tmp != pdFALSE) { + portYIELD_FROM_ISR(); + } + + if(ret != pdPASS) { + return ESP_FAIL; + } + } } else { emac_sig_cnt[sig]++; - portEXIT_CRITICAL(&g_emac_mux); emac_event_t evt; evt.sig = sig; evt.par = par; - if (sig <= SIG_EMAC_RX_DONE) { - portBASE_TYPE tmp; - if (xQueueSendFromISR(emac_xqueue, &evt, &tmp) != pdPASS) { - return ESP_FAIL; - } - } else { - if (xQueueSend(emac_xqueue, &evt, 10 / portTICK_RATE_MS) != pdTRUE) { - return ESP_FAIL; - } + if (xQueueSend(emac_xqueue, &evt, 10 / portTICK_RATE_MS) != pdTRUE) { + return ESP_FAIL; } } @@ -739,7 +878,7 @@ esp_err_t esp_eth_init(eth_config_t *config) REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII); emac_dma_init(); - if (emac_config.mac_mode == EMAC_MODE_RMII) { + if (emac_config.mac_mode == ETH_MODE_RMII) { emac_set_clk_rmii(); } else { emac_set_clk_mii(); @@ -754,8 +893,12 @@ esp_err_t esp_eth_init(eth_config_t *config) //init task for emac emac_g_sem = xSemaphoreCreateBinary(); + emac_rx_xMutex = xSemaphoreCreateRecursiveMutex(); + emac_tx_xMutex = xSemaphoreCreateRecursiveMutex(); emac_xqueue = xQueueCreate(EMAC_EVT_QNUM, sizeof(emac_event_t)); - xTaskCreate(emac_task, "emacT", 2048 * 4, NULL, (19), &emac_task_hdl); + xTaskCreate(emac_task, "emacT", 2048, NULL, EMAC_TASK_PRIORITY, &emac_task_hdl); + + esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0, emac_process_intr, NULL, NULL); emac_reset(); emac_enable_clk(false); diff --git a/components/ethernet/include/esp_eth.h b/components/ethernet/include/esp_eth.h index b97289dd2b..2aae9d2024 100644 --- a/components/ethernet/include/esp_eth.h +++ b/components/ethernet/include/esp_eth.h @@ -22,15 +22,21 @@ extern "C" { #endif -typedef void (*eth_phy_fun)(void); -typedef esp_err_t (*eth_tcpip_input_fun)(void *buffer, uint16_t len, void *eb); -typedef void (*eth_gpio_config_func)(void); - typedef enum { ETH_MODE_RMII = 0, ETH_MDOE_MII, } eth_mode_t; +typedef enum { + ETH_SPEED_MODE_10M = 0, + ETH_SPEED_MODE_100M, +} eth_speed_mode_t; + +typedef enum { + ETH_MODE_HALFDUPLEX = 0, + ETH_MDOE_FULLDUPLEX, +} eth_duplex_mode_t; + typedef enum { PHY0 = 0, PHY1, @@ -66,6 +72,15 @@ typedef enum { PHY31, } eth_phy_base_t; +typedef bool (*eth_phy_check_link_func)(void); +typedef void (*eth_phy_check_init_func)(void); +typedef eth_speed_mode_t (*eth_phy_get_speed_mode_func)(void); +typedef eth_duplex_mode_t (*eth_phy_get_duplex_mode_func)(void); +typedef void (*eth_phy_func)(void); +typedef esp_err_t (*eth_tcpip_input_func)(void *buffer, uint16_t len, void *eb); +typedef void (*eth_gpio_config_func)(void); + + /** * @brief ethernet configuration * @@ -73,8 +88,12 @@ typedef enum { typedef struct { eth_phy_base_t phy_addr; /*!< phy base addr (0~31) */ eth_mode_t mac_mode; /*!< mac mode only support RMII now */ - eth_tcpip_input_fun tcpip_input; /*!< tcpip input func */ - eth_phy_fun phy_init; /*!< phy init func */ + eth_tcpip_input_func tcpip_input; /*!< tcpip input func */ + eth_phy_func phy_init; /*!< phy init func */ + eth_phy_check_link_func phy_check_link; /*!< phy check link func */ + eth_phy_check_init_func phy_check_init; /*!< phy check init func */ + eth_phy_get_speed_mode_func phy_get_speed_mode; /*!< phy check init func */ + eth_phy_get_duplex_mode_func phy_get_duplex_mode; /*!< phy check init func */ eth_gpio_config_func gpio_config; /*!< gpio config func */ } eth_config_t; @@ -159,6 +178,16 @@ void esp_eth_smi_write(uint32_t reg_num, uint16_t value); */ uint16_t esp_eth_smi_read(uint32_t reg_num); +/** + * @brief Free emac rx buf. + * + * @note buf can not be null,and it is tcpip input buf. + * + * @param[in] buf: start address of recevie packet data. + * + */ +void esp_eth_free_rx_buf(void *buf); + #ifdef __cplusplus } #endif diff --git a/components/freertos/Kconfig b/components/freertos/Kconfig index b9db00e50b..f03da6bc01 100644 --- a/components/freertos/Kconfig +++ b/components/freertos/Kconfig @@ -3,7 +3,7 @@ menu "FreeRTOS" # This is actually also handled in the ESP32 startup code, not only in FreeRTOS. config FREERTOS_UNICORE bool "Run FreeRTOS only on first core" - default n + default y help This version of FreeRTOS normally takes control of all cores of the CPU. Select this if you only want to start it on the first core. diff --git a/components/freertos/heap_regions.c b/components/freertos/heap_regions.c index 1abcdf3c6f..5cece756c0 100644 --- a/components/freertos/heap_regions.c +++ b/components/freertos/heap_regions.c @@ -10,12 +10,12 @@ the terms of the GNU General Public License (version 2) as published by the Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - *************************************************************************** + *************************************************************************** >>! NOTE: The modification to the GPL is included to allow you to !<< >>! distribute a combined work that includes FreeRTOS without being !<< >>! obliged to provide the source code for proprietary components !<< >>! outside of the FreeRTOS kernel. !<< - *************************************************************************** + *************************************************************************** FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS @@ -37,17 +37,17 @@ *************************************************************************** http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading - the FAQ page "My application does not run, what could be wrong?". Have you - defined configASSERT()? + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? - http://www.FreeRTOS.org/support - In return for receiving this top quality - embedded software for free we request you assist our global community by - participating in the support forum. + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. - http://www.FreeRTOS.org/training - Investing in training allows your team to - be as productive as possible as early as possible. Now you can receive - FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers - Ltd, and the world's leading authority on the world's leading RTOS. + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, including FreeRTOS+Trace - an indispensable productivity tool, a DOS @@ -85,9 +85,9 @@ * * typedef struct HeapRegion * { - * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. - * size_t xSizeInBytes; << Size of the block of memory. - * BaseType_t xTag; << Tag + * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. + * size_t xSizeInBytes; << Size of the block of memory. + * BaseType_t xTag; << Tag * } HeapRegionTagged_t; * * 'Tag' allows you to allocate memory of a certain type. Tag -1 is special; @@ -101,9 +101,9 @@ * * HeapRegionTagged_t xHeapRegions[] = * { - * { ( uint8_t * ) 0x80000000UL, 0x10000, 1 }, << Defines a block of 0x10000 bytes starting at address 0x80000000, tag 1 - * { ( uint8_t * ) 0x90000000UL, 0xa0000, 2 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000, tag 2 - * { NULL, 0, 0 } << Terminates the array. + * { ( uint8_t * ) 0x80000000UL, 0x10000, 1 }, << Defines a block of 0x10000 bytes starting at address 0x80000000, tag 1 + * { ( uint8_t * ) 0x90000000UL, 0xa0000, 2 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000, tag 2 + * { NULL, 0, 0 } << Terminates the array. * }; * * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). @@ -141,18 +141,21 @@ task.h is included from an application file. */ #include "rom/ets_sys.h" /* Block sizes must not get too small. */ -#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( uxHeapStructSize << 1 ) ) +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( uxHeapStructSize << 1 ) ) /* Assumes 8bit bytes! */ -#define heapBITS_PER_BYTE ( ( size_t ) 8 ) +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) /* Define the linked list structure. This is used to link free blocks in order -of their memory address. */ + of their memory address. This is optimized for size of the linked list struct + and assumes a region is never larger than 16MiB. */ +#define HEAPREGIONS_MAX_REGIONSIZE (16*1024*1024) typedef struct A_BLOCK_LINK { - struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ - size_t xBlockSize; /*<< The size of the free block. */ - BaseType_t xTag; /*<< Tag of this region */ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + int xBlockSize: 24; /*<< The size of the free block. */ + int xTag: 7; /*<< Tag of this region */ + int xAllocated: 1; /*<< 1 if allocated */ } BlockLink_t; //Mux to protect the memory status data @@ -171,22 +174,17 @@ static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); /*-----------------------------------------------------------*/ /* The size of the structure placed at the beginning of each allocated memory -block must by correctly byte aligned. */ -static const uint32_t uxHeapStructSize = ( ( sizeof ( BlockLink_t ) + BLOCK_HEAD_LEN + BLOCK_TAIL_LEN + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); +block must be correctly byte aligned. */ +static const uint32_t uxHeapStructSize = ( ( sizeof ( BlockLink_t ) + BLOCK_HEAD_LEN + BLOCK_TAIL_LEN + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); /* Create a couple of list links to mark the start and end of the list. */ static BlockLink_t xStart, *pxEnd = NULL; /* Keeps track of the number of free bytes remaining, but says nothing about fragmentation. */ -static size_t xFreeBytesRemaining = 0; -static size_t xMinimumEverFreeBytesRemaining = 0; +static size_t xFreeBytesRemaining[HEAPREGIONS_MAX_TAGCOUNT] = {0}; +static size_t xMinimumEverFreeBytesRemaining[HEAPREGIONS_MAX_TAGCOUNT] = {0}; -/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize -member of an BlockLink_t structure is set then the block belongs to the -application. When the bit is free the block is still part of the free heap -space. */ -static size_t xBlockAllocatedBit = 0; /*-----------------------------------------------------------*/ @@ -195,178 +193,167 @@ void *pvPortMallocTagged( size_t xWantedSize, BaseType_t tag ) BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; void *pvReturn = NULL; - /* The heap must be initialised before the first call to - prvPortMalloc(). */ - configASSERT( pxEnd ); + /* The heap must be initialised before the first call to + prvPortMalloc(). */ + configASSERT( pxEnd ); - taskENTER_CRITICAL(&xMallocMutex); - { - /* Check the requested block size is not so large that the top bit is - set. The top bit of the block size member of the BlockLink_t structure - is used to determine who owns the block - the application or the - kernel, so it must be free. */ - if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) - { - /* The wanted size is increased so it can contain a BlockLink_t - structure in addition to the requested amount of bytes. */ - if( xWantedSize > 0 ) - { - xWantedSize += uxHeapStructSize; + taskENTER_CRITICAL(&xMallocMutex); + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += uxHeapStructSize; - /* Ensure that blocks are always aligned to the required number - of bytes. */ - if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) - { - /* Byte alignment required. */ - xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } - if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) - { - /* Traverse the list from the start (lowest address) block until - one of adequate size is found. */ - pxPreviousBlock = &xStart; - pxBlock = xStart.pxNextFreeBlock; - while( ( ( pxBlock->xTag != tag ) || ( pxBlock->xBlockSize < xWantedSize ) ) && ( pxBlock->pxNextFreeBlock != NULL ) ) - { -// ets_printf("Block %x -> %x\n", (uint32_t)pxBlock, (uint32_t)pxBlock->pxNextFreeBlock); + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining[ tag ] ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( ( pxBlock->xTag != tag ) || ( pxBlock->xBlockSize < xWantedSize ) ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { +// ets_printf("Block %x -> %x\n", (uint32_t)pxBlock, (uint32_t)pxBlock->pxNextFreeBlock); - #if (configENABLE_MEMORY_DEBUG == 1) - { - mem_check_block(pxBlock); - } - #endif + #if (configENABLE_MEMORY_DEBUG == 1) + { + mem_check_block(pxBlock); + } + #endif - pxPreviousBlock = pxBlock; - pxBlock = pxBlock->pxNextFreeBlock; - } + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } - /* If the end marker was not reached then a block of adequate size - was found. */ - if( pxBlock != pxEnd ) - { - /* Return the memory space pointed to - jumping over the - BlockLink_t structure at its start. */ - pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + uxHeapStructSize - BLOCK_TAIL_LEN - BLOCK_HEAD_LEN); + /* If the end marker was not reached then a block of adequate size + was found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + uxHeapStructSize - BLOCK_TAIL_LEN - BLOCK_HEAD_LEN); - /* This block is being returned for use so must be taken out - of the list of free blocks. */ - pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; - /* If the block is larger than required it can be split into - two. */ + /* If the block is larger than required it can be split into + two. */ - if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) - { - /* This block is to be split into two. Create a new - block following the number of bytes requested. The void - cast is used to prevent byte alignment warnings from the - compiler. */ - pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize); + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize); - /* Calculate the sizes of two blocks split from the - single block. */ - pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; - pxNewBlockLink->xTag = tag; - pxBlock->xBlockSize = xWantedSize; + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxNewBlockLink->xTag = tag; + pxBlock->xBlockSize = xWantedSize; - #if (configENABLE_MEMORY_DEBUG == 1) - { - mem_init_dog(pxNewBlockLink); - } - #endif + #if (configENABLE_MEMORY_DEBUG == 1) + { + mem_init_dog(pxNewBlockLink); + } + #endif - /* Insert the new block into the list of free blocks. */ - prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } - xFreeBytesRemaining -= pxBlock->xBlockSize; + xFreeBytesRemaining[ tag ] -= pxBlock->xBlockSize; - if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) - { - xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + if( xFreeBytesRemaining[ tag ] < xMinimumEverFreeBytesRemaining[ tag ] ) + { + xMinimumEverFreeBytesRemaining[ tag ] = xFreeBytesRemaining[ tag ]; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } - /* The block is being returned - it is allocated and owned - by the application and has no "next" block. */ - pxBlock->xBlockSize |= xBlockAllocatedBit; - pxBlock->pxNextFreeBlock = NULL; + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xAllocated = 1; + pxBlock->pxNextFreeBlock = NULL; - #if (configENABLE_MEMORY_DEBUG == 1) - { - mem_init_dog(pxBlock); - mem_malloc_block(pxBlock); - } - #endif - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + #if (configENABLE_MEMORY_DEBUG == 1) + { + mem_init_dog(pxBlock); + mem_malloc_block(pxBlock); + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } - traceMALLOC( pvReturn, xWantedSize ); - } - taskEXIT_CRITICAL(&xMallocMutex); + traceMALLOC( pvReturn, xWantedSize ); + } + taskEXIT_CRITICAL(&xMallocMutex); - #if( configUSE_MALLOC_FAILED_HOOK == 1 ) - { - if( pvReturn == NULL ) - { - extern void vApplicationMallocFailedHook( void ); - vApplicationMallocFailedHook(); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - #endif + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif - return pvReturn; + return pvReturn; } /*-----------------------------------------------------------*/ -void vPortFree( void *pv ) +void vPortFreeTagged( void *pv ) { uint8_t *puc = ( uint8_t * ) pv; BlockLink_t *pxLink; - if( pv != NULL ) - { - /* The memory being freed will have an BlockLink_t structure immediately - before it. */ - puc -= (uxHeapStructSize - BLOCK_TAIL_LEN - BLOCK_HEAD_LEN) ; + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= (uxHeapStructSize - BLOCK_TAIL_LEN - BLOCK_HEAD_LEN) ; - /* This casting is to keep the compiler from issuing warnings. */ - pxLink = ( void * ) puc; + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; #if (configENABLE_MEMORY_DEBUG == 1) { @@ -377,49 +364,49 @@ BlockLink_t *pxLink; } #endif - /* Check the block is actually allocated. */ - configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); - configASSERT( pxLink->pxNextFreeBlock == NULL ); + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xAllocated ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); - if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) - { - if( pxLink->pxNextFreeBlock == NULL ) - { - /* The block is being returned to the heap - it is no longer - allocated. */ - pxLink->xBlockSize &= ~xBlockAllocatedBit; + if( pxLink->xAllocated != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xAllocated = 0; - taskENTER_CRITICAL(&xMallocMutex); - { - /* Add this block to the list of free blocks. */ - xFreeBytesRemaining += pxLink->xBlockSize; - traceFREE( pv, pxLink->xBlockSize ); - prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); - } - taskEXIT_CRITICAL(&xMallocMutex); - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } + taskENTER_CRITICAL(&xMallocMutex); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining[ pxLink->xTag ] += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + taskEXIT_CRITICAL(&xMallocMutex); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } } /*-----------------------------------------------------------*/ -size_t xPortGetFreeHeapSize( void ) +size_t xPortGetFreeHeapSizeTagged( BaseType_t tag ) { - return xFreeBytesRemaining; + return xFreeBytesRemaining[ tag ]; } /*-----------------------------------------------------------*/ -size_t xPortGetMinimumEverFreeHeapSize( void ) +size_t xPortGetMinimumEverFreeHeapSizeTagged( BaseType_t tag ) { - return xMinimumEverFreeBytesRemaining; + return xMinimumEverFreeBytesRemaining[ tag ]; } /*-----------------------------------------------------------*/ @@ -428,59 +415,59 @@ static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) BlockLink_t *pxIterator; uint8_t *puc; - /* Iterate through the list until a block is found that has a higher address - than the block being inserted. */ - for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) - { - /* Nothing to do here, just iterate to the right position. */ - } + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } - /* Do the block being inserted, and the block it is being inserted after - make a contiguous block of memory, and are the tags the same? */ - puc = ( uint8_t * ) pxIterator; - if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert && pxBlockToInsert->xTag==pxIterator->xTag) - { - pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; - pxBlockToInsert = pxIterator; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory, and are the tags the same? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert && pxBlockToInsert->xTag==pxIterator->xTag) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } - /* Do the block being inserted, and the block it is being inserted before - make a contiguous block of memory, and are the tags the same */ - puc = ( uint8_t * ) pxBlockToInsert; - if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock && pxBlockToInsert->xTag==pxIterator->pxNextFreeBlock->xTag ) - { - if( pxIterator->pxNextFreeBlock != pxEnd ) - { - /* Form one big block from the two blocks. */ - pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxEnd; - } - } - else - { - pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; - } + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory, and are the tags the same */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock && pxBlockToInsert->xTag==pxIterator->pxNextFreeBlock->xTag ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } - /* If the block being inserted plugged a gap, so was merged with the block - before and the block after, then it's pxNextFreeBlock pointer will have - already been set, and should not be set here as that would make it point - to itself. */ - if( pxIterator != pxBlockToInsert ) - { - pxIterator->pxNextFreeBlock = pxBlockToInsert; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } + /* If the block being inserted plugged a gap, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } /*-----------------------------------------------------------*/ @@ -493,90 +480,94 @@ BaseType_t xDefinedRegions = 0, xRegIdx = 0; uint32_t ulAddress; const HeapRegionTagged_t *pxHeapRegion; - /* Can only call once! */ - configASSERT( pxEnd == NULL ); + /* Can only call once! */ + configASSERT( pxEnd == NULL ); - vPortCPUInitializeMutex(&xMallocMutex); + vPortCPUInitializeMutex(&xMallocMutex); - pxHeapRegion = &( pxHeapRegions[ xRegIdx ] ); + pxHeapRegion = &( pxHeapRegions[ xRegIdx ] ); - while( pxHeapRegion->xSizeInBytes > 0 ) - { - if ( pxHeapRegion->xTag == -1 ) { - /* Move onto the next HeapRegionTagged_t structure. */ - xRegIdx++; - pxHeapRegion = &( pxHeapRegions[ xRegIdx ] ); - continue; - } + while( pxHeapRegion->xSizeInBytes > 0 ) + { + if ( pxHeapRegion->xTag == -1 ) { + /* Move onto the next HeapRegionTagged_t structure. */ + xRegIdx++; + pxHeapRegion = &( pxHeapRegions[ xRegIdx ] ); + continue; + } - xTotalRegionSize = pxHeapRegion->xSizeInBytes; + configASSERT(pxHeapRegion->xTag < HEAPREGIONS_MAX_TAGCOUNT); + configASSERT(pxHeapRegion->xSizeInBytes < HEAPREGIONS_MAX_REGIONSIZE); + xTotalRegionSize = pxHeapRegion->xSizeInBytes; - /* Ensure the heap region starts on a correctly aligned boundary. */ - ulAddress = ( uint32_t ) pxHeapRegion->pucStartAddress; - if( ( ulAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) - { - ulAddress += ( portBYTE_ALIGNMENT - 1 ); - ulAddress &= ~portBYTE_ALIGNMENT_MASK; + /* Ensure the heap region starts on a correctly aligned boundary. */ + ulAddress = ( uint32_t ) pxHeapRegion->pucStartAddress; + if( ( ulAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + ulAddress += ( portBYTE_ALIGNMENT - 1 ); + ulAddress &= ~portBYTE_ALIGNMENT_MASK; - /* Adjust the size for the bytes lost to alignment. */ - xTotalRegionSize -= ulAddress - ( uint32_t ) pxHeapRegion->pucStartAddress; - } + /* Adjust the size for the bytes lost to alignment. */ + xTotalRegionSize -= ulAddress - ( uint32_t ) pxHeapRegion->pucStartAddress; + } - pucAlignedHeap = ( uint8_t * ) ulAddress; + pucAlignedHeap = ( uint8_t * ) ulAddress; - /* Set xStart if it has not already been set. */ - if( xDefinedRegions == 0 ) - { - /* xStart is used to hold a pointer to the first item in the list of - free blocks. The void cast is used to prevent compiler warnings. */ - xStart.pxNextFreeBlock = ( BlockLink_t * ) (pucAlignedHeap + BLOCK_HEAD_LEN); - xStart.xBlockSize = ( size_t ) 0; - } - else - { - /* Should only get here if one region has already been added to the - heap. */ - configASSERT( pxEnd != NULL ); + /* Set xStart if it has not already been set. */ + if( xDefinedRegions == 0 ) + { + /* xStart is used to hold a pointer to the first item in the list of + free blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( BlockLink_t * ) (pucAlignedHeap + BLOCK_HEAD_LEN); + xStart.xBlockSize = ( size_t ) 0; + } + else + { + /* Should only get here if one region has already been added to the + heap. */ + configASSERT( pxEnd != NULL ); - /* Check blocks are passed in with increasing start addresses. */ - configASSERT( ulAddress > ( uint32_t ) pxEnd ); - } + /* Check blocks are passed in with increasing start addresses. */ + configASSERT( ulAddress > ( uint32_t ) pxEnd ); + } - /* Remember the location of the end marker in the previous region, if - any. */ - pxPreviousFreeBlock = pxEnd; + /* Remember the location of the end marker in the previous region, if + any. */ + pxPreviousFreeBlock = pxEnd; - /* pxEnd is used to mark the end of the list of free blocks and is - inserted at the end of the region space. */ - ulAddress = ( ( uint32_t ) pucAlignedHeap ) + xTotalRegionSize; - ulAddress -= uxHeapStructSize; - ulAddress &= ~portBYTE_ALIGNMENT_MASK; - pxEnd = ( BlockLink_t * ) (ulAddress + BLOCK_HEAD_LEN); - pxEnd->xBlockSize = 0; - pxEnd->pxNextFreeBlock = NULL; - pxEnd->xTag = -1; + /* pxEnd is used to mark the end of the list of free blocks and is + inserted at the end of the region space. */ + ulAddress = ( ( uint32_t ) pucAlignedHeap ) + xTotalRegionSize; + ulAddress -= uxHeapStructSize; + ulAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = ( BlockLink_t * ) (ulAddress + BLOCK_HEAD_LEN); + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + pxEnd->xTag = -1; - /* To start with there is a single free block in this region that is - sized to take up the entire heap region minus the space taken by the - free block structure. */ - pxFirstFreeBlockInRegion = ( BlockLink_t * ) (pucAlignedHeap + BLOCK_HEAD_LEN); - pxFirstFreeBlockInRegion->xBlockSize = ulAddress - ( uint32_t ) pxFirstFreeBlockInRegion + BLOCK_HEAD_LEN; - pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; - pxFirstFreeBlockInRegion->xTag=pxHeapRegion->xTag; + /* To start with there is a single free block in this region that is + sized to take up the entire heap region minus the space taken by the + free block structure. */ + pxFirstFreeBlockInRegion = ( BlockLink_t * ) (pucAlignedHeap + BLOCK_HEAD_LEN); + pxFirstFreeBlockInRegion->xBlockSize = ulAddress - ( uint32_t ) pxFirstFreeBlockInRegion + BLOCK_HEAD_LEN; + pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; + pxFirstFreeBlockInRegion->xTag=pxHeapRegion->xTag; - /* If this is not the first region that makes up the entire heap space - then link the previous region to this region. */ - if( pxPreviousFreeBlock != NULL ) - { - pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; - } + /* If this is not the first region that makes up the entire heap space + then link the previous region to this region. */ + if( pxPreviousFreeBlock != NULL ) + { + pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; + } - xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + xMinimumEverFreeBytesRemaining[ pxHeapRegion->xTag ] += pxFirstFreeBlockInRegion->xBlockSize; + xFreeBytesRemaining[ pxHeapRegion->xTag ] += pxFirstFreeBlockInRegion->xBlockSize; - /* Move onto the next HeapRegionTagged_t structure. */ - xDefinedRegions++; - xRegIdx++; - pxHeapRegion = &( pxHeapRegions[ xRegIdx ] ); + /* Move onto the next HeapRegionTagged_t structure. */ + xDefinedRegions++; + xRegIdx++; + pxHeapRegion = &( pxHeapRegions[ xRegIdx ] ); #if (configENABLE_MEMORY_DEBUG == 1) { @@ -584,20 +575,15 @@ const HeapRegionTagged_t *pxHeapRegion; mem_init_dog(pxEnd); } #endif - } + } - xMinimumEverFreeBytesRemaining = xTotalHeapSize; - xFreeBytesRemaining = xTotalHeapSize; + /* Check something was actually defined before it is accessed. */ + configASSERT( xTotalHeapSize ); - /* Check something was actually defined before it is accessed. */ - configASSERT( xTotalHeapSize ); - - /* Work out the position of the top bit in a size_t variable. */ - xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); #if (configENABLE_MEMORY_DEBUG == 1) { - mem_debug_init(uxHeapStructSize, &xStart, pxEnd, &xMallocMutex, xBlockAllocatedBit); + mem_debug_init(uxHeapStructSize, &xStart, pxEnd, &xMallocMutex); mem_check_all(0); } #endif diff --git a/components/freertos/heap_regions_debug.c b/components/freertos/heap_regions_debug.c index d8d444a537..f221e516b0 100644 --- a/components/freertos/heap_regions_debug.c +++ b/components/freertos/heap_regions_debug.c @@ -12,19 +12,17 @@ static size_t g_heap_struct_size; static mem_dbg_ctl_t g_mem_dbg; char g_mem_print = 0; static portMUX_TYPE *g_malloc_mutex = NULL; -static unsigned int g_alloc_bit; #define MEM_DEBUG(...) -void mem_debug_init(size_t size, void *start, void *end, portMUX_TYPE *mutex, unsigned int alloc_bit) +void mem_debug_init(size_t size, void *start, void *end, portMUX_TYPE *mutex) { - MEM_DEBUG("size=%d start=%p end=%p mutex=%p alloc_bit=0x%x\n", size, start, end, mutex, alloc_bit); + MEM_DEBUG("size=%d start=%p end=%p mutex=%p%x\n", size, start, end, mutex); memset(&g_mem_dbg, 0, sizeof(g_mem_dbg)); memset(&g_malloc_list, 0, sizeof(g_malloc_list)); g_malloc_mutex = mutex; g_heap_struct_size = size; g_free_list = start; g_end = end; - g_alloc_bit = alloc_bit; } void mem_debug_push(char type, void *addr) @@ -35,9 +33,9 @@ void mem_debug_push(char type, void *addr) MEM_DEBUG("push type=%d addr=%p\n", type, addr); if (g_mem_print){ if (type == DEBUG_TYPE_MALLOC){ - ets_printf("task=%s t=%s s=%u a=%p\n", debug_b->head.task?debug_b->head.task:"", type==DEBUG_TYPE_MALLOC?"m":"f", b->size&(~g_alloc_bit), addr); + ets_printf("task=%s t=%s s=%u a=%p\n", debug_b->head.task?debug_b->head.task:"", type==DEBUG_TYPE_MALLOC?"m":"f", b->size, addr); } else { - ets_printf("task=%s t=%s s=%u a=%p\n", debug_b->head.task?debug_b->head.task:"", type==DEBUG_TYPE_MALLOC?"m":"f", b->size&(~g_alloc_bit), addr); + ets_printf("task=%s t=%s s=%u a=%p\n", debug_b->head.task?debug_b->head.task:"", type==DEBUG_TYPE_MALLOC?"m":"f", b->size, addr); } } else { mem_dbg_info_t *info = &g_mem_dbg.info[g_mem_dbg.cnt%DEBUG_MAX_INFO_NUM]; @@ -58,7 +56,7 @@ void mem_debug_malloc_show(void) while (b){ d = DEBUG_BLOCK(b); d->head.task[3] = '\0'; - ets_printf("t=%s s=%u a=%p\n", d->head.task?d->head.task:"", b->size&(~g_alloc_bit), b); + ets_printf("t=%s s=%u a=%p\n", d->head.task?d->head.task:"", b->size, b); b = b->next; } taskEXIT_CRITICAL(g_malloc_mutex); @@ -140,7 +138,7 @@ void mem_malloc_show(void) while (b){ debug_b = DEBUG_BLOCK(b); - ets_printf("%s %p %p %u\n", debug_b->head.task, debug_b, b, b->size&(~g_alloc_bit)); + ets_printf("%s %p %p %u\n", debug_b->head.task, debug_b, b, b->size); b = b->next; } } @@ -149,7 +147,7 @@ void mem_malloc_block(void *data) { os_block_t *b = (os_block_t*)data; - MEM_DEBUG("mem malloc block data=%p, size=%u\n", data, b->size&(~g_alloc_bit)); + MEM_DEBUG("mem malloc block data=%p, size=%u\n", data, b->size); mem_debug_push(DEBUG_TYPE_MALLOC, data); if (b){ @@ -165,7 +163,7 @@ void mem_free_block(void *data) os_block_t *pre = &g_malloc_list; debug_block_t *debug_b; - MEM_DEBUG("mem free block data=%p, size=%d\n", data, del->size&(~g_alloc_bit)); + MEM_DEBUG("mem free block data=%p, size=%d\n", data, del->size); mem_debug_push(DEBUG_TYPE_FREE, data); if (!del) { @@ -183,7 +181,7 @@ void mem_free_block(void *data) } debug_b = DEBUG_BLOCK(del); - ets_printf("%s %p %p %u already free\n", debug_b->head.task, debug_b, del, del->size&(~g_alloc_bit)); + ets_printf("%s %p %p %u already free\n", debug_b->head.task, debug_b, del, del->size); mem_malloc_show(); abort(); } diff --git a/components/freertos/include/freertos/heap_regions.h b/components/freertos/include/freertos/heap_regions.h index aedea42a16..090c5b9b36 100644 --- a/components/freertos/include/freertos/heap_regions.h +++ b/components/freertos/include/freertos/heap_regions.h @@ -16,19 +16,81 @@ #include "freertos/FreeRTOS.h" +/* The maximum amount of tags in use */ +#define HEAPREGIONS_MAX_TAGCOUNT 16 +/** + * @brief Structure to define a memory region + */ typedef struct HeapRegionTagged { - uint8_t *pucStartAddress; - size_t xSizeInBytes; - BaseType_t xTag; - uint32_t xExecAddr; + uint8_t *pucStartAddress; ///< Start address of the region + size_t xSizeInBytes; ///< Size of the region + BaseType_t xTag; ///< Tag for the region + uint32_t xExecAddr; ///< If non-zero, indicates the region also has an alias in IRAM. } HeapRegionTagged_t; +/** + * @brief Initialize the heap allocator by feeding it the usable memory regions and their tags. + * + * This takes an array of heapRegionTagged_t structs, the last entry of which is a dummy entry + * which has pucStartAddress set to NULL. It will initialize the heap allocator to serve memory + * from these ranges. + * + * @param pxHeapRegions Array of region definitions + */ void vPortDefineHeapRegionsTagged( const HeapRegionTagged_t * const pxHeapRegions ); + + +/** + * @brief Allocate memory from a region with a certain tag + * + * Like pvPortMalloc, this returns an allocated chunk of memory. This function, + * however, forces the allocator to allocate from a region specified by a + * specific tag. + * + * @param xWantedSize Size needed, in bytes + * @param tag Tag of the memory region the allocation has to be from + * + * @return Pointer to allocated memory if succesful. + * NULL if unsuccesful. + */ void *pvPortMallocTagged( size_t xWantedSize, BaseType_t tag ); +/** + * @brief Free memory allocated with pvPortMallocTagged + * + * This is basically an implementation of free(). + * + * @param pv Pointer to region allocated by pvPortMallocTagged + */ +void vPortFreeTagged( void *pv ); + +/** + * @brief Get the lowest amount of memory free for a certain tag + * + * This function allows the user to see what the least amount of + * free memory for a certain tag is. + * + * @param tag Tag of the memory region + * + * @return Minimum amount of free bytes available in the runtime of + * the program + */ +size_t xPortGetMinimumEverFreeHeapSizeTagged( BaseType_t tag ); + +/** + * @brief Get the amount of free bytes in a certain tagged region + * + * Works like xPortGetFreeHeapSize but allows the user to specify + * a specific tag + * + * @param tag Tag of the memory region + * + * @return Remaining amount of free bytes in region + */ +size_t xPortGetFreeHeapSizeTagged( BaseType_t tag ); #endif \ No newline at end of file diff --git a/components/freertos/include/freertos/heap_regions_debug.h b/components/freertos/include/freertos/heap_regions_debug.h index 81bf1d6c3b..dca9531d7e 100644 --- a/components/freertos/include/freertos/heap_regions_debug.h +++ b/components/freertos/include/freertos/heap_regions_debug.h @@ -22,9 +22,10 @@ typedef struct { /* Please keep this definition same as BlockLink_t */ typedef struct _os_block_t { - struct _os_block_t *next; - size_t size; - unsigned int xtag; + struct _os_block_t *next; /*<< The next free block in the list. */ + int size: 24; /*<< The size of the free block. */ + int xtag: 7; /*<< Tag of this region */ + int xAllocated: 1; /*<< 1 if allocated */ }os_block_t; typedef struct { @@ -50,7 +51,7 @@ typedef struct _mem_dbg_ctl{ #define OS_BLOCK(_b) ((os_block_t*)((debug_block_t*)((char*)(_b) + BLOCK_HEAD_LEN))) #define DEBUG_BLOCK(_b) ((debug_block_t*)((char*)(_b) - BLOCK_HEAD_LEN)) #define HEAD_DOG(_b) ((_b)->head.dog) -#define TAIL_DOG(_b) (*(unsigned int*)((char*)(_b) + (((_b)->os_block.size & (~g_alloc_bit) ) - BLOCK_TAIL_LEN))) +#define TAIL_DOG(_b) (*(unsigned int*)((char*)(_b) + (((_b)->os_block.size ) - BLOCK_TAIL_LEN))) #define DOG_ASSERT()\ {\ @@ -60,7 +61,7 @@ typedef struct _mem_dbg_ctl{ extern void mem_check_block(void * data); extern void mem_init_dog(void *data); -extern void mem_debug_init(size_t size, void *start, void *end, portMUX_TYPE *mutex, unsigned int alloc_bit); +extern void mem_debug_init(size_t size, void *start, void *end, portMUX_TYPE *mutex); extern void mem_malloc_block(void *data); extern void mem_free_block(void *data); extern void mem_check_all(void* pv); diff --git a/components/freertos/ringbuf.c b/components/freertos/ringbuf.c index 7074eb537d..e49b8e5ef4 100644 --- a/components/freertos/ringbuf.c +++ b/components/freertos/ringbuf.c @@ -600,7 +600,7 @@ void *xRingbufferReceiveUpToFromISR(RingbufHandle_t ringbuf, size_t *item_size, configASSERT(rb); configASSERT(rb->flags & flag_bytebuf); portENTER_CRITICAL_ISR(&rb->mux); - itemData=rb->getItemFromRingbufImpl(rb, item_size, 0); + itemData=rb->getItemFromRingbufImpl(rb, item_size, wanted_size); portEXIT_CRITICAL_ISR(&rb->mux); return (void*)itemData; } diff --git a/components/freertos/test/test_tls_deletecb.c b/components/freertos/test/test_tls_deletecb.c index 5277b761ab..8628f42ec9 100644 --- a/components/freertos/test/test_tls_deletecb.c +++ b/components/freertos/test/test_tls_deletecb.c @@ -16,7 +16,7 @@ static void tskdelcb(int no, void *arg) { - printf("Delete callback: %d = %p!\n", no, arg); + ets_printf("Delete callback: %d = %p!\n", no, arg); } diff --git a/components/freertos/xtensa_intr.c b/components/freertos/xtensa_intr.c index e9c0b79b96..4767032277 100644 --- a/components/freertos/xtensa_intr.c +++ b/components/freertos/xtensa_intr.c @@ -39,7 +39,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if XCHAL_HAVE_EXCEPTIONS /* Handler table is in xtensa_intr_asm.S */ -// Todo: Make multicore - JD extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM*portNUM_PROCESSORS]; @@ -101,8 +100,7 @@ extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS*portNUM_P */ void xt_unhandled_interrupt(void * arg) { - ets_printf("Unhandled interrupt!\n"); - //exit(-1); + ets_printf("Unhandled interrupt %d on cpu %d!\n", (int)arg, xPortGetCoreID()); } diff --git a/components/freertos/xtensa_intr_asm.S b/components/freertos/xtensa_intr_asm.S index 8c7ae63fdb..f2d236108d 100644 --- a/components/freertos/xtensa_intr_asm.S +++ b/components/freertos/xtensa_intr_asm.S @@ -40,6 +40,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------- */ + +#if XT_USE_SWPRI +/* Warning - this is not multicore-compatible. */ .data .global _xt_intdata .align 8 @@ -53,7 +56,7 @@ _xt_intdata: _xt_intenable: .word 0 /* Virtual INTENABLE */ _xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */ - +#endif /* ------------------------------------------------------------------------------- @@ -124,7 +127,8 @@ _xt_exception_table: unsigned int xt_ints_on ( unsigned int mask ) Enables a set of interrupts. Does not simply set INTENABLE directly, but - computes it as a function of the current virtual priority. + computes it as a function of the current virtual priority if XT_USE_SWPRI is + enabled. Can be called from interrupt handlers. ------------------------------------------------------------------------------- */ @@ -137,7 +141,9 @@ _xt_exception_table: xt_ints_on: ENTRY0 + #if XCHAL_HAVE_INTERRUPTS +#if XT_USE_SWPRI movi a3, 0 movi a4, _xt_intdata xsr a3, INTENABLE /* Disables all interrupts */ @@ -149,6 +155,15 @@ xt_ints_on: and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */ wsr a5, INTENABLE /* Reenable interrupts */ mov a2, a3 /* Previous mask */ +#else + movi a3, 0 + xsr a3, INTENABLE /* Disables all interrupts */ + rsync + or a2, a3, a2 /* set bits in mask */ + wsr a2, INTENABLE /* Re-enable ints */ + rsync + mov a2, a3 /* return prev mask */ +#endif #else movi a2, 0 /* Return zero */ #endif @@ -162,7 +177,8 @@ xt_ints_on: unsigned int xt_ints_off ( unsigned int mask ) Disables a set of interrupts. Does not simply set INTENABLE directly, - but computes it as a function of the current virtual priority. + but computes it as a function of the current virtual priority if XT_USE_SWPRI is + enabled. Can be called from interrupt handlers. ------------------------------------------------------------------------------- */ @@ -176,6 +192,7 @@ xt_ints_off: ENTRY0 #if XCHAL_HAVE_INTERRUPTS +#if XT_USE_SWPRI movi a3, 0 movi a4, _xt_intdata xsr a3, INTENABLE /* Disables all interrupts */ @@ -188,6 +205,16 @@ xt_ints_off: and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */ wsr a5, INTENABLE /* Reenable interrupts */ mov a2, a3 /* Previous mask */ +#else + movi a4, 0 + xsr a4, INTENABLE /* Disables all interrupts */ + rsync + or a3, a4, a2 /* set bits in mask */ + xor a3, a3, a2 /* invert bits in mask set in mask, essentially clearing them */ + wsr a3, INTENABLE /* Re-enable ints */ + rsync + mov a2, a4 /* return prev mask */ +#endif #else movi a2, 0 /* return zero */ #endif diff --git a/components/freertos/xtensa_vectors.S b/components/freertos/xtensa_vectors.S index f180705e70..7baae07ce0 100644 --- a/components/freertos/xtensa_vectors.S +++ b/components/freertos/xtensa_vectors.S @@ -713,7 +713,7 @@ _xt_user_exc: rsr a2, EXCCAUSE /* recover exc cause */ movi a3, _xt_exception_table - get_percpu_entry_for a3, a4 + get_percpu_entry_for a2, a4 addx4 a4, a2, a3 /* a4 = address of exception table entry */ l32i a4, a4, 0 /* a4 = handler address */ #ifdef __XTENSA_CALL0_ABI__ diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml index 51a6899029..2d332d38a0 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_SYS_01.yml @@ -2,4 +2,6 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [SYS_MISC_0101, SYS_MISC_0201] + ID: + - SYS_MISC_0101 # test reboot function + - SYS_MISC_0201 # get heap size test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml index e86fac28ae..d9bad02c3e 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_01.yml @@ -2,9 +2,34 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_DHCP_0302, TCPIP_DHCP_0302, TCPIP_DHCP_0301, TCPIP_TCP_0403, TCPIP_TCP_0402, - TCPIP_TCP_0401, TCPIP_TCP_0407, TCPIP_TCP_0406, ^TCPIP_TCP_0411, TCPIP_TCP_0404, - TCPIP_TCP_0408, TCPIP_TCP_0110, ^TCPIP_TCP_0111, TCPIP_TCP_0115, TCPIP_IP_0101, - TCPIP_IP_0102, ^TCPIP_IGMP_0102, ^TCPIP_IGMP_0101, ^TCPIP_IGMP_0104, TCPIP_IGMP_0104, - TCPIP_IGMP_0103, TCPIP_IGMP_0102, TCPIP_IGMP_0101, TCPIP_UDP_0108, TCPIP_UDP_0106, - TCPIP_UDP_0107, TCPIP_UDP_0105, TCPIP_UDP_0101, TCPIP_IGMP_0204, TCPIP_IGMP_0201] + ID: + - TCPIP_DHCP_0101 # dhcp client function test + - TCPIP_DHCP_0103 # dhcp status query + - TCPIP_DHCP_0201 # server dhcp lease test + - TCPIP_DHCP_0202 # dhcp server ip pool + - TCPIP_DHCP_0203 # dhcp server ip pool empty + - TCPIP_DHCP_0204 # dhcp server timeout test + - TCPIP_DHCP_0205 # disconnect STA if config dhcp server + - TCPIP_DHCP_0206 # dhcp server assign same IP to same MAC when it's not released + - TCPIP_DHCP_0207 # dhcp server prefer assign released IP to new client + - TCPIP_DHCP_0208 # dhcp server reconfig and new client able to get first IP in pool + - TCPIP_DHCP_0209 # dhcp server reconfig, old client and new client able to get IP + - TCPIP_DHCP_0210 # dhcp server reconfig, old client able to get IP (discover with requested IP) + - TCPIP_DHCP_0211 # dhcp server reconfig, old client able to renew IP (direct send request) + - TCPIP_DHCP_0212 # dhcp server function test + - TCPIP_DHCP_0301 # sta dhcp static ip interaction + - TCPIP_DHCP_0302 # ap dhcp static ip interaction + - TCPIP_IGMP_0101 # station IGMP join group address check + - TCPIP_IGMP_0102 # station IGMP leave group address check + - TCPIP_IGMP_0103 # softAP IGMP join group address check + - TCPIP_IGMP_0104 # softAP IGMP leave group address check + - TCPIP_IGMP_0201 # station IGMP recv packets + - TCPIP_IGMP_0202 # station send multicast packets + - TCPIP_IGMP_0203 # softAP IGMP recv packets + - TCPIP_IGMP_0204 # softAP send multicast packets + - TCPIP_IP_0101 # sta set and query static ip test + - TCPIP_IP_0102 # ap set and query static ip test + - TCPIP_TCP_0101 # STA mode, connect test. use different ip, port + - TCPIP_TCP_0102 # STA mode, server listen test. use different kinds of port + - TCPIP_TCP_0103 # STA mode, send/recv basic test + - TCPIP_TCP_0104 # STA mode, shutdown basic test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml index a746cdd913..a1a927a082 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_02.yml @@ -1,10 +1,35 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [TCPIP_IGMP_0202, TCPIP_IGMP_0203, ^TCPIP_TCP_0403, ^TCPIP_TCP_0408, TCPIP_UDP_0201, - ^TCPIP_DHCP_0301, ^TCPIP_TCP_0101, ^TCPIP_TCP_0103, ^TCPIP_TCP_0105, ^TCPIP_TCP_0104, - ^TCPIP_TCP_0107, ^TCPIP_TCP_0106, ^TCPIP_DHCP_0210, ^TCPIP_DHCP_0211, ^TCPIP_DHCP_0212, - ^TCPIP_TCP_0404, TCPIP_TCP_0212, TCPIP_TCP_0210, ^TCPIP_TCP_0406, ^TCPIP_TCP_0407, - ^TCPIP_TCP_0401, ^TCPIP_TCP_0210, ^TCPIP_TCP_0212, TCPIP_DHCP_0211, TCPIP_DHCP_0210, - TCPIP_DHCP_0212, TCPIP_DHCP_0101, TCPIP_DHCP_0103, TCPIP_DHCP_0206, TCPIP_DHCP_0207] + ID: + - TCPIP_TCP_0105 # STA mode, close for different types of TCP sockets test + - TCPIP_TCP_0106 # STA mode, create max TCP sockets test + - TCPIP_TCP_0107 # STA mode, accept max TCP client by server test + - TCPIP_TCP_0110 # AP mode, connect test. use different ip, port + - TCPIP_TCP_0111 # AP mode, server listen test. use different kinds of port + - TCPIP_TCP_0112 # AP mode, send/recv basic test + - TCPIP_TCP_0113 # AP mode, shutdown basic test + - TCPIP_TCP_0114 # AP mode, close for different types of TCP sockets test + - TCPIP_TCP_0115 # AP mode, create max TCP sockets test + - TCPIP_TCP_0116 # AP mode, accept max TCP client by server test + - TCPIP_TCP_0201 # STA mode, connect test. use socket in state that can't connect + - TCPIP_TCP_0202 # STA mode, server listen test. use socket in state that can't listen + - TCPIP_TCP_0203 # send test. use socket in state that can't send + - TCPIP_TCP_0204 # STA mode, recv buffer test + - TCPIP_TCP_0206 # STA mode, get active socket info test + - TCPIP_TCP_0207 # AP mode, connect test. use socket in state that can't connect + - TCPIP_TCP_0208 # AP mode, server listen test. use socket in state that can't listen + - TCPIP_TCP_0210 # AP mode, recv buffer test + - TCPIP_TCP_0212 # AP mode, get active socket info test + - TCPIP_TCP_0401 # do TCP send after WIFI disconnected + - TCPIP_TCP_0402 # close TCP socket after WIFI disconnected + - TCPIP_TCP_0403 # do TCP send after mode changed + - TCPIP_TCP_0404 # close TCP socket after mode changed + - TCPIP_TCP_0406 # close TCP socket after PC NIC disabled + - TCPIP_TCP_0407 # do TCP send after IP changed + - TCPIP_TCP_0408 # close TCP socket after IP changed + - TCPIP_TCP_0411 # do TCP send after socket changed + - TCPIP_TCP_0412 # close TCP send after socket changed + - TCPIP_UDP_0101 # STA mode, udp bind test. use different ip, port + - TCPIP_UDP_0105 # STA mode, close UDP sockets test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml index f5f0abe5db..dcbd419acc 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_03.yml @@ -2,9 +2,34 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_IP_0102, ^TCPIP_UDP_0105, ^TCPIP_UDP_0107, ^TCPIP_UDP_0106, ^TCPIP_UDP_0101, - TCPIP_TCP_0202, ^TCPIP_UDP_0108, ^TCPIP_IGMP_0201, ^TCPIP_IGMP_0203, ^TCPIP_IGMP_0202, - ^TCPIP_IGMP_0103, TCPIP_UDP_0114, TCPIP_UDP_0113, TCPIP_UDP_0112, TCPIP_UDP_0202, - TCPIP_DHCP_0205, TCPIP_DHCP_0202, TCPIP_DHCP_0203, ^TCPIP_TCP_0102, TCPIP_TCP_0106, - TCPIP_TCP_0107, TCPIP_TCP_0104, TCPIP_TCP_0105, TCPIP_TCP_0102, TCPIP_TCP_0103, - TCPIP_TCP_0101, ^TCPIP_TCP_0116, ^TCPIP_TCP_0114, ^TCPIP_TCP_0115, ^TCPIP_TCP_0112] + ID: + - TCPIP_UDP_0106 # STA mode, create max udp socket test + - TCPIP_UDP_0107 # STA mode, get active socket info test + - TCPIP_UDP_0108 # AP mode, udp bind test. use different ip, port + - TCPIP_UDP_0112 # AP mode, close UDP sockets test + - TCPIP_UDP_0113 # AP mode, create max udp socket test + - TCPIP_UDP_0114 # AP mode, get active socket info test + - TCPIP_UDP_0201 # STA mode, recv buffer test + - TCPIP_UDP_0202 # AP mode, recv buffer test + - ^TCPIP_DHCP_0101 # dhcp client function test + - ^TCPIP_DHCP_0103 # dhcp status query + - ^TCPIP_DHCP_0201 # server dhcp lease test + - ^TCPIP_DHCP_0202 # dhcp server ip pool + - ^TCPIP_DHCP_0203 # dhcp server ip pool empty + - ^TCPIP_DHCP_0204 # dhcp server timeout test + - ^TCPIP_DHCP_0205 # disconnect STA if config dhcp server + - ^TCPIP_DHCP_0206 # dhcp server assign same IP to same MAC when it's not released + - ^TCPIP_DHCP_0207 # dhcp server prefer assign released IP to new client + - ^TCPIP_DHCP_0208 # dhcp server reconfig and new client able to get first IP in pool + - ^TCPIP_DHCP_0209 # dhcp server reconfig, old client and new client able to get IP + - ^TCPIP_DHCP_0210 # dhcp server reconfig, old client able to get IP (discover with requested IP) + - ^TCPIP_DHCP_0211 # dhcp server reconfig, old client able to renew IP (direct send request) + - ^TCPIP_DHCP_0212 # dhcp server function test + - ^TCPIP_DHCP_0301 # sta dhcp static ip interaction + - ^TCPIP_DHCP_0302 # ap dhcp static ip interaction + - ^TCPIP_IGMP_0101 # station IGMP join group address check + - ^TCPIP_IGMP_0102 # station IGMP leave group address check + - ^TCPIP_IGMP_0103 # softAP IGMP join group address check + - ^TCPIP_IGMP_0104 # softAP IGMP leave group address check + - ^TCPIP_IGMP_0201 # station IGMP recv packets + - ^TCPIP_IGMP_0202 # station send multicast packets diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml index b59e8c60cd..17c74c6f70 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_04.yml @@ -2,9 +2,34 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^TCPIP_TCP_0113, ^TCPIP_TCP_0110, TCPIP_DHCP_0209, ^TCPIP_DHCP_0209, ^TCPIP_DHCP_0207, - ^TCPIP_DHCP_0206, ^TCPIP_DHCP_0205, ^TCPIP_DHCP_0204, ^TCPIP_DHCP_0203, ^TCPIP_DHCP_0202, - ^TCPIP_DHCP_0201, TCPIP_TCP_0204, TCPIP_TCP_0207, TCPIP_TCP_0206, TCPIP_TCP_0201, - ^TCPIP_DHCP_0101, TCPIP_TCP_0203, ^TCPIP_DHCP_0103, ^TCPIP_DHCP_0208, TCPIP_TCP_0208, - ^TCPIP_TCP_0202, ^TCPIP_TCP_0203, TCPIP_DHCP_0204, ^TCPIP_TCP_0201, ^TCPIP_TCP_0206, - ^TCPIP_TCP_0207, ^TCPIP_TCP_0204, TCPIP_DHCP_0201, ^TCPIP_TCP_0208, TCPIP_DHCP_0208] + ID: + - ^TCPIP_IGMP_0203 # softAP IGMP recv packets + - ^TCPIP_IGMP_0204 # softAP send multicast packets + - ^TCPIP_IP_0101 # sta set and query static ip test + - ^TCPIP_IP_0102 # ap set and query static ip test + - ^TCPIP_TCP_0101 # STA mode, connect test. use different ip, port + - ^TCPIP_TCP_0102 # STA mode, server listen test. use different kinds of port + - ^TCPIP_TCP_0103 # STA mode, send/recv basic test + - ^TCPIP_TCP_0104 # STA mode, shutdown basic test + - ^TCPIP_TCP_0105 # STA mode, close for different types of TCP sockets test + - ^TCPIP_TCP_0106 # STA mode, create max TCP sockets test + - ^TCPIP_TCP_0107 # STA mode, accept max TCP client by server test + - ^TCPIP_TCP_0110 # AP mode, connect test. use different ip, port + - ^TCPIP_TCP_0111 # AP mode, server listen test. use different kinds of port + - ^TCPIP_TCP_0112 # AP mode, send/recv basic test + - ^TCPIP_TCP_0113 # AP mode, shutdown basic test + - ^TCPIP_TCP_0114 # AP mode, close for different types of TCP sockets test + - ^TCPIP_TCP_0115 # AP mode, create max TCP sockets test + - ^TCPIP_TCP_0116 # AP mode, accept max TCP client by server test + - ^TCPIP_TCP_0201 # STA mode, connect test. use socket in state that can't connect + - ^TCPIP_TCP_0202 # STA mode, server listen test. use socket in state that can't listen + - ^TCPIP_TCP_0203 # send test. use socket in state that can't send + - ^TCPIP_TCP_0204 # STA mode, recv buffer test + - ^TCPIP_TCP_0206 # STA mode, get active socket info test + - ^TCPIP_TCP_0207 # AP mode, connect test. use socket in state that can't connect + - ^TCPIP_TCP_0208 # AP mode, server listen test. use socket in state that can't listen + - ^TCPIP_TCP_0210 # AP mode, recv buffer test + - ^TCPIP_TCP_0212 # AP mode, get active socket info test + - ^TCPIP_TCP_0401 # do TCP send after WIFI disconnected + - ^TCPIP_TCP_0402 # close TCP socket after WIFI disconnected + - ^TCPIP_TCP_0403 # do TCP send after mode changed diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml index 627d67c408..0b07056588 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_05.yml @@ -1,8 +1,21 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [^TCPIP_IGMP_0204, ^TCPIP_TCP_0412, TCPIP_TCP_0411, TCPIP_TCP_0412, ^TCPIP_UDP_0112, - ^TCPIP_UDP_0113, ^TCPIP_UDP_0114, ^TCPIP_UDP_0202, ^TCPIP_UDP_0201, ^TCPIP_IP_0101, - ^TCPIP_TCP_0402, TCPIP_TCP_0114, TCPIP_TCP_0116, TCPIP_TCP_0111, TCPIP_TCP_0113, - TCPIP_TCP_0112] + ID: + - ^TCPIP_TCP_0404 # close TCP socket after mode changed + - ^TCPIP_TCP_0406 # close TCP socket after PC NIC disabled + - ^TCPIP_TCP_0407 # do TCP send after IP changed + - ^TCPIP_TCP_0408 # close TCP socket after IP changed + - ^TCPIP_TCP_0411 # do TCP send after socket changed + - ^TCPIP_TCP_0412 # close TCP send after socket changed + - ^TCPIP_UDP_0101 # STA mode, udp bind test. use different ip, port + - ^TCPIP_UDP_0105 # STA mode, close UDP sockets test + - ^TCPIP_UDP_0106 # STA mode, create max udp socket test + - ^TCPIP_UDP_0107 # STA mode, get active socket info test + - ^TCPIP_UDP_0108 # AP mode, udp bind test. use different ip, port + - ^TCPIP_UDP_0112 # AP mode, close UDP sockets test + - ^TCPIP_UDP_0113 # AP mode, create max udp socket test + - ^TCPIP_UDP_0114 # AP mode, get active socket info test + - ^TCPIP_UDP_0201 # STA mode, recv buffer test + - ^TCPIP_UDP_0202 # AP mode, recv buffer test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml index 7cf6279995..bdfeda4bb4 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_06.yml @@ -2,4 +2,6 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [TCPIP_TCP_0405, ^TCPIP_TCP_0405] + ID: + - TCPIP_TCP_0405 # do TCP send after PC NIC disabled + - ^TCPIP_TCP_0405 # do TCP send after PC NIC disabled diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml index 839ac972f4..862077d54a 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_07.yml @@ -1,10 +1,35 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, TCPIP_UDP_0303, - TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, TCPIP_ICMP_0101, - TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, TCPIP_DNS_0102, - TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, TCPIP_DNS_0101, - ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, ^TCPIP_ICMP_0101, - TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109, TCPIP_UDP_0109] + ID: + - TCPIP_DNS_0101 # get host by name test + - TCPIP_DNS_0101 # get host by name test + - TCPIP_DNS_0101 # get host by name test + - TCPIP_DNS_0101 # get host by name test + - TCPIP_DNS_0101 # get host by name test + - TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - TCPIP_DNS_0103 # UDP send to iot.expressif.com + - TCPIP_DNS_0103 # UDP send to iot.expressif.com + - TCPIP_DNS_0103 # UDP send to iot.expressif.com + - TCPIP_DNS_0103 # UDP send to iot.expressif.com + - TCPIP_DNS_0103 # UDP send to iot.expressif.com + - TCPIP_ICMP_0101 # ping function test + - TCPIP_ICMP_0101 # ping function test + - TCPIP_ICMP_0101 # ping function test + - TCPIP_ICMP_0101 # ping function test + - TCPIP_ICMP_0101 # ping function test + - TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - TCPIP_UDP_0103 # STA mode, sendto test with different length + - TCPIP_UDP_0103 # STA mode, sendto test with different length + - TCPIP_UDP_0103 # STA mode, sendto test with different length + - TCPIP_UDP_0103 # STA mode, sendto test with different length + - TCPIP_UDP_0103 # STA mode, sendto test with different length diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml index b318b09377..af6612e35b 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_08.yml @@ -1,10 +1,35 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC1] +DUT: [SSC2, SSC1] Filter: - Add: - ID: [TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, TCPIP_UDP_0104, - TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, TCPIP_UDP_0102, - TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, TCPIP_UDP_0103, - ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, ^TCPIP_UDP_0307, - ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, ^TCPIP_UDP_0306, - ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305, ^TCPIP_UDP_0305] + ID: + - TCPIP_UDP_0104 # STA mode, recvfrom basic test + - TCPIP_UDP_0104 # STA mode, recvfrom basic test + - TCPIP_UDP_0104 # STA mode, recvfrom basic test + - TCPIP_UDP_0104 # STA mode, recvfrom basic test + - TCPIP_UDP_0104 # STA mode, recvfrom basic test + - TCPIP_UDP_0109 # AP mode, sendto test. use different ip, port + - TCPIP_UDP_0109 # AP mode, sendto test. use different ip, port + - TCPIP_UDP_0109 # AP mode, sendto test. use different ip, port + - TCPIP_UDP_0109 # AP mode, sendto test. use different ip, port + - TCPIP_UDP_0109 # AP mode, sendto test. use different ip, port + - TCPIP_UDP_0110 # AP mode, sendto test with different length + - TCPIP_UDP_0110 # AP mode, sendto test with different length + - TCPIP_UDP_0110 # AP mode, sendto test with different length + - TCPIP_UDP_0110 # AP mode, sendto test with different length + - TCPIP_UDP_0110 # AP mode, sendto test with different length + - TCPIP_UDP_0111 # AP mode, recvfrom basic test + - TCPIP_UDP_0111 # AP mode, recvfrom basic test + - TCPIP_UDP_0111 # AP mode, recvfrom basic test + - TCPIP_UDP_0111 # AP mode, recvfrom basic test + - TCPIP_UDP_0111 # AP mode, recvfrom basic test + - TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - TCPIP_UDP_0302 # close UDP socket after WIFI disconnected diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml index 50b50a3eb6..1a78479f39 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_09.yml @@ -2,9 +2,34 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, ^TCPIP_UDP_0304, - ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, ^TCPIP_UDP_0302, - ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, ^TCPIP_UDP_0301, - ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, ^TCPIP_UDP_0104, - ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, ^TCPIP_UDP_0103, - ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102, ^TCPIP_UDP_0102] + ID: + - TCPIP_UDP_0303 # do UDP send after mode changed + - TCPIP_UDP_0303 # do UDP send after mode changed + - TCPIP_UDP_0303 # do UDP send after mode changed + - TCPIP_UDP_0303 # do UDP send after mode changed + - TCPIP_UDP_0303 # do UDP send after mode changed + - TCPIP_UDP_0304 # close UDP socket after mode changed + - TCPIP_UDP_0304 # close UDP socket after mode changed + - TCPIP_UDP_0304 # close UDP socket after mode changed + - TCPIP_UDP_0304 # close UDP socket after mode changed + - TCPIP_UDP_0304 # close UDP socket after mode changed + - TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - TCPIP_UDP_0306 # do UDP send after IP changed + - TCPIP_UDP_0306 # do UDP send after IP changed + - TCPIP_UDP_0306 # do UDP send after IP changed + - TCPIP_UDP_0306 # do UDP send after IP changed + - TCPIP_UDP_0306 # do UDP send after IP changed + - TCPIP_UDP_0307 # close UDP socket after IP changed + - TCPIP_UDP_0307 # close UDP socket after IP changed + - TCPIP_UDP_0307 # close UDP socket after IP changed + - TCPIP_UDP_0307 # close UDP socket after IP changed + - TCPIP_UDP_0307 # close UDP socket after IP changed + - ^TCPIP_DNS_0101 # get host by name test + - ^TCPIP_DNS_0101 # get host by name test + - ^TCPIP_DNS_0101 # get host by name test + - ^TCPIP_DNS_0101 # get host by name test + - ^TCPIP_DNS_0101 # get host by name test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml index 44b7bd1893..1b7ca56756 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_10.yml @@ -1,10 +1,35 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, TCPIP_UDP_0111, - TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, TCPIP_UDP_0110, - ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, ^TCPIP_DNS_0101, - ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, ^TCPIP_DNS_0103, - ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, ^TCPIP_DNS_0102, - TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304, TCPIP_UDP_0304] + ID: + - ^TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - ^TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - ^TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - ^TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - ^TCPIP_DNS_0102 # TCP connect to iot.espressif.com + - ^TCPIP_DNS_0103 # UDP send to iot.expressif.com + - ^TCPIP_DNS_0103 # UDP send to iot.expressif.com + - ^TCPIP_DNS_0103 # UDP send to iot.expressif.com + - ^TCPIP_DNS_0103 # UDP send to iot.expressif.com + - ^TCPIP_DNS_0103 # UDP send to iot.expressif.com + - ^TCPIP_ICMP_0101 # ping function test + - ^TCPIP_ICMP_0101 # ping function test + - ^TCPIP_ICMP_0101 # ping function test + - ^TCPIP_ICMP_0101 # ping function test + - ^TCPIP_ICMP_0101 # ping function test + - ^TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - ^TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - ^TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - ^TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - ^TCPIP_UDP_0102 # STA mode, sendto test. use different ip, port + - ^TCPIP_UDP_0103 # STA mode, sendto test with different length + - ^TCPIP_UDP_0103 # STA mode, sendto test with different length + - ^TCPIP_UDP_0103 # STA mode, sendto test with different length + - ^TCPIP_UDP_0103 # STA mode, sendto test with different length + - ^TCPIP_UDP_0103 # STA mode, sendto test with different length + - ^TCPIP_UDP_0104 # STA mode, recvfrom basic test + - ^TCPIP_UDP_0104 # STA mode, recvfrom basic test + - ^TCPIP_UDP_0104 # STA mode, recvfrom basic test + - ^TCPIP_UDP_0104 # STA mode, recvfrom basic test + - ^TCPIP_UDP_0104 # STA mode, recvfrom basic test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml index be615d0878..ed03676da8 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_11.yml @@ -2,9 +2,34 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, TCPIP_UDP_0305, - TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, TCPIP_UDP_0306, - TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, TCPIP_UDP_0307, - TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, TCPIP_UDP_0301, - TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, TCPIP_UDP_0302, - TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103, TCPIP_DNS_0103] + ID: + - ^TCPIP_UDP_0110 # AP mode, sendto test with different length + - ^TCPIP_UDP_0110 # AP mode, sendto test with different length + - ^TCPIP_UDP_0110 # AP mode, sendto test with different length + - ^TCPIP_UDP_0110 # AP mode, sendto test with different length + - ^TCPIP_UDP_0110 # AP mode, sendto test with different length + - ^TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - ^TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - ^TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - ^TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - ^TCPIP_UDP_0301 # do UDP send after WIFI disconnected + - ^TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - ^TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - ^TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - ^TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - ^TCPIP_UDP_0302 # close UDP socket after WIFI disconnected + - ^TCPIP_UDP_0303 # do UDP send after mode changed + - ^TCPIP_UDP_0303 # do UDP send after mode changed + - ^TCPIP_UDP_0303 # do UDP send after mode changed + - ^TCPIP_UDP_0303 # do UDP send after mode changed + - ^TCPIP_UDP_0303 # do UDP send after mode changed + - ^TCPIP_UDP_0304 # close UDP socket after mode changed + - ^TCPIP_UDP_0304 # close UDP socket after mode changed + - ^TCPIP_UDP_0304 # close UDP socket after mode changed + - ^TCPIP_UDP_0304 # close UDP socket after mode changed + - ^TCPIP_UDP_0304 # close UDP socket after mode changed + - ^TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - ^TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - ^TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - ^TCPIP_UDP_0305 # close UDP socket after PC NIC disabled + - ^TCPIP_UDP_0305 # close UDP socket after PC NIC disabled diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml index 73b0187eed..a0f7e389df 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_TCPIP_12.yml @@ -2,5 +2,14 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, ^TCPIP_UDP_0303, - ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110, ^TCPIP_UDP_0110] + ID: + - ^TCPIP_UDP_0306 # do UDP send after IP changed + - ^TCPIP_UDP_0306 # do UDP send after IP changed + - ^TCPIP_UDP_0306 # do UDP send after IP changed + - ^TCPIP_UDP_0306 # do UDP send after IP changed + - ^TCPIP_UDP_0306 # do UDP send after IP changed + - ^TCPIP_UDP_0307 # close UDP socket after IP changed + - ^TCPIP_UDP_0307 # close UDP socket after IP changed + - ^TCPIP_UDP_0307 # close UDP socket after IP changed + - ^TCPIP_UDP_0307 # close UDP socket after IP changed + - ^TCPIP_UDP_0307 # close UDP socket after IP changed diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml index 9f8424f6d2..c59f161924 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_01.yml @@ -2,9 +2,34 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [^WIFI_CONN_0601, ^WIFI_ADDR_0101, WIFI_SCAN_0103, WIFI_SCAN_0102, WIFI_SCAN_0101, - WIFI_SCAN_0105, WIFI_SCAN_0104, ^WIFI_CONN_0103, WIFI_CONN_0201, WIFI_CONN_0904, - ^WIFI_SCAN_0102, ^WIFI_SCAN_0103, ^WIFI_SCAN_0104, WIFI_CONN_0401, WIFI_ADDR_0101, - WIFI_ADDR_0102, WIFI_CONN_0301, WIFI_SCAN_0301, WIFI_SCAN_0303, ^WIFI_CONN_0801, - WIFI_SCAN_0304, ^WIFI_CONN_0301, WIFI_CONN_0501, WIFI_CONN_0502, ^WIFI_CONN_0401, - WIFI_MODE_0101, WIFI_MODE_0103, WIFI_MODE_0102, ^WIFI_CONN_0904, ^WIFI_CONN_0901] + ID: + - WIFI_ADDR_0101 # set mac, query mac + - WIFI_ADDR_0102 # set mac and do scan/JAP/SAP + - WIFI_CONN_0101 # station SAP+JAP test, different encryption + - WIFI_CONN_0102 # station SAP+JAP test, different channel + - WIFI_CONN_0103 # station SAP+JAP test, ssid hidden + - WIFI_CONN_0104 # station SAP test, max allowed sta + - WIFI_CONN_0201 # JAP query test + - WIFI_CONN_0301 # AP config query test + - WIFI_CONN_0401 # auto reconnect test + - WIFI_CONN_0501 # reconnect policy test + - WIFI_CONN_0502 # will not do reconnect after manually disconnected + - WIFI_CONN_0601 # list stations connected to soft ap test + - WIFI_CONN_0801 # test auth change event + - WIFI_CONN_0901 # test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, REASON_NO_AP_FOUND + - WIFI_CONN_0904 # test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, REASON_ASSOC_EXPIRE + - WIFI_MODE_0101 # mode switch test (sta mode) + - WIFI_MODE_0102 # mode switch test (AP mode) + - WIFI_MODE_0103 # mode switch test (STA+AP mode) + - WIFI_SCAN_0101 # scan with scan config ssid + - WIFI_SCAN_0102 # scan with scan config bssid + - WIFI_SCAN_0103 # scan with scan config channel + - WIFI_SCAN_0104 # scan with scan config show hidden + - WIFI_SCAN_0105 # scan with several configs + - WIFI_SCAN_0301 # reject scan request before scan finished + - WIFI_SCAN_0302 # scan in congest channel + - WIFI_SCAN_0303 # scan during JAP + - WIFI_SCAN_0304 # scan during ext STA join SoftAP + - ^WIFI_ADDR_0101 # set mac, query mac + - ^WIFI_ADDR_0102 # set mac and do scan/JAP/SAP + - ^WIFI_CONN_0101 # station SAP+JAP test, different encryption diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml index 74e6ca612d..406950f790 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_02.yml @@ -2,6 +2,19 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_SCAN_0302, WIFI_CONN_0601, ^WIFI_CONN_0201, ^WIFI_ADDR_0102, WIFI_CONN_0901, - WIFI_CONN_0801, ^WIFI_CONN_0104, WIFI_CONN_0104, WIFI_CONN_0101, WIFI_CONN_0102, - WIFI_CONN_0103, ^WIFI_SCAN_0101, ^WIFI_CONN_0101, ^WIFI_CONN_0502, ^WIFI_CONN_0501] + ID: + - ^WIFI_CONN_0103 # station SAP+JAP test, ssid hidden + - ^WIFI_CONN_0104 # station SAP test, max allowed sta + - ^WIFI_CONN_0201 # JAP query test + - ^WIFI_CONN_0301 # AP config query test + - ^WIFI_CONN_0401 # auto reconnect test + - ^WIFI_CONN_0501 # reconnect policy test + - ^WIFI_CONN_0502 # will not do reconnect after manually disconnected + - ^WIFI_CONN_0601 # list stations connected to soft ap test + - ^WIFI_CONN_0801 # test auth change event + - ^WIFI_CONN_0901 # test wifi disconnect reason REASON_ASSOC_LEAVE, REASON_4WAY_HANDSHAKE_TIMEOUT, REASON_NO_AP_FOUND + - ^WIFI_CONN_0904 # test wifi disconnect reason REASON_ASSOC_TOOMANY, REASON_HANDSHAKE_TIMEOUT, REASON_ASSOC_EXPIRE + - ^WIFI_SCAN_0101 # scan with scan config ssid + - ^WIFI_SCAN_0102 # scan with scan config bssid + - ^WIFI_SCAN_0103 # scan with scan config channel + - ^WIFI_SCAN_0104 # scan with scan config show hidden diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml index 0f0b4bbaad..e5de3ea97c 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_03.yml @@ -1,6 +1,7 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC3, SSC2, SSC1] +DUT: [SSC1] Filter: - Add: - ID: [WIFI_PHY_0502, WIFI_PHY_0503, WIFI_PHY_0501, WIFI_PHY_0506, WIFI_PHY_0505, - WIFI_PHY_0504] + ID: + - WIFI_CONN_0902 # test wifi disconnect reason REASON_BEACON_TIMEOUT + - ^WIFI_CONN_0902 # test wifi disconnect reason REASON_BEACON_TIMEOUT diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml index 50f8707c72..fb4950f7da 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_04.yml @@ -1,5 +1,11 @@ Config: {execute count: 1, execute order: in order} -DUT: [SSC1] +DUT: [SSC3, SSC2, SSC1] Filter: - Add: - ID: [^WIFI_CONN_0902, WIFI_CONN_0902] + ID: + - WIFI_PHY_0501 # SoftAP STA in channel1 20M, STA changed to channel2 20M + - WIFI_PHY_0502 # SoftAP STA in channel1 20M, STA changed to channel2 40M + - WIFI_PHY_0503 # SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 20M + - WIFI_PHY_0504 # SoftAP STA in channel1, SoftAP 20M, STA 40M, STA changed to channel2 40M + - WIFI_PHY_0505 # SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 20M + - WIFI_PHY_0506 # SoftAP STA in channel1, SoftAP 40M, STA 40M, STA changed to channel2 40M diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml index 3694a698b7..298e49a5bf 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_05.yml @@ -2,4 +2,6 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC1] Filter: - Add: - ID: [^WIFI_CONN_0903, WIFI_CONN_0903] + ID: + - WIFI_CONN_0903 # test wifi disconnect reason REASON_AUTH_EXPIRE + - ^WIFI_CONN_0903 # test wifi disconnect reason REASON_AUTH_EXPIRE diff --git a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml index dd42815a91..b655bbc6c4 100644 --- a/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml +++ b/components/idf_test/integration_test/CIConfigs/IT_Function_WIFI_06.yml @@ -2,5 +2,13 @@ Config: {execute count: 1, execute order: in order} DUT: [SSC2, SSC1] Filter: - Add: - ID: [WIFI_SCAN_0201, WIFI_PHY_0403, WIFI_PHY_0402, WIFI_PHY_0401, WIFI_PHY_0407, - WIFI_PHY_0406, WIFI_PHY_0405, WIFI_PHY_0404, WIFI_PHY_0408] + ID: + - WIFI_PHY_0401 # SoftAP ext AP in defferent channel, both bandwidth 20M, STA connect to AP then Softap get connected + - WIFI_PHY_0402 # SoftAP ext AP in defferent channel, both bandwidth 20M, Softap get connected than STA connect to AP + - WIFI_PHY_0403 # SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, STA connect to AP then Softap get connected + - WIFI_PHY_0404 # SoftAP ext AP in defferent channel, SoftAP 20M, ext AP 40M, Softap get connected than STA connect to AP + - WIFI_PHY_0405 # SoftAP ext AP in defferent channel, both bandwidth 40M, STA connect to AP then Softap get connected + - WIFI_PHY_0406 # SoftAP ext AP in defferent channel, both bandwidth 40M, Softap get connected than STA connect to AP + - WIFI_PHY_0407 # SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, STA connect to AP then Softap get connected + - WIFI_PHY_0408 # SoftAP ext AP in defferent channel, SoftAP 40M, ext AP 20M, Softap get connected than STA connect to AP + - WIFI_SCAN_0201 # STA in differnt PHY mode to scan AP in different PHY mode diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_01.yml new file mode 100644 index 0000000000..5e9fea164f --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_01.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC3, SSC2, SSC1, SSC5, SSC4] +Filter: +- Add: + ID: + - TCPIP_TCP_5101 # 1 AP 4 STA TCP stable test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_02.yml new file mode 100644 index 0000000000..4f70706052 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_02.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: + - TCPIP_TCP_5102 # send random length segment to target diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_03.yml new file mode 100644 index 0000000000..14cc0695ab --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stable_TCPIP_03.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC3, SSC2, SSC1, SSC5, SSC4] +Filter: +- Add: + ID: + - TCPIP_TCP_5103 # TCP SoftSTA send/recv stress test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_01.yml new file mode 100644 index 0000000000..6ec2644dca --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_01.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: + - TCPIP_TCP_5001 # test possible TCP connect/disconnect method diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_02.yml b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_02.yml new file mode 100644 index 0000000000..a6315ddeeb --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_02.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: + - TCPIP_TCP_5201 # TCP send/recv stress test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_03.yml b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_03.yml new file mode 100644 index 0000000000..6fd1ba9128 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_03.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC1] +Filter: +- Add: + ID: + - TCPIP_TCP_5202 # TCP send/recv data validation diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_04.yml b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_04.yml new file mode 100644 index 0000000000..0bc473a8b7 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stress_TCPIP_04.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC2, SSC1] +Filter: +- Add: + ID: + - TCPIP_UDP_5001 # UDP send/recv stress test diff --git a/components/idf_test/integration_test/CIConfigs/IT_Stress_WIFI_01.yml b/components/idf_test/integration_test/CIConfigs/IT_Stress_WIFI_01.yml new file mode 100644 index 0000000000..4ab82dded9 --- /dev/null +++ b/components/idf_test/integration_test/CIConfigs/IT_Stress_WIFI_01.yml @@ -0,0 +1,6 @@ +Config: {execute count: 1, execute order: in order} +DUT: [SSC3, SSC2, SSC1, SSC5, SSC4] +Filter: +- Add: + ID: + - WIFI_CONN_5101 # max sta connect to SotfAP and disconnect diff --git a/components/idf_test/integration_test/TestCaseAll.yml b/components/idf_test/integration_test/TestCaseAll.yml index 9e4823a297..fcdbd9340c 100644 --- a/components/idf_test/integration_test/TestCaseAll.yml +++ b/components/idf_test/integration_test/TestCaseAll.yml @@ -4307,6 +4307,287 @@ test cases: test point 1: abnormal/special use test point 2: TCP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_5001 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stress + cmd set: + - TCPStress/TCPConnection + - - max_connection = 5 + - [dummy] + - - execute_time = 300 + - [''] + - - connect_method = ["C_01", "C_02", "C_05", "C_07"] + - [''] + - - disconnect_method = ["D_01", "D_03", "D_05", "D_06"] + - [''] + - - pc_ip = "pc_ip" + - [''] + - - target_ip = "target_ip" + - [''] + comment: '' + execution time: 5.0 + expected result: 1. succeed + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on + level: Integration + module: TCPIP + steps: '1. random choose connect method to do connect, random choose a method to + close + + Loop executing step 1' + sub module: TCP + summary: test possible TCP connect/disconnect method + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: function + stress + test point 2: TCP connect and disconnect test + version: v2 (2016-11-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_5101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stable + cmd set: + - TCPStress/TCPAPNSTA + - - send_len = 1460 + - [dummy] + - - test_time = 720 + - [''] + - - server_port = "" + - [''] + - - server_echo = True + - [''] + - - sta_number = 4 + - [''] + - - send_delay = 50 + - [''] + - - ap_ip = "" + - [''] + comment: '' + execution time: 12.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed + + 4. all TCP connection not disconnected' + initial condition: None + initial condition description (auto): none + level: Integration + module: TCPIP + steps: '1. all sta connect to softap + + 2. create tcp server on softap + + 3. all sta connect to softap tcp server + + 4. do bi-direction send on all tcp connections' + sub module: TCP + summary: 1 AP 4 STA TCP stable test + test environment: SSC_T5_1 + test environment description (auto): 5 SSC target connect with PC by UART. + test point 1: stable + test point 2: TCP stable test + version: v2 (2016-11-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_5102 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stable + cmd set: + - TCPStress/TCPRandomSend + - - delay_config = [0, 0.01, 0.1, 0.5, 1] + - [dummy] + - - send_count = 1000 + - [''] + - - test_time = 300 + - [''] + comment: '' + execution time: 12.0 + expected result: '1. succeed + + 2. succeed' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on + level: Integration + module: TCPIP + steps: '1. create TCP connection + + 2. PC send random length data to target' + sub module: TCP + summary: send random length segment to target + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: stable + test point 2: TCP stable test + version: v2 (2016-11-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_5103 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stable + cmd set: + - TCPStress/TCPSoftAPSTASendRecv + - - send_len = 1460 + - [dummy] + - - test_time = 720 + - [''] + - - server_port = "" + - [''] + - - server_port_2 = "" + - [''] + - - server_echo = True + - [''] + - - sta_number = 3 + - [''] + - - send_delay = 50 + - [''] + - - ap_ip = "" + - [''] + comment: '' + execution time: 12.0 + expected result: '1. succeed + + 2. verify reciveid data on target and PC succeed' + initial condition: None + initial condition description (auto): none + level: Integration + module: TCPIP + steps: '1. create TCP connection + + 2. send specified pattern on both direction' + sub module: TCP + summary: TCP SoftSTA send/recv stress test + test environment: SSC_T5_1 + test environment description (auto): 5 SSC target connect with PC by UART. + test point 1: stable + test point 2: TCP stable test + version: v2 (2016-11-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_5201 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stress + cmd set: + - TCPStress/TCPSendRecv + - - send_len = 1460 + - [dummy] + - - test_time = 300 + - [''] + - - duplex = True + - [''] + - - conn_num = 5 + - [''] + - - send_delay = 20 + - [''] + comment: '' + execution time: 12.0 + expected result: '1. succeed + + 2. succeed + + 3. all TCP connection not disconnected' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA + level: Integration + module: TCPIP + steps: '1. sta connect to softap + + 2. create multiple tcp connection + + 3. do send/recv on all tcp connections' + sub module: TCP + summary: TCP send/recv stress test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: stress + test point 2: TCP stress test + version: v2 (2016-11-15) +- CI ready: 'Yes' + ID: TCPIP_TCP_5202 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stress + cmd set: + - TCPStress/TCPDataValidation + - - test_time = 1440 + - [dummy] + - - tx_enable = True + - [''] + - - rx_enable = True + - [''] + - - conn_num = 1 + - [''] + - - send_len = 1024 + - [''] + comment: '' + execution time: 24.0 + expected result: '1. succeed + + 2. verify reciveid data on target and PC succeed' + initial condition: STAM2 + initial condition description (auto): sta mode, join AP, DHCP on + level: Integration + module: TCPIP + steps: '1. create TCP connection + + 2. send specified pattern on both direction' + sub module: TCP + summary: TCP send/recv data validation + test environment: SSC_T1_1 + test environment description (auto): 'PC has 2 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 1 SSC target connect with PC by UART.' + test point 1: stress + test point 2: TCP stress test + version: v2 (2016-11-15) - CI ready: 'Yes' ID: TCPIP_UDP_0101 SDK: '8266_NonOS @@ -5653,6 +5934,55 @@ test cases: test point 1: abnormal/special use test point 2: UDP handling abnormal event version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: TCPIP_UDP_5001 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stress + cmd set: + - UDPStress/UDPSendRecv + - - send_len = 1460 + - [dummy] + - - test_time = 300 + - [''] + - - duplex = True + - [''] + - - conn_num = 5 + - [''] + - - send_delay = 20 + - [''] + comment: '' + execution time: 12.0 + expected result: '1. succeed + + 2. succeed + + 3. succeed' + initial condition: T2_1 + initial condition description (auto): target 1 as SoftAP, target 2 as STA + level: Integration + module: TCPIP + steps: '1. sta connect to softap + + 2. create multiple udp + + 3. do send/recv on all udp' + sub module: UDP + summary: UDP send/recv stress test + test environment: SSC_T2_1 + test environment description (auto): 'PC has 1 wired NIC connected to AP. + + PC has 1 WiFi NIC. + + 2 SSC target connect with PC by UART.' + test point 1: stress + test point 2: UDP stress test + version: v2 (2016-11-15) - CI ready: 'Yes' ID: WIFI_ADDR_0101 SDK: '8266_NonOS @@ -6666,6 +6996,53 @@ test cases: test point 1: basic function test point 2: wifi disconnect reason test version: v1 (2016-8-15) +- CI ready: 'Yes' + ID: WIFI_CONN_5101 + SDK: '8266_NonOS + + 8266_RTOS + + ESP32_IDF' + Test App: SSC + auto test: 'Yes' + category: Stress + cmd set: + - WiFiStress/SoftAPNSTA + - - sta_num = 4 + - [dummy] + - - max_sta = 4 + - [''] + - - test_time = 300 + - [''] + - - delay1 = [0, 1] + - [''] + - - delay2 = [0, 1] + - [''] + - - change_mac = True + - [''] + - - channel = 1 + - [''] + comment: '' + execution time: 5.0 + expected result: '1. succeed + + 2. JAP succeed' + initial condition: None + initial condition description (auto): none + level: Integration + module: WIFI MAC + steps: '1. 1 target set to softap mode and rest set to sta mode + + 2. all sta random join and disconnect from softap + + Loop step 2' + sub module: WIFI Connect + summary: max sta connect to SotfAP and disconnect + test environment: SSC_T5_1 + test environment description (auto): 5 SSC target connect with PC by UART. + test point 1: stress + test point 2: SoftAP WIFI connect/disconnect stress test + version: v2 (2016-11-15) - CI ready: 'Yes' ID: WIFI_MODE_0101 SDK: '8266_NonOS diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPAPNSTA.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPAPNSTA.py new file mode 100755 index 0000000000..c8c50fc7a2 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPAPNSTA.py @@ -0,0 +1,223 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + + +TEST_COUNT_ONE_ROUND = 500 + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.send_len = 1460 + self.server_echo = True + self.sta_number = 4 + self.test_time = 12 * 60 + self.send_delay = 50 + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + checker_stings = [] + test_action_strings = [] + for i in range(self.sta_number + 1): + checker_stings.append("R SSC%s C +RECVPRINT:1" % (i+1)) + test_action_strings.append("SSC SSC%s soc -R -o 1" % (i+1)) + fail_string = "Fail, Fail to turn on recv print" + self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + server_echo = self.server_echo + sta_number = self.sta_number + test_time = self.test_time * 60 + send_delay = self.send_delay + ap_ip = self.get_parameter("target_ap_ip") + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + checker_stings = [] + test_action_string = [] + + for i in range(sta_number+1): + checker_stings.append("P SSC%d C !!!ready!!!" % (i+1)) + test_action_string.append("SSCC SSC%d reboot" % (i+1)) + + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # switch off recv print + checker_stings = [] + test_action_strings = [] + for i in range(self.sta_number + 1): + checker_stings.append("R SSC%s C +RECVPRINT:0" % (i+1)) + test_action_strings.append("SSC SSC%s soc -R -o 0" % (i+1)) + fail_string = "Fail, Fail to turn off recv print" + self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + + # step1 set ap on SSC1, create server + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail set mode" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + tcp_port = random.randint(10000, 20000) + + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -t 3 -m 8" % (ssid, password)] + fail_string = "Fail, Fail set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % tcp_port] + fail_string = "Fail, Fail create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 2, 8 SSC target(SSC2 - SSC9) join SSC1 soft AP + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +MODE:OK" % (i+2)) + test_action_string.append("SSCC SSC%d op -S -o 1" % (i+2)) + fail_string = "Fail, Fail set mode" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i+2, ssid)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i+2, ssid, password)) + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 3, create client on SSC2 - SSC9 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i+2, i+2)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i+2)) + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i+2), + "P SSC1 A :ACCEPT:(\d+),.+" % (i+2)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i+2, i+2, ap_ip, tcp_port)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step 4, do send/recv + while time.time() - start_time < test_time: + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d RE \+SEND:\d+,OK NC CLOSED" % (i+2)) + test_action_string.append("SSC SSC%d soc -S -s -l %d -n %d -j %d" % + (i+2, i+2, send_len, TEST_COUNT_ONE_ROUND, send_delay)) + if server_echo is True: + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % + (i+2, send_len, TEST_COUNT_ONE_ROUND, send_delay)) + checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%() NC CLOSED)" % + (i+2)) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=300) is False: + break + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + + if (time.time() - start_time) >= test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + # TODO: create a function to create TCP connections. reuse not copy paste code + checker_stings = [] + test_action_string = [] + for i in range(sta_number + 1): + checker_stings.append("P SSC%d C CLOSEALL" % (i + 1)) + test_action_string.append("SSCC SSC%d soc -T" % (i + 1)) + fail_string = "Fail, Fail to close socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + server_port = random.randint(20000, 30000) + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail to bind socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 2, i + 2)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 2)) + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 2), + "P SSC1 A :ACCEPT:(\d+),.+" % (i + 2)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i + 2, i + 2, ap_ip, server_port)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPConnection.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPConnection.py new file mode 100755 index 0000000000..7bedcaf8a1 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPConnection.py @@ -0,0 +1,335 @@ +import random +import re +import socket +import threading +import time + +import TCPConnectionUtility +from NativeLog import NativeLog +from TCAction import PerformanceTCBase + +DELAY_RANGE = [10, 3000] +CONNECTION_STRUCTURE = ("Connection handler", "PC socket", "Target socket id", + "Target port", "PC port", "PC state", "Target state") + +# max fail count for one connection during test +MAX_FAIL_COUNT = 10 + + +class CheckerBase(threading.Thread): + + CHECK_ITEM = ("CONDITION", "NOTIFIER", "ID", "DATA") + SLEEP_TIME = 0.1 # sleep 100ms between each check action + + def __init__(self): + threading.Thread.__init__(self) + self.setDaemon(True) + self.exit_event = threading.Event() + self.sync_lock = threading.Lock() + self.check_item_list = [] + self.check_item_id = 0 + + def run(self): + while self.exit_event.isSet() is False: + self.process() + pass + + def process(self): + pass + + def add_check_item(self, condition, notifier): + with self.sync_lock: + check_item_id = self.check_item_id + self.check_item_id += 1 + self.check_item_list.append(dict(zip(self.CHECK_ITEM, (condition, notifier, check_item_id, str())))) + return check_item_id + + def remove_check_item(self, check_item_id): + ret = None + with self.sync_lock: + check_items = filter(lambda x: x["ID"] == check_item_id, self.check_item_list) + if len(check_items) > 0: + self.check_item_list.remove(check_items[0]) + ret = check_items[0]["DATA"] + return ret + + def exit(self): + self.exit_event.set() + pass + + +# check on serial port +class SerialPortChecker(CheckerBase): + def __init__(self, serial_reader): + CheckerBase.__init__(self) + self.serial_reader = serial_reader + pass + + # check condition for serial is compiled regular expression pattern + @staticmethod + def do_check(check_item, data): + match = check_item["CONDITION"].search(data) + if match is not None: + pos = data.find(match.group()) + len(match.group()) + # notify user + check_item["NOTIFIER"]("serial", match) + else: + pos = -1 + return pos + + def process(self): + # do check + with self.sync_lock: + # read data + new_data = self.serial_reader() + # NativeLog.add_trace_info("[debug][read data] %s" % new_data) + # do check each item + for check_item in self.check_item_list: + # NativeLog.add_trace_info("[debug][read data][ID][%s]" % check_item["ID"]) + check_item["DATA"] += new_data + self.do_check(check_item, check_item["DATA"]) + time.sleep(self.SLEEP_TIME) + + +# handle PC TCP server accept and notify user +class TCPServerChecker(CheckerBase): + def __init__(self, server_sock): + CheckerBase.__init__(self) + self.server_sock = server_sock + server_sock.settimeout(self.SLEEP_TIME) + self.accepted_socket_list = [] + + # check condition for tcp accepted sock is tcp source port + @staticmethod + def do_check(check_item, data): + for sock_addr_pair in data: + addr = sock_addr_pair[1] + if addr[1] == check_item["CONDITION"]: + # same port, so this is the socket that matched, notify and remove it from list + check_item["NOTIFIER"]("tcp", sock_addr_pair[0]) + data.remove(sock_addr_pair) + + def process(self): + # do accept + try: + client_sock, addr = self.server_sock.accept() + self.accepted_socket_list.append((client_sock, addr)) + except socket.error: + pass + # do check + with self.sync_lock: + check_item_list = self.check_item_list + for check_item in check_item_list: + self.do_check(check_item, self.accepted_socket_list) + pass + + +# this thread handles one tcp connection. +class ConnectionHandler(threading.Thread): + CHECK_FREQ = CheckerBase.SLEEP_TIME/2 + + def __init__(self, utility, serial_checker, tcp_checker, connect_method, disconnect_method, test_case): + threading.Thread.__init__(self) + self.setDaemon(True) + self.utility = utility + self.connect_method = connect_method + self.disconnect_method = disconnect_method + self.exit_event = threading.Event() + # following members are used in communication with checker threads + self.serial_checker = serial_checker + self.tcp_checker = tcp_checker + self.serial_notify_event = threading.Event() + self.tcp_notify_event = threading.Event() + self.serial_result = None + self.tcp_result = None + self.serial_check_item_id = None + self.tcp_check_item_id = None + self.data_cache = None + self.fail_count = 0 + self.test_case = test_case + pass + + def log_error(self): + self.fail_count += 1 + if self.fail_count > MAX_FAIL_COUNT: + self.test_case.error_detected() + + def new_connection_structure(self): + connection = dict.fromkeys(CONNECTION_STRUCTURE, None) + connection["Connection handler"] = self + return connection + + def run(self): + while self.exit_event.isSet() is False: + connection = self.new_connection_structure() + # do connect + connect_method_choice = random.choice(self.connect_method) + if self.utility.execute_tcp_method(connect_method_choice, connection) is False: + self.log_error() + # check if established + if self.utility.is_established_state(connection) is True: + time.sleep(float(random.randint(DELAY_RANGE[0], DELAY_RANGE[1]))/1000) + # do disconnect if established + disconnect_method_choice = random.choice(self.disconnect_method) + if self.utility.execute_tcp_method(disconnect_method_choice, connection) is False: + self.log_error() + # make sure target socket closed + self.utility.close_connection(connection) + time.sleep(float(random.randint(DELAY_RANGE[0], DELAY_RANGE[1]))/1000) + pass + + # serial_condition: re string + # tcp_condition: target local port + def add_checkers(self, serial_condition=None, tcp_condition=None): + # cleanup + self.serial_result = None + self.tcp_result = None + self.serial_notify_event.clear() + self.tcp_notify_event.clear() + # serial_checker + if serial_condition is not None: + pattern = re.compile(serial_condition) + self.serial_check_item_id = self.serial_checker.add_check_item(pattern, self.notifier) + else: + # set event so that serial check always pass + self.serial_notify_event.set() + if tcp_condition is not None: + self.tcp_check_item_id = self.tcp_checker.add_check_item(tcp_condition, self.notifier) + else: + # set event so that tcp check always pass + self.tcp_notify_event.set() + # NativeLog.add_trace_info("[Debug] add check item %s, connection is %s" % (self.serial_check_item_id, self)) + pass + + def get_checker_results(self, timeout=5): + time1 = time.time() + while time.time() - time1 < timeout: + # if one type of checker is not set, its event will be set in add_checkers + if self.serial_notify_event.isSet() is True and self.tcp_notify_event.isSet() is True: + break + time.sleep(self.CHECK_FREQ) + # do cleanup + # NativeLog.add_trace_info("[Debug] remove check item %s, connection is %s" % (self.serial_check_item_id, self)) + self.data_cache = self.serial_checker.remove_check_item(self.serial_check_item_id) + self.tcp_checker.remove_check_item(self.tcp_check_item_id) + # self.serial_check_item_id = None + # self.tcp_check_item_id = None + return self.serial_result, self.tcp_result + + def notifier(self, typ, result): + if typ == "serial": + self.serial_notify_event.set() + self.serial_result = result + elif typ == "tcp": + self.tcp_notify_event.set() + self.tcp_result = result + + def exit(self): + self.exit_event.set() + pass + + +class TestCase(PerformanceTCBase.PerformanceTCBase): + def __init__(self, test_case, test_env, timeout=120, log_path=None): + PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, + timeout=timeout, log_path=log_path) + self.max_connection = 5 + self.execute_time = 120 # execute time default 120 minutes + self.pc_ip = "pc_ip" + self.target_ip = "target_ip" + self.connect_method = ["C_01"] + self.disconnect_method = ["D_05"] + + cmd_set = test_case["cmd set"] + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.error_event = threading.Event() + self.serial_lock = threading.Lock() + pass + + def serial_reader(self): + return self.serial_read_data("SSC1") + + def send_ssc_command(self, data): + with self.serial_lock: + time.sleep(0.05) + self.serial_write_line("SSC1", data) + + def error_detected(self): + self.error_event.set() + + def process(self): + # parameters + max_connection = self.max_connection + execute_time = self.execute_time * 60 + pc_ip = self.get_parameter(self.pc_ip) + target_ip = self.get_parameter(self.target_ip) + connect_method = self.connect_method + disconnect_method = self.disconnect_method + server_port = random.randint(30000, 50000) + + # step 1, create TCP server on target and PC + # create TCP server on target + self.serial_write_line("SSC1", "soc -B -t TCP -p %s" % server_port) + match = self.check_regular_expression("SSC1", re.compile("BIND:(\d+),OK")) + if match is None: + NativeLog.add_prompt_trace("Failed to create TCP server on target") + return + target_sock_id = match.group(1) + + self.serial_write_line("SSC1", "soc -L -s %s" % target_sock_id) + if self.check_response("SSC1", "+LISTEN:%s,OK" % target_sock_id) is False: + NativeLog.add_prompt_trace("Failed to create TCP server on target") + return + + # create TCP server on PC + try: + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, server_port)) + server_sock.listen(5) + except StandardError: + NativeLog.add_prompt_trace("Failed to create TCP server on PC") + return + + # step 2, create checker + serial_port_checker = SerialPortChecker(self.serial_reader) + tcp_server_checker = TCPServerChecker(server_sock) + serial_port_checker.start() + tcp_server_checker.start() + + # step 3, create 5 thread and do connection + utility = TCPConnectionUtility.Utility(self, server_port, server_port, pc_ip, target_ip) + work_thread = [] + for i in range(max_connection): + t = ConnectionHandler(utility, serial_port_checker, tcp_server_checker, + connect_method, disconnect_method, self) + work_thread.append(t) + t.start() + + # step 4, wait and exit + self.error_event.wait(execute_time) + # close all threads + for t in work_thread: + t.exit() + t.join() + serial_port_checker.exit() + tcp_server_checker.exit() + serial_port_checker.join() + tcp_server_checker.join() + + if self.error_event.isSet() is False: + # no error detected + self.set_result("Succeed") + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPConnectionUtility.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPConnectionUtility.py new file mode 100755 index 0000000000..f28218af0b --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPConnectionUtility.py @@ -0,0 +1,251 @@ +import random +import socket +import threading + +from NativeLog import NativeLog + +# from NativeLog import NativeLog + +# make sure target do not listen on this port +ERROR_PORT = 62685 + + +class Utility(object): + METHOD_RESULT = {"C_01": ("ESTABLISHED", "ESTABLISHED"), # target TCP peer state, PC TCP peer state + "C_02": ("SYNC_SENT", "CLOSED"), + "C_03": ("CLOSED", "CLOSED"), + "C_04": ("SYN_RCVD", "ESTABLISHED"), + "C_05": ("ESTABLISHED", "ESTABLISHED"), + "C_06": ("CLOSED", "CLOSED"), + "C_07": ("CLOSED", "CLOSED"), + "C_08": ("CLOSED", "CLOSED"), + "D_01": ("TIME_WAIT", "CLOSED"), + "D_02": ("TIME_WAIT", "TIME_WAIT"), + "D_03": ("FIN_WAIT_2", "CLOSE_WAIT"), + "D_04": ("FIN_WAIT_1", "CLOSE_WAIT"), + "D_05": ("CLOSED", "TIME_WAIT"), + "D_06": ("CLOSED", "CLOSED"), + "D_07": ("CLOSE_WAIT", "FIN_WAIT2"), + "D_08": ("TIME_WAIT", "CLOSED"), } + + SOC_CLOSED_STATE = ("FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT", "LAST_ACK", "CLOSED") + SOC_CREATED_STATE = ("SYNC_RCVD", "ESTABLISHED") + SOC_SEND_DATA_STATE = ("ESTABLISHED", "CLOSE_WAIT") + SOC_ESTABLISHED_STATE = ("ESTABLISHED", ) + + def __init__(self, tc_action, pc_server_port, target_server_port, pc_ip, target_ip): + self.tc_action = tc_action + self.pc_server_port = pc_server_port + self.target_server_port = target_server_port + self.pc_ip = pc_ip + self.target_ip = target_ip + self.pc_close_wait_socket_list = [] + self.sync_lock = threading.Lock() + pass + + # create a tcp socket, return True or False + def __create_tcp_socket(self, connection): + connection_handler = connection["Connection handler"] + connection["Target port"] = random.randint(10000, 60000) + connection_handler.add_checkers("BIND:(\d+),OK,%s,%s" + % (self.target_ip, connection["Target port"])) + self.tc_action.send_ssc_command("soc -B -t TCP -i %s -p %s" % (self.target_ip, connection["Target port"])) + serial_result, tcp_result = connection_handler.get_checker_results() + if serial_result is not None: + connection["Target socket id"] = serial_result.group(1) + return True + else: + return False + + # target do connect, return True or False + def __target_do_connect(self, connection, dest_ip, dest_port, timeout=20): + connection_handler = connection["Connection handler"] + connection_handler.add_checkers("CONNECT:%s,OK" % connection["Target socket id"], + connection["Target port"]) + self.tc_action.send_ssc_command("soc -C -s %s -i %s -p %s" + % (connection["Target socket id"], dest_ip, dest_port)) + serial_result, tcp_result = connection_handler.get_checker_results(timeout) + if serial_result is not None and tcp_result is not None: + connection["PC socket"] = tcp_result + return True + else: + return False + pass + + # pc do connect, return True or False + def __pc_do_connect(self, connection, dest_ip, dest_port, timeout=20): + connection_handler = connection["Connection handler"] + sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + while True: + connection["PC port"] = random.randint(10000, 60000) + try: + sock.bind((self.pc_ip, connection["PC port"])) + break + except socket.error, e: + if e.errno == 10048: # socket port reuse + continue + sock.settimeout(timeout) + connection["PC socket"] = sock + connection_handler.add_checkers("ACCEPT:(\d+),\d+,%s,%s" + % (self.pc_ip, connection["PC port"])) + try: + sock.connect((dest_ip, dest_port)) + except socket.error: + pass + serial_result, tcp_result = connection_handler.get_checker_results() + if serial_result is not None: + connection["Target socket id"] = serial_result.group(1) + return True + else: + return False + pass + + def connect_c_01(self, connection): + if self.__create_tcp_socket(connection) is True: + return self.__target_do_connect(connection, self.pc_ip, self.pc_server_port) + else: + return False + + def connect_c_02(self, connection): + if self.__create_tcp_socket(connection) is True: + return not self.__target_do_connect(connection, self.pc_ip, ERROR_PORT, timeout=5) + else: + return False + + def connect_c_03(self, connection): + return False + + def connect_c_04(self, connection): + return False + + def connect_c_05(self, connection): + return self.__pc_do_connect(connection, self.target_ip, self.target_server_port) + + def connect_c_06(self, connection): + return False + + def connect_c_07(self, connection): + return not self.__pc_do_connect(connection, self.target_ip, ERROR_PORT) + + def connect_c_08(self, connection): + return False + + def __target_socket_close(self, connection): + connection_handler = connection["Connection handler"] + if connection["Target socket id"] is not None: + connection_handler.add_checkers("CLOSE:%s" % connection["Target socket id"]) + self.tc_action.send_ssc_command("soc -T -s %s" % connection["Target socket id"]) + serial_result, tcp_result = connection_handler.get_checker_results() + connection["Target socket id"] = None + else: + serial_result = None + return True if serial_result is not None else False + + @staticmethod + def __pc_socket_close(connection): + connection_handler = connection["Connection handler"] + if connection["PC socket"] is not None: + connection_handler.add_checkers("CLOSED:%s" % connection["Target socket id"]) + connection["PC socket"].close() + serial_result, tcp_result = connection_handler.get_checker_results() + connection["PC socket"] = None + else: + serial_result = None + return True if serial_result is not None else False + + def close_d_01(self, connection): + connection["PC socket"] = None + return self.__target_socket_close(connection) + + def close_d_02(self, connection): + pass + + def close_d_03(self, connection): + with self.sync_lock: + self.pc_close_wait_socket_list.append(connection["PC socket"]) + return self.__target_socket_close(connection) + pass + + def close_d_04(self, connection): + pass + + def close_d_05(self, connection): + return self.__pc_socket_close(connection) + + def close_d_06(self, connection): + # target send data to PC, PC don't recv and close socket + connection_handler = connection["Connection handler"] + connection_handler.add_checkers("SEND:%s,OK" % connection["Target socket id"]) + self.tc_action.send_ssc_command("soc -S -s %s -l 100" % connection["Target socket id"]) + serial_result, tcp_result = connection_handler.get_checker_results() + if serial_result is None: + return False + return self.__pc_socket_close(connection) + + def close_d_07(self, connection): + # PC shutdown WR + result = False + try: + connection["PC socket"].shutdown(socket.SHUT_WR) + result = True + except StandardError: + pass + return result + + def close_d_08(self, connection): + pass + + def close_connection(self, connection): + self.__target_socket_close(connection) + pass + + TCP_ACTION_DICT = {"C_01": connect_c_01, + "C_02": connect_c_02, + "C_03": connect_c_03, + "C_04": connect_c_04, + "C_05": connect_c_05, + "C_06": connect_c_06, + "C_07": connect_c_07, + "C_08": connect_c_08, + "D_01": close_d_01, + "D_02": close_d_02, + "D_03": close_d_03, + "D_04": close_d_04, + "D_05": close_d_05, + "D_06": close_d_06, + "D_07": close_d_07, + "D_08": close_d_08, + } + + def get_method_destination_state(self, method): + return self.METHOD_RESULT[method] + + def execute_tcp_method(self, method, connection): + if method in self.METHOD_RESULT: + result = self.TCP_ACTION_DICT[method](self, connection) + if result is True: + state = self.get_method_destination_state(method) + connection["Target state"] = state[0] + connection["PC state"] = state[1] + else: + NativeLog.add_prompt_trace("[TCPConnection] tcp method %s fail, connection is %s" + % (method, connection)) + NativeLog.add_trace_info("[TCPConnection][data cache][check item %s] %s" + % (connection["Connection handler"].serial_check_item_id, + connection["Connection handler"].data_cache)) + else: + raise StandardError("Not TCP connection method") + return result + + def is_established_state(self, connection): + return True if connection["Target state"] in self.SOC_CREATED_STATE else False + + def is_closed_state(self, connection): + return True if connection["Target state"] in self.SOC_CLOSED_STATE else False + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPDataValidation.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPDataValidation.py new file mode 100755 index 0000000000..a06824ce3e --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPDataValidation.py @@ -0,0 +1,243 @@ +import os +import random +import threading +import socket +import time +import re + +from TCAction import TCActionBase +from TCAction import PerformanceTCBase +from NativeLog import NativeLog + + +def calc_hash(index): + return (index & 0xffffffff) % 83 + (index & 0xffffffff) % 167 + + +def verify_data(data, start_index): + for i, c in enumerate(data): + if ord(c) != calc_hash(start_index + i): + NativeLog.add_trace_critical("[Data Validation Error] target sent data index %u is error." + " Sent data is %x, should be %x" + % (start_index + i, ord(c), calc_hash(start_index + i))) + return False + return True + + +def make_validation_data(length, start_index): + return bytes().join([chr(calc_hash(start_index + i)) for i in range(length)]) + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.send_len = send_len + self.exit_event = threading.Event() + pass + + def exit(self): + self.exit_event.set() + + def run(self): + index = 0 + while self.exit_event.isSet() is False: + data = make_validation_data(self.send_len, index) + try: + self.sock.send(data) + index += self.send_len + except StandardError: + # pass but not exit thread + time.sleep(1) + continue + pass + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.exit_event = threading.Event() + + def exit(self): + self.exit_event.set() + + def run(self): + index = 0 + while self.exit_event.isSet() is False: + if self.sock is not None: + try: + data = self.sock.recv(8*1024) + except StandardError, e: + NativeLog.add_exception_log(e) + NativeLog.add_trace_critical("recv error, connection closed") + break + if verify_data(data, index) is not True: + break + index += len(data) + else: + time.sleep(1) + pass + + +class ValidationThread(threading.Thread): + def __init__(self, tc_action): + threading.Thread.__init__(self) + self.setDaemon(True) + self.tc_action = tc_action + self.exit_event = threading.Event() + + def exit(self): + self.exit_event.set() + + def run(self): + while self.exit_event.isSet() is False: + if self.tc_action.check_response("SSC1", "DATA_ERROR", 5) is True: + NativeLog.add_trace_critical("[Data Validation Error] target recv data error") + break + pass + + +class TestCase(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.send_len = 0 + self.tx_enable = None + self.rx_enable = None + self.conn_num = 0 + self.test_time = 0 + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + + try: + # configurable params + send_len = self.send_len + tx_enable = self.tx_enable + rx_enable = self.rx_enable + conn_num = self.conn_num + test_time = self.test_time * 60 # convert minutes to seconds + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + # init throughput result data + test_item = "" + if tx_enable is True: + test_item += "Tx" + if rx_enable is True: + test_item += "Rx" + if test_item == "": + raise StandardError("no throughput test item") + + pc_ip = self.get_parameter("pc_ip") + tcp_port = random.randint(10000, 50000) + + # disable recv print during throughput test + self.serial_write_line("SSC1", "soc -R -o 0") + if self.check_response("SSC1", "+RECVPRINT", 2) is False: + NativeLog.add_trace_critical("Fail, Fail to disable recv print") + + # create server + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(5) + server_sock.listen(5) + + sock_id_list = [] + send_thread_list = [] + recv_thread_list = [] + + # step 4 create tcp connection + for i in range(conn_num): + self.serial_write_line("SSC1", "soc -B -t TCP") + match = self.check_regular_expression("SSC1", re.compile("\+BIND:(\d+),OK"), 2) + if match is None: + NativeLog.add_trace_critical("Fail, Fail to bind") + return + else: + sock_id_list.append(int(match.group(1))) + + self.serial_write_line("SSC1", "soc -V -s %s -o 3" % sock_id_list[-1]) + if self.check_regular_expression("SSC1", re.compile("\+DATA_VALIDATION:\d+,OK"), 2) is None: + NativeLog.add_trace_critical("Fail, Failed to enable validation") + return + + self.serial_write_line("SSC1", "soc -C -s %s -i %s -p %s" % (sock_id_list[-1], pc_ip, tcp_port)) + try: + sock, addr = server_sock.accept() + except socket.error, e: + NativeLog.add_trace_critical("%s" % e) + raise e + + if self.check_regular_expression("SSC1", re.compile("\+CONNECT:\d+,OK"), 5) is None: + NativeLog.add_trace_critical("Fail, Failed to connect") + return + + sock.settimeout(10) + + send_thread_list.append(SendThread(sock if rx_enable is True else None, send_len)) + recv_thread_list.append(RecvThread(sock if tx_enable is True else None)) + recv_thread_list[-1].start() + + # step 5 do test + validation_thread = ValidationThread(self) + validation_thread.start() + + for send_thread in send_thread_list: + send_thread.start() + + if tx_enable is True: + # do send from target + for sock_id in sock_id_list: + self.serial_write_line("SSC1", "soc -S -s %s -l %s -n 10000000" % (sock_id, send_len)) + + time1 = time.time() + exit_flag = False + + while time.time() - time1 < test_time and exit_flag is False: + for i in sock_id_list: + send_thread_list[i].join(0.5) + recv_thread_list[i].join(0.5) + validation_thread.join(0.5) + if send_thread_list[i].isAlive() is False \ + or recv_thread_list[i].isAlive() is False \ + or validation_thread.isAlive() is False: + NativeLog.add_trace_critical("validation error found") + exit_flag = True + break + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - time1)) + + if time.time() - time1 >= test_time: + self.set_result("Succeed") + else: + self.set_result("Failed") + + # exit all thread + for i in sock_id_list: + send_thread_list[i].exit() + recv_thread_list[i].exit() + send_thread_list[i].join() + send_thread_list[i].join() + + validation_thread.exit() + validation_thread.join() + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPMultiSTASendRecv.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPMultiSTASendRecv.py new file mode 100644 index 0000000000..56cb7e6928 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPMultiSTASendRecv.py @@ -0,0 +1,165 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 500 + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + server_echo = self.server_echo + sta_number = self.sta_number + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C ready!!!" % (i + 1)] + test_action_string = ["SSCC SSC%d restore" % (i + 1)] + fail_string = "Fail, Fail to restore" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # turn off recv print + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C +RECVPRINT:0" % (i + 1)] + test_action_string = ["SSCC SSC%d soc -R -o 0" % (i + 1)] + fail_string = "Fail, Fail to turn off recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, set softap mode on SSC1 + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail to set mode on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set STA mode on SSC2-SSCn + for i in range(sta_number): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 2)] + test_action_string = ["SSCC SSC%d op -S -o 1" % (i + 2)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + tcp_port = random.randint(40000, 50000) + + # step3, set ssid/password on SSC1 + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 10" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step4, SSC2-SSCn join SSC1(soft AP) + for i in range(sta_number): + checker_stings = ["P SSC%d C +JAP:CONNECTED,%s" % (i + 2, ssid)] + test_action_string = ["SSCC SSC%d ap -C -s %s -p %s" % (i + 2, ssid, password)] + fail_string = "Fail, SSC%d Fail to connect to SSC1" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step5, create server on SSC2 + checker_stings = ["R SSC2 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -B -t TCP -p %s" % tcp_port] + fail_string = "Fail, Fail to create server on SSC2 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, Fail to create server on SSC2 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step6, create client on SSC3-SSCn + for i in range(sta_number - 1): + checker_stings = ["P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)] + test_action_string = ["SSCC SSC%d soc -B -t TCP" % (i + 3)] + fail_string = "Fail, SSC%d Fail to connect to TCP server while binding" % (i + 3) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number - 1): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), "P SSC2 A :ACCEPT:(\d+),.+" % i] + test_action_string = [ + "SSCC SSC%d soc -C -s -i 192.168.4.2 -p %s" % (i + 3, i + 3, tcp_port)] + fail_string = "Fail, SSC%d Fail to connect to TCP server while connecting" % (i + 3) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step7, do send/recv, SSC2<---->other STAs + while time.time() - start_time < test_time: + checker_stings = [] + test_action_string = [] + # SSC2 send packets to SSC3-SSCn + if server_echo is True: + for i in range(sta_number - 1): + test_action_string.append("SSC SSC2 soc -S -s -l %d -n 1000 -j %d" % + (i, send_len, send_delay)) + checker_stings.append( + "P SSC2 RE \+SEND:%s,OK NC CLOSED NC ERROR" % self.get_parameter("accept_sock%d" % (i + 3))) + + # SSC3-SSCn send packets to SSC2 + for i in range(sta_number - 1): + checker_stings.append( + "P SSC%d RE \+SEND:%s,OK NC CLOSED NC ERROR" % (i + 3, self.get_parameter("client_sock%d" % i))) + test_action_string.append("SSC SSC%d soc -S -s -l %d -n 1000 -j %d" % + (i + 3, i + 3, send_len, send_delay)) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=900) is False: + break + + # drop off the delay time if it's greater than 20ms + if send_delay > 20: + send_delay -= 10 + + NativeLog.add_trace_critical("Time escape: %d" % (time.time() - start_time)) + + if (time.time() - start_time) >= test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPRandomSend.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPRandomSend.py new file mode 100755 index 0000000000..e32c63bf42 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPRandomSend.py @@ -0,0 +1,109 @@ +import os +import time +import random +import threading +import socket +from TCAction import TCActionBase +from NativeLog import NativeLog +from NativeLog import ThroughputResult + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.send_len_config = range(1460) + self.delay_config = [0, 0.01, 0.1, 0.5, 1] + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len_config = self.send_len_config + delay_config = self.delay_config + send_count = self.send_count + test_time = self.test_time * 60 + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + # disable recv print during random send test + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + pc_ip = self.get_parameter("pc_ip") + tcp_port = random.randint(50000, 60000) + + # step 0 create tcp connection + + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(1) + server_sock.listen(5) + + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP"] + fail_string = "Fail, Fail bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"] + test_action_string = ["SSC SSC1 soc -C -s -i %s -p %s" % (pc_ip, tcp_port)] + fail_string = "Fail, Fail to connect" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + sock, addr = server_sock.accept() + sock.settimeout(10) + # set no delay so that tcp segment will be send as soon as send called + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + + # step 1 start send + start_time = time.time() + while time.time() - start_time < test_time: + for delay in delay_config: + for i in xrange(send_count): + send_len = random.choice(send_len_config) + data = "A" * (send_len+1) + try: + sock.send(data) + except socket.error, e: + NativeLog.add_exception_log(e) + NativeLog.add_trace_critical("Fail to send packets") + return + pass + time.sleep(delay) + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + + if (time.time() - start_time) > test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSTAMuitiSockSendRecv.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSTAMuitiSockSendRecv.py new file mode 100644 index 0000000000..5625756b94 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSTAMuitiSockSendRecv.py @@ -0,0 +1,159 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout, log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + server_echo = self.server_echo + conn_number = self.conn_number + sta_number = self.sta_number + test_time = self.test_time + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C !!!ready!!!" % (i + 1)] + test_action_string = ["SSCC SSC%d reboot" % (i + 1)] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, set ap mode on SSC1, set STA mode on SSC2-SSC3 + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail to set mode on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 2)] + test_action_string = ["SSCC SSC%d op -S -o 1" % (i + 2)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # turn off recv print + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C +RECVPRINT:0" % (i + 1)] + test_action_string = ["SSCC SSC%d soc -R -o 0" % (i + 1)] + fail_string = "Fail, Fail to turn off recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set ssid/password on SSC1 + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + tcp_port = random.randint(10000, 20000) + + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -t 3 -m 8" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step3, SSC2-SSC3 connect to SSC1 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i + 2, ssid)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i + 2, ssid, password)) + fail_string = "Fail, SSC%d Fail to connect to SoftAP" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step4, create tcp server on STA SSC2 + checker_stings = ["R SSC2 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -B -t TCP -p %s" % tcp_port] + fail_string = "Fail, Fail to create server on SSC2 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, Fail to create server on SSC2 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step5, create multi client on SSC3 + for i in range(conn_number): + checker_stings = ["P SSC3 A :BIND:(\d+),OK" % i] + test_action_string = ["SSCC SSC3 soc -B -t TCP"] + fail_string = "Fail, Fail to create client on SSC3" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC3 RE CONNECT:(\d+),OK", "P SSC2 A :ACCEPT:(\d+),.+" % i] + test_action_string = ["SSCC SSC3 soc -C -s -i %s -p %s" % (i, "192.168.4.2", tcp_port)] + fail_string = "Fail, Fail to connect to SSC2 server while connecting" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step6, do send/recv + while time.time() - start_time < test_time: + checker_stings = [] + test_action_string = [] + # SSC2 send packets to SSC3 + if server_echo is True: + for i in range(conn_number): + checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED NC ERROR") + test_action_string.append("SSC SSC2 soc -S -s -l %d -n 1000 -j %d" % + (i, send_len, send_delay)) + # SSC3 send packets to SSC2 + for i in range(conn_number): + test_action_string.append("SSC SSC3 soc -S -s -l %d -n 1000 -j %d" % + (i, send_len, send_delay)) + checker_stings.append("P SSC3 RE \+SEND:\d+,OK NC CLOSED NC ERROR") + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=600) is False: + break + + if send_delay > 20: + send_delay -= 10 + + NativeLog.add_trace_critical("Time escape: %d" % (time.time() - start_time)) + + if (time.time() - start_time) > test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSTAsendrecv.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSTAsendrecv.py new file mode 100644 index 0000000000..8fd0d7d6f7 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSTAsendrecv.py @@ -0,0 +1,167 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout, log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + server_echo = self.server_echo + conn_number = self.conn_number + sta_number = self.sta_number + test_time = self.test_time * 60 + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C ready!!!" % (i + 1)] + test_action_string = ["SSCC SSC%d restore" % (i + 1)] + fail_string = "Fail, Fail to restore" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, set ap mode on SSC1, set STA mode on SSC2-SSC3 + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail to set mode on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 2)] + test_action_string = ["SSCC SSC%d op -S -o 1" % (i + 2)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # turn off recv print + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C +RECVPRINT:0" % (i + 1)] + test_action_string = ["SSCC SSC%d soc -R -o 0" % (i + 1)] + fail_string = "Fail, Fail to turn off recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set ssid/password on SSC1 + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + tcp_port = random.randint(10000, 20000) + + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 10" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step3, SSC2-SSC3 connect to SSC1 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i + 2, ssid)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i + 2, ssid, password)) + fail_string = "Fail, SSC%d Fail to connect to SoftAP" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step4, create tcp server on STA SSC2 + checker_stings = ["R SSC2 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -B -t TCP -p %s" % tcp_port] + fail_string = "Fail, Fail to create server on SSC2 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, Fail to create server on SSC2 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step5, create multi client on SSC3 + for i in range(conn_number): + checker_stings = ["P SSC3 A :BIND:(\d+),OK" % i] + test_action_string = ["SSCC SSC3 soc -B -t TCP"] + fail_string = "Fail, Fail to create client on SSC3" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC3 RE CONNECT:(\d+),OK", "P SSC2 A :ACCEPT:(\d+),.+ NC ERROR" % i] + test_action_string = ["SSCC SSC3 soc -C -s -i %s -p %s" % (i, "192.168.4.2", tcp_port)] + fail_string = "Fail, Fail to connect to SSC2 server while connecting" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step6, do send/recv + while time.time() - start_time < test_time: + checker_stings = [] + test_action_string = [] + # SSC2 send packets to SSC3 + if server_echo is True: + for i in range(conn_number): + checker_stings.append( + "P SSC2 RE \+SEND:%s,OK NC CLOSED NC ERROR NC unexpected" % self.get_parameter( + "accept_sock%d" % i)) + test_action_string.append("SSC SSC2 soc -S -s -l %d -n 1000 -j %d" % + (i, send_len, send_delay)) + # SSC3 send packets to SSC2 + for i in range(conn_number): + test_action_string.append("SSC SSC3 soc -S -s -l %d -n 1000 -j %d" % + (i, send_len, send_delay)) + checker_stings.append( + "P SSC3 RE \+SEND:%s,OK NC CLOSED NC ERROR" % self.get_parameter("client_sock%d" % i)) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=900) is False: + # checker_stings = ["R SSC1 C +LSTADONE"] + # test_action_string = ["SSCC SSC1 ap -L"] + # fail_string = "" + # if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + # pass + break + + if send_delay > 20: + send_delay -= 10 + + NativeLog.add_trace_critical("Time escape: %d" % (time.time() - start_time)) + + if (time.time() - start_time) > test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSendRecv.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSendRecv.py new file mode 100755 index 0000000000..afc3804e78 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSendRecv.py @@ -0,0 +1,154 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 1000 + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + # step 0 turn on recv print + checker_stings = ["P SSC1 C +RECVPRINT:1", "P SSC2 C +RECVPRINT:1"] + test_action_string = ["SSC SSC1 soc -R -o 1", "SSC SSC2 soc -R -o 1"] + fail_string = "Fail, Fail to turn on recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + duplex = self.duplex + conn_num = self.conn_num + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPSendRecv script, error is %s" % e) + raise StandardError("Error configuration") + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + tcp_port = random.randint(10000, 50000) + + # step 0 set ap + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSC SSC1 ap -S -s %s -p %s -t 3" % (ssid, password)] + fail_string = "Fail, Fail to set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + # step 1 connect to ap and turn off recv print + checker_stings = ["R SSC2 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC2 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + self.result_cntx.set_result("Fail") + return + + checker_stings = ["P SSC1 C +RECVPRINT:0", "P SSC2 C +RECVPRINT:0"] + test_action_string = ["SSC SSC1 soc -R -o 0", "SSC SSC2 soc -R -o 0"] + fail_string = "Fail, Fail to turn off recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + self.result_cntx.set_result("Fail") + return + + # step 2 create server on AP + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP -p %s" % tcp_port] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + checker_stings = ["R SSC1 A :\+LISTEN:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -L -s "] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + # step 3 create conn_num tcp connections + for i in range(conn_num): + checker_stings = ["R SSC2 A :\+BIND:(\d+),OK" % i] + test_action_string = ["SSC SSC2 soc -B -t TCP"] + fail_string = "Fail, Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + checker_stings = ["P SSC1 A :\+ACCEPT:(\d+),\d+" % i, + "P SSC2 RE \+CONNECT:\d+,OK"] + test_action_string = ["SSC SSC2 soc -C -s -i -p %s" % (i, tcp_port)] + fail_string = "Fail, Fail to connect" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + start_time = time.time() + # step 4, do send/recv + while time.time()-start_time < test_time: + + checker_stings = ["P SSC1 NC ERROR NC CLOSE NC ERROR"] + for i in range(conn_num): + test_action_string = ["SSC SSC2 soc -S -s -l %d -n %d -j %d" % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay)] + checker_stings.append("P SSC2 RE \"\+SEND:%%%%s,OK\"%%%%() NC ERROR NC CLOSE" % i) + + if duplex is True: + checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%()" % i) + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay)) + + fail_string = "Fail, Failed on send command" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + break + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, ["DELAY 0.1"], fail_string, + check_freq=1, check_time=300) is False: + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + self.result_cntx.set_result("Fail") + return + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + + if (time.time() - start_time) >= test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + + diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py new file mode 100644 index 0000000000..bd66559780 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPSoftAPSTASendRecv.py @@ -0,0 +1,339 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 500 + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, + timeout=timeout, log_path=log_path) + self.send_len = 1460 + self.server_port = random.randint(10000, 50000) + self.server_port_2 = random.randint(10000, 50000) + self.server_echo = True + self.test_time = 12 * 60 + self.sta_number = 3 + self.send_delay = 50 + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + checker_stings = [] + test_action_strings = [] + for i in range(self.sta_number + 2): + checker_stings.append("R SSC%s C +RECVPRINT:1" % (i+1)) + test_action_strings.append("SSC SSC%s soc -R -o 1" % (i+1)) + fail_string = "Fail, Fail to turn on recv print" + self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + # server port + server_port = self.server_port + server_port_t = self.server_port_2 + # ap ip + # ap_ip = self.ap_ip + # server echo + server_echo = self.server_echo + # station number + sta_number = self.sta_number + # send delay + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + checker_stings = [] + test_action_string = [] + + for i in range(sta_number + 2): + checker_stings.append("P SSC%d C !!!ready!!!" % (i + 1)) + test_action_string.append("SSCC SSC%d reboot" % (i + 1)) + + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # switch off recv print + checker_stings = [] + test_action_strings = [] + for i in range(self.sta_number + 2): + checker_stings.append("R SSC%s C +RECVPRINT:0" % (i+1)) + test_action_strings.append("SSC SSC%s soc -R -o 0" % (i+1)) + fail_string = "Fail, Fail to turn off recv print" + self.load_and_exe_one_step(checker_stings, test_action_strings, fail_string) + + # step1, set ap/STA mode on all target + for i in range(sta_number + 2): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 1)] + test_action_string = ["SSCC SSC%d op -S -o 3" % (i + 1)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 1) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # set different getway for SSC1 softAP + checker_stings = ["R SSC1 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC1 dhcp -E -o 2"] + fail_string = "Fail, SSC1 Fail to disable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 C +IP:OK"] + test_action_string = ["SSCC SSC1 ip -S -o 2 -i 192.168.6.1"] + fail_string = "Fail, SSC1 Fail to set IP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC1 dhcp -S -o 2"] + fail_string = "Fail, SSC1 Fail to enable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # set different getway for SSC2 softAP + checker_stings = ["R SSC2 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC2 dhcp -E -o 2"] + fail_string = "Fail, SSC2 Fail to disable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 C +IP:OK"] + test_action_string = ["SSCC SSC2 ip -S -o 2 -i 192.168.5.1"] + fail_string = "Fail, SSC2 Fail to set IP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 C +DHCP:AP,OK"] + test_action_string = ["SSCC SSC2 dhcp -S -o 2"] + fail_string = "Fail, SSC2 Fail to enable DHCP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set ssid/password on SSC1 + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step3, set ssid/password on SSC2 + ssid_1 = "".join([random.choice(string.lowercase) for m in range(10)]) + password_1 = "".join([random.choice(string.lowercase) for m in range(10)]) + checker_stings = ["R SSC2 C +SAP:OK"] + test_action_string = ["SSCC SSC2 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid_1, password_1)] + fail_string = "Fail, Fail to set ap ssid/password on SSC2" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step4, SSC2 join SSC1(soft AP) + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 C +JAP:CONNECTED,%s" % ssid) + test_action_string.append("SSCC SSC2 ap -C -s %s -p %s" % (ssid, password)) + fail_string = "Fail, Fail to connect to SSC1 SoftAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # step5, create server on SSC1 + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail to create server on SSC1 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail to create server on SSC1 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step6, create client on SSC2 + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 A :BIND:(\d+),OK") + test_action_string.append("SSCC SSC2 soc -B -t TCP") + fail_string = "Fail, SSC2 Fail to connect to server while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC2 RE CONNECT:(\d+),OK", "P SSC1 A :ACCEPT:(\d+),.+"] + test_action_string = ["SSCC SSC2 soc -C -s -i %s -p %s" % ("192.168.6.1", server_port)] + fail_string = "Fail, SSC2 Fail to connect to server while connecting" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step7, SSC3 - SSC5 join SSC2 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d C +JAP:CONNECTED,%s" % (i + 3, ssid_1)) + test_action_string.append("SSCC SSC%d ap -C -s %s -p %s" % (i + 3, ssid_1, password_1)) + fail_string = "Fail, SSC%d Fail to connect to SSC2" % (i + 3) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step8, create server on SSC2 + checker_stings = ["R SSC2 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -B -t TCP -p %s -i 192.168.5.1" % server_port_t] + fail_string = "Fail, Fail to create server one SSC2 while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, Fail to create server one SSC2 while listening" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step9, create client on SSC3 - SSC5 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 3)) + fail_string = "Fail, Fail to connect to SSC2 server while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), + "P SSC2 A :ACCEPT:(\d+),.+" % (i + 3)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i + 3, i + 3, "192.168.5.1", server_port_t)] + fail_string = "Fail, Fail to connect to SSC2 server while connecting" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step 10, do send/recv + while time.time() - start_time < test_time: + + checker_stings = [] + test_action_string = [] + if server_echo is True: + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" % + (send_len, TEST_COUNT_ONE_ROUND, send_delay)) + checker_stings.append("P SSC1 RE \+SEND:\d+,OK NC CLOSED") + test_action_string.append("SSC SSC2 soc -S -s -l %d -n %d -j %d" % + (send_len, TEST_COUNT_ONE_ROUND, send_delay)) + checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED") + + for i in range(sta_number): + checker_stings.append("P SSC%d RE \+SEND:\d+,OK NC CLOSED" % (i + 3)) + test_action_string.append("SSC SSC%d soc -S -s -l %d -n %d -j %d" % + (i + 3, i + 3, send_len, TEST_COUNT_ONE_ROUND, send_delay)) + for i in range(sta_number): + test_action_string.append("SSC SSC2 soc -S -s -l %d -n %d -j %d" % + (i + 3, send_len, TEST_COUNT_ONE_ROUND, send_delay)) + checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED") + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=300) is False: + break + pass + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + + if (time.time() - start_time) > test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + checker_stings = [] + test_action_string = [] + for i in range(sta_number + 2): + checker_stings.append("P SSC%d C CLOSEALL" % (i + 1)) + test_action_string.append("SSCC SSC%d soc -T" % (i + 1)) + fail_string = "Fail, Fail to close socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # re-set server on SSC1 + server_port = random.randint(20000, 30000) + checker_stings = ["R SSC1 A :BIND:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -B -t TCP -p %s" % server_port] + fail_string = "Fail, Fail to bind socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC1 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC1 soc -L -s "] + fail_string = "Fail, Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # SSC2 connnect SSC1 + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 A :BIND:(\d+),OK") + test_action_string.append("SSCC SSC2 soc -B -t TCP") + fail_string = "Fail, SSC2 Fail to bind sock" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["P SSC2 RE CONNECT:(\d+),OK", "P SSC1 A :ACCEPT:(\d+),.+"] + test_action_string = ["SSCC SSC2 soc -C -s -i %s -p %s" % ("192.168.6.1", server_port)] + fail_string = "Fail, SSC2 Fail to connect to SSC1 server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # create server on SSC2 + checker_stings = [] + test_action_string = [] + checker_stings.append("P SSC2 A :BIND:(\d+),OK") + test_action_string.append("SSCC SSC2 soc -B -t TCP -p %s -i 192.168.5.1" % server_port_t) + fail_string = "Fail, SSC2 Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + checker_stings = ["R SSC2 RE LISTEN:(\d+),OK"] + test_action_string = ["SSCC SSC2 soc -L -s "] + fail_string = "Fail, SSC2 Fail to listen" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # create client on SSC3-SSC5 + checker_stings = [] + test_action_string = [] + for i in range(sta_number): + checker_stings.append("P SSC%d A :BIND:(\d+),OK" % (i + 3, i + 3)) + test_action_string.append("SSCC SSC%d soc -B -t TCP" % (i + 3)) + fail_string = "Fail, Fail to connect to SSC2 server while binding" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + for i in range(sta_number): + checker_stings = ["P SSC%d RE CONNECT:(\d+),OK" % (i + 3), + "P SSC2 A :ACCEPT:(\d+),.+" % (i + 3)] + test_action_string = ["SSCC SSC%d soc -C -s -i %s -p %s" % + (i + 3, i + 3, "192.168.5.1", server_port_t)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPThroughput.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPThroughput.py new file mode 100755 index 0000000000..85759b702d --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/TCPThroughput.py @@ -0,0 +1,325 @@ +import os +import time +import random +import threading +import socket + +from TCAction import TCActionBase +from NativeLog import NativeLog +from NativeLog import ThroughputResult +from Utility import RSSICalibrator + +LOG_FOLDER = os.path.join("Performance", "Throughput") + +AP_PROP_KEY = ("ssid", "password", "apc") + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.send_len = send_len + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_sent = 0 + pass + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + data = "A" * self.send_len + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + self.sock.send(data) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_sent += self.send_len + + def get_bytes_sent(self): + return self.bytes_sent + + pass + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_recv = 0 + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + data = self.sock.recv(8 * 1024) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + + def get_bytes_recv(self): + return self.bytes_recv + + pass + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.performance_folder_path = log_path + self.att_test_list = range(60) + cmd_set = test_case["cmd set"] + # load param from excel + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + ap_list = self.get_parameter("shield_box_ap_list") + pc_ip = self.get_parameter("pc_ip") + send_len = self.send_len + att_test_list = self.att_test_list + tx_enable = self.tx_enable + rx_enable = self.rx_enable + measure_period = self.measure_period + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + tcp_port = random.randint(40000, 50000) + + # init throughput result data + test_item = "" + if tx_enable is True: + test_item += "Tx" + if rx_enable is True: + test_item += "Rx" + if test_item == "": + raise StandardError("no throughput test item") + + folder_path = os.path.join(self.performance_folder_path, LOG_FOLDER) + file_name = os.path.join(folder_path, + "TCPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime()))) + result = ThroughputResult.ThroughputResult(file_name, standard_required=True) + + # restart before executing throughput + checker_stings = ["R SSC1 C !!!ready!!!"] + test_action_string = ["SSC SSC1 reboot"] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + # disable recv print during throughput test + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + ret = True + for ap_prop in ap_list: + ssid = ap_prop[0] + password = ap_prop[1] + apc = ap_prop[2] + if ap_prop[1] == "": + # set a default string for open ap + password = "1" + # switch off all outlet, switch on AP outlet + outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") + outlet_config_dict[apc] = "ON" + apc_cmd = "APC " + for outlet in outlet_config_dict: + apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) + checker_stings = ["P PC_COM L OK"] + fail_string = "Fail, Fail to switch apc" + if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: + ret = False + break + + # wait AP ready + time.sleep(20) + + # create server + server_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + server_sock.bind((pc_ip, tcp_port)) + server_sock.settimeout(5) + server_sock.listen(5) + + if tx_enable is True: + result.add_test_item(ssid + "_tx") + if rx_enable is True: + result.add_test_item(ssid + "_rx") + + # create RSSI Calibrator + calibrator = RSSICalibrator.Calibrator() + + for att_value in att_test_list: + # step 0 set att value + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %s" % att_value] + fail_string = "Fail, Fail to set att value" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + + # step 1 get AP RSSI + checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ssid] + test_action_string = ["SSC SSC1 sta -S -s %s" % ssid] + fail_string = "Fail, Fail to scan" + rssi = scan_count = 0 + for i in range(3): + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + rssi += int(self.test_env.get_variable_by_name("rssi")[1]) + scan_count += 1 + + rssi = calibrator.calibrate_rssi(float(rssi) / scan_count if scan_count > 0 else 0, att_value) + + # step 2 connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + if rssi < -89: + continue + else: + ret = False + break + + # step 3 close all connections + checker_stings = ["R SSC1 C +CLOSEALL"] + test_action_string = ["SSC SSC1 soc -T"] + fail_string = "Fail, Fail to close socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + + # step 4 create tcp connection + + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t TCP"] + fail_string = "Fail, Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + + checker_stings = ["P SSC1 RE \+CONNECT:\d+,OK"] + test_action_string = ["SSC SSC1 soc -C -s -i %s -p %s" % (pc_ip, tcp_port)] + fail_string = "Fail, Fail to connect socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + + try: + sock, addr = server_sock.accept() + except socket.error, e: + NativeLog.add_trace_critical("%s" % e) + continue + sock.settimeout(measure_period) + + # step 5 do throughput test + send_thread = SendThread(sock if rx_enable is True else None, send_len) + send_thread.start() + + recv_thread = RecvThread(sock if tx_enable is True else None) + recv_thread.start() + + if tx_enable is True: + # do send from target + test_action_string = ["SSC SSC1 soc -S -s -l %s -n 10000000" % send_len] + fail_string = "Fail, Fail to send" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + pass + + # start throughput calculate + send_thread.start_calc() + recv_thread.start_calc() + + # sleep for measure period + time.sleep(measure_period) + + # stop throughput calculate + send_thread.stop_calc() + recv_thread.stop_calc() + + send_thread.join() + recv_thread.join() + + sock.close() + + # output throughput result + # in Mbps + if send_thread.get_bytes_sent() > 0: + result.log_throughput(ssid + "_rx", rssi, att_value, + float(send_thread.get_bytes_sent() * 8) / (measure_period * 1000000)) + + if recv_thread.get_bytes_recv() > 0: + result.log_throughput(ssid + "_tx", rssi, att_value, + float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000)) + + result.output_to_file() + pass + + server_sock.close() + if not ret: + NativeLog.add_trace_critical("Test SUC for %s" % ssid) + elif ret: + NativeLog.add_trace_critical("Test FAIL for %s!!!" % ssid) + if ret: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Fail") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/TCPStress/__init__.py b/components/idf_test/integration_test/TestCaseScript/TCPStress/__init__.py new file mode 100755 index 0000000000..049c1b961f --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/TCPStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["TCPConnUtility", "TCPConnSingleMode", "TCPConnMixedMode"] \ No newline at end of file diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPBroadcast.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPBroadcast.py new file mode 100644 index 0000000000..9ced966a88 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPBroadcast.py @@ -0,0 +1,342 @@ +import time +import random +import threading +import socket +import re + +from TCAction import PerformanceTCBase +from NativeLog import NativeLog +from Utility import Encoding + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len, target_addr, delay): + threading.Thread.__init__(self) + self.sock = sock + self.send_len = send_len + self.target_addr = target_addr + self.delay = delay + self.exit_event = threading.Event() + self.send_count = 0 + pass + + def exit(self): + self.exit_event.set() + + def run(self): + data = "A" * self.send_len + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + self.sock.sendto(data, self.target_addr) + except StandardError: + break + self.send_count += 1 + time.sleep(self.delay * 0.001) + + pass + + def get_send_count(self): + return self.send_count + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.sock = sock + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_recv = 0 + self.Max = 0.0 + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + data, addr = self.sock.recvfrom(2048) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + if len(data) == 0: + start = time.time() + while True: + try: + data, addr = self.sock.recvfrom(2048) + except StandardError: + break + if len(data) > 0: + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + end = time.time() + break + if end - start > self.Max: + self.Max = end - start + + def get_bytes_recv(self): + return self.bytes_recv + + pass + + def get_Max_time(self): + return self.Max + + pass + + +class device_check(threading.Thread): + def __init__(self, port): + threading.Thread.__init__(self) + self.Max = 0.0 + self.port = port + self.recv_data_cache = "" + self.cache_lock = threading.Lock() + self.exit_event = threading.Event() + + def data_recv_callback(self, data): + with self.cache_lock: + self.recv_data_cache += data + pass + + def exit(self): + self.exit_event.set() + pass + + def run(self): + while self.exit_event.isSet() is False: + while True: + if self.recv_data_cache: + match = re.search("\+RECVFROM:\d+,\d+,\d+\.\d+\.\d+\.\d+,\d+", self.recv_data_cache) + if match is not None: + self.recv_data_cache = self.recv_data_cache[len(match.group()):] + else: + start = time.time() + end = 0.0 + while True: + res = re.search("\+RECVFROM:\d+,\d+,\d+\.\d+\.\d+\.\d+,\d+", self.recv_data_cache) + if res is not None: + self.recv_data_cache = self.recv_data_cache[len(res.group()):] + end = time.time() + break + if end - start > self.Max: + self.Max = end - start + pass + + def get_max_time(self): + return self.Max + + +class TestCase(PerformanceTCBase.PerformanceTCBase): + def __init__(self, test_case, test_env, timeout, log_path): + PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, timeout, log_path) + self.send_len = 0 + self.pc_send = 0 + self.target_send = 0 + self.test_time = 0 + self.delay = 0 + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.recv_cb_lock = threading.Lock() + self.recv_cb = dict.fromkeys(["SSC1"]) + pass + + def register_recv_callback(self, port_name, callback): + with self.recv_cb_lock: + if self.recv_cb[port_name] is None: + self.recv_cb[port_name] = [callback] + else: + self.recv_cb[port_name].append(callback) + pass + + def process(self): + try: + # configurable params + send_len = self.send_len + pc_send = self.pc_send + target_send = self.target_send + test_time = self.test_time + delay = self.delay + ap_ssid = self.get_parameter("ap_ssid") + ap_password = self.get_parameter("ap_password") + pc_ip = self.get_parameter("pc_ip") + target_ip = self.get_parameter("target_ip") + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for UDP script, error is %s" % e) + raise StandardError("Error configuration") + + udp_port = random.randint(40000, 50000) + + # reboot before executing + self.flush_data("SSC1") + self.serial_write_line("SSC1", "reboot") + if self.check_response("SSC1", "ready!!!", 5) is False: + NativeLog.add_trace_critical("Fail to reboot") + return + + # set target as STA mode + self.flush_data("SSC1") + self.serial_write_line("SSC1", "op -S -o 1") + if self.check_response("SSC1", "+MODE:OK", 5) is False: + NativeLog.add_trace_critical("Fail to set mode") + return + + # connect to AP + self.flush_data("SSC1") + self.serial_write_line("SSC1", "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + if self.check_response("SSC1", "+JAP:CONNECTED", 30) is False: + NativeLog.add_trace_critical("Fail to JAP") + return + + # disable recv print on target + self.flush_data("SSC1") + self.serial_write_line("SSC1", "soc -R -o 0") + if self.check_response("SSC1", "+RECVPRINT", 5) is False: + NativeLog.add_trace_critical("Fail to disable recv print") + return + + # get broadcast ip + res = re.search("(\d+\.\d+\.\d+\.)\d+", pc_ip) + if res is not None: + udp = res.group(1) + broadcast_ip = udp + "255" + else: + NativeLog.add_trace_critical("No ip addr found") + return + + # close all connection on target + self.flush_data("SSC1") + self.serial_write_line("SSC1", "soc -T") + if self.check_response("SSC1", "+CLOSEALL", 5) is False: + NativeLog.add_trace_critical("Fail to close sock") + return + + # create socket on pc + pc_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + pc_sock.bind((pc_ip, udp_port)) + pc_sock.settimeout(1) + + # create socket on target + self.flush_data("SSC1") + self.serial_write_line("SSC1", "soc -B -t UDP -i %s -p %s" % (target_ip, udp_port)) + if self.check_response("SSC1", "+BIND:0,OK,", 5) is False: + NativeLog.add_trace_critical("Fail to bind") + return + + thread_dict = dict.fromkeys(["SSC1"]) + thread_dict["SSC1"] = dict(zip(["check"], [None])) + thread_dict["SSC1"]["check"] = device_check(self.test_env.get_port_by_name("SSC1")) + self.register_recv_callback("SSC1", thread_dict["SSC1"]["check"].data_recv_callback) + + send_thread = SendThread(pc_sock if pc_send is True else None, send_len, (broadcast_ip, udp_port), delay) + send_thread.start() + + recv_thread = RecvThread(pc_sock if target_send is True else None) + recv_thread.start() + + # start calculate + recv_thread.start_calc() + thread_dict["SSC1"]["check"].start() + send_count = 0 + if target_send is True: + # do send from target + start = time.time() + while time.time() - start < test_time * 60: + self.flush_data("SSC1") + self.serial_write_line("SSC1", "soc -S -s 0 -l %s -n 1000 -i %s -p %s -j %s" % ( + send_len, broadcast_ip, udp_port, delay)) + if self.check_response("SSC1", "+SEND:0,OK", 300) is False: + NativeLog.add_trace_critical("Fail to send") + return + send_count += 1000 + else: + time.sleep(test_time * 60) + + send_thread.exit() + send_thread.join() + + # stop throughput calculate + while True: + if recv_thread.isAlive() is False: + recv_thread.stop_calc() + recv_thread.join() + break + + Max = 0.0 + recv_count = 0 + if pc_send is True: + send_count = send_thread.get_send_count() + start = time.time() + rx_data_len = 0 + suc_time = 0 + while time.time() - start < 30: + self.flush_data("SSC1") + self.serial_write_line("SSC1", "soc -Q -s 0 -o 1") + time.sleep(0.05) + data = self.serial_read_data("SSC1") + if data is not None: + res = re.search("\+RECVLEN:(\d+)", data) + if res is not None: + if rx_data_len < int(res.group(1)): + rx_data_len = int(res.group(1)) + time.sleep(0.5) + else: + suc_time += 1 + if suc_time > 5: + break + + if (rx_data_len * 8 % send_len) > 0: + recv_count = rx_data_len / send_len + 1 + else: + recv_count = rx_data_len / send_len + + if recv_thread.get_bytes_recv() > 0: + if (recv_thread.get_bytes_recv() % send_len) > 0: + recv_count = recv_thread.get_bytes_recv() / send_len + 1 + else: + recv_count = recv_thread.get_bytes_recv() / send_len + Max = recv_thread.get_Max_time() + + thread_dict["SSC1"]["check"].exit() + pc_sock.close() + + self.set_result("Succeed") + NativeLog.add_trace_critical("send_count is %s, recv_count is %s" % (send_count, recv_count)) + NativeLog.add_trace_critical( + "UDP Broadcast lose rate is %.2f%%" % (float(send_count - recv_count) / send_count * 100)) + NativeLog.add_trace_critical("UDP Broadcast lose test MAX time is %.4f" % Max) + + @Encoding.encode_utf8(3) + def result_check(self, port_name, data): + PerformanceTCBase.PerformanceTCBase.result_check(self, port_name, data) + if port_name in self.recv_cb: + with self.recv_cb_lock: + callback_list = self.recv_cb[port_name] + if callback_list is not None: + for callback in callback_list: + callback(data) + pass + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPMultiSTASendRecv.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPMultiSTASendRecv.py new file mode 100644 index 0000000000..82c615d4ee --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPMultiSTASendRecv.py @@ -0,0 +1,156 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + server_echo = self.server_echo + sta_number = self.sta_number + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C ready!!!" % (i + 1)] + test_action_string = ["SSCC SSC%d restore" % (i + 1)] + fail_string = "Fail, Fail to restore" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # turn off recv print + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C +RECVPRINT:0" % (i + 1)] + test_action_string = ["SSCC SSC%d soc -R -o 0" % (i + 1)] + fail_string = "Fail, Fail to turn off recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, set softAP mode on SSC1 + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail to set mode on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set STA mode on SSC2-SSCn + for i in range(sta_number): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 2)] + test_action_string = ["SSCC SSC%d op -S -o 1" % (i + 2)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step3, set ssid/password on SSC1 + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + udp_port = random.randint(10000, 20000) + + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 10" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step4, all STA join SSC1(soft AP) + for i in range(sta_number): + checker_stings = ["R SSC%d C +JAP:CONNECTED,%s" % (i + 2, ssid)] + test_action_string = ["SSCC SSC%d ap -C -s %s -p %s" % (i + 2, ssid, password)] + fail_string = "Fail, Fail to connect to SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step5, get all the STA ip + for i in range(sta_number): + checker_stings = ["R SSC%d A :\+STAIP:192.168.4.(\d+)" % (i + 2, i + 2)] + test_action_string = ["SSCC SSC%d ip -Q" % (i + 2)] + fail_string = "Fail, Fail to get SSC%d ip" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + # else: + # print "SSC%d ip is:" % (i + 2), self.get_parameter("SSC%d_IP" % (i + 2)) + + # step6, create UDP socket on all targets + for i in range(sta_number): + checker_stings = ["R SSC%d A :\+BIND:(\d+),OK" % (i + 2, i + 2)] + test_action_string = ["SSCC SSC%d soc -B -t UDP -p %s" % (i + 2, udp_port + i + 2)] + fail_string = "Fail, SSC%d Fail to bind" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step7, do send/recv, SSC2<---->other STAs + while time.time() - start_time < test_time: + checker_stings = [] + test_action_string = [] + if server_echo is True: + + # SSC2 send packets to SSC3-SSCn + for i in range(sta_number - 1): + ip = "192.168.4." + self.get_parameter("SSC%d_IP" % (i + 3)) + test_action_string.append( + "SSC SSC2 soc -S -s -i %s -p %s -l %d -n 1000 -j %d" % ( + i + 3, ip, udp_port + i + 3, send_len, send_delay)) + checker_stings.append( + "P SSC2 RE \+SEND:%s,OK NC CLOSED NC ERROR" % self.get_parameter("sock%d" % (i + 3))) + + # SSC3-SSCn send packets to SSC2 + ssc2_ip = "192.168.4." + self.get_parameter("SSC2_IP") + for i in range(sta_number - 1): + test_action_string.append( + "SSC SSC%d soc -S -s -i %s -p %s -l %d -n 1000 -j %d" % ( + i + 3, i + 3, ssc2_ip, udp_port + 2, send_len, send_delay)) + checker_stings.append( + "P SSC%d RE \+SEND:%s,OK NC CLOSED NC ERROR" % (i + 3, self.get_parameter("sock%d" % (i + 3)))) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=300) is False: + break + + # drop off the delay time if it's greater than 20ms + if send_delay > 20: + send_delay -= 10 + + NativeLog.add_trace_critical("time escape: %s" % (time.time() - start_time)) + if (time.time() - start_time) >= test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPPacketLose.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPPacketLose.py new file mode 100644 index 0000000000..4cb0c1e8d8 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPPacketLose.py @@ -0,0 +1,246 @@ +import os +import time +import random +import threading +import socket + +from TCAction import TCActionBase +from NativeLog import NativeLog + +AP_PROP_KEY = ("ssid", "password", "apc") + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len, target_addr, delay): + threading.Thread.__init__(self) + self.sock = sock + self.send_len = send_len + self.target_addr = target_addr + self.delay = delay + self.count = 0 + self.exit_event = threading.Event() + pass + + def exit(self): + self.exit_event.set() + + def run(self): + data = "A" * self.send_len + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + self.sock.sendto(data, self.target_addr) + except StandardError: + break + self.count += 1 + time.sleep(self.delay * 0.001) + + def calculate(self): + return self.count + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.sock = sock + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_recv = 0 + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + if self.sock is None: + return + ret = True + while ret: + if self.exit_event.isSet() is True: + break + try: + data, addr = self.sock.recvfrom(65535) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + if len(data) == 0: + start = time.time() + while time.time() - start < 30: + try: + data, addr = self.sock.recvfrom(65535) + except StandardError: + break + if len(data) == 0: + break + else: + self.bytes_recv += len(data) + else: + ret = False + + def get_bytes_recv(self): + return self.bytes_recv + + pass + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout, log_path) + self.att_test_list = range(60) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + pc_send = self.pc_send + target_send = self.target_send + test_time = self.test_time + delay = self.delay + ap_ssid = self.get_parameter("ap_ssid") + ap_password = self.get_parameter("ap_password") + pc_ip = self.get_parameter("pc_ip") + target_ip = self.get_parameter("target_ip") + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for UDP script, error is %s" % e) + raise StandardError("Error configuration") + + udp_port = random.randint(40000, 50000) + + # reboot before executing + checker_stings = ["R SSC1 C ready!!!"] + test_action_string = ["SSC SSC1 reboot"] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # disable recv print on target + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # create socket on pc + udp_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + udp_sock.bind((pc_ip, udp_port)) + udp_sock.settimeout(1) + + # connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ap_ssid, ap_password)] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + return + + # close all connection + checker_stings = ["R SSC1 C +CLOSEALL"] + test_action_string = ["SSC SSC1 soc -T"] + fail_string = "Fail, Fail to create server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # create UDP socket on target + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t UDP -p %s" % udp_port] + fail_string = "Fail, Fail bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + send_thread = SendThread(udp_sock if pc_send is True else None, + send_len, (target_ip, udp_port), delay) + send_thread.start() + + recv_thread = RecvThread(udp_sock if target_send is True else None) + recv_thread.start() + + # start calculate + recv_thread.start_calc() + send_count = 0 + if target_send is True: + # do send from target + start = time.time() + while time.time() - start < test_time * 60: + checker_stings = ["P SSC1 RE \+SEND:0,OK"] + test_action_string = ["SSC SSC1 soc -S -s -l %s -n 1000 -i %s -p %s -j %s" % ( + send_len, pc_ip, udp_port, delay)] + fail_string = "Fail, Fail to send" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_freq=0.1, + check_time=3000) is False: + return + send_count += 1000 + else: + time.sleep(test_time * 60) + + send_thread.exit() + send_thread.join() + + # stop throughput calculate + while True: + if recv_thread.isAlive() is False: + recv_thread.stop_calc() + recv_thread.join() + break + + recv_count = 0 + if pc_send is True: + # get received data len from PC + self.load_and_exe_one_step(["R SSC1 A :RECVLEN:(\d+)"], + ["SSC SSC1 soc -Q -s -o 1"], + "Fail, Fail to get recv data len") + try: + rx_data_len = int(self.get_parameter("recv_len")) + except StandardError: + rx_data_len = 0 + + if (rx_data_len % send_len) > 0: + recv_count = rx_data_len / send_len + 1 + else: + recv_count = rx_data_len / send_len + + send_count = send_thread.calculate() + + if recv_thread.get_bytes_recv() > 0: + if (recv_thread.get_bytes_recv() % send_len) > 0: + recv_count = recv_thread.get_bytes_recv() / send_len + 1 + else: + recv_count = recv_thread.get_bytes_recv() / send_len + udp_sock.close() + + NativeLog.add_trace_critical("send_count is %s, recv_count is %s" % (send_count, recv_count)) + self.result_cntx.set_result("Succeed") + NativeLog.add_trace_critical( + "UDP Packet lose rate is %.2f%%" % (float(send_count - recv_count) / send_count * 100)) + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPSTAMuitiSocketSendRecv.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPSTAMuitiSocketSendRecv.py new file mode 100644 index 0000000000..ca94572617 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPSTAMuitiSocketSendRecv.py @@ -0,0 +1,163 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=45, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + server_echo = self.server_echo + conn_number = self.conn_number + sta_number = self.sta_number + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPTransparent script, error is %s" % e) + raise StandardError("Error configuration") + + # step0 reboot + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C !!!ready!!!" % (i + 1)] + test_action_string = ["SSCC SSC%d reboot" % (i + 1)] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # turn off recv print + for i in range(sta_number + 1): + checker_stings = ["P SSC%d C +RECVPRINT:0" % (i + 1)] + test_action_string = ["SSCC SSC%d soc -R -o 0" % (i + 1)] + fail_string = "Fail, Fail to turn off recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step1, set softAP mode on SSC1 + checker_stings = ["R SSC1 C +MODE:OK"] + test_action_string = ["SSCC SSC1 op -S -o 2"] + fail_string = "Fail, Fail to set mode on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step2, set STA mode on SSC2-SSCn + for i in range(sta_number): + checker_stings = ["R SSC%d C +MODE:OK" % (i + 2)] + test_action_string = ["SSCC SSC%d op -S -o 1" % (i + 2)] + fail_string = "Fail, Fail to set mode on SSC%d" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step3, set ssid/password on SSC1 + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSCC SSC1 ap -S -s %s -p %s -n 10 -t 0 -m 8" % (ssid, password)] + fail_string = "Fail, Fail to set ssid/password on SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step4, all STA join SSC1(soft AP) + for i in range(sta_number): + checker_stings = ["R SSC%d C +JAP:CONNECTED,%s" % (i + 2, ssid)] + test_action_string = ["SSCC SSC%d ap -C -s %s -p %s" % (i + 2, ssid, password)] + fail_string = "Fail, Fail to connect to SSC1" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=450) is False: + return + + # step5, get all the STA ip + for i in range(sta_number): + checker_stings = ["R SSC%d A :\+STAIP:192.168.4.(\d+)" % (i + 2, i + 2)] + test_action_string = ["SSCC SSC%d ip -Q" % (i + 2)] + fail_string = "Fail, Fail to get SSC%d ip" % (i + 2) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + else: + print "SSC%d ip is:" % (i + 2), self.get_parameter("SSC%d_IP" % (i + 2)) + + udp_port_list = [] + # step6, create multi UDP socket on all targets + for i in range(conn_number): + + udp_port = random.randint(10000, 20000) + udp_port_list.append(udp_port) + + checker_stings = ["R SSC2 A :\+BIND:(\d+),OK" % i] + test_action_string = ["SSCC SSC2 soc -B -t UDP -p %s" % udp_port] + fail_string = "Fail, SSC2 Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + checker_stings = ["R SSC3 A :\+BIND:(\d+),OK" % i] + test_action_string = ["SSCC SSC3 soc -B -t UDP -p %s" % (udp_port + 1)] + fail_string = "Fail, SSC3 Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step7, do send/recv, SSC2<---->other STAs + while time.time() - start_time < test_time: + # drop off the delay time if it's greater than 20ms + if send_delay > 20: + send_delay -= 10 + + checker_stings = [] + test_action_string = [] + if server_echo is True: + + # SSC2 send packets to SSC3 + ssc3_ip = "192.168.4." + self.get_parameter("SSC3_IP") + for i in range(conn_number): + test_action_string.append("SSC SSC2 soc -S -s -i %s -p %s -l %d -n 1000 -j %d" % ( + i, ssc3_ip, udp_port_list[i] + 1, send_len, send_delay)) + checker_stings.append("P SSC2 RE \+SEND:\d+,OK NC CLOSED NC ERROR") + + # SSC3 send packets to SSC2 + ssc2_ip = "192.168.4." + self.get_parameter("SSC2_IP") + for i in range(conn_number): + test_action_string.append("SSC SSC3 soc -S -s -i %s -p %s -l %d -n 1000 -j %d" % ( + i, ssc2_ip, udp_port_list[i], send_len, send_delay)) + checker_stings.append("P SSC3 RE \+SEND:\d+,OK NC CLOSED NC ERROR") + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=300) is False: + break + + NativeLog.add_trace_critical("time escape: %s" % (time.time() - start_time)) + if (time.time() - start_time) >= test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Failed") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPSendRecv.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPSendRecv.py new file mode 100755 index 0000000000..032062ad25 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPSendRecv.py @@ -0,0 +1,133 @@ +from TCAction import TCActionBase +from NativeLog import NativeLog +import time +import random +import string + +TEST_COUNT_ONE_ROUND = 1000 + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def cleanup(self): + # step 0 turn on recv print + checker_stings = ["R SSC1 C +RECVPRINT:1"] + test_action_string = ["SSC SSC1 soc -R -o 1"] + fail_string = "Fail, Fail to turn on recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + send_len = self.send_len + test_time = self.test_time * 60 + duplex = self.duplex + conn_num = self.conn_num + send_delay = self.send_delay + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for UDPSendRecv script, error is %s" % e) + raise StandardError("Error configuration") + + ssid = "".join([random.choice(string.lowercase) for m in range(10)]) + password = "".join([random.choice(string.lowercase) for m in range(10)]) + + # step 0 set ap + checker_stings = ["R SSC1 C +SAP:OK"] + test_action_string = ["SSC SSC1 ap -S -s %s -p %s -t 3" % (ssid, password)] + fail_string = "Fail, Fail to set ap" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + # step 1 connect to ap and turn off recv print + checker_stings = ["R SSC2 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC2 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + checker_stings = ["R SSC2 A :\+STAIP:(\d+\.\d+\.\d+\.\d+)\r"] + test_action_string = ["SSC SSC2 ip -Q -o 1"] + fail_string = "Fail, Fail to connect to server" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + checker_stings = ["P SSC1 C +RECVPRINT:0", "P SSC2 C +RECVPRINT:0"] + test_action_string = ["SSC SSC1 soc -R -o 0", "SSC SSC2 soc -R -o 0"] + fail_string = "Fail, Fail to turn off recv print" + self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, check_time=200) is False: + return + + # step 2 create conn_num udp socket + for i in range(1, conn_num+1): + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK" % i, + "R SSC2 A :\+BIND:(\d+),OK" % i] + test_action_string = ["SSC SSC1 soc -B -t UDP -p " % i, + "SSC SSC2 soc -B -t UDP -p " % i] + fail_string = "Fail, Fail to create socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + return + + start_time = time.time() + # step 3, do send/recv + while time.time()-start_time < test_time: + + checker_stings = ["P SSC1 NC ERROR NC CLOSE NC ERROR"] + for i in range(1, conn_num+1): + test_action_string = ["SSC SSC2 soc -S -s -l %d -n %d -j %d " + "-i -p " % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay, i)] + checker_stings.append("P SSC2 RE \"\+SEND:%%%%s,OK\"%%%%() NC ERROR NC CLOSE NC ERROR" % i) + if duplex is True: + test_action_string.append("SSC SSC1 soc -S -s -l %d -n %d -j %d" + " -i -p " % + (i, send_len, TEST_COUNT_ONE_ROUND, send_delay, i)) + checker_stings.append("P SSC1 RE \"\+SEND:%%%%s,OK\"%%%%()" % i) + + fail_string = "Fail, Failed on send command" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + break + time.sleep(1) + + fail_string = "Fail, Failed to send/recv data" + if self.load_and_exe_one_step(checker_stings, ["DELAY 0.1"], fail_string, + check_freq=1, check_time=300) is False: + break + pass + + NativeLog.add_prompt_trace("time escape: %s" % (time.time() - start_time)) + if time.time() - start_time >= test_time: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Fail") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() + + diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPThroughput.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPThroughput.py new file mode 100755 index 0000000000..861f6010d8 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/UDPThroughput.py @@ -0,0 +1,321 @@ +import os +import time +import random +import threading +import socket + +from TCAction import TCActionBase +from NativeLog import NativeLog +from NativeLog import ThroughputResult +from Utility import RSSICalibrator +from Utility import MakeFolder + + +LOG_FOLDER = os.path.join("Performance", "Throughput") + + +AP_PROP_KEY = ("ssid", "password", "apc") + + +class SendThread(threading.Thread): + def __init__(self, sock, send_len, target_addr): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.send_len = send_len + self.target_addr = target_addr + self.exit_event = threading.Event() + pass + + def exit(self): + self.exit_event.set() + + def run(self): + data = "A" * self.send_len + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + self.sock.sendto(data, self.target_addr) + except StandardError: + break + pass + + +class RecvThread(threading.Thread): + def __init__(self, sock): + threading.Thread.__init__(self) + self.setDaemon(True) + self.sock = sock + self.exit_event = threading.Event() + self.calc_event = threading.Event() + self.bytes_recv = 0 + + def start_calc(self): + self.calc_event.set() + + def stop_calc(self): + self.calc_event.clear() + self.exit_event.set() + + def run(self): + if self.sock is None: + return + while True: + if self.exit_event.isSet() is True: + break + try: + data, addr = self.sock.recvfrom(65535) + except StandardError: + break + if self.calc_event.isSet() is True: + self.bytes_recv += len(data) + + def get_bytes_recv(self): + return self.bytes_recv + pass + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.performance_folder_path = log_path + self.att_test_list = range(60) + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + ap_list = self.get_parameter("shield_box_ap_list") + pc_ip = self.get_parameter("pc_ip") + send_len = self.send_len + att_test_list = self.att_test_list + tx_enable = self.tx_enable + rx_enable = self.rx_enable + measure_period = self.measure_period + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for TCPThroughput script, error is %s" % e) + raise StandardError("Error configuration") + + udp_port = random.randint(40000, 50000) + + # init throughput result data + test_item = "" + if tx_enable is True: + test_item += "Tx" + if rx_enable is True: + test_item += "Rx" + if test_item == "": + raise StandardError("no throughput test item") + + folder_path = os.path.join(self.performance_folder_path, LOG_FOLDER) + file_name = os.path.join(folder_path, + "UDPThroughput_%s_%s" % (test_item, time.strftime("%d%H%M%S", time.localtime()))) + + result = ThroughputResult.ThroughputResult(file_name) + + # restart before executing throughput + checker_stings = ["R SSC1 C !!!ready!!!"] + test_action_string = ["SSC SSC1 reboot"] + fail_string = "Fail, Fail to reboot" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + # disable recv print during throughput test + checker_stings = ["R SSC1 C +RECVPRINT"] + test_action_string = ["SSC SSC1 soc -R -o 0"] + fail_string = "Fail, Fail to disable recv print" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + self.result_cntx.set_result("Fail") + return + + ret = True + for ap_prop in ap_list: + ssid = ap_prop[0] + password = ap_prop[1] + apc = ap_prop[2] + if ap_prop[1] == "": + # set a default string for open ap + password = "1" + + # switch off all outlet, switch on AP outlet + outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") + outlet_config_dict[apc] = "ON" + apc_cmd = "APC " + for outlet in outlet_config_dict: + apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) + checker_stings = ["P PC_COM L OK"] + fail_string = "Fail, Fail to switch apc" + if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: + ret = False + break + + # wait AP ready + time.sleep(20) + + # create server + udp_sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) + udp_sock.bind((pc_ip, udp_port)) + udp_sock.settimeout(1) + + if tx_enable is True: + result.add_test_item(ssid + "_tx") + if rx_enable is True: + result.add_test_item(ssid + "_rx") + + # create RSSI Calibrator + calibrator = RSSICalibrator.Calibrator() + + for att_value in att_test_list: + # step 0 set att value + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %s" % att_value] + fail_string = "Fail, Fail to set att value" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + # step 1 get AP RSSI + checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)\r" % ssid] + test_action_string = ["SSC SSC1 sta -S -s %s" % ssid] + fail_string = "Fail, Fail to scan" + rssi = scan_count = 0 + for i in range(3): + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + rssi += int(self.test_env.get_variable_by_name("rssi")[1]) + scan_count += 1 + + rssi = calibrator.calibrate_rssi(float(rssi)/scan_count if scan_count > 0 else 0, att_value) + # step 2 connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + if rssi < -89: + continue + else: + ret = False + break + # continue + checker_stings = ["R SSC1 A :STAIP:(\d+\.\d+\.\d+\.\d+)"] + test_action_string = ["SSC SSC1 ip -Q"] + fail_string = "Fail, Fail to get ip" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=30) is False: + if rssi < -89: + continue + else: + ret = False + break + # continue + target_ip = self.get_parameter("target_ip") + + # step 3 close all connections + checker_stings = ["R SSC1 C +CLOSEALL"] + test_action_string = ["SSC SSC1 soc -T"] + fail_string = "Fail, Fail to close socket" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + + # step 4 create UDP socket + checker_stings = ["R SSC1 A :\+BIND:(\d+),OK"] + test_action_string = ["SSC SSC1 soc -B -t UDP -i %s -p %s" % (target_ip, udp_port)] + fail_string = "Fail, Fail to bind" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + ret = False + break + # continue + + # step 5 do throughput test + send_thread = SendThread(udp_sock if rx_enable is True else None, + send_len, (target_ip, udp_port)) + send_thread.start() + + recv_thread = RecvThread(udp_sock if tx_enable is True else None) + recv_thread.start() + + if tx_enable is True: + # do send from target + test_action_string = ["SSC SSC1 soc -S -s -l %s -n 10000000 -i %s -p %s" + % (send_len, pc_ip, udp_port)] + fail_string = "Fail, Fail to send" + if self.load_and_exe_one_step([], test_action_string, fail_string) is False: + pass + + # start throughput calculate + recv_thread.start_calc() + + # sleep for measure period + time.sleep(measure_period) + + # stop throughput calculate + recv_thread.stop_calc() + send_thread.exit() + + send_thread.join() + recv_thread.join() + + # output throughput result + # in Mbps + if rx_enable is True: + # get received data len from PC + self.load_and_exe_one_step(["R SSC1 A :RECVLEN:(\d+)"], + ["SSC SSC1 soc -Q -s -o 1"], + "Fail, Fail to get recv data len") + try: + rx_data_len = int(self.get_parameter("recv_len")) + except StandardError: + rx_data_len = 0 + + result.log_throughput(ssid + "_rx", rssi, att_value, + float(rx_data_len * 8) / (measure_period * 1000000)) + + if recv_thread.get_bytes_recv() > 0: + result.log_throughput(ssid + "_tx", rssi, att_value, + float(recv_thread.get_bytes_recv() * 8) / (measure_period * 1000000)) + + result.output_to_file() + pass + + udp_sock.close() + if not ret: + NativeLog.add_trace_critical("Test SUC for %s" % ssid) + elif ret: + NativeLog.add_trace_critical("Test FAIL for %s!!!" % ssid) + + if ret: + self.result_cntx.set_result("Succeed") + else: + self.result_cntx.set_result("Fail") + + # finally, execute done + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/UDPStress/__init__.py b/components/idf_test/integration_test/TestCaseScript/UDPStress/__init__.py new file mode 100755 index 0000000000..d29ee405a4 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/UDPStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["UDPSendRecv", ] diff --git a/components/idf_test/integration_test/TestCaseScript/WiFiStress/SoftAPNSTA.py b/components/idf_test/integration_test/TestCaseScript/WiFiStress/SoftAPNSTA.py new file mode 100755 index 0000000000..b8eb75a589 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/WiFiStress/SoftAPNSTA.py @@ -0,0 +1,178 @@ +import random +import time +import string +import threading + +from TCAction import TCActionBase +from NativeLog import NativeLog +from TCAction import PerformanceTCBase +from Utility import Encoding + + +class STAJAPThread(threading.Thread): + def __init__(self, test_action, port_name, ssid, password, delay1, delay2, change_mac): + threading.Thread.__init__(self) + self.setDaemon(True) + self.test_action = test_action + self.port_name = port_name + self.ssid = ssid + self.password = password + self.delay1 = delay1 + self.delay2 = delay2 + self.change_mac = change_mac + self.exit_flag = threading.Event() + pass + + def exit(self): + self.exit_flag.set() + pass + + def run(self): + total_test_count = 0 + fail_count = 0 + while self.exit_flag.isSet() is False: + # change mac + if self.change_mac is True: + mac = Encoding.generate_random_mac() + self.test_action.serial_write_line(self.port_name, "mac -S -o 1 -m %s" % mac) + self.test_action.check_response(self.port_name, "+MAC:STA,OK") + + time.sleep(1) + + # JAP + total_test_count += 1 + # flush current port data + self.test_action.flush_data(self.port_name) + self.test_action.serial_write_line(self.port_name, "sta -C -s %s -p %s" % (self.ssid, self.password)) + if self.test_action.check_response(self.port_name, "+JAP:CONNECTED", 45) is False: + fail_count += 1 + NativeLog.add_trace_critical("[%s] Failed to JAP, Failed/Total : %d/%d" + % (self.port_name, fail_count, total_test_count)) + continue + time.sleep(random.randint(self.delay1[0], self.delay1[1])) + + # QAP + self.test_action.serial_write_line(self.port_name, "sta -D") + if self.test_action.check_response(self.port_name, "+QAP:OK", 5) is False: + NativeLog.add_trace_critical("[%s] Failed to QAP" % self.port_name) + time.sleep(random.randint(self.delay2[0], self.delay2[1])) + + # make sure quit AP + self.test_action.serial_write_line(self.port_name, "sta -D") + pass + pass + + +class TestCase(PerformanceTCBase.PerformanceTCBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + PerformanceTCBase.PerformanceTCBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.sta_num = 0 + self.max_sta = 4 + self.test_time = 60 + self.delay1 = [5, 30] + self.delay2 = [5, 10] + self.change_mac = True + self.channel = 11 + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + pass + + def process(self): + # configurable parameters + try: + sta_num = self.sta_num + max_sta = self.max_sta + test_time = self.test_time + # delay between JAP succeed and QAP + delay1 = self.delay1 + # delay between QAP and JAP + delay2 = self.delay2 + # if change mac each time before JAP + change_mac = self.change_mac + # channel + channel = self.channel + except StandardError, e: + raise StandardError("miss mandatory parameters") + + # step 0, set op mode and enable dhcp + self.serial_write_line("SSC1", "op -S -o 2") + if self.check_response("SSC1", "+MODE:OK", 2) is False: + NativeLog.add_trace_critical("Failed to set ap mode") + return + self.serial_write_line("SSC1", "dhcp -E -o 2") + if self.check_response("SSC1", "+DHCP:AP,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable ap dhcp") + return + self.serial_write_line("SSC1", "dhcp -L -s 192.168.4.2 -e 192.168.4.100 -t 1") + if self.check_response("SSC1", "+DHCP:LEASE,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable ap dhcp") + return + self.serial_write_line("SSC1", "dhcp -S -o 2") + if self.check_response("SSC1", "+DHCP:AP,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable ap dhcp") + return + + for i in range(sta_num): + self.serial_write_line("SSC%d" % (i+2), "op -S -o 1") + if self.check_response("SSC%d" % (i+2), "+MODE:OK", 2) is False: + NativeLog.add_trace_critical("Failed to set sta mode") + return + self.serial_write_line("SSC%d" % (i+2), "dhcp -S -o 1") + if self.check_response("SSC%d" % (i+2), "+DHCP:STA,OK", 2) is False: + NativeLog.add_trace_critical("Failed to enable sta dhcp") + + # step 1, set ap config and load + ap_ssid = "".join([random.choice(string.uppercase) for m in range(15)]) + ap_password = "".join([random.choice(string.lowercase) for m in range(15)]) + + self.serial_write_line("SSC1", "ap -S -s %s -p %s -t 3 -m %s -n %s" + % (ap_ssid, ap_password, max_sta, channel)) + if self.check_response("SSC1", "+SAP:OK", 2) is False: + NativeLog.add_trace_critical("Failed to set AP") + return + + # step 2, start thread to let STA JAP + sta_thread_list = [] + for i in range(sta_num): + sta_thread_list.append(STAJAPThread(self, "SSC%d" % (i+2), + ap_ssid, ap_password, delay1, delay2, change_mac)) + for sta_thread in sta_thread_list: + sta_thread.start() + + # step 3, sleep for test time + for i in range(test_time): + self.flush_data("SSC1") + time.sleep(60) + + # step 4, close all thread, will disconnect when exit thread + for sta_thread in sta_thread_list: + sta_thread.exit() + for sta_thread in sta_thread_list: + sta_thread.join() + # wait and make sure disconnect done + time.sleep(1) + + # step 5, join AP and check + sta_num_temp = max_sta if sta_num > max_sta else sta_num + + for i in range(sta_num_temp): + self.serial_write_line("SSC%d" % (i+2), "sta -C -s %s -p %s" % (ap_ssid, ap_password)) + if self.check_response("SSC%d" % (i+2), "+JAP:CONNECTED", 45) is False: + self.set_result("Fail") + break + pass + else: + self.set_result("Succeed") + + +def main(): + pass + +if __name__ == '__main__': + main() + diff --git a/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiConnUtility.py b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiConnUtility.py new file mode 100755 index 0000000000..24702bfc8d --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiConnUtility.py @@ -0,0 +1,240 @@ +from NativeLog import NativeLog +import time +import random + + +ERROR_AP_PROP = {"ssid": "123456789012345678901234567890", + "ssid_len": 30, + "pwd": "12345678901234567890", + "pwd_len": 20, + "channel": 10, + "enc": 3, + "apc": 9, # invalid apc count + } + + +class WifiConnUtilError(StandardError): + pass + + +class WifiConnUtility(object): + + def __init__(self, tc_action): + self.tc_action = tc_action + self.target_type = tc_action.target_type + pass + + def set_mode(self, mode): + ret = True + fail_string = "set mode fail" + cmd = [] + checker_stings = [] + for i in range(2): + if self.target_type[0] == "SSC": + cmd.append("SSCC SSC%d op -S -o %d" % (i+1, mode[i])) + checker_stings.append("SSCP SSC%d C +MODE:OK" % (i+1)) + pass + else: + cmd.append("ATC AT%d CWMODE %d" % (i+1, mode[i])) + checker_stings.append("ATP AT%d L OK" % (i+1)) + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Failed to set mode") + ret = False + return ret + pass + + def _apc_switch(self, outlet_list, action_list): + checker_stings = ["R PC_COM C OK"] + switch_cmd = "APC " + fail_string = "Error when switching APC" + ret = True + + for [_outlet, _action] in zip(action_list, outlet_list): + switch_cmd += " %s %d" % (_action, _outlet) + + if self.tc_action.load_and_exe_one_step(checker_stings, [switch_cmd], + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("Error when switching APC") + ret = False + return ret + pass + + def _set_target_ap(self, ap_prop): + ret = True + fail_string = "set target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + if self.target_type[1] == "SSC": + if ap_prop["pwd"] == "": + cmd = ["SSCC SSC2 ap -S -s %s -t %d" % (ap_prop["ssid"], + ap_prop["enc"]) + ] + else: + cmd = ["SSCC SSC2 ap -S -s %s -p %s -t %d" % (ap_prop["ssid"], + ap_prop["pwd"], + ap_prop["enc"]) + ] + checker_stings = ["SSCP SSC2 C +SAP:OK"] + pass + else: + cmd = ["ATC AT2 CWSAP \"%s\" \"%s\" %d %d" % (ap_prop["ssid"], + ap_prop["pwd"], + ap_prop["channel"], + ap_prop["enc"]) + ] + checker_stings = ["ATR AT2 L OK"] + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical("set target ap fail") + ret = False + return ret + pass + + def setup_ap(self, ap_type, ap_prop): + if ap_type == "target": + ret = self._set_target_ap(ap_prop) + pass + else: + ret = self._apc_switch(["ON"], [ap_prop["apc"]]) + # delay for 5 seconds, wait AP ready + time.sleep(5) + pass + return ret + + def do_scan(self, ap_prop): + fail_string = "Scan fail" + ret = True + # do not check if the set AP can be scanned + if self.target_type[1] == "SSC": + cmd = ["SSCC SSC1 sta -S"] + checker_stings = ["SSCR SSC1 C +SCANDONE"] + pass + else: + cmd = ["ATS AT1 AT+CWLAP"] + checker_stings = ["ATR AT1 L OK"] + pass + if self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=100) is False: + NativeLog.add_trace_critical("Scan fail") + ret = False + return ret + pass + + def _switch_off_target_ap(self, delay): + time.sleep(delay) + self._set_target_ap(ERROR_AP_PROP) + pass + + def _switch_on_target_ap(self, ap_prop, delay): + time.sleep(delay) + self._set_target_ap(ap_prop) + pass + + def _switch_off_ap(self, ap_type, ap_prop, delay_range): + delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 + if ap_type == "target": + self._switch_off_target_ap(delay) + else: + delay -= 1.5 + time.sleep(delay if delay > 0 else 0) + self._apc_switch(["OFF"], [ap_prop["apc"]]) + pass + + def _switch_on_ap(self, ap_type, ap_prop, delay_range): + delay = random.randint(delay_range[0]*10, delay_range[1]*10)/10 + if ap_type == "target": + self._switch_on_target_ap(ap_prop, delay) + else: + delay -= 1.5 + time.sleep(delay if delay > 0 else 0) + self._apc_switch(["ON"], [ap_prop["apc"]]) + pass + + def _join_ap(self, ap_prop, test_method): + fail_string = "join target ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + if self.target_type[1] == "SSC": + cmd = ["SSCC SSC1 ap -C -s %s -p %s" % (ap_prop["ssid"], + ap_prop["pwd"],) + ] + checker_stings = ["SSCR SSC1 C +JAP:CONNECTED"] + pass + else: + cmd = ["ATC AT1 CWJAP \"%s\" \"%s\"" % (ap_prop["ssid"], + ap_prop["pwd"]) + ] + checker_stings = ["ATR AT1 NC ERROR NC FAIL L OK"] + pass + if test_method == "Normal": + ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_freq=0.1, check_time=350) + if ret is not False: + ret *= 0.1 + else: + ret = self.tc_action.load_and_exe_one_step([], cmd, fail_string) + return ret + pass + + def _check_join_ap_result(self, ap_prop): + ret = False + fail_string = "join ap fail, %s, %s" % (ap_prop["ssid"], ap_prop["pwd"]) + + if self.target_type[1] == "SSC": + checker_stings = ["SSCR SSC1 C +JAP:CONNECTED"] + ret = self.tc_action.load_and_exe_one_step(checker_stings, ["DELAY 0"], + fail_string, check_freq=1, check_time=120) + pass + else: + cmd = ["ATS AT1 AT+CWJAP?"] + checker_stings = ["ATR AT1 NC busy NC No%20AP C +CWJAP"] + for i in range(3): + ret = self.tc_action.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_freq=1, check_time=2) + if ret is not False: + break + time.sleep(15) + + return ret + pass + + def join_ap(self, join_test_method, ap_type, ap_prop, delay): + + if join_test_method == "WRONG_PROP": + _prop = ERROR_AP_PROP + else: + _prop = ap_prop + + ret = self._join_ap(_prop, join_test_method) + + if join_test_method == "OFF_ON": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + self._switch_on_ap(ap_type, ap_prop, delay[1]) + ret = self._check_join_ap_result(_prop) + pass + elif join_test_method == "OFF": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + time.sleep(25) + pass + + return ret + pass + + def do_reconnect(self, reconnect_test_method, ap_type, ap_prop, delay): + ret = True + if reconnect_test_method == "OFF_ON": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + self._switch_on_ap(ap_type, ap_prop, delay[1]) + ret = self._check_join_ap_result(ap_prop) + pass + elif reconnect_test_method == "OFF": + self._switch_off_ap(ap_type, ap_prop, delay[0]) + pass + return ret + pass + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiJAP.py b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiJAP.py new file mode 100755 index 0000000000..64346be17f --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiJAP.py @@ -0,0 +1,219 @@ +import os +import random +import time + +import WifiConnUtility +from NativeLog import NativeLog +from TCAction import TCActionBase +from Utility import Encoding +from Utility import MakeFolder + +STEPS = {"SCAN1": 0x01, "JAP": 0x02, "SCAN2": 0x04, "RECONNECT": 0x08} + +AP_PROP = ("ssid", "ssid_len", "pwd", + "pwd_len", "channel", "enc", "apc") + +JAP_TEST_METHOD = ("Normal", "OFF_ON", "OFF", "WRONG_PROP") + +RECONNECT_TEST_METHOD = ("OFF_ON", "OFF") + +LOG_FOLDER = os.path.join("Performance", "JAP") + + +SSID_LEN_RANGE = (1, 32) # in bytes +ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP +PWD_RANGE = {0: [0, 0], + 1: [5, 5], + 2: [8, 63], + 3: [8, 63], + 4: [8, 63], + } + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + # default value for optional configurable params + self.performance_folder_path = log_path + self.pwd_len = [8, 64] + self.step_config = [0x03, 0x01, 0x02, 0x0B, 0x0F] + self.join_test_method = ["Normal"] + self.join_delay = [[1.5, 5], [1.5, 5]] + self.reconnect_test_method = ["OFF_ON"] + self.reconnect_delay = [[1.5, 5], [1.5, 6]] + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + # read AP list + self.ap_list = [] + for i in range(1, len(cmd_set)): + for j in range(len(cmd_set[i][1])): + if cmd_set[i][1][j] != "": + cmd_string = "self.ap_list.append(dict(zip(AP_PROP, " + cmd_set[i][1][j] + ")))" + exec cmd_string + + folder_path = MakeFolder.make_folder(self.performance_folder_path + "\\" + LOG_FOLDER) + file_name = "JAP_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) + self._performance_log_file = os.path.join(folder_path, file_name) + + # test statistics + self._succeed_count = self._fail_count = self._time_cost_count = 0 + self._total_time = self._longest_time = 0 + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + # get target type "SSC" or "AT" + self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] + self.target_type.append("SSC" if test_env.get_port_by_name("AT2") is None else "AT") + self._utility = WifiConnUtility.WifiConnUtility(self) + pass + + def _generate_random_ap_prop(self): + ap_prop = dict.fromkeys(AP_PROP) + # generate target ap_value + ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) + ap_prop["channel"] = random.choice(range(1, 14)) + ap_prop["enc"] = random.choice(ENC_TYPE) + ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) + # generate string + if self.target_type[0] == self.target_type[1] == "AT": + ap_prop["ssid"] = Encoding.generate_random_utf8_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_utf8_str(ap_prop["pwd_len"]) + # NativeLog.add_trace_info("ssid hex is : %x" % ap_prop["ssid"]) + # NativeLog.add_trace_info("pwd hex is : %x" % ap_prop["pwd"]) + else: + ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) + + return ap_prop + + def _logging_performance(self, ssid, join_method="Normal", time_cost=0): + # log performance to performance log file + with open(self._performance_log_file, "ab+") as f: + # log time and ssid + f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) + if join_method == "Normal" or join_method == "OFF_ON": + if time_cost is not False: + self._succeed_count += 1 + if join_method == "Normal": + f.write("[Succeed][%f]\r\n" % time_cost) + self._longest_time = (time_cost > self._longest_time and + [time_cost] or [self._longest_time])[0] + self._time_cost_count += 1 + self._total_time += time_cost + else: + f.write("[Succeed][%s]\r\n" % join_method) + else: + self._fail_count += 1 + f.write("[Fail][%s]\r\n" % join_method) + pass + + def _logging_fail_step(self, ssid, step): + with open(self._performance_log_file, "ab+") as f: + f.write("\r\n[%s]:\r\n[AP name] %s\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), ssid)) + f.write("[Fail][%s]\r\n" % step) + pass + + def _generate_performance_report(self): + with open(self._performance_log_file, "ab+") as f: + f.write("[Test report] Succeed: %d\r\n" % self._succeed_count) + f.write("[Test report] Failed: %d\r\n" % self._fail_count) + if self._succeed_count > 0 or self._fail_count > 0: + f.write("[Test report] Pass Rate: %f\r\n" % + (self._succeed_count/(self._fail_count+self._succeed_count))) + if self._time_cost_count > 0: + f.write("[Test report] Average time: %f\r\n" % (self._total_time/self._time_cost_count)) + f.write("[Test report] Longest time: %f\r\n" % self._longest_time) + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # mandatory configurable params + try: + target_ap_num = self.target_ap_num + test_count = self.test_count + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) + raise StandardError("Error configuration") + + # prepare ap list + _ap_list = [["target", None]] * target_ap_num + for _ap_prop in self.ap_list: + _ap_list.append(["AP", _ap_prop]) + + # set to correct mode first + self._utility.set_mode([1, 2]) + + for i in xrange(test_count): + _ap = random.choice(_ap_list) + # arrange ap + _ap_type = _ap[0] + _ap_prop = _ap[1] + if _ap_type == "target": + _ap_prop = self._generate_random_ap_prop() + pass + + # step 1 : mandatory step, set up AP + if self._utility.setup_ap(_ap_type, _ap_prop) is False: + self._logging_fail_step(_ap_prop["ssid"], "Set AP") + NativeLog.add_prompt_trace("[Step1] setup AP Fail") + continue + step_config = random.choice(self.step_config) + NativeLog.add_prompt_trace("[Step1] setup AP succeed") + + # step 2 : optional step, do scan before connect + if step_config & STEPS["SCAN1"] != 0: # check option + if self._utility.do_scan(_ap_prop) is False: + self._logging_fail_step(_ap_prop["ssid"], "Scan before JAP") + NativeLog.add_prompt_trace("[Step2] Scan Done") + + # step 3 : mandatory step, join AP + if step_config & STEPS["JAP"] != 0: # check option + _join_test_method = random.choice(self.join_test_method) + time_cost = self._utility.join_ap(_join_test_method, _ap_type, _ap_prop, self.join_delay) + # log performance to performance log file + self._logging_performance(_ap_prop["ssid"], _join_test_method, time_cost) + if time_cost is False: + # do scan once to check if AP exist + self._utility.do_scan(_ap_prop) + continue + NativeLog.add_prompt_trace("[Step3] Join AP done") + + # step 4 : optional step, scan after join AP + if step_config & STEPS["SCAN2"] != 0: # check option + if self._utility.do_scan(_ap_prop) is False: + self._logging_fail_step(_ap_prop["ssid"], "Scan after JAP") + NativeLog.add_prompt_trace("[Step4] Scan done") + + # step 5 : optional step, reconnect test + if step_config & STEPS["RECONNECT"] != 0: # check option + _reconnect_test_method = random.choice(self.reconnect_test_method) + if self._utility.do_reconnect(_reconnect_test_method, + _ap_type, _ap_prop, self.reconnect_delay) is False: + self._logging_fail_step(_ap_prop["ssid"], "Reconnect") + + NativeLog.add_prompt_trace("[Step5] Reconnect done") + # continue to next loop + NativeLog.add_prompt_trace("[WifiJAP] Test count %d done" % i) + + # generate report and cleanup + self._generate_performance_report() + + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiJAPAtt.py b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiJAPAtt.py new file mode 100755 index 0000000000..23eeba3f0e --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiJAPAtt.py @@ -0,0 +1,193 @@ +import os +import time +from TCAction import TCActionBase +from NativeLog import NativeLog +from Utility import RSSICalibrator +from Utility import MakeFolder + +MAX_RSSI = 0 +MIN_RSSI = -110 +MAX_ATT = 60 +LOG_FOLDER = os.path.join("Performance", "JAP") +AP_PROP_KEY = ("ssid", "password", "apc") + + +class Performance(object): + RSSI_THRESHOLD = -90 + + def __init__(self): + self.succeed_rssi = dict.fromkeys(range(MIN_RSSI, MAX_RSSI), 0) + self.failed_rssi = dict.fromkeys(range(MIN_RSSI, MAX_RSSI), 0) + self.failed_att = dict.fromkeys(range(MAX_ATT), 0) + self.result = True + pass + + def log_performance(self, result, att, rssi): + if result == "Succeed": + self.succeed_rssi[rssi] += 1 + else: + if rssi == 0: + self.failed_att[att] += 1 + else: + self.failed_rssi[rssi] += 1 + if rssi > self.RSSI_THRESHOLD: + self.result = False + pass + + def get_result(self): + return self.result + + def __str__(self): + data = "Succeed:\r\n" + for rssi in self.succeed_rssi: + if self.succeed_rssi[rssi] > 0: + data += "\tRSSI%4d: %2d times\r\n" % (rssi, self.succeed_rssi[rssi]) + + data += "Failed during scan:\r\n" + for att in self.failed_att: + if self.failed_att[att] > 0: + data += "\tATT%3d: %2d times\r\n" % (att, self.failed_att[att]) + + data += "Failed during JAP:\r\n" + for rssi in self.failed_rssi: + if self.failed_rssi[rssi] > 0: + data += "\tRSSI%4d: %2d times\r\n" % (rssi, self.failed_rssi[rssi]) + + return data + + pass + + +class TestCase(TCActionBase.CommonTCActionBase): + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.att_test_list = range(60) + self.performance_folder_path = log_path + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + self.ap_list = self.get_parameter("shield_box_ap_list") + + self.performance = dict([(ap_prop["ssid"], Performance()) for ap_prop in self.ap_list]) + # create log file + folder_path = MakeFolder.make_folder(self.performance_folder_path + "\\" + LOG_FOLDER) + self.performance_log = os.path.join(folder_path, + "JAP_Att_%s.log" % time.strftime("%d%H%M%S", time.localtime())) + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def log_performance(self, att, rssi, ssid, result): + NativeLog.add_prompt_trace("[%s][ssid %s] [att %s] [rssi %s]" % (result, ssid, att, rssi)) + data = "" + self.performance[ssid].log_performance(result, att, rssi) + for _ssid in self.performance: + data += "[ssid] %s\r\n%s\r\n" % (_ssid, self.performance[_ssid]) + with open(self.performance_log, "wb+") as f: + f.write(data) + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + try: + # configurable params + ap_list = self.ap_list + att_test_list = self.att_test_list + test_count = self.test_count + # configurable params + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for JAPAtt script, error is %s" % e) + raise StandardError("Error configuration") + + for x in xrange(test_count): + for ap_prop in ap_list: + ssid = ap_prop[0] + password = ap_prop[1] + apc = ap_prop[2] + if ap_prop[1] == "": + # set a default string for open ap + password = "1" + + # switch off all outlet, switch on AP outlet + outlet_config_dict = dict.fromkeys(range(1, 9), "OFF") + outlet_config_dict[apc] = "ON" + apc_cmd = "APC " + for outlet in outlet_config_dict: + apc_cmd += " %s %s" % (outlet_config_dict[outlet], outlet) + checker_stings = ["P PC_COM L OK"] + fail_string = "Fail, Fail to switch apc" + if self.load_and_exe_one_step(checker_stings, [apc_cmd], fail_string) is False: + return + + # wait AP ready + time.sleep(20) + + # create RSSI Calibrator + calibrator = RSSICalibrator.Calibrator() + + ret = True + for att_value in att_test_list: + # step 0 set att value + checker_stings = ["R PC_COM L OK"] + test_action_string = ["ATT %s" % att_value] + fail_string = "Fail, Fail to set att value" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string) is False: + continue + + # step 1 get AP RSSI + checker_stings = ["R SSC1 A :\+SCAN:%s,[:\d\w]+,\d+,\d+,([-\d]+)" % ssid] + test_action_string = ["SSC SSC1 sta -S -s %s" % ssid] + fail_string = "Fail, Fail to scan" + rssi = scan_count = 0 + for i in range(3): + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=5) is False: + self.log_performance(att_value, 0, ssid, "Failed to measure RSSI") + continue + rssi += int(self.test_env.get_variable_by_name("rssi")[1]) + scan_count += 1 + + rssi = calibrator.calibrate_rssi(float(rssi) / scan_count if scan_count > 0 else 0, att_value) + + # step 2 connect to AP + checker_stings = ["R SSC1 C +JAP:CONNECTED"] + test_action_string = ["SSC SSC1 sta -C -s %s -p %s" % (ssid, password)] + fail_string = "Fail, Fail to JAP" + if self.load_and_exe_one_step(checker_stings, test_action_string, fail_string, + check_freq=1, check_time=45) is False: + self.log_performance(att_value, rssi, ssid, "Failed to JAP") + if rssi < -90: + continue + else: + ret = False + break + if ret: + self.log_performance(att_value, rssi, ssid, "Succeed") + else: + self.log_performance(att_value, rssi, ssid, "Failed") + + # finally, execute done + for ssid in self.performance: + if self.performance[ssid].get_result() is False: + self.result_cntx.set_result("Failed") + break + else: + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiSmartConfig.py b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiSmartConfig.py new file mode 100755 index 0000000000..830de766c9 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/WiFiStress/WifiSmartConfig.py @@ -0,0 +1,274 @@ +import random +import os +import time +import copy + +from TCAction import TCActionBase +from NativeLog import NativeLog +from Utility import Encoding +from Utility import MakeFolder + +AP_PROP = ("ssid", "ssid_len", "pwd", + "pwd_len", "channel", "enc", "apc") + +SMART_TYPE = ("esp-touch", "airkiss") + +TEST_METHOD = ("ssid_broadcast", "ssid_hidden") + +HT = ("ht20", "ht40") + +TEST_STAT = ("total count", "fail count", "total time", "longest time") + +_TEST_STAT_INIT_DICT = {"total count": 0, + "fail count": 0, + "total time": 0, + "longest time": 0, + } + +LOG_FOLDER = os.path.join("Performance", "SmartConfig") + + +SSID_LEN_RANGE = (1, 32) # in bytes +ENC_TYPE = (0, 2, 3, 4) # do not support WEP for 8266 soft AP +PWD_RANGE = {0: [0, 0], + 1: [5, 5], + 2: [8, 32], + 3: [8, 32], + 4: [8, 32], + } + + +class TestCase(TCActionBase.CommonTCActionBase): + + def __init__(self, test_case, test_env, timeout=30, log_path=TCActionBase.LOG_PATH): + TCActionBase.CommonTCActionBase.__init__(self, test_case, test_env, timeout=timeout, log_path=log_path) + self.performance_folder_path = log_path + # default value for optional configurable params + self.test_method = ["ssid_hidden", "ssid_broadcast"] + self.bssid = "ff:ff:ff:ff:ff:ff" + self.ht_ap = dict(zip(HT, [("", ""), + ("", "")])) + self.ap_channel = {"ht20": 1, "ht40": 1} + self.delay_time = 3 # default 3s, wait for scan done + # load param from excel + cmd_set = test_case["cmd set"] + for i in range(1, len(cmd_set)): + if cmd_set[i][0] != "dummy" and cmd_set[i][0] != "": + cmd_string = "self." + cmd_set[i][0] + exec cmd_string + + folder_path = MakeFolder.make_folder(self.performance_folder_path + "\\" + LOG_FOLDER) + file_name = "SmartConfig_log_%s.log" % (time.strftime("%m%d%H%M%S", time.localtime())) + self._performance_log_file = os.path.join(folder_path, file_name) + + # type + self.target_type = ["SSC" if test_env.get_port_by_name("AT1") is None else "AT"] + self.target_type.append("SSC" if test_env.get_port_by_name("AT2") is None else "AT") + + # test statistics + # better ways to create? + _test_stat = dict.fromkeys(TEST_STAT, 0) + _test_method = dict.fromkeys(TEST_METHOD) + _test_ht = dict.fromkeys(HT) + self.test_stat = dict.fromkeys(SMART_TYPE) + for i in SMART_TYPE: + self.test_stat[i] = copy.deepcopy(_test_ht) + for j in HT: + self.test_stat[i][j] = copy.deepcopy(_test_method) + for k in TEST_METHOD: + self.test_stat[i][j][k] = copy.deepcopy(_test_stat) + + self.result_cntx = TCActionBase.ResultCheckContext(self, test_env, self.tc_name) + pass + + def _generate_random_ap_prop(self, ht_type): + ap_prop = dict.fromkeys(AP_PROP) + # generate target ap_value + ap_prop["ssid_len"] = random.randint(SSID_LEN_RANGE[0], SSID_LEN_RANGE[1]) + ap_prop["channel"] = self.ap_channel[ht_type] + ap_prop["enc"] = random.choice(ENC_TYPE) + ap_prop["pwd_len"] = random.randint(PWD_RANGE[ap_prop["enc"]][0], PWD_RANGE[ap_prop["enc"]][1]) + ap_prop["ssid"] = Encoding.generate_random_printable_str(ap_prop["ssid_len"]) + ap_prop["pwd"] = Encoding.generate_random_printable_str(ap_prop["pwd_len"]) + + return ap_prop + + def _logging_performance(self, time_cost, ssid, password, smart_type, test_method, ht_type): + # update test statistics + stat = self.test_stat[smart_type][ht_type][test_method] + stat["total count"] += 1 + # log performance to performance log file + with open(self._performance_log_file, "ab+") as f: + # log time and ssid + if time_cost is not False: + time_tmp = float(time_cost)/10 + f.write("\r\n[%s]:\r\n[Succeed] [%.2f]\r\n" % + (time.strftime("%m-%d %H:%M:%S", time.localtime()), time_tmp)) + stat["total time"] += time_tmp + stat["longest time"] = time_tmp if time_tmp > stat["longest time"] else stat["longest time"] + else: + f.write("\r\n[%s]:\r\n[Fail]\r\n" % + time.strftime("%m-%d %H:%M:%S", time.localtime())) + stat["fail count"] += 1 + + f.write("[%s] [%s] [%s]\r\n" % + (smart_type, test_method, ht_type)) + f.write("[ssid] %s \r\n[password] %s\r\n" % + (ssid, password)) + pass + + def _generate_performance_report(self): + with open(self._performance_log_file, "ab+") as f: + for i in SMART_TYPE: + for j in HT: + for k in TEST_METHOD: + stat = self.test_stat[i][j][k] + f.write("\r\n[Test report] [%s] [%s] [%s]\r\n" % (i, j, k)) + if stat["total count"] > 0: + f.write("[Total]: %d\r\n" % stat["total count"]) + f.write("[Failed]: %d\r\n" % stat["fail count"]) + f.write("[Fail ratio]: %.2f%%\r\n" % + (float(stat["fail count"])/stat["total count"] * 100)) + f.write("[Longest time cost]: %.2f\r\n" % stat["longest time"]) + if (stat["total count"] - stat["fail count"]) > 0: + f.write("[Average time cost]: %.2f\r\n" % + (stat["total time"]/(stat["total count"]-stat["fail count"]))) + + @staticmethod + def cmd_exception_catcher(e): + raise e + pass + + def execute(self): + TCActionBase.TCActionBase.execute(self) + self.result_cntx.start() + + # mandatory configurable params + try: + test_count = self.test_count + delay_time = self.delay_time + except StandardError, e: + NativeLog.add_trace_critical("Error configuration for WifiJAP script, error is %s" % e) + raise StandardError("Error configuration") + + # step 0 : set AT1 mode + fail_string = "Fail to restore init condition" + if self.target_type[0] == "AT": + cmd = ["ATS AT1 AT+CWMODE=1"] + checker_stings = ["R AT1 L OK"] + else: + cmd = ["SSC SSC1 op -S -o 1"] + checker_stings = ["R SSC1 C +MODE:OK"] + if self.target_type[1] == "AT": + cmd.append("ATS AT2 AT+CWMODE=2") + checker_stings.append("R AT2 L OK") + else: + cmd.append("SSC SSC2 op -S -o 2") + checker_stings.append("R SSC2 C +MODE:OK") + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=150) is False: + NativeLog.add_trace_critical(fail_string) + return + + for i in xrange(test_count): + _method = random.choice(self.test_method) + _ht = random.choice(self.ht) + _ap_prop = self._generate_random_ap_prop(_ht) + _smart_type = random.choice(self.smart_type) + _ht_ap = self.ht_ap[_ht] + is_hidden = 0 if _method == "ssid_broadcast" else 1 + # get ip and + + # step 1 : restore init condition + fail_string = "Fail to restore init condition" + if self.target_type[0] == "AT": + cmd = ["ATS AT1 AT+CWSTOPSMART", "WIFI CONN %s %s " % (_ht_ap[0], _ht_ap[1])] + checker_stings = ["P AT1 L OK", "P PC_COM L OK"] + else: + cmd = ["SSC SSC1 smart -E", "WIFI CONN %s %s " % (_ht_ap[0], _ht_ap[1])] + checker_stings = ["P SSC1 C +SC:OK", "P PC_COM L OK"] + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=200) is False: + NativeLog.add_trace_critical(fail_string) + continue + NativeLog.add_prompt_trace("Step1 Done") + + # step 2 : test method is ssid_broadcast, then set AP on target 2 + if _method == "ssid_broadcast": + fail_string = "Fail to set AP" + if self.target_type[1] == "AT": + cmd = ["ATS AT2 AT+CWSAP=\"%s\",\"%s\",%d,%d" % (_ap_prop["ssid"], _ap_prop["pwd"], + _ap_prop["channel"], _ap_prop["enc"])] + checker_stings = ["R AT2 L OK"] + else: + cmd = ["SSC SSC2 ap -S -s %s -p %s -n %d -t %d" % (_ap_prop["ssid"], _ap_prop["pwd"], + _ap_prop["channel"], _ap_prop["enc"])] + checker_stings = ["R SSC2 C +SAP:OK"] + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical(fail_string) + continue + NativeLog.add_prompt_trace("Step2 Done") + + # step 3 : start SMART + fail_string = "Fail to start smart config" + if self.target_type[0] == "AT": + cmd = ["ATS AT1 AT+CWSTARTSMART"] + checker_stings = ["R AT1 L OK"] + else: + cmd = ["SSC SSC1 smart -S -a 0"] + checker_stings = ["R SSC1 C +SC:OK"] + + if self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=50) is False: + NativeLog.add_trace_critical(fail_string) + continue + # sleep for delay_time seconds to wait scan done or simulate delay config situation + time.sleep(delay_time) + NativeLog.add_prompt_trace("Step3 Done") + + # step 4 : do smart config + fail_string = "Fail in smart config" + cmd = ["SMART %s %s %s %s %d" + % (_smart_type, _ap_prop["ssid"], _ap_prop["pwd"], self.bssid, is_hidden)] + if self.target_type[0] == "AT": + checker_stings = ["P AT1 C Smart%20get%20wifi%20info", + "P LOG1 C %s C %s" % (_ap_prop["ssid"], _ap_prop["pwd"])] + else: + checker_stings = ["P SSC1 C %s C %s" % (_ap_prop["ssid"], _ap_prop["pwd"])] + + try: + time_cost = self.load_and_exe_one_step(checker_stings, cmd, + fail_string, check_time=400, + cmd_exception_catcher=self.cmd_exception_catcher) + except StandardError: + NativeLog.add_prompt_trace("Exception occurred during executing cmd") + continue + pass + self._logging_performance(time_cost, _ap_prop["ssid"], _ap_prop["pwd"], + _smart_type, _method, _ht) + if time_cost is False: + NativeLog.add_prompt_trace(fail_string) + continue + + # continue to next loop + NativeLog.add_prompt_trace("[WifiSmartConfig] Test count %d done" % i) + + # generate report and cleanup + self._generate_performance_report() + + self.result_cntx.set_result("Succeed") + + def result_check(self, port_name, data): + TCActionBase.CommonTCActionBase.result_check(self, port_name, data) + self.result_cntx.append_data(port_name, data) + + +def main(): + pass + +if __name__ == '__main__': + main() diff --git a/components/idf_test/integration_test/TestCaseScript/WiFiStress/__init__.py b/components/idf_test/integration_test/TestCaseScript/WiFiStress/__init__.py new file mode 100755 index 0000000000..7960a3ce80 --- /dev/null +++ b/components/idf_test/integration_test/TestCaseScript/WiFiStress/__init__.py @@ -0,0 +1 @@ +__all__ = ["WifiJAP", ] \ No newline at end of file diff --git a/components/idf_test/unit_test/TestCaseAll.yml b/components/idf_test/unit_test/TestCaseAll.yml index 6f974e0bf5..4e5c01f219 100644 --- a/components/idf_test/unit_test/TestCaseAll.yml +++ b/components/idf_test/unit_test/TestCaseAll.yml @@ -7,9 +7,9 @@ test cases: category: Function cmd set: - IDFUnitTest/UnitTest - - - test_case = "check if ROM is used for functions" + - - test_case = "check if ROM or Flash is used for functions" - [dummy] - comment: check if ROM is used for functions + comment: check if ROM or Flash is used for functions execution time: 0 expected result: 1. set succeed initial condition: UTINIT1 diff --git a/components/lwip/apps/dhcpserver.c b/components/lwip/apps/dhcpserver.c index fcb27f0b05..94acc881e2 100644 --- a/components/lwip/apps/dhcpserver.c +++ b/components/lwip/apps/dhcpserver.c @@ -268,12 +268,14 @@ static u8_t *add_offer_options(u8_t *optptr) tcpip_adapter_get_ip_info(ESP_IF_WIFI_AP, &if_ip); - *optptr++ = DHCP_OPTION_ROUTER; - *optptr++ = 4; - *optptr++ = ip4_addr1(&if_ip.gw); - *optptr++ = ip4_addr2(&if_ip.gw); - *optptr++ = ip4_addr3(&if_ip.gw); - *optptr++ = ip4_addr4(&if_ip.gw); + if (!ip4_addr_isany_val(if_ip.gw)) { + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = 4; + *optptr++ = ip4_addr1(&if_ip.gw); + *optptr++ = ip4_addr2(&if_ip.gw); + *optptr++ = ip4_addr3(&if_ip.gw); + *optptr++ = ip4_addr4(&if_ip.gw); + } } #ifdef USE_DNS diff --git a/components/lwip/component.mk b/components/lwip/component.mk index 49fc644ae4..df116f1a06 100644 --- a/components/lwip/component.mk +++ b/components/lwip/component.mk @@ -6,5 +6,7 @@ COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port include/lwip/posix COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/freertos port/netif port -CFLAGS += -Wno-address -Wno-unused-variable -Wno-unused-but-set-variable +CFLAGS += -Wno-address # lots of LWIP source files evaluate macros that check address of stack variables +api/tcpip.o apps/dhcpserver.o: CFLAGS += -Wno-unused-variable +apps/dhcpserver.o core/pbuf.o core/tcp_in.o: CFLAGS += -Wno-unused-but-set-variable diff --git a/components/lwip/core/pbuf.c b/components/lwip/core/pbuf.c index 29e24ef2b4..b954817492 100755 --- a/components/lwip/core/pbuf.c +++ b/components/lwip/core/pbuf.c @@ -80,6 +80,7 @@ #if ESP_LWIP #include "esp_wifi_internal.h" +#include "esp_eth.h" #endif #define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) @@ -351,7 +352,8 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) p->flags = 0; #if ESP_LWIP - p->eb = NULL; + p->user_buf = NULL; + p->user_flag = PBUF_USER_FLAG_OWNER_NULL; #endif LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); @@ -720,9 +722,13 @@ pbuf_free(struct pbuf *p) } else if (type == PBUF_ROM || type == PBUF_REF) { #if ESP_LWIP - if (type == PBUF_REF && p->eb != NULL ) esp_wifi_internal_free_rx_buffer(p->eb); + if (type == PBUF_REF && p->user_flag == PBUF_USER_FLAG_OWNER_WIFI ) { + esp_wifi_internal_free_rx_buffer(p->user_buf); + } + if (type == PBUF_REF && p->user_flag == PBUF_USER_FLAG_OWNER_ETH ) { + esp_eth_free_rx_buf(p->user_buf); + } #endif - memp_free(MEMP_PBUF, p); /* type == PBUF_RAM */ } else { diff --git a/components/lwip/include/lwip/lwip/pbuf.h b/components/lwip/include/lwip/lwip/pbuf.h index 1834c4e04c..d84aabaf81 100755 --- a/components/lwip/include/lwip/lwip/pbuf.h +++ b/components/lwip/include/lwip/lwip/pbuf.h @@ -105,6 +105,12 @@ typedef enum { /** indicates this pbuf includes a TCP FIN flag */ #define PBUF_FLAG_TCP_FIN 0x20U +#if ESP_LWIP +#define PBUF_USER_FLAG_OWNER_NULL 0 +#define PBUF_USER_FLAG_OWNER_WIFI 1 +#define PBUF_USER_FLAG_OWNER_ETH 2 +#endif + struct pbuf { /** next pbuf in singly linked pbuf chain */ struct pbuf *next; @@ -138,7 +144,8 @@ struct pbuf { u16_t ref; #if ESP_LWIP - void *eb; + void *user_buf; + u8_t user_flag; #endif }; diff --git a/components/lwip/port/freertos/sys_arch.c b/components/lwip/port/freertos/sys_arch.c index 8d0dd08c58..97ee32d1bd 100755 --- a/components/lwip/port/freertos/sys_arch.c +++ b/components/lwip/port/freertos/sys_arch.c @@ -42,6 +42,9 @@ /* This is the number of threads that can be started with sys_thread_new() */ #define SYS_THREAD_MAX 4 +static bool g_lwip_in_critical_section = false; +static BaseType_t g_lwip_critical_section_needs_taskswitch; + #if !LWIP_COMPAT_MUTEX /** Create a new mutex * @param mutex pointer to the mutex to create @@ -122,7 +125,18 @@ sys_sem_new(sys_sem_t *sem, u8_t count) void sys_sem_signal(sys_sem_t *sem) { - xSemaphoreGive(*sem); + if (g_lwip_in_critical_section){ + /* In function event_callback in sockets.c, lwip signals a semaphore inside a critical + * section. According to the FreeRTOS documentation for FreertosTaskEnterCritical, it's + * not allowed to call any FreeRTOS API function within a critical region. Unfortunately, + * it's not feasible to rework the affected region in LWIP. As a solution, when in a + * critical region, we call xSemaphoreGiveFromISR. This routine is hand-vetted to work + * in a critical region and it will not cause a task switch. + */ + xSemaphoreGiveFromISR(*sem, &g_lwip_critical_section_needs_taskswitch); + } else { + xSemaphoreGive(*sem); + } } /*-----------------------------------------------------------------------------------*/ @@ -453,6 +467,7 @@ sys_prot_t sys_arch_protect(void) { portENTER_CRITICAL(&g_lwip_mux); + g_lwip_in_critical_section = true; return (sys_prot_t) 1; } @@ -467,7 +482,12 @@ void sys_arch_unprotect(sys_prot_t pval) { (void) pval; + g_lwip_in_critical_section = false; portEXIT_CRITICAL(&g_lwip_mux); + if (g_lwip_critical_section_needs_taskswitch){ + g_lwip_critical_section_needs_taskswitch = 0; + portYIELD(); + } } /*-----------------------------------------------------------------------------------*/ diff --git a/components/lwip/port/netif/ethernetif.c b/components/lwip/port/netif/ethernetif.c index c6f08ec832..79f21f6b3f 100755 --- a/components/lwip/port/netif/ethernetif.c +++ b/components/lwip/port/netif/ethernetif.c @@ -113,7 +113,8 @@ ethernet_low_level_output(struct netif *netif, struct pbuf *p) esp_interface_t eth_if = tcpip_adapter_get_esp_if(netif); if (eth_if != ESP_IF_ETH) { - printf("eth_if=%d netif=%p pbuf=%p len=%d\n", eth_if, netif, p, p->len); + LWIP_DEBUGF(NETIF_DEBUG,("eth_if=%d netif=%p pbuf=%p len=%d\n", eth_if, netif, p, p->len)); + return ERR_IF; } @@ -134,7 +135,6 @@ ethernet_low_level_output(struct netif *netif, struct pbuf *p) } } - //printf("netif=%p pbuf=%p len=%d\n", netif, p, p->len); return esp_eth_tx(q->payload, pbuf_x_len); #else for(q = p; q != NULL; q = q->next) { @@ -160,7 +160,7 @@ ethernetif_input(struct netif *netif, void *buffer, uint16_t len) if(buffer== NULL || netif == NULL) goto _exit; - +#if CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); if (p == NULL) { //g_rx_alloc_pbuf_fail_cnt++; @@ -168,12 +168,28 @@ ethernetif_input(struct netif *netif, void *buffer, uint16_t len) } memcpy(p->payload, buffer, len); - /* full packet send to tcpip_thread to process */ - if (netif->input(p, netif) != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); - pbuf_free(p); +/* full packet send to tcpip_thread to process */ +if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + pbuf_free(p); +} + +#else + p = pbuf_alloc(PBUF_RAW, len, PBUF_REF); + if (p == NULL){ + return; } - + p->payload = buffer; + p->user_flag = PBUF_USER_FLAG_OWNER_ETH; + p->user_buf = buffer; + + /* full packet send to tcpip_thread to process */ +if (netif->input(p, netif) != ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + p->user_flag = PBUF_USER_FLAG_OWNER_NULL; + pbuf_free(p); +} +#endif _exit: ; } diff --git a/components/lwip/port/netif/wlanif.c b/components/lwip/port/netif/wlanif.c index efaa76a73f..fea163f8cc 100755 --- a/components/lwip/port/netif/wlanif.c +++ b/components/lwip/port/netif/wlanif.c @@ -176,7 +176,8 @@ wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb) return; } p->payload = buffer; - p->eb = eb; + p->user_buf = eb; + p->user_flag = PBUF_USER_FLAG_OWNER_WIFI; #endif /* full packet send to tcpip_thread to process */ diff --git a/components/mbedtls/Kconfig b/components/mbedtls/Kconfig index 1e347582f0..e6619e36c4 100644 --- a/components/mbedtls/Kconfig +++ b/components/mbedtls/Kconfig @@ -61,14 +61,6 @@ config MBEDTLS_MPI_USE_INTERRUPT This allows other code to run on the CPU while an MPI operation is pending. Otherwise the CPU busy-waits. -config MBEDTLS_MPI_INTERRUPT_NUM - int "MPI Interrupt number" - depends on MBEDTLS_MPI_USE_INTERRUPT - default 18 - help - CPU interrupt number for MPI interrupt to connect to. Must be otherwise unused. - Eventually this assignment will be handled automatically at runtime. - config MBEDTLS_HARDWARE_SHA bool "Enable hardware SHA acceleration" default y @@ -81,4 +73,24 @@ config MBEDTLS_HARDWARE_SHA be calculated fully in hardware and the rest will be calculated (at least partially calculated) in software. +config MBEDTLS_HAVE_TIME + bool "Enable mbedtls time" + depends on !ESP32_TIME_SYSCALL_USE_NONE + default y + help + System has time.h and time(). + The time does not need to be correct, only time differences are used, + +config MBEDTLS_HAVE_TIME_DATE + bool "Enable mbedtls time data" + depends on MBEDTLS_HAVE_TIME + default n + help + System has time.h and time(), gmtime() and the clock is correct. + The time needs to be correct (not necesarily very accurate, but at least + the date should be correct). This is used to verify the validity period of + X.509 certificates. + + It is suggested that you should get the real time by "SNTP". + endmenu diff --git a/components/mbedtls/port/esp_bignum.c b/components/mbedtls/port/esp_bignum.c index 2fe4d920c3..5cce103ea3 100644 --- a/components/mbedtls/port/esp_bignum.c +++ b/components/mbedtls/port/esp_bignum.c @@ -32,6 +32,7 @@ #include "esp_system.h" #include "esp_log.h" #include "esp_intr.h" +#include "esp_intr_alloc.h" #include "esp_attr.h" #include "soc/dport_reg.h" @@ -59,10 +60,7 @@ static void rsa_isr_initialise() { if (op_complete_sem == NULL) { op_complete_sem = xSemaphoreCreateBinary(); - intr_matrix_set(xPortGetCoreID(), ETS_RSA_INTR_SOURCE, CONFIG_MBEDTLS_MPI_INTERRUPT_NUM); - xt_set_interrupt_handler(CONFIG_MBEDTLS_MPI_INTERRUPT_NUM, &rsa_complete_isr, NULL); - xthal_set_intclear(1 << CONFIG_MBEDTLS_MPI_INTERRUPT_NUM); - xt_ints_on(1 << CONFIG_MBEDTLS_MPI_INTERRUPT_NUM); + esp_intr_alloc(ETS_RSA_INTR_SOURCE, 0, rsa_complete_isr, NULL, NULL); } } diff --git a/components/mbedtls/port/include/mbedtls/esp_config.h b/components/mbedtls/port/include/mbedtls/esp_config.h index cd9f87e698..fd6c023fa3 100644 --- a/components/mbedtls/port/include/mbedtls/esp_config.h +++ b/components/mbedtls/port/include/mbedtls/esp_config.h @@ -74,7 +74,9 @@ * * Comment if your system does not support time functions */ -//#define MBEDTLS_HAVE_TIME +#ifdef CONFIG_MBEDTLS_HAVE_TIME +#define MBEDTLS_HAVE_TIME +#endif /** * \def MBEDTLS_HAVE_TIME_DATE @@ -86,7 +88,9 @@ * * Comment if your system does not have a correct clock. */ -//#define MBEDTLS_HAVE_TIME_DATE +#ifdef CONFIG_MBEDTLS_HAVE_TIME_DATE +#define MBEDTLS_HAVE_TIME_DATE +#endif /** * \def MBEDTLS_PLATFORM_MEMORY diff --git a/components/mbedtls/port/net.c b/components/mbedtls/port/net.c index 45aa4b2deb..bb0884ac87 100644 --- a/components/mbedtls/port/net.c +++ b/components/mbedtls/port/net.c @@ -29,6 +29,16 @@ #if !defined(MBEDTLS_NET_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#define mbedtls_time time +#define mbedtls_time_t time_t +#endif + #include "mbedtls/net.h" #include diff --git a/components/newlib/component.mk b/components/newlib/component.mk index 4f567242b6..8715c475a4 100644 --- a/components/newlib/component.mk +++ b/components/newlib/component.mk @@ -1,4 +1,14 @@ -COMPONENT_ADD_LDFLAGS := $(COMPONENT_PATH)/lib/libc.a $(COMPONENT_PATH)/lib/libm.a -lnewlib + +ifdef CONFIG_NEWLIB_NANO_FORMAT +LIBC_PATH := $(COMPONENT_PATH)/lib/libc_nano.a +else +LIBC_PATH := $(COMPONENT_PATH)/lib/libc.a +endif + +LIBM_PATH := $(COMPONENT_PATH)/lib/libm.a + +COMPONENT_ADD_LDFLAGS := $(LIBC_PATH) $(LIBM_PATH) -lnewlib + +COMPONENT_ADD_LINKER_DEPS := $(LIBC_PATH) $(LIBM_PATH) COMPONENT_ADD_INCLUDEDIRS := include platform_include - diff --git a/components/newlib/lib/extracted/romsyms b/components/newlib/lib/extracted/romsyms deleted file mode 100644 index 61a10cdfb2..0000000000 --- a/components/newlib/lib/extracted/romsyms +++ /dev/null @@ -1,639 +0,0 @@ -abort -abs -__adddf3 -__any_on -app_gpio_arg -app_gpio_handler -__ascii_wctomb -asctime -asctime_r -asiprintf -_asiprintf_r -asniprintf -_asniprintf_r -asnprintf -_asnprintf_r -asprintf -_asprintf_r -atoi -_atoi_r -atol -_atol_r -__b2d -_Balloc -_Bfree -_bss_end -_bss_start -btdummy_bss -btdummy_text -bzero -cache_flash_mmu_set -Cache_Flush -Cache_Read_Disable -Cache_Read_Enable -Cache_Read_Init -cache_sram_mmu_set -calloc -_calloc_r -check_pos -_cleanup -_cleanup_r -close -_close_r -__copybits -creat -ctime -ctime_r -__d2b -_data_end -_data_start -_daylight -_DebugExceptionVector -debug_timer -debug_timerfn -div -__divdf3 -__divsi3 -_DoubleExceptionVector -__dummy_lock -__dummy_lock_try -environ -__env_lock -__env_unlock -eprintf -eprintf_init_buf -eprintf_to_host -__eqdf2 -est_get_printf_buf_remain_len -est_reset_printf_buf_len -_etext -ets_aes_crypt -ets_aes_set_endian -ets_aes_setkey_dec -ets_aes_setkey_enc -ets_aes_start -ets_aes_stop -ets_bigint_disable -ets_bigint_enable -ets_bigint_mod_mult_getz -ets_bigint_mod_mult_prepare -ets_bigint_mod_power_getz -ets_bigint_mod_power_prepare -ets_bigint_montgomery_mult_getz -ets_bigint_montgomery_mult_prepare -ets_bigint_mult_getz -ets_bigint_mult_prepare -ets_bigint_wait_finish -ets_delay_us -ets_efuse_get_8M_clock -ets_efuse_get_spiconfig -ets_efuse_program_op -ets_efuse_read_op -ets_efuse_start -ets_efuse_stop -ets_external_printf -ets_get_cpu_frequency -ets_get_detected_xtal_freq -ets_get_xtal_scale -ets_install_external_printf -ets_install_putc1 -ets_install_putc2 -ets_install_uart_printf -ets_intr_count -ets_intr_lock -ets_intr_unlock -ets_isr_attach -ets_isr_mask -ets_isr_unmask -ets_post -ets_printf -ets_readySet_ -ets_run -ets_secure_boot_check -ets_secure_boot_check_finish -ets_secure_boot_check_start -ets_secure_boot_finish -ets_secure_boot_hash -ets_secure_boot_obtain -ets_secure_boot_rd_abstract -ets_secure_boot_rd_iv -ets_secure_boot_start -ets_set_appcpu_boot_addr -ets_set_idle_cb -ets_set_startup_callback -ets_set_user_start -ets_sha_finish -ets_sha_init -ets_sha_start -ets_sha_stop -ets_sha_update -ets_startup_callback -ets_task -ets_timer_arm -ets_timer_arm_us -ets_timer_disarm -ets_timer_done -ets_timer_handler_isr -ets_timer_init -ets_timer_setfn -ets_uart_printf -ets_unpack_flash_code -ets_update_cpu_frequency -ets_waiti0 -_exit_r -fclose -_fclose_r -fflush -_fflush_r -FilePacketSendDeflatedReqMsgProc -FilePacketSendReqMsgProc -_findenv_r -fiprintf -_fiprintf_r -fiscanf -_fiscanf_r -__fixdfsi -__fixunsdfsi -FlashDwnLdDeflatedStartMsgProc -FlashDwnLdParamCfgMsgProc -FlashDwnLdStartMsgProc -FlashDwnLdStopDeflatedReqMsgProc -FlashDwnLdStopReqMsgProc -__floatsidf -__floatunsidf -__fpclassifyd -__fp_lock_all -fprintf -_fprintf_r -__fp_unlock_all -fputwc -__fputwc -_fputwc_r -free -_free_r -fscanf -_fscanf_r -_fstat_r -_fwalk -_fwalk_reent -__gedf2 -_GeneralException -__get_current_time_locale -_getenv_r -__gethex -_getpid_r -__getreent -_gettimeofday_r -__gettzinfo -GetUartDevice -_global_impure_ptr -gmtime -gmtime_r -gpio_init -gpio_input_get -gpio_input_get_high -gpio_intr_ack -gpio_intr_ack_high -gpio_intr_handler_register -gpio_intr_pending -gpio_intr_pending_high -gpio_matrix_in -gpio_matrix_out -gpio_output_set -gpio_output_set_high -gpio_pad_unhold -gpio_pending_mask -gpio_pending_mask_high -gpio_pin_intr_state_set -gpio_pin_wakeup_disable -gpio_pin_wakeup_enable -gpio_register_get -gpio_register_set -__gtdf2 -gTxMsg -__hexdig_fun -__hexnan -__hi0bits -__i2b -intr_matrix_set -iprintf -_iprintf_r -isalnum -isalpha -isascii -_isatty_r -isblank -iscanf -_iscanf_r -iscntrl -isdigit -isgraph -islower -isprint -ispunct -isspace -isupper -itoa -__itoa -_KernelExceptionVector -_kill_r -labs -ldiv -__ledf2 -_Level2FromVector -_Level2Vector -_Level3FromVector -_Level3Vector -_Level4FromVector -_Level4Vector -_Level5FromVector -_Level5Vector -_LevelOneInterrupt -_link_r -lldesc_build_chain -lldesc_num2link -lldesc_set_owner -__lo0bits -__locale_charset -__locale_cjk_lang -localeconv -_localeconv_r -__locale_mb_cur_max -__locale_msgcharset -localtime -localtime_r -_lock_acquire -_lock_acquire_recursive -_lock_close -_lock_close_recursive -_lock_init -_lock_init_recursive -_lock_release -_lock_release_recursive -_lock_try_acquire -_lock_try_acquire_recursive -longjmp -_lseek_r -__lshift -__ltdf2 -main -malloc -_malloc_r -__mcmp -MD5Final -MD5Init -MD5Update -md5_vector -__mdiff -memccpy -memchr -memcmp -memcpy -MemDwnLdStartMsgProc -MemDwnLdStopReqMsgProc -memmove -MemPacketSendReqMsgProc -memrchr -memset -mktime -mmu_init -_mprec_log10 -__muldf3 -__multadd -__multiply -multofup -mz_adler32 -mz_crc32 -mz_free -nanf -__nedf2 -_NMIExceptionVector -open -_open_r -__pow5mult -printf -_printf_common -_printf_float -_printf_i -_printf_r -print_rom_meminfo -qsort -_raise_r -rand -rand_r -__ratio -RcvMsg -read -_read_r -realloc -_realloc_r -RecvBuff -recv_packet -_rename_r -_ResetHandler -_ResetVector -_rom_store -_rom_store_table -roundup2 -rtc_boot_control -rtc_get_reset_reason -rtc_get_wakeup_cause -rtc_select_apb_bridge -__s2b -sbrk -_sbrk_r -scanf -_scanf_chars -_scanf_float -_scanf_i -_scanf_r -__sccl -__sclose -SelectSpiFunction -SelectSpiQIO -SendMsg -send_packet -__seofread -setjmp -setlocale -_setlocale_r -sf_dump -__sflush_r -__sfmoreglue -__sfp -__sfp_lock_acquire -__sfp_lock_release -__sfputs_r -__sfvwrite_r -__sinit -__sinit_lock_acquire -__sinit_lock_release -sip_alloc_to_host_evt -sip_get_ptr -sip_get_state -sip_init_attach -sip_install_rx_ctrl_cb -sip_install_rx_data_cb -sip_post_init -sip_reclaim_from_host_cmd -sip_reclaim_tx_data_pkt -siprintf -_siprintf_r -sip_send -sip_to_host_chain_append -sip_to_host_evt_send_done -siscanf -_siscanf_r -slc_add_credits -slc_enable -slc_from_host_chain_fetch -slc_from_host_chain_recycle -slc_has_pkt_to_host -slc_init_attach -slc_init_credit -slc_reattach -slc_select_tohost_gpio -slc_select_tohost_gpio_mode -slc_send_to_host_chain -slc_set_host_io_max_window -slc_to_host_chain_recycle -__smakebuf_r -sniprintf -_sniprintf_r -snprintf -_snprintf_r -software_reset -software_reset_app_cpu -software_reset_pro_cpu -spi_cache_sram_init -SPIClkConfig -SPI_Common_Command -SPI_Encrypt_Write -SPIEraseArea -SPIEraseBlock -SPIEraseChip -SPIEraseSector -spi_flash_attach -SPILock -SPIMasterReadModeCnfig -SPIParamCfg -SPI_Prepare_Encrypt_Data -SPIRead -SPIReadModeCnfig -SPIUnlock -SPIWrite -SPI_Write_Encrypt_Disable -SPI_Write_Encrypt_Enable -sprintf -_sprintf_r -__sprint_r -srand -__sread -__srefill_r -sscanf -_sscanf_r -__sseek -__ssprint_r -__ssputs_r -__ssrefill_r -__ssvfiscanf_r -__ssvfscanf_r -__stack -__stack_app -_stack_sentry -_stack_sentry_app -_start -start_tb_console -_stat_r -_stext -strcasecmp -strcasestr -strcat -strchr -strcmp -strcoll -strcpy -strcspn -strdup -_strdup_r -strftime -strlcat -strlcpy -strlen -strlwr -strncasecmp -strncat -strncmp -strncpy -strndup -_strndup_r -strnlen -strrchr -strsep -strspn -strstr -strtod -_strtod_r -strtof -__strtok_r -strtok_r -strtol -_strtol_r -strtoul -_strtoul_r -strupr -__subdf3 -__submore -_sungetc_r -_svfiprintf_r -__svfiscanf_r -_svfprintf_r -__svfscanf -__svfscanf_r -__swbuf -__swbuf_r -__swrite -__swsetup_r -_SyscallException -syscall_table_ptr_app -syscall_table_ptr_pro -_system_r -tdefl_compress -tdefl_compress_buffer -tdefl_compress_mem_to_heap -tdefl_compress_mem_to_mem -tdefl_compress_mem_to_output -tdefl_get_adler32 -tdefl_get_prev_return_status -tdefl_init -tdefl_write_image_to_png_file_in_memory -tdefl_write_image_to_png_file_in_memory_ex -time -__time_load_locale -times -_times_r -_timezone -tinfl_decompress -tinfl_decompress_mem_to_callback -tinfl_decompress_mem_to_heap -tinfl_decompress_mem_to_mem -toascii -tolower -toupper -__truncdfsf2 -__tzcalc_limits -__tz_lock -tzset -_tzset_r -__tz_unlock -uartAttach -uart_baudrate_detect -uart_buff_switch -UartConnCheck -UartConnectProc -UartDev -uart_div_modify -UartDwnLdProc -UartGetCmdLn -Uart_Init -UartRegReadProc -UartRegWriteProc -uart_rx_intr_handler -uart_rx_one_char -uart_rx_one_char_block -uart_rx_readbuff -UartRxString -UartSetBaudProc -UartSpiAttachProc -UartSpiReadProc -uart_tx_flush -uart_tx_one_char -uart_tx_one_char2 -uart_tx_switch -uart_tx_wait_idle -__udivdi3 -__ulp -__umoddi3 -ungetc -_ungetc_r -_unlink_r -__unorddf2 -user_code_start -_UserExceptionVector -utoa -__utoa -vasiprintf -_vasiprintf_r -vasniprintf -_vasniprintf_r -vasnprintf -_vasnprintf_r -vasprintf -_vasprintf_r -VerifyFlashMd5Proc -vfiprintf -_vfiprintf_r -vfiscanf -_vfiscanf_r -vfprintf -_vfprintf_r -vfscanf -_vfscanf_r -viprintf -_viprintf_r -viscanf -_viscanf_r -vprintf -_vprintf_r -vscanf -_vscanf_r -vsiprintf -_vsiprintf_r -vsiscanf -_vsiscanf_r -vsniprintf -_vsniprintf_r -vsnprintf -_vsnprintf_r -vsprintf -_vsprintf_r -vsscanf -_vsscanf_r -wcrtomb -_wcrtomb_r -_wctomb_r -_WindowOverflow12 -_WindowOverflow4 -_WindowOverflow8 -_WindowUnderflow12 -_WindowUnderflow4 -_WindowUnderflow8 -write -_write_r -xthal_bcopy -xthal_copy123 -xthal_get_ccompare -xthal_get_ccount -xthal_get_interrupt -xthal_get_intread -xthal_memcpy -xthal_set_ccompare -xthal_set_intclear -_xtos_alloca_handler -_xtos_cause3_handler -_xtos_c_wrapper_handler -_xtos_ints_off -_xtos_ints_on -_xtos_l1int_handler -_xtos_p_none -_xtos_restore_intlevel -_xtos_return_from_exc -_xtos_set_exception_handler -_xtos_set_interrupt_handler -_xtos_set_interrupt_handler_arg -_xtos_set_intlevel -_xtos_set_min_intlevel -_xtos_set_vpri -_xtos_syscall_handler -_xtos_unhandled_exception -_xtos_unhandled_interrupt diff --git a/components/newlib/lib/fixlibc.sh b/components/newlib/lib/fixlibc.sh deleted file mode 100755 index 5a9e3fd006..0000000000 --- a/components/newlib/lib/fixlibc.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -ROMELF=~/esp8266/esp32/rom_image/eagle.pro.rom.out - -rm -rf extracted -mkdir extracted -cd extracted -mkdir inrom -ar x ../libc.a -cp ../libc.a ../libc-minusrom.a - -nm $ROMELF | grep -e ' [TB] ' | cut -d ' ' -f 3- > romsyms - -for x in *.o; do - nm $x | grep -e ' [TB] ' | cut -d ' ' -f 3- | while read a; do - if [ -e "$x" ] && cat romsyms | grep -q '^'$a'$'; then - echo "$a found in rom" - mv $x inrom - ar -d ../libc-minusrom.a $x - fi - done -done - diff --git a/components/newlib/lib/libc-minusrom.a b/components/newlib/lib/libc-minusrom.a deleted file mode 100644 index 6f593d0587..0000000000 Binary files a/components/newlib/lib/libc-minusrom.a and /dev/null differ diff --git a/components/newlib/lib/libc.a b/components/newlib/lib/libc.a index 263a4d8858..4377fa252f 100644 Binary files a/components/newlib/lib/libc.a and b/components/newlib/lib/libc.a differ diff --git a/components/newlib/lib/libc_nano.a b/components/newlib/lib/libc_nano.a new file mode 100644 index 0000000000..2a99a9c490 Binary files /dev/null and b/components/newlib/lib/libc_nano.a differ diff --git a/components/newlib/lib/libc_rom.a b/components/newlib/lib/libc_rom.a deleted file mode 100644 index e79ed8a926..0000000000 Binary files a/components/newlib/lib/libc_rom.a and /dev/null differ diff --git a/components/newlib/lib/libg.a b/components/newlib/lib/libg.a index f583174f16..27bf971e04 100644 Binary files a/components/newlib/lib/libg.a and b/components/newlib/lib/libg.a differ diff --git a/components/newlib/lib/libm.a b/components/newlib/lib/libm.a index f3fe6dab3e..aa683ac0b9 100644 Binary files a/components/newlib/lib/libm.a and b/components/newlib/lib/libm.a differ diff --git a/components/newlib/syscall_table.c b/components/newlib/syscall_table.c index feed768172..624ffcffab 100644 --- a/components/newlib/syscall_table.c +++ b/components/newlib/syscall_table.c @@ -25,6 +25,7 @@ #include "rom/libc_stubs.h" #include "esp_vfs.h" #include "esp_newlib.h" +#include "sdkconfig.h" static struct _reent s_reent; @@ -76,8 +77,13 @@ static struct syscall_stub_table s_stub_table = { ._lock_try_acquire_recursive = &_lock_try_acquire_recursive, ._lock_release = &_lock_release, ._lock_release_recursive = &_lock_release_recursive, +#ifdef CONFIG_NEWLIB_NANO_FORMAT ._printf_float = &_printf_float, ._scanf_float = &_scanf_float, +#else + ._printf_float = NULL, + ._scanf_float = NULL, +#endif }; void esp_setup_syscall_table() diff --git a/components/newlib/test/test_newlib.c b/components/newlib/test/test_newlib.c index b498b4bd43..1d86cd4a97 100644 --- a/components/newlib/test/test_newlib.c +++ b/components/newlib/test/test_newlib.c @@ -1,10 +1,11 @@ #include +#include #include #include #include #include #include "unity.h" - +#include "sdkconfig.h" TEST_CASE("test ctype functions", "[newlib]") { @@ -22,6 +23,10 @@ TEST_CASE("test atoX functions", "[newlib]") TEST_ASSERT_EQUAL_INT(2147483647, atoi("2147483647")); TEST_ASSERT_EQUAL_INT(42, atoi("000000042")); TEST_ASSERT_EQUAL_INT(0, strtol("foo", NULL, 10)); + TEST_ASSERT_EQUAL(0.123443, atof("0.123443")); + TEST_ASSERT_EQUAL(0.123443f, atoff("0.123443")); + TEST_ASSERT_EQUAL(31.41238, strtod("0.3141238e2", NULL)); + TEST_ASSERT_EQUAL(0.025f, strtof("0.025", NULL)); } TEST_CASE("test sprintf function", "[newlib]") @@ -81,22 +86,64 @@ TEST_CASE("test time functions", "[newlib]") } -static int checkFnRom(void *fn, char *name) +static bool fn_in_rom(void *fn, char *name) { - int fnaddr = (int)fn; - printf("%s: 0X%x\n", name, fnaddr); - if ((fnaddr >= 0x40000000) && (fnaddr < 0x40070000)) { - return 1; - } else { - return 0; - } + const int fnaddr = (int)fn; + return (fnaddr >= 0x40000000) && (fnaddr < 0x40070000); } -TEST_CASE("check if ROM is used for functions", "[newlib]") +TEST_CASE("check if ROM or Flash is used for functions", "[newlib]") { - TEST_ASSERT(checkFnRom(printf, "printf")); - TEST_ASSERT(checkFnRom(sscanf, "sscanf")); - TEST_ASSERT(checkFnRom(atoi, "atoi")); - TEST_ASSERT(checkFnRom(strtol, "strtol")); -} \ No newline at end of file +#ifdef CONFIG_NEWLIB_NANO_FORMAT + TEST_ASSERT(fn_in_rom(printf, "printf")); + TEST_ASSERT(fn_in_rom(sscanf, "sscanf")); +#else + TEST_ASSERT_FALSE(fn_in_rom(printf, "printf")); + TEST_ASSERT_FALSE(fn_in_rom(sscanf, "sscanf")); +#endif + TEST_ASSERT(fn_in_rom(atoi, "atoi")); + TEST_ASSERT(fn_in_rom(strtol, "strtol")); +} + +#ifndef CONFIG_NEWLIB_NANO_FORMAT +TEST_CASE("test 64bit int formats", "[newlib]") +{ + char* res = NULL; + const uint64_t val = 123456789012LL; + + asprintf(&res, "%llu", val); + TEST_ASSERT_NOT_NULL(res); + TEST_ASSERT_EQUAL_STRING("123456789012", res); + + uint64_t sval; + int ret = sscanf(res, "%llu", &sval); + free(res); + + TEST_ASSERT_EQUAL(1, ret); + TEST_ASSERT_EQUAL(val, sval); +} +#else +TEST_CASE("test 64bit int formats", "[newlib]") +{ + char* res = NULL; + const uint64_t val = 123456789012LL; + + asprintf(&res, "%llu", val); + TEST_ASSERT_NOT_NULL(res); + TEST_ASSERT_EQUAL_STRING("lu", res); + + uint64_t sval; + int ret = sscanf(res, "%llu", &sval); + free(res); + + TEST_ASSERT_EQUAL(0, ret); +} +#endif + + +TEST_CASE("fmod and fmodf work as expected", "[newlib]") +{ + TEST_ASSERT_EQUAL(0.1, fmod(10.1, 2.0)); + TEST_ASSERT_EQUAL(0.1f, fmodf(10.1f, 2.0f)); +} diff --git a/components/newlib/time.c b/components/newlib/time.c index 1baa955759..363e17b3eb 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -22,6 +22,7 @@ #include #include #include "esp_attr.h" +#include "esp_intr_alloc.h" #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include "soc/frc_timer_reg.h" @@ -105,9 +106,7 @@ void esp_setup_time_syscalls() SET_PERI_REG_MASK(FRC_TIMER_CTRL_REG(0), FRC_TIMER_ENABLE | \ FRC_TIMER_INT_ENABLE); - intr_matrix_set(xPortGetCoreID(), ETS_TIMER1_INTR_SOURCE, ETS_FRC1_INUM); - xt_set_interrupt_handler(ETS_FRC1_INUM, &frc_timer_isr, NULL); - xt_ints_on(1 << ETS_FRC1_INUM); + esp_intr_alloc(ETS_TIMER1_INTR_SOURCE, 0, &frc_timer_isr, NULL, NULL); #endif // WITH_FRC1 } diff --git a/components/partition_table/Makefile.projbuild b/components/partition_table/Makefile.projbuild index 5bd13f766d..5d1e726a86 100644 --- a/components/partition_table/Makefile.projbuild +++ b/components/partition_table/Makefile.projbuild @@ -11,6 +11,7 @@ # NB: gen_esp32part.py lives in the sdk/bin/ dir not component dir GEN_ESP32PART := $(PYTHON) $(COMPONENT_PATH)/gen_esp32part.py -q +# Has a matching value in bootloader_support esp_flash_partitions.h PARTITION_TABLE_OFFSET := 0x8000 # Path to partition CSV file is relative to project path for custom @@ -20,11 +21,11 @@ PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(s PARTITION_TABLE_BIN := $(BUILD_DIR_BASE)/$(notdir $(PARTITION_TABLE_CSV_PATH:.csv=.bin)) -ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES PARTITION_TABLE_BIN_UNSIGNED := $(PARTITION_TABLE_BIN:.bin=-unsigned.bin) # add an extra signing step for secure partition table -$(PARTITION_TABLE_BIN): $(PARTITION_TABLE_BIN_UNSIGNED) - $(Q) $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $< +$(PARTITION_TABLE_BIN): $(PARTITION_TABLE_BIN_UNSIGNED) $(SDKCONFIG_MAKEFILE) $(SECURE_BOOT_SIGNING_KEY) + $(ESPSECUREPY) sign_data --keyfile $(SECURE_BOOT_SIGNING_KEY) -o $@ $< else # secure bootloader disabled, both files are the same PARTITION_TABLE_BIN_UNSIGNED := $(PARTITION_TABLE_BIN) diff --git a/components/partition_table/gen_esp32part.py b/components/partition_table/gen_esp32part.py index 5ead13adc7..a4412ad45b 100755 --- a/components/partition_table/gen_esp32part.py +++ b/components/partition_table/gen_esp32part.py @@ -90,11 +90,11 @@ class PartitionTable(list): for o in range(0,len(b),32): data = b[o:o+32] if len(data) != 32: - raise InputError("Ran out of partition table data before reaching end marker") + raise InputError("Partition table length must be a multiple of 32 bytes") if data == '\xFF'*32: - break # end of partition table + return result # got end marker result.append(PartitionDefinition.from_binary(data)) - return result + raise InputError("Partition table is missing an end-of-table marker") def to_binary(self): result = "".join(e.to_binary() for e in self) @@ -105,7 +105,7 @@ class PartitionTable(list): def to_csv(self, simple_formatting=False): rows = [ "# Espressif ESP32 Partition Table", - "# Name, Type, SubType, Offset, Size" ] + "# Name, Type, SubType, Offset, Size, Flags" ] rows += [ x.to_csv(simple_formatting) for x in self ] return "\n".join(rows) + "\n" @@ -140,6 +140,12 @@ class PartitionDefinition(object): DATA_TYPE : 0x04, } + # dictionary maps flag name (as used in CSV flags list, property name) + # to bit set in flags words in binary format + FLAGS = { + "encrypted" : 1 + } + # add subtypes for the 16 OTA slot values ("ota_XXX, etc.") for ota_slot in range(16): SUBTYPES[TYPES["app"]]["ota_%d" % ota_slot] = 0x10 + ota_slot @@ -150,11 +156,12 @@ class PartitionDefinition(object): self.subtype = None self.offset = None self.size = None + self.encrypted = False @classmethod def from_csv(cls, line): """ Parse a line from the CSV """ - line_w_defaults = line + ",,," # lazy way to support default fields + line_w_defaults = line + ",,,," # lazy way to support default fields fields = [ f.strip() for f in line_w_defaults.split(",") ] res = PartitionDefinition() @@ -165,6 +172,14 @@ class PartitionDefinition(object): res.size = res.parse_address(fields[4]) if res.size is None: raise InputError("Size field can't be empty") + + flags = fields[5].split(":") + for flag in flags: + if flag in cls.FLAGS: + setattr(res, flag, True) + elif len(flag) > 0: + raise InputError("CSV flag column contains unknown flag '%s'" % (flag)) + return res def __eq__(self, other): @@ -220,22 +235,30 @@ class PartitionDefinition(object): raise InputError("Partition definition length must be exactly 32 bytes. Got %d bytes." % len(b)) res = cls() (magic, res.type, res.subtype, res.offset, - res.size, res.name, reserved) = struct.unpack(cls.STRUCT_FORMAT, b) + res.size, res.name, flags) = struct.unpack(cls.STRUCT_FORMAT, b) if "\x00" in res.name: # strip null byte padding from name string res.name = res.name[:res.name.index("\x00")] if magic != cls.MAGIC_BYTES: raise InputError("Invalid magic bytes (%r) for partition definition" % magic) - if reserved != 0: - critical("WARNING: Partition definition had unexpected reserved value 0x%08x. Newer binary format?" % reserved) + for flag,bit in cls.FLAGS.items(): + if flags & (1< #include #include +#include // For MIN/MAX(a, b) #include #include @@ -32,7 +33,7 @@ #include "cache_utils.h" /* bytes erased by SPIEraseBlock() ROM function */ -#define BLOCK_ERASE_SIZE 32768 +#define BLOCK_ERASE_SIZE 65536 #if CONFIG_SPI_FLASH_ENABLE_COUNTERS static const char* TAG = "spi_flash"; @@ -114,8 +115,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) rc = SPIEraseBlock(sector / sectors_per_block); sector += sectors_per_block; COUNTER_ADD_BYTES(erase, sectors_per_block * SPI_FLASH_SEC_SIZE); - } - else { + } else { rc = SPIEraseSector(sector); ++sector; COUNTER_ADD_BYTES(erase, SPI_FLASH_SEC_SIZE); @@ -127,121 +127,224 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) return spi_flash_translate_rc(rc); } -esp_err_t IRAM_ATTR spi_flash_write(size_t dest_addr, const void *src, size_t size) +esp_err_t IRAM_ATTR spi_flash_write(size_t dst, const void *srcv, size_t size) { - // Destination alignment is also checked in ROM code, but we can give - // better error code here - // TODO: add handling of unaligned destinations - uint8_t *temp_write_buf = NULL; - uint8_t pad_head = 0; - uint8_t pad_end = 0; - SpiFlashOpResult rc; // Out of bound writes are checked in ROM code, but we can give better // error code here - if (dest_addr + size > g_rom_flashchip.chip_size) { + if (dst + size > g_rom_flashchip.chip_size) { return ESP_ERR_INVALID_SIZE; } - - while(size >= 1024) { - // max need pad byte num for 1024 is 4 - temp_write_buf = (uint8_t*)malloc(1024 + 4); - if(temp_write_buf == NULL) { - return ESP_ERR_NO_MEM; - } - - if(dest_addr%4 != 0) { - pad_head = dest_addr%4; - pad_end = 4 - pad_head; - } - memset(temp_write_buf,0xFF,pad_head); - memcpy(temp_write_buf + pad_head ,src,1024); - memset(temp_write_buf + pad_head + 1024, 0xFF,pad_end); - COUNTER_START(); - spi_flash_disable_interrupts_caches_and_other_cpu(); - rc = spi_flash_unlock(); - if (rc == SPI_FLASH_RESULT_OK) { - rc = SPIWrite((uint32_t) (dest_addr - pad_head), (const uint32_t*) temp_write_buf, (int32_t) (1024 + pad_head + pad_end)); - COUNTER_ADD_BYTES(write, 1024 + pad_head + pad_end); - } - COUNTER_STOP(write); - spi_flash_enable_interrupts_caches_and_other_cpu(); - if(rc != ESP_OK) { - free(temp_write_buf); - temp_write_buf = NULL; - return spi_flash_translate_rc(rc); - } - - free(temp_write_buf); - temp_write_buf = NULL; - size -= 1024; - dest_addr += 1024; - src = (uint8_t*)src + 1024; + if (size == 0) { + return ESP_OK; } - if(size > 0) { - // max need pad byte num for rand size is 6 - temp_write_buf = (uint8_t*)malloc(size + 6); - if(temp_write_buf == NULL) { - return ESP_ERR_NO_MEM; - } - if(dest_addr%4 != 0) { - pad_head = dest_addr%4; - } - if ((pad_head + size)%4 != 0){ - pad_end = 4 - (pad_head + size) % 4; - } - memset(temp_write_buf,0xFF,pad_head); - memcpy(temp_write_buf + pad_head, src, size); - memset(temp_write_buf + pad_head + size, 0xFF,pad_end); - COUNTER_START(); + + SpiFlashOpResult rc = SPI_FLASH_RESULT_OK; + COUNTER_START(); + const char *srcc = (const char *) srcv; + /* + * Large operations are split into (up to) 3 parts: + * - Left padding: 4 bytes up to the first 4-byte aligned destination offset. + * - Middle part + * - Right padding: 4 bytes from the last 4-byte aligned offset covered. + */ + size_t left_off = dst & ~3U; + size_t left_size = MIN(((dst + 3) & ~3U) - dst, size); + size_t mid_off = left_size; + size_t mid_size = (size - left_size) & ~3U; + size_t right_off = left_size + mid_size; + size_t right_size = size - mid_size - left_size; + rc = spi_flash_unlock(); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + if (left_size > 0) { + uint32_t t = 0xffffffff; + memcpy(((uint8_t *) &t) + (dst - left_off), srcc, left_size); spi_flash_disable_interrupts_caches_and_other_cpu(); - rc = spi_flash_unlock(); - if (rc == SPI_FLASH_RESULT_OK) { - rc = SPIWrite((uint32_t) (dest_addr - pad_head), (const uint32_t*) temp_write_buf, (int32_t) (size + pad_head + pad_end)); - COUNTER_ADD_BYTES(write, size + pad_head + pad_end); - } - COUNTER_STOP(write); + rc = SPIWrite(left_off, &t, 4); spi_flash_enable_interrupts_caches_and_other_cpu(); - if(rc != ESP_OK) { - free(temp_write_buf); - temp_write_buf = NULL; - return spi_flash_translate_rc(rc); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; } - - free(temp_write_buf); - temp_write_buf = NULL; - size = 0; - dest_addr += size; - src = (uint8_t*)src + size; - return spi_flash_translate_rc(rc); - } - return spi_flash_translate_rc(SPI_FLASH_RESULT_OK); - + COUNTER_ADD_BYTES(write, 4); + } + if (mid_size > 0) { + /* If src buffer is 4-byte aligned as well and is not in a region that + * requires cache access to be enabled, we can write it all at once. */ +#ifdef ESP_PLATFORM + bool in_dram = ((uintptr_t) srcc >= 0x3FFAE000 && + (uintptr_t) srcc < 0x40000000); +#else + bool in_dram = true; +#endif + if (in_dram && (((uintptr_t) srcc) + mid_off) % 4 == 0) { + spi_flash_disable_interrupts_caches_and_other_cpu(); + rc = SPIWrite(dst + mid_off, (const uint32_t *) (srcc + mid_off), mid_size); + spi_flash_enable_interrupts_caches_and_other_cpu(); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(write, mid_size); + } else { + /* + * Otherwise, unlike for read, we cannot manipulate data in the + * user-provided buffer, so we write in 32 byte blocks. + */ + while (mid_size > 0) { + uint32_t t[8]; + uint32_t write_size = MIN(mid_size, sizeof(t)); + memcpy(t, srcc + mid_off, write_size); + spi_flash_disable_interrupts_caches_and_other_cpu(); + rc = SPIWrite(dst + mid_off, t, write_size); + spi_flash_enable_interrupts_caches_and_other_cpu(); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(write, write_size); + mid_size -= write_size; + mid_off += write_size; + } + } + } + if (right_size > 0) { + uint32_t t = 0xffffffff; + memcpy(&t, srcc + right_off, right_size); + spi_flash_disable_interrupts_caches_and_other_cpu(); + rc = SPIWrite(dst + right_off, &t, 4); + spi_flash_enable_interrupts_caches_and_other_cpu(); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(write, 4); + } +out: + COUNTER_STOP(write); + return spi_flash_translate_rc(rc); } -esp_err_t IRAM_ATTR spi_flash_read(size_t src_addr, void *dest, size_t size) +esp_err_t IRAM_ATTR spi_flash_write_encrypted(size_t dest_addr, const void *src, size_t size) { - // TODO: replace this check with code which deals with unaligned destinations - if (((ptrdiff_t) dest) % 4 != 0) { + if ((dest_addr % 32) != 0) { return ESP_ERR_INVALID_ARG; } - // Source alignment is also checked in ROM code, but we can give - // better error code here - // TODO: add handling of unaligned destinations - if (src_addr % 4 != 0) { + if ((size % 32) != 0) { + return ESP_ERR_INVALID_SIZE; + } + if ((uint32_t) src < 0x3ff00000) { + // if source address is in DROM, we won't be able to read it + // from within SPIWrite + // TODO: consider buffering source data using heap and writing it anyway? return ESP_ERR_INVALID_ARG; } - if (size % 4 != 0) { - return ESP_ERR_INVALID_SIZE; - } - // Out of bound reads are checked in ROM code, but we can give better - // error code here - if (src_addr + size > g_rom_flashchip.chip_size) { - return ESP_ERR_INVALID_SIZE; - } COUNTER_START(); spi_flash_disable_interrupts_caches_and_other_cpu(); - SpiFlashOpResult rc = SPIRead((uint32_t) src_addr, (uint32_t*) dest, (int32_t) size); - COUNTER_ADD_BYTES(read, size); + SpiFlashOpResult rc; + rc = spi_flash_unlock(); + if (rc == SPI_FLASH_RESULT_OK) { + /* SPI_Encrypt_Write encrypts data in RAM as it writes, + so copy to a temporary buffer - 32 bytes at a time. + */ + uint32_t encrypt_buf[32/sizeof(uint32_t)]; + for (size_t i = 0; i < size; i += 32) { + memcpy(encrypt_buf, ((const uint8_t *)src) + i, 32); + rc = SPI_Encrypt_Write((uint32_t) dest_addr + i, encrypt_buf, 32); + if (rc != SPI_FLASH_RESULT_OK) { + break; + } + } + bzero(encrypt_buf, sizeof(encrypt_buf)); + } + COUNTER_ADD_BYTES(write, size); + return spi_flash_translate_rc(rc); +} + +esp_err_t IRAM_ATTR spi_flash_read(size_t src, void *dstv, size_t size) +{ + // Out of bound reads are checked in ROM code, but we can give better + // error code here + if (src + size > g_rom_flashchip.chip_size) { + return ESP_ERR_INVALID_SIZE; + } + if (size == 0) { + return ESP_OK; + } + + SpiFlashOpResult rc = SPI_FLASH_RESULT_OK; + COUNTER_START(); + spi_flash_disable_interrupts_caches_and_other_cpu(); + /* To simplify boundary checks below, we handle small reads separately. */ + if (size < 16) { + uint32_t t[6]; /* Enough for 16 bytes + 4 on either side for padding. */ + uint32_t read_src = src & ~3U; + uint32_t left_off = src & 3U; + uint32_t read_size = (left_off + size + 3) & ~3U; + rc = SPIRead(read_src, t, read_size); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(read, read_size); + memcpy(dstv, ((char *) t) + left_off, size); + goto out; + } + char *dstc = (char *) dstv; + intptr_t dsti = (intptr_t) dstc; + /* + * Large operations are split into (up to) 3 parts: + * - The middle part: from the first 4-aligned position in src to the first + * 4-aligned position in dst. + */ + size_t src_mid_off = (src % 4 == 0 ? 0 : 4 - (src % 4)); + size_t dst_mid_off = (dsti % 4 == 0 ? 0 : 4 - (dsti % 4)); + size_t mid_size = (size - MAX(src_mid_off, dst_mid_off)) & ~3U; + /* + * - Once the middle part is in place, src_mid_off bytes from the preceding + * 4-aligned source location are added on the left. + */ + size_t pad_left_src = src & ~3U; + size_t pad_left_size = src_mid_off; + /* + * - Finally, the right part is added: from the end of the middle part to + * the end. Depending on the alignment of source and destination, this may + * be a 4 or 8 byte read from pad_right_src. + */ + size_t pad_right_src = (src + pad_left_size + mid_size) & ~3U; + size_t pad_right_off = (pad_right_src - src); + size_t pad_right_size = (size - pad_right_off); + if (mid_size > 0) { + rc = SPIRead(src + src_mid_off, (uint32_t *) (dstc + dst_mid_off), mid_size); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(read, mid_size); + /* + * If offsets in src and dst are different, perform an in-place shift + * to put destination data into its final position. + * Note that the shift can be left (src_mid_off < dst_mid_off) or right. + */ + if (src_mid_off != dst_mid_off) { + memmove(dstc + src_mid_off, dstc + dst_mid_off, mid_size); + } + } + if (pad_left_size > 0) { + uint32_t t; + rc = SPIRead(pad_left_src, &t, 4); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(read, 4); + memcpy(dstc, ((uint8_t *) &t) + (4 - pad_left_size), pad_left_size); + } + if (pad_right_size > 0) { + uint32_t t[2]; + int32_t read_size = (pad_right_size <= 4 ? 4 : 8); + rc = SPIRead(pad_right_src, t, read_size); + if (rc != SPI_FLASH_RESULT_OK) { + goto out; + } + COUNTER_ADD_BYTES(read, read_size); + memcpy(dstc + pad_right_off, t, pad_right_size); + } +out: spi_flash_enable_interrupts_caches_and_other_cpu(); COUNTER_STOP(read); return spi_flash_translate_rc(rc); @@ -265,7 +368,7 @@ static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc) static inline void dump_counter(spi_flash_counter_t* counter, const char* name) { ESP_LOGI(TAG, "%s count=%8d time=%8dms bytes=%8d\n", name, - counter->count, counter->time, counter->bytes); + counter->count, counter->time, counter->bytes); } const spi_flash_counters_t* spi_flash_get_counters() diff --git a/components/spi_flash/include/esp_partition.h b/components/spi_flash/include/esp_partition.h index 13b803e10f..b67891ae15 100644 --- a/components/spi_flash/include/esp_partition.h +++ b/components/spi_flash/include/esp_partition.h @@ -89,6 +89,10 @@ typedef struct esp_partition_iterator_opaque_* esp_partition_iterator_t; /** * @brief partition information structure + * + * This is not the format in flash, that format is esp_partition_info_t. + * + * However, this is the format used by this API. */ typedef struct { esp_partition_type_t type; /*!< partition type (app/data) */ diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index f940c0ad50..91675088ae 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -16,6 +16,7 @@ #define ESP_SPI_FLASH_H #include +#include #include #include "esp_err.h" #include "sdkconfig.h" @@ -74,25 +75,39 @@ esp_err_t spi_flash_erase_range(size_t start_address, size_t size); /** * @brief Write data to Flash. * - * @note Address in flash, dest, has to be 4-byte aligned. - * This is a temporary limitation which will be removed. * @note If source address is in DROM, this function will return * ESP_ERR_INVALID_ARG. * - * @param dest destination address in Flash - * @param src pointer to the source buffer - * @param size length of data, in bytes + * @param dest destination address in Flash. Must be a multiple of 4 bytes. + * @param src pointer to the source buffer. + * @param size length of data, in bytes. Must be a multiple of 4 bytes. * * @return esp_err_t */ esp_err_t spi_flash_write(size_t dest, const void *src, size_t size); + +/** + * @brief Write data encrypted to Flash. + * + * @note Flash encryption must be enabled for this function to work. + * + * @note Address in flash, dest, has to be 32-byte aligned. + * + * @note If source address is in DROM, this function will return + * ESP_ERR_INVALID_ARG. + * + * @param dest destination address in Flash. Must be a multiple of 32 bytes. + * @param src pointer to the source buffer. + * @param size length of data, in bytes. Must be a multiple of 32 bytes. + * + * @return esp_err_t + */ +esp_err_t spi_flash_write_encrypted(size_t dest, const void *src, size_t size); + /** * @brief Read data from Flash. * - * @note Both src and dest have to be 4-byte aligned. - * This is a temporary limitation which will be removed. - * * @param src source address of the data in Flash. * @param dest pointer to the destination buffer * @param size length of data diff --git a/components/spi_flash/partition.c b/components/spi_flash/partition.c index c54da24caa..490efbb32c 100644 --- a/components/spi_flash/partition.c +++ b/components/spi_flash/partition.c @@ -22,6 +22,7 @@ #include "esp_flash_data_types.h" #include "esp_spi_flash.h" #include "esp_partition.h" +#include "esp_flash_encrypt.h" #include "esp_log.h" @@ -164,7 +165,11 @@ static esp_err_t load_partitions() item->info.size = it->pos.size; item->info.type = it->type; item->info.subtype = it->subtype; - item->info.encrypted = false; + item->info.encrypted = it->flags & PART_FLAG_ENCRYPTED; + if (esp_flash_encryption_enabled() && it->type == PART_TYPE_APP) { + /* All app partitions are encrypted if encryption is turned on */ + item->info.encrypted = true; + } // it->label may not be zero-terminated strncpy(item->info.label, (const char*) it->label, sizeof(it->label)); item->info.label[sizeof(it->label)] = 0; @@ -201,7 +206,24 @@ esp_err_t esp_partition_read(const esp_partition_t* partition, if (src_offset + size > partition->size) { return ESP_ERR_INVALID_SIZE; } - return spi_flash_read(partition->address + src_offset, dst, size); + + if (!partition->encrypted) { + return spi_flash_read(partition->address + src_offset, dst, size); + } else { + /* Encrypted partitions need to be read via a cache mapping */ + const void *buf; + spi_flash_mmap_handle_t handle; + esp_err_t err; + + err = esp_partition_mmap(partition, src_offset, size, + SPI_FLASH_MMAP_DATA, &buf, &handle); + if (err != ESP_OK) { + return err; + } + memcpy(dst, buf, size); + spi_flash_munmap(handle); + return ESP_OK; + } } esp_err_t esp_partition_write(const esp_partition_t* partition, @@ -218,7 +240,12 @@ esp_err_t esp_partition_write(const esp_partition_t* partition, if (dst_offset + size > partition->size) { return ESP_ERR_INVALID_SIZE; } - return spi_flash_write(partition->address + dst_offset, src, size); + dst_offset = partition->address + dst_offset; + if (partition->encrypted) { + return spi_flash_write_encrypted(dst_offset, src, size); + } else { + return spi_flash_write(dst_offset, src, size); + } } esp_err_t esp_partition_erase_range(const esp_partition_t* partition, diff --git a/components/spi_flash/test/test_mmap.c b/components/spi_flash/test/test_mmap.c index 28d9ae6dda..d3d16802ea 100644 --- a/components/spi_flash/test/test_mmap.c +++ b/components/spi_flash/test/test_mmap.c @@ -10,8 +10,8 @@ uint32_t buffer[1024]; -static const uint32_t start = 0x200000; -static const uint32_t end = 0x300000; +static const uint32_t start = 0x100000; +static const uint32_t end = 0x200000; diff --git a/components/spi_flash/test/test_read_write.c b/components/spi_flash/test/test_read_write.c new file mode 100644 index 0000000000..c9067463e4 --- /dev/null +++ b/components/spi_flash/test/test_read_write.c @@ -0,0 +1,207 @@ +// 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. + +// Test for spi_flash_{read,write}. + +#include +#include +#include +#include +#include + +#include +#include +#include +#include "../cache_utils.h" +#include "soc/timer_group_struct.h" +#include "soc/timer_group_reg.h" + +/* Base offset in flash for tests. */ +#define FLASH_BASE 0x120000 + +#ifndef CONFIG_SPI_FLASH_MINIMAL_TEST +#define CONFIG_SPI_FLASH_MINIMAL_TEST 1 +#endif + +static void fill(char *dest, int32_t start, int32_t len) +{ + for (int32_t i = 0; i < len; i++) { + *(dest + i) = (char) (start + i); + } +} + +static int cmp_or_dump(const void *a, const void *b, size_t len) +{ + int r = memcmp(a, b, len); + if (r != 0) { + for (int i = 0; i < len; i++) { + fprintf(stderr, "%02x", ((unsigned char *) a)[i]); + } + fprintf(stderr, "\n"); + for (int i = 0; i < len; i++) { + fprintf(stderr, "%02x", ((unsigned char *) b)[i]); + } + fprintf(stderr, "\n"); + } + return r; +} + +static void IRAM_ATTR test_read(int src_off, int dst_off, int len) +{ + uint32_t src_buf[16]; + char dst_buf[64], dst_gold[64]; + fprintf(stderr, "src=%d dst=%d len=%d\n", src_off, dst_off, len); + memset(src_buf, 0xAA, sizeof(src_buf)); + fill(((char *) src_buf) + src_off, src_off, len); + ESP_ERROR_CHECK(spi_flash_erase_sector((FLASH_BASE + src_off) / SPI_FLASH_SEC_SIZE)); + spi_flash_disable_interrupts_caches_and_other_cpu(); + SpiFlashOpResult rc = SPIWrite(FLASH_BASE, src_buf, sizeof(src_buf)); + spi_flash_enable_interrupts_caches_and_other_cpu(); + TEST_ASSERT_EQUAL_INT(rc, SPI_FLASH_RESULT_OK); + memset(dst_buf, 0x55, sizeof(dst_buf)); + memset(dst_gold, 0x55, sizeof(dst_gold)); + fill(dst_gold + dst_off, src_off, len); + + ESP_ERROR_CHECK(spi_flash_read(FLASH_BASE + src_off, dst_buf + dst_off, len)); + TEST_ASSERT_EQUAL_INT(cmp_or_dump(dst_buf, dst_gold, sizeof(dst_buf)), 0); +} + +TEST_CASE("Test spi_flash_read", "[spi_flash_read]") +{ +#if CONFIG_SPI_FLASH_MINIMAL_TEST + test_read(0, 0, 0); + test_read(0, 0, 4); + test_read(0, 0, 16); + test_read(0, 0, 64); + test_read(0, 0, 1); + test_read(0, 1, 1); + test_read(1, 0, 1); + test_read(1, 1, 1); + test_read(1, 1, 2); + test_read(1, 1, 3); + test_read(1, 1, 4); + test_read(1, 1, 5); + test_read(3, 2, 5); + test_read(0, 0, 17); + test_read(0, 1, 17); + test_read(1, 0, 17); + test_read(1, 1, 17); + test_read(1, 1, 18); + test_read(1, 1, 19); + test_read(1, 1, 20); + test_read(1, 1, 21); + test_read(3, 2, 21); + test_read(4, 4, 60); + test_read(59, 0, 5); + test_read(60, 0, 4); + test_read(60, 0, 3); + test_read(60, 0, 2); + test_read(63, 0, 1); + test_read(64, 0, 0); + test_read(59, 59, 5); + test_read(60, 60, 4); + test_read(60, 60, 3); + test_read(60, 60, 2); + test_read(63, 63, 1); + test_read(64, 64, 0); +#else + /* This will run a more thorough test but will slam flash pretty hard. */ + for (int src_off = 1; src_off < 16; src_off++) { + for (int dst_off = 0; dst_off < 16; dst_off++) { + for (int len = 0; len < 32; len++) { + test_read(dst_off, src_off, len); + } + } + } +#endif +} + +static void IRAM_ATTR test_write(int dst_off, int src_off, int len) +{ + char src_buf[64], dst_gold[64]; + uint32_t dst_buf[16]; + fprintf(stderr, "dst=%d src=%d len=%d\n", dst_off, src_off, len); + memset(src_buf, 0x55, sizeof(src_buf)); + fill(src_buf + src_off, src_off, len); + // Fills with 0xff + ESP_ERROR_CHECK(spi_flash_erase_sector((FLASH_BASE + dst_off) / SPI_FLASH_SEC_SIZE)); + memset(dst_gold, 0xff, sizeof(dst_gold)); + if (len > 0) { + int pad_left_off = (dst_off & ~3U); + memset(dst_gold + pad_left_off, 0xff, 4); + if (dst_off + len > pad_left_off + 4 && (dst_off + len) % 4 != 0) { + int pad_right_off = ((dst_off + len) & ~3U); + memset(dst_gold + pad_right_off, 0xff, 4); + } + fill(dst_gold + dst_off, src_off, len); + } + ESP_ERROR_CHECK(spi_flash_write(FLASH_BASE + dst_off, src_buf + src_off, len)); + spi_flash_disable_interrupts_caches_and_other_cpu(); + SpiFlashOpResult rc = SPIRead(FLASH_BASE, dst_buf, sizeof(dst_buf)); + spi_flash_enable_interrupts_caches_and_other_cpu(); + TEST_ASSERT_EQUAL_INT(rc, SPI_FLASH_RESULT_OK); + TEST_ASSERT_EQUAL_INT(cmp_or_dump(dst_buf, dst_gold, sizeof(dst_buf)), 0); +} + +TEST_CASE("Test spi_flash_write", "[spi_flash_write]") +{ +#if CONFIG_SPI_FLASH_MINIMAL_TEST + test_write(0, 0, 0); + test_write(0, 0, 4); + test_write(0, 0, 16); + test_write(0, 0, 64); + test_write(0, 0, 1); + test_write(0, 1, 1); + test_write(1, 0, 1); + test_write(1, 1, 1); + test_write(1, 1, 2); + test_write(1, 1, 3); + test_write(1, 1, 4); + test_write(1, 1, 5); + test_write(3, 2, 5); + test_write(4, 4, 60); + test_write(59, 0, 5); + test_write(60, 0, 4); + test_write(60, 0, 3); + test_write(60, 0, 2); + test_write(63, 0, 1); + test_write(64, 0, 0); + test_write(59, 59, 5); + test_write(60, 60, 4); + test_write(60, 60, 3); + test_write(60, 60, 2); + test_write(63, 63, 1); + test_write(64, 64, 0); +#else + /* This will run a more thorough test but will slam flash pretty hard. */ + for (int dst_off = 1; dst_off < 16; dst_off++) { + for (int src_off = 0; src_off < 16; src_off++) { + for (int len = 0; len < 16; len++) { + test_write(dst_off, src_off, len); + } + } + } +#endif + /* + * Test writing from ROM, IRAM and caches. We don't know what exactly will be + * written, we're testing that there's no crash here. + * + * NB: At the moment these only support aligned addresses, because memcpy + * is not aware of the 32-but load requirements for these regions. + */ + ESP_ERROR_CHECK(spi_flash_write(FLASH_BASE, (char *) 0x40000000, 16)); + ESP_ERROR_CHECK(spi_flash_write(FLASH_BASE, (char *) 0x40070000, 16)); + ESP_ERROR_CHECK(spi_flash_write(FLASH_BASE, (char *) 0x40078000, 16)); + ESP_ERROR_CHECK(spi_flash_write(FLASH_BASE, (char *) 0x40080000, 16)); +} diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index 222e8017eb..726434b5fa 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -25,6 +25,9 @@ #include "lwip/ip_addr.h" #include "lwip/ip6_addr.h" #include "lwip/nd6.h" +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ +#include "lwip/dns.h" +#endif #include "netif/wlanif.h" #include "netif/ethernetif.h" @@ -64,7 +67,7 @@ esp_err_t tcpip_adapter_start(tcpip_adapter_if_t tcpip_if, uint8_t *mac, tcpip_a } if (esp_netif[tcpip_if] == NULL) { - esp_netif[tcpip_if] = malloc(sizeof(struct netif)); + esp_netif[tcpip_if] = calloc(1, sizeof(*esp_netif[tcpip_if])); if (esp_netif[tcpip_if] == NULL) { return ESP_ERR_NO_MEM; } @@ -213,7 +216,7 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i tcpip_adapter_dhcp_status_t status; if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || ip_info == NULL || - ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask) || ip4_addr_isany_val(ip_info->gw)) { + ip4_addr_isany_val(ip_info->ip) || ip4_addr_isany_val(ip_info->netmask)) { return ESP_ERR_TCPIP_ADAPTER_INVALID_PARAMS; } @@ -229,6 +232,12 @@ esp_err_t tcpip_adapter_set_ip_info(tcpip_adapter_if_t tcpip_if, tcpip_adapter_i if (status != TCPIP_ADAPTER_DHCP_STOPPED) { return ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED; } +#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ + u8_t numdns = 0; + for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) { + dns_setserver(numdns, NULL); + } +#endif } ip4_addr_copy(esp_ip[tcpip_if].ip, ip_info->ip); diff --git a/components/ulp/README.rst b/components/ulp/README.rst new file mode 100644 index 0000000000..875a01ef88 --- /dev/null +++ b/components/ulp/README.rst @@ -0,0 +1,124 @@ +ULP coprocessor programming +=========================== + +.. warning:: ULP coprocessor programming approach described here is experimental. It is probable that once binutils support for ULP is done, this preprocessor-based approach may be deprecated. We welcome discussion about and contributions to ULP programming tools. + +ULP coprocessor is a simple FSM which is designed to perform measurements using ADC, temperature sensor, and external I2C sensors, while main processors are in deep sleep mode. ULP coprocessor can access RTC_SLOW_MEM memory region, and registers in RTC_CNTL, RTC_IO, and SARADC peripherals. ULP coprocessor uses fixed-width 32-bit instructions, 32-bit memory addressing, and has 4 general purpose 16-bit registers. + +ULP coprocessor doesn't have a dedicated binutils port yet. Programming ULP coprocessor is possible by embedding assembly-like macros into an ESP32 application. +Here is an example how this can be done:: + + const ulp_insn_t program[] = { + I_MOVI(R3, 16), // R3 <- 16 + I_LD(R0, R3, 0), // R0 <- RTC_SLOW_MEM[R3 + 0] + I_LD(R1, R3, 1), // R1 <- RTC_SLOW_MEM[R3 + 1] + I_ADDR(R2, R0, R1), // R2 <- R0 + R1 + I_ST(R2, R3, 2), // R2 -> RTC_SLOW_MEM[R2 + 2] + I_HALT() + }; + size_t load_addr = 0; + size_t size = sizeof(program)/sizeof(ulp_insn_t); + ulp_process_macros_and_load(load_addr, program, &size); + ulp_run(load_addr); + +The ``program`` array is an array of ``ulp_insn_t``, i.e. ULP coprocessor instructions. Each ``I_XXX`` preprocessor define translates into a single 32-bit instruction. Arguments of these preprocessor defines can be register numbers (``R0 — R3``) and literal constants. See `ULP coprocessor instruction defines`_ section for descriptions of instructions and arguments they take. + +Load and store instructions use addresses expressed in 32-bit words. Address 0 corresponds to the first word of ``RTC_SLOW_MEM`` (which is address 0x50000000 as seen by the main CPUs). + +To generate branch instructions, special ``M_`` preprocessor defines are used. ``M_LABEL`` define can be used to define a branch target. Label identifier is a 16-bit integer. ``M_Bxxx`` defines can be used to generate branch instructions with target set to a particular label. + +Implementation note: these ``M_`` preprocessor defines will be translated into two ``ulp_insn_t`` values: one is a token value which contains label number, and the other is the actual instruction. ``ulp_process_macros_and_load`` function resolves the label number to the address, modifies the branch instruction to use the correct address, and removes the the extra ``ulp_insn_t`` token which contains the label numer. + +Here is an example of using labels and branches:: + + const ulp_insn_t program[] = { + I_MOVI(R0, 34), // R0 <- 34 + M_LABEL(1), // label_1 + I_MOVI(R1, 32), // R1 <- 32 + I_LD(R1, R1, 0), // R1 <- RTC_SLOW_MEM[R1] + I_MOVI(R2, 33), // R2 <- 33 + I_LD(R2, R2, 0), // R2 <- RTC_SLOW_MEM[R2] + I_SUBR(R3, R1, R2), // R3 <- R1 - R2 + I_ST(R3, R0, 0), // R3 -> RTC_SLOW_MEM[R0 + 0] + I_ADDI(R0, R0, 1), // R0++ + M_BL(1, 64), // if (R0 < 64) goto label_1 + I_HALT(), + }; + RTC_SLOW_MEM[32] = 42; + RTC_SLOW_MEM[33] = 18; + size_t load_addr = 0; + size_t size = sizeof(program)/sizeof(ulp_insn_t); + ulp_process_macros_and_load(load_addr, program, &size); + ulp_run(load_addr); + + +Functions +^^^^^^^^^ + +.. doxygenfunction:: ulp_process_macros_and_load +.. doxygenfunction:: ulp_run + +Error codes +^^^^^^^^^^^ + +.. doxygendefine:: ESP_ERR_ULP_BASE +.. doxygendefine:: ESP_ERR_ULP_SIZE_TOO_BIG +.. doxygendefine:: ESP_ERR_ULP_INVALID_LOAD_ADDR +.. doxygendefine:: ESP_ERR_ULP_DUPLICATE_LABEL +.. doxygendefine:: ESP_ERR_ULP_UNDEFINED_LABEL +.. doxygendefine:: ESP_ERR_ULP_BRANCH_OUT_OF_RANGE + +ULP coprocessor registers +^^^^^^^^^^^^^^^^^^^^^^^^^ + +ULP co-processor has 4 16-bit general purpose registers. All registers have same functionality, with one exception. R0 register is used by some of the compare-and-branch instructions as a source register. + +These definitions can be used for all instructions which require a register. + +.. doxygengroup:: ulp_registers + :content-only: + +ULP coprocessor instruction defines +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. doxygendefine:: I_DELAY +.. doxygendefine:: I_HALT +.. doxygendefine:: I_END +.. doxygendefine:: I_ST +.. doxygendefine:: I_LD +.. doxygendefine:: I_WR_REG +.. doxygendefine:: I_RD_REG +.. doxygendefine:: I_BL +.. doxygendefine:: I_BGE +.. doxygendefine:: I_BXR +.. doxygendefine:: I_BXI +.. doxygendefine:: I_BXZR +.. doxygendefine:: I_BXZI +.. doxygendefine:: I_BXFR +.. doxygendefine:: I_BXFI +.. doxygendefine:: I_ADDR +.. doxygendefine:: I_SUBR +.. doxygendefine:: I_ANDR +.. doxygendefine:: I_ORR +.. doxygendefine:: I_MOVR +.. doxygendefine:: I_LSHR +.. doxygendefine:: I_RSHR +.. doxygendefine:: I_ADDI +.. doxygendefine:: I_SUBI +.. doxygendefine:: I_ANDI +.. doxygendefine:: I_ORI +.. doxygendefine:: I_MOVI +.. doxygendefine:: I_LSHI +.. doxygendefine:: I_RSHI +.. doxygendefine:: M_LABEL +.. doxygendefine:: M_BL +.. doxygendefine:: M_BGE +.. doxygendefine:: M_BX +.. doxygendefine:: M_BXZ +.. doxygendefine:: M_BXF + +Defines +^^^^^^^ + +.. doxygendefine:: RTC_SLOW_MEM + diff --git a/components/ulp/component.mk b/components/ulp/component.mk new file mode 100755 index 0000000000..e69de29bb2 diff --git a/components/ulp/include/esp32/ulp.h b/components/ulp/include/esp32/ulp.h new file mode 100644 index 0000000000..f4e37e924a --- /dev/null +++ b/components/ulp/include/esp32/ulp.h @@ -0,0 +1,775 @@ +// Copyright 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 +#include +#include +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup ulp_registers ULP coprocessor registers + * @{ + */ + + +#define R0 0 /*!< general purpose register 0 */ +#define R1 1 /*!< general purpose register 1 */ +#define R2 2 /*!< general purpose register 2 */ +#define R3 3 /*!< general purpose register 3 */ +/**@}*/ + +/** @defgroup ulp_opcodes ULP coprocessor opcodes, sub opcodes, and various modifiers/flags + * + * These definitions are not intended to be used directly. + * They are used in definitions of instructions later on. + * + * @{ + */ + +#define OPCODE_WR_REG 1 /*!< Instruction: write peripheral register (RTC_CNTL/RTC_IO/SARADC) (not implemented yet) */ + +#define OPCODE_RD_REG 2 /*!< Instruction: read peripheral register (RTC_CNTL/RTC_IO/SARADC) (not implemented yet) */ + +#define RD_REG_PERIPH_RTC_CNTL 0 /*!< Identifier of RTC_CNTL peripheral for RD_REG and WR_REG instructions */ +#define RD_REG_PERIPH_RTC_IO 1 /*!< Identifier of RTC_IO peripheral for RD_REG and WR_REG instructions */ +#define RD_REG_PERIPH_SENS 2 /*!< Identifier of SARADC peripheral for RD_REG and WR_REG instructions */ + +#define OPCODE_I2C 3 /*!< Instruction: read/write I2C (not implemented yet) */ + +#define OPCODE_DELAY 4 /*!< Instruction: delay (nop) for a given number of cycles */ + +#define OPCODE_ADC 5 /*!< Instruction: SAR ADC measurement (not implemented yet) */ + +#define OPCODE_ST 6 /*!< Instruction: store indirect to RTC memory */ +#define SUB_OPCODE_ST 4 /*!< Store 32 bits, 16 MSBs contain PC, 16 LSBs contain value from source register */ + +#define OPCODE_ALU 7 /*!< Arithmetic instructions */ +#define SUB_OPCODE_ALU_REG 0 /*!< Arithmetic instruction, both source values are in register */ +#define SUB_OPCODE_ALU_IMM 1 /*!< Arithmetic instruction, one source value is an immediate */ +#define SUB_OPCODE_ALU_CNT 2 /*!< Arithmetic instruction between counter register and an immediate (not implemented yet)*/ +#define ALU_SEL_ADD 0 /*!< Addition */ +#define ALU_SEL_SUB 1 /*!< Subtraction */ +#define ALU_SEL_AND 2 /*!< Logical AND */ +#define ALU_SEL_OR 3 /*!< Logical OR */ +#define ALU_SEL_MOV 4 /*!< Copy value (immediate to destination register or source register to destination register */ +#define ALU_SEL_LSH 5 /*!< Shift left by given number of bits */ +#define ALU_SEL_RSH 6 /*!< Shift right by given number of bits */ + +#define OPCODE_BRANCH 8 /*!< Branch instructions */ +#define SUB_OPCODE_BX 0 /*!< Branch to absolute PC (immediate or in register) */ +#define BX_JUMP_TYPE_DIRECT 0 /*!< Unconditional jump */ +#define BX_JUMP_TYPE_ZERO 1 /*!< Branch if last ALU result is zero */ +#define BX_JUMP_TYPE_OVF 2 /*!< Branch if last ALU operation caused and overflow */ +#define SUB_OPCODE_B 1 /*!< Branch to a relative offset */ +#define B_CMP_L 0 /*!< Branch if R0 is less than an immediate */ +#define B_CMP_GE 1 /*!< Branch if R0 is greater than or equal to an immediate */ + +#define OPCODE_END 9 /*!< Stop executing the program (not implemented yet) */ +#define SUB_OPCODE_END 0 /*!< Stop executing the program and optionally wake up the chip */ +#define SUB_OPCODE_SLEEP 1 /*!< Stop executing the program and run it again after selected interval */ + +#define OPCODE_TSENS 10 /*!< Instruction: temperature sensor measurement (not implemented yet) */ + +#define OPCODE_HALT 11 /*!< Halt the coprocessor */ + +#define OPCODE_LD 13 /*!< Indirect load lower 16 bits from RTC memory */ + +#define OPCODE_MACRO 15 /*!< Not a real opcode. Used to identify labels and branches in the program */ +#define SUB_OPCODE_MACRO_LABEL 0 /*!< Label macro */ +#define SUB_OPCODE_MACRO_BRANCH 1 /*!< Branch macro */ +/**@}*/ + +/**@{*/ +#define ESP_ERR_ULP_BASE 0x1200 /*!< Offset for ULP-related error codes */ +#define ESP_ERR_ULP_SIZE_TOO_BIG (ESP_ERR_ULP_BASE + 1) /*!< Program doesn't fit into RTC memory reserved for the ULP */ +#define ESP_ERR_ULP_INVALID_LOAD_ADDR (ESP_ERR_ULP_BASE + 2) /*!< Load address is outside of RTC memory reserved for the ULP */ +#define ESP_ERR_ULP_DUPLICATE_LABEL (ESP_ERR_ULP_BASE + 3) /*!< More than one label with the same number was defined */ +#define ESP_ERR_ULP_UNDEFINED_LABEL (ESP_ERR_ULP_BASE + 4) /*!< Branch instructions references an undefined label */ +#define ESP_ERR_ULP_BRANCH_OUT_OF_RANGE (ESP_ERR_ULP_BASE + 5) /*!< Branch target is out of range of B instruction (try replacing with BX) */ +/**@}*/ + + +/** + * @brief Instruction format structure + * + * All ULP instructions are 32 bit long. + * This union contains field layouts used by all of the supported instructions. + * This union also includes a special "macro" instruction layout. + * This is not a real instruction which can be executed by the CPU. It acts + * as a token which is removed from the program by the + * ulp_process_macros_and_load function. + * + * These structures are not intended to be used directly. + * Preprocessor definitions provided below fill the fields of these structure with + * the right arguments. + */ +typedef union { + + struct { + uint32_t cycles : 16; /*!< Number of cycles to sleep */ + uint32_t unused : 12; /*!< Unused */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_DELAY) */ + } delay; /*!< Format of DELAY instruction */ + + struct { + uint32_t dreg : 2; /*!< Register which contains data to store */ + uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */ + uint32_t unused1 : 6; /*!< Unused */ + uint32_t offset : 11; /*!< Offset to add to sreg */ + uint32_t unused2 : 4; /*!< Unused */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ST) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_ST) */ + } st; /*!< Format of ST instruction */ + + struct { + uint32_t dreg : 2; /*!< Register where the data should be loaded to */ + uint32_t sreg : 2; /*!< Register which contains address in RTC memory (expressed in words) */ + uint32_t unused1 : 6; /*!< Unused */ + uint32_t offset : 11; /*!< Offset to add to sreg */ + uint32_t unused2 : 7; /*!< Unused */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_LD) */ + } ld; /*!< Format of LD instruction */ + + struct { + uint32_t unused : 28; /*!< Unused */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_HALT) */ + } halt; /*!< Format of HALT instruction */ + + struct { + uint32_t dreg : 2; /*!< Register which contains target PC, expressed in words (used if .reg == 1) */ + uint32_t addr : 11; /*!< Target PC, expressed in words (used if .reg == 0) */ + uint32_t unused : 8; /*!< Unused */ + uint32_t reg : 1; /*!< Target PC in register (1) or immediate (0) */ + uint32_t type : 3; /*!< Jump condition (BX_JUMP_TYPE_xxx) */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_BX) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */ + } bx; /*!< Format of BRANCH instruction (absolute address) */ + + struct { + uint32_t imm : 16; /*!< Immediate value to compare against */ + uint32_t cmp : 1; /*!< Comparison to perform: B_CMP_L or B_CMP_GE */ + uint32_t offset : 7; /*!< Absolute value of target PC offset w.r.t. current PC, expressed in words */ + uint32_t sign : 1; /*!< Sign of target PC offset: 0: positive, 1: negative */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_B) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_BRANCH) */ + } b; /*!< Format of BRANCH instruction (relative address) */ + + struct { + uint32_t dreg : 2; /*!< Destination register */ + uint32_t sreg : 2; /*!< Register with operand A */ + uint32_t treg : 2; /*!< Register with operand B */ + uint32_t unused : 15; /*!< Unused */ + uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_REG) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */ + } alu_reg; /*!< Format of ALU instruction (both sources are registers) */ + + struct { + uint32_t dreg : 2; /*!< Destination register */ + uint32_t sreg : 2; /*!< Register with operand A */ + uint32_t imm : 16; /*!< Immediate value of operand B */ + uint32_t unused : 1; /*!< Unused */ + uint32_t sel : 4; /*!< Operation to perform, one of ALU_SEL_xxx */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_ALU_IMM) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_ALU) */ + } alu_imm; /*!< Format of ALU instruction (one source is an immediate) */ + + struct { + uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */ + uint32_t periph_sel : 2; /*!< Select peripheral: RTC_CNTL (0), RTC_IO(1), SARADC(2) */ + uint32_t data : 8; /*!< 8 bits of data to write */ + uint32_t low : 5; /*!< Low bit */ + uint32_t high : 5; /*!< High bit */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */ + } wr_reg; /*!< Format of WR_REG instruction */ + + struct { + uint32_t addr : 8; /*!< Address within either RTC_CNTL, RTC_IO, or SARADC */ + uint32_t periph_sel : 2; /*!< Select peripheral: RTC_CNTL (0), RTC_IO(1), SARADC(2) */ + uint32_t unused : 8; /*!< Unused */ + uint32_t low : 5; /*!< Low bit */ + uint32_t high : 5; /*!< High bit */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_WR_REG) */ + } rd_reg; /*!< Format of RD_REG instruction */ + + struct { + uint32_t dreg : 2; /*!< Register where to store ADC result */ + uint32_t mux : 4; /*!< Select SARADC pad (mux + 1) */ + uint32_t sar_sel : 1; /*!< Select SARADC0 (0) or SARADC1 (1) */ + uint32_t unused1 : 1; /*!< Unused */ + uint32_t cycles : 16; /*!< TBD, cycles used for measurement */ + uint32_t unused2 : 4; /*!< Unused */ + uint32_t opcode: 4; /*!< Opcode (OPCODE_ADC) */ + } adc; /*!< Format of ADC instruction */ + + struct { + uint32_t dreg : 2; /*!< Register where to store temperature measurement result */ + uint32_t wait_delay: 14; /*!< Cycles to wait after measurement is done */ + uint32_t cycles: 12; /*!< Cycles used to perform measurement */ + uint32_t opcode: 4; /*!< Opcode (OPCODE_TSENS) */ + } tsens; /*!< Format of TSENS instruction */ + + struct { + uint32_t i2c_addr : 8; /*!< I2C slave address */ + uint32_t data : 8; /*!< Data to read or write */ + uint32_t low_bits : 3; /*!< TBD */ + uint32_t high_bits : 3; /*!< TBD */ + uint32_t i2c_sel : 4; /*!< TBD, select reg_i2c_slave_address[7:0] */ + uint32_t unused : 1; /*!< Unused */ + uint32_t rw : 1; /*!< Write (1) or read (0) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_I2C) */ + } i2c; /*!< Format of I2C instruction */ + + struct { + uint32_t wakeup : 1; /*!< Set to 1 to wake up chip */ + uint32_t unused : 24; /*!< Unused */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_WAKEUP) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */ + } end; /*!< Format of END instruction with wakeup */ + + struct { + uint32_t cycle_sel : 4; /*!< Select which one of SARADC_ULP_CP_SLEEP_CYCx_REG to get the sleep duration from */ + uint32_t unused : 21; /*!< Unused */ + uint32_t sub_opcode : 3; /*!< Sub opcode (SUB_OPCODE_SLEEP) */ + uint32_t opcode : 4; /*!< Opcode (OPCODE_END) */ + } sleep; /*!< Format of END instruction with sleep */ + + struct { + uint32_t label : 16; /*!< Label number */ + uint32_t unused : 8; /*!< Unused */ + uint32_t sub_opcode : 4; /*!< SUB_OPCODE_MACRO_LABEL or SUB_OPCODE_MACRO_BRANCH */ + uint32_t opcode: 4; /*!< Opcode (OPCODE_MACRO) */ + } macro; /*!< Format of tokens used by LABEL and BRANCH macros */ + +} ulp_insn_t; + +_Static_assert(sizeof(ulp_insn_t) == 4, "ULP coprocessor instruction size should be 4 bytes"); + +/** + * Delay (nop) for a given number of cycles + */ +#define I_DELAY(cycles_) { .delay = {\ + .opcode = OPCODE_DELAY, \ + .unused = 0, \ + .cycles = cycles_ } } + +/** + * Halt the coprocessor + */ +#define I_HALT() { .halt = {\ + .unused = 0, \ + .opcode = OPCODE_HALT } } + +/** + * Map SoC peripheral register to periph_sel field of RD_REG and WR_REG + * instructions. + * + * @param reg peripheral register in RTC_CNTL_, RTC_IO_, SENS_ peripherals. + * @return periph_sel value for the peripheral to which this register belongs. + */ +static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) { + uint32_t ret = 3; + if (reg < DR_REG_RTCCNTL_BASE) { + assert(0 && "invalid register base"); + } else if (reg < DR_REG_RTCIO_BASE) { + ret = RD_REG_PERIPH_RTC_CNTL; + } else if (reg < DR_REG_SENS_BASE) { + ret = RD_REG_PERIPH_RTC_IO; + } else if (reg < DR_REG_RTCMEM0_BASE){ + ret = RD_REG_PERIPH_SENS; + } else { + assert(0 && "invalid register base"); + } + return ret; +} + +/** + * Write literal value to a peripheral register + * + * reg[high_bit : low_bit] = val + * This instruction can access RTC_CNTL_, RTC_IO_, and SENS_ peripheral registers. + */ +#define I_WR_REG(reg, low_bit, high_bit, val) {.wr_reg = {\ + .addr = reg & 0xff, \ + .periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \ + .data = val, \ + .low = low_bit, \ + .high = high_bit, \ + .opcode = OPCODE_WR_REG } } + +/** + * Read from peripheral register into R0 + * + * R0 = reg[high_bit : low_bit] + * This instruction can access RTC_CNTL_, RTC_IO_, and SENS_ peripheral registers. + */ +#define I_RD_REG(reg, low_bit, high_bit, val) {.wr_reg = {\ + .addr = reg & 0xff, \ + .periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \ + .unused = 0, \ + .low = low_bit, \ + .high = high_bit, \ + .opcode = OPCODE_RD_REG } } + +/** + * End program. + * + * If wake == 1, wake up main CPU. + */ +#define I_END(wake) { .end = { \ + .wakeup = wake, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_END, \ + .opcode = OPCODE_END } } + +/** + * Store value from register reg_val into RTC memory. + * + * The value is written to an offset calculated by adding value of + * reg_addr register and offset_ field (this offset is expressed in 32-bit words). + * 32 bits written to RTC memory are built as follows: + * - 5 MSBs are zero + * - next 11 bits hold the PC of current instruction, expressed in 32-bit words + * - next 16 bits hold the actual value to be written + * + * RTC_SLOW_MEM[addr + offset_] = { 5'b0, insn_PC[10:0], val[15:0] } + */ +#define I_ST(reg_val, reg_addr, offset_) { .st = { \ + .dreg = reg_val, \ + .sreg = reg_addr, \ + .unused1 = 0, \ + .offset = offset_, \ + .unused2 = 0, \ + .sub_opcode = SUB_OPCODE_ST, \ + .opcode = OPCODE_ST } } + + +/** + * Load value from RTC memory into reg_dest register. + * + * Loads 16 LSBs from RTC memory word given by the sum of value in reg_addr and + * value of offset_. + */ +#define I_LD(reg_dest, reg_addr, offset_) { .ld = { \ + .dreg = reg_dest, \ + .sreg = reg_addr, \ + .unused1 = 0, \ + .offset = offset_, \ + .unused2 = 0, \ + .opcode = OPCODE_LD } } + + +/** + * Branch relative if R0 less than immediate value. + * + * pc_offset is expressed in words, and can be from -127 to 127 + * imm_value is a 16-bit value to compare R0 against + */ +#define I_BL(pc_offset, imm_value) { .b = { \ + .imm = imm_value, \ + .cmp = B_CMP_L, \ + .offset = abs(pc_offset), \ + .sign = (pc_offset >= 0) ? 0 : 1, \ + .sub_opcode = SUB_OPCODE_B, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch relative if R0 greater or equal than immediate value. + * + * pc_offset is expressed in words, and can be from -127 to 127 + * imm_value is a 16-bit value to compare R0 against + */ +#define I_BGE(pc_offset, imm_value) { .b = { \ + .imm = imm_value, \ + .cmp = B_CMP_GE, \ + .offset = abs(pc_offset), \ + .sign = (pc_offset >= 0) ? 0 : 1, \ + .sub_opcode = SUB_OPCODE_B, \ + .opcode = OPCODE_BRANCH } } + +/** + * Unconditional branch to absolute PC, address in register. + * + * reg_pc is the register which contains address to jump to. + * Address is expressed in 32-bit words. + */ +#define I_BXR(reg_pc) { .bx = { \ + .dreg = reg_pc, \ + .addr = 0, \ + .unused = 0, \ + .reg = 1, \ + .type = BX_JUMP_TYPE_DIRECT, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Unconditional branch to absolute PC, immediate address. + * + * Address imm_pc is expressed in 32-bit words. + */ +#define I_BXI(imm_pc) { .bx = { \ + .dreg = 0, \ + .addr = imm_pc, \ + .unused = 0, \ + .reg = 0, \ + .type = BX_JUMP_TYPE_DIRECT, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU result is zero, address in register. + * + * reg_pc is the register which contains address to jump to. + * Address is expressed in 32-bit words. + */ +#define I_BXZR(reg_pc) { .bx = { \ + .dreg = reg_pc, \ + .addr = 0, \ + .unused = 0, \ + .reg = 1, \ + .type = BX_JUMP_TYPE_ZERO, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU result is zero, immediate address. + * + * Address imm_pc is expressed in 32-bit words. + */ +#define I_BXZI(imm_pc) { .bx = { \ + .dreg = 0, \ + .addr = imm_pc, \ + .unused = 0, \ + .reg = 0, \ + .type = BX_JUMP_TYPE_ZERO, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU overflow, address in register + * + * reg_pc is the register which contains address to jump to. + * Address is expressed in 32-bit words. + */ +#define I_BXFR(reg_pc) { .bx = { \ + .dreg = reg_pc, \ + .addr = 0, \ + .unused = 0, \ + .reg = 1, \ + .type = BX_JUMP_TYPE_OVF, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + +/** + * Branch to absolute PC if ALU overflow, immediate address + * + * Address imm_pc is expressed in 32-bit words. + */ +#define I_BXFI(imm_pc) { .bx = { \ + .dreg = 0, \ + .addr = imm_pc, \ + .unused = 0, \ + .reg = 0, \ + .type = BX_JUMP_TYPE_OVF, \ + .sub_opcode = SUB_OPCODE_BX, \ + .opcode = OPCODE_BRANCH } } + + +/** + * Addition: dest = src1 + src2 + */ +#define I_ADDR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_ADD, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Subtraction: dest = src1 - src2 + */ +#define I_SUBR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_SUB, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Logical AND: dest = src1 & src2 + */ +#define I_ANDR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_AND, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Logical OR: dest = src1 | src2 + */ +#define I_ORR(reg_dest, reg_src1, reg_src2) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src1, \ + .treg = reg_src2, \ + .unused = 0, \ + .sel = ALU_SEL_OR, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Copy: dest = src + */ +#define I_MOVR(reg_dest, reg_src) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .treg = 0, \ + .unused = 0, \ + .sel = ALU_SEL_MOV, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Logical shift left: dest = src << shift + */ +#define I_LSHR(reg_dest, reg_src, reg_shift) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .treg = reg_shift, \ + .unused = 0, \ + .sel = ALU_SEL_LSH, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + + +/** + * Logical shift right: dest = src >> shift + */ +#define I_RSHR(reg_dest, reg_src, reg_shift) { .alu_reg = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .treg = reg_shift, \ + .unused = 0, \ + .sel = ALU_SEL_RSH, \ + .sub_opcode = SUB_OPCODE_ALU_REG, \ + .opcode = OPCODE_ALU } } + +/** + * Add register and an immediate value: dest = src1 + imm + */ +#define I_ADDI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_ADD, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + + +/** + * Subtract register and an immediate value: dest = src - imm + */ +#define I_SUBI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_SUB, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Logical AND register and an immediate value: dest = src & imm + */ +#define I_ANDI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_AND, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Logical OR register and an immediate value: dest = src | imm + */ +#define I_ORI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_OR, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Copy an immediate value into register: dest = imm + */ +#define I_MOVI(reg_dest, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = 0, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_MOV, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Logical shift left register value by an immediate: dest = src << imm + */ +#define I_LSHI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_LSH, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + + +/** + * Logical shift right register value by an immediate: dest = val >> imm + */ +#define I_RSHI(reg_dest, reg_src, imm_) { .alu_imm = { \ + .dreg = reg_dest, \ + .sreg = reg_src, \ + .imm = imm_, \ + .unused = 0, \ + .sel = ALU_SEL_RSH, \ + .sub_opcode = SUB_OPCODE_ALU_IMM, \ + .opcode = OPCODE_ALU } } + +/** + * Define a label with number label_num. + * + * This is a macro which doesn't generate a real instruction. + * The token generated by this macro is removed by ulp_process_macros_and_load + * function. Label defined using this macro can be used in branch macros defined + * below. + */ +#define M_LABEL(label_num) { .macro = { \ + .label = label_num, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_MACRO_LABEL, \ + .opcode = OPCODE_MACRO } } + +/** + * Token macro used by M_B and M_BX macros. Not to be used directly. + */ +#define M_BRANCH(label_num) { .macro = { \ + .label = label_num, \ + .unused = 0, \ + .sub_opcode = SUB_OPCODE_MACRO_BRANCH, \ + .opcode = OPCODE_MACRO } } + +/** + * Macro: branch to label label_num if R0 is less than immediate value. + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BL(label_num, imm_value) \ + M_BRANCH(label_num), \ + I_BL(0, imm_value) + +/** + * Macro: branch to label label_num if R0 is greater or equal than immediate value + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BGE(label_num, imm_value) \ + M_BRANCH(label_num), \ + I_BGE(0, imm_value) + +/** + * Macro: unconditional branch to label + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BX(label_num) \ + M_BRANCH(label_num), \ + I_BXI(0) + +/** + * Macro: branch to label if ALU result is zero + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BXZ(label_num) \ + M_BRANCH(label_num), \ + I_BXZI(0) + +/** + * Macro: branch to label if ALU overflow + * + * This macro generates two ulp_insn_t values separated by a comma, and should + * be used when defining contents of ulp_insn_t arrays. First value is not a + * real instruction; it is a token which is removed by ulp_process_macros_and_load + * function. + */ +#define M_BXF(label_num) \ + M_BRANCH(label_num), \ + I_BXFI(0) + + + +#define RTC_SLOW_MEM ((uint32_t*) 0x50000000) /*!< RTC slow memory, 8k size */ + +/** + * @brief Resolve all macro references in a program and load it into RTC memory + * @param load_addr address where the program should be loaded, expressed in 32-bit words + * @param program ulp_insn_t array with the program + * @param psize size of the program, expressed in 32-bit words + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM if auxiliary temporary structure can not be allocated + * - one of ESP_ERR_ULP_xxx if program is not valid or can not be loaded + */ +esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* program, size_t* psize); + +/** + * @brief Run the program loaded into RTC memory + * @param entry_point entry point, expressed in 32-bit words + * @return ESP_OK on success + */ +esp_err_t ulp_run(uint32_t entry_point); + + +#ifdef __cplusplus +} +#endif diff --git a/components/ulp/test/component.mk b/components/ulp/test/component.mk new file mode 100644 index 0000000000..ce464a212a --- /dev/null +++ b/components/ulp/test/component.mk @@ -0,0 +1 @@ +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/ulp/test/test_ulp.c b/components/ulp/test/test_ulp.c new file mode 100644 index 0000000000..854eb3ee20 --- /dev/null +++ b/components/ulp/test/test_ulp.c @@ -0,0 +1,170 @@ +// 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 +#include +#include +#include +#include + +#include +#include "esp_attr.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_deep_sleep.h" + +#include "esp32/ulp.h" + +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/sens_reg.h" +#include "driver/rtc_io.h" + +#include "sdkconfig.h" + +static void hexdump(const uint32_t* src, size_t count) { + for (size_t i = 0; i < count; ++i) { + printf("%08x ", *src); + ++src; + if ((i + 1) % 4 == 0) { + printf("\n"); + } + } +} + +TEST_CASE("ulp add test", "[ulp]") +{ + memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); + const ulp_insn_t program[] = { + I_MOVI(R3, 16), + I_LD(R0, R3, 0), + I_LD(R1, R3, 1), + I_ADDR(R2, R0, R1), + I_ST(R2, R3, 2), + I_HALT() + }; + RTC_SLOW_MEM[16] = 10; + RTC_SLOW_MEM[17] = 11; + size_t size = sizeof(program)/sizeof(ulp_insn_t); + TEST_ASSERT_EQUAL(ESP_OK, ulp_process_macros_and_load(0, program, &size)); + TEST_ASSERT_EQUAL(ESP_OK, ulp_run(0)); + ets_delay_us(1000); + hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4); + TEST_ASSERT_EQUAL(10 + 11, RTC_SLOW_MEM[18] & 0xffff); +} + +TEST_CASE("ulp branch test", "[ulp]") +{ + assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); + memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); + const ulp_insn_t program[] = { + I_MOVI(R0, 34), // r0 = dst + M_LABEL(1), + I_MOVI(R1, 32), + I_LD(R1, R1, 0), // r1 = mem[33] + I_MOVI(R2, 33), + I_LD(R2, R2, 0), // r2 = mem[34] + I_SUBR(R3, R1, R2), // r3 = r1 - r2 + I_ST(R3, R0, 0), // dst[0] = r3 + I_ADDI(R0, R0, 1), + M_BL(1, 64), + I_HALT(), + }; + RTC_SLOW_MEM[32] = 42; + RTC_SLOW_MEM[33] = 18; + hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4); + size_t size = sizeof(program)/sizeof(ulp_insn_t); + ulp_process_macros_and_load(0, program, &size); + ulp_run(0); + printf("\n\n"); + hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4); + for (int i = 34; i < 64; ++i) { + TEST_ASSERT_EQUAL(42 - 18, RTC_SLOW_MEM[i] & 0xffff); + } + TEST_ASSERT_EQUAL(0, RTC_SLOW_MEM[64]); +} + +TEST_CASE("ulp wakeup test", "[ulp]") +{ + assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); + memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); + const ulp_insn_t program[] = { + I_MOVI(R1, 1024), + M_LABEL(1), + I_DELAY(32000), + I_SUBI(R1, R1, 1), + M_BXZ(3), + I_RSHI(R3, R1, 5), // R3 = R1 / 32 + I_ST(R1, R3, 16), + M_BX(1), + M_LABEL(3), + I_MOVI(R2, 42), + I_MOVI(R3, 15), + I_ST(R2, R3, 0), + I_END(1) + }; + size_t size = sizeof(program)/sizeof(ulp_insn_t); + ulp_process_macros_and_load(0, program, &size); + ulp_run(0); + esp_deep_sleep_enable_ulp_wakeup(); + esp_deep_sleep_start(); +} + +TEST_CASE("ulp controls RTC_IO", "[ulp]") +{ + assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); + memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); + const ulp_insn_t program[] = { + I_MOVI(R0, 0), // R0 is LED state + I_MOVI(R2, 16), // loop R2 from 16 down to 0 + M_LABEL(4), + I_SUBI(R2, R2, 1), + M_BXZ(6), + I_ADDI(R0, R0, 1), // R0 = (R0 + 1) % 2 + I_ANDI(R0, R0, 0x1), + M_BL(0, 1), // if R0 < 1 goto 0 + M_LABEL(1), + I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 1), // RTC_GPIO12 = 1 + M_BX(2), // goto 2 + M_LABEL(0), // 0: + I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 0), // RTC_GPIO12 = 0 + M_LABEL(2), // 2: + I_MOVI(R1, 100), // loop R1 from 100 down to 0 + M_LABEL(3), + I_SUBI(R1, R1, 1), + M_BXZ(5), + I_DELAY(32000), // delay for a while + M_BX(3), + M_LABEL(5), + M_BX(4), + M_LABEL(6), + I_END(1) // wake up the SoC + }; + const gpio_num_t led_gpios[] = { + GPIO_NUM_2, + GPIO_NUM_0, + GPIO_NUM_4 + }; + for (size_t i = 0; i < sizeof(led_gpios)/sizeof(led_gpios[0]); ++i) { + rtc_gpio_init(led_gpios[i]); + rtc_gpio_set_direction(led_gpios[i], RTC_GPIO_MODE_OUTPUT_ONLY); + rtc_gpio_set_level(led_gpios[i], 0); + } + size_t size = sizeof(program)/sizeof(ulp_insn_t); + ulp_process_macros_and_load(0, program, &size); + ulp_run(0); + esp_deep_sleep_enable_ulp_wakeup(); + esp_deep_sleep_start(); +} + diff --git a/components/ulp/ulp.c b/components/ulp/ulp.c new file mode 100644 index 0000000000..60fa292f7c --- /dev/null +++ b/components/ulp/ulp.c @@ -0,0 +1,277 @@ +// 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 +#include +#include + +#include "esp_attr.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp32/ulp.h" + +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/sens_reg.h" + +#include "sdkconfig.h" + +static const char* TAG = "ulp"; + +typedef struct { + uint32_t label : 16; + uint32_t addr : 11; + uint32_t unused : 1; + uint32_t type : 4; +} reloc_info_t; + +#define RELOC_TYPE_LABEL 0 +#define RELOC_TYPE_BRANCH 1 + +/* This record means: there is a label at address + * insn_addr, with number label_num. + */ +#define RELOC_INFO_LABEL(label_num, insn_addr) (reloc_info_t) { \ + .label = label_num, \ + .addr = insn_addr, \ + .unused = 0, \ + .type = RELOC_TYPE_LABEL } + +/* This record means: there is a branch instruction at + * insn_addr, it needs to be changed to point to address + * of label label_num. + */ +#define RELOC_INFO_BRANCH(label_num, insn_addr) (reloc_info_t) { \ + .label = label_num, \ + .addr = insn_addr, \ + .unused = 0, \ + .type = RELOC_TYPE_BRANCH } + + +/* Processing branch and label macros involves four steps: + * + * 1. Iterate over program and count all instructions + * with "macro" opcode. Allocate relocations array + * with number of entries equal to number of macro + * instructions. + * + * 2. Remove all fake instructions with "macro" opcode + * and record their locations into relocations array. + * Removal is done using two pointers. Instructions + * are read from read_ptr, and written to write_ptr. + * When a macro instruction is encountered, + * its contents are recorded into the appropriate + * table, and then read_ptr is advanced again. + * When a real instruction is encountered, it is + * read via read_ptr and written to write_ptr. + * In the end, all macro instructions are removed, + * size of the program (expressed in words) is + * reduced by the total number of macro instructions + * which were present. + * + * 3. Sort relocations array by label number, and then + * by type ("label" or "branch") if label numbers + * match. This is done to simplify lookup on the next + * step. + * + * 4. Iterate over entries of relocations table. + * For each label number, label entry comes first + * because the array was sorted at the previous step. + * Label address is recorded, and all subsequent + * "branch" entries which point to the same label number + * are processed. For each branch entry, correct offset + * or absolute address is calculated, depending on branch + * type, and written into the appropriate field of + * the instruction. + * + */ + +static esp_err_t do_single_reloc(ulp_insn_t* program, uint32_t load_addr, + reloc_info_t label_info, reloc_info_t branch_info) +{ + size_t insn_offset = branch_info.addr - load_addr; + ulp_insn_t* insn = &program[insn_offset]; + // B and BX have the same layout of opcode/sub_opcode fields, + // and share the same opcode + assert(insn->b.opcode == OPCODE_BRANCH + && "branch macro was applied to a non-branch instruction"); + switch (insn->b.sub_opcode) { + case SUB_OPCODE_B: { + int32_t offset = ((int32_t) label_info.addr) - ((int32_t) branch_info.addr); + uint32_t abs_offset = abs(offset); + uint32_t sign = (offset >= 0) ? 0 : 1; + if (abs_offset > 127) { + ESP_LOGW(TAG, "target out of range: branch from %x to %x", + branch_info.addr, label_info.addr); + return ESP_ERR_ULP_BRANCH_OUT_OF_RANGE; + } + insn->b.offset = abs_offset; + insn->b.sign = sign; + break; + } + case SUB_OPCODE_BX: { + assert(insn->bx.reg == 0 && + "relocation applied to a jump with offset in register"); + insn->bx.addr = label_info.addr; + break; + } + default: + assert(false && "unexpected sub-opcode"); + } + return ESP_OK; +} + +esp_err_t ulp_process_macros_and_load(uint32_t load_addr, const ulp_insn_t* program, size_t* psize) +{ + const ulp_insn_t* read_ptr = program; + const ulp_insn_t* end = program + *psize; + size_t macro_count = 0; + // step 1: calculate number of macros + while (read_ptr < end) { + ulp_insn_t r_insn = *read_ptr; + if (r_insn.macro.opcode == OPCODE_MACRO) { + ++macro_count; + } + ++read_ptr; + } + size_t real_program_size = *psize - macro_count; + const size_t ulp_mem_end = CONFIG_ULP_COPROC_RESERVE_MEM / sizeof(ulp_insn_t); + if (load_addr > ulp_mem_end) { + ESP_LOGW(TAG, "invalid load address %x, max is %x", + load_addr, ulp_mem_end); + return ESP_ERR_ULP_INVALID_LOAD_ADDR; + } + if (real_program_size + load_addr > ulp_mem_end) { + ESP_LOGE(TAG, "program too big: %d words, max is %d words", + real_program_size, ulp_mem_end); + return ESP_ERR_ULP_SIZE_TOO_BIG; + } + // If no macros found, copy the program and return. + if (macro_count == 0) { + memcpy(((ulp_insn_t*) RTC_SLOW_MEM) + load_addr, program, *psize * sizeof(ulp_insn_t)); + return ESP_OK; + } + reloc_info_t* reloc_info = + (reloc_info_t*) malloc(sizeof(reloc_info_t) * macro_count); + if (reloc_info == NULL) { + return ESP_ERR_NO_MEM; + } + + // step 2: record macros into reloc_info array + // and remove them from then program + read_ptr = program; + ulp_insn_t* output_program = ((ulp_insn_t*) RTC_SLOW_MEM) + load_addr; + ulp_insn_t* write_ptr = output_program; + uint32_t cur_insn_addr = load_addr; + reloc_info_t* cur_reloc = reloc_info; + while (read_ptr < end) { + ulp_insn_t r_insn = *read_ptr; + if (r_insn.macro.opcode == OPCODE_MACRO) { + switch(r_insn.macro.sub_opcode) { + case SUB_OPCODE_MACRO_LABEL: + *cur_reloc = RELOC_INFO_LABEL(r_insn.macro.label, + cur_insn_addr); + break; + case SUB_OPCODE_MACRO_BRANCH: + *cur_reloc = RELOC_INFO_BRANCH(r_insn.macro.label, + cur_insn_addr); + break; + default: + assert(0 && "invalid sub_opcode for macro insn"); + } + ++read_ptr; + assert(read_ptr != end && "program can not end with macro insn"); + ++cur_reloc; + } else { + // normal instruction (not a macro) + *write_ptr = *read_ptr; + ++read_ptr; + ++write_ptr; + ++cur_insn_addr; + } + } + + // step 3: sort relocations array + int reloc_sort_func(const void* p_lhs, const void* p_rhs) { + const reloc_info_t lhs = *(const reloc_info_t*) p_lhs; + const reloc_info_t rhs = *(const reloc_info_t*) p_rhs; + if (lhs.label < rhs.label) { + return -1; + } else if (lhs.label > rhs.label) { + return 1; + } + // label numbers are equal + if (lhs.type < rhs.type) { + return -1; + } else if (lhs.type > rhs.type) { + return 1; + } + + // both label number and type are equal + return 0; + } + qsort(reloc_info, macro_count, sizeof(reloc_info_t), + reloc_sort_func); + + // step 4: walk relocations array and fix instructions + reloc_info_t* reloc_end = reloc_info + macro_count; + cur_reloc = reloc_info; + while(cur_reloc < reloc_end) { + reloc_info_t label_info = *cur_reloc; + assert(label_info.type == RELOC_TYPE_LABEL); + ++cur_reloc; + while (cur_reloc < reloc_end) { + if (cur_reloc->type == RELOC_TYPE_LABEL) { + if(cur_reloc->label == label_info.label) { + ESP_LOGE(TAG, "duplicate label definition: %d", + label_info.label); + free(reloc_info); + return ESP_ERR_ULP_DUPLICATE_LABEL; + } + break; + } + if (cur_reloc->label != label_info.label) { + ESP_LOGE(TAG, "branch to an inexistent label: %d", + cur_reloc->label); + free(reloc_info); + return ESP_ERR_ULP_UNDEFINED_LABEL; + } + esp_err_t rc = do_single_reloc(output_program, load_addr, + label_info, *cur_reloc); + if (rc != ESP_OK) { + free(reloc_info); + return rc; + } + ++cur_reloc; + } + } + free(reloc_info); + *psize = real_program_size; + return ESP_OK; +} + +esp_err_t ulp_run(uint32_t entry_point) +{ + // disable ULP timer + CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + // set entry point + SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_PC_INIT_V, entry_point, SENS_PC_INIT_S); + // disable force start + CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP_M); + // make sure voltage is raised when RTC 8MCLK is enabled + SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FOLW_8M); + // enable ULP timer + SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + return ESP_OK; +} diff --git a/docs/Doxyfile b/docs/Doxyfile index 11921dfe06..668ebaba02 100755 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -26,7 +26,13 @@ INPUT = ../components/esp32/include/esp_wifi.h \ ../components/esp32/include/esp_int_wdt.h \ ../components/esp32/include/esp_task_wdt.h \ ../components/app_update/include/esp_ota_ops.h \ - ../components/ethernet/include/esp_eth.h + ../components/ethernet/include/esp_eth.h \ + ../components/ulp/include/esp32/ulp.h \ + ../components/esp32/include/esp_intr_alloc.h \ + ../components/esp32/include/esp_heap_alloc_caps.h \ + ../components/freertos/include/freertos/heap_regions.h \ + ../components/esp32/include/esp_smartconfig.h \ + ../components/esp32/include/esp_deep_sleep.h ## Get warnings for functions that have no documentation for their parameters or return value ## diff --git a/docs/api/deep_sleep.rst b/docs/api/deep_sleep.rst new file mode 100644 index 0000000000..3a458fb4a8 --- /dev/null +++ b/docs/api/deep_sleep.rst @@ -0,0 +1,87 @@ +Deep Sleep +========== + +Overview +-------- + +ESP32 is capable of deep sleep power saving mode. In this mode CPUs, most of the RAM, and all the digital peripherals which are clocked from APB_CLK are powered off. The only parts of the chip which can still be powered on are: RTC controller, RTC peripherals (including ULP coprocessor), and RTC memories (slow and fast). + +Wakeup from deep sleep mode can be done using several sources. These sources can be combined, in this case the chip will wake up when any one of the sources is triggered. Wakeup sources can be enabled using ``esp_deep_sleep_enable_X_wakeup`` APIs. Next section describes these APIs in detail. Wakeup sources can be configured at any moment before entering deep sleep mode. + +Additionally, the application can force specific powerdown modes for the RTC peripherals and RTC memories using ``esp_deep_sleep_pd_config`` API. + +Once wakeup sources are configured, application can start deep sleep using ``esp_deep_sleep_start`` API. At this point the hardware will be configured according to the requested wakeup sources, and RTC controller will power down the CPUs and digital peripherals. + +Wakeup sources +-------------- + +Timer +^^^^^ + +RTC controller has a built in timer which can be used to wake up the chip after a predefined amount of time. Time is specified at microsecond precision, but the actual resolution depends on the clock source selected for RTC SLOW_CLK. See chapter "Reset and Clock" of the ESP32 Technical Reference Manual for details about RTC clock options. + +This wakeup mode doesn't require RTC peripherals or RTC memories to be powered on during deep sleep. + +The following function can be used to enable deep sleep wakeup using a timer. + +.. doxygenfunction:: esp_deep_sleep_enable_timer_wakeup + + +External wakeup (ext0) +^^^^^^^^^^^^^^^^^^^^^^ + +RTC IO module contains logic to trigger wakeup when one of RTC GPIOs is set to a predefined logic level. RTC IO is part of RTC peripherals power domain, so RTC peripherals will be kept powered on during deep sleep if this wakeup source is requested. + +Because RTC IO module is enabled in this mode, internal pullup or pulldown resistors can also be used. They need to be configured by the application using ``rtc_gpio_pullup_en`` and ``rtc_gpio_pulldown_en`` functions, before calling ``esp_deep_sleep_start``. + +.. doxygenfunction:: esp_deep_sleep_enable_ext0_wakeup + +External wakeup (ext1) +^^^^^^^^^^^^^^^^^^^^^^ + +RTC controller contains logic to trigger wakeup using multiple RTC GPIOs. One of the two logic functions can be used to trigger wakeup: + + - wake up if any of the selected pins is low + - wake up if all the selected pins are high + +This wakeup source is implemented by the RTC controller. As such, RTC peripherals and RTC memories can be powered off in this mode. However, if RTC peripherals are powered down, internal pullup and pulldown resistors will be disabled. To use internal pullup or pulldown resistors, request RTC peripherals power domain to be kept on during deep sleep, and configure pullup/pulldown resistors using ``rtc_gpio_`` functions, before entering deep sleep:: + + esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + gpio_pullup_dis(gpio_num); + gpio_pulldown_en(gpio_num); + +The following function can be used to enable this wakeup mode: + +.. doxygenfunction:: esp_deep_sleep_enable_ext1_wakeup + +.. doxygenenum:: esp_ext1_wakeup_mode_t + + +ULP coprocessor wakeup +^^^^^^^^^^^^^^^^^^^^^^ + +ULP coprocessor can run while the chip is in deep sleep, and may be used to poll sensors, monitor ADC or touch sensor values, and wake up the chip when a specific event is detected. ULP coprocessor is part of RTC peripherals power domain, and it runs the program stored in RTC slow memeory. Therefore RTC peripherals and RTC slow memory will be powered on during deep sleep if this wakeup mode is requested. + +The following function can be used to enable this wakeup mode: + +.. doxygenfunction:: esp_deep_sleep_enable_ulp_wakeup + +Power-down of RTC peripherals and memories +------------------------------------------ + +By default, ``esp_deep_sleep_start`` function will power down all RTC power domains which are not needed by the enabled wakeup sources. To override this behaviour, the following function is provided: + +Note: on the first revision of the ESP32, RTC fast memory will always be kept enabled in deep sleep, so that the deep sleep stub can run after reset. This can be overriden, if the application doesn't need clean reset behaviour after deep sleep. + +.. doxygenfunction:: esp_deep_sleep_pd_config +.. doxygenenum:: esp_deep_sleep_pd_domain_t +.. doxygenenum:: esp_deep_sleep_pd_option_t + + +Entering deep sleep +------------------- + +The following function can be used to enter deep sleep once wakeup sources are configured. It is also possible to go into deep sleep with no wakeup sources configured, in this case the chip will be in deep sleep mode indefinetly, until external reset is applied. + +.. doxygenfunction:: esp_deep_sleep_start + diff --git a/docs/api/esp_eth.rst b/docs/api/esp_eth.rst index f8f19092d1..d6d98e43d8 100644 --- a/docs/api/esp_eth.rst +++ b/docs/api/esp_eth.rst @@ -4,7 +4,7 @@ ETHERNET Application Example ------------------- -ethernet example: `examples/14_ethernet `_. +ethernet example: `examples/17_ethernet `_. API Reference ------------- diff --git a/docs/api/esp_gatt_defs.rst b/docs/api/esp_gatt_defs.rst index a4cfe918cd..b5a416d436 100644 --- a/docs/api/esp_gatt_defs.rst +++ b/docs/api/esp_gatt_defs.rst @@ -25,7 +25,65 @@ Header Files Macros ^^^^^^ - +.. doxygendefine:: ESP_GATT_UUID_PRI_SERVICE +.. doxygendefine:: ESP_GATT_UUID_SEC_SERVICE +.. doxygendefine:: ESP_GATT_UUID_INCLUDE_SERVICE +.. doxygendefine:: ESP_GATT_UUID_CHAR_DECLARE +.. doxygendefine:: ESP_GATT_UUID_CHAR_EXT_PROP +.. doxygendefine:: ESP_GATT_UUID_CHAR_DESCRIPTION +.. doxygendefine:: ESP_GATT_UUID_CHAR_CLIENT_CONFIG +.. doxygendefine:: ESP_GATT_UUID_CHAR_SRVR_CONFIG +.. doxygendefine:: ESP_GATT_UUID_CHAR_PRESENT_FORMAT +.. doxygendefine:: ESP_GATT_UUID_CHAR_AGG_FORMAT +.. doxygendefine:: ESP_GATT_UUID_CHAR_VALID_RANGE +.. doxygendefine:: ESP_GATT_UUID_EXT_RPT_REF_DESCR +.. doxygendefine:: ESP_GATT_UUID_RPT_REF_DESCR +.. doxygendefine:: ESP_GATT_UUID_GAP_DEVICE_NAME +.. doxygendefine:: ESP_GATT_UUID_GAP_ICON +.. doxygendefine:: ESP_GATT_UUID_GAP_PREF_CONN_PARAM +.. doxygendefine:: ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL +.. doxygendefine:: ESP_GATT_UUID_GATT_SRV_CHGD +.. doxygendefine:: ESP_GATT_UUID_ALERT_LEVEL +.. doxygendefine:: ESP_GATT_UUID_TX_POWER_LEVEL +.. doxygendefine:: ESP_GATT_UUID_CURRENT_TIME +.. doxygendefine:: ESP_GATT_UUID_LOCAL_TIME_INFO +.. doxygendefine:: ESP_GATT_UUID_REF_TIME_INFO +.. doxygendefine:: ESP_GATT_UUID_NW_STATUS +.. doxygendefine:: ESP_GATT_UUID_NW_TRIGGER +.. doxygendefine:: ESP_GATT_UUID_ALERT_STATUS +.. doxygendefine:: ESP_GATT_UUID_RINGER_CP +.. doxygendefine:: ESP_GATT_UUID_RINGER_SETTING +.. doxygendefine:: ESP_GATT_UUID_GM_MEASUREMENT +.. doxygendefine:: ESP_GATT_UUID_GM_CONTEXT +.. doxygendefine:: ESP_GATT_UUID_GM_CONTROL_POINT +.. doxygendefine:: ESP_GATT_UUID_GM_FEATURE +.. doxygendefine:: ESP_GATT_UUID_SYSTEM_ID +.. doxygendefine:: ESP_GATT_UUID_MODEL_NUMBER_STR +.. doxygendefine:: ESP_GATT_UUID_SERIAL_NUMBER_STR +.. doxygendefine:: ESP_GATT_UUID_FW_VERSION_STR +.. doxygendefine:: ESP_GATT_UUID_HW_VERSION_STR +.. doxygendefine:: ESP_GATT_UUID_SW_VERSION_STR +.. doxygendefine:: ESP_GATT_UUID_MANU_NAME +.. doxygendefine:: ESP_GATT_UUID_IEEE_DATA +.. doxygendefine:: ESP_GATT_UUID_PNP_ID +.. doxygendefine:: ESP_GATT_UUID_HID_INFORMATION +.. doxygendefine:: ESP_GATT_UUID_HID_REPORT_MAP +.. doxygendefine:: ESP_GATT_UUID_HID_CONTROL_POINT +.. doxygendefine:: ESP_GATT_UUID_HID_REPORT +.. doxygendefine:: ESP_GATT_UUID_HID_PROTO_MODE +.. doxygendefine:: ESP_GATT_UUID_HID_BT_KB_INPUT +.. doxygendefine:: ESP_GATT_UUID_HID_BT_KB_OUTPUT +.. doxygendefine:: ESP_GATT_UUID_HID_BT_MOUSE_INPUT +.. doxygendefine:: ESP_GATT_UUID_BATTERY_LEVEL +.. doxygendefine:: ESP_GATT_UUID_SC_CONTROL_POINT +.. doxygendefine:: ESP_GATT_UUID_SENSOR_LOCATION +.. doxygendefine:: ESP_GATT_UUID_RSC_MEASUREMENT +.. doxygendefine:: ESP_GATT_UUID_RSC_FEATURE +.. doxygendefine:: ESP_GATT_UUID_CSC_MEASUREMENT +.. doxygendefine:: ESP_GATT_UUID_CSC_FEATURE +.. doxygendefine:: ESP_GATT_UUID_SCAN_INT_WINDOW +.. doxygendefine:: ESP_GATT_UUID_SCAN_REFRESH +.. doxygendefine:: ESP_GATT_ILLEGAL_UUID .. doxygendefine:: ESP_GATT_MAX_ATTR_LEN Type Definitions diff --git a/docs/api/esp_smartconfig.rst b/docs/api/esp_smartconfig.rst new file mode 100644 index 0000000000..262218aa8b --- /dev/null +++ b/docs/api/esp_smartconfig.rst @@ -0,0 +1,25 @@ +Smart Config +=== + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `esp32/include/esp_smartconfig.h `_ + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: sc_callback_t + +Functions +^^^^^^^^^ + +.. doxygenfunction:: esp_smartconfig_get_version +.. doxygenfunction:: esp_smartconfig_start +.. doxygenfunction:: esp_smartconfig_stop +.. doxygenfunction:: esp_esptouch_set_timeout +.. doxygenfunction:: esp_smartconfig_set_type +.. doxygenfunction:: esp_smartconfig_fast_mode diff --git a/docs/api/intr_alloc.rst b/docs/api/intr_alloc.rst new file mode 100644 index 0000000000..4d2f21abac --- /dev/null +++ b/docs/api/intr_alloc.rst @@ -0,0 +1,111 @@ +Interrupt allocation +==================== + +Overview +-------- + +The ESP32 has two cores, with 32 interrupts each. Each interrupt has a certain priority level, most (but not all) interrupts are connected +to the interrupt mux. Because there are more interrupt sources than interrupts, sometimes it makes sense to share an interrupt in +multiple drivers. The esp_intr_alloc abstraction exists to hide all these implementation details. + +A driver can allocate an interrupt for a certain peripheral by calling esp_intr_alloc (or esp_intr_alloc_sintrstatus). It can use +the flags passed to this function to set the type of interrupt allocated, specifying a specific level or trigger method. The +interrupt allocation code will then find an applicable interrupt, use the interrupt mux to hook it up to the peripheral, and +install the given interrupt handler and ISR to it. + +This code has two different types of interrupts it handles differently: Shared interrupts and non-shared interrupts. The simplest +of the two are non-shared interrupts: a separate interrupt is allocated per esp_intr_alloc call and this interrupt is solely used for +the peripheral attached to it, with only one ISR that will get called. Non-shared interrupts can have multiple peripherals triggering +it, with multiple ISRs being called when one of the peripherals attached signals an interrupt. Thus, ISRs that are intended for shared +interrupts should check the interrupt status of the peripheral they service in order to see if any action is required. + +Non-shared interrupts can be either level- or edge-triggered. Shared interrupts can +only be level interrupts (because of the chance of missed interrupts when edge interrupts are +used.) +(The logic behind this: DevA and DevB share an int. DevB signals an int. Int line goes high. ISR handler +calls code for DevA -> does nothing. ISR handler calls code for DevB, but while doing that, +DevA signals an int. ISR DevB is done, clears int for DevB, exits interrupt code. Now an +interrupt for DevA is still pending, but because the int line never went low (DevA kept it high +even when the int for DevB was cleared) the interrupt is never serviced.) + + +Multicore issues +---------------- + +Peripherals that can generate interrupts can be divided in two types: external peripherals, outside the Xtensa +cores in the ESP32, and internal peripherals, inside the ESP32. Interrupt handling differs slightly between +these two types of peripherals. + +Each Xtensa core has its own set of internal peripherals: three timer comparators, a performance monitor and two +software interrupts. These peripherals can only be configured from the core they are associated with. When +generating an interrupt, the interrupt they generate is hard-wired to their associated core; it's not possible +to have e.g. an internal timer comparator of one core generate an interrupt on another core. That is why these +sources can only be managed using a task running on that specific core. Internal interrupt sources are still +allocatable using esp_intr_alloc as normal, but they cannot be shared and will always have a fixed interrupt +level (namely, the one associated in hardware with the peripheral). Internal interrupt sources are defined +in esp_intr_alloc.h as ETS_INTERNAL_*_INTR_SOURCE. + +The remaining interrupt slots in both cores are wired to an interrupt multiplexer, which can be used to +route any external interrupt source to any of these interrupt slots. Allocating an external interrupt will always +allocate it on the core that does the allocation, and freeing the interrupt should always happen on the same +core. Disabling and enabling the interrupt from another core is allowed, however. External interrupts can +share an interrupt slot bu passing ESP_INTR_FLAG_SHARED as a flag to esp_intr_alloc. External interrupt sources +are defined in soc/soc.h as ETS_*_INTR_SOURCE. + +Care should be taken when allocating an interrupt using a task not pinned to a certain core; while running +code not in a critical secion, these tasks can migrate between cores at any moment, possibly making an +interrupt operation fail because of the reasons mentioned above. It is advised to always use +xTaskCreatePinnedToCore with a specific CoreID argument to create tasks that will handle interrupts. + +Application Example +------------------- + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `esp_intr_alloc.h `_ + + +Macros +^^^^^^ + +.. doxygendefine:: ESP_INTR_FLAG_LEVEL1 +.. doxygendefine:: ESP_INTR_FLAG_LEVEL2 +.. doxygendefine:: ESP_INTR_FLAG_LEVEL3 +.. doxygendefine:: ESP_INTR_FLAG_LEVEL4 +.. doxygendefine:: ESP_INTR_FLAG_LEVEL5 +.. doxygendefine:: ESP_INTR_FLAG_LEVEL6 +.. doxygendefine:: ESP_INTR_FLAG_NMI +.. doxygendefine:: ESP_INTR_FLAG_LOWMED +.. doxygendefine:: ESP_INTR_FLAG_HIGH +.. doxygendefine:: ESP_INTR_FLAG_SHARED +.. doxygendefine:: ESP_INTR_FLAG_EDGE +.. doxygendefine:: ESP_INTR_FLAG_IRAM +.. doxygendefine:: ESP_INTR_FLAG_INTRDISABLED + +Type Definitions +^^^^^^^^^^^^^^^^ + +Enumerations +^^^^^^^^^^^^ + +Structures +^^^^^^^^^^ + +Functions +^^^^^^^^^ + +.. doxygenfunction:: esp_intr_mark_shared +.. doxygenfunction:: esp_intr_reserve +.. doxygenfunction:: esp_intr_alloc +.. doxygenfunction:: esp_intr_alloc_intrstatus +.. doxygenfunction:: esp_intr_free +.. doxygenfunction:: esp_intr_get_cpu +.. doxygenfunction:: esp_intr_get_intno +.. doxygenfunction:: esp_intr_disable +.. doxygenfunction:: esp_intr_enable +.. doxygenfunction:: esp_intr_noniram_disable +.. doxygenfunction:: esp_intr_noniram_enable diff --git a/docs/api/mem_alloc.rst b/docs/api/mem_alloc.rst new file mode 100644 index 0000000000..cebea5b8a5 --- /dev/null +++ b/docs/api/mem_alloc.rst @@ -0,0 +1,77 @@ +Memory allocation +==================== + +Overview +-------- + +The ESP32 has multiple types of RAM. Internally, there's IRAM, DRAM as well as RAM that can be used as both. It's also +possible to connect external SPI flash to the ESP32; it's memory can be integrated into the ESP32s memory map using +the flash cache. + +In order to make use of all this memory, esp-idf has a capabilities-based memory allocator. Basically, if you want to have +memory with certain properties (for example, DMA-capable, accessible by a certain PID, or capable of executing code), you +can create an OR-mask of the required capabilities and pass that to pvPortMallocCaps. For instance, the normal malloc +code internally allocates memory with ```pvPortMallocCaps(size, MALLOC_CAP_8BIT)``` in order to get data memory that is +byte-addressable. + +Because malloc uses this allocation system as well, memory allocated using pvPortMallocCaps can be freed by calling +the standard ```free()``` function. + +Internally, this allocator is split in two pieces. The allocator in the FreeRTOS directory can allocate memory from +tagged regions: a tag is an integer value and every region of free memory has one of these tags. The esp32-specific +code initializes these regions with specific tags, and contains the logic to select applicable tags from the +capabilities given by the user. While shown in the public API, tags are used in the communication between the two parts +and should not be used directly. + +Special Uses +------------ + +If a certain memory structure is only addressed in 32-bit units, for example an array of ints or pointers, it can be +useful to allocate it with the MALLOC_CAP_32BIT flag. This also allows the allocator to give out IRAM memory; something +which it can't do for a normal malloc() call. This can help to use all the available memory in the ESP32. + + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `esp_heap_alloc_caps.h `_ + * `heap_regions.h `_ + + +Macros +^^^^^^ + +.. doxygendefine:: MALLOC_CAP_EXEC +.. doxygendefine:: MALLOC_CAP_32BIT +.. doxygendefine:: MALLOC_CAP_8BIT +.. doxygendefine:: MALLOC_CAP_DMA +.. doxygendefine:: MALLOC_CAP_PID2 +.. doxygendefine:: MALLOC_CAP_PID3 +.. doxygendefine:: MALLOC_CAP_PID4 +.. doxygendefine:: MALLOC_CAP_PID5 +.. doxygendefine:: MALLOC_CAP_PID6 +.. doxygendefine:: MALLOC_CAP_PID7 +.. doxygendefine:: MALLOC_CAP_SPISRAM +.. doxygendefine:: MALLOC_CAP_INVALID + +Type Definitions +^^^^^^^^^^^^^^^^ + +.. doxygentypedef:: HeapRegionTagged_t + + +Functions +^^^^^^^^^ + +.. doxygenfunction:: heap_alloc_caps_init +.. doxygenfunction:: pvPortMallocCaps +.. doxygenfunction:: xPortGetFreeHeapSizeCaps +.. doxygenfunction:: xPortGetMinimumEverFreeHeapSizeCaps +.. doxygenfunction:: vPortDefineHeapRegionsTagged +.. doxygenfunction:: pvPortMallocTagged +.. doxygenfunction:: vPortFreeTagged +.. doxygenfunction:: xPortGetMinimumEverFreeHeapSizeTagged +.. doxygenfunction:: xPortGetFreeHeapSizeTagged diff --git a/docs/api/nvs_flash.rst b/docs/api/nvs_flash.rst index a765f7608e..e2ac34ada8 100644 --- a/docs/api/nvs_flash.rst +++ b/docs/api/nvs_flash.rst @@ -87,5 +87,4 @@ Functions .. doxygenfunction:: nvs_commit .. doxygenfunction:: nvs_close .. doxygenfunction:: nvs_flash_init -.. doxygenfunction:: nvs_flash_init_custom diff --git a/docs/api/pcnt.rst b/docs/api/pcnt.rst index 848fa55267..7fe73e6f47 100644 --- a/docs/api/pcnt.rst +++ b/docs/api/pcnt.rst @@ -1,5 +1,5 @@ Pulse Counter -======== +============= Overview -------- @@ -9,7 +9,7 @@ The PCNT (Pulse Counter) module is designed to count the number of rising and/or Application Example ------------------- -Pulse counter with control signal and event interrupt example: `examples/12_pcnt `_. +Pulse counter with control signal and event interrupt example: `examples/16_pcnt `_. API Reference ------------- diff --git a/docs/api/sigmadelta.rst b/docs/api/sigmadelta.rst new file mode 100644 index 0000000000..acfdaaa27d --- /dev/null +++ b/docs/api/sigmadelta.rst @@ -0,0 +1,51 @@ +Sigma-delta Modulation +======== + +Overview +-------- + +ESP32 has a second-order sigma-delta modulation module. +This driver configures the channels of the sigma-delta module. + +Application Example +------------------- + +Sigma-delta Modulation example: `examples/14_sigmadelta `_. + +API Reference +------------- + +Header Files +^^^^^^^^^^^^ + + * `driver/sigmadelta.h `_ + + +Macros +^^^^^^ + + +Type Definitions +^^^^^^^^^^^^^^^^ + + +Enumerations +^^^^^^^^^^^^ + +.. doxygenenum:: sigmadelta_channel_t + +Structures +^^^^^^^^^^ + +.. doxygenstruct:: sigmadelta_config_t + :members: + + +Functions +^^^^^^^^^ + +.. doxygenfunction:: sigmadelta_config +.. doxygenfunction:: sigmadelta_set_duty +.. doxygenfunction:: sigmadelta_set_prescale +.. doxygenfunction:: sigmadelta_set_pin + diff --git a/docs/api/uart.rst b/docs/api/uart.rst index 609816fd46..fa83309e2a 100644 --- a/docs/api/uart.rst +++ b/docs/api/uart.rst @@ -94,5 +94,7 @@ Functions .. doxygenfunction:: uart_write_bytes_with_break .. doxygenfunction:: uart_read_bytes .. doxygenfunction:: uart_flush - +.. doxygenfunction:: uart_get_buffered_data_len +.. doxygenfunction:: uart_disable_pattern_det_intr +.. doxygenfunction:: uart_enable_pattern_det_intr diff --git a/docs/api/ulp.rst b/docs/api/ulp.rst new file mode 100644 index 0000000000..9db42e633e --- /dev/null +++ b/docs/api/ulp.rst @@ -0,0 +1 @@ +.. include:: ../../components/ulp/README.rst diff --git a/docs/build_system.rst b/docs/build_system.rst index ad263da7af..6687fa69ed 100644 --- a/docs/build_system.rst +++ b/docs/build_system.rst @@ -188,6 +188,10 @@ The following variables can be set inside ``component.mk`` to control build sett are available at all times. It is necessary if one component generates an include file which you then want to include in another component. Most components do not need to set this variable. +- ``COMPONENT_ADD_LINKER_DEPS``: Optional list of component-relative paths + to files which should trigger a re-link of the ELF file if they change. + Typically used for linker script files and binary libraries. Most components do + not need to set this variable. The following variable only works for components that are part of esp-idf itself: @@ -244,7 +248,12 @@ The following variables can be set inside ``component.mk`` to control the build settings. Component-specific additions can be made via ``CXXFLAGS +=``. It is also possible (although not recommended) to override this variable completely for a component. -- ``FLAGS_basename`` allows you to set compilation flags to apply to a single source file only. For example, this can useful for disabling warnings in a single upstream source file. The ``basename`` portion is the directory (relative to ``COMPONENT_PATH``) and the base filename (without extension) of the source file. For example, if a file inside ``COMPONENT_PATH`` is ``library/alpha/widget.c`` then you can set variable ``FLAGS_library/alpha/widget := -DTEST`` to pass the TEST macro when compiling this source file only. + +To apply compilation flags to a single source file, you can add a variable override as a target, ie:: + + apps/dhcpserver.o: CFLAGS += -Wno-unused-variable + +This can be useful if there is upstream code that emits warnings. Component Configuration ----------------------- diff --git a/docs/index.rst b/docs/index.rst old mode 100755 new mode 100644 index be6a372b4b..ba25b49691 --- a/docs/index.rst +++ b/docs/index.rst @@ -35,7 +35,9 @@ Contents: partition-tables build_system openocd + Flash encryption Secure Boot + ULP coprocessor .. API Reference .. @@ -47,7 +49,8 @@ Contents: 1.3. Flash encryption and secure boot: how they work and APIs 1.4. Lower Power Coprocessor - TBA 1.5. Watchdogs - 1.6. ... + 1.6. Memory allocation + 1.7. ... 2. Memory - TBA 2.1. Memory layout of the application (IRAM/IROM, limitations of each) - TBA 2.2. Flash layout and partitions - TBA @@ -95,6 +98,7 @@ Contents: :maxdepth: 1 Wi-Fi + Smart Config Bluetooth Watchdogs OTA @@ -104,11 +108,15 @@ Contents: Remote Control Timer Pulse Counter + Sigma-delta Modulation SPI Flash and Partition APIs Logging Non-Volatile Storage Virtual Filesystem Ethernet + Interrupt Allocation + Memory Allocation + Deep Sleep deep-sleep-stub Template diff --git a/docs/partition-tables.rst b/docs/partition-tables.rst index c9709029d8..d45a540c66 100644 --- a/docs/partition-tables.rst +++ b/docs/partition-tables.rst @@ -4,7 +4,7 @@ Partition Tables Overview -------- -A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash. +A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x8000 in the flash. Partition table length is 0xC00 bytes (maximum 95 partition table entries). If the partition table is signed due to `secure boot`, the signature is appended after the table data. @@ -125,5 +125,6 @@ Flashing the partition table A manual flashing command is also printed as part of ``make partition_table``. +Note that updating the partition table doesn't erase data that may have been stored according to the old partition table. You can use ``make erase_flash`` (or ``esptool.py erase_flash``) to erase the entire flash contents. .. _secure boot: security/secure-boot.rst diff --git a/docs/security/flash-encryption.rst b/docs/security/flash-encryption.rst new file mode 100644 index 0000000000..b73d8a9ad3 --- /dev/null +++ b/docs/security/flash-encryption.rst @@ -0,0 +1,321 @@ +Flash Encryption +================ + +Flash Encryption is a feature for encrypting the contents of the ESP32's attached SPI flash. When flash encryption is enabled, physical readout of the SPI flash is not sufficient to recover most flash contents. + +Flash Encryption is separate from the `Secure Boot` feature, and you can use flash encryption without enabling secure boot. However we recommend using both features together for a secure environment. + +**IMPORTANT: Enabling flash encryption limits your options for further updates of your ESP32. Make sure to read this document (including `Limitations of Flash Encryption` and understand the implications of enabling flash encryption.** + +**IMPORTANT: Flash Encryption feature is currently enabled for development use only, with a key generated on the host. The recommended production configuration, where the flash encryption key is generated by the device on first boot, is currently disabled while final testing is done. This documentation refers to flash encryption keys being generated on first boot, however for now it is necessary to follow the additional steps shown under `Precalculated Flash Encryption Key`.** + + +Background +---------- + +- The contents of the flash are encrypted using AES with a 256 bit key. The flash encryption key is stored in efuse internal to the chip, and is (by default) protected from software access. + +- Flash access is transparent via the flash cache mapping feature of ESP32 - any flash regions which are mapped to the address space will be transparently decrypted when read. + +- Encryption is applied by flashing the ESP32 with plaintext data, and (if encryption is enabled) the bootloader encrypts the data in place on first boot. + +- Not all of the flash is encrypted. The following kinds of flash data are encrypted: + - Bootloader + - Secure boot bootloader digest (if secure boot is enabled) + - Partition Table + - All "app" type partitions + - Any partition marked with the "encrypt" flag in the partition table + + It may be desirable for some data partitions to remain unencrypted for ease of access, or to use flash-friendly update algorithms that are ineffective if the data is encrypted. "NVS" partitions for non-volatile storage cannot be encrypted. + +- The flash encryption key is stored in efuse key block 1, internal to the ESP32 chip. By default, this key is read- and write-protected so software cannot access it or change it. + +- The `flash encryption algorithm` is AES-256, where the key is "tweaked" with the offset address of each 32 byte block of flash. This means every 32 byte block (two consecutive 16 byte AES blocks) is encrypted with a unique key derived from the flash encryption key. + +- Although software running on the chip can transparently decrypt flash contents, by default it is made possible for the UART bootloader to decrypt (or encrypt) data when flash encryption is enabled. + +Flash Encryption Initialisation +------------------------------- + +This is the default (and recommended) flash encryption initialisation process. It is possible to customise this process for development or other purposes, see `Flash Encryption Advanced Features` for details. + +**IMPORTANT: Once flash encryption is enabled on first boot, the hardware allows a maximum of 3 subsequent flash updates via physical re-flashing. If secure boot is enabled, no physical re-flashes are possible. OTA updates can be used to update flash content without counting towards this limit. When enabling flash encryption in development, use a `precalculated flash encryption key` to allow physically re-flashing an unlimited number of times with pre-encrypted data.** + +- The bootloader must be compiled with flash encryption support enabled. In ``make menuconfig``, navigate to "Security Features" and select "Yes" for "Enable flash nencryption on boot". + +- If enabling Secure Boot at the same time, you can simultaneously select those options now. See the `Secure Boot` documentation for details. + +- Build and flash the bootloader, partition table and factory app image as normal. These partitions are initially written to the flash unencrypted. + +- On first boot, the bootloader sees ``FLASH_CRYPT_CNT`` efuse is set to 0 so it generates a flash encryption key using the hardware random number generator. This key is stored in efuse. The key is read and write protected against further software access. + +- All of the encrypted partitions are then encrypted in-place by the bootloader. Encrypting in-place can take some time (up to a minute for large partitions.) + +**IMPORTANT: Do not interrupt power to the ESP32 while the first boot encryption pass is running. If power is interrupted, the flash contents will be corrupted and require flashing with unencrypted data again. This re-flash will not count towards the flashing limit, as ``FLASH_CRYPT_CNT`` is only updated after this process finishes.** + +- Once flashing is complete. efuses are blown (by default) to disable encrypted flash access while the UART bootloader is running. + +- If not already write-protected, the ``FLASH_CRYPT_CONFIG`` efuse is also burned to the maximum value (``0xF``) to maximise the number of key bits which are tweaked in the flash algorithm. See `Setting FLASH_CRYPT_CONFIG` for details of this efuse. + +- Finally, the ``FLASH_CRYPT_CNT`` efuse is burned with the initial value 1. It is this efuse which activates the transparent flash encryption layer, and limits the number of subsequent reflashes. See the `Updating Encrypted Flash` section for details about ``FLASH_CRYPT_CNT``. + +- The bootloader resets itself to reboot from the newly encrypted flash. + + +Encrypted Flash Access +---------------------- + +Reading Encrypted Flash +^^^^^^^^^^^^^^^^^^^^^^^ + +Whenever the ``FLASH_CRYPT_CNT`` efuse is set to a value with an odd number of bits set, all flash content which is accessed via the MMU's flash cache is transparently decrypted. This includes: + +- Executable application code in flash (IROM). +- All read-only data stored in flash (DROM). +- Any data accessed via ``esp_spi_flash_mmap``. +- The software bootloader image when it is read by the ROM bootloader. + +**IMPORTANT: The MMU flash cache unconditionally decrypts all data. Data which is stored unencrypted in the flash will be "transparently decrypted" via the flash cache and appear to software like random garbage.** + +To read data without using a flash cache MMU mapping, we recommend using the partition read function ``esp_partition_read``. When using this function, data will only be decrypted when it is read from an encrypted partition. Other partitions will be read unencrypted. In this way, software can access encrypted and non-encrypted flash in the same way. + +Data which is read via other SPI read APIs are not decrypted: + +- Data read via ``esp_spi_flash_read`` is not decrypted +- Data read via ROM function ``SPIRead`` is not decrypted (this function is not supported in esp-idf apps). +- Data stored using the Non-Volatile Storage (NVS) API is always stored decrypted. + + +Writing Encrypted Flash +^^^^^^^^^^^^^^^^^^^^^^^ + +Where possible, we recommend using the partition write function ``esp_partition_write``. When using this function, data will only be encrypted when writing to encrypted partitions. Data will be written to other partitions unencrypted. In this way, software can access encrypted and non-encrypted flash in the same way. + +The ``esp_spi_flash_write`` function will write data when the write_encrypted parameter is set to true. Otherwise, data will be written unencrypted. + +The ROM function ``SPI_Encrypt_Write`` will write encrypted data to flash, the ROM function ``SPIWrite`` will write unencrypted to flash. (these function are not supported in esp-idf apps). + +The minimum write size for unencrypted data is 4 bytes (and the alignment is 4 bytes). Because data is encrypted in blocks, the minimum write size for encrypted data is 32 bytes (and the alignment is 32 bytes.) + +Updating Encrypted Flash +------------------------ + +OTA Updates +^^^^^^^^^^^ + +OTA updates to encrypted partitions will automatically write encrypted, as long as the ``esp_partition_write`` function is used. + +Serial Flashing +^^^^^^^^^^^^^^^ + +Provided secure boot is not used, the ``FLASH_CRYPT_CNT`` registers allow the flash to be updated with new plaintext data via serial flashing (or other physical methods), up to 3 additional times. ``FLASH_CRYPT_CNT`` efuse is an 8-bit value, and the flash encryption enables or disables based on the number of bits which are set to "1": + +- Even number (0-6) bits are set: Transparent reading of encrypted flash is disabled, any encrypted data cannot be decrypted. If the bootloader was built with "Enable flash encryption on boot" then it will see this situation and immediately re-encrypt the flash wherever it finds unencrypted data. Once done, it sets another bit in the efuse to '1' meaning an odd number of bits are now set. + +- Odd number (1-7) bits are set: Transparent reading of encrypted flash is enabled. + +- All 8 bits are set (valuye 0: Transparent reading of encrypted flash is disabled, any encrypted data is inaccessible. Bootloader will normally detect this condition and halt. To avoid use of this state to load unauthorised code, secure boot must be used or ``FLASH_CRYPT_CNT`` must be write-protected. + +The espefuse.py tool can be used to manually change the number of bits set in ``FLASH_CRYPT_CNT``, via serial bootloader. + +Limited Updates +^^^^^^^^^^^^^^^ + +Only 4 physical flash updates (writing plaintext data which is then encrypted) are possible: + +1. On first plaintext boot, bit count has brand new value 0 and bootloader changes to 1 (0x01) following encryption. +2. On next plaintext flash update, bit count is manually updated to 2 (0x03) and bootloader changes to 4 (0x07) following encryption. +3. Then bit count is manually updated to 4 (0x0F) and the bootloader changes efuse bit count to 5 (0x1F). +4. Finally bootloader is manually updated to 6 (0x3F) and bootloader changes efuse bit count to 7 (0x7F). + +Cautions With Re-Flashing +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- When reflashing via serial, reflash every partition that was previously written with plaintext (including bootloader). It is possible to skip app partitions which are not the "currently selected" OTA partition (these will not be re-encrypted unless a plaintext app image is found there.) However any partition marked with the "encrypt" flag will be unconditionally re-encrypted, meaning that any already encrypted data will be encrypted twice and corrupted. + +- If secure boot is enabled, you can't reflash via serial at all unless you used chosen the "Reflashable" option for Secure Boot, pre-generated a key and burned it to the ESP32. In this case you can re-flash a plaintext secure boot digest and bootloader image at offset 0 (see `Secure Boot` documentation.) In production secure boot configuration, the secure boot digest is stored encrypted - so if ``FLASH_CRYPT_CNT`` is set to an even value then the ROM bootloader will read the encrypted digest as-is and therefore will fail to verify any bootloader image as valid. + +Re-Flashing Procedure +^^^^^^^^^^^^^^^^^^^^^ + +The steps to update a device with plaintext via UART bootloader, when flash encryption is enabled are: + +- Build the application as usual. + +- Burn the ``FLASH_CRYPT_CNT`` efuse by running the command ``espefuse.py burn_efuse FLASH_CRYPT_CNT``. espefuse.py will automatically increment the bit count by 1. + +- Flash the device with plaintext data as usual (``make flash`` or ``esptool.py`` commands.) Flash all previously encrypted partitions, including the bootloader. If secure boot is enabled, it must be enabled in "Reflashable" mode and a pre-generated key burned to the ESP32 - flash the bootloader-reflash-digest.bin file at offset 0x0. + +- Reset the device and it will re-encrypt plaintext partitions, burn the ``FLASH_CRYPT_CNT`` flag to re-enable encryption. + + +Disabling Updates +^^^^^^^^^^^^^^^^^ + +To prevent further plaintext updates via physical access, use espefuse.py to write protect the ``FLASH_CRYPT_CNT`` efuse after flash encryption has been enabled (ie after first boot is complete):: + + espefuse.py write_protect_efuse FLASH_CRYPT_CNT + +This prevents any further modifications to disable or re-enable flash encryption. + +Limitations of Flash Encryption +------------------------------- + +Flash Encryption prevents plaintext readout of the encrypted flash, to protect firmware against unauthorised readout and modification. It is important to understand the limitations of the flash encryption system: + +- Flash encryption is only as strong as the key. For this reason, we recommend keys are generated on the device during first boot (default behaviour). If generating keys off-device to burn with ``esp_efuse.py burn_key``, ensure they are generated from a quality random number source, kept secure, and never shared between devices. + +- Not all data is stored encrypted. If storing data on flash, check if the method you are using (library, API, etc.) supports flash encryption. + +- Flash encryption does not prevent an attacker from understanding the high-level layout of the flash. This is because the same AES key is used for every two 16 byte AES blocks. When both adjacent 16 byte blocks contain identical content (such as empty or padding areas), these blocks will encrypt to produce matching pairs of encrypted blocks. This may allow an attacker to make high-level comparisons between encrypted devices (ie to tell if two devices are probably running the same firmware version). + +- For the same reason, an attacker can always guess when two adjacent 16 byte blocks (32 byte aligned) contain identical content. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). + +- Flash encryption alone may not prevent an attacker from modifying the firmware of the device. Always use flash encryption in combination with Secure Boot. + + +Flash Encryption Advanced Features +---------------------------------- + +Encrypted Partition Flag +^^^^^^^^^^^^^^^^^^^^^^^^ + +In the `partition table` description CSV files, there is a field for flags. + +Usually left blank, if you write "encrypted" in this field then the partition will be marked as encrypted in the partition table, and data written here will be treated as encrypted (same as an app partition):: + + # Name, Type, SubType, Offset, Size, Flags + nvs, data, nvs, 0x9000, 0x6000 + phy_init, data, phy, 0xf000, 0x1000 + factory, app, factory, 0x10000, 1M + secret_data, 0x40, 0x01, 0x20000, 256K, encrypted + +- None of the default partition formats have any encrypted data partitions. + +- It is not necessary to mark "app" partitions as encrypted, they are always treated as encrypted. + +- The "encrypted" flag does nothing if flash encryption is not enabled. + +- It is possible to mark the optional ``phy`` partition with ``phy_init`` data as encrypted, if you wish to protect this data from physical access readout or modification. + +- It is not possible to mark the ``nvs`` partition as encrypted. + +Precalculated Flash Encryption Key +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +It is possible to pre-generate a flash encryption key on the host computer and burn it into the ESP32 efuse. This allows data to be per-encrypted on the host and flashed to the ESP32 without needing a plaintext flash update. + +This is useful for development, because it removes the 4 flash limit and allows reflashing with secure boot enabled. + +**IMPORTANT** This method is intended to assist with development only, not for production devices. If pre-generating flash encryption for production, ensure the keys are generated from a high quality random number source and do not share the same flash encryption key across multiple devices. + +Obtaining Flash Encryption Key +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Flash encryption keys are 32 bytes of random data. You can generate a random key with espsecure.py:: + + espsecure.py generate_flash_encryption_key my_flash_encryption_key.bin + +(The randomness of this data is only as good as the OS and it's Python installation's random data source.) + +Alternatively, if you're using `secure boot` and have a secure boot signing key then you can generate a deterministic SHA-256 digest of the secure boot private key to use:: + + espsecure.py digest_private-key --keyfile secure_boot_signing_key.pem my_flash_encryption_key.bin + +The same key is used as the secure boot digest key if you enabled "Reflashable" mode for secure boot. + +This means you can always re-calculate the flash encryption key from the secure boot private signing key. This method is **not at all suitable** for production devices. + +Burning Flash Encryption Key +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you have generated a flash encryption key, you need to burn it to efuse on the device. This **must be done before first boot**, otherwise the ESP32 will generate a random key that software can't access. + +To burn a key to the device (possible one time only):: + + espefuse.py burn_key flash_encryption my_flash_encryption_key.bin + +First Flash +~~~~~~~~~~~ + +For the first flash, follow the same steps as for default `Flash Encryption Initialisation` and flash a plaintext image. The bootloader will enable flash encryption using the pre-burned key and encrypt all partitions. + +Reflashing +~~~~~~~~~~ + +To reflash an encrypted image requires an additional manual update step, to encrypt the data you wish to flash. + +Suppose that this is the normal flashing non-encrypted flashing step:: + + esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x10000 build/my-app.bin + +The data needs to be pre-encrypted with knowledge of the address (0x10000) and the binary file name:: + + espsecure.py encrypt_flash_data --keyfile my_flash_encryption_key.bin --address 0x10000 -o build/my-app-encrypted.bin build/my-app.bin + +This step will encrypt ``my-app.bin`` using the supplied key, and produce an encrypted file ``my-app-encrypted.bin``. Be sure that the address argument matches the address where you plan to flash the binary. + +Then, flash the encrypted binary with esptool.py:: + + esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash -z 0x10000 build/my-app-encrypted.bin + +Enabling UART Bootloader Encryption/Decryption +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, on first boot the flash encryption process will burn efuses ``DISABLE_DL_ENCRYPT``, ``DISABLE_DL_DECRYPT`` and ``DISABLE_DL_CACHE``. + +- ``DISABLE_DL_ENCRYPT`` disables the flash encryption operations when running in UART bootloader boot mode. +- ``DISABLE_DL_DECRYPT`` disables transparent flash decryption when running in UART bootloader mode, even if ``FLASH_CRYPT_CNT`` is set to enable it in normal operation. +- ``DISABLE_DL_CACHE`` disables the entire MMU flash cache when running in UART bootloader mode. + +It is possible to burn only some of these efuses, and write-protect the rest (with unset value 0) before the first boot, in order to preserve them:: + + espefuse.py burn_efuse DISABLE_DL_DECRYPT + espefuse.py write_protect_efuse DISABLE_DL_ENCRYPT + +(Note that all 3 of these efuses are disabled via one write protect bit, so write protecting one will write protect all of them.) + +Write protecting these efuses when they are unset (0) is not currently useful, as ``esptool.py`` does not support flash encryption functions. + +However, note that write protecting ``DISABLE_DL_DECRYPT`` when it is unset (0) effectively makes flash encryption useless, as an attacker with physical access can use UART bootloader mode to read out the flash. + +Technical Details +----------------- + +Flash Encryption Algorithm +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- AES-256 operates on 16 byte blocks of data. The flash encryption engine encrypts and decrypts data in 32 byte blocks, two AES blocks in series. + +- AES algorithm is used inverted in flash encryption, so the flash encryption "encrypt" operation is AES decrypt and the "decrypt" operation is AES encrypt. This is for performance reasons and does not alter the effectiveness of the algorithm. + +- The main flash encryption key is stored in efuse (BLK2) and by default is protected from further writes or software readout. + +- Each 32 byte block is encrypted with a unique key which is derived from this main flash encryption key XORed with the offset of this block in the flash (a "key tweak"). + +- The specific tweak depends on the setting of ``FLASH_CRYPT_CONFIG`` efuse. This is a 4 bit efuse, where each bit enables XORing of a particular range of the key bits: + - Bit 1, bits 0-66 of the key are XORed. + - Bit 2, bits 67-131 of the key are XORed. + - Bit 3, bits 132-194 of the key are XORed. + - Bit 4, bits 195-256 of the key are XORed. +It is recommended that ``FLASH_CRYPT_CONFIG`` is always left to set the default value `0xF`, so that all key bits are XORed with the block offset. See `Setting FLASH_CRYPT_CONFIG` for details. + +- The high 19 bits of the block offset (bit 5 to bit 23) are XORed with the main flash encryption key. This range is chosen for two reasons: the maximum flash size is 16MB (24 bits), and each block is 32 bytes so the least significant 5 bits are always zero. + +- There is a particular mapping from each of the 19 block offset bits to the 256 bits of the flash encryption key, to determine which bit is XORed with which. See the variable _FLASH_ENCRYPTION_TWEAK_PATTERN in espsecure.py for a list of these. + +- For the full algorithm implemented in Python, see `_flash_encryption_operation()` in the espsecure.py source code. + +Setting FLASH_CRYPT_CONFIG +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``FLASH_CRYPT_CONFIG`` efuse determines the number of bits in the flash encryption key which are "tweaked" with the block offset. See `Flash Encryption Algorithm` for details. + +First boot of the bootloader always sets this value to the maximum `0xF`. + +It is possible to write these efuse manually, and write protect it before first boot in order to select different tweak values. This is not recommended. + +It is strongly recommended to never write protect ``FLASH_CRYPT_CONFIG`` when it the value is zero. If this efuse is set to zero, no bits in the flash encryption key are tweaked and the flash encryption algorithm is equivalent to AES ECB mode. + +.. _Secure Boot: secure-boot.rst +.. _partition table: ../partition-tables.rst diff --git a/docs/security/secure-boot.rst b/docs/security/secure-boot.rst index 113d250902..7aaf9abf81 100644 --- a/docs/security/secure-boot.rst +++ b/docs/security/secure-boot.rst @@ -3,9 +3,9 @@ Secure Boot Secure Boot is a feature for ensuring only your code can run on the chip. Data loaded from flash is verified on each reset. -Secure Boot is separate from the Encrypted Flash feature, and you can use secure boot without encrypting the flash contents. However we recommend using both features together for a secure environment. +Secure Boot is separate from the `Flash Encryption` feature, and you can use secure boot without encrypting the flash contents. However we recommend using both features together for a secure environment. -**IMPORTANT: As Encrypted Flash feature and related security features are not yet released, Secure Boot should not be considered sufficient for a secure device and we strongly recommend not enabling the one-time secure bootloader feature until it is mature.** +**IMPORTANT: Secure Boot feature is currently enabled for development use only, with a key generated on the host. The recommended production configuration, where the secure boot key is generated by the device on first boot, is currently disabled while final testing is done. This documentation refers to "One-Time Flashable" mode (where keys are generated on the device), but for now only the `Re-Flashable Software Bootloader` mode is available.** Background ---------- @@ -25,7 +25,7 @@ This is a high level overview of the secure boot process. Step by step instructi 1. The options to enable secure boot are provided in the ``make menuconfig`` hierarchy, under "Secure Boot Configuration". -2. Secure Boot Configuration includes "Secure boot signing key", which is a file path. This file is a ECDSA public/private key pair in a PEM format file. +2. Secure Boot defaults to signing images and partition table data during the build process. The "Secure boot private signing key" config item is a file path to a ECDSA public/private key pair in a PEM format file. 3. The software bootloader image is built by esp-idf with secure boot support enabled and the public key (signature verification) portion of the secure boot signing key compiled in. This software bootloader image is flashed at offset 0x1000. @@ -119,6 +119,27 @@ openssl ecparam -name prime256v1 -genkey -noout -out my_secure_boot_signing_key. Remember that the strength of the secure boot system depends on keeping the signing key private. +Remote Signing of Images +------------------------ + +For production builds, it can be good practice to use a remote signing server rather than have the signing key on the build machine (which is the default esp-idf secure boot configuration). The espsecure.py command line program can be used to sign app images & partition table data for secure boot, on a remote system. + +To use remote signing, disable the option "Sign binaries during build". The private signing key does not need to be present on the build system. However, the public (signature verification) key is required because it is compiled into the bootloader (and can be used to verify image signatures during OTA updates. + +To extract the public key from the private key:: + + espsecure.py extract_public_key --keyfile PRIVATE_SIGNING_KEY PUBLIC_VERIFICATION_KEY + +The path to the public signature verification key needs to be specified in the menuconfig under "Secure boot public signature verification key" in order to build the secure bootloader. + +After the app image and partition table are built, the build system will print signing steps using espsecure.py:: + + espsecure.py sign_data --keyfile PRIVATE_SIGNING_KEY BINARY_FILE + +The above command appends the image signature to the existing binary. You can use the --output argument to place the binary with signature appended into a separate file:: + + espsecure.py sign_data --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE + Secure Boot Best Practices -------------------------- @@ -175,5 +196,26 @@ Deterministic ECDSA as specified by `RFC6979`. - In the bootloader, the public key (for signature verification) is flashed as 64 raw bytes. - Image signature is 68 bytes - a 4 byte version word (currently zero), followed by a 64 bytes of signature data. These 68 bytes are appended to an app image or partition table data. +Manual Commands +~~~~~~~~~~~~~~~ + +Secure boot is integrated into the esp-idf build system, so `make` will automatically sign an app image if secure boot is enabled. `make bootloader` will produce a bootloader digest if menuconfig is configured for it. + +However, it is possible to use the `espsecure.py` tool to make standalone signatures and digests. + +To sign a binary image:: + + espsecure.py sign_data --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin + +Keyfile is the PEM file containing an ECDSA private signing key. + +To generate a bootloader digest:: + + espsecure.py digest_secure_bootloader --keyfile ./securebootkey.bin --output ./bootloader-digest.bin build/bootloader/bootloader.bin + +Keyfile is the 32 byte raw secure boot key for the device. To flash this digest onto the device:: + + esptool.py write_flash 0x0 bootloader-digest.bin .. _RFC6979: https://tools.ietf.org/html/rfc6979 +.. _Flash Encryption: flash-encryption.rst diff --git a/examples/04_https_request/main/https_request_main.c b/examples/04_https_request/main/https_request_main.c index 1d6115d08c..caf3f374a3 100644 --- a/examples/04_https_request/main/https_request_main.c +++ b/examples/04_https_request/main/https_request_main.c @@ -38,6 +38,7 @@ #include "lwip/netdb.h" #include "lwip/dns.h" +#include "mbedtls/platform.h" #include "mbedtls/net.h" #include "mbedtls/debug.h" #include "mbedtls/ssl.h" diff --git a/examples/06_sntp/main/sntp_main.c b/examples/06_sntp/main/sntp_main.c index c3edb9e2bd..f128323dcb 100644 --- a/examples/06_sntp/main/sntp_main.c +++ b/examples/06_sntp/main/sntp_main.c @@ -17,7 +17,7 @@ #include "esp_event_loop.h" #include "esp_log.h" #include "esp_attr.h" -#include "esp_deepsleep.h" +#include "esp_deep_sleep.h" #include "nvs_flash.h" #include "lwip/err.h" diff --git a/examples/09_a2dp/components/bluedroid_demos/app_project/SampleA2dp.c b/examples/09_a2dp/components/bluedroid_demos/app_project/SampleA2dp.c index 3439c1049b..28f231b6a6 100644 --- a/examples/09_a2dp/components/bluedroid_demos/app_project/SampleA2dp.c +++ b/examples/09_a2dp/components/bluedroid_demos/app_project/SampleA2dp.c @@ -7,8 +7,8 @@ #include "freertos/task.h" #include "esp_system.h" -#include "EspAudio.h" -#include "EspAudioCom.h" +// #include "EspAudio.h" +// #include "EspAudioCom.h" #include "bt_app_common.h" #include "esp_bt_stack_manager.h" @@ -45,7 +45,8 @@ static void bt_app_a2d_cb(uint32_t event, void *param) static void bt_app_a2d_data_cb(uint8_t *data, uint32_t len) { - EspAudioPlayerStreamWrite(data, len, 10); + // EspAudioPlayerStreamWrite(data, len, 10); + return; } static void bt_app_handle_evt(UINT16 event, void *p_param) @@ -81,9 +82,9 @@ static void bt_app_handle_evt(UINT16 event, void *p_param) if (a2d->audio_cfg.mcc.type == ESP_A2D_MCT_SBC) { // temporarily hardcoded the PCM configuaration BT_APP_TRACE_ERROR("configure audio player\n"); - EspAudioPlayerStreamCfg(StreamSampleRate_44k, 2, StreamBitLen_16BIT); - EspAudio_SetupStream("stream.pcm", InputSrcType_Stream); - EspAudio_SetVolume(99); + // EspAudioPlayerStreamCfg(StreamSampleRate_44k, 2, StreamBitLen_16BIT); + // EspAudio_SetupStream("stream.pcm", InputSrcType_Stream); + // EspAudio_SetVolume(99); } break; } diff --git a/examples/09_a2dp/main/demo_main.c b/examples/09_a2dp/main/demo_main.c index fae8b983f1..7d7bf118b2 100755 --- a/examples/09_a2dp/main/demo_main.c +++ b/examples/09_a2dp/main/demo_main.c @@ -8,7 +8,7 @@ #include "nvs_flash.h" #include "esp_system.h" -#include "EspAudio.h" +// #include "EspAudio.h" extern void bte_main_boot_entry(void *); extern void bt_app_task_start_up(void); @@ -17,13 +17,9 @@ extern void bt_app_core_start(void); void app_main() { nvs_flash_init(); - system_init(); - #include "psramApi.h" - psram_cache_enable(); - - printf("Free memory: %d bytes\n", system_get_free_heap_size()); - EspAudio_Init(); + // system_init(); + // printf("Free memory: %d bytes\n", system_get_free_heap_size()); + // EspAudio_Init(); bt_controller_init(); bt_app_task_start_up(); - // bte_main_boot_entry(bt_app_core_start); } diff --git a/examples/09_openssl_client/main/Kconfig.projbuild b/examples/09_openssl_client/main/Kconfig.projbuild index 1767923ad1..ff1cb863c7 100644 --- a/examples/09_openssl_client/main/Kconfig.projbuild +++ b/examples/09_openssl_client/main/Kconfig.projbuild @@ -9,7 +9,7 @@ config TARGET_DOMAIN config TARGET_PORT_NUMBER int "Target port number" range 0 65535 - default 433 + default 443 help Target port number for the example to connect to. @@ -25,4 +25,4 @@ config WIFI_PASSWORD help WiFi password (WPA or WPA2) for the example to use. -endmenu \ No newline at end of file +endmenu diff --git a/examples/11_rmt_nec_tx_rx/main/infrared_nec.c b/examples/11_rmt_nec_tx_rx/main/infrared_nec.c index dbd11fbae5..d2f7b091fa 100644 --- a/examples/11_rmt_nec_tx_rx/main/infrared_nec.c +++ b/examples/11_rmt_nec_tx_rx/main/infrared_nec.c @@ -43,7 +43,6 @@ static const char* NEC_TAG = "NEC"; #define RMT_TX_GPIO_NUM 16 /*!< GPIO number for transmitter signal */ #define RMT_RX_CHANNEL 0 /*!< RMT channel for receiver */ #define RMT_RX_GPIO_NUM 19 /*!< GPIO number for receiver */ -#define RMT_INTR_NUM 19 /*!< RMT interrupt number, select from soc.h */ #define RMT_CLK_DIV 100 /*!< RMT counter clock divider */ #define RMT_TICK_10_US (80000000/RMT_CLK_DIV/100000) /*!< RMT counter value for 10 us.(Source clock is APB clock) */ @@ -254,7 +253,7 @@ static void rmt_tx_init() rmt_tx.tx_config.idle_output_en = true; rmt_tx.rmt_mode = 0; rmt_config(&rmt_tx); - rmt_driver_install(rmt_tx.channel, 0, RMT_INTR_NUM); + rmt_driver_install(rmt_tx.channel, 0, 0); } /* @@ -272,7 +271,7 @@ void rmt_rx_init() rmt_rx.rx_config.filter_ticks_thresh = 100; rmt_rx.rx_config.idle_threshold = rmt_item32_tIMEOUT_US / 10 * (RMT_TICK_10_US); rmt_config(&rmt_rx); - rmt_driver_install(rmt_rx.channel, 1000, RMT_INTR_NUM); + rmt_driver_install(rmt_rx.channel, 1000, 0); } /** diff --git a/examples/12_blufi/components/blufi/blufi.c b/examples/12_blufi/components/blufi/blufi.c index 34d3857f15..5a1c543b50 100644 --- a/examples/12_blufi/components/blufi/blufi.c +++ b/examples/12_blufi/components/blufi/blufi.c @@ -51,17 +51,17 @@ static void blufi_data_recv(uint8_t *data, int len) char *p = NULL; LOG_DEBUG("the data is:%s\n", data); - p = strstr(data, HEADER_SSID); + p = strstr((char *)data, HEADER_SSID); if (p) { LOG_ERROR("SSID: %s\n", p + strlen(HEADER_SSID) + 1); strcpy(tmp_ssid, p + strlen(HEADER_SSID) + 1); } - p = strstr(data, HEADER_PASSWD); + p = strstr((char *)data, HEADER_PASSWD); if (p) { LOG_ERROR("PASSWORD: %s\n", p + strlen(HEADER_PASSWD) + 1); strcpy(tmp_passwd, p + strlen(HEADER_PASSWD) + 1); } - p = strstr(data, HEADER_CONFIRM); + p = strstr((char *)data, HEADER_CONFIRM); if (p) { LOG_ERROR("CONFIRM\n"); wifi_set_blue_config(tmp_ssid, tmp_passwd); diff --git a/examples/13_timer_group/main/timer_group.c b/examples/13_timer_group/main/timer_group.c index 15d1ca2c05..37e22faafc 100644 --- a/examples/13_timer_group/main/timer_group.c +++ b/examples/13_timer_group/main/timer_group.c @@ -16,8 +16,6 @@ #include "driver/periph_ctrl.h" #include "driver/timer.h" -#define TIMER_INTR_NUM_0 17 /*!< Interrupt number for hardware timer 0 */ -#define TIMER_INTR_NUM_1 18 /*!< Interrupt number for hardware timer 1*/ #define TIMER_INTR_SEL TIMER_INTR_LEVEL /*!< Timer level interrupt */ #define TIMER_GROUP TIMER_GROUP_0 /*!< Test on timer group 0 */ #define TIMER_DIVIDER 16 /*!< Hardware timer clock divider */ @@ -85,10 +83,12 @@ void IRAM_ATTR timer_group0_isr(void *para) uint32_t intr_status = TIMERG0.int_st_timers.val; timer_event_t evt; if((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) { - /*Timer0 is an example that don't reload counter value*/ + /*Timer0 is an example that doesn't reload counter value*/ TIMERG0.hw_timer[timer_idx].update = 1; - /*We don't call a API here because they are not declared with IRAM_ATTR*/ + /* We don't call a API here because they are not declared with IRAM_ATTR. + If we're okay with the timer irq not being serviced while SPI flash cache is disabled, + we can alloc this interrupt without the ESP_INTR_FLAG_IRAM flag and use the normal API. */ TIMERG0.int_clr_timers.t0 = 1; uint64_t timer_val = ((uint64_t) TIMERG0.hw_timer[timer_idx].cnt_high) << 32 | TIMERG0.hw_timer[timer_idx].cnt_low; @@ -157,7 +157,7 @@ void tg0_timer0_init() /*Enable timer interrupt*/ timer_enable_intr(timer_group, timer_idx); /*Set ISR handler*/ - timer_isr_register(timer_group, timer_idx, TIMER_INTR_NUM_0, TIMER_INTR_SEL, timer_group0_isr, (void*) timer_idx); + timer_isr_register(timer_group, timer_idx, timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL); /*Start timer counter*/ timer_start(timer_group, timer_idx); } @@ -187,7 +187,7 @@ void tg0_timer1_init() /*Enable timer interrupt*/ timer_enable_intr(timer_group, timer_idx); /*Set ISR handler*/ - timer_isr_register(timer_group, timer_idx, TIMER_INTR_NUM_1, TIMER_INTR_SEL, timer_group0_isr, (void*) timer_idx); + timer_isr_register(timer_group, timer_idx, timer_group0_isr, (void*) timer_idx, ESP_INTR_FLAG_IRAM, NULL); /*Start timer counter*/ timer_start(timer_group, timer_idx); } @@ -197,9 +197,9 @@ void tg0_timer1_init() */ void app_main() { + timer_queue = xQueueCreate(10, sizeof(timer_event_t)); tg0_timer0_init(); tg0_timer1_init(); - timer_queue = xQueueCreate(10, sizeof(timer_event_t)); - xTaskCreate(timer_evt_task, "timer_evt_task", 1024, NULL, 5, NULL); + xTaskCreate(timer_evt_task, "timer_evt_task", 2048, NULL, 5, NULL); } diff --git a/examples/14_ethernet/main/tlk110_phy.h b/examples/14_ethernet/main/tlk110_phy.h new file mode 100644 index 0000000000..5f2ca644dc --- /dev/null +++ b/examples/14_ethernet/main/tlk110_phy.h @@ -0,0 +1,28 @@ +#define BASIC_MODE_STATUS_REG (0x1) +#define AUTO_NEGOTIATION_COMPLETE BIT(5) +#define LINK_STATUS BIT(2) + +#define PHY_IDENTIFIER_REG (0x2) +#define OUI_MSB_21TO6_DEF 0x2000 + +#define SOFTWARE_STAP_CONTROL_REG (0x9) +#define SW_STRAP_CONFIG_DONE BIT(15) +#define AUTO_MDIX_ENABLE BIT(14) +#define AUTO_NEGOTIATION_ENABLE BIT(13) +#define AN_1 BIT(12) +#define AN_0 BIT(11) +#define LED_CFG BIT(10) +#define RMII_ENHANCED_MODE BIT(9) + +#define PHY_STATUS_REG (0x10) +#define AUTO_NEGTIATION_STATUS BIT(4) +#define DUPLEX_STATUS BIT(2) +#define SPEED_STATUS BIT(1) + +#define CABLE_DIAGNOSTIC_CONTROL_REG (0x1e) +#define DIAGNOSTIC_DONE BIT(1) + +#define PHY_RESET_CONTROL_REG (0x1f) +#define SOFTWARE_RESET BIT(15) + + diff --git a/examples/14_gatt_server/main/component.mk b/examples/14_gatt_server/main/component.mk index 24356f23ed..79edf031d3 100644 --- a/examples/14_gatt_server/main/component.mk +++ b/examples/14_gatt_server/main/component.mk @@ -6,5 +6,3 @@ # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, # please read the ESP-IDF documents if you need to do this. # - -include $(IDF_PATH)/make/component_common.mk diff --git a/examples/14_gatt_server/main/gatts_demo.c b/examples/14_gatt_server/main/gatts_demo.c index 7ba9447eaa..48576d362f 100644 --- a/examples/14_gatt_server/main/gatts_demo.c +++ b/examples/14_gatt_server/main/gatts_demo.c @@ -38,7 +38,6 @@ #define TEST_DEVICE_NAME "ESP_GATTS_DEMO" #define TEST_MANUFACTURER_DATA_LEN 17 -static uint16_t test_service_uuid = GATTS_SERVICE_UUID_TEST; static uint8_t test_service_uuid128[32] = { /* LSB <--------------------------------------------------------------------------------> MSB */ //first uuid, 16bit, [12],[13] is the value @@ -47,7 +46,7 @@ static uint8_t test_service_uuid128[32] = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xAB, 0xCD, 0xAB, 0xCD, }; -static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56}; +//static uint8_t test_manufacturer[TEST_MANUFACTURER_DATA_LEN] = {0x12, 0x23, 0x45, 0x56}; static esp_ble_adv_data_t test_adv_data = { .set_scan_rsp = false, .include_name = true, @@ -166,7 +165,7 @@ static void gatts_event_handler(uint32_t event, void *param) gl_test.char_handle = p->add_char.attr_handle; gl_test.descr_uuid.len = ESP_UUID_LEN_16; - gl_test.descr_uuid.uuid.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG; + gl_test.descr_uuid.uuid.uuid16 = ESP_GATT_UUID_CHAR_CLIENT_CONFIG; esp_ble_gatts_add_char_descr(gl_test.service_handle, &gl_test.descr_uuid, ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE); break; diff --git a/examples/16_pcnt/main/pcnt_test.c b/examples/16_pcnt/main/pcnt_test.c index 1da4cca56e..b8489ecb2f 100644 --- a/examples/16_pcnt/main/pcnt_test.c +++ b/examples/16_pcnt/main/pcnt_test.c @@ -36,13 +36,11 @@ * When counter value reaches thresh1 or thresh0 value, it will trigger interrupt. * When counter value reaches l_lim value or h_lim value, counter value will be reset to zero and trigger interrupt. */ -static const char* TAG = "PCNT_TEST"; #define PCNT_TEST_UNIT PCNT_UNIT_0 #define PCNT_H_LIM_VAL (10) #define PCNT_L_LIM_VAL (-10) #define PCNT_THRESH1_VAL (5) #define PCNT_THRESH0_VAL (-5) -#define PCNT_INTR_NUM (18) #define PCNT_INPUT_SIG_IO (4) #define PCNT_INPUT_CTRL_IO (5) #define LEDC_OUPUT_IO (18) @@ -177,7 +175,7 @@ static void pcnt_init(void) /*Reset counter value*/ pcnt_counter_clear(PCNT_TEST_UNIT); /*Register ISR handler*/ - pcnt_isr_register(PCNT_INTR_NUM, pcnt_intr_handler, NULL); + pcnt_isr_register(pcnt_intr_handler, NULL, 0, NULL); /*Enable interrupt for PCNT unit*/ pcnt_intr_enable(PCNT_TEST_UNIT); /*Resume counting*/ diff --git a/examples/14_ethernet/Makefile b/examples/17_ethernet/Makefile similarity index 100% rename from examples/14_ethernet/Makefile rename to examples/17_ethernet/Makefile diff --git a/examples/14_ethernet/README.md b/examples/17_ethernet/README.md similarity index 100% rename from examples/14_ethernet/README.md rename to examples/17_ethernet/README.md diff --git a/examples/14_ethernet/main/component.mk b/examples/17_ethernet/main/component.mk similarity index 100% rename from examples/14_ethernet/main/component.mk rename to examples/17_ethernet/main/component.mk diff --git a/examples/14_ethernet/main/ethernet_main.c b/examples/17_ethernet/main/ethernet_main.c similarity index 58% rename from examples/14_ethernet/main/ethernet_main.c rename to examples/17_ethernet/main/ethernet_main.c index 836e977f48..7e84a9badd 100644 --- a/examples/14_ethernet/main/ethernet_main.c +++ b/examples/17_ethernet/main/ethernet_main.c @@ -32,30 +32,64 @@ #include "tcpip_adapter.h" #include "nvs_flash.h" #include "driver/gpio.h" +#include "tlk110_phy.h" static const char *TAG = "eth_demo"; +#define DEFAULT_PHY_CONFIG (AUTO_MDIX_ENABLE|AUTO_NEGOTIATION_ENABLE|AN_1|AN_0|LED_CFG) + +void phy_tlk110_check_phy_init(void) +{ + while((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & AUTO_NEGOTIATION_COMPLETE ) != AUTO_NEGOTIATION_COMPLETE) + {}; + while((esp_eth_smi_read(PHY_STATUS_REG) & AUTO_NEGTIATION_STATUS ) != AUTO_NEGTIATION_STATUS) + {}; + while((esp_eth_smi_read(CABLE_DIAGNOSTIC_CONTROL_REG) & DIAGNOSTIC_DONE ) != DIAGNOSTIC_DONE) + {}; +} + +eth_speed_mode_t phy_tlk110_get_speed_mode(void) +{ + if((esp_eth_smi_read(PHY_STATUS_REG) & SPEED_STATUS ) != SPEED_STATUS) { + return ETH_SPEED_MODE_100M; + } else { + return ETH_SPEED_MODE_10M; + } +} + +eth_duplex_mode_t phy_tlk110_get_duplex_mode(void) +{ + if((esp_eth_smi_read(PHY_STATUS_REG) & DUPLEX_STATUS ) == DUPLEX_STATUS) { + return ETH_MDOE_FULLDUPLEX; + } else { + return ETH_MODE_HALFDUPLEX; + } +} + +bool phy_tlk110_check_phy_link_status(void) +{ + return ((esp_eth_smi_read(BASIC_MODE_STATUS_REG) & LINK_STATUS) == LINK_STATUS ); +} + void phy_tlk110_init(void) { - esp_eth_smi_write(0x1f, 0x8000); - ets_delay_us(20000); + esp_eth_smi_write(PHY_RESET_CONTROL_REG, SOFTWARE_RESET); - while (esp_eth_smi_read(0x2) != 0x2000) { + while (esp_eth_smi_read(PHY_IDENTIFIER_REG) != OUI_MSB_21TO6_DEF) { } - esp_eth_smi_write(0x9, 0x7400); - esp_eth_smi_write(0x9, 0xf400); - ets_delay_us(20000); + esp_eth_smi_write(SOFTWARE_STAP_CONTROL_REG, DEFAULT_PHY_CONFIG |SW_STRAP_CONFIG_DONE); + ets_delay_us(300); } void eth_gpio_config_rmii(void) { //txd0 to gpio19 ,can not change - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, 5); - //rx_en to gpio21 ,can not change - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO21_U, 5); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, FUNC_GPIO19_EMAC_TXD0); + //tx_en to gpio21 ,can not change + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO21_U, FUNC_GPIO21_EMAC_TX_EN); //txd1 to gpio22 , can not change - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO22_U, 5); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO22_U, FUNC_GPIO22_EMAC_TXD1); //rxd0 to gpio25 , can not change gpio_set_direction(25, GPIO_MODE_INPUT); //rxd1 to gpio26 ,can not change @@ -102,8 +136,13 @@ void app_main() config.phy_init = phy_tlk110_init; config.gpio_config = eth_gpio_config_rmii; config.tcpip_input = tcpip_adapter_eth_input; + config.phy_check_init = phy_tlk110_check_phy_init; + config.phy_check_link = phy_tlk110_check_phy_link_status; + config.phy_get_speed_mode = phy_tlk110_get_speed_mode; + config.phy_get_duplex_mode = phy_tlk110_get_duplex_mode; ret = esp_eth_init(&config); + if(ret == ESP_OK) { esp_eth_enable(); xTaskCreate(eth_task, "eth_task", 2048, NULL, (tskIDLE_PRIORITY + 2), NULL); diff --git a/examples/19_sigmadelta/Makefile b/examples/19_sigmadelta/Makefile new file mode 100644 index 0000000000..75f7111ab2 --- /dev/null +++ b/examples/19_sigmadelta/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := sigmadelta + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/19_sigmadelta/main/component.mk b/examples/19_sigmadelta/main/component.mk new file mode 100644 index 0000000000..4d3b30caf3 --- /dev/null +++ b/examples/19_sigmadelta/main/component.mk @@ -0,0 +1,5 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + diff --git a/examples/19_sigmadelta/main/sigmadelta_test.c b/examples/19_sigmadelta/main/sigmadelta_test.c new file mode 100644 index 0000000000..92bc6e0a83 --- /dev/null +++ b/examples/19_sigmadelta/main/sigmadelta_test.c @@ -0,0 +1,54 @@ +/* Sigma-delta Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "driver/sigmadelta.h" + +/* + * This test code intended to configure sigma-delta and set GPIO4 as signal output pin. + * If you connect this GPIO4 with an LED, you will see the LED blinking slowly. + */ + +/** + * @brief Sigma-delta initialization. + */ +static void sigmadelta_init(void) +{ + sigmadelta_config_t sigmadelta_cfg = { + /* Sigma-delta channel0*/ + .channel = SIGMADELTA_CHANNEL_0, + /* Sigma-delta set duty 10*/ + .sigmadelta_duty = 10, + /* Set prescale 30 */ + .sigmadelta_prescale = 80, + /*select GPIO4 as output_io */ + .sigmadelta_gpio = 4, + }; + sigmadelta_config(&sigmadelta_cfg); +} + +/** + * @brief Sigma-delta test to change duty of output signal. + */ +void app_main() +{ + sigmadelta_init(); + int8_t duty = 0; + int inc = 1; + while(1) { + sigmadelta_set_duty(SIGMADELTA_CHANNEL_0, duty); + /*by changing delay time, you can change the blink frequency of LED. */ + vTaskDelay(10 / portTICK_RATE_MS); + + duty += inc; + if(duty == 127 || duty == -127) inc = (-1) * inc; + } +} diff --git a/examples/20_uart/Makefile b/examples/20_uart/Makefile new file mode 100644 index 0000000000..4c523bd68a --- /dev/null +++ b/examples/20_uart/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := uart + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/20_uart/main/component.mk b/examples/20_uart/main/component.mk new file mode 100644 index 0000000000..44bd2b5273 --- /dev/null +++ b/examples/20_uart/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# diff --git a/examples/20_uart/main/uart_test.c b/examples/20_uart/main/uart_test.c new file mode 100644 index 0000000000..9a0d0003c3 --- /dev/null +++ b/examples/20_uart/main/uart_test.c @@ -0,0 +1,183 @@ +/* Uart Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "nvs_flash.h" +#include "driver/uart.h" +#include "freertos/queue.h" +#include "esp_log.h" +#include "soc/uart_struct.h" +static const char *TAG = "uart_example"; + +/** + * Test code brief + * This example shows how to configure uart settings and install uart driver. + * + * uart_evt_test() is an example that read and write data on UART0, and handler some of the special events. + * - port: UART0 + * - rx buffer: on + * - tx buffer: on + * - flow control: off + * - event queue: on + * - pin assignment: txd(default), rxd(default) + * + * uart_echo_test() is an example that read and write data on UART1, with hardware flow control turning on. + * - port: UART1 + * - rx buffer: on + * - tx buffer: off + * - flow control: on + * - event queue: off + * - pin assignment: txd(io4), rxd(io5), rts(18), cts(19) + */ + +#define BUF_SIZE (1024) +#define ECHO_TEST_TXD (4) +#define ECHO_TEST_RXD (5) +#define ECHO_TEST_RTS (18) +#define ECHO_TEST_CTS (19) + +QueueHandle_t uart0_queue; +void uart_task(void *pvParameters) +{ + int uart_num = (int) pvParameters; + uart_event_t event; + size_t buffered_size; + uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE); + for(;;) { + //Waiting for UART event. + if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) { + ESP_LOGI(TAG, "uart[%d] event:", uart_num); + switch(event.type) { + //Event of UART receving data + /*We'd better handler data event fast, there would be much more data events than + other types of events. If we take too much time on data event, the queue might + be full. + in this example, we don't process data in event, but read data outside.*/ + case UART_DATA: + uart_get_buffered_data_len(uart_num, &buffered_size); + ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size); + break; + //Event of HW FIFO overflow detected + case UART_FIFO_OVF: + ESP_LOGI(TAG, "hw fifo overflow\n"); + //If fifo overflow happened, you should consider adding flow control for your application. + //We can read data out out the buffer, or directly flush the rx buffer. + uart_flush(uart_num); + break; + //Event of UART ring buffer full + case UART_BUFFER_FULL: + ESP_LOGI(TAG, "ring buffer full\n"); + //If buffer full happened, you should consider encreasing your buffer size + //We can read data out out the buffer, or directly flush the rx buffer. + uart_flush(uart_num); + break; + //Event of UART RX break detected + case UART_BREAK: + ESP_LOGI(TAG, "uart rx break\n"); + break; + //Event of UART parity check error + case UART_PARITY_ERR: + ESP_LOGI(TAG, "uart parity error\n"); + break; + //Event of UART frame error + case UART_FRAME_ERR: + ESP_LOGI(TAG, "uart frame error\n"); + break; + //UART_PATTERN_DET + case UART_PATTERN_DET: + ESP_LOGI(TAG, "uart pattern detected\n"); + break; + //Others + default: + ESP_LOGI(TAG, "uart event type: %d\n", event.type); + break; + } + } + } + free(dtmp); + dtmp = NULL; + vTaskDelete(NULL); +} + +void uart_evt_test() +{ + int uart_num = UART_NUM_0; + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 122, + }; + //Set UART parameters + uart_param_config(uart_num, &uart_config); + //Set UART log level + esp_log_level_set(TAG, ESP_LOG_INFO); + //Install UART driver, and get the queue. + uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0); + //Set UART pins,(-1: default pin, no change.) + //For UART0, we can just use the default pins. + //uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + //Set uart pattern detect function. + uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10); + //Create a task to handler UART event from ISR + xTaskCreate(uart_task, "uart_task", 2048, (void*)uart_num, 12, NULL); + //process data + uint8_t* data = (uint8_t*) malloc(BUF_SIZE); + do { + int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS); + if(len > 0) { + ESP_LOGI(TAG, "uart read : %d", len); + uart_write_bytes(uart_num, (const char*)data, len); + } + } while(1); +} + +//an example of echo test with hardware flow control on UART1 +void uart_echo_test() +{ + int uart_num = UART_NUM_1; + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + .rx_flow_ctrl_thresh = 122, + }; + //Configure UART1 parameters + uart_param_config(uart_num, &uart_config); + //Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19) + uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS); + //Install UART driver( We don't need an event queue here) + //In this example we don't even use a buffer for sending data. + uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0); + + uint8_t* data = (uint8_t*) malloc(BUF_SIZE); + while(1) { + //Read data from UART + int len = uart_read_bytes(uart_num, data, BUF_SIZE, 20 / portTICK_RATE_MS); + //Write data back to UART + uart_write_bytes(uart_num, (const char*) data, len); + } +} + +void app_main() +{ + //A uart read/write example without event queue; + xTaskCreate(uart_echo_test, "uart_echo_test", 1024, NULL, 10, NULL); + + //A uart example with event queue. + uart_evt_test(); +} diff --git a/make/build_examples.sh b/make/build_examples.sh index 8345dab502..f1b37b7b4b 100755 --- a/make/build_examples.sh +++ b/make/build_examples.sh @@ -12,24 +12,42 @@ EXAMPLE_NUM=1 RESULT=0 +RESULT_WARNINGS=22 # magic number result code for "warnings found" + set -e for example in ${IDF_PATH}/examples/*; do [ -f ${example}/Makefile ] || continue echo "Building ${example} as ${EXAMPLE_NUM}..." - mkdir ${EXAMPLE_NUM} - cp -r ${example} ${EXAMPLE_NUM} - pushd ${EXAMPLE_NUM}/`basename ${example}` + mkdir -p example_builds/${EXAMPLE_NUM} + cp -r ${example} example_builds/${EXAMPLE_NUM} + pushd example_builds/${EXAMPLE_NUM}/`basename ${example}` # be stricter in the CI build than the default IDF settings export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations" export EXTRA_CXXFLAGS=${EXTRA_CFLAGS} - # build non-verbose first, only build verbose if there's an error - (make clean defconfig && make all ) || (RESULT=$?; make V=1) + # build non-verbose first + BUILDLOG=$(mktemp -t examplebuild.XXXX.log) + ( + set -e + make clean defconfig + make all 2>&1 | tee $BUILDLOG + ) || (RESULT=$?; make V=1) # only build verbose if there's an error popd EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) + + if [ $RESULT -eq 0 ] && grep -q ": warning:" $BUILDLOG; then + echo "Build will fail, due to warnings in this example" + RESULT=$RESULT_WARNINGS + fi + + rm -f $BUILDLOG done +if [ $RESULT -eq $RESULT_WARNINGS ]; then + echo "Build would have passed, except for warnings." +fi + exit $RESULT diff --git a/make/common.mk b/make/common.mk index 4d40f7abc3..605b8ab862 100644 --- a/make/common.mk +++ b/make/common.mk @@ -52,5 +52,19 @@ endef # # example $(call resolvepath,$(CONFIG_PATH),$(CONFIG_DIR)) define resolvepath -$(if $(filter /%,$(1)),$(1),$(subst //,/,$(2)/$(1))) +$(foreach dir,$(1),$(if $(filter /%,$(dir)),$(dir),$(subst //,/,$(2)/$(dir)))) +endef + + +# macro to include a target only if it's on the list of targets that make +# was invoked with +# +# This allows you to have something like an "order-only phony prerequisite", +# ie a prerequisite that determines an order phony targets have to run in. +# +# Because normal order-only prerequisites don't work with phony targets. +# +# example $(call prereq_if_explicit,erase_flash) +define prereq_if_explicit +$(filter $(1),$(MAKECMDGOALS)) endef diff --git a/make/component_wrapper.mk b/make/component_wrapper.mk index 63f687d930..c750341c27 100644 --- a/make/component_wrapper.mk +++ b/make/component_wrapper.mk @@ -74,7 +74,6 @@ endif # Correspond to the files named in COMPONENT_EMBED_FILES & COMPONENT_EMBED_TXTFILES COMPONENT_EMBED_OBJS ?= $(addsuffix .bin.o,$(COMPONENT_EMBED_FILES)) $(addsuffix .txt.o,$(COMPONENT_EMBED_TXTFILES)) - # If we're called to compile something, we'll get passed the COMPONENT_INCLUDES # variable with all the include dirs from all the components in random order. This # means we can accidentally grab a header from another component before grabbing our own. @@ -95,7 +94,7 @@ COMPONENT_INCLUDES := $(OWN_INCLUDES) $(filter-out $(OWN_INCLUDES),$(COMPONENT_I # # This means if directories move (breaking absolute paths), don't need to 'make clean' define MakeVariablePath -$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),\$$(BUILD_DIR_BASE),$(1)))) +$(subst $(IDF_PATH),$$(IDF_PATH),$(subst $(PROJECT_PATH),$$(PROJECT_PATH),$(subst $(BUILD_DIR_BASE),$$(BUILD_DIR_BASE),$(1)))) endef # component_project_vars.mk target for the component. This is used to @@ -116,6 +115,7 @@ component_project_vars.mk:: @echo '# Automatically generated build file. Do not edit.' > $@ @echo 'COMPONENT_INCLUDES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_ADD_INCLUDEDIRS)))' >> $@ @echo 'COMPONENT_LDFLAGS += $(call MakeVariablePath,$(COMPONENT_ADD_LDFLAGS))' >> $@ + @echo 'COMPONENT_LINKER_DEPS += $(call MakeVariablePath,$(call resolvepath,$(COMPONENT_ADD_LINKER_DEPS),$(COMPONENT_PATH)))' >> $@ @echo 'COMPONENT_SUBMODULES += $(call MakeVariablePath,$(addprefix $(COMPONENT_PATH)/,$(COMPONENT_SUBMODULES)))' >> $@ @echo '$(COMPONENT_NAME)-build: $(addsuffix -build,$(COMPONENT_DEPENDS))' >> $@ @@ -157,15 +157,15 @@ define GenerateCompileTargets # $(1) - directory containing source files, relative to $(COMPONENT_PATH) $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.c $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(1) $$(summary) CC $$@ - $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(FLAGS_$$(subst .o,,$$(@))) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(CC) $$(CFLAGS) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.cpp $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(1) $$(summary) CXX $$@ - $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(FLAGS_$$(subst .o,,$$(@))) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(CXX) $$(CXXFLAGS) $$(CPPFLAGS) $$(addprefix -I,$$(COMPONENT_INCLUDES)) $$(addprefix -I,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ $(1)/%.o: $$(COMPONENT_PATH)/$(1)/%.S $(COMMON_MAKEFILES) $(COMPONENT_MAKEFILE) | $(1) $$(summary) AS $$@ - $$(CC) $$(CPPFLAGS) $$(FLAGS_$$(subst .o,,$$(@))) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ + $$(CC) $$(CPPFLAGS) $$(addprefix -I ,$$(COMPONENT_INCLUDES)) $$(addprefix -I ,$$(COMPONENT_EXTRA_INCLUDES)) -I$(1) -c $$< -o $$@ # CWD is build dir, create the build subdirectory if it doesn't exist $(1): diff --git a/make/project.mk b/make/project.mk index 181152f118..a5e487b85c 100644 --- a/make/project.mk +++ b/make/project.mk @@ -10,7 +10,7 @@ # where this file is located. # -.PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules +.PHONY: build-components menuconfig defconfig all build clean all_binaries check-submodules size all: all_binaries # see below for recipe of 'all' target # @@ -26,8 +26,10 @@ help: @echo "make defconfig - Set defaults for all new configuration options" @echo "" @echo "make all - Build app, bootloader, partition table" - @echo "make flash - Flash all components to a fresh chip" + @echo "make flash - Flash app, bootloader, partition table to a chip" @echo "make clean - Remove all build output" + @echo "make size - Display the memory footprint of the app" + @echo "make erase_flash - Erase entire flash contents" @echo "" @echo "make app - Build just the app" @echo "make app-flash - Flash just the app" @@ -43,6 +45,27 @@ $(warning "esp-idf build system only supports GNU Make versions 3.81 or newer. Y endif endif +# make IDF_PATH a "real" absolute path +# * works around the case where a shell character is embedded in the environment variable value. +# * changes Windows-style C:/blah/ paths to MSYS/Cygwin style /c/blah +export IDF_PATH:=$(realpath $(wildcard $(IDF_PATH))) + +ifndef IDF_PATH +$(error IDF_PATH variable is not set to a valid directory.) +endif + +ifneq ("$(IDF_PATH)","$(realpath $(wildcard $(IDF_PATH)))") +# due to the way make manages variables, this is hard to account for +# +# if you see this error, do the shell expansion in the shell ie +# make IDF_PATH=~/blah not make IDF_PATH="~/blah" +$(error If IDF_PATH is overriden on command line, it must be an absolute path with no embedded shell special characters) +endif + +ifneq ("$(IDF_PATH)","$(subst :,,$(IDF_PATH))") +$(error IDF_PATH cannot contain colons. If overriding IDF_PATH on Windows, use Cygwin-style /c/dir instead of C:/dir) +endif + # disable built-in make rules, makes debugging saner MAKEFLAGS_OLD := $(MAKEFLAGS) MAKEFLAGS +=-rR @@ -139,8 +162,13 @@ export COMPONENT_INCLUDES include $(IDF_PATH)/make/common.mk all: -ifdef CONFIG_SECURE_BOOTLOADER_ENABLED +ifdef CONFIG_SECURE_BOOT_ENABLED @echo "(Secure boot enabled, so bootloader not flashed automatically. See 'make bootloader' output)" +ifndef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES + @echo "App built but not signed. Sign app & partition data before flashing, via espsecure.py:" + @echo "espsecure.py sign_data --keyfile KEYFILE $(APP_BIN)" + @echo "espsecure.py sign_data --keyfile KEYFILE $(PARTITION_TABLE_BIN)" +endif @echo "To flash app & partition table, run 'make flash' or:" else @echo "To flash all build output, run 'make flash' or:" @@ -150,8 +178,6 @@ endif # Set default LDFLAGS LDFLAGS ?= -nostdlib \ - -L$(IDF_PATH)/lib \ - -L$(IDF_PATH)/ld \ $(addprefix -L$(BUILD_DIR_BASE)/,$(COMPONENTS) $(TEST_COMPONENT_NAMES) $(SRCDIRS) ) \ -u call_user_start_cpu0 \ $(EXTRA_LDFLAGS) \ @@ -173,7 +199,7 @@ LDFLAGS ?= -nostdlib \ # CPPFLAGS used by C preprocessor # If any flags are defined in application Makefile, add them at the end. -CPPFLAGS := -DESP_PLATFORM $(CPPFLAGS) $(EXTRA_CPPFLAGS) +CPPFLAGS := -DESP_PLATFORM -MMD -MP $(CPPFLAGS) $(EXTRA_CPPFLAGS) # Warnings-related flags relevant both for C and C++ COMMON_WARNING_FLAGS = -Wall -Werror=all \ @@ -189,8 +215,7 @@ COMMON_FLAGS = \ -ffunction-sections -fdata-sections \ -fstrict-volatile-bitfields \ -mlongcalls \ - -nostdlib \ - -MMD -MP + -nostdlib # Optimization flags are set based on menuconfig choice ifneq ("$(CONFIG_OPTIMIZATION_LEVEL_RELEASE)","") @@ -232,7 +257,8 @@ HOSTCC := $(CC) HOSTLD := $(LD) HOSTAR := $(AR) HOSTOBJCOPY := $(OBJCOPY) -export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY +HOSTSIZE := $(SIZE) +export HOSTCC HOSTLD HOSTAR HOSTOBJCOPY SIZE # Set target compiler. Defaults to whatever the user has # configured as prefix + ye olde gcc commands @@ -241,7 +267,8 @@ CXX := $(call dequote,$(CONFIG_TOOLPREFIX))c++ LD := $(call dequote,$(CONFIG_TOOLPREFIX))ld AR := $(call dequote,$(CONFIG_TOOLPREFIX))ar OBJCOPY := $(call dequote,$(CONFIG_TOOLPREFIX))objcopy -export CC CXX LD AR OBJCOPY +SIZE := $(call dequote,$(CONFIG_TOOLPREFIX))size +export CC CXX LD AR OBJCOPY SIZE PYTHON=$(call dequote,$(CONFIG_PYTHON)) @@ -273,15 +300,25 @@ COMPONENT_LIBRARIES = $(filter $(notdir $(COMPONENT_PATHS_BUILDABLE)) $(TEST_COM # ELF depends on the library archive files for COMPONENT_LIBRARIES # the rules to build these are emitted as part of GenerateComponentTarget below -$(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) +# +# also depends on additional dependencies (linker scripts & binary libraries) +# stored in COMPONENT_LINKER_DEPS, built via component.mk files' COMPONENT_ADD_LINKER_DEPS variable +$(APP_ELF): $(foreach libcomp,$(COMPONENT_LIBRARIES),$(BUILD_DIR_BASE)/$(libcomp)/lib$(libcomp).a) $(COMPONENT_LINKER_DEPS) $(summary) LD $(notdir $@) $(CC) $(LDFLAGS) -o $@ -Wl,-Map=$(APP_MAP) # Generation of $(APP_BIN) from $(APP_ELF) is added by the esptool # component's Makefile.projbuild app: $(APP_BIN) +ifeq ("$(CONFIG_SECURE_BOOT_ENABLED)$(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)","y") # secure boot enabled, but remote sign app image + @echo "App built but not signed. Signing step via espsecure.py:" + @echo "espsecure.py sign_data --keyfile KEYFILE $(APP_BIN)" + @echo "Then flash app command is:" + @echo $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) +else @echo "App built. Default flash app command is:" @echo $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN) +endif all_binaries: $(APP_BIN) @@ -343,6 +380,9 @@ app-clean: $(addsuffix -clean,$(notdir $(COMPONENT_PATHS_BUILDABLE))) $(summary) RM $(APP_ELF) rm -f $(APP_ELF) $(APP_BIN) $(APP_MAP) +size: $(APP_ELF) + $(SIZE) $(APP_ELF) + # NB: this ordering is deliberate (app-clean before config-clean), # so config remains valid during all component clean targets config-clean: app-clean @@ -368,7 +408,7 @@ $(IDF_PATH)/$(1)/.git: # Parse 'git submodule status' output for out-of-date submodule. # Status output prefixes status line with '+' if the submodule commit doesn't match ifneq ("$(shell cd ${IDF_PATH} && git submodule status $(1) | grep '^+')","") -$$(info WARNING: git submodule $(1) may be out of date. Run 'git submodule update' to update.) +$$(info WARNING: esp-idf git submodule $(1) may be out of date. Run 'git submodule update' in IDF_PATH dir to update.) endif endef diff --git a/make/project_config.mk b/make/project_config.mk index a32c74a380..187d1ac282 100644 --- a/make/project_config.mk +++ b/make/project_config.mk @@ -26,7 +26,7 @@ menuconfig: $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig $(KCONFIG_TOOL_ENV) $(KCONFIG_TOOL_DIR)/mconf $(IDF_PATH)/Kconfig ifeq ("$(wildcard $(SDKCONFIG))","") -ifeq ("$(filter defconfig,$(MAKECMDGOALS))","") +ifeq ("$(call prereq_if_explicit,defconfig)","") # if not configuration is present and defconfig is not a target, run makeconfig $(SDKCONFIG): menuconfig else diff --git a/make/test_build_system.sh b/make/test_build_system.sh index d08ae6c8a2..5d24e2a948 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -141,6 +141,30 @@ function run_tests() assert_built ${APP_BINS} ${BOOTLOADER_BINS} partitions_singleapp.bin [ -f ${BUILD}/partition*.bin ] || failure "A partition table should have been built in CRLF mode" + print_status "Touching rom ld file should re-link app and bootloader" + make + take_build_snapshot + touch ${IDF_PATH}/components/esp32/ld/esp32.rom.ld + make + assert_rebuilt ${APP_BINS} ${BOOTLOADER_BINS} + + print_status "Touching peripherals ld file should only re-link app" + take_build_snapshot + touch ${IDF_PATH}/components/esp32/ld/esp32.peripherals.ld + make + assert_rebuilt ${APP_BINS} + assert_not_rebuilt ${BOOTLOADER_BINS} + + print_status "sdkconfig update triggers recompiles" + make + take_build_snapshot + touch sdkconfig + make + # pick one each of .c, .cpp, .S that #includes sdkconfig.h + # and therefore should rebuild + assert_rebuilt newlib/syscall_table.o + assert_rebuilt nvs_flash/src/nvs_api.o + assert_rebuilt freertos/xtensa_vectors.o print_status "All tests completed" if [ -n "${FAILURES}" ]; then diff --git a/tools/format.sh b/tools/format.sh old mode 100644 new mode 100755 diff --git a/tools/kconfig/confdata.c b/tools/kconfig/confdata.c index dd243d2abd..1e3d1f35b2 100644 --- a/tools/kconfig/confdata.c +++ b/tools/kconfig/confdata.c @@ -771,7 +771,7 @@ int conf_write(const char *name) sprintf(newname, "%s%s", dirname, basename); env = getenv("KCONFIG_OVERWRITECONFIG"); if (!env || !*env) { - sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid()); + sprintf(tmpname, "%s.tmpconfig.%d", newname, (int)getpid()); out = fopen(tmpname, "w"); } else { *tmpname = 0; diff --git a/tools/unit-test-app/components/unity/unity_platform.c b/tools/unit-test-app/components/unity/unity_platform.c index 4e1c0b8e07..74f2108425 100644 --- a/tools/unit-test-app/components/unity/unity_platform.c +++ b/tools/unit-test-app/components/unity/unity_platform.c @@ -1,16 +1,16 @@ #include #include #include +#include #include "unity.h" #include "rom/ets_sys.h" +#include "rom/uart.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" #define unity_printf ets_printf -// Functions which are defined in ROM, linker script provides addresses for these: -int uart_tx_one_char(uint8_t c); -void uart_tx_wait_idle(uint8_t uart_no); -int UartRxString(uint8_t* dst, uint8_t max_length); - // Pointers to the head and tail of linked list of test description structs: static struct test_desc_t* s_unity_tests_first = NULL; static struct test_desc_t* s_unity_tests_last = NULL; @@ -114,35 +114,46 @@ static void trim_trailing_space(char* str) } } +static int print_test_menu(void) +{ + int test_counter = 0; + unity_printf("\n\nHere's the test menu, pick your combo:\n"); + for (const struct test_desc_t* test = s_unity_tests_first; + test != NULL; + test = test->next, ++test_counter) + { + unity_printf("(%d)\t\"%s\" %s\n", test_counter + 1, test->name, test->desc); + } + return test_counter; +} + void unity_run_menu() { - while (true) + int test_count = print_test_menu(); + while (true) { - int test_counter = 0; - unity_printf("\n\nHere's the test menu, pick your combo:\n"); - for (const struct test_desc_t* test = s_unity_tests_first; - test != NULL; - test = test->next, ++test_counter) + char cmdline[256] = { 0 }; + while(strlen(cmdline) == 0) { - unity_printf("(%d)\t\"%s\" %s\n", test_counter + 1, test->name, test->desc); + /* Flush anything already in the RX buffer */ + while(uart_rx_one_char((uint8_t *) cmdline) == OK) { + } + /* Read input */ + UartRxString((uint8_t*) cmdline, sizeof(cmdline) - 1); + trim_trailing_space(cmdline); + if(strlen(cmdline) == 0) { + /* if input was newline, print a new menu */ + print_test_menu(); + } } - - char cmdline[256]; - UartRxString((uint8_t*) cmdline, sizeof(cmdline) - 1); - trim_trailing_space(cmdline); - if (strlen(cmdline) == 0) - { - continue; - } - UNITY_BEGIN(); - - if (cmdline[0] == '*') + + if (cmdline[0] == '*') { unity_run_all_tests(); } - else if (cmdline[0] =='[') + else if (cmdline[0] =='[') { unity_run_tests_with_filter(cmdline); } @@ -150,16 +161,21 @@ void unity_run_menu() { unity_run_single_test_by_name(cmdline); } - else + else { int test_index = strtol(cmdline, NULL, 10); - if (test_index >= 1 && test_index <= test_counter) + if (test_index >= 1 && test_index <= test_count) { + uint32_t start = esp_log_timestamp(); /* hacky way to get ms */ unity_run_single_test_by_index(test_index - 1); + uint32_t end = esp_log_timestamp(); + printf("Test ran in %dms\n", end - start); } } UNITY_END(); + + printf("Enter next test, or 'enter' to see menu\n"); } } diff --git a/tools/unit-test-app/main/component.mk b/tools/unit-test-app/main/component.mk index fd2dbe7b84..a98f634eae 100644 --- a/tools/unit-test-app/main/component.mk +++ b/tools/unit-test-app/main/component.mk @@ -1,5 +1,4 @@ # -# Main Makefile. This is basically the same as a component makefile. +# "main" pseudo-component makefile. # - -include $(IDF_PATH)/make/component_common.mk +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/tools/unit-test-app/sdkconfig b/tools/unit-test-app/sdkconfig index 7121dcc8a9..14b31e0d18 100644 --- a/tools/unit-test-app/sdkconfig +++ b/tools/unit-test-app/sdkconfig @@ -74,6 +74,7 @@ CONFIG_OPTIMIZATION_LEVEL_DEBUG=y # # Component config # +CONFIG_BTC_TASK_STACK_SIZE=2048 CONFIG_BT_RESERVE_DRAM=0 # @@ -85,7 +86,6 @@ CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 # CONFIG_ESP32_ENABLE_STACK_WIFI is not set # CONFIG_ESP32_ENABLE_STACK_BT is not set -CONFIG_ESP32_ENABLE_STACK_NONE=y CONFIG_MEMMAP_SMP=y # CONFIG_MEMMAP_TRACEMEM is not set CONFIG_TRACEMEM_RESERVE_DRAM=0x0 @@ -93,8 +93,14 @@ CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048 CONFIG_MAIN_TASK_STACK_SIZE=4096 CONFIG_NEWLIB_STDOUT_ADDCR=y -# CONFIG_ULP_COPROC_ENABLED is not set -CONFIG_ULP_COPROC_RESERVE_MEM=0 +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_RESERVE_MEM=512 # CONFIG_ESP32_PANIC_PRINT_HALT is not set CONFIG_ESP32_PANIC_PRINT_REBOOT=y # CONFIG_ESP32_PANIC_SILENT_REBOOT is not set @@ -112,6 +118,7 @@ CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y CONFIG_ESP32_PHY_AUTO_INIT=y # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# CONFIG_ETHERNET is not set # # FreeRTOS @@ -164,8 +171,9 @@ CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 CONFIG_MBEDTLS_HARDWARE_AES=y CONFIG_MBEDTLS_HARDWARE_MPI=y CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y -CONFIG_MBEDTLS_MPI_INTERRUPT_NUM=18 CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set # # SPI Flash driver