├── .cargo └── config ├── .gitattributes ├── .gitignore ├── .gitmodules ├── Cargo.toml ├── Makefile ├── README.md ├── bindgen-project ├── esp32-sys ├── Cargo.toml └── src │ ├── bindings.h │ ├── bindings.rs │ └── lib.rs ├── main ├── component.mk └── esp_app_main.c ├── sdkconfig └── src ├── app.rs ├── error.rs ├── http ├── config.rs ├── error.rs ├── mod.rs └── response.rs ├── letsencrypt.der ├── letsencrypt.pem ├── log └── mod.rs ├── main.rs ├── timer.rs └── uart └── mod.rs /.cargo/config: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "xtensa-esp32-none-elf" 3 | 4 | [target.xtensa-esp32-none-elf] 5 | rustflags = [ 6 | "-C", "target-cpu=esp32", 7 | "-C", "save-temps", 8 | "-C", "link-arg=-nostdlib", 9 | # "-C", "link-arg=-nostartfiles", 10 | 11 | "-C", "link-arg=-ucall_user_start_cpu0", 12 | "-C", "link-arg=-u__cxa_guard_dummy", 13 | "-C", "link-arg=-u__cxx_fatal_exception", 14 | "-C", "link-arg=-uld_include_panic_highint_hdl", 15 | "-C", "link-arg=-uesp_app_desc", 16 | 17 | "-C", "link-arg=-Wl,--gc-sections", 18 | "-C", "link-arg=-Wl,-static", 19 | "-C", "link-arg=-Wl,--start-group", 20 | 21 | "-C", "link-arg=-Lbuild/app_update", "-C", "link-arg=-lapp_update", 22 | "-C", "link-arg=-Lbuild/driver", "-C", "link-arg=-ldriver", 23 | "-C", "link-arg=-Lbuild/esp-tls", "-C", "link-arg=-lesp-tls", 24 | "-C", "link-arg=esp-idf/components/esp32/libhal.a", 25 | 26 | "-C", "link-arg=-Lesp-idf/components/esp32/ld", 27 | "-C", "link-arg=-Tesp32_out.ld", 28 | "-C", "link-arg=-Tbuild/esp32/esp32.project.ld", 29 | "-C", "link-arg=-Tesp32.rom.ld", 30 | "-C", "link-arg=-Tesp32.peripherals.ld", 31 | "-C", "link-arg=-Tesp32.rom.libgcc.ld", 32 | "-C", "link-arg=-Tesp32.rom.spiram_incompatible_fns.ld", 33 | 34 | "-C", "link-arg=-Lbuild/esp_ringbuf", "-C", "link-arg=-lesp_ringbuf", 35 | "-C", "link-arg=-Lbuild/esp_event", "-C", "link-arg=-lesp_event", 36 | "-C", "link-arg=-Lbuild/efuse", "-C", "link-arg=-lefuse", 37 | "-C", "link-arg=-Lbuild/freertos", "-C", "link-arg=-lfreertos", 38 | 39 | "-C", "link-arg=-Wl,--undefined=uxTopUsedPriority", 40 | 41 | "-C", "link-arg=-Lbuild/heap", "-C", "link-arg=-lheap", 42 | "-C", "link-arg=-Lbuild/log", "-C", "link-arg=-llog", 43 | 44 | "-C", "link-arg=esp-idf/components/newlib/lib/libc.a", 45 | "-C", "link-arg=esp-idf/components/newlib/lib/libm.a", 46 | 47 | "-C", "link-arg=-Lbuild/newlib", "-C", "link-arg=-lnewlib", 48 | "-C", "link-arg=-Lbuild/pthread", "-C", "link-arg=-lpthread", 49 | "-C", "link-arg=-Lbuild/soc", "-C", "link-arg=-lsoc", 50 | "-C", "link-arg=-Lbuild/spi_flash", "-C", "link-arg=-lspi_flash", 51 | "-C", "link-arg=-Lbuild/vfs", "-C", "link-arg=-lvfs", 52 | 53 | "-C", "link-arg=-Lbuild/esp_http_client", "-C", "link-arg=-lesp_http_client", 54 | "-C", "link-arg=-Lbuild/esp-tls", "-C", "link-arg=-lesp-tls", 55 | "-C", "link-arg=-Lbuild/mbedtls", "-C", "link-arg=-lmbedtls", 56 | "-C", "link-arg=-Lbuild/tcp_transport", "-C", "link-arg=-ltcp_transport", 57 | "-C", "link-arg=-Lbuild/lwip", "-C", "link-arg=-llwip", 58 | "-C", "link-arg=-Lbuild/nghttp", "-C", "link-arg=-lnghttp", 59 | "-C", "link-arg=-Lbuild/wpa_supplicant", "-C", "link-arg=-lwpa_supplicant", 60 | "-C", "link-arg=-Lbuild/nvs_flash", "-C", "link-arg=-lnvs_flash", 61 | 62 | "-C", "link-arg=-Lbuild/tcpip_adapter", "-C", "link-arg=-ltcpip_adapter", 63 | "-C", "link-arg=-Lbuild/tcp_transport", "-C", "link-arg=-ltcp_transport", 64 | "-C", "link-arg=-Lbuild/wifi_provisioning", "-C", "link-arg=-lwifi_provisioning", 65 | 66 | "-C", "link-arg=-Lbuild/xtensa-debug-module", "-C", "link-arg=-lxtensa-debug-module", 67 | 68 | "-C", "link-arg=-Lbuild/smartconfig_ack", "-C", "link-arg=-lsmartconfig_ack", 69 | 70 | "-C", "link-arg=-Lbuild/esp32", "-C", "link-arg=-lesp32", 71 | 72 | "-C", "link-arg=-Lesp-idf/components/esp32/lib", 73 | "-C", "link-arg=-lcore", 74 | "-C", "link-arg=-lphy", 75 | "-C", "link-arg=-lnet80211", 76 | "-C", "link-arg=-lwps", 77 | "-C", "link-arg=-lwpa", 78 | "-C", "link-arg=-lwpa2", 79 | "-C", "link-arg=-lpp", 80 | "-C", "link-arg=-lcoexist", 81 | "-C", "link-arg=-lrtc", 82 | "-C", "link-arg=-lsmartconfig", 83 | 84 | "-C", "link-arg=-lgcc", 85 | "-C", "link-arg=-lstdc++", 86 | "-C", "link-arg=-lgcov", 87 | "-C", "link-arg=-Wl,--end-group", 88 | "-C", "link-arg=-Wl,-EL", 89 | ] 90 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | build/ 3 | Cargo.lock 4 | 5 | /sdkconfig.old 6 | esp-idf 7 | esp-app.bin 8 | 9 | .project 10 | .settings/ 11 | 12 | .idea/ 13 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cstr_core"] 2 | path = cstr_core 3 | url = git@github.com:ctron/cstr_core.git 4 | [submodule "esp-idf-alloc"] 5 | path = esp-idf-alloc 6 | url = git@github.com:ctron/esp-idf-alloc.git 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "esp-app" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [patch.crates-io] 7 | cstr_core = { path = "cstr_core" } 8 | 9 | # Use https://github.com/japaric/serde-json-core/pull/12 10 | serde-json-core = { git = "https://github.com/ctron/serde-json-core", branch = "feature/support_floats_1" } 11 | 12 | [dependencies] 13 | esp-idf-alloc = { path = "esp-idf-alloc" } 14 | esp32-sys = { path = "esp32-sys" } 15 | cstr_core = { version = "0.1.2", features = [ "alloc" ] } 16 | cty = "0.2.1" 17 | serde = { version = "1.0.99", default-features = false, features = ["derive"] } 18 | serde-json-core = "0.0.1" 19 | heapless = "0.4" 20 | generic-array = "0.11" 21 | 22 | [profile.dev] 23 | lto = false 24 | incremental = false 25 | debug = false # debug adds frame pointers - which must be omitted 26 | 27 | [profile.release] 28 | lto = false 29 | incremental = false 30 | debug = false # debug adds frame pointers - which must be omitted 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | PROJECT_NAME := esp-app 3 | 4 | include $(IDF_PATH)/make/project.mk 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rust ESP32 project template 2 | 3 | This is a project template for the use of [ctron/rust-esp-container](https://github.com/ctron/rust-esp-container). 4 | 5 | Build with: 6 | 7 | docker run -v $PWD:/home/project:z --rm -ti quay.io/ctron/rust-esp xbuild-project 8 | 9 | On Windows: 10 | 11 | docker run -v %CD%:/home/project --rm -ti quay.io/ctron/rust-esp xbuild-project 12 | 13 | Flash with: 14 | 15 | esptool.py --chip esp32 --baud 115200 --before default_reset --after hard_reset write_flash -z --flash_mode dio --flash_freq 40m --flash_size detect 0x1000 build/bootloader/bootloader.bin 0x10000 esp-app.bin 0x8000 build/partitions_singleapp.bin 16 | -------------------------------------------------------------------------------- /bindgen-project: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | FLAGS="" 6 | FLAGS+=" --sysroot=/esp/xtensa-esp32-elf/xtensa-esp32-elf/sysroot" 7 | FLAGS+=" -I/build/build/include" 8 | FLAGS+=" -D__bindgen" 9 | FLAGS+=" -target xtensa" 10 | FLAGS+=" -x c" 11 | 12 | FLAGS+=" -I$IDF_PATH/components/newlib/platform_include" 13 | 14 | for i in $(find "$IDF_PATH/components" -name include); do 15 | FLAGS+=" -I$i" 16 | done 17 | 18 | FLAGS+=" -I$IDF_PATH/components/lwip/include/apps" 19 | FLAGS+=" -I$IDF_PATH/components/lwip/lwip/src/include/lwip/apps" 20 | FLAGS+=" -I$IDF_PATH/components/esp-tls" 21 | 22 | : ${BINDGEN_FLAGS:="--use-core --no-layout-tests --ctypes-prefix cty --blacklist-type _reent"} 23 | 24 | bindgen $BINDGEN_FLAGS --output esp32-sys/src/bindings.rs esp32-sys/src/bindings.h -- $FLAGS 25 | -------------------------------------------------------------------------------- /esp32-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "esp32-sys" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | cty = "0.2.1" -------------------------------------------------------------------------------- /esp32-sys/src/bindings.h: -------------------------------------------------------------------------------- 1 | typedef long _off_t; 2 | typedef short __dev_t; 3 | typedef unsigned short __uid_t; 4 | typedef unsigned short __gid_t; 5 | typedef int _ssize_t; 6 | 7 | typedef int _lock_t; 8 | typedef _lock_t _LOCK_RECURSIVE_T; 9 | typedef _lock_t _LOCK_T; 10 | typedef struct _reent *_data; 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | -------------------------------------------------------------------------------- /esp32-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![allow(non_upper_case_globals)] 3 | #![allow(non_camel_case_types)] 4 | #![allow(non_snake_case)] 5 | 6 | extern crate cty; 7 | 8 | #[repr(C)] 9 | pub struct _reent { 10 | d: * const cty::c_void 11 | } 12 | 13 | include!("bindings.rs"); 14 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # empty "main" Makefile 2 | -------------------------------------------------------------------------------- /main/esp_app_main.c: -------------------------------------------------------------------------------- 1 | void app_main() {} 2 | -------------------------------------------------------------------------------- /sdkconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file; DO NOT EDIT. 3 | # Espressif IoT Development Framework Configuration 4 | # 5 | CONFIG_IDF_TARGET="esp32" 6 | 7 | # 8 | # SDK tool configuration 9 | # 10 | CONFIG_TOOLPREFIX="xtensa-esp32-elf-" 11 | CONFIG_PYTHON="python" 12 | CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y 13 | 14 | # 15 | # Application manager 16 | # 17 | CONFIG_APP_COMPILE_TIME_DATE=y 18 | CONFIG_APP_EXCLUDE_PROJECT_VER_VAR= 19 | CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR= 20 | 21 | # 22 | # Bootloader config 23 | # 24 | CONFIG_LOG_BOOTLOADER_LEVEL_NONE= 25 | CONFIG_LOG_BOOTLOADER_LEVEL_ERROR= 26 | CONFIG_LOG_BOOTLOADER_LEVEL_WARN= 27 | CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y 28 | CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= 29 | CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= 30 | CONFIG_LOG_BOOTLOADER_LEVEL=3 31 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V= 32 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y 33 | CONFIG_BOOTLOADER_FACTORY_RESET= 34 | CONFIG_BOOTLOADER_APP_TEST= 35 | CONFIG_BOOTLOADER_WDT_ENABLE=y 36 | CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE= 37 | CONFIG_BOOTLOADER_WDT_TIME_MS=9000 38 | CONFIG_APP_ROLLBACK_ENABLE= 39 | 40 | # 41 | # Security features 42 | # 43 | CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT= 44 | CONFIG_SECURE_BOOT_ENABLED= 45 | CONFIG_FLASH_ENCRYPTION_ENABLED= 46 | 47 | # 48 | # Serial flasher config 49 | # 50 | CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" 51 | CONFIG_ESPTOOLPY_BAUD_115200B=y 52 | CONFIG_ESPTOOLPY_BAUD_230400B= 53 | CONFIG_ESPTOOLPY_BAUD_921600B= 54 | CONFIG_ESPTOOLPY_BAUD_2MB= 55 | CONFIG_ESPTOOLPY_BAUD_OTHER= 56 | CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 57 | CONFIG_ESPTOOLPY_BAUD=115200 58 | CONFIG_ESPTOOLPY_COMPRESSED=y 59 | CONFIG_FLASHMODE_QIO= 60 | CONFIG_FLASHMODE_QOUT= 61 | CONFIG_FLASHMODE_DIO=y 62 | CONFIG_FLASHMODE_DOUT= 63 | CONFIG_ESPTOOLPY_FLASHMODE="dio" 64 | CONFIG_ESPTOOLPY_FLASHFREQ_80M= 65 | CONFIG_ESPTOOLPY_FLASHFREQ_40M=y 66 | CONFIG_ESPTOOLPY_FLASHFREQ_26M= 67 | CONFIG_ESPTOOLPY_FLASHFREQ_20M= 68 | CONFIG_ESPTOOLPY_FLASHFREQ="40m" 69 | CONFIG_ESPTOOLPY_FLASHSIZE_1MB= 70 | CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y 71 | CONFIG_ESPTOOLPY_FLASHSIZE_4MB= 72 | CONFIG_ESPTOOLPY_FLASHSIZE_8MB= 73 | CONFIG_ESPTOOLPY_FLASHSIZE_16MB= 74 | CONFIG_ESPTOOLPY_FLASHSIZE="2MB" 75 | CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y 76 | CONFIG_ESPTOOLPY_BEFORE_RESET=y 77 | CONFIG_ESPTOOLPY_BEFORE_NORESET= 78 | CONFIG_ESPTOOLPY_BEFORE="default_reset" 79 | CONFIG_ESPTOOLPY_AFTER_RESET=y 80 | CONFIG_ESPTOOLPY_AFTER_NORESET= 81 | CONFIG_ESPTOOLPY_AFTER="hard_reset" 82 | CONFIG_MONITOR_BAUD_9600B= 83 | CONFIG_MONITOR_BAUD_57600B= 84 | CONFIG_MONITOR_BAUD_115200B=y 85 | CONFIG_MONITOR_BAUD_230400B= 86 | CONFIG_MONITOR_BAUD_921600B= 87 | CONFIG_MONITOR_BAUD_2MB= 88 | CONFIG_MONITOR_BAUD_OTHER= 89 | CONFIG_MONITOR_BAUD_OTHER_VAL=115200 90 | CONFIG_MONITOR_BAUD=115200 91 | 92 | # 93 | # Partition Table 94 | # 95 | CONFIG_PARTITION_TABLE_SINGLE_APP=y 96 | CONFIG_PARTITION_TABLE_TWO_OTA= 97 | CONFIG_PARTITION_TABLE_CUSTOM= 98 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" 99 | CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" 100 | CONFIG_PARTITION_TABLE_OFFSET=0x8000 101 | CONFIG_PARTITION_TABLE_MD5=y 102 | 103 | # 104 | # Compiler options 105 | # 106 | CONFIG_OPTIMIZATION_LEVEL_DEBUG=y 107 | CONFIG_OPTIMIZATION_LEVEL_RELEASE= 108 | CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y 109 | CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= 110 | CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= 111 | CONFIG_CXX_EXCEPTIONS= 112 | CONFIG_STACK_CHECK_NONE= 113 | CONFIG_STACK_CHECK_NORM=y 114 | CONFIG_STACK_CHECK_STRONG= 115 | CONFIG_STACK_CHECK_ALL= 116 | CONFIG_STACK_CHECK=y 117 | CONFIG_WARN_WRITE_STRINGS= 118 | CONFIG_DISABLE_GCC8_WARNINGS= 119 | 120 | # 121 | # Component config 122 | # 123 | 124 | # 125 | # Application Level Tracing 126 | # 127 | CONFIG_ESP32_APPTRACE_DEST_TRAX= 128 | CONFIG_ESP32_APPTRACE_DEST_NONE=y 129 | CONFIG_ESP32_APPTRACE_ENABLE= 130 | CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y 131 | CONFIG_AWS_IOT_SDK= 132 | 133 | # 134 | # Bluetooth 135 | # 136 | CONFIG_BT_ENABLED= 137 | CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 138 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 139 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 140 | CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 141 | CONFIG_BT_RESERVE_DRAM=0 142 | 143 | # 144 | # Driver configurations 145 | # 146 | 147 | # 148 | # ADC configuration 149 | # 150 | CONFIG_ADC_FORCE_XPD_FSM= 151 | CONFIG_ADC2_DISABLE_DAC=y 152 | 153 | # 154 | # SPI configuration 155 | # 156 | CONFIG_SPI_MASTER_IN_IRAM= 157 | CONFIG_SPI_MASTER_ISR_IN_IRAM=y 158 | CONFIG_SPI_SLAVE_IN_IRAM= 159 | CONFIG_SPI_SLAVE_ISR_IN_IRAM=y 160 | 161 | # 162 | # eFuse Bit Manager 163 | # 164 | CONFIG_EFUSE_CUSTOM_TABLE= 165 | CONFIG_EFUSE_VIRTUAL= 166 | CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE= 167 | CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y 168 | CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT= 169 | CONFIG_EFUSE_MAX_BLK_LEN=192 170 | 171 | # 172 | # ESP32-specific 173 | # 174 | CONFIG_IDF_TARGET_ESP32=y 175 | CONFIG_ESP32_DEFAULT_CPU_FREQ_80= 176 | CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y 177 | CONFIG_ESP32_DEFAULT_CPU_FREQ_240= 178 | CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 179 | CONFIG_SPIRAM_SUPPORT= 180 | CONFIG_MEMMAP_TRACEMEM= 181 | CONFIG_MEMMAP_TRACEMEM_TWOBANKS= 182 | CONFIG_ESP32_TRAX= 183 | CONFIG_TRACEMEM_RESERVE_DRAM=0x0 184 | CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= 185 | CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y 186 | CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 187 | CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 188 | CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 189 | CONFIG_MAIN_TASK_STACK_SIZE=3584 190 | CONFIG_IPC_TASK_STACK_SIZE=1024 191 | CONFIG_TIMER_TASK_STACK_SIZE=3584 192 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y 193 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= 194 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= 195 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= 196 | CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= 197 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y 198 | CONFIG_NEWLIB_NANO_FORMAT= 199 | CONFIG_CONSOLE_UART_DEFAULT=y 200 | CONFIG_CONSOLE_UART_CUSTOM= 201 | CONFIG_CONSOLE_UART_NONE= 202 | CONFIG_CONSOLE_UART_NUM=0 203 | CONFIG_CONSOLE_UART_BAUDRATE=115200 204 | CONFIG_ULP_COPROC_ENABLED= 205 | CONFIG_ULP_COPROC_RESERVE_MEM=0 206 | CONFIG_ESP32_PANIC_PRINT_HALT= 207 | CONFIG_ESP32_PANIC_PRINT_REBOOT=y 208 | CONFIG_ESP32_PANIC_SILENT_REBOOT= 209 | CONFIG_ESP32_PANIC_GDBSTUB= 210 | CONFIG_ESP32_DEBUG_OCDAWARE=y 211 | CONFIG_ESP32_DEBUG_STUBS_ENABLE=y 212 | CONFIG_INT_WDT=y 213 | CONFIG_INT_WDT_TIMEOUT_MS=300 214 | CONFIG_INT_WDT_CHECK_CPU1=y 215 | CONFIG_TASK_WDT= 216 | CONFIG_BROWNOUT_DET=y 217 | CONFIG_BROWNOUT_DET_LVL_SEL_0=y 218 | CONFIG_BROWNOUT_DET_LVL_SEL_1= 219 | CONFIG_BROWNOUT_DET_LVL_SEL_2= 220 | CONFIG_BROWNOUT_DET_LVL_SEL_3= 221 | CONFIG_BROWNOUT_DET_LVL_SEL_4= 222 | CONFIG_BROWNOUT_DET_LVL_SEL_5= 223 | CONFIG_BROWNOUT_DET_LVL_SEL_6= 224 | CONFIG_BROWNOUT_DET_LVL_SEL_7= 225 | CONFIG_BROWNOUT_DET_LVL=0 226 | CONFIG_REDUCE_PHY_TX_POWER=y 227 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y 228 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC= 229 | CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= 230 | CONFIG_ESP32_TIME_SYSCALL_USE_NONE= 231 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y 232 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= 233 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC= 234 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256= 235 | CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 236 | CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 237 | CONFIG_ESP32_XTAL_FREQ_40=y 238 | CONFIG_ESP32_XTAL_FREQ_26= 239 | CONFIG_ESP32_XTAL_FREQ_AUTO= 240 | CONFIG_ESP32_XTAL_FREQ=40 241 | CONFIG_DISABLE_BASIC_ROM_CONSOLE= 242 | CONFIG_NO_BLOBS= 243 | CONFIG_ESP_TIMER_PROFILING= 244 | CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= 245 | CONFIG_ESP_ERR_TO_NAME_LOOKUP= 246 | 247 | # 248 | # Wi-Fi 249 | # 250 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 251 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 252 | CONFIG_ESP32_WIFI_STATIC_TX_BUFFER= 253 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y 254 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 255 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 256 | CONFIG_ESP32_WIFI_CSI_ENABLED= 257 | CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y 258 | CONFIG_ESP32_WIFI_TX_BA_WIN=6 259 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y 260 | CONFIG_ESP32_WIFI_RX_BA_WIN=6 261 | CONFIG_ESP32_WIFI_NVS_ENABLED=y 262 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y 263 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1= 264 | CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 265 | CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 266 | CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE= 267 | CONFIG_ESP32_WIFI_IRAM_OPT=y 268 | 269 | # 270 | # PHY 271 | # 272 | CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y 273 | CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= 274 | CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 275 | CONFIG_ESP32_PHY_MAX_TX_POWER=20 276 | 277 | # 278 | # Power Management 279 | # 280 | CONFIG_PM_ENABLE= 281 | 282 | # 283 | # ADC-Calibration 284 | # 285 | CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y 286 | CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y 287 | CONFIG_ADC_CAL_LUT_ENABLE=y 288 | 289 | # 290 | # Event Loop Library 291 | # 292 | CONFIG_EVENT_LOOP_PROFILING= 293 | 294 | # 295 | # ESP HTTP client 296 | # 297 | CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y 298 | 299 | # 300 | # HTTP Server 301 | # 302 | CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 303 | CONFIG_HTTPD_MAX_URI_LEN=512 304 | CONFIG_HTTPD_ERR_RESP_NO_DELAY=y 305 | 306 | # 307 | # ESP HTTPS OTA 308 | # 309 | CONFIG_OTA_ALLOW_HTTP= 310 | 311 | # 312 | # Core dump 313 | # 314 | CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= 315 | CONFIG_ESP32_ENABLE_COREDUMP_TO_UART= 316 | CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y 317 | CONFIG_ESP32_ENABLE_COREDUMP= 318 | 319 | # 320 | # Ethernet 321 | # 322 | CONFIG_DMA_RX_BUF_NUM=10 323 | CONFIG_DMA_TX_BUF_NUM=10 324 | CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE=y 325 | CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000 326 | CONFIG_EMAC_TASK_PRIORITY=20 327 | CONFIG_EMAC_TASK_STACK_SIZE=3072 328 | 329 | # 330 | # FAT Filesystem support 331 | # 332 | CONFIG_FATFS_CODEPAGE_DYNAMIC= 333 | CONFIG_FATFS_CODEPAGE_437=y 334 | CONFIG_FATFS_CODEPAGE_720= 335 | CONFIG_FATFS_CODEPAGE_737= 336 | CONFIG_FATFS_CODEPAGE_771= 337 | CONFIG_FATFS_CODEPAGE_775= 338 | CONFIG_FATFS_CODEPAGE_850= 339 | CONFIG_FATFS_CODEPAGE_852= 340 | CONFIG_FATFS_CODEPAGE_855= 341 | CONFIG_FATFS_CODEPAGE_857= 342 | CONFIG_FATFS_CODEPAGE_860= 343 | CONFIG_FATFS_CODEPAGE_861= 344 | CONFIG_FATFS_CODEPAGE_862= 345 | CONFIG_FATFS_CODEPAGE_863= 346 | CONFIG_FATFS_CODEPAGE_864= 347 | CONFIG_FATFS_CODEPAGE_865= 348 | CONFIG_FATFS_CODEPAGE_866= 349 | CONFIG_FATFS_CODEPAGE_869= 350 | CONFIG_FATFS_CODEPAGE_932= 351 | CONFIG_FATFS_CODEPAGE_936= 352 | CONFIG_FATFS_CODEPAGE_949= 353 | CONFIG_FATFS_CODEPAGE_950= 354 | CONFIG_FATFS_CODEPAGE=437 355 | CONFIG_FATFS_LFN_NONE=y 356 | CONFIG_FATFS_LFN_HEAP= 357 | CONFIG_FATFS_LFN_STACK= 358 | CONFIG_FATFS_FS_LOCK=0 359 | CONFIG_FATFS_TIMEOUT_MS=10000 360 | CONFIG_FATFS_PER_FILE_CACHE=y 361 | 362 | # 363 | # Modbus configuration 364 | # 365 | CONFIG_MB_QUEUE_LENGTH=20 366 | CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 367 | CONFIG_MB_SERIAL_BUF_SIZE=256 368 | CONFIG_MB_SERIAL_TASK_PRIO=10 369 | CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT= 370 | CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 371 | CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 372 | CONFIG_MB_CONTROLLER_STACK_SIZE=4096 373 | CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 374 | CONFIG_MB_TIMER_PORT_ENABLED=y 375 | CONFIG_MB_TIMER_GROUP=0 376 | CONFIG_MB_TIMER_INDEX=0 377 | 378 | # 379 | # FreeRTOS 380 | # 381 | CONFIG_FREERTOS_UNICORE= 382 | CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF 383 | CONFIG_FREERTOS_CORETIMER_0=y 384 | CONFIG_FREERTOS_CORETIMER_1= 385 | CONFIG_FREERTOS_HZ=100 386 | CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y 387 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE= 388 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL=y 389 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY= 390 | CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= 391 | CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y 392 | CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 393 | CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y 394 | CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= 395 | CONFIG_FREERTOS_ASSERT_DISABLE= 396 | CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 397 | CONFIG_FREERTOS_ISR_STACKSIZE=1536 398 | CONFIG_FREERTOS_LEGACY_HOOKS= 399 | CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 400 | CONFIG_SUPPORT_STATIC_ALLOCATION= 401 | CONFIG_TIMER_TASK_PRIORITY=1 402 | CONFIG_TIMER_TASK_STACK_DEPTH=8192 403 | CONFIG_TIMER_QUEUE_LENGTH=10 404 | CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 405 | CONFIG_FREERTOS_USE_TRACE_FACILITY= 406 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= 407 | CONFIG_FREERTOS_DEBUG_INTERNALS= 408 | CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y 409 | 410 | # 411 | # Heap memory debugging 412 | # 413 | CONFIG_HEAP_POISONING_DISABLED= 414 | CONFIG_HEAP_POISONING_LIGHT= 415 | CONFIG_HEAP_POISONING_COMPREHENSIVE=y 416 | CONFIG_HEAP_TRACING=y 417 | CONFIG_HEAP_TRACING_STACK_DEPTH=2 418 | CONFIG_HEAP_TASK_TRACKING=y 419 | 420 | # 421 | # libsodium 422 | # 423 | 424 | # 425 | # Log output 426 | # 427 | CONFIG_LOG_DEFAULT_LEVEL_NONE= 428 | CONFIG_LOG_DEFAULT_LEVEL_ERROR= 429 | CONFIG_LOG_DEFAULT_LEVEL_WARN= 430 | CONFIG_LOG_DEFAULT_LEVEL_INFO= 431 | CONFIG_LOG_DEFAULT_LEVEL_DEBUG= 432 | CONFIG_LOG_DEFAULT_LEVEL_VERBOSE=y 433 | CONFIG_LOG_DEFAULT_LEVEL=5 434 | CONFIG_LOG_COLORS=y 435 | 436 | # 437 | # LWIP 438 | # 439 | CONFIG_L2_TO_L3_COPY= 440 | CONFIG_LWIP_IRAM_OPTIMIZATION= 441 | CONFIG_LWIP_MAX_SOCKETS=10 442 | CONFIG_USE_ONLY_LWIP_SELECT= 443 | CONFIG_LWIP_SO_REUSE=y 444 | CONFIG_LWIP_SO_REUSE_RXTOALL=y 445 | CONFIG_LWIP_SO_RCVBUF= 446 | CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 447 | CONFIG_LWIP_IP_FRAG= 448 | CONFIG_LWIP_IP_REASSEMBLY= 449 | CONFIG_LWIP_STATS= 450 | CONFIG_LWIP_ETHARP_TRUST_IP_MAC= 451 | CONFIG_ESP_GRATUITOUS_ARP=y 452 | CONFIG_GARP_TMR_INTERVAL=60 453 | CONFIG_TCPIP_RECVMBOX_SIZE=32 454 | CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y 455 | CONFIG_LWIP_DHCP_RESTORE_LAST_IP= 456 | 457 | # 458 | # DHCP server 459 | # 460 | CONFIG_LWIP_DHCPS_LEASE_UNIT=60 461 | CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 462 | CONFIG_LWIP_AUTOIP= 463 | CONFIG_LWIP_NETIF_LOOPBACK=y 464 | CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 465 | 466 | # 467 | # TCP 468 | # 469 | CONFIG_LWIP_MAX_ACTIVE_TCP=16 470 | CONFIG_LWIP_MAX_LISTENING_TCP=16 471 | CONFIG_TCP_MAXRTX=12 472 | CONFIG_TCP_SYNMAXRTX=6 473 | CONFIG_TCP_MSS=1436 474 | CONFIG_TCP_MSL=60000 475 | CONFIG_TCP_SND_BUF_DEFAULT=5744 476 | CONFIG_TCP_WND_DEFAULT=5744 477 | CONFIG_TCP_RECVMBOX_SIZE=6 478 | CONFIG_TCP_QUEUE_OOSEQ=y 479 | CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES= 480 | CONFIG_TCP_OVERSIZE_MSS=y 481 | CONFIG_TCP_OVERSIZE_QUARTER_MSS= 482 | CONFIG_TCP_OVERSIZE_DISABLE= 483 | 484 | # 485 | # UDP 486 | # 487 | CONFIG_LWIP_MAX_UDP_PCBS=16 488 | CONFIG_UDP_RECVMBOX_SIZE=6 489 | CONFIG_TCPIP_TASK_STACK_SIZE=4096 490 | CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y 491 | CONFIG_TCPIP_TASK_AFFINITY_CPU0= 492 | CONFIG_TCPIP_TASK_AFFINITY_CPU1= 493 | CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF 494 | CONFIG_PPP_SUPPORT= 495 | 496 | # 497 | # ICMP 498 | # 499 | CONFIG_LWIP_MULTICAST_PING= 500 | CONFIG_LWIP_BROADCAST_PING= 501 | 502 | # 503 | # LWIP RAW API 504 | # 505 | CONFIG_LWIP_MAX_RAW_PCBS=16 506 | 507 | # 508 | # mbedTLS 509 | # 510 | CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y 511 | CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC= 512 | CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= 513 | CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 514 | CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= 515 | CONFIG_MBEDTLS_DEBUG=y 516 | CONFIG_MBEDTLS_HARDWARE_AES=y 517 | CONFIG_MBEDTLS_HARDWARE_MPI= 518 | CONFIG_MBEDTLS_HARDWARE_SHA=y 519 | CONFIG_MBEDTLS_HAVE_TIME=y 520 | CONFIG_MBEDTLS_HAVE_TIME_DATE=y 521 | CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT= 522 | CONFIG_MBEDTLS_TLS_SERVER_ONLY= 523 | CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y 524 | CONFIG_MBEDTLS_TLS_DISABLED= 525 | CONFIG_MBEDTLS_TLS_CLIENT=y 526 | CONFIG_MBEDTLS_TLS_ENABLED=y 527 | 528 | # 529 | # TLS Key Exchange Methods 530 | # 531 | CONFIG_MBEDTLS_PSK_MODES= 532 | CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y 533 | CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y 534 | CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y 535 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y 536 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y 537 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y 538 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y 539 | CONFIG_MBEDTLS_SSL_RENEGOTIATION=y 540 | CONFIG_MBEDTLS_SSL_PROTO_SSL3= 541 | CONFIG_MBEDTLS_SSL_PROTO_TLS1= 542 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y 543 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y 544 | CONFIG_MBEDTLS_SSL_PROTO_DTLS= 545 | CONFIG_MBEDTLS_SSL_ALPN=y 546 | CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y 547 | 548 | # 549 | # Symmetric Ciphers 550 | # 551 | CONFIG_MBEDTLS_AES_C=y 552 | CONFIG_MBEDTLS_CAMELLIA_C=y 553 | CONFIG_MBEDTLS_DES_C= 554 | CONFIG_MBEDTLS_RC4_DISABLED=y 555 | CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= 556 | CONFIG_MBEDTLS_RC4_ENABLED= 557 | CONFIG_MBEDTLS_BLOWFISH_C= 558 | CONFIG_MBEDTLS_XTEA_C= 559 | CONFIG_MBEDTLS_CCM_C=y 560 | CONFIG_MBEDTLS_GCM_C=y 561 | CONFIG_MBEDTLS_RIPEMD160_C=y 562 | 563 | # 564 | # Certificates 565 | # 566 | CONFIG_MBEDTLS_PEM_PARSE_C=y 567 | CONFIG_MBEDTLS_PEM_WRITE_C=y 568 | CONFIG_MBEDTLS_X509_CRL_PARSE_C=y 569 | CONFIG_MBEDTLS_X509_CSR_PARSE_C=y 570 | CONFIG_MBEDTLS_ECP_C=y 571 | CONFIG_MBEDTLS_ECDH_C=y 572 | CONFIG_MBEDTLS_ECDSA_C=y 573 | CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y 574 | CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y 575 | CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y 576 | CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y 577 | CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y 578 | CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y 579 | CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y 580 | CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y 581 | CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y 582 | CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y 583 | CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y 584 | CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y 585 | CONFIG_MBEDTLS_ECP_NIST_OPTIM=y 586 | 587 | # 588 | # mDNS 589 | # 590 | CONFIG_MDNS_MAX_SERVICES=10 591 | 592 | # 593 | # ESP-MQTT Configurations 594 | # 595 | CONFIG_MQTT_PROTOCOL_311= 596 | CONFIG_MQTT_TRANSPORT_SSL= 597 | CONFIG_MQTT_TRANSPORT_WEBSOCKET= 598 | CONFIG_MQTT_USE_CUSTOM_CONFIG= 599 | CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED= 600 | CONFIG_MQTT_CUSTOM_OUTBOX= 601 | 602 | # 603 | # NVS 604 | # 605 | 606 | # 607 | # OpenSSL 608 | # 609 | CONFIG_OPENSSL_DEBUG=y 610 | CONFIG_OPENSSL_DEBUG_LEVEL=0 611 | CONFIG_OPENSSL_LOWLEVEL_DEBUG= 612 | CONFIG_OPENSSL_ASSERT_DO_NOTHING=y 613 | CONFIG_OPENSSL_ASSERT_EXIT= 614 | CONFIG_OPENSSL_ASSERT_DEBUG= 615 | CONFIG_OPENSSL_ASSERT_DEBUG_EXIT= 616 | CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK= 617 | 618 | # 619 | # PThreads 620 | # 621 | CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 622 | CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 623 | CONFIG_PTHREAD_STACK_MIN=768 624 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y 625 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0= 626 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1= 627 | CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 628 | CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" 629 | 630 | # 631 | # SPI Flash driver 632 | # 633 | CONFIG_SPI_FLASH_VERIFY_WRITE= 634 | CONFIG_SPI_FLASH_ENABLE_COUNTERS= 635 | CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y 636 | 637 | # 638 | # SPIFFS Configuration 639 | # 640 | CONFIG_SPIFFS_MAX_PARTITIONS=3 641 | 642 | # 643 | # SPIFFS Cache Configuration 644 | # 645 | CONFIG_SPIFFS_CACHE=y 646 | CONFIG_SPIFFS_CACHE_WR=y 647 | CONFIG_SPIFFS_CACHE_STATS= 648 | CONFIG_SPIFFS_PAGE_CHECK=y 649 | CONFIG_SPIFFS_GC_MAX_RUNS=10 650 | CONFIG_SPIFFS_GC_STATS= 651 | CONFIG_SPIFFS_PAGE_SIZE=256 652 | CONFIG_SPIFFS_OBJ_NAME_LEN=32 653 | CONFIG_SPIFFS_USE_MAGIC=y 654 | CONFIG_SPIFFS_USE_MAGIC_LENGTH=y 655 | CONFIG_SPIFFS_META_LENGTH=4 656 | CONFIG_SPIFFS_USE_MTIME=y 657 | 658 | # 659 | # Debug Configuration 660 | # 661 | CONFIG_SPIFFS_DBG= 662 | CONFIG_SPIFFS_API_DBG= 663 | CONFIG_SPIFFS_GC_DBG= 664 | CONFIG_SPIFFS_CACHE_DBG= 665 | CONFIG_SPIFFS_CHECK_DBG= 666 | CONFIG_SPIFFS_TEST_VISUALISATION= 667 | 668 | # 669 | # TCP/IP Adapter 670 | # 671 | CONFIG_IP_LOST_TIMER_INTERVAL=120 672 | CONFIG_TCPIP_LWIP=y 673 | 674 | # 675 | # Unity unit testing library 676 | # 677 | CONFIG_UNITY_ENABLE_FLOAT=y 678 | CONFIG_UNITY_ENABLE_DOUBLE=y 679 | CONFIG_UNITY_ENABLE_COLOR= 680 | CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y 681 | CONFIG_UNITY_ENABLE_FIXTURE= 682 | 683 | # 684 | # Virtual file system 685 | # 686 | CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y 687 | CONFIG_SUPPORT_TERMIOS=y 688 | 689 | # 690 | # Wear Levelling 691 | # 692 | CONFIG_WL_SECTOR_SIZE_512= 693 | CONFIG_WL_SECTOR_SIZE_4096=y 694 | CONFIG_WL_SECTOR_SIZE=4096 695 | -------------------------------------------------------------------------------- /src/app.rs: -------------------------------------------------------------------------------- 1 | use crate::error::{err, err_check, EspError}; 2 | use crate::log; 3 | use crate::log::Level; 4 | use crate::timer; 5 | 6 | use esp32_sys::*; 7 | 8 | use core::ffi::c_void; 9 | 10 | pub struct Application { 11 | timer: timer::Timer, 12 | 13 | ssid: &'static str, 14 | password: &'static str, 15 | 16 | event_group: EventGroupHandle_t, 17 | 18 | retry_num: u32, 19 | } 20 | 21 | fn nvs_init() -> Result<(), EspError> { 22 | unsafe { 23 | let mut ret = nvs_flash_init(); 24 | if ret == ESP_ERR_NVS_NO_FREE_PAGES as i32 || ret == ESP_ERR_NVS_NEW_VERSION_FOUND as i32 { 25 | log::log( 26 | Level::INFO, 27 | &TAG, 28 | format_args!("Need to erase flash: rc = {}", ret), 29 | ); 30 | err(nvs_flash_erase())?; 31 | ret = nvs_flash_init(); 32 | } 33 | err(ret) 34 | } 35 | } 36 | 37 | const WIFI_CONNECTED_BIT: u32 = BIT0; 38 | const APP_ESP_MAXIMUM_RETRY: u32 = 10u32; 39 | const TAG: &'static [u8] = b"app\0"; 40 | 41 | unsafe fn default_config() -> wifi_init_config_t { 42 | wifi_init_config_t { 43 | event_handler: Some(esp_event_send), 44 | osi_funcs: &mut g_wifi_osi_funcs, 45 | wpa_crypto_funcs: g_wifi_default_wpa_crypto_funcs, 46 | static_rx_buf_num: CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM as i32, 47 | dynamic_rx_buf_num: CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM as i32, 48 | tx_buf_type: CONFIG_ESP32_WIFI_TX_BUFFER_TYPE as i32, 49 | static_tx_buf_num: WIFI_STATIC_TX_BUFFER_NUM as i32, 50 | dynamic_tx_buf_num: WIFI_DYNAMIC_TX_BUFFER_NUM as i32, 51 | csi_enable: WIFI_CSI_ENABLED as i32, 52 | ampdu_rx_enable: WIFI_AMPDU_RX_ENABLED as i32, 53 | ampdu_tx_enable: WIFI_AMPDU_TX_ENABLED as i32, 54 | nvs_enable: WIFI_NVS_ENABLED as i32, 55 | nano_enable: WIFI_NANO_FORMAT_ENABLED as i32, 56 | tx_ba_win: WIFI_DEFAULT_TX_BA_WIN as i32, 57 | rx_ba_win: WIFI_DEFAULT_RX_BA_WIN as i32, 58 | wifi_task_core_id: WIFI_TASK_CORE_ID as i32, 59 | beacon_max_len: WIFI_SOFTAP_BEACON_MAX_LEN as i32, 60 | mgmt_sbuf_num: WIFI_MGMT_SBUF_NUM as i32, 61 | magic: WIFI_INIT_CONFIG_MAGIC as i32, 62 | } 63 | } 64 | 65 | unsafe extern "C" fn event_handler(ctx: *mut cty::c_void, event: *mut system_event_t) -> esp_err_t { 66 | log::log( 67 | Level::INFO, 68 | &TAG, 69 | format_args!("event_handler - {}", (*event).event_id), 70 | ); 71 | 72 | let app: *mut Application = ctx as *mut Application; 73 | let app: &mut Application = &mut *app; 74 | 75 | app.event_handler(&*event) 76 | .map_or_else(|e| e.code(), |_| ESP_OK as i32) 77 | } 78 | 79 | 80 | const SNTP_SERVER_NAME: &'static [u8] = b"0.pool.ntp.org\0"; 81 | 82 | unsafe fn wifi_init_sta(app: &mut Application, ssid: &'static str, password: &'static str) { 83 | log::log( 84 | Level::INFO, 85 | &TAG, 86 | format_args!("STA - SSID: {:?}, password: {:?}", ssid, password), 87 | ); 88 | 89 | log::log(Level::INFO, &TAG, format_args!("Init TCP/IP")); 90 | 91 | tcpip_adapter_init(); 92 | 93 | log::log(Level::INFO, &TAG, format_args!("Init event loop")); 94 | 95 | err_check(esp_event_loop_init( 96 | Some(event_handler), 97 | (app as *mut Application) as *mut c_void, 98 | )); 99 | 100 | let cfg = default_config(); 101 | 102 | log::log(Level::INFO, &TAG, format_args!("Init wifi")); 103 | 104 | err_check(esp_wifi_init(&cfg)); 105 | 106 | log::log(Level::INFO, &TAG, format_args!("Wifi initialized")); 107 | 108 | let mut fixed_ssid: [u8; 32] = [0; 32]; 109 | { 110 | let b = ssid.as_bytes(); 111 | fixed_ssid.split_at_mut(b.len()).0.copy_from_slice(b); 112 | } 113 | 114 | let mut fixed_password: [u8; 64] = [0; 64]; 115 | { 116 | let b = password.as_bytes(); 117 | fixed_password.split_at_mut(b.len()).0.copy_from_slice(b); 118 | } 119 | 120 | log::log( 121 | Level::DEBUG, 122 | &TAG, 123 | format_args!( 124 | "SSID: {:?} Password: {:?}", 125 | &fixed_ssid[..], 126 | &fixed_password[..] 127 | ), 128 | ); 129 | 130 | let mut wifi_config = wifi_config_t { 131 | sta: wifi_sta_config_t { 132 | ssid: fixed_ssid, 133 | password: fixed_password, 134 | 135 | bssid_set: false, 136 | bssid: [0, 0, 0, 0, 0, 0], 137 | 138 | channel: 0, 139 | listen_interval: 0, 140 | scan_method: wifi_scan_method_t_WIFI_FAST_SCAN, 141 | sort_method: wifi_sort_method_t_WIFI_CONNECT_AP_BY_SIGNAL, 142 | threshold: wifi_fast_scan_threshold_t { 143 | rssi: 0, 144 | authmode: wifi_auth_mode_t_WIFI_AUTH_OPEN, 145 | }, 146 | }, 147 | }; 148 | 149 | log::log(Level::INFO, &TAG, format_args!("Wifi set mode")); 150 | err_check(esp_wifi_set_mode(wifi_mode_t_WIFI_MODE_STA)); 151 | log::log(Level::INFO, &TAG, format_args!("Wifi set config")); 152 | err_check(esp_wifi_set_config( 153 | esp_interface_t_ESP_IF_WIFI_STA, 154 | &mut wifi_config, 155 | )); 156 | 157 | log::log(Level::INFO, &TAG, format_args!("Start wifi")); 158 | 159 | err_check(esp_wifi_start()); 160 | 161 | log::log(Level::INFO, &TAG, format_args!("Wifi started")); 162 | 163 | sntp_setoperatingmode(SNTP_OPMODE_POLL as _); 164 | sntp_setservername(0, SNTP_SERVER_NAME.as_ptr() as _); 165 | sntp_init(); 166 | 167 | } 168 | 169 | impl Application { 170 | pub fn new(ssid: &'static str, password: &'static str, ticked: F) -> Application 171 | where 172 | F: FnMut() + 'static, 173 | { 174 | let event_group = unsafe { xEventGroupCreate() }; 175 | 176 | Application { 177 | ssid, 178 | password, 179 | event_group, 180 | retry_num: 0, 181 | timer: timer::Timer::new(200, true, ticked), 182 | } 183 | } 184 | 185 | pub fn run(&mut self) -> ! { 186 | nvs_init().expect("Failed to init NVS"); 187 | unsafe { 188 | wifi_init_sta(self, self.ssid, self.password); 189 | loop { 190 | ets_delay_us(1_000_000); 191 | } 192 | } 193 | } 194 | 195 | fn event_handler(&mut self, event: &system_event_t) -> Result<(), EspError> { 196 | #[allow(non_upper_case_globals)] 197 | match event.event_id { 198 | system_event_id_t_SYSTEM_EVENT_STA_START => { 199 | log::log(Level::INFO, &TAG, format_args!("Started")); 200 | 201 | unsafe { 202 | esp_wifi_connect(); 203 | } 204 | } 205 | system_event_id_t_SYSTEM_EVENT_STA_GOT_IP => { 206 | log::log(Level::INFO, &TAG, format_args!("Got IP")); 207 | self.retry_num = 0; 208 | 209 | unsafe { 210 | xEventGroupSetBits(self.event_group, WIFI_CONNECTED_BIT); 211 | } 212 | 213 | log::log(Level::DEBUG, &TAG, format_args!("Starting timer")); 214 | self.timer.start(); 215 | log::log(Level::DEBUG, &TAG, format_args!("Timer started")); 216 | } 217 | system_event_id_t_SYSTEM_EVENT_STA_DISCONNECTED => { 218 | log::log( 219 | Level::INFO, 220 | &TAG, 221 | format_args!("Disconnected - retry: {}", self.retry_num), 222 | ); 223 | log::log(Level::DEBUG, &TAG, format_args!("Stopping timer")); 224 | self.timer.stop_non_blocking(); 225 | log::log(Level::DEBUG, &TAG, format_args!("Timer stopped")); 226 | if self.retry_num < APP_ESP_MAXIMUM_RETRY { 227 | unsafe { 228 | esp_wifi_connect(); 229 | xEventGroupClearBits(self.event_group, WIFI_CONNECTED_BIT); 230 | } 231 | self.retry_num += 1; 232 | } 233 | } 234 | _ => {} 235 | }; 236 | 237 | Ok(()) 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | 3 | use esp32_sys::*; 4 | 5 | #[derive(Debug)] 6 | pub struct EspError { 7 | code: i32, 8 | } 9 | 10 | impl EspError { 11 | pub fn code(&self) -> i32 { 12 | self.code 13 | } 14 | } 15 | 16 | impl fmt::Display for EspError { 17 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 18 | write!(f, "code: {}", self.code) 19 | } 20 | } 21 | 22 | impl From for EspError { 23 | fn from(e: i32) -> Self { 24 | EspError { code: e } 25 | } 26 | } 27 | 28 | impl From for EspError { 29 | fn from(_e: cstr_core::NulError) -> Self { 30 | EspError { code: 1 } 31 | } 32 | } 33 | 34 | impl From for EspError { 35 | fn from(_e: serde_json_core::ser::Error) -> Self { 36 | EspError { code: 2 } 37 | } 38 | } 39 | 40 | impl Into for EspError { 41 | fn into(self) -> i32 { 42 | self.code 43 | } 44 | } 45 | 46 | pub fn err_check(err: i32) { 47 | if err != ESP_OK as i32 { 48 | panic!("Failed - rc = {}", err); 49 | } 50 | } 51 | 52 | pub fn err(err: i32) -> Result<(), EspError> { 53 | if err != ESP_OK as i32 { 54 | return Err(err.into()); 55 | } else { 56 | return Ok(()); 57 | } 58 | } 59 | 60 | pub fn err_to_str(err: esp_err_t) -> &'static str { 61 | unsafe { 62 | let err = esp_err_to_name(err); 63 | 64 | return cstr_core::CStr::from_ptr(err).to_str().unwrap(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/http/config.rs: -------------------------------------------------------------------------------- 1 | use core::time::Duration; 2 | 3 | use core::default::Default; 4 | 5 | #[derive(Default)] 6 | pub struct HttpClientConfig<'a> { 7 | pub url: &'a str, 8 | pub username: Option<&'a str>, 9 | pub password: Option<&'a str>, 10 | pub method: Method, 11 | pub timeout: Duration, 12 | pub max_redirect: u8, 13 | pub authentication_type: Option, 14 | pub authentication_header: Option<&'a str>, 15 | pub cert_pem: Option<&'a str>, 16 | } 17 | 18 | // method 19 | 20 | pub enum Method { 21 | GET, 22 | PUT, 23 | POST, 24 | HEAD, 25 | DELETE, 26 | PATCH, 27 | } 28 | 29 | impl Default for Method { 30 | fn default() -> Self { 31 | Method::GET 32 | } 33 | } 34 | 35 | // auth type 36 | 37 | pub enum AuthenticationType { 38 | BASIC, 39 | DIGEST, 40 | } 41 | -------------------------------------------------------------------------------- /src/http/error.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | 3 | use esp32_sys::*; 4 | 5 | use cstr_core; 6 | 7 | #[derive(Debug)] 8 | pub struct Error { 9 | message: &'static str, 10 | } 11 | 12 | impl fmt::Display for Error { 13 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 14 | self.message.fmt(f) 15 | } 16 | } 17 | 18 | impl From<&'static str> for Error { 19 | fn from(e: &'static str) -> Self { 20 | Error { message: e } 21 | } 22 | } 23 | 24 | impl From for Error { 25 | fn from(_e: cstr_core::NulError) -> Self { 26 | Error { 27 | message: "Null byte in string", 28 | } 29 | } 30 | } 31 | 32 | impl From for Error { 33 | fn from(e: esp_err_t) -> Self { 34 | Error { 35 | message: err_to_str(e), 36 | } 37 | } 38 | } 39 | 40 | fn err_to_str(err: esp_err_t) -> &'static str { 41 | unsafe { 42 | let err = esp_err_to_name(err); 43 | 44 | return cstr_core::CStr::from_ptr(err).to_str().unwrap(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/http/mod.rs: -------------------------------------------------------------------------------- 1 | use core::ptr::*; 2 | use core::result; 3 | 4 | use cstr_core::CString; 5 | 6 | use esp32_sys::*; 7 | 8 | mod config; 9 | mod response; 10 | 11 | pub use self::config::*; 12 | pub use self::response::*; 13 | 14 | use crate::error::*; 15 | use crate::log; 16 | use crate::log::Level; 17 | 18 | use generic_array; 19 | 20 | const TAG: &'static [u8] = b"http\0"; 21 | 22 | pub type Result = result::Result; 23 | 24 | struct State { 25 | url: CString, 26 | username: Option, 27 | password: Option, 28 | cert_pem: Option, 29 | authentication_header: Option, 30 | } 31 | 32 | pub struct HttpClient { 33 | client: esp_http_client_handle_t, 34 | http_config: esp_http_client_config_t, 35 | state: State, 36 | } 37 | 38 | impl HttpClient { 39 | pub fn new(config: &HttpClientConfig) -> Result { 40 | let url = CString::new(config.url)?; 41 | 42 | let username = config.username.map(CString::new).transpose()?; 43 | let password = config.password.map(CString::new).transpose()?; 44 | let authentication_header = config.authentication_header.map(CString::new).transpose()?; 45 | 46 | let cert_pem = config.cert_pem.map(CString::new).transpose()?; 47 | 48 | let state = State { 49 | url, 50 | username, 51 | password, 52 | cert_pem, 53 | authentication_header, 54 | }; 55 | 56 | let (client, http_config) = Self::create(&state, config); 57 | 58 | Ok(HttpClient { 59 | client, 60 | http_config, 61 | state, 62 | }) 63 | } 64 | 65 | fn create( 66 | state: &State, 67 | config: &HttpClientConfig, 68 | ) -> (esp_http_client_handle_t, esp_http_client_config_t) { 69 | let method = match config.method { 70 | Method::GET => esp_http_client_method_t_HTTP_METHOD_GET, 71 | Method::POST => esp_http_client_method_t_HTTP_METHOD_POST, 72 | Method::PUT => esp_http_client_method_t_HTTP_METHOD_PUT, 73 | Method::DELETE => esp_http_client_method_t_HTTP_METHOD_DELETE, 74 | Method::HEAD => esp_http_client_method_t_HTTP_METHOD_HEAD, 75 | Method::PATCH => esp_http_client_method_t_HTTP_METHOD_PATCH, 76 | }; 77 | 78 | let auth_type = match config.authentication_type { 79 | None => esp_http_client_auth_type_t_HTTP_AUTH_TYPE_NONE, 80 | Some(AuthenticationType::BASIC) => esp_http_client_auth_type_t_HTTP_AUTH_TYPE_BASIC, 81 | Some(AuthenticationType::DIGEST) => esp_http_client_auth_type_t_HTTP_AUTH_TYPE_DIGEST, 82 | }; 83 | 84 | let username = match &state.password { 85 | Some(username) => username.as_ptr(), 86 | None => null(), 87 | }; 88 | 89 | let password = match &state.password { 90 | Some(password) => password.as_ptr(), 91 | None => null(), 92 | }; 93 | 94 | let use_global_ca_store = state.cert_pem.is_some(); 95 | let cert_pem = match &state.cert_pem { 96 | Some(cert_pem) => cert_pem.as_ptr(), 97 | None => null(), 98 | }; 99 | 100 | let http_config = esp_http_client_config_t { 101 | url: state.url.as_ptr(), 102 | host: null(), 103 | port: 0, 104 | username: username, 105 | password: password, 106 | auth_type, 107 | path: null(), 108 | query: null(), 109 | cert_pem: cert_pem, 110 | client_cert_pem: null(), 111 | client_key_pem: null(), 112 | method, 113 | timeout_ms: config.timeout.as_millis() as i32, 114 | disable_auto_redirect: false, 115 | max_redirection_count: config.max_redirect as i32, 116 | event_handler: None, 117 | transport_type: 0, 118 | buffer_size: 16 * 1024, 119 | user_data: null_mut(), 120 | is_async: false, 121 | use_global_ca_store, 122 | }; 123 | 124 | unsafe { 125 | return (esp_http_client_init(&http_config), http_config); 126 | } 127 | } 128 | 129 | pub fn send(&mut self) -> Result { 130 | unsafe { 131 | let err = esp_http_client_perform(self.client); 132 | 133 | if err == ESP_OK as _ { 134 | Ok(Response { 135 | status_code: esp_http_client_get_status_code(self.client) as _, 136 | }) 137 | } else { 138 | Err(err.into()) 139 | } 140 | } 141 | } 142 | 143 | pub fn send_json, T>( 144 | &mut self, 145 | payload: &T, 146 | ) -> Result 147 | where 148 | B: generic_array::ArrayLength, 149 | T: serde::ser::Serialize, 150 | { 151 | log::log(Level::INFO, &TAG, format_args!("Sending payload")); 152 | 153 | let payload = serde_json_core::ser::to_vec::(payload)?; 154 | 155 | log::log(Level::INFO, &TAG, format_args!("Payload encoded")); 156 | 157 | unsafe { 158 | log::log(Level::INFO, &TAG, format_args!("set content type header")); 159 | 160 | if let Some(authentication_header) = &self.state.authentication_header { 161 | esp_http_client_set_header( 162 | self.client, 163 | b"Authorization\0".as_ptr() as *const _, 164 | authentication_header.as_ptr(), 165 | ); 166 | } 167 | 168 | esp_http_client_set_header( 169 | self.client, 170 | b"Content-Type\0".as_ptr() as *const _, 171 | b"application/json\0".as_ptr() as *const _, 172 | ); 173 | 174 | log::log(Level::INFO, &TAG, format_args!("Set post data")); 175 | 176 | err(esp_http_client_set_post_field( 177 | self.client, 178 | payload.as_ptr() as *const _, 179 | payload.len() as _, 180 | ))?; 181 | 182 | log::log(Level::INFO, &TAG, format_args!("Perform HTTP request")); 183 | 184 | let err = esp_http_client_perform(self.client); 185 | 186 | if err == ESP_OK as _ { 187 | Ok(Response { 188 | status_code: esp_http_client_get_status_code(self.client) as _, 189 | }) 190 | } else { 191 | Err(err.into()) 192 | } 193 | } 194 | } 195 | } 196 | 197 | impl core::ops::Drop for HttpClient { 198 | fn drop(&mut self) { 199 | unsafe { 200 | esp_http_client_cleanup(self.client); 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/http/response.rs: -------------------------------------------------------------------------------- 1 | pub struct Response { 2 | pub status_code: u16, 3 | } 4 | -------------------------------------------------------------------------------- /src/letsencrypt.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ctron/rust-esp32-hono/e74f88daef6c1889be247ed5ca5a4bace23a8ca4/src/letsencrypt.der -------------------------------------------------------------------------------- /src/letsencrypt.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ 3 | MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT 4 | DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow 5 | SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT 6 | GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC 7 | AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF 8 | q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 9 | SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 10 | Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA 11 | a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj 12 | /PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T 13 | AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG 14 | CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv 15 | bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k 16 | c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw 17 | VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC 18 | ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz 19 | MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu 20 | Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF 21 | AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo 22 | uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ 23 | wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu 24 | X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG 25 | PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 26 | KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== 27 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /src/log/mod.rs: -------------------------------------------------------------------------------- 1 | use esp32_sys::*; 2 | 3 | use alloc::fmt; 4 | use core::fmt::Arguments; 5 | use cstr_core::{CStr, CString}; 6 | 7 | pub enum Level { 8 | DEBUG, 9 | INFO, 10 | WARN, 11 | ERROR, 12 | } 13 | 14 | pub fn log(level: Level, tag: &[u8], args: Arguments) { 15 | let c = CString::new(fmt::format(args)).expect(""); 16 | let (format, level) = match level { 17 | Level::ERROR => ("E (%d) %s: %s\n\0", esp_log_level_t_ESP_LOG_ERROR), 18 | Level::WARN => ("W (%d) %s: %s\n\0", esp_log_level_t_ESP_LOG_WARN), 19 | Level::INFO => ("I (%d) %s: %s\n\0", esp_log_level_t_ESP_LOG_INFO), 20 | Level::DEBUG => ("D (%d) %s: %s\n\0", esp_log_level_t_ESP_LOG_DEBUG), 21 | }; 22 | unsafe { 23 | let tag = CStr::from_bytes_with_nul_unchecked(tag); 24 | esp_log_write( 25 | level, 26 | tag.as_ptr() as *const i8, 27 | format.as_ptr() as *const i8, 28 | esp_log_timestamp(), 29 | tag.as_ptr(), 30 | c.as_ptr(), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![no_main] 3 | #![feature(alloc_error_handler)] 4 | #![feature(result_map_or_else)] 5 | 6 | extern crate cstr_core; 7 | extern crate esp32_sys; 8 | extern crate esp_idf_alloc; 9 | 10 | extern crate alloc; 11 | 12 | #[global_allocator] 13 | static A: esp_idf_alloc::EspIdfAllocator = esp_idf_alloc::EspIdfAllocator; 14 | 15 | use core::alloc::Layout; 16 | 17 | extern "C" { 18 | fn abort() -> !; 19 | } 20 | 21 | #[alloc_error_handler] 22 | fn alloc_error(_layout: Layout) -> ! { 23 | unsafe { 24 | abort(); 25 | } 26 | } 27 | 28 | use core::panic::PanicInfo; 29 | use esp32_sys::*; 30 | 31 | mod error; 32 | mod http; 33 | pub mod log; 34 | pub mod timer; 35 | mod uart; 36 | 37 | mod app; 38 | 39 | use log::Level; 40 | use serde::{Deserialize, Serialize}; 41 | 42 | const TAG: &'static [u8] = b"app\0"; 43 | 44 | #[panic_handler] 45 | fn panic(info: &PanicInfo) -> ! { 46 | log::log(Level::ERROR, &TAG, format_args!("{}", info)); 47 | loop {} 48 | } 49 | 50 | extern "C" { 51 | fn temprature_sens_read() -> u8; 52 | } 53 | 54 | fn temperate_sensor_read() -> f32 { 55 | unsafe { 56 | // as f32, to DegC 57 | temprature_sens_read() as f32 - 32.0 / 1.8 58 | } 59 | } 60 | 61 | const WIFI_SSID: &str = "xx"; 62 | const WIFI_PASSWORD: &str = "xx"; 63 | const HONO_HTTP_ADAPTER_URL: &str = 64 | "https://iot-http-adapter-enmasse-infra.apps.wonderful.iot-playground.org/telemetry"; 65 | const HONO_DEVICE_AUTH_ID: &str = "xx@rhte2019.iot"; 66 | const HONO_DEVICE_PASSWORD: &str = "xx"; 67 | const HONO_AUTH_HEADER: &str = "Basic xx"; 68 | 69 | #[derive(Serialize, Deserialize, Debug)] 70 | pub struct TelemetryPayload { 71 | temp: f32, 72 | } 73 | 74 | fn publish_telemetry(client: &mut http::HttpClient, temp: f32) -> http::Result { 75 | let payload = TelemetryPayload { temp: temp }; 76 | client.send_json::(&payload) 77 | } 78 | 79 | /// Initialize the global CA store with the Let's Encrypt 80 | /// Certificate in the DER format. 81 | fn init_global_ca_store() { 82 | let cert = include_bytes!("letsencrypt.der"); 83 | 84 | unsafe { 85 | esp_tls_set_global_ca_store(cert.as_ptr(), cert.len() as _); 86 | } 87 | } 88 | 89 | #[no_mangle] 90 | pub fn app_main() { 91 | log::log(Level::INFO, &TAG, format_args!("Hello World")); 92 | 93 | init_global_ca_store(); 94 | 95 | let config = http::HttpClientConfig { 96 | url: HONO_HTTP_ADAPTER_URL, 97 | authentication_type: Some(http::AuthenticationType::BASIC), 98 | authentication_header: Some(HONO_AUTH_HEADER), 99 | method: http::Method::POST, 100 | ..Default::default() 101 | }; 102 | 103 | let mut http = http::HttpClient::new(&config).expect("Failed to init HTTP client"); 104 | 105 | let mut app = app::Application::new(WIFI_SSID, WIFI_PASSWORD, move || { 106 | let temp = temperate_sensor_read(); 107 | log::log(Level::INFO, &TAG, format_args!("Ticked: {}", temp)); 108 | if let Err(err) = publish_telemetry(&mut http, temp) { 109 | log::log( 110 | Level::ERROR, 111 | &TAG, 112 | format_args!("Failed to execute HTTP upload: {}", err), 113 | ); 114 | } 115 | }); 116 | 117 | app.run(); 118 | } 119 | -------------------------------------------------------------------------------- /src/timer.rs: -------------------------------------------------------------------------------- 1 | use alloc::boxed::Box; 2 | 3 | use core::ffi::c_void; 4 | use core::ptr::null_mut; 5 | use esp32_sys::*; 6 | 7 | use crate::log; 8 | use crate::log::Level; 9 | 10 | const TAG: &'static [u8] = b"timer\0"; 11 | 12 | struct TimerBase { 13 | callback: Box, 14 | } 15 | 16 | pub struct Timer { 17 | handle: TimerHandle_t, 18 | } 19 | 20 | impl Timer { 21 | pub fn new(period_ticks: u32, reload: bool, callback: F) -> Self 22 | where 23 | F: FnMut() + 'static, 24 | { 25 | let reload = match reload { 26 | true => 1u32, 27 | false => 0u32, 28 | }; 29 | 30 | let base = Box::new(TimerBase { 31 | callback: Box::new(callback), 32 | }); 33 | 34 | unsafe { 35 | let ptr = Box::into_raw(base) as *mut c_void; 36 | 37 | log::log(Level::DEBUG, &TAG, format_args!("Timer ptr: {:?}", ptr)); 38 | 39 | let timer = xTimerCreate( 40 | b"Timer\0".as_ptr() as *const i8, 41 | period_ticks, 42 | reload, 43 | ptr, 44 | Some(Timer::handler), 45 | ); 46 | 47 | log::log( 48 | Level::DEBUG, 49 | &TAG, 50 | format_args!("Created timer: {:?}", timer), 51 | ); 52 | 53 | Timer { handle: timer } 54 | } 55 | } 56 | 57 | unsafe extern "C" fn handler(handle: *mut c_void) { 58 | log::log( 59 | Level::DEBUG, 60 | &TAG, 61 | format_args!("Executing timer - handle: {:?}", handle), 62 | ); 63 | 64 | let ptr = pvTimerGetTimerID(handle); 65 | log::log( 66 | Level::DEBUG, 67 | &TAG, 68 | format_args!("Executing timer - ptr: {:?}", ptr), 69 | ); 70 | 71 | let timer: *mut TimerBase = ptr as *mut TimerBase; 72 | let timer: &mut TimerBase = &mut *timer; 73 | 74 | (timer.callback)(); 75 | 76 | log::log(Level::DEBUG, &TAG, format_args!("Timer executed")); 77 | } 78 | 79 | pub fn start(&mut self) { 80 | unsafe { 81 | xTimerGenericCommand( 82 | self.handle, 83 | 1, /*START*/ 84 | xTaskGetTickCount(), 85 | null_mut(), 86 | 0, 87 | ); 88 | } 89 | } 90 | 91 | pub fn stop_non_blocking(&mut self) { 92 | unsafe { 93 | xTimerGenericCommand(self.handle, 3 /*STOP*/, 0, null_mut(), 0); 94 | } 95 | } 96 | } 97 | 98 | impl core::ops::Drop for Timer { 99 | fn drop(&mut self) { 100 | log::log(Level::INFO, &TAG, format_args!("Dropping timer")); 101 | self.stop_non_blocking(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/uart/mod.rs: -------------------------------------------------------------------------------- 1 | use esp32_sys::*; 2 | 3 | use core::fmt::Write; 4 | 5 | pub struct Uart { 6 | pub port: uart_port_t, 7 | } 8 | 9 | impl Write for Uart { 10 | fn write_str(&mut self, output: &str) -> core::fmt::Result { 11 | unsafe { 12 | uart_write_bytes(self.port, output.as_ptr() as *const _, output.len()); 13 | } 14 | Ok(()) 15 | } 16 | } 17 | --------------------------------------------------------------------------------