diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 47051ac69..959a1b737 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -58,6 +58,7 @@ jobs: echo "::set-output name=short_ref::${BRANCHTRANSLATED}" echo "::set-output name=sha_short::SHA-$(git rev-parse --short=12 HEAD)" echo "::set-output name=version::${VERSION}" + build2: name: Build Simulator needs: refs @@ -101,6 +102,7 @@ jobs: with: name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }} path: output/${{ needs.refs.outputs.version }}/obkSimulator_${{ needs.refs.outputs.version }}.zip + build: name: Build needs: refs @@ -152,10 +154,52 @@ jobs: output/${{ needs.refs.outputs.version }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}_OTA.bin.xz.ota if-no-files-found: warn + build_idf: + name: Build IDF + needs: refs + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + platform: [OpenESP32, OpenESP32C3, OpenESP32C2, OpenESP32C6, OpenESP32S3, OpenESP32S2] + steps: + - name: Source checkout + uses: actions/checkout@v3 + with: + submodules: recursive + - uses: actions/setup-python@v2 + with: + python-version: '3.8' + architecture: 'x64' + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get -y install make cmake python3-venv + pip3 install pycryptodomex + pip3 install configobj + pip3 install toml + pip3 install fdt + - name: Run make + run: | + cd sdk/esp-idf + ./install.sh > /dev/null + . ./export.sh + . ./add_path.sh + cd ../.. + make APP_VERSION=${{ needs.refs.outputs.version }} APP_NAME=${{ matrix.platform }} ${{ matrix.platform }} + - name: Save build assets + uses: actions/upload-artifact@v3 + with: + name: ${{ env.APP_NAME }}_${{ needs.refs.outputs.version }} + path: | + output/${{ needs.refs.outputs.version }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}.img + output/${{ needs.refs.outputs.version }}/${{ matrix.platform }}_${{ needs.refs.outputs.version }}.factory.bin + if-no-files-found: warn + release: name: Semantic Release Images and Artifacts runs-on: ubuntu-20.04 - needs: [ refs, build, build2 ] + needs: [ refs, build, build_idf, build2 ] if: always() && needs.refs.outputs.new_release == 'true' && (github.ref == 'refs/heads/main' || github.ref_name == 'alpha') steps: - name: Source checkout diff --git a/.gitmodules b/.gitmodules index bf6442382..7bafa7abd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,7 @@ [submodule "sdk/OpenLN882H"] path = sdk/OpenLN882H url = https://github.com/openshwprojects/OpenLN882H.git +[submodule "sdk/esp-idf"] + path = sdk/esp-idf + url = https://github.com/espressif/esp-idf.git + branch = release/v5.3 diff --git a/Makefile b/Makefile index 3bbd24cd6..bf0577e36 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ else endif update-submodules: submodules - git add sdk/OpenBK7231T sdk/OpenBK7231N sdk/OpenXR809 sdk/OpenBL602 sdk/OpenW800 sdk/OpenW600 sdk/OpenLN882H + git add sdk/OpenBK7231T sdk/OpenBK7231N sdk/OpenXR809 sdk/OpenBL602 sdk/OpenW800 sdk/OpenW600 sdk/OpenLN882H sdk/esp-idf ifdef GITHUB_ACTIONS git config user.name github-actions git config user.email github-actions@github.com @@ -74,7 +74,7 @@ sdk/OpenLN882H/project/OpenBeken/app: @mkdir -p "sdk/OpenLN882H/project/OpenBeken" ln -s "$(shell pwd)/" "sdk/OpenLN882H/project/OpenBeken/app" -.PHONY: prebuild_OpenBK7231N prebuild_OpenBK7231T prebuild_OpenBL602 prebuild_OpenLN882H prebuild_OpenW600 prebuild_OpenW800 prebuild_OpenXR809 +.PHONY: prebuild_OpenBK7231N prebuild_OpenBK7231T prebuild_OpenBL602 prebuild_OpenLN882H prebuild_OpenW600 prebuild_OpenW800 prebuild_OpenXR809 prebuild_ESPIDF prebuild_OpenBK7231N: @if [ -e platforms/BK7231N/pre_build.sh ]; then \ @@ -83,7 +83,6 @@ prebuild_OpenBK7231N: else echo "prebuild for OpenBK7231N not found ... "; \ fi - prebuild_OpenBK7231T: @if [ -e platforms/BK7231T/pre_build.sh ]; then \ echo "prebuild found for OpenBK7231T"; \ @@ -91,7 +90,6 @@ prebuild_OpenBK7231T: else echo "prebuild for OpenBK7231T not found ... "; \ fi - prebuild_OpenBL602: @if [ -e platforms/BL602/pre_build.sh ]; then \ echo "prebuild found for OpenBL602"; \ @@ -99,7 +97,6 @@ prebuild_OpenBL602: else echo "prebuild for OpenBL602 not found ... "; \ fi - prebuild_OpenLN882H: @if [ -e platforms/LN882H/pre_build.sh ]; then \ echo "prebuild found for OpenLN882H"; \ @@ -107,7 +104,6 @@ prebuild_OpenLN882H: else echo "prebuild for OpenLN882H not found ... "; \ fi - prebuild_OpenW600: @if [ -e platforms/W600/pre_build.sh ]; then \ echo "prebuild found for OpenW600"; \ @@ -115,7 +111,6 @@ prebuild_OpenW600: else echo "prebuild for OpenW600 not found ... "; \ fi - prebuild_OpenW800: @if [ -e platforms/W800/pre_build.sh ]; then \ echo "prebuild found for OpenW800"; \ @@ -123,7 +118,6 @@ prebuild_OpenW800: else echo "prebuild for OpenW800 not found ... "; \ fi - prebuild_OpenXR809: @if [ -e platforms/XR809/pre_build.sh ]; then \ echo "prebuild found for OpenXR809"; \ @@ -131,10 +125,12 @@ prebuild_OpenXR809: else echo "prebuild for OpenXR809 not found ... "; \ fi - - - - +prebuild_ESPIDF: + @if [ -e platforms/ESP-IDF/pre_build.sh ]; then \ + echo "prebuild found for ESP-IDF"; \ + sh platforms/ESP-IDF/pre_build.sh; \ + else echo "prebuild for ESP-IDF not found ... "; \ + fi # Build main binaries OpenBK7231T: prebuild_OpenBK7231T @@ -209,6 +205,60 @@ OpenLN882H: submodules sdk/OpenLN882H/project/OpenBeken/app prebuild_OpenLN882H cp sdk/OpenLN882H/build/bin/flashimage.bin output/$(APP_VERSION)/OpenLN882H_$(APP_VERSION).bin cp sdk/OpenLN882H/build/bin/flashimage-ota-xz-v0.1.bin output/$(APP_VERSION)/OpenLN882H_$(APP_VERSION)_OTA.bin +.PHONY: OpenESP32 +OpenESP32: prebuild_ESPIDF + -rm platforms/ESP-IDF/sdkconfig + IDF_TARGET="esp32" USER_SW_VER=$(APP_VERSION) cmake platforms/ESP-IDF -B platforms/ESP-IDF/build-32 + IDF_TARGET="esp32" USER_SW_VER=$(APP_VERSION) cmake --build ./platforms/ESP-IDF/build-32 -j $(shell nproc) + mkdir -p output/$(APP_VERSION) + esptool.py -c esp32 merge_bin -o output/$(APP_VERSION)/OpenESP32_$(APP_VERSION).factory.bin --flash_mode dio --flash_size 4MB 0x1000 ./platforms/ESP-IDF/build-32/bootloader/bootloader.bin 0x8000 ./platforms/ESP-IDF/build-32/partition_table/partition-table.bin 0x10000 ./platforms/ESP-IDF/build-32/OpenBeken.bin + cp ./platforms/ESP-IDF/build-32/OpenBeken.bin output/$(APP_VERSION)/OpenESP32_$(APP_VERSION).img + +.PHONY: OpenESP32C3 +OpenESP32C3: prebuild_ESPIDF + -rm platforms/ESP-IDF/sdkconfig + IDF_TARGET="esp32c3" USER_SW_VER=$(APP_VERSION) cmake platforms/ESP-IDF -B platforms/ESP-IDF/build-c3 + IDF_TARGET="esp32c3" USER_SW_VER=$(APP_VERSION) cmake --build ./platforms/ESP-IDF/build-c3 -j $(shell nproc) + mkdir -p output/$(APP_VERSION) + esptool.py -c esp32c3 merge_bin -o output/$(APP_VERSION)/OpenESP32C3_$(APP_VERSION).factory.bin --flash_mode dio --flash_size 2MB 0x0 ./platforms/ESP-IDF/build-c3/bootloader/bootloader.bin 0x8000 ./platforms/ESP-IDF/build-c3/partition_table/partition-table.bin 0x10000 ./platforms/ESP-IDF/build-c3/OpenBeken.bin + cp ./platforms/ESP-IDF/build-c3/OpenBeken.bin output/$(APP_VERSION)/OpenESP32C3_$(APP_VERSION).img + +.PHONY: OpenESP32C2 +OpenESP32C2: prebuild_ESPIDF + -rm platforms/ESP-IDF/sdkconfig + IDF_TARGET="esp32c2" USER_SW_VER=$(APP_VERSION) cmake platforms/ESP-IDF -B platforms/ESP-IDF/build-c2 + IDF_TARGET="esp32c2" USER_SW_VER=$(APP_VERSION) cmake --build ./platforms/ESP-IDF/build-c2 -j $(shell nproc) + mkdir -p output/$(APP_VERSION) + esptool.py -c esp32c2 merge_bin -o output/$(APP_VERSION)/OpenESP32C2_$(APP_VERSION).factory.bin --flash_mode dio --flash_size 2MB 0x0 ./platforms/ESP-IDF/build-c2/bootloader/bootloader.bin 0x8000 ./platforms/ESP-IDF/build-c2/partition_table/partition-table.bin 0x10000 ./platforms/ESP-IDF/build-c2/OpenBeken.bin + cp ./platforms/ESP-IDF/build-c2/OpenBeken.bin output/$(APP_VERSION)/OpenESP32C2_$(APP_VERSION).img + +.PHONY: OpenESP32C6 +OpenESP32C6: prebuild_ESPIDF + -rm platforms/ESP-IDF/sdkconfig + IDF_TARGET="esp32c6" USER_SW_VER=$(APP_VERSION) cmake platforms/ESP-IDF -B platforms/ESP-IDF/build-c6 + IDF_TARGET="esp32c6" USER_SW_VER=$(APP_VERSION) cmake --build ./platforms/ESP-IDF/build-c6 -j $(shell nproc) + mkdir -p output/$(APP_VERSION) + esptool.py -c esp32c6 merge_bin -o output/$(APP_VERSION)/OpenESP32C6_$(APP_VERSION).factory.bin --flash_mode dio --flash_size 4MB 0x0 ./platforms/ESP-IDF/build-c6/bootloader/bootloader.bin 0x8000 ./platforms/ESP-IDF/build-c6/partition_table/partition-table.bin 0x10000 ./platforms/ESP-IDF/build-c6/OpenBeken.bin + cp ./platforms/ESP-IDF/build-c6/OpenBeken.bin output/$(APP_VERSION)/OpenESP32C6_$(APP_VERSION).img + +.PHONY: OpenESP32S2 +OpenESP32S2: prebuild_ESPIDF + -rm platforms/ESP-IDF/sdkconfig + IDF_TARGET="esp32s2" USER_SW_VER=$(APP_VERSION) cmake platforms/ESP-IDF -B platforms/ESP-IDF/build-s2 + IDF_TARGET="esp32s2" USER_SW_VER=$(APP_VERSION) cmake --build ./platforms/ESP-IDF/build-s2 -j $(shell nproc) + mkdir -p output/$(APP_VERSION) + esptool.py -c esp32s2 merge_bin -o output/$(APP_VERSION)/OpenESP32S2_$(APP_VERSION).factory.bin --flash_mode dio --flash_size 4MB 0x1000 ./platforms/ESP-IDF/build-s2/bootloader/bootloader.bin 0x8000 ./platforms/ESP-IDF/build-s2/partition_table/partition-table.bin 0x10000 ./platforms/ESP-IDF/build-s2/OpenBeken.bin + cp ./platforms/ESP-IDF/build-s2/OpenBeken.bin output/$(APP_VERSION)/OpenESP32S2_$(APP_VERSION).img + +.PHONY: OpenESP32S3 +OpenESP32S3: prebuild_ESPIDF + -rm platforms/ESP-IDF/sdkconfig + IDF_TARGET="esp32s3" USER_SW_VER=$(APP_VERSION) cmake platforms/ESP-IDF -B platforms/ESP-IDF/build-s3 + IDF_TARGET="esp32s3" USER_SW_VER=$(APP_VERSION) cmake --build ./platforms/ESP-IDF/build-s3 -j $(shell nproc) + mkdir -p output/$(APP_VERSION) + esptool.py -c esp32s3 merge_bin -o output/$(APP_VERSION)/OpenESP32S3_$(APP_VERSION).factory.bin --flash_mode dio --flash_size 4MB 0x0 ./platforms/ESP-IDF/build-s3/bootloader/bootloader.bin 0x8000 ./platforms/ESP-IDF/build-s3/partition_table/partition-table.bin 0x10000 ./platforms/ESP-IDF/build-s3/OpenBeken.bin + cp ./platforms/ESP-IDF/build-s3/OpenBeken.bin output/$(APP_VERSION)/OpenESP32S3_$(APP_VERSION).img + # clean .o files and output directory .PHONY: clean clean: @@ -219,6 +269,12 @@ clean: $(MAKE) -C sdk/OpenW800 clean $(MAKE) -C sdk/OpenW600 clean test -d ./sdk/OpenLN882H/build && cmake --build ./sdk/OpenLN882H/build --target clean + test -d ./platforms/ESP-IDF/build-32 && cmake --build ./platforms/ESP-IDF/build-32 --target clean + test -d ./platforms/ESP-IDF/build-c3 && cmake --build ./platforms/ESP-IDF/build-c3 --target clean + test -d ./platforms/ESP-IDF/build-c2 && cmake --build ./platforms/ESP-IDF/build-c2 --target clean + test -d ./platforms/ESP-IDF/build-c6 && cmake --build ./platforms/ESP-IDF/build-c6 --target clean + test -d ./platforms/ESP-IDF/build-s2 && cmake --build ./platforms/ESP-IDF/build-s2 --target clean + test -d ./platforms/ESP-IDF/build-s3 && cmake --build ./platforms/ESP-IDF/build-s3 --target clean # Add custom Makefile if required -include custom.mk diff --git a/platforms/ESP-IDF/.gitignore b/platforms/ESP-IDF/.gitignore new file mode 100644 index 000000000..26fad58aa --- /dev/null +++ b/platforms/ESP-IDF/.gitignore @@ -0,0 +1,2 @@ +build* +sdkconfig \ No newline at end of file diff --git a/platforms/ESP-IDF/CMakeLists.txt b/platforms/ESP-IDF/CMakeLists.txt new file mode 100644 index 000000000..fe64132ce --- /dev/null +++ b/platforms/ESP-IDF/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.16.0) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +add_compile_definitions(PLATFORM_ESPIDF=1) +add_compile_definitions(MQTT_OUTPUT_RINGBUF_SIZE=2048) +add_compile_definitions(MQTT_VAR_HEADER_BUFFER_LEN=256) +add_compile_definitions(MQTT_REQ_MAX_IN_FLIGHT=16) +add_compile_definitions(LWIP_NOASSERT=1) +add_definitions( -DUSER_SW_VER="$ENV{USER_SW_VER}" ) +set(PROJECT_VER "$ENV{USER_SW_VER}") +project(OpenBeken) +idf_build_set_property(COMPILE_OPTIONS "-Wno-format-truncation" APPEND) \ No newline at end of file diff --git a/platforms/ESP-IDF/main/CMakeLists.txt b/platforms/ESP-IDF/main/CMakeLists.txt new file mode 100644 index 000000000..30e2fb316 --- /dev/null +++ b/platforms/ESP-IDF/main/CMakeLists.txt @@ -0,0 +1,131 @@ +set(PROJ_ALL_SRC + ../../../src/base64/base64.c + ../../../src/bitmessage/bitmessage_read.c + ../../../src/bitmessage/bitmessage_write.c + ../../../src/cJSON/cJSON.c + ../../../src/cmnds/cmd_channels.c + ../../../src/cmnds/cmd_eventHandlers.c + ../../../src/cmnds/cmd_if.c + ../../../src/cmnds/cmd_main.c + ../../../src/cmnds/cmd_newLEDDriver_colors.c + ../../../src/cmnds/cmd_newLEDDriver.c + ../../../src/cmnds/cmd_repeatingEvents.c + ../../../src/cmnds/cmd_script.c +# ../../../src/cmnds/cmd_send.c + ../../../src/cmnds/cmd_simulatorOnly.c + ../../../src/cmnds/cmd_tasmota.c + ../../../src/cmnds/cmd_tcp.c + ../../../src/cmnds/cmd_test.c + ../../../src/cmnds/cmd_tokenizer.c + ../../../src/devicegroups/deviceGroups_read.c + ../../../src/devicegroups/deviceGroups_util.c + ../../../src/devicegroups/deviceGroups_write.c + ../../../src/driver/drv_adcButton.c + ../../../src/driver/drv_adcSmoother.c + ../../../src/driver/drv_aht2x.c + ../../../src/driver/drv_battery.c + ../../../src/driver/drv_bl_shared.c + ../../../src/driver/drv_bl0937.c +# ../../../src/driver/drv_bl0942.c + ../../../src/driver/drv_bmp280.c + ../../../src/driver/drv_bmpi2c.c + ../../../src/driver/drv_bp1658cj.c + ../../../src/driver/drv_bp5758d.c + ../../../src/driver/drv_bridge_driver.c + ../../../src/driver/drv_chargingLimit.c + ../../../src/driver/drv_charts.c + ../../../src/driver/drv_cht8305.c + ../../../src/driver/drv_cse7766.c + ../../../src/driver/drv_ddp.c + ../../../src/driver/drv_debouncer.c + ../../../src/driver/drv_dht_internal.c + ../../../src/driver/drv_dht.c +# ../../../src/driver/drv_doorSensorWithDeepSleep.c + ../../../src/driver/drv_gn6932.c + ../../../src/driver/drv_hd2015.c + ../../../src/driver/drv_ht16k33.c + ../../../src/driver/drv_httpButtons.c + ../../../src/driver/drv_hue.c + ../../../src/driver/drv_kp18058.c + ../../../src/driver/drv_kp18068.c + ../../../src/driver/drv_main.c + ../../../src/driver/drv_max72xx_clock.c + ../../../src/driver/drv_max72xx_internal.c + ../../../src/driver/drv_max72xx_single.c + ../../../src/driver/drv_mcp9808.c + ../../../src/driver/drv_ntp_events.c + ../../../src/driver/drv_ntp.c + ../../../src/driver/drv_pt6523.c + ../../../src/driver/drv_pwm_groups.c + ../../../src/driver/drv_pwmToggler.c + ../../../src/driver/drv_pwrCal.c +# ../../../src/driver/drv_rn8209.c + ../../../src/driver/drv_sgp.c + ../../../src/driver/drv_shiftRegister.c + ../../../src/driver/drv_sht3x.c +# ../../../src/driver/drv_sm15155e.c +# ../../../src/driver/drv_sm16703P.c + ../../../src/driver/drv_sm2135.c + ../../../src/driver/drv_sm2235.c + ../../../src/driver/drv_soft_i2c.c + ../../../src/driver/drv_soft_spi.c +# ../../../src/driver/drv_spi_flash.c +# ../../../src/driver/drv_spi.c +# ../../../src/driver/drv_spidma.c + ../../../src/driver/drv_ssdp.c + ../../../src/driver/drv_tasmotaDeviceGroups.c + ../../../src/driver/drv_test_drivers.c + ../../../src/driver/drv_textScroller.c + ../../../src/driver/drv_tm_gn_display_shared.c + ../../../src/driver/drv_tm1637.c + ../../../src/driver/drv_tm1638.c + ../../../src/driver/drv_tuyaMCU.c + ../../../src/driver/drv_tuyaMCUSensor.c + ../../../src/driver/drv_uart.c +# ../../../src/driver/drv_ucs1912.c + ../../../src/driver/drv_wemo.c + ../../../src/driver/drv_ds1820_simple.c + ../../../src/hal/espidf/hal_adc_espidf.c + ../../../src/hal/espidf/hal_flashConfig_espidf.c + ../../../src/hal/espidf/hal_flashVars_espidf.c + ../../../src/hal/espidf/hal_generic_espidf.c + ../../../src/hal/espidf/hal_main_espidf.c + ../../../src/hal/espidf/hal_pins_espidf.c + ../../../src/hal/espidf/hal_wifi_espidf.c + ../../../src/httpserver/hass.c + ../../../src/httpserver/http_basic_auth.c + ../../../src/httpserver/http_fns.c + ../../../src/httpserver/http_tcp_server_nonblocking.c + ../../../src/httpserver/http_tcp_server.c + ../../../src/httpserver/json_interface.c + ../../../src/httpserver/new_http.c + ../../../src/httpserver/rest_interface.c +# ../../../src/httpclient/http_client.c +# ../../../src/httpclient/utils_net.c +# ../../../src/httpclient/utils_timer.c + ../../../src/i2c/drv_i2c_lcd_pcf8574t.c + ../../../src/i2c/drv_i2c_main.c + ../../../src/i2c/drv_i2c_mcp23017.c + ../../../src/i2c/drv_i2c_tc74.c + ../../../src/jsmn/jsmn.c + ../../../src/littlefs/lfs_util.c + ../../../src/littlefs/lfs.c + ../../../src/littlefs/our_lfs.c + ../../../src/logging/logging.c +# ../../../src/memory/memtest.c + ../../../src/mqtt/new_mqtt_deduper.c + ../../../src/mqtt/new_mqtt.c + ../../../src/new_cfg.c + ../../../src/new_common.c + ../../../src/new_ping.c + ../../../src/new_pins.c +# ../../../src/ota/ota.c + ../../../src/rgb2hsv.c +# ../../../src/sim/sim_uart.c + ../../../src/tiny_crc8.c + ../../../src/user_main.c + $ENV{IDF_PATH}/components/lwip/lwip/src/apps/mqtt/mqtt.c + app.c +) +idf_component_register(SRCS ${PROJ_ALL_SRC} + PRIV_REQUIRES mqtt lwip esp_wifi nvs_flash esp_driver_tsens esp_driver_gpio esp_pm esp_partition app_update esp_adc esp_driver_uart esp_driver_ledc) diff --git a/platforms/ESP-IDF/main/app.c b/platforms/ESP-IDF/main/app.c new file mode 100644 index 000000000..83dd620ab --- /dev/null +++ b/platforms/ESP-IDF/main/app.c @@ -0,0 +1,59 @@ +#include +#include "esp_wifi.h" +#include "esp_sleep.h" +#include "hal/wdt_hal.h" + +void app_main(void); + +void Main_Init(); +void Main_OnEverySecond(); +float g_wifi_temperature = 0; + +#ifndef CONFIG_IDF_TARGET_ESP32 + +#include "driver/temperature_sensor.h" + +#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2) +#define TEMP_STACK_SIZE 1024 +#else +#define TEMP_STACK_SIZE 384 +#endif + +temperature_sensor_handle_t temp_handle = NULL; + +void temp_func(void* pvParameters) +{ + for(;;) + { + temperature_sensor_enable(temp_handle); + temperature_sensor_get_celsius(temp_handle, &g_wifi_temperature); + temperature_sensor_disable(temp_handle); + vTaskDelay(10000 / portTICK_PERIOD_MS); + } +} + +#endif + +void app_main(void) +{ + esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); + esp_netif_init(); + esp_event_loop_create_default(); +#ifndef CONFIG_IDF_TARGET_ESP32 + temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(-10, 80); + temperature_sensor_install(&temp_sensor_config, &temp_handle); + xTaskCreate(temp_func, "IntTemp", TEMP_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL); +#endif + + Main_Init(); + + while(1) + { + wdt_hal_context_t rtc_wdt_ctx = RWDT_HAL_CONTEXT_DEFAULT(); + wdt_hal_write_protect_disable(&rtc_wdt_ctx); + wdt_hal_feed(&rtc_wdt_ctx); + wdt_hal_write_protect_enable(&rtc_wdt_ctx); + Main_OnEverySecond(); + sys_delay_ms(1000); + } +} diff --git a/platforms/ESP-IDF/partitions-2mb.csv b/platforms/ESP-IDF/partitions-2mb.csv new file mode 100644 index 000000000..e24861dc3 --- /dev/null +++ b/platforms/ESP-IDF/partitions-2mb.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +otadata, data, ota, , 0x2000, +nvs, data, nvs, , 0x5000, +app0, app, ota_0, , 0xF0000, +app1, app, ota_1, , 0xF0000, +lfs, data, spiffs, , 0x10000, \ No newline at end of file diff --git a/platforms/ESP-IDF/partitions-4mb.csv b/platforms/ESP-IDF/partitions-4mb.csv new file mode 100644 index 000000000..b737523c1 --- /dev/null +++ b/platforms/ESP-IDF/partitions-4mb.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +otadata, data, ota, , 0x2000, +nvs, data, nvs, , 0x5000, +app0, app, ota_0, , 0x1D0000, +app1, app, ota_1, , 0x1D0000, +lfs, data, spiffs, , 0x50000, \ No newline at end of file diff --git a/platforms/ESP-IDF/pre_build.sh b/platforms/ESP-IDF/pre_build.sh new file mode 100644 index 000000000..dab1f180b --- /dev/null +++ b/platforms/ESP-IDF/pre_build.sh @@ -0,0 +1,41 @@ +# This script will be called just before starting build process for ESP-IDF +# It allows you to make changes to the SDK, for example.. +# For example, you can use changed files in the SDK for the automated build during the checks for a PR without changing the SDK itself: +# So your PR needs a modified define in the SDK, for example ? This script can make this change directly before the build. + +# +# +# As an example you will find a script below which will copy all content of the "override" +# directory to the corresponding location in the SDK +# +#DIRNAME=$(dirname $0); +#echo "PREBUILD script! Executed from $DIRNAME!" +# allow whitspace in file or path, so take only newline as seperator +#OFS=$IFS +#IFS=' +#' +#for X in $(find platforms/ESP-IDF/override/ -type f);do +# # script is executed from main app directory, so take found file and path as source +# S=${X}; +# # destination is path stripped from path to override +# # so inside "override" we have the full path to the file +# # starting with "sdk/esp-idf/..." +# D=${X#platforms/ESP-IDF/override/}; +# # if file is present, we replace it, otherwise file is added ... +# [ -e $D ] && echo "PREBUILD: replacing file\n\t$D\n\twith file\n\t$S" || echo "PREBUILD: adding file\n\t$S\n\tas\n\t$D" +# cp $S $D; +#done +## restore IFS to whatever it was before ... +#IFS=$OFS + +# you can also use all other commands to change files, like +# sed -i "s/#define FOO bar/#define FOO baz/" sdk/esp-idf/components/esp_driver_ledc/src/ledc.c +# or, let's assume you made a local change to your SDK +# and make a diff from that change (inside sdk/esp-idf/) +# git diff > ../../platforms/ESP-IDF/my_change.diff +# ( or make the diff and copy this file to platforms/ESP-IDF) +# +# and then in pre_build.sh you apply this patch with: +# +# patch -p 1 -d sdk/esp-idf < platforms/ESP_IDF/my_change.diff + diff --git a/platforms/ESP-IDF/sdkconfig.defaults b/platforms/ESP-IDF/sdkconfig.defaults new file mode 100644 index 000000000..df345192c --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults @@ -0,0 +1,20 @@ +CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION=n +CONFIG_LWIP_IPV6=n +CONFIG_LWIP_IPV6_AUTOCONFIG=n +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=n +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=n +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=n +CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_NEWLIB_NANO_FORMAT=y +CONFIG_PARTITION_TABLE_SINGLE_APP=n +CONFIG_PARTITION_TABLE_TWO_OTA=y +CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE=y +CONFIG_ESP_MAIN_TASK_STACK_SIZE=4096 +CONFIG_VFS_SUPPORT_IO=n +CONFIG_MBEDTLS_SHA512_C=n +CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y +CONFIG_HAL_LOG_LEVEL_ERROR=y + +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=n +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=n \ No newline at end of file diff --git a/platforms/ESP-IDF/sdkconfig.defaults.esp32 b/platforms/ESP-IDF/sdkconfig.defaults.esp32 new file mode 100644 index 000000000..0f00f7e88 --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults.esp32 @@ -0,0 +1,8 @@ +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4mb.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +CONFIG_ESPTOOLPY_FLASHFREQ="40m" \ No newline at end of file diff --git a/platforms/ESP-IDF/sdkconfig.defaults.esp32c2 b/platforms/ESP-IDF/sdkconfig.defaults.esp32c2 new file mode 100644 index 000000000..2d252bd29 --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults.esp32c2 @@ -0,0 +1,46 @@ +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y + +CONFIG_XTAL_FREQ_26=y +CONFIG_XTAL_FREQ=26 + +CONFIG_RTC_CLK_SRC_INT_RC=y + +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y +CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION=y + +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-2mb.csv" + +CONFIG_LWIP_MAX_SOCKETS=5 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=16 +CONFIG_LWIP_MAX_ACTIVE_TCP=5 +CONFIG_LWIP_MAX_LISTENING_TCP=5 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=n +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSL=40000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=16000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=4096 +CONFIG_LWIP_TCP_WND_DEFAULT=2440 +CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS=y +CONFIG_LWIP_TCP_RTO_TIME=1500 +CONFIG_LWIP_MAX_UDP_PCBS=8 +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=2560 + +CONFIG_MBEDTLS_DYNAMIC_BUFFER=y +CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y +CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y +CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH=y +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n + +CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH=y + +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=3 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=6 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=6 +CONFIG_ESP_WIFI_RX_BA_WIN=6 + +CONFIG_SPI_MASTER_ISR_IN_IRAM=n +CONFIG_SPI_SLAVE_ISR_IN_IRAM=n +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=n +CONFIG_SPI_FLASH_ROM_IMPL=y \ No newline at end of file diff --git a/platforms/ESP-IDF/sdkconfig.defaults.esp32c3 b/platforms/ESP-IDF/sdkconfig.defaults.esp32c3 new file mode 100644 index 000000000..d68edc6d0 --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults.esp32c3 @@ -0,0 +1,4 @@ +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-2mb.csv" \ No newline at end of file diff --git a/platforms/ESP-IDF/sdkconfig.defaults.esp32c6 b/platforms/ESP-IDF/sdkconfig.defaults.esp32c6 new file mode 100644 index 000000000..5b03b1399 --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults.esp32c6 @@ -0,0 +1,6 @@ +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4mb.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" \ No newline at end of file diff --git a/platforms/ESP-IDF/sdkconfig.defaults.esp32s2 b/platforms/ESP-IDF/sdkconfig.defaults.esp32s2 new file mode 100644 index 000000000..5b03b1399 --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults.esp32s2 @@ -0,0 +1,6 @@ +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4mb.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" \ No newline at end of file diff --git a/platforms/ESP-IDF/sdkconfig.defaults.esp32s3 b/platforms/ESP-IDF/sdkconfig.defaults.esp32s3 new file mode 100644 index 000000000..5b03b1399 --- /dev/null +++ b/platforms/ESP-IDF/sdkconfig.defaults.esp32s3 @@ -0,0 +1,6 @@ +CONFIG_PM_ENABLE=y +CONFIG_PM_DFS_INIT_AUTO=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions-4mb.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" \ No newline at end of file diff --git a/sdk/esp-idf b/sdk/esp-idf new file mode 160000 index 000000000..c8fc5f643 --- /dev/null +++ b/sdk/esp-idf @@ -0,0 +1 @@ +Subproject commit c8fc5f643b7a7b0d3b182d3df610844e3dc9bd74 diff --git a/src/cmnds/cmd_eventHandlers.c b/src/cmnds/cmd_eventHandlers.c index 569aa4e11..f48dc3583 100644 --- a/src/cmnds/cmd_eventHandlers.c +++ b/src/cmnds/cmd_eventHandlers.c @@ -208,7 +208,7 @@ int EVENT_ParseEventName(const char *s) { return CMD_EVENT_CUSTOM_DOWN; if (!stricmp(s, "OnCustomUP")) return CMD_EVENT_CUSTOM_UP; - if (isdigit(*s)) { + if (isdigit((unsigned char)*s)) { return atoi(s); } return CMD_EVENT_NONE; diff --git a/src/cmnds/cmd_if.c b/src/cmnds/cmd_if.c index c475cbf88..818729ad4 100644 --- a/src/cmnds/cmd_if.c +++ b/src/cmnds/cmd_if.c @@ -687,37 +687,42 @@ const char *CMD_ExpandConstantString(const char *s, const char *stop, char *out, } #endif -const char *CMD_ExpandConstantToString(const char *constant, char *out, char *stop) { -int outLen; -float value; -int valueInt; -const char *after; -float delta; +const char* CMD_ExpandConstantToString(const char* constant, char* out, char* stop) +{ + int outLen; + float value = 0; + int valueInt; + const char* after; + float delta; -outLen = (stop - out) - 1; + outLen = (stop - out) - 1; -after = CMD_ExpandConstant(constant, 0, &value); + after = CMD_ExpandConstant(constant, 0, &value); #if WINDOWS -if (after == 0) { - after = CMD_ExpandConstantString(constant, 0, out, outLen); - return after; -} + if(after == 0) + { + after = CMD_ExpandConstantString(constant, 0, out, outLen); + return after; + } #endif -if (after == 0) -return 0; + if(after == 0) + return 0; -valueInt = (int)value; -delta = valueInt - value; -if (delta < 0) - delta = -delta; -if (delta < 0.001f) { - snprintf(out, outLen, "%i", valueInt); -} -else { - snprintf(out, outLen, "%f", value); -} -return after; + valueInt = (int)value; + delta = valueInt - value; + if(delta < 0) + delta = -delta; + if(delta < 0.001f) + { + snprintf(out, outLen, "%i", valueInt); + } + else + { + snprintf(out, outLen, "%f", value); + } + return after; } + void CMD_ExpandConstantsWithinString(const char *in, char *out, int outLen) { char *outStop; const char *tmp; diff --git a/src/cmnds/cmd_main.c b/src/cmnds/cmd_main.c index 0e7879d3b..5429785b4 100644 --- a/src/cmnds/cmd_main.c +++ b/src/cmnds/cmd_main.c @@ -21,6 +21,14 @@ int cmd_uartInitIndex = 0; #elif PLATFORM_LN882H #include #include +#elif PLATFORM_ESPIDF +#include "esp_wifi.h" +#include "esp_pm.h" +#include "esp_sleep.h" +#include "driver/rtc_io.h" +#include "driver/gpio.h" +#include "driver/ledc.h" +#include "esp_check.h" #endif #define HASH_SIZE 128 @@ -111,6 +119,48 @@ static commandResult_t CMD_PowerSave(const void* context, const char* cmd, const g_ln882h_pendingPowerSaveCommand = bOn; } else LN882H_ApplyPowerSave(bOn); +#elif defined(PLATFORM_ESPIDF) + if(Tokenizer_GetArgsCount() > 1) + { + int tx = Tokenizer_GetArgInteger(1); + int8_t maxtx = 0; + esp_wifi_get_max_tx_power(&maxtx); + if(tx > maxtx / 4) + { + ADDLOG_ERROR(LOG_FEATURE_CMD, "TX power maximum is: %ddBm, entered: %idBm", maxtx / 4, tx); + } + else + { + esp_wifi_set_max_tx_power(tx * 4); + ADDLOG_INFO(LOG_FEATURE_CMD, "Setting TX power to: %idBm", tx); + } + } + if(Tokenizer_GetArgsCount() > 3) + { + int minfreq = Tokenizer_GetArgInteger(2); + int maxfreq = Tokenizer_GetArgInteger(3); + esp_pm_config_t pm_config = { + .max_freq_mhz = maxfreq, + .min_freq_mhz = minfreq, + }; + esp_pm_configure(&pm_config); + ADDLOG_INFO(LOG_FEATURE_CMD, "PowerSave freq scaling, min: %iMhz, max: %iMhz", minfreq, maxfreq); + } + else if(bOn >= 2) + { + ADDLOG_INFO(LOG_FEATURE_CMD, "PowerSave max_modem"); + esp_wifi_set_ps(WIFI_PS_MAX_MODEM); + } + else if(bOn == 1) + { + ADDLOG_INFO(LOG_FEATURE_CMD, "PowerSave min_modem"); + esp_wifi_set_ps(WIFI_PS_MIN_MODEM); + } + else + { + ADDLOG_INFO(LOG_FEATURE_CMD, "PowerSave disabled"); + esp_wifi_set_ps(WIFI_PS_NONE); + } #else ADDLOG_INFO(LOG_FEATURE_CMD, "PowerSave is not implemented on this platform"); #endif @@ -139,7 +189,12 @@ static commandResult_t CMD_DeepSleep(const void* context, const char* cmd, const bk_wlan_ps_wakeup_with_timer(timeMS); return CMD_RES_OK; #elif defined(PLATFORM_W600) - +#elif defined(PLATFORM_ESPIDF) + esp_sleep_enable_timer_wakeup(timeMS * 1000000); +#if CONFIG_IDF_TARGET_ESP32 + rtc_gpio_isolate(GPIO_NUM_12); +#endif + esp_deep_sleep_start(); #endif return CMD_RES_OK; @@ -619,6 +674,20 @@ commandResult_t CMD_PWMFrequency(const void* context, const char* cmd, const cha } g_pwmFrequency = Tokenizer_GetArgInteger(0); + +#ifdef PLATFORM_ESPIDF + esp_err_t err = ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_TIMER_0, (uint32_t)g_pwmFrequency); + if(err == ESP_ERR_INVALID_ARG) + { + ADDLOG_ERROR(LOG_FEATURE_CMD, "ledc_set_freq: invalid arg"); + return CMD_RES_BAD_ARGUMENT; + } + else if(err == ESP_FAIL) + { + ADDLOG_ERROR(LOG_FEATURE_CMD, "ledc_set_freq: Can not find a proper pre-divider number base on the given frequency and the current duty_resolution"); + return CMD_RES_ERROR; + } +#endif return CMD_RES_OK; } commandResult_t CMD_IndexRefreshInterval(const void* context, const char* cmd, const char* args, int cmdFlags) { @@ -786,7 +855,7 @@ void CMD_Init_Early() { CMD_RegisterCommand("IndexRefreshInterval", CMD_IndexRefreshInterval, NULL); -#if (defined WINDOWS) || (defined PLATFORM_BEKEN) || (defined PLATFORM_BL602) || (defined PLATFORM_LN882H) +#if (defined WINDOWS) || (defined PLATFORM_BEKEN) || (defined PLATFORM_BL602) || (defined PLATFORM_LN882H) || (defined PLATFORM_ESPIDF) CMD_InitScripting(); #endif if (!bSafeMode) { @@ -803,7 +872,7 @@ void CMD_Init_Delayed() { if (CFG_HasFlag(OBK_FLAG_CMD_ENABLETCPRAWPUTTYSERVER)) { CMD_StartTCPCommandLine(); } -#if defined(PLATFORM_BEKEN) || defined(WINDOWS) || defined(PLATFORM_BL602) +#if defined(PLATFORM_BEKEN) || defined(WINDOWS) || defined(PLATFORM_BL602) || defined(PLATFORM_ESPIDF) UART_AddCommands(); #endif } diff --git a/src/driver/drv_battery.c b/src/driver/drv_battery.c index 1e4e588fc..84002608d 100644 --- a/src/driver/drv_battery.c +++ b/src/driver/drv_battery.c @@ -38,6 +38,7 @@ static void Batt_Measure() { //channel_rel = g_cfg.pins.channels[g_pin_rel]; //} } + // maybe move init code to Batt_Init? HAL_ADC_Init(g_pin_adc); g_battlevel = HAL_ADC_Read(g_pin_adc); if (g_battlevel < 1024) { diff --git a/src/driver/drv_dht_internal.c b/src/driver/drv_dht_internal.c index 1e7a28fc1..2cc86c292 100644 --- a/src/driver/drv_dht_internal.c +++ b/src/driver/drv_dht_internal.c @@ -66,6 +66,8 @@ void usleep2(int r) //delay function do 10*r nops, because rtos_delay_millisecon __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); } +#elif PLATFORM_ESPIDF + usleep(r); #else for (volatile int i = 0; i < r; i++) { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); diff --git a/src/driver/drv_ds1820_simple.c b/src/driver/drv_ds1820_simple.c index 4df7eccea..ea33465df 100644 --- a/src/driver/drv_ds1820_simple.c +++ b/src/driver/drv_ds1820_simple.c @@ -1,24 +1,32 @@ #include "drv_ds1820_simple.h" +#if PLATFORM_ESPIDF +#include "freertos/task.h" +#define noInterrupts() portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;taskENTER_CRITICAL(&mux) +#define interrupts() taskEXIT_CRITICAL(&mux) +#else #include +#define noInterrupts() taskENTER_CRITICAL() +#define interrupts() taskEXIT_CRITICAL() +#endif -static uint8_t dsread=0; +static uint8_t dsread = 0; static int Pin; -static int t=-127; -static int errcount=0; -static int lastconv; // secondsElapsed on last successfull reading +static int t = -127; +static int errcount = 0; +static int lastconv; // secondsElapsed on last successfull reading static uint8_t ds18_family = 0; static int ds18_conversionPeriod = 0; #define DS1820_LOG(x, fmt, ...) addLogAdv(LOG_##x, LOG_FEATURE_SENSOR, "DS1820[%i] - " fmt, Pin, ##__VA_ARGS__) // usleep adopted from DHT driver - -void usleepds(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much +void usleepds(int r) { #ifdef WIN32 // not possible on Windows port #elif PLATFORM_BL602 - for (volatile int i = 0; i < r; i++) { + for(volatile int i = 0; i < r; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); @@ -34,7 +42,8 @@ void usleepds(int r) //delay function do 10*r nops, because rtos_delay_milliseco __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); } #elif PLATFORM_W600 - for (volatile int i = 0; i < r; i++) { + for(volatile int i = 0; i < r; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); @@ -44,7 +53,8 @@ void usleepds(int r) //delay function do 10*r nops, because rtos_delay_milliseco __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); } #elif PLATFORM_W800 - for (volatile int i = 0; i < r; i++) { + for(volatile int i = 0; i < r; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); @@ -70,11 +80,16 @@ void usleepds(int r) //delay function do 10*r nops, because rtos_delay_milliseco __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); } #elif PLATFORM_BEKEN - usleep((17*r)/10); // "1" is to fast and "2" to slow, 1.7 seems better than 1.5 (only from observing readings, no scope involved) + float adj = 1; + if(g_powersave) adj = 1.5; + usleep((17 * r * adj) / 10); // "1" is to fast and "2" to slow, 1.7 seems better than 1.5 (only from observing readings, no scope involved) #elif PLATFORM_LN882H - usleep(5*r); // "5" seems o.k + usleep(5 * r); // "5" seems o.k +#elif PLATFORM_ESPIDF + usleep(r); #else - for (volatile int i = 0; i < r; i++) { + for(volatile int i = 0; i < r; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); @@ -82,17 +97,15 @@ void usleepds(int r) //delay function do 10*r nops, because rtos_delay_milliseco #endif } - // add some "special timing" for Beken - works w/o and with powerSave 1 for me - void usleepshort(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much { -# #if PLATFORM_BEKEN - int newr=r/(3*g_powersave+1); // devide by 4 if powerSave set to 1 - for (volatile int i = 0; i < newr; i++) { + int newr = r / (3 * g_powersave + 1); // devide by 4 if powerSave set to 1 + for(volatile int i = 0; i < newr; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); -// __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); + //__asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop"); } @@ -100,12 +113,13 @@ void usleepshort(int r) //delay function do 10*r nops, because rtos_delay_millis usleepds(r); #endif } + void usleepmed(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much { -# #if PLATFORM_BEKEN - int newr= 10 * r / (10 + 5 * g_powersave) ; // devide by 1.5 powerSave set to 1 - for (volatile int i = 0; i < newr; i++) { + int newr = 10 * r / (10 + 5 * g_powersave); // devide by 1.5 powerSave set to 1 + for(volatile int i = 0; i < newr; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); @@ -118,17 +132,18 @@ void usleepmed(int r) //delay function do 10*r nops, because rtos_delay_millisec usleepds(r); #endif } + void usleeplong(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much { -# #if PLATFORM_BEKEN - int newr= 10 * r / (10 + 5 * g_powersave) ; // devide by 1.5 powerSave set to 1 - for (volatile int i = 0; i < newr; i++) { + int newr = 10 * r / (10 + 5 * g_powersave); // devide by 1.5 powerSave set to 1 + for(volatile int i = 0; i < newr; i++) + { __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); -// __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); // 5 + // __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); // 5 __asm__("nop\nnop\nnop\nnop\nnop"); // 5 } @@ -137,9 +152,6 @@ void usleeplong(int r) //delay function do 10*r nops, because rtos_delay_millise #endif } - - - /* timing numbers and general code idea from @@ -171,147 +183,144 @@ J Standard 410 #define OWtimeI 70 #define OWtimeJ 410 - int OWReset(int Pin) { - int result; - -// usleep(OWtimeG); - HAL_PIN_Setup_Output(Pin); - HAL_PIN_SetOutputValue(Pin,0); // Drives DQ low - usleeplong(OWtimeH); - HAL_PIN_SetOutputValue(Pin,1); // Releases the bus - usleepmed(OWtimeI); - HAL_PIN_Setup_Input(Pin); - result = HAL_PIN_ReadDigitalInput(Pin) ^ 0x01; // Sample for presence pulse from slave - usleeplong(OWtimeJ); // Complete the reset sequence recovery - return result; // Return sample presence pulse result + int result; + + //usleep(OWtimeG); + HAL_PIN_Setup_Output(Pin); + HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low + usleeplong(OWtimeH); + HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus + usleepmed(OWtimeI); + HAL_PIN_Setup_Input(Pin); + result = HAL_PIN_ReadDigitalInput(Pin) ^ 0x01; // Sample for presence pulse from slave + usleeplong(OWtimeJ); // Complete the reset sequence recovery + return result; // Return sample presence pulse result } //----------------------------------------------------------------------------- // Send a 1-Wire write bit. Provide 10us recovery time. -// +//----------------------------------------------------------------------------- void OWWriteBit(int Pin, int bit) { - if (bit) - { - // Write '1' bit - HAL_PIN_Setup_Output(Pin); - taskENTER_CRITICAL(); - HAL_PIN_SetOutputValue(Pin,0); // Drives DQ low - usleepshort(OWtimeA); - HAL_PIN_SetOutputValue(Pin,1); // Releases the bus - taskEXIT_CRITICAL(); // hope for the best for the following timer and keep CRITICAL as short as possible - usleepmed(OWtimeB); // Complete the time slot and 10us recovery - } - else - { - // Write '0' bit - HAL_PIN_Setup_Output(Pin); - taskENTER_CRITICAL(); - HAL_PIN_SetOutputValue(Pin,0); // Drives DQ low - usleepmed(OWtimeC); - HAL_PIN_SetOutputValue(Pin,1); // Releases the bus - taskEXIT_CRITICAL(); // hope for the best for the following timer and keep CRITICAL as short as possible - usleepshort(OWtimeD); - } + if(bit) + { + // Write '1' bit + HAL_PIN_Setup_Output(Pin); + noInterrupts(); + HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low + usleepshort(OWtimeA); + HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus + interrupts(); // hope for the best for the following timer and keep CRITICAL as short as possible + usleepmed(OWtimeB); // Complete the time slot and 10us recovery + } + else + { + // Write '0' bit + HAL_PIN_Setup_Output(Pin); + noInterrupts(); + HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low + usleepmed(OWtimeC); + HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus + interrupts(); // hope for the best for the following timer and keep CRITICAL as short as possible + usleepshort(OWtimeD); + } } //----------------------------------------------------------------------------- // Read a bit from the 1-Wire bus and return it. Provide 10us recovery time. -// +//----------------------------------------------------------------------------- int OWReadBit(int Pin) { - int result; - - taskENTER_CRITICAL(); - HAL_PIN_Setup_Output(Pin); - HAL_PIN_SetOutputValue(Pin,0); // Drives DQ low - usleepshort(OWtimeA); - HAL_PIN_SetOutputValue(Pin,1); // Releases the bus - usleepshort(OWtimeE); - HAL_PIN_Setup_Input(Pin); - result = HAL_PIN_ReadDigitalInput(Pin); // Sample for presence pulse from slave - taskEXIT_CRITICAL(); // hope for the best for the following timer and keep CRITICAL as short as possible - usleepmed(OWtimeF); // Complete the time slot and 10us recovery - return result; + int result; + + noInterrupts(); + HAL_PIN_Setup_Output(Pin); + HAL_PIN_SetOutputValue(Pin, 0); // Drives DQ low + usleepshort(OWtimeA); + HAL_PIN_SetOutputValue(Pin, 1); // Releases the bus + usleepshort(OWtimeE); + HAL_PIN_Setup_Input(Pin); + result = HAL_PIN_ReadDigitalInput(Pin); // Sample for presence pulse from slave + interrupts(); // hope for the best for the following timer and keep CRITICAL as short as possible + usleepmed(OWtimeF); // Complete the time slot and 10us recovery + return result; } //----------------------------------------------------------------------------- // Poll if DS1820 temperature conversion is complete -// +//----------------------------------------------------------------------------- int DS1820TConversionDone(int Pin) { - int result; - - // Write '1' bit - OWWriteBit(Pin, 1); + // Write '1' bit + OWWriteBit(Pin, 1); // check for '1' - conversion complete (will be '0' else) - return OWReadBit(Pin); + return OWReadBit(Pin); } //----------------------------------------------------------------------------- // Write 1-Wire data byte -// +//----------------------------------------------------------------------------- void OWWriteByte(int Pin, int data) { - int loop; + int loop; - // Loop to write each bit in the byte, LS-bit first - for (loop = 0; loop < 8; loop++) - { - OWWriteBit(Pin, data & 0x01); + // Loop to write each bit in the byte, LS-bit first + for(loop = 0; loop < 8; loop++) + { + OWWriteBit(Pin, data & 0x01); - // shift the data byte for the next bit - data >>= 1; - } + // shift the data byte for the next bit + data >>= 1; + } } //----------------------------------------------------------------------------- // Read 1-Wire data byte and return it -// +//----------------------------------------------------------------------------- int OWReadByte(int Pin) { - int loop, result=0; - - for (loop = 0; loop < 8; loop++) - { - // shift the result to get it ready for the next bit - result >>= 1; - - // if result is one, then set MS bit - if (OWReadBit(Pin)) - result |= 0x80; - } - return result; + int loop, result = 0; + + for(loop = 0; loop < 8; loop++) + { + // shift the result to get it ready for the next bit + result >>= 1; + + // if result is one, then set MS bit + if(OWReadBit(Pin)) + result |= 0x80; + } + return result; } //----------------------------------------------------------------------------- // Write a 1-Wire data byte and return the sampled result. -// +//----------------------------------------------------------------------------- int OWTouchByte(int Pin, int data) { - int loop, result=0; - - for (loop = 0; loop < 8; loop++) - { - // shift the result to get it ready for the next bit - result >>= 1; - - // If sending a '1' then read a bit else write a '0' - if (data & 0x01) - { - if (OWReadBit(Pin)) - result |= 0x80; - } - else - OWWriteBit(Pin,0); - - // shift the data byte for the next bit - data >>= 1; - } - return result; + int loop, result = 0; + + for(loop = 0; loop < 8; loop++) + { + // shift the result to get it ready for the next bit + result >>= 1; + + // If sending a '1' then read a bit else write a '0' + if(data & 0x01) + { + if(OWReadBit(Pin)) + result |= 0x80; + } + else + OWWriteBit(Pin, 0); + + // shift the data byte for the next bit + data >>= 1; + } + return result; } // quicker CRC with lookup table @@ -319,42 +328,45 @@ int OWTouchByte(int Pin, int data) // Dallas 1-Wire CRC Test App - // x^8 + x^5 + x^4 + 1 0x8C (0x131) -uint8_t Crc8CQuick(uint8_t *Buffer,uint8_t Size) -{ static const uint8_t CrcTable[] = { // Nibble table for polynomial 0x8C - 0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8, - 0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74 }; - uint8_t Crc=0x00; - while(Size--) - { - Crc ^= *Buffer++; // Apply Data - Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits - Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; - } - return(Crc); - +uint8_t Crc8CQuick(uint8_t* Buffer, uint8_t Size) +{ + // Nibble table for polynomial 0x8C + static const uint8_t CrcTable[] = + { + 0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8, + 0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74 + }; + uint8_t Crc = 0x00; + while(Size--) + { + Crc ^= *Buffer++; // Apply Data + Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits + Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; + } + return(Crc); } - - -int DS1820_getTemp() { +int DS1820_getTemp() +{ return t; } // startDriver DS1820 [conversionPeriod (seconds) - default 15] -void DS1820_driver_Init(){ +void DS1820_driver_Init() +{ ds18_conversionPeriod = Tokenizer_GetArgIntegerDefault(1, 15); - lastconv=0; + lastconv = 0; }; - -void DS1820_AppendInformationToHTTPIndexPage(http_request_t *request) +void DS1820_AppendInformationToHTTPIndexPage(http_request_t* request) { - - hprintf255(request, "
DS1820 Temperature: %.2f C (read %i secs ago)
",(float)t/100, g_secondsElapsed-lastconv); + hprintf255(request, "
DS1820 Temperature: %.2f C (read %i secs ago)
", (float)t / 100, g_secondsElapsed - lastconv); } -int DS1820_DiscoverFamily() { - if (!OWReset(Pin)) { +int DS1820_DiscoverFamily() +{ + if(!OWReset(Pin)) + { DS1820_LOG(DEBUG, "Discover Reset failed"); return 0; } @@ -362,13 +374,15 @@ int DS1820_DiscoverFamily() { // Read ROM uint8_t ROM[8]; OWWriteByte(Pin, 0x33); - for (int i = 0; i < 8; i++) { + for(int i = 0; i < 8; i++) + { ROM[i] = OWReadByte(Pin); } // Check CRC uint8_t crc = Crc8CQuick(ROM, 7); - if (crc != ROM[7]) { + if(crc != ROM[7]) + { // This might mean bad signal integrity or multiple 1-wire devices on the bus DS1820_LOG(DEBUG, "Discover CRC failed (CRC=%x != calculated:%x)", ROM[7], crc); return 0; @@ -376,40 +390,46 @@ int DS1820_DiscoverFamily() { // Check family uint8_t family = ROM[0]; - if (family == 0x10 || family == 0x28) { + if(family == 0x10 || family == 0x28) + { ds18_family = family; DS1820_LOG(INFO, "Discover Family - discovered %x", family); return 1; - } else { + } + else + { DS1820_LOG(DEBUG, "Discover Family %x not supported", family); return 0; } } -void DS1820_OnEverySecond() { - +void DS1820_OnEverySecond() +{ // for now just find the pin used - // - Pin=PIN_FindPinIndexForRole(IOR_DS1820_IO, 99); + Pin = PIN_FindPinIndexForRole(IOR_DS1820_IO, 99); uint8_t scratchpad[9], crc; - if (Pin != 99) { // only if pin is set + if(Pin != 99) + { + // only if pin is set // request temp if conversion was requested two seconds after request // if (dsread == 1 && g_secondsElapsed % 5 == 2) { // better if we don't use parasitic power, we can check if conversion is ready - if (dsread == 1 && DS1820TConversionDone(Pin) == 1) { - if (OWReset(Pin) == 0) { + if(dsread == 1 && DS1820TConversionDone(Pin) == 1) + { + if(OWReset(Pin) == 0) + { DS1820_LOG(ERROR, "Read Reset failed"); return; } - OWWriteByte(Pin,0xCC); - OWWriteByte(Pin,0xBE); + OWWriteByte(Pin, 0xCC); + OWWriteByte(Pin, 0xBE); - for (int i = 0; i < 9; i++) + for(int i = 0; i < 9; i++) { - scratchpad[i] = OWReadByte(Pin);//read Scratchpad Memory of DS + scratchpad[i] = OWReadByte(Pin); //read Scratchpad Memory of DS } - crc= Crc8CQuick(scratchpad, 8); - if (crc != scratchpad[8]) + crc = Crc8CQuick(scratchpad, 8); + if(crc != scratchpad[8]) { errcount++; DS1820_LOG(ERROR, "Read CRC=%x != calculated:%x (errcount=%i)", scratchpad[8], crc, errcount); @@ -417,84 +437,91 @@ void DS1820_OnEverySecond() { scratchpad[0], scratchpad[1], scratchpad[2], scratchpad[3], scratchpad[4], scratchpad[5], scratchpad[6], scratchpad[7], scratchpad[8]); - if (errcount > 5) dsread=0; // retry afer 5 failures - } + if(errcount > 5) dsread = 0; // retry afer 5 failures + } else - { + { int16_t raw = (scratchpad[1] << 8) | scratchpad[0]; - if (ds18_family == 0x10) { // DS18S20 or old DS1820 + if(ds18_family == 0x10) + { + // DS18S20 or old DS1820 int16_t dT = 128 * (scratchpad[7] - scratchpad[6]); dT /= scratchpad[7]; raw = 64 * (raw & 0xFFFE) - 32 + dT; DS1820_LOG(DEBUG, "family=%x, raw=%i, count_remain=%i, count_per_c=%i, dT=%i", ds18_family, raw, scratchpad[6], scratchpad[7], dT); - } else { // DS18B20 + } + else + { // DS18B20 uint8_t cfg = scratchpad[4] & 0x60; - if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms - else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms - else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms + if(cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms + else if(cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms + else if(cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms raw = raw << 3; // multiply by 8 - DS1820_LOG(DEBUG, "family=%x, raw=%i, cfg=%x (%i bit resolution)", ds18_family, raw, cfg, 9+(cfg)/32) ; + DS1820_LOG(DEBUG, "family=%x, raw=%i, cfg=%x (%i bit resolution)", ds18_family, raw, cfg, 9 + (cfg) / 32); } - + // Raw is t * 128 t = (raw / 128) * 100; // Whole degrees int frac = (raw % 128) * 100 / 128; // Fractional degrees t += t > 0 ? frac : -frac; - dsread=0; - lastconv=g_secondsElapsed; + dsread = 0; + lastconv = g_secondsElapsed; CHANNEL_Set(g_cfg.pins.channels[Pin], t, CHANNEL_SET_FLAG_SILENT); - DS1820_LOG(INFO, "Temp=%i.%02i", (int)t/100 , (int)t%100); + DS1820_LOG(INFO, "Temp=%i.%02i", (int)t / 100, (int)t % 100); } } - else if (dsread == 0 && (g_secondsElapsed % ds18_conversionPeriod == 0 || lastconv == 0)) { - if (OWReset(Pin) == 0) { - lastconv=-1; // reset lastconv to avoid immediate retry + else if(dsread == 0 && (g_secondsElapsed % ds18_conversionPeriod == 0 || lastconv == 0)) + { + if(OWReset(Pin) == 0) + { + lastconv = -1; // reset lastconv to avoid immediate retry DS1820_LOG(ERROR, "Reset failed"); // if device is not found, maybe "usleep" is not working as expected // lets do usleepds() with numbers 50.000 and 100.00 // if all is well, it should take 50ms and 100ms // if not, we need to "calibrate" the loop - int tempsleep=5000; - TickType_t actTick=portTICK_RATE_MS*xTaskGetTickCount(); + int tempsleep = 5000; + TickType_t actTick = portTICK_RATE_MS * xTaskGetTickCount(); usleepds(tempsleep); - int duration = (int)(portTICK_RATE_MS*xTaskGetTickCount()-actTick); + int duration = (int)(portTICK_RATE_MS * xTaskGetTickCount() - actTick); DS1820_LOG(DEBUG, "usleepds(%i) took %i ms ", tempsleep, duration); - tempsleep=100000; - actTick=portTICK_RATE_MS*xTaskGetTickCount(); + tempsleep = 100000; + actTick = portTICK_RATE_MS * xTaskGetTickCount(); usleepds(tempsleep); - duration = (int)(portTICK_RATE_MS*xTaskGetTickCount()-actTick); + duration = (int)(portTICK_RATE_MS * xTaskGetTickCount() - actTick); DS1820_LOG(DEBUG, "usleepds(%i) took %i ms ", tempsleep, duration); - - if (duration < 95 || duration > 105){ + + if(duration < 95 || duration > 105) + { // calc a new factor for usleepds - DS1820_LOG(ERROR, "usleepds duration divergates - proposed factor to adjust usleepds %f ",(float)100/duration); + DS1820_LOG(ERROR, "usleepds duration divergates - proposed factor to adjust usleepds %f ", (float)100 / duration); } - - } - else { - if (ds18_family == 0) { + } + else + { + if(ds18_family == 0) + { int discovered = DS1820_DiscoverFamily(); - if (!discovered) { - lastconv=-1; // reset lastconv to avoid immediate retry + if(!discovered) + { + lastconv = -1; // reset lastconv to avoid immediate retry DS1820_LOG(ERROR, "Family not discovered"); return; } } - OWWriteByte(Pin,0xCC); - OWWriteByte(Pin,0x44); + OWWriteByte(Pin, 0xCC); + OWWriteByte(Pin, 0x44); DS1820_LOG(INFO, "Starting conversion"); - dsread=1; - errcount=0; + dsread = 1; + errcount = 0; } } - - } } diff --git a/src/driver/drv_main.c b/src/driver/drv_main.c index d0ff0b7a2..45d07a3c0 100644 --- a/src/driver/drv_main.c +++ b/src/driver/drv_main.c @@ -326,7 +326,7 @@ static driver_t g_drivers[] = { //drvdetail:"requires":""} { "CHT83XX", CHT83XX_Init, CHT83XX_OnEverySecond, CHT83XX_AppendInformationToHTTPIndexPage, NULL, NULL, NULL, false }, #endif -#if defined(PLATFORM_BEKEN) || defined(WINDOWS) +#if defined(PLATFORM_BEKEN) || defined(WINDOWS) || defined(PLATFORM_ESPIDF) //drvdetail:{"name":"MCP9808", //drvdetail:"title":"TODO", //drvdetail:"descr":"MCP9808 is a Temperature sensor with I2C interface and an external wakeup pin, see [docs](https://www.elektroda.pl/rtvforum/topic3988466.html).", diff --git a/src/driver/drv_soft_i2c.c b/src/driver/drv_soft_i2c.c index 8b2804541..8384b87b1 100644 --- a/src/driver/drv_soft_i2c.c +++ b/src/driver/drv_soft_i2c.c @@ -10,6 +10,7 @@ #include "../httpserver/new_http.h" #include "../hal/hal_pins.h" +#ifndef PLATFORM_ESPIDF void usleep(int r) //delay function do 10*r nops, because rtos_delay_milliseconds is too much { #ifdef WIN32 @@ -19,6 +20,7 @@ void usleep(int r) //delay function do 10*r nops, because rtos_delay_millisecond __asm__("nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop"); #endif } +#endif void Soft_I2C_SetLow(uint8_t pin) { HAL_PIN_Setup_Output(pin); diff --git a/src/driver/drv_uart.c b/src/driver/drv_uart.c index 78edcf173..ad5a16ab4 100644 --- a/src/driver/drv_uart.c +++ b/src/driver/drv_uart.c @@ -89,6 +89,22 @@ int g_chosenUART = BK_UART_1; //int g_fd; uint8_t g_id = 1; int fd_console = -1; +#elif PLATFORM_ESPIDF +#include "driver/uart.h" +#include "driver/gpio.h" +#ifdef CONFIG_IDF_TARGET_ESP32C6 +#define RX1_PIN GPIO_NUM_7 +#define TX1_PIN GPIO_NUM_5 +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 +#define RX1_PIN GPIO_NUM_6 +#define TX1_PIN GPIO_NUM_7 +#else +#define RX1_PIN UART_PIN_NO_CHANGE +#define TX1_PIN UART_PIN_NO_CHANGE +#endif +uart_port_t uartnum = UART_NUM_0; +static QueueHandle_t uart_queue; +uint8_t* data = NULL; #else #endif @@ -184,6 +200,44 @@ static void console_cb_read(int fd, void *param) } #endif +#ifdef PLATFORM_ESPIDF + +static void uart_event_task(void* pvParameters) +{ + uart_event_t event; + for(;;) + { + if(xQueueReceive(uart_queue, (void*)&event, (TickType_t)portMAX_DELAY)) + { + bzero(data, 256); + switch(event.type) + { + case UART_DATA: + uart_read_bytes(uartnum, data, event.size, portMAX_DELAY); + for(int i = 0; i < event.size; i++) + { + UART_AppendByteToReceiveRingBuffer(data[i]); + vTaskDelay(3); + } + break; + case UART_BUFFER_FULL: + case UART_FIFO_OVF: + addLogAdv(LOG_WARN, LOG_FEATURE_CMD, "%s", event.type == UART_BUFFER_FULL ? "UART_BUFFER_FULL" : "UART_FIFO_OVF"); + uart_flush_input(uartnum); + xQueueReset(uart_queue); + break; + default: + break; + } + } + } + free(data); + data = NULL; + vTaskDelete(NULL); +} + +#endif + void UART_SendByte(byte b) { #if PLATFORM_BK7231T | PLATFORM_BK7231N // BK_UART_1 is defined to 0 @@ -199,6 +253,8 @@ void UART_SendByte(byte b) { #elif PLATFORM_BL602 aos_write(fd_console, &b, 1); //bl_uart_data_send(g_id, b); +#elif PLATFORM_ESPIDF + uart_write_bytes(uartnum, &b, 1); #endif } commandResult_t CMD_UART_Send_Hex(const void *context, const char *cmd, const char *args, int cmdFlags) { @@ -278,54 +334,101 @@ void UART_ResetForSimulator() { g_uart_init_counter = 0; } -int UART_InitUART(int baud, int parity) { +int UART_InitUART(int baud, int parity) +{ g_uart_init_counter++; #if PLATFORM_BK7231T | PLATFORM_BK7231N bk_uart_config_t config; config.baud_rate = baud; config.data_width = 0x03; - config.parity = parity; //0:no parity,1:odd,2:even - config.stop_bits = 0; //0:1bit,1:2bit - config.flow_control = 0; //FLOW_CTRL_DISABLED + config.parity = parity; //0:no parity,1:odd,2:even + config.stop_bits = 0; //0:1bit,1:2bit + config.flow_control = 0; //FLOW_CTRL_DISABLED config.flags = 0; // BK_UART_1 is defined to 0 - if (CFG_HasFlag(OBK_FLAG_USE_SECONDARY_UART)) { + if(CFG_HasFlag(OBK_FLAG_USE_SECONDARY_UART)) + { g_chosenUART = BK_UART_2; - } - else { + } + else + { g_chosenUART = BK_UART_1; } bk_uart_initialize(g_chosenUART, &config, NULL); - bk_uart_set_rx_callback(g_chosenUART, test_ty_read_uart_data_to_buffer, NULL); + bk_uart_set_rx_callback(g_chosenUART, test_ty_read_uart_data_to_buffer, NULL); #elif PLATFORM_BL602 - if (fd_console < 0) { - //uint8_t tx_pin = 16; - //uint8_t rx_pin = 7; - //bl_uart_init(g_id, tx_pin, rx_pin, 0, 0, baud); - //g_fd = aos_open(name, 0); - //bl_uart_int_rx_enable(1); - //bl_irq_register(UART1_IRQn, MY_UART1_IRQHandler); - //bl_irq_enable(UART1_IRQn); - //vfs_uart_init_simple_mode(0, 7, 16, baud, "/dev/ttyS0"); - - if (CFG_HasFlag(OBK_FLAG_USE_SECONDARY_UART)) { + if(fd_console < 0) + { + //uint8_t tx_pin = 16; + //uint8_t rx_pin = 7; + //bl_uart_init(g_id, tx_pin, rx_pin, 0, 0, baud); + //g_fd = aos_open(name, 0); + //bl_uart_int_rx_enable(1); + //bl_irq_register(UART1_IRQn, MY_UART1_IRQHandler); + //bl_irq_enable(UART1_IRQn); + //vfs_uart_init_simple_mode(0, 7, 16, baud, "/dev/ttyS0"); + + if(CFG_HasFlag(OBK_FLAG_USE_SECONDARY_UART)) + { fd_console = aos_open("/dev/ttyS1", 0); - } - else { + } + else + { fd_console = aos_open("/dev/ttyS0", 0); } - if (fd_console >= 0) { + if(fd_console >= 0) + { aos_ioctl(fd_console, IOCTL_UART_IOC_BAUD_MODE, baud); - addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "Init CLI with event Driven\r\n"); + addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "Init CLI with event Driven\r\n"); aos_cli_init(0); - aos_poll_read_fd(fd_console, console_cb_read, (void*)0x12345678); - } - else { - addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "failed CLI with event Driven\r\n"); + aos_poll_read_fd(fd_console, console_cb_read, (void*)0x12345678); } + else + { + addLogAdv(LOG_INFO, LOG_FEATURE_ENERGYMETER, "failed CLI with event Driven\r\n"); + } + } +#elif PLATFORM_ESPIDF + if(CFG_HasFlag(OBK_FLAG_USE_SECONDARY_UART)) + { + uartnum = UART_NUM_1; + esp_log_level_set("*", ESP_LOG_INFO); + } + else + { + uartnum = UART_NUM_0; + esp_log_level_set("*", ESP_LOG_NONE); + } + if(uart_is_driver_installed(uartnum)) + { + uart_driver_delete(uartnum); + } + uart_config_t uart_config = + { + .baud_rate = baud, + .data_bits = UART_DATA_8_BITS, + .parity = parity > 0 ? parity + 1 : parity, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_DEFAULT, + }; + uart_driver_install(uartnum, 256, 0, 20, &uart_queue, 0); + uart_param_config(uartnum, &uart_config); + if(uartnum == UART_NUM_0) + { + uart_set_pin(uartnum, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + } + else + { + uart_set_pin(uartnum, TX1_PIN, RX1_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); + } + if(data == NULL) + { + data = (uint8_t*)malloc(256); + xTaskCreate(uart_event_task, "uart_event_task", 1024, NULL, 16, NULL); } #endif return g_uart_init_counter; @@ -373,9 +476,10 @@ commandResult_t CMD_UART_Init(const void *context, const char *cmd, const char * baud = Tokenizer_GetArgInteger(0); + UART_InitReceiveRingBuffer(512); + UART_InitUART(baud, 0); g_uart_manualInitCounter = g_uart_init_counter; - UART_InitReceiveRingBuffer(512); return CMD_RES_OK; } diff --git a/src/hal/espidf/hal_adc_espidf.c b/src/hal/espidf/hal_adc_espidf.c new file mode 100644 index 000000000..4fc277b4d --- /dev/null +++ b/src/hal/espidf/hal_adc_espidf.c @@ -0,0 +1,110 @@ +#ifdef PLATFORM_ESPIDF + +#include "../hal_adc.h" +#include "../../logging/logging.h" +#include "esp_adc/adc_oneshot.h" +#include "esp_adc/adc_cali.h" +#include "esp_adc/adc_cali_scheme.h" +#include "hal_generic_espidf.h" + +extern espPinMapping_t g_pins[]; +extern int g_numPins; + +adc_oneshot_unit_handle_t adc1_handle; +adc_oneshot_unit_handle_t adc2_handle; +static bool g_adc1_conf = false, g_adc2_conf = false; + +void adc_err(int pin) +{ + ADDLOG_ERROR(LOG_FEATURE_PINS, "Selected pin (%i) is neither ADC1 or ADC2", pin); +} + +void HAL_ADC_Init(int pinNumber) +{ + if(pinNumber >= g_numPins) + return; + espPinMapping_t* pin = g_pins + pinNumber; + + adc_channel_t channel; + adc_unit_t unit_id; + esp_err_t err = adc_oneshot_io_to_channel(pin->pin, &unit_id, &channel); + if(err != ESP_OK) + { + adc_err(pin->pin); + return; + } + else + { + adc_oneshot_unit_init_cfg_t init_config = + { + .unit_id = unit_id, + .ulp_mode = ADC_ULP_MODE_DISABLE, + }; + if(unit_id == ADC_UNIT_1 && !g_adc1_conf) + { + adc_oneshot_new_unit(&init_config, &adc1_handle); + ADDLOG_DEBUG(LOG_FEATURE_PINS, "Init ADC1"); + g_adc1_conf = true; + } + else if(unit_id == ADC_UNIT_2 && !g_adc2_conf) + { + adc_oneshot_new_unit(&init_config, &adc2_handle); + ADDLOG_DEBUG(LOG_FEATURE_PINS, "Init ADC2"); + g_adc2_conf = true; + } + } + + adc_oneshot_chan_cfg_t config = + { + .atten = ADC_ATTEN_DB_12, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + + if(unit_id == ADC_UNIT_1) + { + adc_oneshot_config_channel(adc1_handle, channel, &config); + } + else if(unit_id == ADC_UNIT_2) + { + adc_oneshot_config_channel(adc2_handle, channel, &config); + } + else + { + adc_err(pin->pin); + return; + } + ADDLOG_DEBUG(LOG_FEATURE_PINS, "Init ADC%d Channel[%d]", unit_id + 1, channel); +} + +int HAL_ADC_Read(int pinNumber) +{ + if(pinNumber >= g_numPins) + return 0; + espPinMapping_t* pin = g_pins + pinNumber; + int raw = 0; + adc_channel_t channel; + adc_unit_t unit_id; + esp_err_t err = adc_oneshot_io_to_channel(pin->pin, &unit_id, &channel); + if(err != ESP_OK) + { + adc_err(pin->pin); + } + else + { + if(unit_id == ADC_UNIT_1) + { + adc_oneshot_read(adc1_handle, channel, &raw); + } + else if(unit_id == ADC_UNIT_2) + { + adc_oneshot_read(adc2_handle, channel, &raw); + } + else + { + adc_err(pin->pin); + } + } + return raw; +} + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_flashConfig_espidf.c b/src/hal/espidf/hal_flashConfig_espidf.c new file mode 100644 index 000000000..7c590f8b7 --- /dev/null +++ b/src/hal/espidf/hal_flashConfig_espidf.c @@ -0,0 +1,32 @@ +#ifdef PLATFORM_ESPIDF + +#include "../hal_flashConfig.h" +#include "nvs_flash.h" +#include "nvs.h" + +void InitFlashIfNeeded(); + +int HAL_Configuration_ReadConfigMemory(void* target, int dataLen) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + nvs_get_blob(handle, "cfg", target, (size_t*) &dataLen); + nvs_close(handle); + + return dataLen; +} + +int HAL_Configuration_SaveConfigMemory(void* src, int dataLen) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_set_blob(handle, "cfg", src, dataLen); + nvs_commit(handle); + nvs_close(handle); + + return dataLen; +} + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_flashVars_espidf.c b/src/hal/espidf/hal_flashVars_espidf.c new file mode 100644 index 000000000..b7403ae85 --- /dev/null +++ b/src/hal/espidf/hal_flashVars_espidf.c @@ -0,0 +1,165 @@ +#ifdef PLATFORM_ESPIDF + +#include "../../new_cfg.h" +#include "../../logging/logging.h" +#include "../../new_common.h" +#include "../hal_flashVars.h" +#include "nvs_flash.h" +#include "nvs.h" + +void InitFlashIfNeeded(); + +void HAL_FlashVars_IncreaseBootCount() +{ + uint32_t bootc = 0; + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_get_u32(handle, "bootc", &bootc); + nvs_set_u32(handle, "bootc", ++bootc); + nvs_commit(handle); + nvs_close(handle); +} + +int HAL_FlashVars_GetChannelValue(int ch) +{ + char channel[4]; + sprintf(channel, "ch%i", ch); + int32_t value = 0; + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + nvs_get_i32(handle, channel, &value); + nvs_close(handle); + return value; +} + +void HAL_FlashVars_SaveChannel(int index, int value) +{ + char channel[4]; + sprintf(channel, "ch%i", index); + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_set_i16(handle, channel, value); + nvs_commit(handle); + nvs_close(handle); +} + +void HAL_FlashVars_ReadLED(byte* mode, short* brightness, short* temperature, byte* rgb, byte* bEnableAll) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + nvs_get_u8(handle, "mode", mode); + nvs_get_i16(handle, "brs", brightness); + nvs_get_i16(handle, "temp", temperature); + nvs_get_u8(handle, "r", &rgb[0]); + nvs_get_u8(handle, "g", &rgb[1]); + nvs_get_u8(handle, "b", &rgb[2]); + nvs_get_u8(handle, "ena", bEnableAll); + nvs_close(handle); +} + + +void HAL_FlashVars_SaveLED(byte mode, short brightness, short temperature, byte r, byte g, byte b, byte bEnableAll) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_set_u8(handle, "mode", mode); + nvs_set_i16(handle, "brs", brightness); + nvs_set_i16(handle, "temp", temperature); + nvs_set_u8(handle, "r", r); + nvs_set_u8(handle, "g", g); + nvs_set_u8(handle, "b", b); + nvs_set_u8(handle, "ena", bEnableAll); + nvs_commit(handle); + nvs_close(handle); +} + +short HAL_FlashVars_ReadUsage() +{ + short usage = 0; + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + nvs_get_i16(handle, "tu", &usage); + nvs_close(handle); + return usage; +} + +void HAL_FlashVars_SaveTotalUsage(short usage) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_set_i16(handle, "tu", usage); + nvs_commit(handle); + nvs_close(handle); +} + +void HAL_FlashVars_SaveBootComplete() +{ + uint32_t bootc = 0; + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_get_u32(handle, "bootc", &bootc); + nvs_set_u32(handle, "bootsc", bootc); + nvs_commit(handle); + nvs_close(handle); +} + +// call to return the number of boots since a HAL_FlashVars_SaveBootComplete +int HAL_FlashVars_GetBootFailures() +{ + uint32_t bootc = 0, bootsc = 0; + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + nvs_get_u32(handle, "bootc", &bootc); + nvs_get_u32(handle, "bootsc", &bootsc); + nvs_close(handle); + return bootc - bootsc; +} + +int HAL_FlashVars_GetBootCount() +{ + uint32_t bootc = 0; + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + nvs_get_u32(handle, "bootc", &bootc); + nvs_close(handle); + return bootc; +} + +int HAL_GetEnergyMeterStatus(ENERGY_METERING_DATA* data) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READONLY, &handle); + size_t size = sizeof(data); + nvs_get_blob(handle, "emd", data, &size); + nvs_close(handle); + return 0; +} + +int HAL_SetEnergyMeterStatus(ENERGY_METERING_DATA* data) +{ + InitFlashIfNeeded(); + nvs_handle_t handle = 0; + nvs_open("config", NVS_READWRITE, &handle); + nvs_set_blob(handle, "emd", data, sizeof(data)); + nvs_commit(handle); + nvs_close(handle); + return 0; +} + +void HAL_FlashVars_SaveTotalConsumption(float total_consumption) +{ + +} + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_generic_espidf.c b/src/hal/espidf/hal_generic_espidf.c new file mode 100644 index 000000000..de5ae3265 --- /dev/null +++ b/src/hal/espidf/hal_generic_espidf.c @@ -0,0 +1,30 @@ +#ifdef PLATFORM_ESPIDF + +#include "esp_system.h" +#include "nvs_flash.h" +#include "nvs.h" + +static int bFlashReady = 0; + +void InitFlashIfNeeded() +{ + if(bFlashReady) + return; + + esp_err_t ret = nvs_flash_init(); + if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) + { + nvs_flash_erase(); + nvs_flash_init(); + } + + bFlashReady = 1; + +} + +void HAL_RebootModule() +{ + esp_restart(); +} + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_generic_espidf.h b/src/hal/espidf/hal_generic_espidf.h new file mode 100644 index 000000000..b67dfa5bb --- /dev/null +++ b/src/hal/espidf/hal_generic_espidf.h @@ -0,0 +1,12 @@ +#ifdef PLATFORM_ESPIDF + +#include "driver/gpio.h" + +typedef struct espPinMapping_s +{ + const char* name; + gpio_num_t pin; + bool isConfigured; +} espPinMapping_t; + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_main_espidf.c b/src/hal/espidf/hal_main_espidf.c new file mode 100644 index 000000000..48f83c437 --- /dev/null +++ b/src/hal/espidf/hal_main_espidf.c @@ -0,0 +1,7 @@ +#ifdef PLATFORM_ESPIDF + +#include "../../new_common.h" +#include "../../logging/logging.h" +#include "../../quicktick.h" + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_pins_espidf.c b/src/hal/espidf/hal_pins_espidf.c new file mode 100644 index 000000000..da1e1eea9 --- /dev/null +++ b/src/hal/espidf/hal_pins_espidf.c @@ -0,0 +1,504 @@ +#ifdef PLATFORM_ESPIDF + +#include "../../new_common.h" +#include "../../logging/logging.h" +#include "../../new_cfg.h" +#include "../../new_pins.h" +#include "driver/gpio.h" +#include "driver/ledc.h" +#include "hal_generic_espidf.h" + +#define LEDC_MAX_CH 6 + +#ifdef CONFIG_IDF_TARGET_ESP32C3 + +espPinMapping_t g_pins[] = { + { "IO0", GPIO_NUM_0, false }, + { "IO1", GPIO_NUM_1, false }, + { "IO2", GPIO_NUM_2, false }, + { "IO3", GPIO_NUM_3, false }, + { "IO4", GPIO_NUM_4, false }, + { "IO5", GPIO_NUM_5, false }, + { "IO6", GPIO_NUM_6, false }, + { "IO7", GPIO_NUM_7, false }, + { "IO8", GPIO_NUM_8, false }, + { "IO9", GPIO_NUM_9, false }, + { "IO10", GPIO_NUM_10, false }, + // SPI flash 11-17 + { "IO11", GPIO_NUM_11, false }, + { "IO12", GPIO_NUM_12, false }, + { "IO13", GPIO_NUM_13, false }, + { "IO14", GPIO_NUM_14, false }, + { "IO15", GPIO_NUM_15, false }, + { "IO16", GPIO_NUM_16, false }, + { "IO17", GPIO_NUM_17, false }, + { "IO18", GPIO_NUM_18, false }, + { "IO19", GPIO_NUM_19, false }, + { "IO20 (RX)", GPIO_NUM_20, false }, + { "IO21 (TX)", GPIO_NUM_21, false }, +}; + +#elif CONFIG_IDF_TARGET_ESP32C2 + +espPinMapping_t g_pins[] = { + { "IO0", GPIO_NUM_0, false }, + { "IO1", GPIO_NUM_1, false }, + { "IO2", GPIO_NUM_2, false }, + { "IO3", GPIO_NUM_3, false }, + { "IO4", GPIO_NUM_4, false }, + { "IO5", GPIO_NUM_5, false }, + { "IO6", GPIO_NUM_6, false }, + { "IO7", GPIO_NUM_7, false }, + { "IO8", GPIO_NUM_8, false }, + { "IO9", GPIO_NUM_9, false }, + { "IO10", GPIO_NUM_10, false }, + { "IO11", GPIO_NUM_11, false }, + { "IO12", GPIO_NUM_12, false }, + { "IO13", GPIO_NUM_13, false }, + { "IO14", GPIO_NUM_14, false }, + { "IO15", GPIO_NUM_15, false }, + { "IO16", GPIO_NUM_16, false }, + { "IO17", GPIO_NUM_17, false }, + { "IO18", GPIO_NUM_18, false }, + { "IO19", GPIO_NUM_19, false }, + { "IO20", GPIO_NUM_20, false }, +}; + +#elif CONFIG_IDF_TARGET_ESP32C6 + +espPinMapping_t g_pins[] = { + { "IO0", GPIO_NUM_0, false }, + { "IO1", GPIO_NUM_1, false }, + { "IO2", GPIO_NUM_2, false }, + { "IO3", GPIO_NUM_3, false }, + { "IO4", GPIO_NUM_4, false }, + { "IO5", GPIO_NUM_5, false }, + { "IO6", GPIO_NUM_6, false }, + { "IO7", GPIO_NUM_7, false }, + { "IO8", GPIO_NUM_8, false }, + { "IO9", GPIO_NUM_9, false }, + { "IO10", GPIO_NUM_10, false }, + { "IO11", GPIO_NUM_11, false }, + { "IO12", GPIO_NUM_12, false }, + { "IO13", GPIO_NUM_13, false }, + { "IO14", GPIO_NUM_14, false }, + { "IO15", GPIO_NUM_15, false }, + { "IO16", GPIO_NUM_16, false }, + { "IO17", GPIO_NUM_17, false }, + { "IO18", GPIO_NUM_18, false }, + { "IO19", GPIO_NUM_19, false }, + { "IO20", GPIO_NUM_20, false }, + { "IO21", GPIO_NUM_21, false }, + { "IO22", GPIO_NUM_22, false }, + { "IO23", GPIO_NUM_23, false }, + { "IO24", GPIO_NUM_24, false }, + { "IO25", GPIO_NUM_25, false }, + { "IO26", GPIO_NUM_26, false }, + { "IO27", GPIO_NUM_27, false }, + { "IO28", GPIO_NUM_28, false }, + { "IO29", GPIO_NUM_29, false }, + { "IO30", GPIO_NUM_30, false }, +}; + +#elif CONFIG_IDF_TARGET_ESP32S2 + +espPinMapping_t g_pins[] = { + { "IO0", GPIO_NUM_0, false }, + { "IO1", GPIO_NUM_1, false }, + { "IO2", GPIO_NUM_2, false }, + { "IO3", GPIO_NUM_3, false }, + { "IO4", GPIO_NUM_4, false }, + { "IO5", GPIO_NUM_5, false }, + { "IO6", GPIO_NUM_6, false }, + { "IO7", GPIO_NUM_7, false }, + { "IO8", GPIO_NUM_8, false }, + { "IO9", GPIO_NUM_9, false }, + { "IO10", GPIO_NUM_10, false }, + { "IO11", GPIO_NUM_11, false }, + { "IO12", GPIO_NUM_12, false }, + { "IO13", GPIO_NUM_13, false }, + { "IO14", GPIO_NUM_14, false }, + { "IO15", GPIO_NUM_15, false }, + { "IO16", GPIO_NUM_16, false }, + { "IO17", GPIO_NUM_17, false }, + { "IO18", GPIO_NUM_18, false }, + { "IO19", GPIO_NUM_19, false }, + { "IO20", GPIO_NUM_20, false }, + { "IO21", GPIO_NUM_21, false }, + { "NC", GPIO_NUM_NC, true }, + { "NC", GPIO_NUM_NC, true }, + { "NC", GPIO_NUM_NC, true }, + { "NC", GPIO_NUM_NC, true }, + { "IO26", GPIO_NUM_26, false }, + { "IO27", GPIO_NUM_27, false }, + { "IO28", GPIO_NUM_28, false }, + { "IO29", GPIO_NUM_29, false }, + { "IO30", GPIO_NUM_30, false }, + { "IO31", GPIO_NUM_31, false }, + { "IO32", GPIO_NUM_32, false }, + { "IO33", GPIO_NUM_33, false }, + { "IO34", GPIO_NUM_34, false }, + { "IO35", GPIO_NUM_35, false }, + { "IO36", GPIO_NUM_36, false }, + { "IO37", GPIO_NUM_37, false }, + { "IO38", GPIO_NUM_38, false }, + { "IO39", GPIO_NUM_39, false }, + { "IO40", GPIO_NUM_40, false }, + { "IO41", GPIO_NUM_41, false }, + { "IO42", GPIO_NUM_42, false }, + { "IO43", GPIO_NUM_43, false }, + { "IO44", GPIO_NUM_44, false }, + { "IO45", GPIO_NUM_45, false }, + { "IO46", GPIO_NUM_46, false }, +}; + +#elif CONFIG_IDF_TARGET_ESP32S3 + +espPinMapping_t g_pins[] = { + { "IO0", GPIO_NUM_0, false }, + { "IO1", GPIO_NUM_1, false }, + { "IO2", GPIO_NUM_2, false }, + { "IO3", GPIO_NUM_3, false }, + { "IO4", GPIO_NUM_4, false }, + { "IO5", GPIO_NUM_5, false }, + { "IO6", GPIO_NUM_6, false }, + { "IO7", GPIO_NUM_7, false }, + { "IO8", GPIO_NUM_8, false }, + { "IO9", GPIO_NUM_9, false }, + { "IO10", GPIO_NUM_10, false }, + { "IO11", GPIO_NUM_11, false }, + { "IO12", GPIO_NUM_12, false }, + { "IO13", GPIO_NUM_13, false }, + { "IO14", GPIO_NUM_14, false }, + { "IO15", GPIO_NUM_15, false }, + { "IO16", GPIO_NUM_16, false }, + { "IO17", GPIO_NUM_17, false }, + { "IO18", GPIO_NUM_18, false }, + { "IO19", GPIO_NUM_19, false }, + { "IO20", GPIO_NUM_20, false }, + { "IO21", GPIO_NUM_21, false }, + { "NC", GPIO_NUM_NC, true }, + { "NC", GPIO_NUM_NC, true }, + { "NC", GPIO_NUM_NC, true }, + { "NC", GPIO_NUM_NC, true }, + { "IO26", GPIO_NUM_26, false }, + { "IO27", GPIO_NUM_27, false }, + { "IO28", GPIO_NUM_28, false }, + { "IO29", GPIO_NUM_29, false }, + { "IO30", GPIO_NUM_30, false }, + { "IO31", GPIO_NUM_31, false }, + { "IO32", GPIO_NUM_32, false }, + { "IO33", GPIO_NUM_33, false }, + { "IO34", GPIO_NUM_34, false }, + { "IO35", GPIO_NUM_35, false }, + { "IO36", GPIO_NUM_36, false }, + { "IO37", GPIO_NUM_37, false }, + { "IO38", GPIO_NUM_38, false }, + { "IO39", GPIO_NUM_39, false }, + { "IO40", GPIO_NUM_40, false }, + { "IO41", GPIO_NUM_41, false }, + { "IO42", GPIO_NUM_42, false }, + { "IO43", GPIO_NUM_43, false }, + { "IO44", GPIO_NUM_44, false }, + { "IO45", GPIO_NUM_45, false }, + { "IO46", GPIO_NUM_46, false }, + { "IO47", GPIO_NUM_47, false }, + { "IO48", GPIO_NUM_48, false }, +}; + +#elif CONFIG_IDF_TARGET_ESP32 + +espPinMapping_t g_pins[] = { + { "IO0", GPIO_NUM_0, false }, + { "IO1", GPIO_NUM_1, false }, + { "IO2", GPIO_NUM_2, false }, + { "IO3", GPIO_NUM_3, false }, + { "IO4", GPIO_NUM_4, false }, + { "IO5", GPIO_NUM_5, false }, + { "IO6", GPIO_NUM_6, false }, + { "IO7", GPIO_NUM_7, false }, + { "IO8", GPIO_NUM_8, false }, + { "IO9", GPIO_NUM_9, false }, + { "IO10", GPIO_NUM_10, false }, + { "IO11", GPIO_NUM_11, false }, + { "IO12", GPIO_NUM_12, false }, + { "IO13", GPIO_NUM_13, false }, + { "IO14", GPIO_NUM_14, false }, + { "IO15", GPIO_NUM_15, false }, + { "IO16", GPIO_NUM_16, false }, + { "IO17", GPIO_NUM_17, false }, + { "IO18", GPIO_NUM_18, false }, + { "IO19", GPIO_NUM_19, false }, + { "IO20", GPIO_NUM_20, false }, + { "IO21", GPIO_NUM_21, false }, + { "IO22", GPIO_NUM_22, false }, + { "IO23", GPIO_NUM_23, false }, + { "NC", GPIO_NUM_NC, true }, + { "IO25", GPIO_NUM_25, false }, + { "IO26", GPIO_NUM_26, false }, + { "IO27", GPIO_NUM_27, false }, + { "IO28", GPIO_NUM_28, false }, + { "IO29", GPIO_NUM_29, false }, + { "IO30", GPIO_NUM_30, false }, + { "IO31", GPIO_NUM_31, false }, + { "IO32", GPIO_NUM_32, false }, + { "IO33", GPIO_NUM_33, false }, + { "IO34", GPIO_NUM_34, false }, + { "IO35", GPIO_NUM_35, false }, + { "IO36", GPIO_NUM_36, false }, + { "IO37", GPIO_NUM_37, false }, + { "IO38", GPIO_NUM_38, false }, + { "IO39", GPIO_NUM_39, false }, +}; + +#else + +espPinMapping_t g_pins[] = { }; + +#endif + +int g_numPins = sizeof(g_pins) / sizeof(g_pins[0]); + +static ledc_channel_config_t ledc_channel[LEDC_MAX_CH]; +static bool g_ledc_init = false; + +void InitLEDC() +{ + if(!g_ledc_init) + { + ledc_timer_config_t ledc_timer = + { + .duty_resolution = LEDC_TIMER_13_BIT, + .freq_hz = 1000, + .speed_mode = LEDC_LOW_SPEED_MODE, + .timer_num = LEDC_TIMER_0, + .clk_cfg = SOC_MOD_CLK_RC_FAST, + }; + ledc_timer_config(&ledc_timer); + for(int i = 0; i < LEDC_MAX_CH; i++) + { + ledc_channel[i].channel = i; + ledc_channel[i].duty = 0; + ledc_channel[i].gpio_num = GPIO_NUM_NC; + ledc_channel[i].speed_mode = LEDC_LOW_SPEED_MODE; + ledc_channel[i].hpoint = 0; + ledc_channel[i].timer_sel = LEDC_TIMER_0; + ledc_channel[i].intr_type = LEDC_INTR_DISABLE; + } + g_ledc_init = true; + } +} + +int GetAvailableLedcChannel() +{ + for(int i = 0; i < LEDC_MAX_CH; i++) + { + if(ledc_channel[i].gpio_num == GPIO_NUM_NC) + { + return ledc_channel[i].channel; + } + } + return -1; +} + +int GetLedcChannelForPin(gpio_num_t pin) +{ + for(int i = 0; i < LEDC_MAX_CH; i++) + { + if(ledc_channel[i].gpio_num == pin) + { + return ledc_channel[i].channel; + } + } + return -1; +} + +int PIN_GetPWMIndexForPinIndex(int index) +{ + if(index >= g_numPins) + return -1; + espPinMapping_t* pin = g_pins + index; + int ch = GetLedcChannelForPin(pin->pin); + if(ch >= 0) + { + return ch; + } + return -1; +} + +const char* HAL_PIN_GetPinNameAlias(int index) +{ + if(index >= g_numPins) + return "error"; + return g_pins[index].name; +} + +int HAL_PIN_CanThisPinBePWM(int index) +{ + if(index >= g_numPins) + return 0; + espPinMapping_t* pin = g_pins + index; + if(pin->pin != GPIO_NUM_NC) return 1; + else return 0; +} + +void HAL_PIN_SetOutputValue(int index, int iVal) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + if(pin->pin == GPIO_NUM_NC) return; + gpio_set_level(pin->pin, iVal ? 1 : 0); +} + +int HAL_PIN_ReadDigitalInput(int index) +{ + if(index >= g_numPins) + return 0; + espPinMapping_t* pin = g_pins + index; + if(pin->pin == GPIO_NUM_NC) return 0; + return gpio_get_level(pin->pin); +} + +void ESP_ConfigurePin(gpio_num_t pin, gpio_mode_t mode, bool pup, bool pdown) +{ + gpio_config_t conf = {}; + conf.pin_bit_mask = 1ULL << (uint32_t)pin; + conf.mode = mode; + conf.pull_up_en = pup ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE; + conf.pull_down_en = pdown ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE; + conf.intr_type = GPIO_INTR_DISABLE; + gpio_config(&conf); +} + +void HAL_PIN_Setup_Input_Pullup(int index) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + if(pin->pin == GPIO_NUM_NC) return; + if(!pin->isConfigured) + { + pin->isConfigured = true; + ESP_ConfigurePin(pin->pin, GPIO_MODE_INPUT, true, false); + return; + } + gpio_set_direction(pin->pin, GPIO_MODE_INPUT); + gpio_set_pull_mode(pin->pin, GPIO_PULLUP_ONLY); +} + +void HAL_PIN_Setup_Input_Pulldown(int index) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + if(pin->pin == GPIO_NUM_NC) return; + if(!pin->isConfigured) + { + pin->isConfigured = true; + ESP_ConfigurePin(pin->pin, GPIO_MODE_INPUT, false, true); + return; + } + gpio_set_direction(pin->pin, GPIO_MODE_INPUT); + gpio_set_pull_mode(pin->pin, GPIO_PULLDOWN_ONLY); +} + +void HAL_PIN_Setup_Input(int index) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + if(pin->pin == GPIO_NUM_NC) return; + if(!pin->isConfigured) + { + pin->isConfigured = true; + ESP_ConfigurePin(pin->pin, GPIO_MODE_INPUT, false, false); + return; + } + gpio_set_direction(pin->pin, GPIO_MODE_INPUT); + gpio_set_pull_mode(pin->pin, GPIO_FLOATING); +} + +void HAL_PIN_Setup_Output(int index) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + if(pin->pin == GPIO_NUM_NC) return; + if(!pin->isConfigured) + { + pin->isConfigured = true; + ESP_ConfigurePin(pin->pin, GPIO_MODE_OUTPUT, true, false); + return; + } + gpio_set_direction(pin->pin, GPIO_MODE_OUTPUT); + gpio_set_pull_mode(pin->pin, GPIO_PULLUP_ONLY); + gpio_set_level(pin->pin, 0); +} + +void HAL_PIN_PWM_Stop(int index) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + int ch = GetLedcChannelForPin(pin->pin); + if(ch >= 0) + { + ledc_stop(LEDC_LOW_SPEED_MODE, ch, 0); + gpio_reset_pin(pin->pin); + pin->isConfigured = false; + ledc_channel[ch].gpio_num = GPIO_NUM_NC; + } +} + +void HAL_PIN_PWM_Start(int index) +{ + if(index >= g_numPins) + return; + InitLEDC(); + espPinMapping_t* pin = g_pins + index; + int freecha = GetAvailableLedcChannel(); + if(freecha >= 0) + { + ledc_channel[freecha].gpio_num = pin->pin; + ledc_channel_config(&ledc_channel[freecha]); + ADDLOG_INFO(LOG_FEATURE_PINS, "init ledc ch %i pin %i\n", freecha, pin->pin); + } + else + { + ADDLOG_ERROR(LOG_FEATURE_PINS, "PWM_Start: no free ledc channels for pin %i", pin->pin); + } +} + +void HAL_PIN_PWM_Update(int index, float value) +{ + if(index >= g_numPins) + return; + espPinMapping_t* pin = g_pins + index; + int ch = GetLedcChannelForPin(pin->pin); + if(ch >= 0) + { + uint32_t curduty = ledc_get_duty(LEDC_LOW_SPEED_MODE, ch); + uint32_t propduty = value * 81.91; + if(propduty != curduty) + { + ledc_set_duty(LEDC_LOW_SPEED_MODE, ch, value * 81.91); + ledc_update_duty(LEDC_LOW_SPEED_MODE, ch); + if(value == 100.0f) + { + ledc_stop(LEDC_LOW_SPEED_MODE, ch, 1); + } + else if(value <= 0.01f) + { + ledc_stop(LEDC_LOW_SPEED_MODE, ch, 0); + } + } + } +} + +unsigned int HAL_GetGPIOPin(int index) +{ + return index; +} + +#endif // PLATFORM_ESPIDF diff --git a/src/hal/espidf/hal_wifi_espidf.c b/src/hal/espidf/hal_wifi_espidf.c new file mode 100644 index 000000000..80f0bcc8a --- /dev/null +++ b/src/hal/espidf/hal_wifi_espidf.c @@ -0,0 +1,241 @@ +#ifdef PLATFORM_ESPIDF + +#include "../../new_cfg.h" +#include "../../logging/logging.h" +#include "../../new_common.h" +#include "../hal_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "esp_event.h" +#include "esp_mac.h" +#include "esp_log.h" +#include "esp_netif.h" +#include "esp_netif_net_stack.h" +#include "lwip/err.h" +#include "lwip/sys.h" + +static void (*g_wifiStatusCallback)(int code); +static int g_bOpenAccessPointMode = 0; +static esp_netif_ip_info_t g_ip_info; +static esp_netif_t* sta_netif = NULL; +static esp_netif_t* ap_netif = NULL; +static char g_ip[16]; +static char g_gw[16]; +static char g_ms[16]; + +// This must return correct IP for both SOFT_AP and STATION modes, +// because, for example, javascript control panel requires it +const char* HAL_GetMyIPString() +{ + sprintf(g_ip, IPSTR, IP2STR(&g_ip_info.ip)); + return g_ip; +} + +const char* HAL_GetMyGatewayString() +{ + sprintf(g_gw, IPSTR, IP2STR(&g_ip_info.gw)); + return g_gw; +} + +const char* HAL_GetMyDNSString() +{ + return "error"; +} + +const char* HAL_GetMyMaskString() +{ + sprintf(g_ms, IPSTR, IP2STR(&g_ip_info.netmask)); + return g_ms; +} + + +int WiFI_SetMacAddress(char* mac) +{ + return 0; +} + +void WiFI_GetMacAddress(char* mac) +{ + esp_read_mac((unsigned char*)mac, ESP_MAC_BASE); +} + +const char* HAL_GetMACStr(char* macstr) +{ + uint8_t mac[6]; + esp_read_mac(mac, ESP_MAC_BASE); + sprintf(macstr, MACSTR, MAC2STR(mac)); + return macstr; +} + +void HAL_PrintNetworkInfo() +{ + uint8_t mac[6]; + esp_read_mac(mac, ESP_MAC_BASE); + bk_printf("+--------------- net device info ------------+\r\n"); + bk_printf("|netif type : %-16s |\r\n", g_bOpenAccessPointMode == 0 ? "STA" : "AP"); + bk_printf("|netif ip = %-16s |\r\n", HAL_GetMyIPString()); + bk_printf("|netif mask = %-16s |\r\n", HAL_GetMyMaskString()); + bk_printf("|netif gateway = %-16s |\r\n", HAL_GetMyGatewayString()); + bk_printf("|netif mac : [%02X:%02X:%02X:%02X:%02X:%02X] %-7s |\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], ""); + bk_printf("+--------------------------------------------+\r\n"); +} + +int HAL_GetWifiStrength() +{ + wifi_ap_record_t ap; + esp_wifi_sta_get_ap_info(&ap); + return ap.rssi; +} + +void HAL_WiFi_SetupStatusCallback(void (*cb)(int code)) +{ + g_wifiStatusCallback = cb; +} + +void event_handler(void* arg, esp_event_base_t event_base, + int32_t event_id, void* event_data) +{ + if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START && !g_bOpenAccessPointMode) + { + if(g_wifiStatusCallback != NULL) + { + g_wifiStatusCallback(WIFI_STA_CONNECTING); + } + ADDLOG_INFO(LOG_FEATURE_MAIN, "WiFi Connecting..."); + esp_wifi_connect(); + } + else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) + { + if(g_wifiStatusCallback != NULL) + { + g_wifiStatusCallback(WIFI_STA_DISCONNECTED); + } + ADDLOG_INFO(LOG_FEATURE_MAIN, "WiFi Disconnected"); + } + else if(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) + { + ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data; + g_ip_info = event->ip_info; + if(g_wifiStatusCallback != NULL) + { + g_wifiStatusCallback(WIFI_STA_CONNECTED); + } + } + else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STACONNECTED) + { + if(g_wifiStatusCallback != NULL) + { + g_wifiStatusCallback(WIFI_AP_CONNECTED); + } + } +} + +void HAL_ConnectToWiFi(const char* oob_ssid, const char* connect_key, obkStaticIP_t* ip) +{ + if(sta_netif != NULL) + { + esp_wifi_stop(); + esp_netif_destroy(sta_netif); + esp_wifi_deinit(); + delay_ms(10); + } + else + { + esp_event_handler_instance_t instance_any_id, instance_got_ip; + + esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id); + esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &event_handler, + NULL, + &instance_got_ip); + } + + sta_netif = esp_netif_create_default_wifi_sta(); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + esp_wifi_init(&cfg); + + wifi_config_t wifi_config; + esp_wifi_get_config(WIFI_IF_STA, &wifi_config); + if(strcmp((char*)wifi_config.sta.ssid, oob_ssid) != 0 || strcmp((char*)wifi_config.sta.password, connect_key) != 0) + { + ADDLOG_ERROR(LOG_FEATURE_MAIN, "WiFi saved ssid/pass != current, resetting"); + memset(&wifi_config.sta, 0, sizeof(wifi_sta_config_t)); + wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + strncpy((char*)wifi_config.sta.ssid, (char*)oob_ssid, 32); + strncpy((char*)wifi_config.sta.password, (char*)connect_key, 64); + } + + esp_netif_set_hostname(sta_netif, CFG_GetDeviceName()); + + esp_wifi_set_config(WIFI_IF_STA, &wifi_config); + esp_wifi_set_mode(WIFI_MODE_STA); + + esp_wifi_start(); +} + +void HAL_DisconnectFromWifi() +{ + esp_wifi_disconnect(); +} + +int HAL_SetupWiFiOpenAccessPoint(const char* ssid) +{ + g_bOpenAccessPointMode = 1; + ap_netif = esp_netif_create_default_wifi_ap(); + esp_netif_create_default_wifi_sta(); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + cfg.nvs_enable = false; + esp_wifi_init(&cfg); + + esp_event_handler_instance_t instance_any_id; + + esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &event_handler, + NULL, + &instance_any_id); + + wifi_config_t wifi_ap_config = + { + .ap = + { + .ssid_len = strlen(ssid), + .channel = 1, + .max_connection = 1, + .authmode = WIFI_AUTH_OPEN, + .pmf_cfg = + { + .required = false, + }, + }, + }; + + wifi_config_t wifi_sta_config = + { + .sta = { }, + }; + strncpy((char*)wifi_ap_config.ap.ssid, (char*)ssid, 32); + esp_netif_set_hostname(ap_netif, CFG_GetDeviceName()); + + esp_wifi_set_config(WIFI_IF_AP, &wifi_ap_config); + esp_wifi_set_config(WIFI_IF_STA, &wifi_sta_config); + esp_wifi_set_mode(WIFI_MODE_APSTA); + esp_wifi_set_max_tx_power(10 * 4); + esp_wifi_start(); + + //esp_netif_set_default_netif(ap_netif); + + esp_netif_get_ip_info(ap_netif, &g_ip_info); + + return 1; +} + +#endif // PLATFORM_ESPIDF diff --git a/src/httpserver/http_fns.c b/src/httpserver/http_fns.c index 76cf0bd4a..8bb48e1b6 100644 --- a/src/httpserver/http_fns.c +++ b/src/httpserver/http_fns.c @@ -39,7 +39,9 @@ static char SUBMIT_AND_END_FORM[] = "
Reboot reason: %i - %s", g_rebootReason, s); } +#elif PLATFORM_ESPIDF + esp_reset_reason_t reason = esp_reset_reason(); + const char* s = "Unknown"; + switch(reason) + { + case ESP_RST_UNKNOWN: s = "ESP_RST_UNKNOWN"; break; + case ESP_RST_POWERON: s = "ESP_RST_POWERON"; break; + case ESP_RST_EXT: s = "ESP_RST_EXT"; break; + case ESP_RST_SW: s = "ESP_RST_SW"; break; + case ESP_RST_PANIC: s = "ESP_RST_PANIC"; break; + case ESP_RST_INT_WDT: s = "ESP_RST_INT_WDT"; break; + case ESP_RST_TASK_WDT: s = "ESP_RST_TASK_WDT"; break; + case ESP_RST_WDT: s = "ESP_RST_WDT"; break; + case ESP_RST_DEEPSLEEP: s = "ESP_RST_DEEPSLEEP"; break; + case ESP_RST_BROWNOUT: s = "ESP_RST_BROWNOUT"; break; + case ESP_RST_SDIO: s = "ESP_RST_SDIO"; break; + case ESP_RST_USB: s = "ESP_RST_USB"; break; + case ESP_RST_JTAG: s = "ESP_RST_JTAG"; break; + case ESP_RST_EFUSE: s = "ESP_RST_EFUSE"; break; + case ESP_RST_PWR_GLITCH: s = "ESP_RST_PWR_GLITCH"; break; + case ESP_RST_CPU_LOCKUP: s = "ESP_RST_CPU_LOCKUP"; break; + default: break; + } + hprintf255(request, "
Reboot reason: %i - %s
", reason, s); #endif if (CFG_GetMQTTHost()[0] == 0) { hprintf255(request, "
MQTT State: not configured
"); @@ -1258,6 +1284,20 @@ int http_fn_cfg_wifi(http_request_t* request) { #elif PLATFORM_LN882H // TODO:LN882H action poststr(request, "TODO LN882H
"); +#elif PLATFORM_ESPIDF + // doesn't work in ap mode, only sta/apsta + uint16_t ap_count = 0, number = 30; + wifi_ap_record_t ap_info[number]; + memset(ap_info, 0, sizeof(ap_info)); + bk_printf("Scan begin...\r\n"); + esp_wifi_scan_start(NULL, true); + esp_wifi_scan_get_ap_num(&ap_count); + bk_printf("Scan returned %i networks, max allowed: %i\r\n", ap_count, number); + esp_wifi_scan_get_ap_records(&number, ap_info); + for(int i = 0; i < number; i++) + { + hprintf255(request, "[%i/%u] SSID: %s, Channel: %i, Signal %i
", i + 1, number, ap_info[i].ssid, ap_info[i].primary, ap_info[i].rssi); + } #else #error "Unknown platform" poststr(request, "Unknown platform
"); @@ -2930,7 +2970,7 @@ void OTA_RequestDownloadFromHTTP(const char* s) { #elif PLATFORM_LN882H - +#elif PLATFORM_ESPIDF #elif PLATFORM_W600 || PLATFORM_W800 t_http_fwup(s); #elif PLATFORM_XR809 diff --git a/src/httpserver/new_http.c b/src/httpserver/new_http.c index 95e7786cb..97ea7d76f 100644 --- a/src/httpserver/new_http.c +++ b/src/httpserver/new_http.c @@ -287,6 +287,10 @@ void http_html_end(http_request_t* request) { poststr(request, upTimeStr); snprintf(upTimeStr, sizeof(upTimeStr), "
Short name: %s, Chipset %s", CFG_GetShortDeviceName(), PLATFORM_MCU_NAME); poststr(request, upTimeStr); +#ifdef PLATFORM_ESPIDF + snprintf(upTimeStr, sizeof(upTimeStr), " ESP-IDF %s", esp_get_idf_version()); + poststr(request, upTimeStr); +#endif poststr(request, htmlBodyEnd); poststr(request, pageScriptPart1); diff --git a/src/httpserver/rest_interface.c b/src/httpserver/rest_interface.c index 978362521..6d6a851da 100644 --- a/src/httpserver/rest_interface.c +++ b/src/httpserver/rest_interface.c @@ -48,6 +48,8 @@ uint32_t flash_read(uint32_t flash, uint32_t addr, void* buf, uint32_t size); #elif PLATFORM_LN882H +#elif PLATFORM_ESPIDF + #else extern UINT32 flash_read(char* user_buf, UINT32 count, UINT32 address); @@ -244,6 +246,8 @@ static int http_rest_post(http_request_t* request) { return http_rest_post_flash(request, -1, -1); #elif PLATFORM_LN882H return http_rest_post_flash(request, -1, -1); +#elif PLATFORM_ESPIDF + return http_rest_post_flash(request, -1, -1); #else // TODO ADDLOG_DEBUG(LOG_FEATURE_API, "No OTA"); @@ -1400,7 +1404,20 @@ static int ota_verify_download(void) } #endif -static int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr) { +#if PLATFORM_ESPIDF +#include "esp_system.h" +#include "esp_ota_ops.h" +#include "esp_app_format.h" +#include "esp_flash_partitions.h" +#include "esp_partition.h" +#include "nvs.h" +#include "nvs_flash.h" +#include "esp_wifi.h" +#include "esp_pm.h" +#endif + +static int http_rest_post_flash(http_request_t* request, int startaddr, int maxaddr) +{ #if PLATFORM_XR809 || PLATFORM_W800 return 0; //Operation not supported yet @@ -1411,6 +1428,7 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa int towrite = request->bodylen; char* writebuf = request->bodystart; int writelen = request->bodylen; + int fsize = 0; ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA post len %d", request->contentLength); @@ -1418,7 +1436,8 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa int nRetCode = 0; char error_message[256]; - if (writelen < 0) { + if(writelen < 0) + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "ABORTED: %d bytes to write", writelen); return http_rest_error(request, -20, "writelen < 0"); } @@ -1430,7 +1449,8 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa char* Buffer = (char*)os_malloc(2048 + 3); memset(Buffer, 0, 2048 + 3); - if (request->contentLength >= 0) { + if(request->contentLength >= 0) + { towrite = request->contentLength; } @@ -1440,15 +1460,17 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa do { - if (writelen > 0) { + if(writelen > 0) + { //bk_printf("Copying %d from writebuf to Buffer towrite=%d\n", writelen, towrite); memcpy(Buffer + 3, writebuf, writelen); - if (recvLen == 0) { + if(recvLen == 0) + { T_BOOTER* booter = (T_BOOTER*)(Buffer + 3); bk_printf("magic_no=%u, img_type=%u, zip_type=%u\n", booter->magic_no, booter->img_type, booter->zip_type); - if (TRUE == tls_fwup_img_header_check(booter)) + if(TRUE == tls_fwup_img_header_check(booter)) { totalLen = booter->upd_img_len + sizeof(T_BOOTER); OTA_ResetProgress(); @@ -1462,26 +1484,31 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa } nRetCode = socket_fwup_accept(0, ERR_OK); - if (nRetCode != ERR_OK) { + if(nRetCode != ERR_OK) + { sprintf(error_message, "Firmware update startup failed"); break; } } p = pbuf_alloc(PBUF_TRANSPORT, writelen + 3, PBUF_REF); - if (!p) { + if(!p) + { sprintf(error_message, "Unable to allocate memory for buffer"); nRetCode = -18; break; } - if (recvLen == 0) { + if(recvLen == 0) + { *Buffer = SOCKET_FWUP_START; } - else if (recvLen == (totalLen - writelen)) { + else if(recvLen == (totalLen - writelen)) + { *Buffer = SOCKET_FWUP_END; } - else { + else + { *Buffer = SOCKET_FWUP_DATA; } @@ -1491,11 +1518,13 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa p->len = p->tot_len = writelen + 3; nRetCode = socket_fwup_recv(0, p, ERR_OK); - if (nRetCode != ERR_OK) { + if(nRetCode != ERR_OK) + { sprintf(error_message, "Firmware data processing failed"); break; } - else { + else + { OTA_IncrementProgress(writelen); recvLen += writelen; printf("Downloaded %d / %d\n", recvLen, totalLen); @@ -1504,19 +1533,22 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa towrite -= writelen; } - if (towrite > 0) { + if(towrite > 0) + { writebuf = request->received; writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); - if (writelen < 0) { + if(writelen < 0) + { sprintf(error_message, "recv returned %d - end of data - remaining %d", writelen, towrite); nRetCode = -17; } } - } while ((nRetCode == 0) && (towrite > 0) && (writelen >= 0)); + } while((nRetCode == 0) && (towrite > 0) && (writelen >= 0)); tls_mem_free(Buffer); - if (nRetCode != 0) { + if(nRetCode != 0) + { ADDLOG_ERROR(LOG_FEATURE_OTA, error_message); socket_fwup_err(0, nRetCode); return http_rest_error(request, nRetCode, error_message); @@ -1526,8 +1558,8 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa #elif PLATFORM_BL602 int sockfd, i; int ret; - struct hostent *hostinfo; - uint8_t *recv_buffer; + struct hostent* hostinfo; + uint8_t* recv_buffer; struct sockaddr_in dest; iot_sha256_context ctx; uint8_t sha256_result[32]; @@ -1538,10 +1570,11 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa #define OTA_PROGRAM_SIZE (512) int ota_header_found, use_xz; - ota_header_t *ota_header = 0; + ota_header_t* ota_header = 0; ret = bl_mtd_open(BL_MTD_PARTITION_NAME_FW_DEFAULT, &handle, BL_MTD_OPEN_FLAG_BACKUP); - if (ret) { + if(ret) + { return http_rest_error(request, -20, "Open Default FW partition failed"); } @@ -1558,7 +1591,8 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa printf("[OTA] [TEST] activeID is %u\r\n", activeID); - if (hal_boot2_get_active_entries(BOOT2_PARTITION_TYPE_FW, &ptEntry)) { + if(hal_boot2_get_active_entries(BOOT2_PARTITION_TYPE_FW, &ptEntry)) + { printf("PtTable_Get_Active_Entries fail\r\n"); vPortFree(recv_buffer); bl_mtd_close(handle); @@ -1582,10 +1616,10 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa //Erase in chunks, because erasing everything at once is slow and causes issues with http connection uint32_t erase_offset = 0; uint32_t erase_len = 0; - while (erase_offset < bin_size) + while(erase_offset < bin_size) { erase_len = bin_size - erase_offset; - if (erase_len > 0x10000) + if(erase_len > 0x10000) { erase_len = 0x10000; //Erase in 64kb chunks } @@ -1596,7 +1630,8 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa } printf("[OTA] Done\r\n"); - if (request->contentLength >= 0) { + if(request->contentLength >= 0) + { towrite = request->contentLength; } @@ -1629,17 +1664,19 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa utils_sha256_init(&ctx); utils_sha256_starts(&ctx); memset(sha256_result, 0, sizeof(sha256_result)); - do { - char *useBuf = writebuf; + do + { + char* useBuf = writebuf; int useLen = writelen; - if (ota_header == 0) { + if(ota_header == 0) + { int take_len; // how much left for header? take_len = OTA_PROGRAM_SIZE - buffer_offset; // clamp to available len - if (take_len > useLen) + if(take_len > useLen) take_len = useLen; printf("Header takes %i. ", take_len); memcpy(recv_buffer + buffer_offset, writebuf, take_len); @@ -1647,19 +1684,23 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa useBuf = writebuf + take_len; useLen = writelen - take_len; - if (buffer_offset >= OTA_PROGRAM_SIZE) { + if(buffer_offset >= OTA_PROGRAM_SIZE) + { ota_header = (ota_header_t*)recv_buffer; - if (strncmp((const char*)ota_header, "BL60X_OTA", 9)) { + if(strncmp((const char*)ota_header, "BL60X_OTA", 9)) + { return http_rest_error(request, -20, "Invalid header ident"); } } } - if (ota_header && useLen) { + if(ota_header && useLen) + { - if (flash_offset + useLen >= part_size) { + if(flash_offset + useLen >= part_size) + { return http_rest_error(request, -20, "Too large bin"); } //ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen); @@ -1676,28 +1717,34 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa towrite -= writelen; - if (towrite > 0) { + if(towrite > 0) + { writebuf = request->received; writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); - if (writelen < 0) { + if(writelen < 0) + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite); } } - } while ((towrite > 0) && (writelen >= 0)); + } while((towrite > 0) && (writelen >= 0)); - if (ota_header == 0) { + if(ota_header == 0) + { return http_rest_error(request, -20, "No header found"); } utils_sha256_finish(&ctx, sha256_result); puts("\r\nCalculated SHA256 Checksum:"); - for (i = 0; i < sizeof(sha256_result); i++) { + for(i = 0; i < sizeof(sha256_result); i++) + { printf("%02X", sha256_result[i]); } puts("\r\nHeader SHA256 Checksum:"); - for (i = 0; i < sizeof(sha256_result); i++) { + for(i = 0; i < sizeof(sha256_result); i++) + { printf("%02X", ota_header->u.s.sha256[i]); } - if (memcmp(ota_header->u.s.sha256, sha256_result, sizeof(sha256_img))) { + if(memcmp(ota_header->u.s.sha256, sha256_result, sizeof(sha256_img))) + { /*Error found*/ return http_rest_error(request, -20, "SHA256 NOT Correct"); } @@ -1713,19 +1760,23 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa #elif PLATFORM_LN882H ADDLOG_DEBUG(LOG_FEATURE_OTA, "Ota start!\r\n"); - if (LN_TRUE != ota_persistent_start()) { + if(LN_TRUE != ota_persistent_start()) + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "Ota start error, exit...\r\n"); return 0; } - if (request->contentLength >= 0) { + if(request->contentLength >= 0) + { towrite = request->contentLength; } - do { + do + { //ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen); - if (LN_TRUE != ota_persistent_write(writebuf, writelen)) { + if(LN_TRUE != ota_persistent_write(writebuf, writelen)) + { // ADDLOG_DEBUG(LOG_FEATURE_OTA, "ota write err.\r\n"); return -1; } @@ -1735,14 +1786,16 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa total += writelen; startaddr += writelen; towrite -= writelen; - if (towrite > 0) { + if(towrite > 0) + { writebuf = request->received; writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); - if (writelen < 0) { + if(writelen < 0) + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite); } } - } while ((towrite > 0) && (writelen >= 0)); + } while((towrite > 0) && (writelen >= 0)); ota_persistent_finish(); is_ready_to_verify = LN_TRUE; @@ -1750,50 +1803,152 @@ static int http_rest_post_flash(http_request_t* request, int startaddr, int maxa ADDLOG_DEBUG(LOG_FEATURE_OTA, "http client job done, exit...\r\n"); - if (LN_TRUE == is_precheck_ok) + if(LN_TRUE == is_precheck_ok) { - if ((LN_TRUE == is_ready_to_verify) && (LN_TRUE == ota_verify_download())) { + if((LN_TRUE == is_ready_to_verify) && (LN_TRUE == ota_verify_download())) + { update_ota_state(); //ln_chip_reboot(); } - else { + else + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "Veri bad\r\n"); } } - else { + else + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "Precheck bad\r\n"); } + +#elif PLATFORM_ESPIDF + + ADDLOG_DEBUG(LOG_FEATURE_OTA, "Ota start!\r\n"); + esp_err_t err; + esp_ota_handle_t update_handle = 0; + const esp_partition_t* update_partition = NULL; + const esp_partition_t* running = esp_ota_get_running_partition(); + update_partition = esp_ota_get_next_update_partition(NULL); + if(request->contentLength >= 0) + { + fsize = towrite = request->contentLength; + } + + esp_wifi_set_ps(WIFI_PS_NONE); + bool image_header_was_checked = false; + do + { + if(image_header_was_checked == false) + { + esp_app_desc_t new_app_info; + if(towrite > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) + { + memcpy(&new_app_info, &writebuf[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t)); + ADDLOG_DEBUG(LOG_FEATURE_OTA, "New firmware version: %s", new_app_info.version); + + esp_app_desc_t running_app_info; + if(esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) + { + ADDLOG_DEBUG(LOG_FEATURE_OTA, "Running firmware version: %s", running_app_info.version); + } + + image_header_was_checked = true; + + err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle); + if(err != ESP_OK) + { + ADDLOG_ERROR(LOG_FEATURE_OTA, "esp_ota_begin failed (%s)", esp_err_to_name(err)); + esp_ota_abort(update_handle); + return -1; + } + ADDLOG_DEBUG(LOG_FEATURE_OTA, "esp_ota_begin succeeded"); + } + else + { + ADDLOG_ERROR(LOG_FEATURE_OTA, "received package is not fit len"); + esp_ota_abort(update_handle); + return -1; + } + } + err = esp_ota_write(update_handle, (const void*)writebuf, writelen); + if(err != ESP_OK) + { + esp_ota_abort(update_handle); + return -1; + } + + ADDLOG_DEBUG(LOG_FEATURE_OTA, "OTA in progress: %.1f%%", (100 - ((float)towrite / fsize) * 100)); + total += writelen; + startaddr += writelen; + towrite -= writelen; + + if(towrite > 0) + { + writebuf = request->received; + writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); + if(writelen < 0) + { + ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite); + } + } + } while((towrite > 0) && (writelen >= 0)); + + ADDLOG_INFO(LOG_FEATURE_OTA, "OTA in progress: 100%%, total Write binary data length: %d", total); + + err = esp_ota_end(update_handle); + if(err != ESP_OK) + { + if(err == ESP_ERR_OTA_VALIDATE_FAILED) + { + ADDLOG_ERROR(LOG_FEATURE_OTA, "Image validation failed, image is corrupted"); + } + else + { + ADDLOG_ERROR(LOG_FEATURE_OTA, "esp_ota_end failed (%s)!", esp_err_to_name(err)); + } + return -1; + } + err = esp_ota_set_boot_partition(update_partition); + if(err != ESP_OK) + { + ADDLOG_ERROR(LOG_FEATURE_OTA, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); + return -1; + } + #else init_ota(startaddr); - if (request->contentLength >= 0) { + if(request->contentLength >= 0) + { towrite = request->contentLength; } - if (writelen < 0 || (startaddr + writelen > maxaddr)) { + if(writelen < 0 || (startaddr + writelen > maxaddr)) + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "ABORTED: %d bytes to write", writelen); return http_rest_error(request, -20, "writelen < 0 or end > 0x200000"); } - do { + do + { //ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d bytes to write", writelen); add_otadata((unsigned char*)writebuf, writelen); total += writelen; startaddr += writelen; towrite -= writelen; - if (towrite > 0) { + if(towrite > 0) + { writebuf = request->received; writelen = recv(request->fd, writebuf, request->receivedLenmax, 0); - if (writelen < 0) { + if(writelen < 0) + { ADDLOG_DEBUG(LOG_FEATURE_OTA, "recv returned %d - end of data - remaining %d", writelen, towrite); } } - } while ((towrite > 0) && (writelen >= 0)); + } while((towrite > 0) && (writelen >= 0)); close_ota(); #endif - ADDLOG_DEBUG(LOG_FEATURE_OTA, "%d total bytes written", total); http_setup(request, httpMimeTypeJson); hprintf255(request, "{\"size\":%d}", total); @@ -1858,7 +2013,7 @@ static int http_rest_get_flash(http_request_t* request, int startaddr, int len) res = bl_flash_read(startaddr, (uint8_t *)buffer, readlen); #elif PLATFORM_W600 || PLATFORM_W800 res = 0; -#elif PLATFORM_LN882H +#elif PLATFORM_LN882H || PLATFORM_ESPIDF // TODO:LN882H flash read? res = 0; #else diff --git a/src/littlefs/lfs_util.h b/src/littlefs/lfs_util.h index 554c91a03..1f5b10d11 100644 --- a/src/littlefs/lfs_util.h +++ b/src/littlefs/lfs_util.h @@ -9,7 +9,7 @@ #if PLATFORM_BEKEN #include "mem_pub.h" -#elif PLATFORM_BL602 || PLATFORM_LN882H +#elif PLATFORM_BL602 || PLATFORM_LN882H || PLATFORM_ESPIDF #define os_free free #define os_malloc malloc #endif diff --git a/src/littlefs/our_lfs.c b/src/littlefs/our_lfs.c index 34e7657c6..088202e47 100644 --- a/src/littlefs/our_lfs.c +++ b/src/littlefs/our_lfs.c @@ -30,6 +30,10 @@ #include "hal/hal_flash.h" #include "flash_partition_table.h" +#elif PLATFORM_ESPIDF + +#include "esp_partition.h" +esp_partition_t* esplfs = NULL; #endif @@ -109,6 +113,11 @@ static commandResult_t CMD_LFS_Size(const void *context, const char *cmd, const ADDLOG_INFO(LOG_FEATURE_CMD, "unchanged LFS size 0x%X configured 0x%X", LFS_Size, CFG_GetLFS_Size()); return CMD_RES_OK; } +#ifdef PLATFORM_ESPIDF + ADDLOG_ERROR(LOG_FEATURE_CMD, "ESP doesn't support changing LFS size"); + return CMD_RES_ERROR; +#endif // PLATFORM_ESPIDF + const char *p = args; @@ -410,6 +419,23 @@ void init_lfs(int create){ } #endif +#if PLATFORM_ESPIDF + if(esplfs == NULL) + { + esplfs = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, NULL); + if(esplfs != NULL) + { + ADDLOGF_INFO("Partition %s found, size: %i", esplfs->label, esplfs->size); + } + else + { + return; + } + } + newstart = 0; + newsize = esplfs->size; +#endif + LFS_Start = newstart; LFS_Size = newsize; cfg.block_count = (newsize/LFS_BLOCK_SIZE); @@ -612,6 +638,46 @@ static int lfs_erase(const struct lfs_config *c, lfs_block_t block){ return res; } +#elif PLATFORM_ESPIDF + +static int lfs_read(const struct lfs_config* c, lfs_block_t block, + lfs_off_t off, void* buffer, lfs_size_t size) +{ + int res = LFS_ERR_OK; + unsigned int startAddr = block * LFS_BLOCK_SIZE; + startAddr += off; + res = esp_partition_read(esplfs, startAddr, (uint8_t*)buffer, size); + return res; +} + +// Program a region in a block. The block must have previously +// been erased. Negative error codes are propogated to the user. +// May return LFS_ERR_CORRUPT if the block should be considered bad. +static int lfs_write(const struct lfs_config* c, lfs_block_t block, + lfs_off_t off, const void* buffer, lfs_size_t size) +{ + int res = LFS_ERR_OK; + + unsigned int startAddr = block * LFS_BLOCK_SIZE; + startAddr += off; + + res = esp_partition_write(esplfs, startAddr, (uint8_t*)buffer, size); + + return res; +} + +// Erase a block. A block must be erased before being programmed. +// The state of an erased block is undefined. Negative error codes +// are propogated to the user. +// May return LFS_ERR_CORRUPT if the block should be considered bad. +static int lfs_erase(const struct lfs_config* c, lfs_block_t block) +{ + int res = LFS_ERR_OK; + unsigned int startAddr = block * LFS_BLOCK_SIZE; + res = esp_partition_erase_range(esplfs, startAddr, LFS_BLOCK_SIZE); + return res; +} + #endif diff --git a/src/littlefs/our_lfs.h b/src/littlefs/our_lfs.h index 986323367..ed4d88a33 100644 --- a/src/littlefs/our_lfs.h +++ b/src/littlefs/our_lfs.h @@ -62,6 +62,12 @@ // end media partition #define LFS_BLOCKS_END 0x001DD000 +#elif PLATFORM_ESPIDF + +#define LFS_BLOCKS_START 0x0 +#define LFS_BLOCKS_START_MIN 0x0 +#define LFS_BLOCKS_END 0x50000 + #else // TODO // start 0x1000 after OTA addr diff --git a/src/mqtt/new_mqtt.c b/src/mqtt/new_mqtt.c index d9f62a426..6473a4c67 100644 --- a/src/mqtt/new_mqtt.c +++ b/src/mqtt/new_mqtt.c @@ -32,7 +32,6 @@ extern void MQTT_TriggerRead(); #endif - // these won't exist except on Beken? #ifndef LOCK_TCPIP_CORE #define LOCK_TCPIP_CORE() @@ -1635,7 +1634,7 @@ static BENCHMARK_TEST_INFO* info = NULL; #if WINDOWS -#elif PLATFORM_BL602 +#elif PLATFORM_BL602 || PLATFORM_W600 || PLATFORM_W800 || PLATFORM_ESPIDF static void mqtt_timer_thread(void* param) { while (1) @@ -1644,14 +1643,6 @@ static void mqtt_timer_thread(void* param) MQTT_Test_Tick(param); } } -#elif PLATFORM_W600 || PLATFORM_W800 -static void mqtt_timer_thread(void* param) -{ - while (1) { - vTaskDelay(MQTT_TMR_DURATION); - MQTT_Test_Tick(param); - } -} #elif PLATFORM_XR809 || PLATFORM_LN882H static OS_Timer_t timer; #else @@ -1683,9 +1674,7 @@ commandResult_t MQTT_StartMQTTTestThread(const void* context, const char* cmd, c #if WINDOWS -#elif PLATFORM_BL602 - xTaskCreate(mqtt_timer_thread, "mqtt", 1024, (void*)info, 15, NULL); -#elif PLATFORM_W600 || PLATFORM_W800 +#elif PLATFORM_BL602 || PLATFORM_W600 || PLATFORM_W800 || PLATFORM_ESPIDF xTaskCreate(mqtt_timer_thread, "mqtt", 1024, (void*)info, 15, NULL); #elif PLATFORM_XR809 || PLATFORM_LN882H OS_TimerSetInvalid(&timer); diff --git a/src/new_cfg.c b/src/new_cfg.c index 23ce98e44..f5b3b0683 100644 --- a/src/new_cfg.c +++ b/src/new_cfg.c @@ -147,6 +147,8 @@ void CFG_SetDefaultConfig() { strcpy_safe(g_cfg.mqtt_group, "xr809s", sizeof(g_cfg.mqtt_group)); #elif PLATFORM_BL602 strcpy_safe(g_cfg.mqtt_group, "bl602s", sizeof(g_cfg.mqtt_group)); +#elif PLATFORM_ESPIDF + strcpy_safe(g_cfg.mqtt_group, "esp", sizeof(g_cfg.mqtt_group)); #elif WINDOWS strcpy_safe(g_cfg.mqtt_group, "bekens", sizeof(g_cfg.mqtt_group)); #else @@ -718,7 +720,7 @@ void CFG_InitAndLoad() { // mark as changed g_cfg_pendingChanges ++; } else { -#if defined(PLATFORM_XR809) || defined(PLATFORM_BL602) +#if defined(PLATFORM_XR809) || defined(PLATFORM_BL602) || defined(PLATFORM_ESPIDF) if (g_cfg.mac[0] == 0 && g_cfg.mac[1] == 0 && g_cfg.mac[2] == 0 && g_cfg.mac[3] == 0 && g_cfg.mac[4] == 0 && g_cfg.mac[5] == 0) { WiFI_GetMacAddress((char*)g_cfg.mac); } diff --git a/src/new_common.c b/src/new_common.c index b56030f2d..bc5ec9005 100644 --- a/src/new_common.c +++ b/src/new_common.c @@ -119,8 +119,8 @@ char *strdup(const char *s) char *res; size_t len; - if (s == NULL) - return NULL; + //if (s == NULL) + // return NULL; len = strlen(s); res = malloc(len + 1); diff --git a/src/new_common.h b/src/new_common.h index fe9027f0e..6f4f72ea6 100644 --- a/src/new_common.h +++ b/src/new_common.h @@ -81,6 +81,25 @@ typedef long BaseType_t; #define DEVICENAME_PREFIX_SHORT "ln882h" #define PLATFORM_MCU_NAME "LN882H" #define MANUFACTURER "LightningSemi" +#elif PLATFORM_ESPIDF +#define MANUFACTURER "Espressif" +#define DEVICENAME_PREFIX_SHORT "esp" +#ifdef CONFIG_IDF_TARGET_ESP32C3 +#define PLATFORM_MCU_NAME "ESP32C3" +#elif CONFIG_IDF_TARGET_ESP32C2 +#define PLATFORM_MCU_NAME "ESP32C2" +#elif CONFIG_IDF_TARGET_ESP32 +#define PLATFORM_MCU_NAME "ESP32" +#elif CONFIG_IDF_TARGET_ESP32C6 +#define PLATFORM_MCU_NAME "ESP32C6" +#elif CONFIG_IDF_TARGET_ESP32S2 +#define PLATFORM_MCU_NAME "ESP32S2" +#elif CONFIG_IDF_TARGET_ESP32S3 +#define PLATFORM_MCU_NAME "ESP32S3" +#else +#define PLATFORM_MCU_NAME MANUFACTURER +#endif +#define DEVICENAME_PREFIX_FULL "Open" PLATFORM_MCU_NAME #else #error "You must define a platform.." This platform is not supported, error! @@ -106,6 +125,8 @@ This platform is not supported, error! #define USER_SW_VER "W800_Test" #elif defined(PLATFORM_LN882H) #define USER_SW_VER "LN882H_Test" +#elif defined(PLATFORM_ESPIDF) +#define USER_SW_VER PLATFORM_MCU_NAME "_Test" #else #define USER_SW_VER "unknown" #endif @@ -360,6 +381,47 @@ OSStatus rtos_create_thread( beken_thread_t* thread, beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg ); +#elif PLATFORM_ESPIDF + +#include +#include +#include "esp_timer.h" +#include "esp_log.h" +#include "esp_idf_version.h" + +#define ASSERT +#define os_strcpy strcpy +#define os_malloc malloc +#define os_free free +#define os_memset memset + +//#define bk_printf printf + +#define bk_printf(...) ESP_LOGI("OpenBeken", __VA_ARGS__); + +#define kNoErr 0 //! No error occurred. +#define rtos_delay_milliseconds sys_delay_ms +typedef void* beken_thread_arg_t; +typedef void* beken_thread_t; +typedef void (*beken_thread_function_t)(beken_thread_arg_t arg); +typedef int OSStatus; + +#define BEKEN_DEFAULT_WORKER_PRIORITY (6) +#define BEKEN_APPLICATION_PRIORITY (7) + +// wrappers for XR809??? threads to work like bekken +OSStatus rtos_delete_thread(beken_thread_t* thread); +OSStatus rtos_create_thread(beken_thread_t* thread, + uint8_t priority, const char* name, + beken_thread_function_t function, + uint32_t stack_size, beken_thread_arg_t arg); + +#define portTICK_RATE_MS portTICK_PERIOD_MS +#define portTickType TickType_t +#define xTaskHandle TaskHandle_t +#define delay_ms sys_delay_ms +#define UINT32 uint32_t + #else #include "gw_intf.h" @@ -430,7 +492,10 @@ int strcpy_safe(char *tg, const char *src, int tgMaxLen); int strcpy_safe_checkForChanges(char *tg, const char *src, int tgMaxLen); void urldecode2_safe(char *dst, const char *srcin, int maxDstLen); int strIsInteger(const char *s); + +#ifndef PLATFORM_ESPIDF const char* strcasestr(const char* str1, const char* str2); +#endif // user_main.c char Tiny_CRC8(const char *data,int length); @@ -456,8 +521,10 @@ int PingWatchDog_GetTotalReceived(); int LWIP_GetMaxSockets(); int LWIP_GetActiveSockets(); +#ifndef PLATFORM_ESPIDF //delay function do 10*r nops, because rtos_delay_milliseconds is too much void usleep(int r); +#endif #define RESTARTS_REQUIRED_FOR_SAFE_MODE 4 diff --git a/src/new_pins.c b/src/new_pins.c index 2e0dccc6d..e9b246ed6 100644 --- a/src/new_pins.c +++ b/src/new_pins.c @@ -20,6 +20,8 @@ #ifdef PLATFORM_BEKEN #include #include "driver/drv_ir.h" +#elif PLATFORM_ESPIDF +#include "esp_sleep.h" #endif @@ -201,8 +203,19 @@ void PINS_BeginDeepSleepWithPinWakeUp(unsigned int wakeUpTime) { bk_enter_deep_sleep(g_gpio_index_map[0], g_gpio_edge_map[0]); } #endif -#else - +#elif PLATFORM_ESPIDF +// if(wakeUpTime) +// { +// esp_sleep_enable_timer_wakeup(timeMS * 1000000); +// } +//#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP +// esp_deep_sleep_start(); +//#else +// addLogAdv(LOG_ERROR, LOG_FEATURE_GENERAL, "%s, doesn't support gpio deep sleep, entering light sleep.", PLATFORM_MCU_NAME); +// delay_ms(10); +// esp_sleep_enable_gpio_wakeup(); +// esp_light_sleep_start(); +//#endif #endif } @@ -267,7 +280,7 @@ void PIN_SetupPins() { } #endif #endif -#if defined(PLATFORM_BEKEN) || defined(PLATFORM_BL602) || defined(PLATFORM_W600) || defined(WINDOWS) +#ifdef ENABLE_DRIVER_DHT // TODO: better place to call? DHT_OnPinsConfigChanged(); #endif @@ -989,7 +1002,7 @@ void PIN_SetPinRoleForPinIndex(int index, int role) { } if (bDHTChange) { -#if defined(PLATFORM_BEKEN) || defined(PLATFORM_BL602) || defined(PLATFORM_W600) || defined(WINDOWS) +#ifdef ENABLE_DRIVER_DHT // TODO: better place to call? DHT_OnPinsConfigChanged(); #endif diff --git a/src/new_pins.h b/src/new_pins.h index e2cbcdf41..574c85e57 100644 --- a/src/new_pins.h +++ b/src/new_pins.h @@ -1000,6 +1000,22 @@ typedef enum channelType_e { #define PLATFORM_GPIO_MAX 44 #elif PLATFORM_LN882H #define PLATFORM_GPIO_MAX 26 +#elif PLATFORM_ESPIDF +#ifdef CONFIG_IDF_TARGET_ESP32C3 +#define PLATFORM_GPIO_MAX 22 +#elif CONFIG_IDF_TARGET_ESP32C2 +#define PLATFORM_GPIO_MAX 21 +#elif CONFIG_IDF_TARGET_ESP32S2 +#define PLATFORM_GPIO_MAX 47 +#elif CONFIG_IDF_TARGET_ESP32S3 +#define PLATFORM_GPIO_MAX 49 +#elif CONFIG_IDF_TARGET_ESP32C6 +#define PLATFORM_GPIO_MAX 31 +#elif CONFIG_IDF_TARGET_ESP32 +#define PLATFORM_GPIO_MAX 40 +#else +#define PLATFORM_GPIO_MAX 0 +#endif #else #define PLATFORM_GPIO_MAX 29 #endif @@ -1045,6 +1061,23 @@ typedef struct pinsState_s { byte channelTypes[CHANNEL_MAX]; } pinsState_t; +#elif PLATFORM_ESPIDF + +typedef struct pinsState_s +{ + // All above values are indexed by physical pin index + // (so we assume we have maximum of 32 pins) + byte roles[50]; + byte channels[50]; + // extra channels array - this is needed for + // buttons, so button can toggle one relay on single click + // and other relay on double click + byte channels2[50]; + // This single field above, is indexed by CHANNEL INDEX + // (not by pin index) + byte channelTypes[CHANNEL_MAX]; +} pinsState_t; + #else typedef struct pinsState_s { @@ -1271,6 +1304,8 @@ typedef struct mainConfig_s { int loggerFlags; #if PLATFORM_W800 byte unusedSectorAB[51]; +#elif PLATFORM_ESPIDF + byte unusedSectorAB[43]; #else byte unusedSectorAB[99]; #endif diff --git a/src/obk_config.h b/src/obk_config.h index 7fcf37e61..2ed0531e1 100644 --- a/src/obk_config.h +++ b/src/obk_config.h @@ -1,4 +1,4 @@ -///////////////////////////////////////////////////// +////////////////////////////////////////////////////// // specify which parts of the app we wish to be active // #ifndef OBK_CONFIG_H @@ -167,6 +167,30 @@ #define ENABLE_TASMOTA_JSON 1 #define ENABLE_DRIVER_DS1820 1 +#elif PLATFORM_ESPIDF + +#define ENABLE_I2C 1 +#define ENABLE_NTP 1 +#define ENABLE_DRIVER_LED 1 +#define ENABLE_DRIVER_TUYAMCU 1 +#define ENABLE_LITTLEFS 1 +#define ENABLE_DRIVER_BMPI2C 1 +#define ENABLE_DRIVER_DS1820 1 +#define ENABLE_DRIVER_DHT 1 +#define ENABLE_DRIVER_AHT2X 1 +#define ENABLE_DRIVER_BATTERY 1 +#define ENABLE_DRIVER_CHARTS 1 +#define ENABLE_EXPAND_CONSTANT 1 +#define ENABLE_DRIVER_HUE 1 +#define ENABLE_DRIVER_WEMO 1 +#define ENABLE_DRIVER_BL0937 1 +#define ENABLE_TASMOTADEVICEGROUPS 1 +#define ENABLE_TASMOTA_JSON 1 +#define ENABLE_CALENDAR_EVENTS 1 +#define ENABLE_DRIVER_DDP 1 +#define ENABLE_DRIVER_SSDP 1 +#define ENABLE_DRIVER_CHT83XX 1 + #else #error "Platform not defined" diff --git a/src/user_main.c b/src/user_main.c index 484a6452a..656f2dcdd 100644 --- a/src/user_main.c +++ b/src/user_main.c @@ -56,9 +56,10 @@ void bg_register_irda_check_func(FUNCPTR func); #elif PLATFORM_LN882H #include "hal/hal_wdt.h" #include "hal/hal_gpio.h" +#elif PLATFORM_ESPIDF +#include "esp_timer.h" #endif - int g_secondsElapsed = 0; // open access point after this number of seconds int g_openAP = 0; @@ -201,7 +202,7 @@ void extended_app_waiting_for_launch2(void) { #endif -#if defined(PLATFORM_LN882H) +#if defined(PLATFORM_LN882H) || defined(PLATFORM_ESPIDF) int LWIP_GetMaxSockets() { return 0; @@ -211,9 +212,7 @@ int LWIP_GetActiveSockets() { } #endif -#if defined(PLATFORM_BL602) || defined(PLATFORM_W800) || defined(PLATFORM_W600)|| defined(PLATFORM_LN882H) - - +#if defined(PLATFORM_BL602) || defined(PLATFORM_W800) || defined(PLATFORM_W600)|| defined(PLATFORM_LN882H) || defined(PLATFORM_ESPIDF) OSStatus rtos_create_thread(beken_thread_t* thread, uint8_t priority, const char* name, @@ -525,7 +524,7 @@ bool Main_HasFastConnect() { } return false; } -#if PLATFORM_LN882H +#if PLATFORM_LN882H || PLATFORM_ESPIDF // Quick hack to display LN-only temperature, // we may improve it in the future extern float g_wifi_temperature; @@ -593,7 +592,7 @@ void Main_OnEverySecond() LED_RunOnEverySecond(); #ifndef OBK_DISABLE_ALL_DRIVERS DRV_OnEverySecond(); -#if defined(PLATFORM_BEKEN) || defined(WINDOWS) || defined(PLATFORM_BL602) +#if defined(PLATFORM_BEKEN) || defined(WINDOWS) || defined(PLATFORM_BL602) || defined(PLATFORM_ESPIDF) UART_RunEverySecond(); #endif #endif @@ -904,6 +903,8 @@ void QuickTick(void* param) #if defined(PLATFORM_BEKEN) || defined(WINDOWS) g_time = rtos_get_time(); +#elif defined (PLATFORM_ESPIDF) + g_time = esp_timer_get_time() / 1000; #else g_time += QUICK_TMR_DURATION; #endif @@ -915,7 +916,7 @@ void QuickTick(void* param) g_last_time = g_time; -#if (defined WINDOWS) || (defined PLATFORM_BEKEN) || (defined PLATFORM_BL602) || (defined PLATFORM_LN882H) +#if (defined WINDOWS) || (defined PLATFORM_BEKEN) || (defined PLATFORM_BL602) || (defined PLATFORM_LN882H) || (defined PLATFORM_ESPIDF) SVM_RunThreads(g_deltaTimeMS); #endif RepeatingEvents_RunUpdate(g_deltaTimeMS * 0.001f); @@ -966,15 +967,7 @@ void QuickTick(void* param) // this is the bit which runs the quick tick timer #if WINDOWS -#elif PLATFORM_BL602 -void quick_timer_thread(void* param) -{ - while (1) { - vTaskDelay(QUICK_TMR_DURATION); - QuickTick(0); - } -} -#elif PLATFORM_W600 || PLATFORM_W800 +#elif PLATFORM_BL602 || PLATFORM_W600 || PLATFORM_W800 void quick_timer_thread(void* param) { while (1) { @@ -982,6 +975,8 @@ void quick_timer_thread(void* param) QuickTick(0); } } +#elif PLATFORM_ESPIDF +esp_timer_handle_t g_quick_timer; #elif PLATFORM_XR809 || PLATFORM_LN882H OS_Timer_t g_quick_timer; #else @@ -991,12 +986,18 @@ void QuickTick_StartThread(void) { #if WINDOWS -#elif PLATFORM_BL602 +#elif PLATFORM_BL602 || PLATFORM_W600 || PLATFORM_W800 xTaskCreate(quick_timer_thread, "quick", 1024, NULL, 15, NULL); -#elif PLATFORM_W600 || PLATFORM_W800 +#elif PLATFORM_ESPIDF + const esp_timer_create_args_t g_quick_timer_args = + { + .callback = &QuickTick, + .name = "quick" + }; - xTaskCreate(quick_timer_thread, "quick", 1024, NULL, 15, NULL); + esp_timer_create(&g_quick_timer_args, &g_quick_timer); + esp_timer_start_periodic(g_quick_timer, QUICK_TMR_DURATION * 1000); #elif PLATFORM_XR809 || PLATFORM_LN882H OS_TimerSetInvalid(&g_quick_timer);