diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh index 4227e920d21..c3e32d06e83 100755 --- a/.github/scripts/on-push.sh +++ b/.github/scripts/on-push.sh @@ -73,22 +73,16 @@ if [ "$BUILD_PIO" -eq 0 ]; then SKETCHES_ESP32="\ $ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ - $ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino\ + $ARDUINO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino\ $ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino\ $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ " - SKETCHES_ESP32XX="\ - $ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino\ - $ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino\ - $ARDUINO_ESP32_PATH/libraries/Insights/examples/MinimalDiagnostics/MinimalDiagnostics.ino\ - " - build "esp32s3" $FQBN_ESP32S3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 - build "esp32s2" $FQBN_ESP32S2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX - build "esp32c3" $FQBN_ESP32C3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX - build "esp32c6" $FQBN_ESP32C6 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX - build "esp32h2" $FQBN_ESP32H2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX + build "esp32s2" $FQBN_ESP32S2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 + build "esp32c3" $FQBN_ESP32C3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 + build "esp32c6" $FQBN_ESP32C6 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 + build "esp32h2" $FQBN_ESP32H2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 build "esp32" $FQBN_ESP32 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32 else source ${SCRIPTS_DIR}/install-platformio-esp32.sh @@ -98,7 +92,7 @@ else build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \ - build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \ + build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/Server/Server.ino" && \ build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino" # Basic sanity testing for other series diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index 42b3669bb8b..79fb568b797 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -126,6 +126,11 @@ function build_sketch(){ # build_sketch [ex # of configuration built in case of a multiconfiguration test. sketchname=$(basename $sketchdir) + + if [[ -n $target ]] && [[ -f "$sketchdir/.skip.$target" ]]; then + echo "Skipping $sketchname for target $target" + exit 0 + fi ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" if [ -n "$ARDUINO_BUILD_DIR" ]; then @@ -159,6 +164,12 @@ function build_sketch(){ # build_sketch [ex --build-cache-path "$ARDUINO_CACHE_DIR" \ --build-path "$build_dir" \ $xtra_opts "${sketchdir}" + + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo ""ERROR: Compilation failed with error code $exit_status"" + exit $exit_status + fi elif [ -f "$ide_path/arduino-builder" ]; then echo "Building $sketchname with arduino-builder and FQBN=$currfqbn" echo "Build path = $build_dir" @@ -173,6 +184,11 @@ function build_sketch(){ # build_sketch [ex -build-path "$build_dir" \ $xtra_opts "${sketchdir}/${sketchname}.ino" + exit_status=$? + if [ $exit_status -ne 0 ]; then + echo ""ERROR: Compilation failed with error code $exit_status"" + exit $exit_status + fi # $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \ # -fqbn=\"$currfqbn\" \ # -warnings="all" \ diff --git a/.github/workflows/build_py_tools.yml b/.github/workflows/build_py_tools.yml index 907a3438bb8..46ecf6da756 100644 --- a/.github/workflows/build_py_tools.yml +++ b/.github/workflows/build_py_tools.yml @@ -22,7 +22,7 @@ jobs: fetch-depth: 2 ref: ${{ github.event.pull_request.head.ref }} - name: Verify Python Tools Changed - uses: tj-actions/changed-files@v36 + uses: tj-actions/changed-files@v41 id: verify-changed-files with: fetch_depth: '2' diff --git a/.github/workflows/dangerjs.yml b/.github/workflows/dangerjs.yml new file mode 100644 index 00000000000..9f7360bc34f --- /dev/null +++ b/.github/workflows/dangerjs.yml @@ -0,0 +1,22 @@ +name: DangerJS Pull Request linter +on: + pull_request_target: + types: [opened, edited, reopened, synchronize] + +permissions: + pull-requests: write + contents: write + +jobs: + pull-request-style-linter: + runs-on: ubuntu-latest + steps: + - name: Check out PR head + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: DangerJS pull request linter + uses: espressif/shared-github-dangerjs@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs_build.yml similarity index 60% rename from .github/workflows/docs.yml rename to .github/workflows/docs_build.yml index f01fb76ee84..c18120c079f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs_build.yml @@ -1,13 +1,6 @@ -name: ReadTheDocs CI +name: Documentation Build and Deploy CI on: - push: - branches: - - master - - release/* - paths: - - 'docs/**' - - '.github/workflows/docs.yml' pull_request: paths: - 'docs/**' @@ -16,7 +9,7 @@ on: jobs: build-docs: - name: Build ReadTheDocs + name: Build Documentation runs-on: ubuntu-22.04 defaults: run: @@ -34,5 +27,11 @@ jobs: sudo apt install python3-pip python3-setuptools # GitHub CI installs pip3 and setuptools outside the path. # Update the path to include them and run. - PATH=/home/runner/.local/bin:$PATH pip3 install --user -r ./docs/requirements.txt - cd ./docs && PATH=/home/runner/.local/bin:$PATH SPHINXOPTS="-W" make html + cd ./docs + PATH=/home/runner/.local/bin:$PATH pip3 install -r requirements.txt --prefer-binary + PATH=/home/runner/.local/bin:$PATH SPHINXOPTS="-W" build-docs -l en + - name: Archive Docs + uses: actions/upload-artifact@v2 + with: + name: docs + path: docs diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml new file mode 100644 index 00000000000..ebc8acac792 --- /dev/null +++ b/.github/workflows/docs_deploy.yml @@ -0,0 +1,46 @@ +name: Documentation Build and Deploy Production CI + +on: + push: + branches: + - release/* + paths: + - 'docs/**' + - '.github/workflows/docs.yml' + +jobs: + + deploy-prod-docs: + name: Deploy Documentation Production + runs-on: ubuntu-22.04 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: actions/setup-python@v2 + with: + python-version: '3.10' + - name: Deploy Preview + env: + # Deploy to production server + DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/" + DOCS_DEPLOY_PRIVATEKEY: ${{ secrets.DOCS_PROD_PRIVATEKEY }} + DOCS_DEPLOY_PATH: ${{ secrets.DOCS_PROD_PATH }} + DOCS_DEPLOY_SERVER: ${{ secrets.DOCS_PROD_SERVER }} + DOCS_DEPLOY_URL_BASE: ${{ secrets.DOCS_PROD_URL_BASE }} + DOCS_DEPLOY_SERVER_USER: ${{ secrets.DOCS_PROD_USER }} + run: | + sudo apt update + sudo apt install python3-pip python3-setuptools + source ./docs/utils.sh + add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER + export GIT_VER=$(git describe --always) + echo "PIP install requirements..." + pip3 install --user -r ./docs/requirements.txt + echo "Building the Docs..." + cd ./docs && build-docs -l en + echo "Deploy the Docs..." + deploy-docs diff --git a/.github/workflows/docs_preview.yml b/.github/workflows/docs_preview.yml new file mode 100644 index 00000000000..41de91838b3 --- /dev/null +++ b/.github/workflows/docs_preview.yml @@ -0,0 +1,46 @@ +name: Documentation Build and Deploy CI + +on: + push: + branches: + - master + paths: + - 'docs/**' + - '.github/workflows/docs.yml' + +jobs: + + deploy-preview-docs: + name: Deploy Documentation Preview + runs-on: ubuntu-22.04 + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Deploy Preview + env: + # Deploy to preview server + DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/" + DOCS_DEPLOY_PRIVATEKEY: ${{ secrets.DOCS_KEY }} + DOCS_DEPLOY_PATH: ${{ secrets.DOCS_PATH }} + DOCS_DEPLOY_SERVER: ${{ secrets.DOCS_SERVER }} + DOCS_DEPLOY_URL_BASE: ${{ secrets.DOCS_URL }} + DOCS_DEPLOY_SERVER_USER: ${{ secrets.DOCS_USER }} + run: | + sudo apt update + sudo apt install python3-pip python3-setuptools + source ./docs/utils.sh + add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER + export GIT_VER=$(git describe --always) + echo "PIP install requirements..." + pip3 install --user -r ./docs/requirements.txt + echo "Building the Docs..." + cd ./docs && build-docs -l en + echo "Deploy the Docs..." + deploy-docs diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 115b9e7122a..729ffebbf2c 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -13,7 +13,7 @@ build: # Build documentation in the docs/ directory with Sphinx sphinx: - configuration: docs/source/conf.py + configuration: docs/en/conf.py python: install: diff --git a/boards.txt b/boards.txt index f1256a1ed28..903948aedb5 100644 --- a/boards.txt +++ b/boards.txt @@ -29364,7 +29364,7 @@ esp32s3_powerfeather.build.variant=esp32s3_powerfeather esp32s3_powerfeather.build.board=ESP32S3_POWERFEATHER esp32s3_powerfeather.build.usb_mode=1 -esp32s3_powerfeather.build.cdc_on_boot=0 +esp32s3_powerfeather.build.cdc_on_boot=1 esp32s3_powerfeather.build.msc_on_boot=0 esp32s3_powerfeather.build.dfu_on_boot=0 esp32s3_powerfeather.build.f_cpu=240000000L @@ -29377,8 +29377,9 @@ esp32s3_powerfeather.build.partitions=default_8MB esp32s3_powerfeather.build.defines= esp32s3_powerfeather.build.loop_core= esp32s3_powerfeather.build.event_core= +esp32s3_powerfeather.build.flash_type=qio esp32s3_powerfeather.build.psram_type=qspi -esp32s3_powerfeather.build.memory_type={build.boot}_{build.psram_type} +esp32s3_powerfeather.build.memory_type={build.flash_type}_{build.psram_type} esp32s3_powerfeather.menu.PSRAM.disabled=Disabled esp32s3_powerfeather.menu.PSRAM.disabled.build.defines= @@ -29418,10 +29419,10 @@ esp32s3_powerfeather.menu.USBMode.hwcdc.build.usb_mode=1 esp32s3_powerfeather.menu.USBMode.default=USB-OTG (TinyUSB) esp32s3_powerfeather.menu.USBMode.default.build.usb_mode=0 -esp32s3_powerfeather.menu.CDCOnBoot.default=Disabled -esp32s3_powerfeather.menu.CDCOnBoot.default.build.cdc_on_boot=0 esp32s3_powerfeather.menu.CDCOnBoot.cdc=Enabled esp32s3_powerfeather.menu.CDCOnBoot.cdc.build.cdc_on_boot=1 +esp32s3_powerfeather.menu.CDCOnBoot.default=Disabled +esp32s3_powerfeather.menu.CDCOnBoot.default.build.cdc_on_boot=0 esp32s3_powerfeather.menu.MSCOnBoot.default=Disabled esp32s3_powerfeather.menu.MSCOnBoot.default.build.msc_on_boot=0 @@ -29440,39 +29441,21 @@ esp32s3_powerfeather.menu.UploadMode.cdc=USB-OTG CDC (TinyUSB) esp32s3_powerfeather.menu.UploadMode.cdc.upload.use_1200bps_touch=true esp32s3_powerfeather.menu.UploadMode.cdc.upload.wait_for_upload_port=true -esp32s3_powerfeather.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) -esp32s3_powerfeather.menu.PartitionScheme.default.build.partitions=default -esp32s3_powerfeather.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) -esp32s3_powerfeather.menu.PartitionScheme.defaultffat.build.partitions=default_ffat esp32s3_powerfeather.menu.PartitionScheme.default_8MB=8M with spiffs (3MB APP/1.5MB SPIFFS) esp32s3_powerfeather.menu.PartitionScheme.default_8MB.build.partitions=default_8MB esp32s3_powerfeather.menu.PartitionScheme.default_8MB.upload.maximum_size=3342336 -esp32s3_powerfeather.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) -esp32s3_powerfeather.menu.PartitionScheme.minimal.build.partitions=minimal -esp32s3_powerfeather.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) -esp32s3_powerfeather.menu.PartitionScheme.no_ota.build.partitions=no_ota -esp32s3_powerfeather.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 -esp32s3_powerfeather.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) -esp32s3_powerfeather.menu.PartitionScheme.noota_3g.build.partitions=noota_3g -esp32s3_powerfeather.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 -esp32s3_powerfeather.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) -esp32s3_powerfeather.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat -esp32s3_powerfeather.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 -esp32s3_powerfeather.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) -esp32s3_powerfeather.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat -esp32s3_powerfeather.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 -esp32s3_powerfeather.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) -esp32s3_powerfeather.menu.PartitionScheme.huge_app.build.partitions=huge_app -esp32s3_powerfeather.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 -esp32s3_powerfeather.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) -esp32s3_powerfeather.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs -esp32s3_powerfeather.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +esp32s3_powerfeather.menu.PartitionScheme.default_ffat_8MB=8M with ffat (3MB APP/1.5MB FATFS) +esp32s3_powerfeather.menu.PartitionScheme.default_ffat_8MB.build.partitions=default_ffat_8MB +esp32s3_powerfeather.menu.PartitionScheme.default_ffat_8MB.upload.maximum_size=3342336 +esp32s3_powerfeather.menu.PartitionScheme.large_spiffs_8MB=Large SPIFFS (1.2MB APP/5.3MB SPIFFS) +esp32s3_powerfeather.menu.PartitionScheme.large_spiffs_8MB.build.partitions=large_spiffs_8MB +esp32s3_powerfeather.menu.PartitionScheme.large_spiffs_8MB.upload.maximum_size=1310720 +esp32s3_powerfeather.menu.PartitionScheme.large_ffat_8MB=Large FFAT (1.2MB APP/5.3MB FATFS) +esp32s3_powerfeather.menu.PartitionScheme.large_ffat_8MB.build.partitions=large_ffat_8MB +esp32s3_powerfeather.menu.PartitionScheme.large_ffat_8MB.upload.maximum_size=1310720 esp32s3_powerfeather.menu.PartitionScheme.max_app_8MB=Maximum APP (7.9MB APP No OTA/No FS) esp32s3_powerfeather.menu.PartitionScheme.max_app_8MB.build.partitions=max_app_8MB esp32s3_powerfeather.menu.PartitionScheme.max_app_8MB.upload.maximum_size=8257536 -esp32s3_powerfeather.menu.PartitionScheme.rainmaker=RainMaker -esp32s3_powerfeather.menu.PartitionScheme.rainmaker.build.partitions=rainmaker -esp32s3_powerfeather.menu.PartitionScheme.rainmaker.upload.maximum_size=3145728 esp32s3_powerfeather.menu.CPUFreq.240=240MHz (WiFi) esp32s3_powerfeather.menu.CPUFreq.240.build.f_cpu=240000000L diff --git a/cores/esp32/Esp.cpp b/cores/esp32/Esp.cpp index 0d812b2fcb0..ecbf4877d90 100644 --- a/cores/esp32/Esp.cpp +++ b/cores/esp32/Esp.cpp @@ -131,7 +131,7 @@ unsigned long long operator"" _GB(unsigned long long x) EspClass ESP; -void EspClass::deepSleep(uint32_t time_us) +void EspClass::deepSleep(uint64_t time_us) { esp_deep_sleep(time_us); } @@ -225,30 +225,31 @@ String EspClass::getSketchMD5() const esp_partition_t *running = esp_ota_get_running_partition(); if (!running) { log_e("Partition could not be found"); - return String(); } + const size_t bufSize = SPI_FLASH_SEC_SIZE; - std::unique_ptr buf(new uint8_t[bufSize]); - uint32_t offset = 0; - if(!buf.get()) { + uint8_t *pb = (uint8_t *)malloc(bufSize); + if(!pb) { log_e("Not enough memory to allocate buffer"); - return String(); } + uint32_t offset = 0; + MD5Builder md5; md5.begin(); - while( lengthLeft > 0) { + while(lengthLeft > 0) { size_t readBytes = (lengthLeft < bufSize) ? lengthLeft : bufSize; - if (!ESP.flashRead(running->address + offset, reinterpret_cast(buf.get()), (readBytes + 3) & ~3)) { + if (!ESP.flashRead(running->address + offset, (uint32_t *)pb, (readBytes + 3) & ~3)) { + free(pb); log_e("Could not read buffer from flash"); - return String(); } - md5.add(buf.get(), readBytes); + md5.add(pb, readBytes); lengthLeft -= readBytes; offset += readBytes; } + free(pb); md5.calculate(); result = md5.toString(); return result; diff --git a/cores/esp32/Esp.h b/cores/esp32/Esp.h index 478158ddf1f..82dd25e3c25 100644 --- a/cores/esp32/Esp.h +++ b/cores/esp32/Esp.h @@ -86,7 +86,7 @@ class EspClass const char * getSdkVersion(); //version of ESP-IDF const char * getCoreVersion();//version of this core - void deepSleep(uint32_t time_us); + void deepSleep(uint64_t time_us); uint32_t getFlashChipSize(); uint32_t getFlashChipSpeed(); diff --git a/cores/esp32/IPAddress.cpp b/cores/esp32/IPAddress.cpp index 0575363f254..002dccb3fcd 100644 --- a/cores/esp32/IPAddress.cpp +++ b/cores/esp32/IPAddress.cpp @@ -20,78 +20,244 @@ #include #include #include +#include -IPAddress::IPAddress() +IPAddress::IPAddress() : IPAddress(IPv4) {} + +IPAddress::IPAddress(IPType ip_type) { - _address.dword = 0; + _type = ip_type; + memset(_address.bytes, 0, sizeof(_address.bytes)); } IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { - _address.bytes[0] = first_octet; - _address.bytes[1] = second_octet; - _address.bytes[2] = third_octet; - _address.bytes[3] = fourth_octet; + _type = IPv4; + memset(_address.bytes, 0, sizeof(_address.bytes)); + _address.bytes[IPADDRESS_V4_BYTES_INDEX] = first_octet; + _address.bytes[IPADDRESS_V4_BYTES_INDEX + 1] = second_octet; + _address.bytes[IPADDRESS_V4_BYTES_INDEX + 2] = third_octet; + _address.bytes[IPADDRESS_V4_BYTES_INDEX + 3] = fourth_octet; +} + +IPAddress::IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16) { + _type = IPv6; + _address.bytes[0] = o1; + _address.bytes[1] = o2; + _address.bytes[2] = o3; + _address.bytes[3] = o4; + _address.bytes[4] = o5; + _address.bytes[5] = o6; + _address.bytes[6] = o7; + _address.bytes[7] = o8; + _address.bytes[8] = o9; + _address.bytes[9] = o10; + _address.bytes[10] = o11; + _address.bytes[11] = o12; + _address.bytes[12] = o13; + _address.bytes[13] = o14; + _address.bytes[14] = o15; + _address.bytes[15] = o16; } IPAddress::IPAddress(uint32_t address) { - _address.dword = address; + // IPv4 only + _type = IPv4; + memset(_address.bytes, 0, sizeof(_address.bytes)); + _address.dword[IPADDRESS_V4_DWORD_INDEX] = address; + + // NOTE on conversion/comparison and uint32_t: + // These conversions are host platform dependent. + // There is a defined integer representation of IPv4 addresses, + // based on network byte order (will be the value on big endian systems), + // e.g. http://2398766798 is the same as http://142.250.70.206, + // However on little endian systems the octets 0x83, 0xFA, 0x46, 0xCE, + // in that order, will form the integer (uint32_t) 3460758158 . +} + +IPAddress::IPAddress(const uint8_t *address) : IPAddress(IPv4, address) {} + +IPAddress::IPAddress(IPType ip_type, const uint8_t *address) +{ + _type = ip_type; + if (ip_type == IPv4) { + memset(_address.bytes, 0, sizeof(_address.bytes)); + memcpy(&_address.bytes[IPADDRESS_V4_BYTES_INDEX], address, sizeof(uint32_t)); + } else { + memcpy(_address.bytes, address, sizeof(_address.bytes)); + } } -IPAddress::IPAddress(const uint8_t *address) +IPAddress::IPAddress(const char *address) { - memcpy(_address.bytes, address, sizeof(_address.bytes)); + fromString(address); } IPAddress& IPAddress::operator=(const uint8_t *address) { - memcpy(_address.bytes, address, sizeof(_address.bytes)); + // IPv4 only conversion from byte pointer + _type = IPv4; + memset(_address.bytes, 0, sizeof(_address.bytes)); + memcpy(&_address.bytes[IPADDRESS_V4_BYTES_INDEX], address, sizeof(uint32_t)); + return *this; +} + +IPAddress& IPAddress::operator=(const char *address) +{ + fromString(address); return *this; } IPAddress& IPAddress::operator=(uint32_t address) { - _address.dword = address; + // IPv4 conversion + // See note on conversion/comparison and uint32_t + _type = IPv4; + memset(_address.bytes, 0, sizeof(_address.bytes)); + _address.dword[IPADDRESS_V4_DWORD_INDEX] = address; return *this; } +bool IPAddress::operator==(const IPAddress& addr) const +{ + return (addr._type == _type) + && (memcmp(addr._address.bytes, _address.bytes, sizeof(_address.bytes)) == 0); +} + bool IPAddress::operator==(const uint8_t* addr) const { - return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; + // IPv4 only comparison to byte pointer + // Can't support IPv6 as we know our type, but not the length of the pointer + return _type == IPv4 && memcmp(addr, &_address.bytes[IPADDRESS_V4_BYTES_INDEX], sizeof(uint32_t)) == 0; +} + +uint8_t IPAddress::operator[](int index) const { + if (_type == IPv4) { + return _address.bytes[IPADDRESS_V4_BYTES_INDEX + index]; + } + return _address.bytes[index]; +} + +uint8_t& IPAddress::operator[](int index) { + if (_type == IPv4) { + return _address.bytes[IPADDRESS_V4_BYTES_INDEX + index]; + } + return _address.bytes[index]; } size_t IPAddress::printTo(Print& p) const { size_t n = 0; - for(int i = 0; i < 3; i++) { - n += p.print(_address.bytes[i], DEC); + + if (_type == IPv6) { + // IPv6 IETF canonical format: compress left-most longest run of two or more zero fields, lower case + int8_t longest_start = -1; + int8_t longest_length = 1; + int8_t current_start = -1; + int8_t current_length = 0; + for (int8_t f = 0; f < 8; f++) { + if (_address.bytes[f * 2] == 0 && _address.bytes[f * 2 + 1] == 0) { + if (current_start == -1) { + current_start = f; + current_length = 1; + } else { + current_length++; + } + if (current_length > longest_length) { + longest_start = current_start; + longest_length = current_length; + } + } else { + current_start = -1; + } + } + for (int f = 0; f < 8; f++) { + if (f < longest_start || f >= longest_start + longest_length) { + uint8_t c1 = _address.bytes[f * 2] >> 4; + uint8_t c2 = _address.bytes[f * 2] & 0xf; + uint8_t c3 = _address.bytes[f * 2 + 1] >> 4; + uint8_t c4 = _address.bytes[f * 2 + 1] & 0xf; + if (c1 > 0) { + n += p.print((char)(c1 < 10 ? '0' + c1 : 'a' + c1 - 10)); + } + if (c1 > 0 || c2 > 0) { + n += p.print((char)(c2 < 10 ? '0' + c2 : 'a' + c2 - 10)); + } + if (c1 > 0 || c2 > 0 || c3 > 0) { + n += p.print((char)(c3 < 10 ? '0' + c3 : 'a' + c3 - 10)); + } + n += p.print((char)(c4 < 10 ? '0' + c4 : 'a' + c4 - 10)); + if (f < 7) { + n += p.print(':'); + } + } else if (f == longest_start) { + if (longest_start == 0) { + n += p.print(':'); + } + n += p.print(':'); + } + } + return n; + } + + // IPv4 + for (int i =0; i < 3; i++) + { + n += p.print(_address.bytes[IPADDRESS_V4_BYTES_INDEX + i], DEC); n += p.print('.'); } - n += p.print(_address.bytes[3], DEC); + n += p.print(_address.bytes[IPADDRESS_V4_BYTES_INDEX + 3], DEC); return n; } -String IPAddress::toString() const +String IPAddress::toString4() const { char szRet[16]; - sprintf(szRet,"%u.%u.%u.%u", _address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3]); + snprintf(szRet, sizeof(szRet), "%u.%u.%u.%u", _address.bytes[IPADDRESS_V4_BYTES_INDEX], _address.bytes[IPADDRESS_V4_BYTES_INDEX + 1], _address.bytes[IPADDRESS_V4_BYTES_INDEX + 2], _address.bytes[IPADDRESS_V4_BYTES_INDEX + 3]); return String(szRet); } +String IPAddress::toString6() const +{ + StreamString s; + s.reserve(40); + printTo(s); + return s; +} + +String IPAddress::toString() const +{ + if (_type == IPv4) { + return toString4(); + } else { + return toString6(); + } +} + bool IPAddress::fromString(const char *address) +{ + if (!fromString4(address)) + { + return fromString6(address); + } + return true; +} + +bool IPAddress::fromString4(const char *address) { // TODO: add support for "a", "a.b", "a.b.c" formats - uint16_t acc = 0; // Accumulator + int16_t acc = -1; // Accumulator uint8_t dots = 0; + memset(_address.bytes, 0, sizeof(_address.bytes)); while (*address) { char c = *address++; if (c >= '0' && c <= '9') { - acc = acc * 10 + (c - '0'); + acc = (acc < 0) ? (c - '0') : acc * 10 + (c - '0'); if (acc > 255) { // Value out of [0..255] range return false; @@ -100,11 +266,15 @@ bool IPAddress::fromString(const char *address) else if (c == '.') { if (dots == 3) { - // Too much dots (there must be 3 dots) + // Too many dots (there must be 3 dots) return false; } - _address.bytes[dots++] = acc; - acc = 0; + if (acc < 0) { + /* No value between dots, e.g. '1..' */ + return false; + } + _address.bytes[IPADDRESS_V4_BYTES_INDEX + dots++] = acc; + acc = -1; } else { @@ -117,7 +287,80 @@ bool IPAddress::fromString(const char *address) // Too few dots (there must be 3 dots) return false; } - _address.bytes[3] = acc; + if (acc < 0) { + /* No value between dots, e.g. '1..' */ + return false; + } + _address.bytes[IPADDRESS_V4_BYTES_INDEX + 3] = acc; + _type = IPv4; + return true; +} + +bool IPAddress::fromString6(const char *address) { + uint32_t acc = 0; // Accumulator + int colons = 0, double_colons = -1; + + while (*address) + { + char c = tolower(*address++); + if (isalnum(c) && c <= 'f') { + if (c >= 'a') + c -= 'a' - '0' - 10; + acc = acc * 16 + (c - '0'); + if (acc > 0xffff) + // Value out of range + return false; + } + else if (c == ':') { + if (*address == ':') { + if (double_colons >= 0) { + // :: allowed once + return false; + } + if (*address != '\0' && *(address + 1) == ':') { + // ::: not allowed + return false; + } + // remember location + double_colons = colons + !!acc; + address++; + } else if (*address == '\0') { + // can't end with a single colon + return false; + } + if (colons == 7) + // too many separators + return false; + _address.bytes[colons * 2] = acc >> 8; + _address.bytes[colons * 2 + 1] = acc & 0xff; + colons++; + acc = 0; + } + else + // Invalid char + return false; + } + + if (double_colons == -1 && colons != 7) { + // Too few separators + return false; + } + if (double_colons > -1 && colons > 6) { + // Too many segments (double colon must be at least one zero field) + return false; + } + _address.bytes[colons * 2] = acc >> 8; + _address.bytes[colons * 2 + 1] = acc & 0xff; + colons++; + + if (double_colons != -1) { + for (int i = colons * 2 - double_colons * 2 - 1; i >= 0; i--) + _address.bytes[16 - colons * 2 + double_colons * 2 + i] = _address.bytes[double_colons * 2 + i]; + for (int i = double_colons * 2; i < 16 - colons * 2 + double_colons * 2; i++) + _address.bytes[i] = 0; + } + + _type = IPv6; return true; } diff --git a/cores/esp32/IPAddress.h b/cores/esp32/IPAddress.h index 3bedd4f8749..329ca92afe9 100644 --- a/cores/esp32/IPAddress.h +++ b/cores/esp32/IPAddress.h @@ -26,13 +26,23 @@ // A class to make it easier to handle and pass around IP addresses +#define IPADDRESS_V4_BYTES_INDEX 12 +#define IPADDRESS_V4_DWORD_INDEX 3 + +enum IPType +{ + IPv4, + IPv6 +}; + class IPAddress: public Printable { private: union { - uint8_t bytes[4]; // IPv4 address - uint32_t dword; + uint8_t bytes[16]; + uint32_t dword[4]; } _address; + IPType _type; // Access the raw byte array containing the address. Because this returns a pointer // to the internal structure rather than a copy of the address this function should only @@ -40,57 +50,65 @@ class IPAddress: public Printable // stored. uint8_t* raw_address() { - return _address.bytes; + return _type == IPv4 ? &_address.bytes[IPADDRESS_V4_BYTES_INDEX] : _address.bytes; } public: // Constructors IPAddress(); + IPAddress(IPType ip_type); IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + IPAddress(uint8_t o1, uint8_t o2, uint8_t o3, uint8_t o4, uint8_t o5, uint8_t o6, uint8_t o7, uint8_t o8, uint8_t o9, uint8_t o10, uint8_t o11, uint8_t o12, uint8_t o13, uint8_t o14, uint8_t o15, uint8_t o16); IPAddress(uint32_t address); IPAddress(const uint8_t *address); + IPAddress(IPType ip_type, const uint8_t *address); + // If IPv4 fails tries IPv6 see fromString function + IPAddress(const char *address); virtual ~IPAddress() {} bool fromString(const char *address); bool fromString(const String &address) { return fromString(address.c_str()); } - // Overloaded cast operator to allow IPAddress objects to be used where a pointer - // to a four-byte uint8_t array is expected + // Overloaded cast operator to allow IPAddress objects to be used where a + // uint32_t is expected operator uint32_t() const { - return _address.dword; - } - bool operator==(const IPAddress& addr) const - { - return _address.dword == addr._address.dword; + return _type == IPv4 ? _address.dword[IPADDRESS_V4_DWORD_INDEX] : 0; } + + bool operator==(const IPAddress& addr) const; bool operator==(const uint8_t* addr) const; // Overloaded index operator to allow getting and setting individual octets of the address - uint8_t operator[](int index) const - { - return _address.bytes[index]; - } - uint8_t& operator[](int index) - { - return _address.bytes[index]; - } + uint8_t operator[](int index) const; + uint8_t& operator[](int index); // Overloaded copy operators to allow initialisation of IPAddress objects from other types IPAddress& operator=(const uint8_t *address); IPAddress& operator=(uint32_t address); + // If IPv4 fails tries IPv6 see fromString function + IPAddress& operator=(const char *address); virtual size_t printTo(Print& p) const; String toString() const; + IPType type() const { return _type; } + friend class EthernetClass; friend class UDP; friend class Client; friend class Server; friend class DhcpClass; friend class DNSClient; + +protected: + bool fromString4(const char *address); + bool fromString6(const char *address); + String toString4() const; + String toString6() const; }; // changed to extern because const declaration creates copies in BSS of INADDR_NONE for each CPP unit that includes it extern IPAddress INADDR_NONE; +extern IPAddress IN6ADDR_ANY; #endif diff --git a/cores/esp32/Tone.cpp b/cores/esp32/Tone.cpp index 77a254cd1d1..772b2b6bba1 100644 --- a/cores/esp32/Tone.cpp +++ b/cores/esp32/Tone.cpp @@ -95,6 +95,7 @@ void noTone(uint8_t pin){ .frequency = 0, // Ignored .duration = 0, // Ignored }; + xQueueReset(_tone_queue); // clear queue xQueueSend(_tone_queue, &tone_msg, portMAX_DELAY); } } diff --git a/cores/esp32/USBCDC.cpp b/cores/esp32/USBCDC.cpp index da0d5587af6..c99659dadac 100644 --- a/cores/esp32/USBCDC.cpp +++ b/cores/esp32/USBCDC.cpp @@ -79,7 +79,7 @@ void tud_cdc_tx_complete_cb(uint8_t itf){ static void ARDUINO_ISR_ATTR cdc0_write_char(char c){ if(devices[0] != NULL){ - devices[0]->write(c); + tud_cdc_n_write_char(0, c); } } diff --git a/cores/esp32/WString.cpp b/cores/esp32/WString.cpp index 6f0a4fc68a8..990a2824a51 100644 --- a/cores/esp32/WString.cpp +++ b/cores/esp32/WString.cpp @@ -677,7 +677,10 @@ int String::lastIndexOf(char ch, unsigned int fromIndex) const { wbuffer()[fromIndex + 1] = tempchar; if(temp == NULL) return -1; - return temp - buffer(); + const int rv = temp - buffer(); + if(rv >= len()) + return -1; + return rv; } int String::lastIndexOf(const String &s2) const { diff --git a/cores/esp32/esp32-hal-gpio.c b/cores/esp32/esp32-hal-gpio.c index 456f12c833e..df0e6a29984 100644 --- a/cores/esp32/esp32-hal-gpio.c +++ b/cores/esp32/esp32-hal-gpio.c @@ -104,14 +104,14 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode) #endif if (pin >= SOC_GPIO_PIN_COUNT) { - log_e("Invalid pin selected"); + log_e("Invalid IO %i selected", pin); return; } if(perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) == NULL){ perimanSetBusDeinit(ESP32_BUS_TYPE_GPIO, gpioDetachBus); if(!perimanClearPinBus(pin)){ - log_e("Deinit of previous bus failed"); + log_e("Deinit of previous bus from IO %i failed", pin); return; } } @@ -140,7 +140,7 @@ extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode) } if(gpio_config(&conf) != ESP_OK) { - log_e("GPIO config failed"); + log_e("IO %i config failed", pin); return; } if(perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) == NULL){ @@ -164,7 +164,7 @@ extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val) if(perimanGetPinBus(pin, ESP32_BUS_TYPE_GPIO) != NULL){ gpio_set_level((gpio_num_t)pin, val); } else { - log_e("Pin is not set as GPIO."); + log_e("IO %i is not set as GPIO.", pin); } } @@ -174,7 +174,7 @@ extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin) return gpio_get_level((gpio_num_t)pin); } else { - log_e("Pin is not set as GPIO."); + log_e("IO %i is not set as GPIO.", pin); return 0; } } @@ -204,7 +204,7 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, interrupt_initialized = (err == ESP_OK) || (err == ESP_ERR_INVALID_STATE); } if(!interrupt_initialized) { - log_e("GPIO ISR Service Failed To Start"); + log_e("IO %i ISR Service Failed To Start", pin); return; } @@ -256,6 +256,14 @@ extern void __detachInterrupt(uint8_t pin) gpio_set_intr_type((gpio_num_t)pin, GPIO_INTR_DISABLE); } +extern void enableInterrupt(uint8_t pin) { + gpio_intr_enable((gpio_num_t)pin); +} + +extern void disableInterrupt(uint8_t pin) { + gpio_intr_disable((gpio_num_t)pin); +} + extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode"))); extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite"))); diff --git a/cores/esp32/esp32-hal-gpio.h b/cores/esp32/esp32-hal-gpio.h index 69b55178d3f..a45302d9e99 100644 --- a/cores/esp32/esp32-hal-gpio.h +++ b/cores/esp32/esp32-hal-gpio.h @@ -78,6 +78,8 @@ int digitalRead(uint8_t pin); void attachInterrupt(uint8_t pin, void (*)(void), int mode); void attachInterruptArg(uint8_t pin, void (*)(void*), void * arg, int mode); void detachInterrupt(uint8_t pin); +void enableInterrupt(uint8_t pin); +void disableInterrupt(uint8_t pin); int8_t digitalPinToTouchChannel(uint8_t pin); int8_t digitalPinToAnalogChannel(uint8_t pin); diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c index c96d1b0a650..76d522c2313 100644 --- a/cores/esp32/esp32-hal-ledc.c +++ b/cores/esp32/esp32-hal-ledc.c @@ -56,12 +56,11 @@ static bool ledcDetachBus(void * bus){ return true; } -bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) +bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel) { - int free_channel = ~ledc_handle.used_channels & (ledc_handle.used_channels+1); - if (free_channel == 0 || resolution > LEDC_MAX_BIT_WIDTH) + if (channel >= LEDC_CHANNELS || resolution > LEDC_MAX_BIT_WIDTH) { - log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); + log_e("Channel %u is not available! (maximum %u) or bit width too big (maximum %u)", channel, LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); return false; } @@ -71,7 +70,6 @@ bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) return false; } - int channel = log2(free_channel & -free_channel); uint8_t group=(channel/8), timer=((channel/2)%4); ledc_timer_config_t ledc_timer = { @@ -115,8 +113,22 @@ bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) return false; } + log_i("LEDC attached to pin %u (channel %u, resolution %u)", pin, channel, resolution); return true; } + +bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution) +{ + uint8_t free_channel = ~ledc_handle.used_channels & (ledc_handle.used_channels+1); + if (free_channel == 0 || resolution > LEDC_MAX_BIT_WIDTH){ + log_e("No more LEDC channels available! (maximum %u) or bit width too big (maximum %u)", LEDC_CHANNELS, LEDC_MAX_BIT_WIDTH); + return false; + } + int channel = log2(free_channel & -free_channel); + + return ledcAttachChannel(pin, freq, resolution, channel); +} + bool ledcWrite(uint8_t pin, uint32_t duty) { ledc_channel_handle_t *bus = (ledc_channel_handle_t*)perimanGetPinBus(pin, ESP32_BUS_TYPE_LEDC); diff --git a/cores/esp32/esp32-hal-ledc.h b/cores/esp32/esp32-hal-ledc.h index ca172844247..c81da6dced2 100644 --- a/cores/esp32/esp32-hal-ledc.h +++ b/cores/esp32/esp32-hal-ledc.h @@ -45,6 +45,7 @@ typedef struct { //channel 0-15 resolution 1-16bits freq limits depend on resolution bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution); +bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel); bool ledcWrite(uint8_t pin, uint32_t duty); uint32_t ledcWriteTone(uint8_t pin, uint32_t freq); uint32_t ledcWriteNote(uint8_t pin, note_t note, uint8_t octave); diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index ba5447de969..00000000000 --- a/docs/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = source -BUILDDIR = build - -LINKCHECKDIR = build/linkcheck - -.PHONY: checklinks - checklinks: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(LINKCHECKDIR) - @echo - @echo "Check finished. Report is in $(LINKCHECKDIR)." - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/source/_static/arduino-ide.png b/docs/_static/arduino-ide.png similarity index 100% rename from docs/source/_static/arduino-ide.png rename to docs/_static/arduino-ide.png diff --git a/docs/source/_static/arduino_i2c_master.png b/docs/_static/arduino_i2c_master.png similarity index 100% rename from docs/source/_static/arduino_i2c_master.png rename to docs/_static/arduino_i2c_master.png diff --git a/docs/source/_static/arduino_i2c_slave.png b/docs/_static/arduino_i2c_slave.png similarity index 100% rename from docs/source/_static/arduino_i2c_slave.png rename to docs/_static/arduino_i2c_slave.png diff --git a/docs/_static/arduino_versions.js b/docs/_static/arduino_versions.js new file mode 100644 index 00000000000..825bc0cbc27 --- /dev/null +++ b/docs/_static/arduino_versions.js @@ -0,0 +1,16 @@ +var DOCUMENTATION_VERSIONS = { + DEFAULTS: { has_targets: false, + supported_targets: [ "esp32" ] + }, + VERSIONS: [ + { name: "latest", has_targets: true, supported_targets: [ "esp32", "esp32s2", "esp32s3", "esp32c3", "esp32h2", "esp32c6" ] }, + ], + IDF_TARGETS: [ + { text: "ESP32", value: "esp32"}, + { text: "ESP32-S2", value: "esp32s2"}, + { text: "ESP32-S3", value: "esp32s3"}, + { text: "ESP32-C3", value: "esp32c3"}, + { text: "ESP32-H2", value: "esp32h2"}, + { text: "ESP32-C6", value: "esp32c6"}, + ] +}; diff --git a/docs/source/_static/cross.png b/docs/_static/cross.png similarity index 100% rename from docs/source/_static/cross.png rename to docs/_static/cross.png diff --git a/docs/source/_static/esp32-c3_devkitM-1_pinlayout.png b/docs/_static/esp32-c3_devkitM-1_pinlayout.png similarity index 100% rename from docs/source/_static/esp32-c3_devkitM-1_pinlayout.png rename to docs/_static/esp32-c3_devkitM-1_pinlayout.png diff --git a/docs/source/_static/esp32-s2_saola1_pinlayout.png b/docs/_static/esp32-s2_saola1_pinlayout.png similarity index 100% rename from docs/source/_static/esp32-s2_saola1_pinlayout.png rename to docs/_static/esp32-s2_saola1_pinlayout.png diff --git a/docs/source/_static/esp32_devkitC_pinlayout.png b/docs/_static/esp32_devkitC_pinlayout.png similarity index 100% rename from docs/source/_static/esp32_devkitC_pinlayout.png rename to docs/_static/esp32_devkitC_pinlayout.png diff --git a/docs/source/_static/external_library_test_pr.png b/docs/_static/external_library_test_pr.png similarity index 100% rename from docs/source/_static/external_library_test_pr.png rename to docs/_static/external_library_test_pr.png diff --git a/docs/source/_static/external_library_test_schedule.png b/docs/_static/external_library_test_schedule.png similarity index 100% rename from docs/source/_static/external_library_test_schedule.png rename to docs/_static/external_library_test_schedule.png diff --git a/docs/source/_static/gpio_output.png b/docs/_static/gpio_output.png similarity index 100% rename from docs/source/_static/gpio_output.png rename to docs/_static/gpio_output.png diff --git a/docs/source/_static/gpio_pullup.png b/docs/_static/gpio_pullup.png similarity index 100% rename from docs/source/_static/gpio_pullup.png rename to docs/_static/gpio_pullup.png diff --git a/docs/source/_static/green_checkmark.png b/docs/_static/green_checkmark.png similarity index 100% rename from docs/source/_static/green_checkmark.png rename to docs/_static/green_checkmark.png diff --git a/docs/source/_static/install_guide_boards_manager_esp32.png b/docs/_static/install_guide_boards_manager_esp32.png similarity index 100% rename from docs/source/_static/install_guide_boards_manager_esp32.png rename to docs/_static/install_guide_boards_manager_esp32.png diff --git a/docs/source/_static/install_guide_boards_manager_url.png b/docs/_static/install_guide_boards_manager_url.png similarity index 100% rename from docs/source/_static/install_guide_boards_manager_url.png rename to docs/_static/install_guide_boards_manager_url.png diff --git a/docs/source/_static/install_guide_preferences.png b/docs/_static/install_guide_preferences.png similarity index 100% rename from docs/source/_static/install_guide_preferences.png rename to docs/_static/install_guide_preferences.png diff --git a/docs/source/_static/logo_arduino.png b/docs/_static/logo_arduino.png similarity index 100% rename from docs/source/_static/logo_arduino.png rename to docs/_static/logo_arduino.png diff --git a/docs/source/_static/logo_espressif.png b/docs/_static/logo_espressif.png similarity index 100% rename from docs/source/_static/logo_espressif.png rename to docs/_static/logo_espressif.png diff --git a/docs/source/_static/logo_linux.png b/docs/_static/logo_linux.png similarity index 100% rename from docs/source/_static/logo_linux.png rename to docs/_static/logo_linux.png diff --git a/docs/source/_static/logo_macos.png b/docs/_static/logo_macos.png similarity index 100% rename from docs/source/_static/logo_macos.png rename to docs/_static/logo_macos.png diff --git a/docs/source/_static/logo_pio.png b/docs/_static/logo_pio.png similarity index 100% rename from docs/source/_static/logo_pio.png rename to docs/_static/logo_pio.png diff --git a/docs/source/_static/logo_windows.png b/docs/_static/logo_windows.png similarity index 100% rename from docs/source/_static/logo_windows.png rename to docs/_static/logo_windows.png diff --git a/docs/source/_static/ota_esp32_login.png b/docs/_static/ota_esp32_login.png similarity index 100% rename from docs/source/_static/ota_esp32_login.png rename to docs/_static/ota_esp32_login.png diff --git a/docs/source/_static/ota_esp32_upload.png b/docs/_static/ota_esp32_upload.png similarity index 100% rename from docs/source/_static/ota_esp32_upload.png rename to docs/_static/ota_esp32_upload.png diff --git a/docs/source/_static/ota_esp32_verbose.png b/docs/_static/ota_esp32_verbose.png similarity index 100% rename from docs/source/_static/ota_esp32_verbose.png rename to docs/_static/ota_esp32_verbose.png diff --git a/docs/source/_static/ota_export_to_binary.png b/docs/_static/ota_export_to_binary.png similarity index 100% rename from docs/source/_static/ota_export_to_binary.png rename to docs/_static/ota_export_to_binary.png diff --git a/docs/source/_static/soc-module.png b/docs/_static/soc-module.png similarity index 100% rename from docs/source/_static/soc-module.png rename to docs/_static/soc-module.png diff --git a/docs/source/_static/tutorials/basic/tutorial_basic_ide.png b/docs/_static/tutorials/basic/tutorial_basic_ide.png similarity index 100% rename from docs/source/_static/tutorials/basic/tutorial_basic_ide.png rename to docs/_static/tutorials/basic/tutorial_basic_ide.png diff --git a/docs/source/_static/tutorials/peripherals/tutorial_peripheral_diagram.png b/docs/_static/tutorials/peripherals/tutorial_peripheral_diagram.png similarity index 100% rename from docs/source/_static/tutorials/peripherals/tutorial_peripheral_diagram.png rename to docs/_static/tutorials/peripherals/tutorial_peripheral_diagram.png diff --git a/docs/source/_static/usb_msc_drive.png b/docs/_static/usb_msc_drive.png similarity index 100% rename from docs/source/_static/usb_msc_drive.png rename to docs/_static/usb_msc_drive.png diff --git a/docs/source/_static/warning.png b/docs/_static/warning.png similarity index 100% rename from docs/source/_static/warning.png rename to docs/_static/warning.png diff --git a/docs/source/_static/wifi_esp32_ap.png b/docs/_static/wifi_esp32_ap.png similarity index 100% rename from docs/source/_static/wifi_esp32_ap.png rename to docs/_static/wifi_esp32_ap.png diff --git a/docs/source/_static/wifi_esp32_sta.png b/docs/_static/wifi_esp32_sta.png similarity index 100% rename from docs/source/_static/wifi_esp32_sta.png rename to docs/_static/wifi_esp32_sta.png diff --git a/docs/source/_static/win-gui-1.png b/docs/_static/win-gui-1.png similarity index 100% rename from docs/source/_static/win-gui-1.png rename to docs/_static/win-gui-1.png diff --git a/docs/source/_static/win-gui-2.png b/docs/_static/win-gui-2.png similarity index 100% rename from docs/source/_static/win-gui-2.png rename to docs/_static/win-gui-2.png diff --git a/docs/source/_static/win-gui-3.png b/docs/_static/win-gui-3.png similarity index 100% rename from docs/source/_static/win-gui-3.png rename to docs/_static/win-gui-3.png diff --git a/docs/source/_static/win-gui-4.png b/docs/_static/win-gui-4.png similarity index 100% rename from docs/source/_static/win-gui-4.png rename to docs/_static/win-gui-4.png diff --git a/docs/source/_static/win-gui-5.png b/docs/_static/win-gui-5.png similarity index 100% rename from docs/source/_static/win-gui-5.png rename to docs/_static/win-gui-5.png diff --git a/docs/source/_static/win-gui-update-1.png b/docs/_static/win-gui-update-1.png similarity index 100% rename from docs/source/_static/win-gui-update-1.png rename to docs/_static/win-gui-update-1.png diff --git a/docs/source/_static/win-gui-update-2.png b/docs/_static/win-gui-update-2.png similarity index 100% rename from docs/source/_static/win-gui-update-2.png rename to docs/_static/win-gui-update-2.png diff --git a/docs/conf_common.py b/docs/conf_common.py new file mode 100644 index 00000000000..eceaebb8a25 --- /dev/null +++ b/docs/conf_common.py @@ -0,0 +1,54 @@ +# --------------------------------------------------------------- + +from esp_docs.conf_docs import * # noqa: F403,F401 + +languages = ["en"] + +# idf_targets = [ +# "esp32", +# "esp32s2", +# "esp32s3", +# "esp32c3", +# "esp32c6", +# "esp32h2", +# ] + +# link roles config +github_repo = "espressif/arduino-esp32" + +# context used by sphinx_idf_theme +html_context["github_user"] = "espressif" +html_context["github_repo"] = "arduino-esp32" + +html_static_path = ["../_static"] + +# Conditional content + +extensions += ['sphinx_copybutton', + 'sphinx_tabs.tabs', + 'esp_docs.esp_extensions.dummy_build_system', + ] + +# ESP32_DOCS = [ +# "index.rst", +# ] + +# ESP32S2_DOCS = ESP32_DOCS +# ESP32C3_DOCS = ESP32S2_DOCS +# ESP32S3_DOCS = ESP32S2_DOCS +# ESP32C6_DOCS = ESP32S2_DOCS +# ESP32H2_DOCS = ESP32S2_DOCS + +# conditional_include_dict = { +# "esp32": ESP32_DOCS, +# "esp32s2": ESP32S2_DOCS, +# "esp32c3": ESP32C3_DOCS, +# "esp32s3": ESP32S3_DOCS, +# "esp32c6": ESP32C6_DOCS, +# "esp32h2": ESP32H2_DOCS, +# } + +# Extra options required by sphinx_idf_theme +project_slug = "arduino-esp32" + +# versions_url = "./_static/arduino_versions.js" diff --git a/docs/source/advanced_utils.rst b/docs/en/advanced_utils.rst similarity index 100% rename from docs/source/advanced_utils.rst rename to docs/en/advanced_utils.rst diff --git a/docs/source/api/adc.rst b/docs/en/api/adc.rst similarity index 100% rename from docs/source/api/adc.rst rename to docs/en/api/adc.rst diff --git a/docs/source/api/ble.rst b/docs/en/api/ble.rst similarity index 100% rename from docs/source/api/ble.rst rename to docs/en/api/ble.rst diff --git a/docs/source/api/bluetooth.rst b/docs/en/api/bluetooth.rst similarity index 100% rename from docs/source/api/bluetooth.rst rename to docs/en/api/bluetooth.rst diff --git a/docs/source/api/dac.rst b/docs/en/api/dac.rst similarity index 100% rename from docs/source/api/dac.rst rename to docs/en/api/dac.rst diff --git a/docs/source/api/deepsleep.rst b/docs/en/api/deepsleep.rst similarity index 100% rename from docs/source/api/deepsleep.rst rename to docs/en/api/deepsleep.rst diff --git a/docs/source/api/espnow.rst b/docs/en/api/espnow.rst similarity index 100% rename from docs/source/api/espnow.rst rename to docs/en/api/espnow.rst diff --git a/docs/source/api/ethernet.rst b/docs/en/api/ethernet.rst similarity index 100% rename from docs/source/api/ethernet.rst rename to docs/en/api/ethernet.rst diff --git a/docs/source/api/gpio.rst b/docs/en/api/gpio.rst similarity index 100% rename from docs/source/api/gpio.rst rename to docs/en/api/gpio.rst diff --git a/docs/source/api/i2c.rst b/docs/en/api/i2c.rst similarity index 99% rename from docs/source/api/i2c.rst rename to docs/en/api/i2c.rst index f53d8f27a3c..31a07f88046 100644 --- a/docs/source/api/i2c.rst +++ b/docs/en/api/i2c.rst @@ -19,7 +19,7 @@ The I2C can be used in two different modes: * **I2C Master Mode** * In this mode, the ESP32 generates the clock signal and initiates the communication with the slave device. -.. figure:: ../_static/arduino_i2c_master.png +.. figure:: ../../_static/arduino_i2c_master.png :align: center :width: 720 :figclass: align-center @@ -27,7 +27,7 @@ The I2C can be used in two different modes: * **I2C Slave Mode** * The slave mode, the clock is generated by the master device and responds to the master if the destination address is the same as the destination. -.. figure:: ../_static/arduino_i2c_slave.png +.. figure:: ../../_static/arduino_i2c_slave.png :align: center :width: 520 :figclass: align-center diff --git a/docs/source/api/i2s.rst b/docs/en/api/i2s.rst similarity index 100% rename from docs/source/api/i2s.rst rename to docs/en/api/i2s.rst diff --git a/docs/source/api/insights.rst b/docs/en/api/insights.rst similarity index 100% rename from docs/source/api/insights.rst rename to docs/en/api/insights.rst diff --git a/docs/source/api/ledc.rst b/docs/en/api/ledc.rst similarity index 92% rename from docs/source/api/ledc.rst rename to docs/en/api/ledc.rst index b69f581f5bf..1abeea2f6ee 100644 --- a/docs/source/api/ledc.rst +++ b/docs/en/api/ledc.rst @@ -27,6 +27,7 @@ ledcAttach ********** This function is used to setup LEDC pin with given frequency and resolution. +LEDC channel will be selected automatically. .. code-block:: arduino @@ -41,6 +42,25 @@ This function is used to setup LEDC pin with given frequency and resolution. This function will return ``true`` if configuration is successful. If ``false`` is returned, error occurs and LEDC channel was not configured. +ledcAttachChannel +***************** + +This function is used to setup LEDC pin with given frequency, resolution and channel. + +.. code-block:: arduino + + bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel); + +* ``pin`` select LEDC pin. +* ``freq`` select frequency of pwm. +* ``resolution`` select resolution for LEDC channel. +* ``channel`` select LEDC channel. + + * range is 1-14 bits (1-20 bits for ESP32). + +This function will return ``true`` if configuration is successful. +If ``false`` is returned, error occurs and LEDC channel was not configured. + ledcWrite ********* diff --git a/docs/source/api/preferences.rst b/docs/en/api/preferences.rst similarity index 100% rename from docs/source/api/preferences.rst rename to docs/en/api/preferences.rst diff --git a/docs/source/api/pulse_counter.rst b/docs/en/api/pulse_counter.rst similarity index 100% rename from docs/source/api/pulse_counter.rst rename to docs/en/api/pulse_counter.rst diff --git a/docs/source/api/rainmaker.rst b/docs/en/api/rainmaker.rst similarity index 100% rename from docs/source/api/rainmaker.rst rename to docs/en/api/rainmaker.rst diff --git a/docs/en/api/reset_reason.rst~HEAD b/docs/en/api/reset_reason.rst~HEAD new file mode 100644 index 00000000000..813216909b0 --- /dev/null +++ b/docs/en/api/reset_reason.rst~HEAD @@ -0,0 +1,19 @@ +############ +Reset Reason +############ + +About +----- + +.. note:: This is a work in progress project and this section is still missing. If you want to contribute, please see the `Contributions Guide <../contributing.html>`_. + +Example +------- + +To get started with Reset Reason, you can try: + +Reset Reason +************ + +.. literalinclude:: ../../../libraries/ESP32/examples/ResetReason/ResetReason/ResetReason.ino + :language: arduino diff --git a/docs/source/api/reset_reason.rst b/docs/en/api/reset_reason.rst~docs_migration_to_esp_docs similarity index 93% rename from docs/source/api/reset_reason.rst rename to docs/en/api/reset_reason.rst~docs_migration_to_esp_docs index 49bf9397797..006c2c1d530 100644 --- a/docs/source/api/reset_reason.rst +++ b/docs/en/api/reset_reason.rst~docs_migration_to_esp_docs @@ -15,5 +15,5 @@ To get started with Reset Reason, you can try: Reset Reason ************ -.. literalinclude:: ../../../libraries/ESP32/examples/ResetReason/ResetReason.ino +.. literalinclude:: ../../../libraries/ESP32/examples/ResetReason/ResetReason/ResetReason.ino :language: arduino \ No newline at end of file diff --git a/docs/source/api/rmt.rst b/docs/en/api/rmt.rst similarity index 100% rename from docs/source/api/rmt.rst rename to docs/en/api/rmt.rst diff --git a/docs/source/api/sdio.rst b/docs/en/api/sdio.rst similarity index 100% rename from docs/source/api/sdio.rst rename to docs/en/api/sdio.rst diff --git a/docs/source/api/sdmmc.rst b/docs/en/api/sdmmc.rst similarity index 100% rename from docs/source/api/sdmmc.rst rename to docs/en/api/sdmmc.rst diff --git a/docs/source/api/sigmadelta.rst b/docs/en/api/sigmadelta.rst similarity index 100% rename from docs/source/api/sigmadelta.rst rename to docs/en/api/sigmadelta.rst diff --git a/docs/source/api/spi.rst b/docs/en/api/spi.rst similarity index 100% rename from docs/source/api/spi.rst rename to docs/en/api/spi.rst diff --git a/docs/source/api/timer.rst b/docs/en/api/timer.rst similarity index 100% rename from docs/source/api/timer.rst rename to docs/en/api/timer.rst diff --git a/docs/source/api/touch.rst b/docs/en/api/touch.rst similarity index 100% rename from docs/source/api/touch.rst rename to docs/en/api/touch.rst diff --git a/docs/source/api/usb.rst b/docs/en/api/usb.rst similarity index 100% rename from docs/source/api/usb.rst rename to docs/en/api/usb.rst diff --git a/docs/source/api/usb_cdc.rst b/docs/en/api/usb_cdc.rst similarity index 100% rename from docs/source/api/usb_cdc.rst rename to docs/en/api/usb_cdc.rst diff --git a/docs/source/api/usb_msc.rst b/docs/en/api/usb_msc.rst similarity index 100% rename from docs/source/api/usb_msc.rst rename to docs/en/api/usb_msc.rst diff --git a/docs/en/api/wifi.rst~HEAD b/docs/en/api/wifi.rst~HEAD new file mode 100644 index 00000000000..ebae513e821 --- /dev/null +++ b/docs/en/api/wifi.rst~HEAD @@ -0,0 +1,678 @@ +######### +Wi-Fi API +######### + +About +----- + +The Wi-Fi API provides support for the 802.11b/g/n protocol driver. This API includes: + +* Station mode (STA mode or Wi-Fi client mode). ESP32 connects to an access point + +* AP mode (aka Soft-AP mode or Access Point mode). Devices connect to the ESP32 + +* Security modes (WPA2, WPA3 etc.) + +* Scanning for access points + +Working as AP +************* + +In this mode, the ESP32 is configured as an Access Point (AP) and it's capable of receiving incoming connections from other devices (stations) by providing +a Wi-Fi network. + +.. figure:: ../../_static/wifi_esp32_ap.png + :align: center + :width: 520 + :figclass: align-center + +This mode can be used for serving an HTTP or HTTPS server inside the ESP32, for example. + +Working as STA +************** + +The STA mode is used to connect the ESP32 to a Wi-Fi network, provided by an Access Point. + +.. figure:: ../../_static/wifi_esp32_sta.png + :align: center + :width: 520 + :figclass: align-center + +This is the mode to be used if you want to connect your project to the Internet. + +API Description +--------------- + +Here is the description of the WiFi API. + +Common API +---------- + +Here are the common APIs that are used for both modes, AP and STA. + +onEvent (and removeEvent) +************************* + +Registers a caller-supplied function to be called when WiFi events +occur. Several forms are available. + +Function pointer callback taking the event ID: + +.. code-block:: arduino + + typedef void (*WiFiEventCb)(arduino_event_id_t); + wifi_event_id_t onEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + +Function pointer callback taking an event-ID-and-info struct: + +.. code-block:: arduino + + typedef struct{ + arduino_event_id_t event_id; + arduino_event_info_t event_info; + } arduino_event_t; + + typedef void (*WiFiEventSysCb)(arduino_event_t *); + wifi_event_id_t onEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + +Callback using ``std::function`` taking event ID and info separately: + +.. code-block:: arduino + + typedef std::function WiFiEventFuncCb; + wifi_event_id_t onEvent(WiFiEventFuncCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + +A similar set of functions are available to remove callbacks: + +.. code-block:: arduino + + void removeEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + void removeEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + void removeEvent(wifi_event_id_t = ARDUINO_EVENT_MAX); + +In all cases, the subscribing function accepts an optional event type to +invoke the callback only for that specific event; with the default +``ARDUINO_EVENT_MAX``, the callback will be invoked for all WiFi events. + +Any callback function is given the event type in a parameter. +Some of the possible callback function formats also take an +``arduino_event_info_t`` (or use ``arduino_event_t`` which includes both +ID and info) which is a union of structs with additional information +about different event types. + +See +`WiFiGeneric.h `_ +for the list of event types and "info" substructures, and also see a full +example of event handling: `events example`_. + +.. warning:: + + Event callback functions are invoked on a separate + `thread `_ + (`FreeRTOS task `_) + independent of the main application thread that runs ``setup()`` and + ``loop()``. Callback functions must therefore be + `thread-safe `_; + they must not access shared/global variables directly without locking, + and must only call similarly thread-safe functions. + + Some core operations like ``Serial.print()`` are thread-safe but many + functions are not. Notably, ``WiFi.onEvent()`` and ``WiFi.removeEvent()`` + are not thread-safe and should never be invoked from a callback thread. + +setHostname (and getHostname) +***************************** + +Sets the name the DHCP client uses to identify itself. In a typical network +setup this will be the name that shows up in the Wi-Fi router's device list. +The hostname must be no longer than 32 characters. + +.. code-block:: arduino + + setHostname(const char *hostname); + +If the hostname is never specified, a default one will be assigned based +on the chip type and MAC address. The current hostname (default or custom) +may be retrieved: + +.. code-block:: arduino + + const char *getHostname(); + +.. warning:: + + The ``setHostname()`` function must be called BEFORE WiFi is started with + ``WiFi.begin()``, ``WiFi.softAP()``, ``WiFi.mode()``, or ``WiFi.run()``. + To change the name, reset WiFi with ``WiFi.mode(WIFI_MODE_NULL)``, + then proceed with ``WiFi.setHostname(...)`` and restart WiFi from scratch. + +useStaticBuffers +**************** + +This function is used to set the memory allocation mode for the Wi-Fi buffers. + +.. code-block:: arduino + + static void useStaticBuffers(bool bufferMode); + +* Set ``true`` to use the Wi-Fi buffers memory allocation as **static**. +* Set ``false`` to set the buffers memory allocation to **dynamic**. + +The use of dynamic allocation is recommended to save memory and reduce resources usage. However, the dynamic performs slightly slower than the static allocation. +Use static allocation if you want to have more performance and if your application is multi-tasking. + +By default, the memory allocation will be set to **dynamic** if this function is not being used. + +setDualAntennaConfig +******************** + +Configures the Dual antenna functionallity. This function should be used only on the **ESP32-WROOM-DA** module or any other ESP32 with RF switch. + +.. code-block:: arduino + + bool setDualAntennaConfig(uint8_t gpio_ant1, uint8_t gpio_ant2, wifi_rx_ant_t rx_mode, wifi_tx_ant_t tx_mode); + + +* ``gpio_ant1`` Configure the GPIO number for the antenna 1 connected to the RF switch (default ``GPIO2`` on ESP32-WROOM-DA) +* ``gpio_ant2`` Configure the GPIO number for the antenna 2 connected to the RF switch (default ``GPIO25`` on ESP32-WROOM-DA) +* ``rx_mode`` Set the RX antenna mode. See wifi_rx_ant_t for the options. +* ``tx_mode`` Set the TX antenna mode. See wifi_tx_ant_t for the options. + +Return ``true`` if the configuration was successful. + +For the ``rx_mode`` you can use the following configuration: + +* ``WIFI_RX_ANT0`` Selects the antenna 1 for all RX activity. +* ``WIFI_RX_ANT1`` Selects the antenna 2 for all RX activity. +* ``WIFI_RX_ANT_AUTO`` Selects the antenna for RX automatically. + +For the ``tx_mode`` you can use the following configuration: + +* ``WIFI_TX_ANT0`` Selects the antenna 1 for all TX activity. +* ``WIFI_TX_ANT1`` Selects the antenna 2 for all TX activity. +* ``WIFI_TX_ANT_AUTO`` Selects the antenna for TX automatically. + +WiFiAP +------ + +The ``WiFiAP`` is used to configure and manage the Wi-Fi as an Access Point. This is where you can find the related functions for the AP. + +Basic Usage +*********** + +To start the Wi-Fi as an Access Point. + +.. code-block:: arduino + + WiFi.softAP(ssid, password); + +Please see the full WiFiAP example in: `ap example`_. + +AP Configuration +---------------- + +softAP +****** + +Use the function ``softAP`` to configure the Wi-Fi AP characteristics: + +.. code-block:: arduino + + bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4, bool ftm_responder = false); + +Where: + +* ``ssid`` sets the Wi-Fi network SSID. +* ``passphrase`` sets the Wi-Fi network password. If the network is open, set as ``NULL``. +* ``channel`` configures the Wi-Fi channel. +* ``ssid_hidden`` sets the network as hidden. +* ``max_connection`` sets the maximum number of simultaneous connections. The default is 4. +* ``ftm_responder`` sets the Wi-Fi FTM responder feature. **Only for ESP32-S2 and ESP32-C3 SoC!** + +Return ``true`` if the configuration was successful. + +softAPConfig +************ + +Function used to configure the IP as static (fixed) as well as the gateway and subnet. + +.. code-block:: arduino + + bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet); + +Where: + +* ``local_ip`` sets the local IP address. +* ``gateway`` sets the gateway IP. +* ``subnet`` sets the subnet mask. + +The function will return ``true`` if the configuration is successful. + +AP Connection +------------- + +softAPdisconnect +**************** + +Function used to force the AP disconnection. + +.. code-block:: arduino + + bool softAPdisconnect(bool wifioff = false); + +Where: + +* ``wifioff`` sets the Wi-Fi off if ``true``. + +The function will return ``true`` if the configuration is successful. + + +softAPgetStationNum +******************* + +This function returns the number of clients connected to the AP. + +.. code-block:: arduino + + uint8_t softAPgetStationNum(); + +softAPIP +******** + +Function to get the AP IPv4 address. + +.. code-block:: arduino + + IPAddress softAPIP(); + +The function will return the AP IP address in ``IPAddress`` format. + +softAPBroadcastIP +***************** + +Function to get the AP IPv4 broadcast address. + +.. code-block:: arduino + + IPAddress softAPBroadcastIP(); + +The function will return the AP broadcast address in ``IPAddress`` format. + +softAPNetworkID +*************** + +Get the softAP network ID. + +.. code-block:: arduino + + IPAddress softAPNetworkID(); + +The function will return the AP network address in ``IPAddress`` format. + +softAPSubnetCIDR +**************** + +Get the softAP subnet CIDR. + +.. code-block:: arduino + + uint8_t softAPSubnetCIDR(); + +softAPSubnetMask +**************** + +Get the softAP subnet mask. + +.. code-block:: arduino + + IPAddress softAPSubnetMask(); + +softAPenableIpV6 +**************** + +Function used to enable the IPv6 support. + +.. code-block:: arduino + + bool softAPenableIpV6(); + +The function will return ``true`` if the configuration is successful. + +softAPIPv6 +********** + +Function to get the IPv6 address. + +.. code-block:: arduino + + IPv6Address softAPIPv6(); + +The function will return the AP IPv6 address in ``IPv6Address`` format. + +softAPgetHostname +***************** + +Function to get the AP hostname. + +.. code-block:: arduino + + const char * softAPgetHostname(); + +softAPsetHostname +***************** + +Function to set the AP hostname. + +.. code-block:: arduino + + bool softAPsetHostname(const char * hostname); + +Where: + +* ``hostname`` sets the device hostname. + +The function will return ``true`` if the configuration is successful. + + +softAPmacAddress +**************** + +Function to define the AP MAC address. + +.. code-block:: arduino + + uint8_t* softAPmacAddress(uint8_t* mac); + +Where: + +* ``mac`` sets the new MAC address. + +Function to get the AP MAC address. + +.. code-block:: arduino + + String softAPmacAddress(void); + +softAPSSID +********** + +Function to get the AP SSID. + +.. code-block:: arduino + + String softAPSSID(void) const; + +Returns the AP SSID. + +WiFiSTA +------- + +The ``WiFiSTA`` is used to configure and manage the Wi-Fi as Station. The related functions for the STA are here. + +Basic Usage +*********** + +The following code shows the basic usage of the WifiSTA functionality. + +.. code-block:: arduino + + WiFi.begin(ssid, password); + +Where the ``ssid`` and ``password`` are from the network you want to connect the ESP32. + +To check if the connection is successful, you can use: + +.. code-block:: arduino + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + +After a successful connection, you can print the IP address given by the network. + +.. code-block:: arduino + + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + +Please see the full example of the WiFiSTA in: `sta example`_. + +STA Configuration +----------------- + +begin +***** + +- Functions ``begin`` are used to configure and start the Wi-Fi. + +.. code-block:: arduino + + wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + +Where: + +* ``ssid`` sets the AP SSID. +* ``passphrase`` sets the AP password. Set as ``NULL`` for open networks. +* ``channel`` sets the Wi-Fi channel. +* ``uint8_t* bssid`` sets the AP BSSID. +* ``connect`` sets ``true`` to connect to the configured network automatically. + +.. code-block:: arduino + + wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + +Where: + +* ``ssid`` sets the AP SSID. +* ``passphrase`` sets the AP password. Set as ``NULL`` for open networks. +* ``channel`` sets the Wi-Fi channel. +* ``bssid`` sets the AP BSSID. +* ``connect`` sets ``true`` to connect to the configured network automatically. + +Function to start the connection after being configured. + +.. code-block:: arduino + + wl_status_t begin(); + +config +****** + +Function ``config`` is used to configure Wi-Fi. After configuring, you can call function ``begin`` to start the Wi-Fi process. + +.. code-block:: arduino + + bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); + +Where: + +* ``local_ip`` sets the local IP. +* ``gateway`` sets the gateway IP. +* ``subnet`` sets the subnet mask. +* ``dns1`` sets the DNS. +* ``dns2`` sets the DNS alternative option. + +The function will return ``true`` if the configuration is successful. + +The ``IPAddress`` format is defined by 4 bytes as described here: + +.. code-block:: arduino + + IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); + +Example: + +.. code-block:: arduino + + IPAddress local_ip(192, 168, 10, 20); + +See the ``WiFiClientStaticIP.ino`` for more details on how to use this feature. + +STA Connection +-------------- + +reconnect +********* + +Function used to reconnect the Wi-Fi connection. + +.. code-block:: arduino + + bool reconnect(); + +disconnect +********** + +Function to force disconnection. + +.. code-block:: arduino + + bool disconnect(bool wifioff = false, bool eraseap = false); + +Where: + +* ``wifioff`` use ``true`` to turn the Wi-Fi radio off. +* ``eraseap`` use ``true`` to erase the AP configuration from the NVS memory. + +The function will return ``true`` if the configuration is successful. + +isConnected +*********** + +Function used to get the connection state. + +.. code-block:: arduino + + bool isConnected(); + +Return the connection state. + +setAutoConnect +************** + +Function is deprecated. + +getAutoConnect +************** + +Function is deprecated. + +setAutoReconnect +**************** + +Function used to set the automatic reconnection if the connection is lost. + +.. code-block:: arduino + + bool setAutoReconnect(bool autoReconnect); + +Where: + +* ``autoConnect`` is set to ``true`` to enable this option. + +getAutoReconnect +**************** + +Function used to get the automatic reconnection if the connection is lost. + +.. code-block:: arduino + + bool getAutoReconnect(); + +The function will return ``true`` if this setting is enabled. + +setMinSecurity +************** + +Function used to set the minimum security for AP to be considered connectable. + +.. code-block:: arduino + + bool setMinSecurity(wifi_auth_mode_t minSecurity); + +Where: + +* ``minSecurity`` is the minimum security for AP to be considered connectable. Default is ``WIFI_AUTH_WPA2_PSK``. + +WiFiMulti +--------- + +The ``WiFiMulti`` allows you to add more than one option for the AP connection while running as a station. + +To add the AP, use the following function. You can add multiple AP's and this library will handle the connection. + +.. code-block:: arduino + + bool addAP(const char* ssid, const char *passphrase = NULL); + +After adding the AP's, run by the following function. + +.. code-block:: arduino + + uint8_t run(uint32_t connectTimeout=5000); + +To see how to use the ``WiFiMulti``, take a look at the ``WiFiMulti.ino`` example available. + +WiFiScan +-------- + +To perform the Wi-Fi scan for networks, you can use the following functions: + +Start scan WiFi networks available. + +.. code-block:: arduino + + int16_t scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300, uint8_t channel = 0); + +Called to get the scan state in Async mode. + +.. code-block:: arduino + + int16_t scanComplete(); + +Delete last scan result from RAM. + +.. code-block:: arduino + + void scanDelete(); + +Loads all infos from a scanned wifi in to the ptr parameters. + +.. code-block:: arduino + + bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel); + +To see how to use the ``WiFiScan``, take a look at the ``WiFiScan.ino`` example available. + +Examples +-------- + +`Complete list of WiFi examples `_. + +.. _ap example: + +Wi-Fi AP Example +**************** + +.. literalinclude:: ../../../libraries/WiFi/examples/WiFiAccessPoint/WiFiAccessPoint.ino + :language: arduino + +.. _sta example: + +Wi-Fi STA Example +***************** + +.. literalinclude:: ../../../libraries/WiFi/examples/WiFiClient/WiFiClient.ino + :language: arduino + +References +---------- + +.. _events example: + +Wi-Fi Events Example +******************** + +.. literalinclude:: ../../../libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino + :language: arduino diff --git a/docs/source/api/wifi.rst b/docs/en/api/wifi.rst~docs_migration_to_esp_docs similarity index 99% rename from docs/source/api/wifi.rst rename to docs/en/api/wifi.rst~docs_migration_to_esp_docs index 1fd5651f38b..9a4c1b17aba 100644 --- a/docs/source/api/wifi.rst +++ b/docs/en/api/wifi.rst~docs_migration_to_esp_docs @@ -21,7 +21,7 @@ Working as AP In this mode, the ESP32 is configured as an Access Point (AP) and it's capable of receiving incoming connections from other devices (stations) by providing a Wi-Fi network. -.. figure:: ../_static/wifi_esp32_ap.png +.. figure:: ../../_static/wifi_esp32_ap.png :align: center :width: 520 :figclass: align-center @@ -33,7 +33,7 @@ Working as STA The STA mode is used to connect the ESP32 to a Wi-Fi network, provided by an Access Point. -.. figure:: ../_static/wifi_esp32_sta.png +.. figure:: ../../_static/wifi_esp32_sta.png :align: center :width: 520 :figclass: align-center diff --git a/docs/source/boards/ESP32-C3-DevKitM-1.rst b/docs/en/boards/ESP32-C3-DevKitM-1.rst similarity index 98% rename from docs/source/boards/ESP32-C3-DevKitM-1.rst rename to docs/en/boards/ESP32-C3-DevKitM-1.rst index 7ce9475d69b..11e6e45d55f 100644 --- a/docs/source/boards/ESP32-C3-DevKitM-1.rst +++ b/docs/en/boards/ESP32-C3-DevKitM-1.rst @@ -88,7 +88,7 @@ No. Name Type [1]_ Function Pin Layout ---------- -.. figure:: ../_static/esp32-c3_devkitM-1_pinlayout.png +.. figure:: ../../_static/esp32-c3_devkitM-1_pinlayout.png :align: center :width: 600 :alt: ESP32-C3-DevKitM-1 (click to enlarge) diff --git a/docs/source/boards/ESP32-DevKitC-1.rst b/docs/en/boards/ESP32-DevKitC-1.rst similarity index 98% rename from docs/source/boards/ESP32-DevKitC-1.rst rename to docs/en/boards/ESP32-DevKitC-1.rst index dcd5632eab7..4bb86696227 100644 --- a/docs/source/boards/ESP32-DevKitC-1.rst +++ b/docs/en/boards/ESP32-DevKitC-1.rst @@ -96,7 +96,7 @@ No. Name Type Function Pin Layout ---------- -.. figure:: ../_static/esp32_devkitC_pinlayout.png +.. figure:: ../../_static/esp32_devkitC_pinlayout.png :align: center :width: 600 :alt: ESP32-DevKitC-1 (click to enlarge) diff --git a/docs/source/boards/ESP32-S2-Saola-1.rst b/docs/en/boards/ESP32-S2-Saola-1.rst similarity index 98% rename from docs/source/boards/ESP32-S2-Saola-1.rst rename to docs/en/boards/ESP32-S2-Saola-1.rst index fd41772c234..1a06a6d87bb 100644 --- a/docs/source/boards/ESP32-S2-Saola-1.rst +++ b/docs/en/boards/ESP32-S2-Saola-1.rst @@ -100,7 +100,7 @@ No. Name Type Function Pin Layout ---------- -.. figure:: ../_static/esp32-s2_saola1_pinlayout.png +.. figure:: ../../_static/esp32-s2_saola1_pinlayout.png :align: center :width: 600 :alt: ESP32-S2-Saola-1 (click to enlarge) diff --git a/docs/source/boards/boards.rst b/docs/en/boards/boards.rst similarity index 94% rename from docs/source/boards/boards.rst rename to docs/en/boards/boards.rst index 6214fe4ebd1..3730f6ef2d1 100644 --- a/docs/source/boards/boards.rst +++ b/docs/en/boards/boards.rst @@ -21,16 +21,16 @@ The ESP32 is divided by family: * ESP32-S * Wi-Fi only * ESP32-C - * Wi-Fi and BLE 5 + * Wi-Fi, BLE 5 and IEEE 802.15.4 (Zigbee and Thread) - C6 only * ESP32-H - * BLE and IEEE 802.15.4 + * BLE and IEEE 802.15.4 (Zigbee and Thread) For each family, we have SoC variants with some differentiation. The differences are more about the embedded flash and its size and the number of the cores (dual or single). The modules use the SoC internally, including the external flash, PSRAM (in some models) and other essential electronic components. Essentially, all modules from the same family use the same SoC. -.. figure:: ../_static/soc-module.png +.. figure:: ../../_static/soc-module.png :align: center :width: 250 :alt: ESP32 SoC and Module (click to enlarge) @@ -60,7 +60,7 @@ Before buying: Keep in mind that for some "must have" features when choosing the Espressif --------- -.. figure:: ../_static/logo_espressif.png +.. figure:: ../../_static/logo_espressif.png :align: center :width: 250 :alt: Espressif Logo diff --git a/docs/en/boards/boards.rst~docs_migration_to_esp_docs b/docs/en/boards/boards.rst~docs_migration_to_esp_docs new file mode 100644 index 00000000000..7323ba2a933 --- /dev/null +++ b/docs/en/boards/boards.rst~docs_migration_to_esp_docs @@ -0,0 +1,121 @@ +###### +Boards +###### + +Development Boards +------------------ + +You will need a development board or a custom board with the ESP32 (see Supported SoC's) to start playing. +There is a bunch of different types and models widely available on the Internet. You need to choose one that covers all your requirements. + +To help you on this selection, we point out some facts about choosing the proper boards to help you to save money and time. + +**One ESP32 to rule them all!** + +One important information that usually bring about some confusion is regarding the different models of the ESP32 SoC and modules. + +The ESP32 is divided by family: + +* ESP32 + * Wi-Fi and BLE +* ESP32-S + * Wi-Fi only +* ESP32-C + * Wi-Fi and BLE 5 + * IEEE 802.15.4 (only in ESP32-C6) +* ESP32-H + * BLE and IEEE 802.15.4 + +For each family, we have SoC variants with some differentiation. The differences are more about the embedded flash and its size and the number of the cores (dual or single). + +The modules use the SoC internally, including the external flash, PSRAM (in some models) and other essential electronic components. Essentially, all +modules from the same family use the same SoC. + +.. figure:: ../../_static/soc-module.png + :align: center + :width: 250 + :alt: ESP32 SoC and Module (click to enlarge) + :figclass: align-center + +**For example:** + +The SoC partnumber is the ESP32-D0WD-V3 and it's the same SoC used inside of the ESP32-WROVER (with PSRAM) and ESP32-WROOM modules. This means that the +same characteristics are present in both modules' core. + +For more detailed information regarding the SoC's and modules, see the `Espressif Product Selector`_. + +Now that you know that the module can be different but the heart is the same, you can choose your development board. + +Before buying: Keep in mind that for some "must have" features when choosing the best board for your needs: + +- Embedded USB-to-Serial + - This is very convenient for programming and monitoring the logs with the terminal via USB. +- Breadboard friendly + - If you are prototyping, this will be very useful to connect your board directly on the breadboard. +- open-source/open-hardware + - Check if the schematics are available for download. This helps a lot on prototyping. +- Support + - Some of the manufacturers offer a very good level of support, with examples and demo projects. + + +Espressif +--------- + +.. figure:: ../../_static/logo_espressif.png + :align: center + :width: 250 + :alt: Espressif Logo + :figclass: align-center + +.. toctree:: + :maxdepth: 1 + + ESP32-DevKitC + ESP32-S2-Saola-1 + ESP32-C3-DevKitM-1 + +.. note:: + Only a few development boards are described on this documentation page. For more information about other Espressif development boards please refer to the `Espressif website `_. + +Third Party +----------- + +Add here the third party boards, listed by vendors. + +.. note:: + All the information must be provided by the vendor. If your favorite board is not here, consider + creating an `issue on GitHub `_ and directly + link/mention the vendor in the issue description. + +LOLIN +***** + +* |board_lolin_d32| +* |board_lolin_d32_pro| + +Generic Vendor +************** + + .. toctree:: + :maxdepth: 1 + + Generic Board Name + + .. note:: + Create one file per board or one file with multiple boards. Do not add board information/description on this file. + +.. include:: ../common/datasheet.inc + +Resources +--------- + +.. _Espressif Systems: https://www.espressif.com +.. _Espressif Product Selector: https://products.espressif.com/ + +.. |board_lolin_d32| raw:: html + + LOLIN D32 + +.. |board_lolin_d32_pro| raw:: html + + LOLIN D32 Pro diff --git a/docs/source/boards/generic.rst b/docs/en/boards/generic.rst similarity index 100% rename from docs/source/boards/generic.rst rename to docs/en/boards/generic.rst diff --git a/docs/source/common/datasheet.inc b/docs/en/common/datasheet.inc similarity index 100% rename from docs/source/common/datasheet.inc rename to docs/en/common/datasheet.inc diff --git a/docs/en/conf.py b/docs/en/conf.py new file mode 100644 index 00000000000..9979662dae0 --- /dev/null +++ b/docs/en/conf.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# +# English Language RTD & Sphinx config file +# +# Uses ../conf_common.py for most non-language-specific settings. + +# Importing conf_common adds all the non-language-specific +# parts to this conf module + +try: + from conf_common import * # noqa: F403,F401 +except ImportError: + import os + import sys + sys.path.insert(0, os.path.abspath('../')) + from conf_common import * # noqa: F403,F401 + +import datetime +current_year = datetime.datetime.now().year + +# General information about the project. +project = u'Arduino ESP32' +copyright = u'2016 - {}, Espressif Systems (Shanghai) Co., Ltd'.format(current_year) +pdf_title = u'Arduino ESP32 Documentation Guide' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +language = 'en' + +# Tracking ID for Google Analytics +google_analytics_id = 'G-F58JM78930' \ No newline at end of file diff --git a/docs/source/contributing.rst b/docs/en/contributing.rst similarity index 100% rename from docs/source/contributing.rst rename to docs/en/contributing.rst diff --git a/docs/source/esp-idf_component.rst b/docs/en/esp-idf_component.rst similarity index 100% rename from docs/source/esp-idf_component.rst rename to docs/en/esp-idf_component.rst diff --git a/docs/source/external_libraries_test.rst b/docs/en/external_libraries_test.rst similarity index 92% rename from docs/source/external_libraries_test.rst rename to docs/en/external_libraries_test.rst index 2064987df07..0a5a34a9e1a 100644 --- a/docs/source/external_libraries_test.rst +++ b/docs/en/external_libraries_test.rst @@ -104,7 +104,7 @@ You can check the results in `LIBRARIES_TEST.md`_. The results file example: -.. image:: _static/external_library_test_schedule.png +.. image:: ../_static/external_library_test_schedule.png :width: 600 Pull Request test result @@ -113,20 +113,20 @@ Pull Request test result If the test run on Pull Request, it will compile all libraries and sketches 2 times (before/after changes in PR) to see, if the PR is breaking/fixing libraries. In the table the results are in order ``BEFORE -> AFTER``. -.. image:: _static/external_library_test_pr.png +.. image:: ../_static/external_library_test_pr.png :width: 600 -.. |success| image:: _static/green_checkmark.png +.. |success| image:: ../_static/green_checkmark.png :height: 2ex :class: no-scaled-link -.. |warning| image:: _static/warning.png +.. |warning| image:: ../_static/warning.png :height: 2ex :class: no-scaled-link -.. |fail| image:: _static/cross.png +.. |fail| image:: ../_static/cross.png :height: 2ex :class: no-scaled-link .. _LIBRARIES_TEST.md: https://github.com/espressif/arduino-esp32/blob/gh-pages/LIBRARIES_TEST.md -.. _lib.json: https://github.com/espressif/arduino-esp32/.github/workflow/lib.json \ No newline at end of file +.. _lib.json: https://github.com/espressif/arduino-esp32/blob/master/.github/workflows/lib.json diff --git a/docs/source/faq.rst b/docs/en/faq.rst similarity index 100% rename from docs/source/faq.rst rename to docs/en/faq.rst diff --git a/docs/source/getting_started.rst b/docs/en/getting_started.rst similarity index 95% rename from docs/source/getting_started.rst rename to docs/en/getting_started.rst index 3540dda685b..9267f1b427f 100644 --- a/docs/source/getting_started.rst +++ b/docs/en/getting_started.rst @@ -64,9 +64,9 @@ Supported Operating Systems | Windows | Linux | macOS | +-------------------+-------------------+-------------------+ -.. |windows-logo| image:: _static/logo_windows.png -.. |linux-logo| image:: _static/logo_linux.png -.. |macos-logo| image:: _static/logo_macos.png +.. |windows-logo| image:: ../_static/logo_windows.png +.. |linux-logo| image:: ../_static/logo_linux.png +.. |macos-logo| image:: ../_static/logo_macos.png Supported IDEs --------------------------- @@ -79,8 +79,8 @@ Here is the list of supported IDE for Arduino ESP32 support integration. | Arduino IDE | PlatformIO | +-------------------+-------------------+ -.. |arduino-logo| image:: _static/logo_arduino.png -.. |pio-logo| image:: _static/logo_pio.png +.. |arduino-logo| image:: ../_static/logo_arduino.png +.. |pio-logo| image:: ../_static/logo_pio.png See `Installing Guides `_ for more details on how to install the Arduino ESP32 support. diff --git a/docs/source/guides/core_debug.rst b/docs/en/guides/core_debug.rst similarity index 100% rename from docs/source/guides/core_debug.rst rename to docs/en/guides/core_debug.rst diff --git a/docs/source/guides/docs_contributing.rst b/docs/en/guides/docs_contributing.rst similarity index 99% rename from docs/source/guides/docs_contributing.rst rename to docs/en/guides/docs_contributing.rst index be5a54e4b37..3bcffc0bf74 100644 --- a/docs/source/guides/docs_contributing.rst +++ b/docs/en/guides/docs_contributing.rst @@ -309,7 +309,7 @@ After that, you can use the following structure to include the image in the docs .. code-block:: - .. figure:: ../_static/arduino_i2c_master.png + .. figure:: ../../_static/arduino_i2c_master.png :align: center :width: 720 :figclass: align-center diff --git a/docs/source/guides/guides.rst b/docs/en/guides/guides.rst similarity index 100% rename from docs/source/guides/guides.rst rename to docs/en/guides/guides.rst diff --git a/docs/source/guides/tools_menu.rst b/docs/en/guides/tools_menu.rst similarity index 99% rename from docs/source/guides/tools_menu.rst rename to docs/en/guides/tools_menu.rst index 96b3bcc3674..41c8878bf6e 100644 --- a/docs/source/guides/tools_menu.rst +++ b/docs/en/guides/tools_menu.rst @@ -240,7 +240,7 @@ The USB Mass Storage Class, or USB MSC, is a class used for storage devices, lik This option can be used to ``Enable`` or ``Disable`` this function at the boot. If this option is ``Enabled``, once the device is connected via USB, one new storage device will appear in the system as a storage drive. Use this new storage drive to write and read files or to drop a new firmware binary to flash the device. -.. figure:: ../_static/usb_msc_drive.png +.. figure:: ../../_static/usb_msc_drive.png :align: center :width: 720 :figclass: align-center diff --git a/docs/source/index.rst b/docs/en/index.rst similarity index 79% rename from docs/source/index.rst rename to docs/en/index.rst index 4016f36f3d4..11a4f8539c5 100644 --- a/docs/source/index.rst +++ b/docs/en/index.rst @@ -1,8 +1,8 @@ -############################################# -Welcome to ESP32 Arduino Core's documentation -############################################# +####################################### +Welcome to Arduino Core's documentation +####################################### -Here you will find all the relevant information about the project. +Here you will find all the relevant information about the project based on the Arduino Core ESP32. .. note:: This is a work in progress documentation and we will appreciate your help! We are looking for contributors! diff --git a/docs/source/installing.rst b/docs/en/installing.rst similarity index 95% rename from docs/source/installing.rst rename to docs/en/installing.rst index 3b5554baf32..3acabd5505c 100644 --- a/docs/source/installing.rst +++ b/docs/en/installing.rst @@ -13,7 +13,7 @@ To install Arduino-ESP32 support, you can use one of the following options. Installing using Arduino IDE ---------------------------- -.. figure:: _static/logo_arduino.png +.. figure:: ../_static/logo_arduino.png :align: center :width: 200 :figclass: align-center @@ -42,21 +42,21 @@ To start the installation process using the Boards Managaer, follow these steps: - Start Arduino and open the Preferences window. -.. figure:: _static/install_guide_preferences.png +.. figure:: ../_static/install_guide_preferences.png :align: center :width: 600 :figclass: align-center - Enter one of the release links above into *Additional Board Manager URLs* field. You can add multiple URLs, separating them with commas. -.. figure:: _static/install_guide_boards_manager_url.png +.. figure:: ../_static/install_guide_boards_manager_url.png :align: center :width: 600 :figclass: align-center - Open Boards Manager from Tools > Board menu and install *esp32* platform (and do not forget to select your ESP32 board from Tools > Board menu after installation). -.. figure:: _static/install_guide_boards_manager_esp32.png +.. figure:: ../_static/install_guide_boards_manager_esp32.png :align: center :width: 600 :figclass: align-center @@ -66,7 +66,7 @@ To start the installation process using the Boards Managaer, follow these steps: Installing using PlatformIO --------------------------- -.. figure:: _static/logo_pio.png +.. figure:: ../_static/logo_pio.png :align: center :width: 200 :figclass: align-center @@ -166,7 +166,7 @@ Steps to install Arduino ESP32 support on Windows: - Select ``Clone Existing Repository`` -.. figure:: _static/win-gui-1.png +.. figure:: ../_static/win-gui-1.png :align: center :width: 600 :figclass: align-center @@ -179,13 +179,13 @@ Steps to install Arduino ESP32 support on Windows: **Step 2** -.. figure:: _static/win-gui-2.png +.. figure:: ../_static/win-gui-2.png :align: center :figclass: align-center **Step 3** -.. figure:: _static/win-gui-3.png +.. figure:: ../_static/win-gui-3.png :align: center :figclass: align-center @@ -194,7 +194,7 @@ Steps to install Arduino ESP32 support on Windows: **Step 4** -.. figure:: _static/win-gui-4.png +.. figure:: ../_static/win-gui-4.png :align: center :figclass: align-center @@ -202,7 +202,7 @@ Steps to install Arduino ESP32 support on Windows: **Step 5** -.. figure:: _static/win-gui-5.png +.. figure:: ../_static/win-gui-5.png :align: center :figclass: align-center @@ -212,7 +212,7 @@ Steps to install Arduino ESP32 support on Windows: 4. Select the COM port that the board is attached to 5. Compile and upload (You might need to hold the boot button while uploading) -.. figure:: _static/arduino-ide.png +.. figure:: ../_static/arduino-ide.png :align: center :figclass: align-center @@ -221,27 +221,27 @@ How to update to the latest code 1. Start ``Git GUI`` and you should see the repository under ``Open Recent Repository``. Click on it! -.. figure:: _static/win-gui-update-1.png +.. figure:: ../_static/win-gui-update-1.png :align: center :figclass: align-center 1. From menu ``Remote`` select ``Fetch from`` > ``origin`` -.. figure:: _static/win-gui-update-2.png +.. figure:: ../_static/win-gui-update-2.png :align: center :figclass: align-center 1. Wait for git to pull any changes and close ``Git GUI`` 2. Open ``[ARDUINO_SKETCHBOOK_DIR]/hardware/espressif/esp32/tools`` and double-click ``get.exe`` -.. figure:: _static/win-gui-4.png +.. figure:: ../_static/win-gui-4.png :align: center :figclass: align-center Linux ----- -.. figure:: _static/logo_linux.png +.. figure:: ../_static/logo_linux.png :align: center :width: 200 :figclass: align-center diff --git a/docs/source/lib_builder.rst b/docs/en/lib_builder.rst similarity index 100% rename from docs/source/lib_builder.rst rename to docs/en/lib_builder.rst diff --git a/docs/source/libraries.rst b/docs/en/libraries.rst similarity index 100% rename from docs/source/libraries.rst rename to docs/en/libraries.rst diff --git a/docs/source/make.rst b/docs/en/make.rst similarity index 100% rename from docs/source/make.rst rename to docs/en/make.rst diff --git a/docs/source/migration_guides/2.x_to_3.0.rst b/docs/en/migration_guides/2.x_to_3.0.rst similarity index 100% rename from docs/source/migration_guides/2.x_to_3.0.rst rename to docs/en/migration_guides/2.x_to_3.0.rst diff --git a/docs/source/migration_guides/migration_guides.rst b/docs/en/migration_guides/migration_guides.rst similarity index 100% rename from docs/source/migration_guides/migration_guides.rst rename to docs/en/migration_guides/migration_guides.rst diff --git a/docs/source/ota_web_update.rst b/docs/en/ota_web_update.rst similarity index 94% rename from docs/source/ota_web_update.rst rename to docs/en/ota_web_update.rst index be0a6d5e263..179101770a0 100644 --- a/docs/source/ota_web_update.rst +++ b/docs/en/ota_web_update.rst @@ -39,14 +39,14 @@ Prepare the sketch and configuration for initial upload with a serial port - Update ssid and pass in the sketch so the module can join your Wi-Fi network - Open File > Preferences, look for “Show verbose output during:” and check out “compilation” option -.. figure:: _static/ota_esp32_verbose.png +.. figure:: ../_static/ota_esp32_verbose.png :align: center :figclass: align-center - Upload sketch (Ctrl+U) - Now open web browser and enter the url, i.e. http://esp32.local. Once entered, browser should display a form -.. figure:: _static/ota_esp32_login.png +.. figure:: ../_static/ota_esp32_login.png :align: center :figclass: align-center @@ -59,7 +59,7 @@ Prepare the sketch and configuration for initial upload with a serial port Now click on the Login button and browser will display an upload form -.. figure:: _static/ota_esp32_upload.png +.. figure:: ../_static/ota_esp32_upload.png :align: center :figclass: align-center @@ -70,7 +70,7 @@ Exporting Binary file of the Firmware (Code) - Open up the Code, for Exporting up Binary file - Now go to Sketch > export compiled Binary -.. figure:: _static/ota_export_to_binary.png +.. figure:: ../_static/ota_export_to_binary.png :align: center :figclass: align-center diff --git a/docs/source/troubleshooting.rst b/docs/en/troubleshooting.rst similarity index 100% rename from docs/source/troubleshooting.rst rename to docs/en/troubleshooting.rst diff --git a/docs/source/tutorials/basic.rst b/docs/en/tutorials/basic.rst similarity index 97% rename from docs/source/tutorials/basic.rst rename to docs/en/tutorials/basic.rst index 34d9a05c094..8b932987bea 100644 --- a/docs/source/tutorials/basic.rst +++ b/docs/en/tutorials/basic.rst @@ -21,7 +21,7 @@ Here are the steps for this tutorial. 1. Open the Arduino IDE -.. figure:: ../_static/tutorials/basic/tutorial_basic_ide.png +.. figure:: ../../_static/tutorials/basic/tutorial_basic_ide.png :align: center :width: 600 :alt: Arduino IDE (click to enlarge) diff --git a/docs/source/tutorials/blink.rst b/docs/en/tutorials/blink.rst similarity index 100% rename from docs/source/tutorials/blink.rst rename to docs/en/tutorials/blink.rst diff --git a/docs/source/tutorials/cdc_dfu_flash.rst b/docs/en/tutorials/cdc_dfu_flash.rst similarity index 100% rename from docs/source/tutorials/cdc_dfu_flash.rst rename to docs/en/tutorials/cdc_dfu_flash.rst diff --git a/docs/source/tutorials/io_mux.rst b/docs/en/tutorials/io_mux.rst similarity index 98% rename from docs/source/tutorials/io_mux.rst rename to docs/en/tutorials/io_mux.rst index 12e0a9c9c0c..03b10449013 100644 --- a/docs/source/tutorials/io_mux.rst +++ b/docs/en/tutorials/io_mux.rst @@ -23,7 +23,7 @@ GPIO Matrix and Pin Mux The ESP32 architecture includes the capability of configuring some peripherals to any of the GPIOs pins, managed by the `IO MUX GPIO`_. Essentially, this capability means that we can route the internal peripheral into a different physical pin using the IO MUX and the GPIO Matrix. -.. figure:: ../_static/tutorials/peripherals/tutorial_peripheral_diagram.png +.. figure:: ../../_static/tutorials/peripherals/tutorial_peripheral_diagram.png :align: center :width: 600 :figclass: align-center diff --git a/docs/source/tutorials/partition_table.rst b/docs/en/tutorials/partition_table.rst similarity index 100% rename from docs/source/tutorials/partition_table.rst rename to docs/en/tutorials/partition_table.rst diff --git a/docs/source/tutorials/preferences.rst b/docs/en/tutorials/preferences.rst similarity index 100% rename from docs/source/tutorials/preferences.rst rename to docs/en/tutorials/preferences.rst diff --git a/docs/source/tutorials/tutorials.rst b/docs/en/tutorials/tutorials.rst similarity index 100% rename from docs/source/tutorials/tutorials.rst rename to docs/en/tutorials/tutorials.rst diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 6247f7e2317..00000000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/requirements.txt b/docs/requirements.txt index da0d937707a..97b552574b9 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,7 +1,3 @@ -# This is a list of python packages used to generate documentation. This file is used with pip: -# pip install --user -r requirements.txt -# -# matplotlib is currently required only by the script generate_chart.py -sphinx-rtd-theme +esp-docs==1.4.* sphinx-copybutton==0.5.0 sphinx-tabs==3.2.0 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py deleted file mode 100644 index 47b30b912ed..00000000000 --- a/docs/source/conf.py +++ /dev/null @@ -1,72 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = 'Arduino-ESP32' -copyright = '2023, Espressif' -author = 'Espressif' - -# The full version, including alpha/beta/rc tags -release = '2.0.14' - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx_rtd_theme', - 'sphinx_copybutton', - 'sphinx_tabs.tabs' -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [] - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" -html_logo = '_static/logo_espressif.png' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Style -# pygments_style = "sphinx" - -# Tracking ID for Google Analytics -google_analytics_id = 'G-F58JM78930' diff --git a/docs/utils.sh b/docs/utils.sh new file mode 100644 index 00000000000..0f9574e57a5 --- /dev/null +++ b/docs/utils.sh @@ -0,0 +1,18 @@ +# Bash helper functions for adding SSH keys + +function add_ssh_keys() { + local key_string="${1}" + mkdir -p ~/.ssh + chmod 700 ~/.ssh + echo -n "${key_string}" >~/.ssh/id_rsa_base64 + base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 >~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa +} + +function add_doc_server_ssh_keys() { + local key_string="${1}" + local server_url="${2}" + local server_user="${3}" + add_ssh_keys "${key_string}" + echo -e "Host ${server_url}\n\tStrictHostKeyChecking no\n\tUser ${server_user}\n" >>~/.ssh/config +} \ No newline at end of file diff --git a/libraries/BLE/src/BLEAdvertising.cpp b/libraries/BLE/src/BLEAdvertising.cpp index b09f96b3ba0..3e934d28f1e 100644 --- a/libraries/BLE/src/BLEAdvertising.cpp +++ b/libraries/BLE/src/BLEAdvertising.cpp @@ -231,7 +231,12 @@ void BLEAdvertising::start() { int numServices = m_serviceUUIDs.size(); if (numServices > 0) { m_advData.service_uuid_len = 16 * numServices; - m_advData.p_service_uuid = new uint8_t[m_advData.service_uuid_len]; + m_advData.p_service_uuid = (uint8_t *)malloc(m_advData.service_uuid_len); + if(!m_advData.p_service_uuid) { + log_e(">> start failed: out of memory"); + return; + } + uint8_t* p = m_advData.p_service_uuid; for (int i = 0; i < numServices; i++) { log_d("- advertising service: %s", m_serviceUUIDs[i].toString().c_str()); @@ -276,10 +281,8 @@ void BLEAdvertising::start() { // If we had services to advertise then we previously allocated some storage for them. // Here we release that storage. - if (m_advData.service_uuid_len > 0) { - delete[] m_advData.p_service_uuid; - m_advData.p_service_uuid = nullptr; - } + free(m_advData.p_service_uuid); //TODO change this variable to local scope? + m_advData.p_service_uuid = nullptr; // Start advertising. errRc = ::esp_ble_gap_start_advertising(&m_advParams); diff --git a/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino b/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino index 9221af1eaa2..7e292e1adfb 100644 --- a/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino +++ b/libraries/DNSServer/examples/CaptivePortal/CaptivePortal.ino @@ -1,52 +1,59 @@ +/* +This example enables catch-all Captive portal for ESP32 Access-Point +It will allow modern devices/OSes to detect that WiFi connection is +limited and offer a user to access a banner web-page. +There is no need to find and open device's IP address/URL, i.e. http://192.168.4.1/ +This works for Android, Ubuntu, FireFox, Windows, maybe others... +*/ + +#include #include #include +#include + -const byte DNS_PORT = 53; -IPAddress apIP(8,8,4,4); // The default android DNS DNSServer dnsServer; -WiFiServer server(80); +WebServer server(80); + +static const char responsePortal[] = R"===( +ESP32 CaptivePortal +

Hello World!

This is a captive portal example page. All unknown http requests will +be redirected here.

+)==="; + +// index page handler +void handleRoot() { + server.send(200, "text/plain", "Hello from esp32!"); +} -String responseHTML = "" - "CaptivePortal" - "

Hello World!

This is a captive portal example. All requests will " - "be redirected here.

"; +// this will redirect unknown http req's to our captive portal page +// based on this redirect various systems could detect that WiFi AP has a captive portal page +void handleNotFound() { + server.sendHeader("Location", "/portal"); + server.send(302, "text/plain", "redirect to captive portal"); +} -void setup() { +void setup() { + Serial.begin(115200); WiFi.mode(WIFI_AP); WiFi.softAP("ESP32-DNSServer"); - WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); - // if DNSServer is started with "*" for domain name, it will reply with - // provided IP to all DNS request - dnsServer.start(DNS_PORT, "*", apIP); + // by default DNSServer is started serving any "*" domain name. It will reply + // AccessPoint's IP to all DNS request (this is requred for Captive Portal detection) + dnsServer.start(); + + // serve a simple root page + server.on("/", handleRoot); + + // serve portal page + server.on("/portal",[](){server.send(200, "text/html", responsePortal);}); + // all unknown pages are redirected to captive portal + server.onNotFound(handleNotFound); server.begin(); } void loop() { - dnsServer.processNextRequest(); - WiFiClient client = server.available(); // listen for incoming clients - - if (client) { - String currentLine = ""; - while (client.connected()) { - if (client.available()) { - char c = client.read(); - if (c == '\n') { - if (currentLine.length() == 0) { - client.println("HTTP/1.1 200 OK"); - client.println("Content-type:text/html"); - client.println(); - client.print(responseHTML); - break; - } else { - currentLine = ""; - } - } else if (c != '\r') { - currentLine += c; - } - } - } - client.stop(); - } + server.handleClient(); + delay(5); // give CPU some idle time } diff --git a/libraries/DNSServer/src/DNSServer.cpp b/libraries/DNSServer/src/DNSServer.cpp index aaa3d33344b..a8114733460 100644 --- a/libraries/DNSServer/src/DNSServer.cpp +++ b/libraries/DNSServer/src/DNSServer.cpp @@ -1,6 +1,8 @@ #include "DNSServer.h" #include #include +#include + // #define DEBUG_ESP_DNS #ifdef DEBUG_ESP_PORT @@ -9,45 +11,37 @@ #define DEBUG_OUTPUT Serial #endif -DNSServer::DNSServer() -{ - _ttl = htonl(DNS_DEFAULT_TTL); - _errorReplyCode = DNSReplyCode::NonExistentDomain; - _dnsHeader = (DNSHeader*) malloc( sizeof(DNSHeader) ) ; - _dnsQuestion = (DNSQuestion*) malloc( sizeof(DNSQuestion) ) ; - _buffer = NULL; - _currentPacketSize = 0; - _port = 0; -} +#define DNS_MIN_REQ_LEN 17 // minimal size for DNS request asking ROOT = DNS_HEADER_SIZE + 1 null byte for Name + 4 bytes type/class -DNSServer::~DNSServer() -{ - if (_dnsHeader) { - free(_dnsHeader); - _dnsHeader = NULL; - } - if (_dnsQuestion) { - free(_dnsQuestion); - _dnsQuestion = NULL; - } - if (_buffer) { - free(_buffer); - _buffer = NULL; - } +DNSServer::DNSServer() : _port(DNS_DEFAULT_PORT), _ttl(htonl(DNS_DEFAULT_TTL)), _errorReplyCode(DNSReplyCode::NonExistentDomain){} + +DNSServer::DNSServer(const String &domainName) : _port(DNS_DEFAULT_PORT), _ttl(htonl(DNS_DEFAULT_TTL)), _errorReplyCode(DNSReplyCode::NonExistentDomain), _domainName(domainName){}; + + +bool DNSServer::start(){ + if (_resolvedIP.operator uint32_t() == 0){ // no address is set, try to obtain AP interface's IP + if (WiFi.getMode() & WIFI_AP){ + _resolvedIP = WiFi.softAPIP(); + } else return false; // won't run if WiFi is not in AP mode + } + + _udp.close(); + _udp.onPacket([this](AsyncUDPPacket& pkt){ this->_handleUDP(pkt); }); + return _udp.listen(_port); } -bool DNSServer::start(const uint16_t &port, const String &domainName, - const IPAddress &resolvedIP) -{ +bool DNSServer::start(uint16_t port, const String &domainName, const IPAddress &resolvedIP){ _port = port; - _buffer = NULL; - _domainName = domainName; - _resolvedIP[0] = resolvedIP[0]; - _resolvedIP[1] = resolvedIP[1]; - _resolvedIP[2] = resolvedIP[2]; - _resolvedIP[3] = resolvedIP[3]; - downcaseAndRemoveWwwPrefix(_domainName); - return _udp.begin(_port) == 1; + if (domainName != "*"){ + _domainName = domainName; + downcaseAndRemoveWwwPrefix(_domainName); + } else + _domainName.clear(); + + _resolvedIP = resolvedIP; + _udp.close(); + _udp.onPacket([this](AsyncUDPPacket& pkt){ this->_handleUDP(pkt); }); + return _udp.listen(_port); } void DNSServer::setErrorReplyCode(const DNSReplyCode &replyCode) @@ -62,9 +56,7 @@ void DNSServer::setTTL(const uint32_t &ttl) void DNSServer::stop() { - _udp.stop(); - free(_buffer); - _buffer = NULL; + _udp.close(); } void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName) @@ -73,151 +65,125 @@ void DNSServer::downcaseAndRemoveWwwPrefix(String &domainName) domainName.replace("www.", ""); } -void DNSServer::processNextRequest() +void DNSServer::_handleUDP(AsyncUDPPacket& pkt) { - _currentPacketSize = _udp.parsePacket(); - if (_currentPacketSize) - { - // Allocate buffer for the DNS query - if (_buffer != NULL) - free(_buffer); - _buffer = (unsigned char*)malloc(_currentPacketSize * sizeof(char)); - if (_buffer == NULL) - return; + if (pkt.length() < DNS_MIN_REQ_LEN) return; // truncated packet or not a DNS req + + // get DNS header (beginning of message) + DNSHeader dnsHeader; + DNSQuestion dnsQuestion; + memcpy( &dnsHeader, pkt.data(), DNS_HEADER_SIZE ); + if (dnsHeader.QR != DNS_QR_QUERY) return; // ignore non-query mesages - // Put the packet received in the buffer and get DNS header (beginning of message) - // and the question - _udp.read(_buffer, _currentPacketSize); - memcpy( _dnsHeader, _buffer, DNS_HEADER_SIZE ) ; - if ( requestIncludesOnlyOneQuestion() ) + if ( requestIncludesOnlyOneQuestion(dnsHeader) ) { +/* // The QName has a variable length, maximum 255 bytes and is comprised of multiple labels. // Each label contains a byte to describe its length and the label itself. The list of // labels terminates with a zero-valued byte. In "github.com", we have two labels "github" & "com" - // Iterate through the labels and copy them as they come into a single buffer (for simplicity's sake) - _dnsQuestion->QNameLength = 0 ; - while ( _buffer[ DNS_HEADER_SIZE + _dnsQuestion->QNameLength ] != 0 ) - { - memcpy( (void*) &_dnsQuestion->QName[_dnsQuestion->QNameLength], (void*) &_buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength], _buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength] + 1 ) ; - _dnsQuestion->QNameLength += _buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength] + 1 ; - } - _dnsQuestion->QName[_dnsQuestion->QNameLength] = 0 ; - _dnsQuestion->QNameLength++ ; - - // Copy the QType and QClass - memcpy( &_dnsQuestion->QType, (void*) &_buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength], sizeof(_dnsQuestion->QType) ) ; - memcpy( &_dnsQuestion->QClass, (void*) &_buffer[DNS_HEADER_SIZE + _dnsQuestion->QNameLength + sizeof(_dnsQuestion->QType)], sizeof(_dnsQuestion->QClass) ) ; +*/ + const char * enoflbls = strchr(reinterpret_cast(pkt.data()) + DNS_HEADER_SIZE, 0); // find end_of_label marker + ++enoflbls; // advance after null terminator + dnsQuestion.QName = pkt.data() + DNS_HEADER_SIZE; // we can reference labels from the request + dnsQuestion.QNameLength = enoflbls - (char*)pkt.data() - DNS_HEADER_SIZE; + /* + check if we aint going out of pkt bounds + proper dns req should have label terminator at least 4 bytes before end of packet + */ + if (dnsQuestion.QNameLength > pkt.length() - DNS_HEADER_SIZE - sizeof(dnsQuestion.QType) - sizeof(dnsQuestion.QClass)) return; // malformed packet + + // Copy the QType and QClass + memcpy( &dnsQuestion.QType, enoflbls, sizeof(dnsQuestion.QType) ); + memcpy( &dnsQuestion.QClass, enoflbls + sizeof(dnsQuestion.QType), sizeof(dnsQuestion.QClass) ); } - - if (_dnsHeader->QR == DNS_QR_QUERY && - _dnsHeader->OPCode == DNS_OPCODE_QUERY && - requestIncludesOnlyOneQuestion() && - (_domainName == "*" || getDomainNameWithoutWwwPrefix() == _domainName) + // will reply with IP only to "*" or if doman matches without www. subdomain + if (dnsHeader.OPCode == DNS_OPCODE_QUERY && + requestIncludesOnlyOneQuestion(dnsHeader) && + (_domainName.isEmpty() || + getDomainNameWithoutWwwPrefix(static_cast(dnsQuestion.QName), dnsQuestion.QNameLength) == _domainName) ) { - replyWithIP(); - } - else if (_dnsHeader->QR == DNS_QR_QUERY) - { - replyWithCustomCode(); + replyWithIP(pkt, dnsHeader, dnsQuestion); + return; } - free(_buffer); - _buffer = NULL; - } + // otherwise reply with custom code + replyWithCustomCode(pkt, dnsHeader); } -bool DNSServer::requestIncludesOnlyOneQuestion() +bool DNSServer::requestIncludesOnlyOneQuestion(DNSHeader& dnsHeader) { - return ntohs(_dnsHeader->QDCount) == 1 && - _dnsHeader->ANCount == 0 && - _dnsHeader->NSCount == 0 && - _dnsHeader->ARCount == 0; + return ntohs(dnsHeader.QDCount) == 1 && + dnsHeader.ANCount == 0 && + dnsHeader.NSCount == 0 && + dnsHeader.ARCount == 0; } -String DNSServer::getDomainNameWithoutWwwPrefix() +String DNSServer::getDomainNameWithoutWwwPrefix(const unsigned char* start, size_t len) { - // Error checking : if the buffer containing the DNS request is a null pointer, return an empty domain - String parsedDomainName = ""; - if (_buffer == NULL) - return parsedDomainName; - - // Set the start of the domain just after the header (12 bytes). If equal to null character, return an empty domain - unsigned char *start = _buffer + DNS_OFFSET_DOMAIN_NAME; - if (*start == 0) - { - return parsedDomainName; - } + String parsedDomainName(start, --len); // exclude trailing null byte from labels length, String constructor will add it anyway int pos = 0; - while(true) + while(posQR = DNS_QR_RESPONSE; - _dnsHeader->ANCount = _dnsHeader->QDCount; - _udp.write( (unsigned char*) _dnsHeader, DNS_HEADER_SIZE ) ; + dnsHeader.QR = DNS_QR_RESPONSE; + dnsHeader.ANCount = dnsHeader.QDCount; + rpl.write( (unsigned char*) &dnsHeader, DNS_HEADER_SIZE ) ; // Write the question - _udp.write(_dnsQuestion->QName, _dnsQuestion->QNameLength) ; - _udp.write( (unsigned char*) &_dnsQuestion->QType, 2 ) ; - _udp.write( (unsigned char*) &_dnsQuestion->QClass, 2 ) ; + rpl.write(dnsQuestion.QName, dnsQuestion.QNameLength) ; + rpl.write( (uint8_t*) &dnsQuestion.QType, 2 ) ; + rpl.write( (uint8_t*) &dnsQuestion.QClass, 2 ) ; // Write the answer // Use DNS name compression : instead of repeating the name in this RNAME occurence, // set the two MSB of the byte corresponding normally to the length to 1. The following // 14 bits must be used to specify the offset of the domain name in the message // (<255 here so the first byte has the 6 LSB at 0) - _udp.write((uint8_t) 0xC0); - _udp.write((uint8_t) DNS_OFFSET_DOMAIN_NAME); + rpl.write((uint8_t) 0xC0); + rpl.write((uint8_t) DNS_OFFSET_DOMAIN_NAME); // DNS type A : host address, DNS class IN for INternet, returning an IPv4 address uint16_t answerType = htons(DNS_TYPE_A), answerClass = htons(DNS_CLASS_IN), answerIPv4 = htons(DNS_RDLENGTH_IPV4) ; - _udp.write((unsigned char*) &answerType, 2 ); - _udp.write((unsigned char*) &answerClass, 2 ); - _udp.write((unsigned char*) &_ttl, 4); // DNS Time To Live - _udp.write((unsigned char*) &answerIPv4, 2 ); - _udp.write(_resolvedIP, sizeof(_resolvedIP)); // The IP address to return - _udp.endPacket(); + rpl.write((unsigned char*) &answerType, 2 ); + rpl.write((unsigned char*) &answerClass, 2 ); + rpl.write((unsigned char*) &_ttl, 4); // DNS Time To Live + rpl.write((unsigned char*) &answerIPv4, 2 ); + uint32_t ip = _resolvedIP; + rpl.write(reinterpret_cast(&ip), sizeof(uint32_t)); // The IPv4 address to return + + _udp.sendTo(rpl, req.remoteIP(), req.remotePort()); #ifdef DEBUG_ESP_DNS DEBUG_OUTPUT.printf("DNS responds: %s for %s\n", - IPAddress(_resolvedIP).toString().c_str(), getDomainNameWithoutWwwPrefix().c_str() ); + _resolvedIP.toString().c_str(), getDomainNameWithoutWwwPrefix(static_cast(dnsQuestion.QName), dnsQuestion.QNameLength).c_str() ); #endif } -void DNSServer::replyWithCustomCode() +void DNSServer::replyWithCustomCode(AsyncUDPPacket& req, DNSHeader& dnsHeader) { - _dnsHeader->QR = DNS_QR_RESPONSE; - _dnsHeader->RCode = (unsigned char)_errorReplyCode; - _dnsHeader->QDCount = 0; + dnsHeader.QR = DNS_QR_RESPONSE; + dnsHeader.RCode = static_cast(_errorReplyCode); + dnsHeader.QDCount = 0; - _udp.beginPacket(_udp.remoteIP(), _udp.remotePort()); - _udp.write((unsigned char*)_dnsHeader, sizeof(DNSHeader)); - _udp.endPacket(); + AsyncUDPMessage rpl(sizeof(DNSHeader)); + rpl.write(reinterpret_cast(&dnsHeader), sizeof(DNSHeader)); + _udp.sendTo(rpl, req.remoteIP(), req.remotePort()); } diff --git a/libraries/DNSServer/src/DNSServer.h b/libraries/DNSServer/src/DNSServer.h index 1250f5ce960..860507ac9ec 100644 --- a/libraries/DNSServer/src/DNSServer.h +++ b/libraries/DNSServer/src/DNSServer.h @@ -1,15 +1,15 @@ -#ifndef DNSServer_h -#define DNSServer_h -#include +#pragma once +#include #define DNS_QR_QUERY 0 #define DNS_QR_RESPONSE 1 #define DNS_OPCODE_QUERY 0 #define DNS_DEFAULT_TTL 60 // Default Time To Live : time interval in seconds that the resource record should be cached before being discarded -#define DNS_OFFSET_DOMAIN_NAME 12 // Offset in bytes to reach the domain name in the DNS message #define DNS_HEADER_SIZE 12 +#define DNS_OFFSET_DOMAIN_NAME DNS_HEADER_SIZE // Offset in bytes to reach the domain name labels in the DNS message +#define DNS_DEFAULT_PORT 53 -enum class DNSReplyCode +enum class DNSReplyCode:uint16_t { NoError = 0, FormError = 1, @@ -59,14 +59,14 @@ struct DNSHeader uint16_t Flags; }; uint16_t QDCount; // number of question entries - uint16_t ANCount; // number of answer entries + uint16_t ANCount; // number of ANswer entries uint16_t NSCount; // number of authority entries - uint16_t ARCount; // number of resource entries + uint16_t ARCount; // number of Additional Resource entries }; struct DNSQuestion { - uint8_t QName[256] ; //need 1 Byte for zero termination! + const uint8_t* QName; uint16_t QNameLength ; uint16_t QType ; uint16_t QClass ; @@ -75,36 +75,116 @@ struct DNSQuestion class DNSServer { public: + /** + * @brief Construct a new DNSServer object + * by default server is configured to run in "Captive-portal" mode + * it must be started with start() call to establish a listening socket + * + */ DNSServer(); - ~DNSServer(); - void processNextRequest(); + + /** + * @brief Construct a new DNSServer object + * builds DNS server with default parameters + * @param domainName - domain name to serve + */ + DNSServer(const String &domainName); + ~DNSServer(){}; // default d-tor + + // Copy semantics not implemented (won't run on same UDP port anyway) + DNSServer(const DNSServer&) = delete; + DNSServer& operator=(const DNSServer&) = delete; + + + /** + * @brief stub, left for compatibility with an old version + * does nothing actually + * + */ + void processNextRequest(){}; + + /** + * @brief Set the Error Reply Code for all req's not matching predifined domain + * + * @param replyCode + */ void setErrorReplyCode(const DNSReplyCode &replyCode); + + /** + * @brief set TTL for successfull replies + * + * @param ttl in seconds + */ void setTTL(const uint32_t &ttl); - // Returns true if successful, false if there are no sockets available - bool start(const uint16_t &port, + /** + * @brief (re)Starts a server with current configuration or with default parameters + * if it's the first call. + * Defaults are: + * port: 53 + * domainName: any + * ip: WiFi AP's IP address + * + * @return true on success + * @return false if IP or socket error + */ + bool start(); + + /** + * @brief (re)Starts a server with provided configuration + * + * @return true on success + * @return false if IP or socket error + */ + bool start(uint16_t port, const String &domainName, const IPAddress &resolvedIP); - // stops the DNS server + + /** + * @brief stops the server and close UDP socket + * + */ void stop(); + /** + * @brief returns true if DNS server runs in captive-portal mode + * i.e. all requests are served with AP's ip address + * + * @return true if catch-all mode active + * @return false otherwise + */ + inline bool isCaptive() const { return _domainName.isEmpty(); }; + + /** + * @brief returns 'true' if server is up and UDP socket is listening for UDP req's + * + * @return true if server is up + * @return false otherwise + */ + inline bool isUp() { return _udp.connected(); }; + private: - WiFiUDP _udp; + AsyncUDP _udp; uint16_t _port; - String _domainName; - unsigned char _resolvedIP[4]; - int _currentPacketSize; - unsigned char* _buffer; - DNSHeader* _dnsHeader; uint32_t _ttl; DNSReplyCode _errorReplyCode; - DNSQuestion* _dnsQuestion ; + String _domainName; + IPAddress _resolvedIP; void downcaseAndRemoveWwwPrefix(String &domainName); - String getDomainNameWithoutWwwPrefix(); - bool requestIncludesOnlyOneQuestion(); - void replyWithIP(); - void replyWithCustomCode(); + + /** + * @brief Get the Domain Name Without Www Prefix object + * scan labels in DNS packet and build a string of a domain name + * truncate any www. label if found + * @param start a pointer to the start of labels records in DNS packet + * @param len labels length + * @return String + */ + String getDomainNameWithoutWwwPrefix(const unsigned char* start, size_t len); + inline bool requestIncludesOnlyOneQuestion(DNSHeader& dnsHeader); + void replyWithIP(AsyncUDPPacket& req, DNSHeader& dnsHeader, DNSQuestion& dnsQuestion); + inline void replyWithCustomCode(AsyncUDPPacket& req, DNSHeader& dnsHeader); + void _handleUDP(AsyncUDPPacket& pkt); }; -#endif diff --git a/libraries/ESP32/examples/Serial/RS485_Echo_Demo/RS485_Echo_Demo.ino b/libraries/ESP32/examples/Serial/RS485_Echo_Demo/RS485_Echo_Demo.ino new file mode 100644 index 00000000000..a19be7ffe25 --- /dev/null +++ b/libraries/ESP32/examples/Serial/RS485_Echo_Demo/RS485_Echo_Demo.ino @@ -0,0 +1,48 @@ +/* + This Sketch demonstrates how to use the Hardware Serial peripheral to communicate over an RS485 bus. + + Data received on the primary serial port is relayed to the bus acting as an RS485 interface and vice versa. + + UART to RS485 translation hardware (e.g., MAX485, MAX33046E, ADM483) is assumed to be configured in half-duplex + mode with collision detection as described in + https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html#circuit-a-collision-detection-circuit + + To use the script open the Arduino serial monitor (or alternative serial monitor on the Arduino port). Then, + using an RS485 tranciver, connect another serial monitor to the RS485 port. Entering data on one terminal + should be displayed on the other terminal. +*/ +#include "hal/uart_types.h" + +#define RS485_RX_PIN 16 +#define RS485_TX_PIN 5 +#define RS485_RTS_PIN 4 + +#define RS485 Serial1 + +void setup() { + Serial.begin(115200); + while(!Serial) { delay(10); } + + RS485.begin(9600, SERIAL_8N1, RS485_RX_PIN, RS485_TX_PIN); + while(!RS485) { delay(10); } + if(!RS485.setPins(-1, -1, -1, RS485_RTS_PIN)){ + Serial.print("Failed to set RS485 pins"); + } + + // Certain versions of Arduino core don't define MODE_RS485_HALF_DUPLEX and so fail to compile. + // By using UART_MODE_RS485_HALF_DUPLEX defined in hal/uart_types.h we work around this problem. + // If using a newer IDF and Arduino core you can ommit including hal/uart_types.h and use MODE_RS485_HALF_DUPLEX + // defined in esp32-hal-uart.h (included during other build steps) instead. + if(!RS485.setMode(UART_MODE_RS485_HALF_DUPLEX)) { + Serial.print("Failed to set RS485 mode"); + } +} + +void loop() { + if (RS485.available()) { + Serial.write(RS485.read()); + } + if (Serial.available()) { + RS485.write(Serial.read()); + } +} diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index 62a9c44901b..1733d0cede1 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -495,7 +495,7 @@ void HTTPClient::setTimeout(uint16_t timeout) { _tcpTimeout = timeout; if(connected()) { - _client->setTimeout((timeout + 500) / 1000); + _client->setTimeout(timeout); } } @@ -1165,7 +1165,7 @@ bool HTTPClient::connect(void) } // set Timeout for WiFiClient and for Stream::readBytesUntil() and Stream::readStringUntil() - _client->setTimeout((_tcpTimeout + 500) / 1000); + _client->setTimeout(_tcpTimeout); log_d(" connected to %s:%u", _host.c_str(), _port); diff --git a/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino b/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino index 2028d192c06..e528a9fdb1c 100644 --- a/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino +++ b/libraries/HTTPUpdate/examples/httpUpdateSecure/httpUpdateSecure.ino @@ -96,7 +96,7 @@ void loop() { client.setCACert(rootCACertificate); // Reading data over SSL may be slow, use an adequate timeout - client.setTimeout(12000 / 1000); // timeout argument is defined in seconds for setTimeout + client.setTimeout(12000); // timeout argument is defined in miliseconds for setTimeout // The line below is optional. It can be used to blink the LED on the board during flashing // The LED will be on during download of one buffer of data from the network. The LED will diff --git a/libraries/LittleFS/src/LittleFS.cpp b/libraries/LittleFS/src/LittleFS.cpp index f23a3cfe611..f20b4f16b4c 100644 --- a/libraries/LittleFS/src/LittleFS.cpp +++ b/libraries/LittleFS/src/LittleFS.cpp @@ -81,7 +81,9 @@ bool LittleFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpen esp_vfs_littlefs_conf_t conf = { .base_path = basePath, .partition_label = partitionLabel_, + .partition = NULL, .format_if_mount_failed = false, + .read_only = false, .dont_mount = false, .grow_on_mount = true }; diff --git a/libraries/SD/src/sd_diskio.cpp b/libraries/SD/src/sd_diskio.cpp index f6a8df5e42b..c6943ce4c8b 100644 --- a/libraries/SD/src/sd_diskio.cpp +++ b/libraries/SD/src/sd_diskio.cpp @@ -233,7 +233,7 @@ char sdWriteBytes(uint8_t pdrv, const char* buffer, char token) ardu_sdcard_t * card = s_cards[pdrv]; unsigned short crc = (card->supports_crc)?CRC16(buffer, 512):0xFFFF; if (!sdWait(pdrv, 500)) { - return false; + return 0; } card->spi->write(token); @@ -424,7 +424,7 @@ unsigned long sdGetSectorsCount(uint8_t pdrv) { for (int f = 0; f < 3; f++) { if(!sdSelectCard(pdrv)) { - return false; + return 0; } if (!sdCommand(pdrv, SEND_CSD, 0, NULL)) { @@ -818,7 +818,7 @@ bool sdcard_mount(uint8_t pdrv, const char* path, uint8_t max_files, bool format } //FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, 0}; - res = f_mkfs(drv, &opt, work, sizeof(work)); + res = f_mkfs(drv, &opt, work, sizeof(BYTE) * FF_MAX_SS); free(work); if (res != FR_OK) { log_e("f_mkfs failed: %s", fferr2str[res]); diff --git a/libraries/WebServer/src/WebServer.cpp b/libraries/WebServer/src/WebServer.cpp index bc0d172fd85..ea9b4d5692e 100644 --- a/libraries/WebServer/src/WebServer.cpp +++ b/libraries/WebServer/src/WebServer.cpp @@ -135,26 +135,26 @@ bool WebServer::authenticate(const char * username, const char * password){ authReq = authReq.substring(6); authReq.trim(); char toencodeLen = strlen(username)+strlen(password)+1; - char *toencode = new char[toencodeLen + 1]; + char *toencode = (char *)malloc(toencodeLen + 1); if(toencode == NULL){ authReq = ""; return false; } - char *encoded = new char[base64_encode_expected_len(toencodeLen)+1]; + char *encoded = (char *)malloc(base64_encode_expected_len(toencodeLen)+1); if(encoded == NULL){ authReq = ""; - delete[] toencode; + free(toencode); return false; } sprintf(toencode, "%s:%s", username, password); if(base64_encode_chars(toencode, toencodeLen, encoded) > 0 && authReq.equalsConstantTime(encoded)) { authReq = ""; - delete[] toencode; - delete[] encoded; + free(toencode); + free(encoded); return true; } - delete[] toencode; - delete[] encoded; + free(toencode); + free(encoded);; } else if(authReq.startsWith(F("Digest"))) { authReq = authReq.substring(7); log_v("%s", authReq.c_str()); @@ -303,7 +303,7 @@ void WebServer::handleClient() { if (_parseRequest(_currentClient)) { // because HTTP_MAX_SEND_WAIT is expressed in milliseconds, // it must be divided by 1000 - _currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000); + _currentClient.setTimeout(HTTP_MAX_SEND_WAIT); /* / 1000 removed, WifiClient setTimeout changed to ms */ _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest(); diff --git a/libraries/WiFi/examples/WiFiScan/README.md b/libraries/WiFi/examples/WiFiScan/README.md index 188ae7453a0..7a4a7ec8350 100644 --- a/libraries/WiFi/examples/WiFiScan/README.md +++ b/libraries/WiFi/examples/WiFiScan/README.md @@ -6,8 +6,8 @@ This example demonstrates how to use the WiFi library to scan available WiFi net Currently this example supports the following targets. -| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C6 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | ## How to Use Example @@ -61,4 +61,5 @@ Before creating a new issue, be sure to try the Troubleshooting and to check if * ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) * ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) * ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) * Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 b/libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/libraries/WiFi/examples/WiFiScanAsync/.skip.esp32h2 @@ -0,0 +1 @@ + diff --git a/libraries/WiFi/examples/WiFiScanAsync/README.md b/libraries/WiFi/examples/WiFiScanAsync/README.md new file mode 100644 index 00000000000..195605bce60 --- /dev/null +++ b/libraries/WiFi/examples/WiFiScanAsync/README.md @@ -0,0 +1,75 @@ +# WiFiScanAsync Example + +This example demonstrates how to use the WiFi library to scan available WiFi networks in asynchronous mode and print the results. + +## Supported Targets + +Currently this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C6 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | + +## How to Use Example + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or setting the `upload_port` option on the `platformio.ini` file. + +## Example/Log Output + +``` +Setup done +Scan start +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... +Loop running... + +Scan done +17 networks found +Nr | SSID | RSSI | CH | Encryption + 1 | IoTNetwork | -62 | 1 | WPA2 + 2 | WiFiSSID | -62 | 1 | WPA2-EAP + 3 | B3A7992 | -63 | 6 | WPA+WPA2 + 4 | WiFi | -63 | 6 | WPA3 + 5 | IoTNetwork2 | -64 | 11 | WPA2+WPA3 +... +``` + +## Troubleshooting + +***Important: Be sure you're using a good quality USB cable and you have enought power source for your project.*** + +* **Programming Fail:** If the programming/flash procedure fails, try to reduce the serial connection speed. +* **COM port not detected:** Check the USB cable connection and the USB to Serial driver installation. + +If the error persist, you can ask help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try the Troubleshooting and to check if the same issue was already created by someone else. + +## Resources + +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* ESP32-C6 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c6_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino b/libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino new file mode 100644 index 00000000000..9f4408cdfe1 --- /dev/null +++ b/libraries/WiFi/examples/WiFiScanAsync/WiFiScanAsync.ino @@ -0,0 +1,102 @@ +/* + This sketch demonstrates how to scan WiFi networks in Async Mode. + The API is based on the Arduino WiFi Shield library, but has significant changes as newer WiFi functions are supported. + E.g. the return value of `encryptionType()` different because more modern encryption is supported. +*/ +#include "WiFi.h" + +void startWiFiScan() { + Serial.println("Scan start"); + // WiFi.scanNetworks will return immediately in Async Mode. + WiFi.scanNetworks(true); // 'true' turns Async Mode ON +} + +void printScannedNetworks(uint16_t networksFound) { + if (networksFound == 0) { + Serial.println("no networks found"); + } else { + Serial.println("\nScan done"); + Serial.print(networksFound); + Serial.println(" networks found"); + Serial.println("Nr | SSID | RSSI | CH | Encryption"); + for (int i = 0; i < networksFound; ++i) { + // Print SSID and RSSI for each network found + Serial.printf("%2d", i + 1); + Serial.print(" | "); + Serial.printf("%-32.32s", WiFi.SSID(i).c_str()); + Serial.print(" | "); + Serial.printf("%4ld", WiFi.RSSI(i)); + Serial.print(" | "); + Serial.printf("%2ld", WiFi.channel(i)); + Serial.print(" | "); + switch (WiFi.encryptionType(i)) + { + case WIFI_AUTH_OPEN: + Serial.print("open"); + break; + case WIFI_AUTH_WEP: + Serial.print("WEP"); + break; + case WIFI_AUTH_WPA_PSK: + Serial.print("WPA"); + break; + case WIFI_AUTH_WPA2_PSK: + Serial.print("WPA2"); + break; + case WIFI_AUTH_WPA_WPA2_PSK: + Serial.print("WPA+WPA2"); + break; + case WIFI_AUTH_WPA2_ENTERPRISE: + Serial.print("WPA2-EAP"); + break; + case WIFI_AUTH_WPA3_PSK: + Serial.print("WPA3"); + break; + case WIFI_AUTH_WPA2_WPA3_PSK: + Serial.print("WPA2+WPA3"); + break; + case WIFI_AUTH_WAPI_PSK: + Serial.print("WAPI"); + break; + default: + Serial.print("unknown"); + } + Serial.println(); + delay(10); + } + Serial.println(""); + // Delete the scan result to free memory for code below. + WiFi.scanDelete(); + } +} + +void setup() { + Serial.begin(115200); + + // Set WiFi to station mode and disconnect from an AP if it was previously connected. + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + + Serial.println("Setup done"); + startWiFiScan(); +} + +void loop() { + // check WiFi Scan Async process + int16_t WiFiScanStatus = WiFi.scanComplete(); + if (WiFiScanStatus < 0) { // it is busy scanning or got an error + if (WiFiScanStatus == WIFI_SCAN_FAILED) { + Serial.println("WiFi Scan has failed. Starting again."); + startWiFiScan(); + } + // other option is status WIFI_SCAN_RUNNING - just wait. + } else { // Found Zero or more Wireless Networks + printScannedNetworks(WiFiScanStatus); + startWiFiScan(); // start over... + } + + // Loop can do something else... + delay(250); + Serial.println("Loop running..."); +} diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp index 91247d17386..864c33322f3 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/WiFi/src/WiFiClient.cpp @@ -211,6 +211,8 @@ void WiFiClient::stop() clientSocketHandle = NULL; _rxBuffer = NULL; _connected = false; + _lastReadTimeout = 0; + _lastWriteTimeout = 0; } int WiFiClient::connect(IPAddress ip, uint16_t port) @@ -331,25 +333,6 @@ int WiFiClient::getSocketOption(int level, int option, const void* value, size_t return res; } - -int WiFiClient::setTimeout(uint32_t seconds) -{ - Client::setTimeout(seconds * 1000); // This should be here? - _timeout = seconds * 1000; - if(fd() >= 0) { - struct timeval tv; - tv.tv_sec = seconds; - tv.tv_usec = 0; - if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { - return -1; - } - return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); - } - else { - return 0; - } -} - int WiFiClient::setOption(int option, int *value) { return setSocketOption(IPPROTO_TCP, option, (const void*)value, sizeof(int)); @@ -365,6 +348,11 @@ int WiFiClient::getOption(int option, int *value) return res; } +void WiFiClient::setConnectionTimeout(uint32_t milliseconds) +{ + _timeout = milliseconds; +} + int WiFiClient::setNoDelay(bool nodelay) { int flag = nodelay; @@ -418,6 +406,18 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size) tv.tv_usec = WIFI_CLIENT_SELECT_TIMEOUT_US; retry--; + if(_lastWriteTimeout != _timeout){ + if(fd() >= 0){ + struct timeval timeout_tv; + timeout_tv.tv_sec = _timeout / 1000; + timeout_tv.tv_usec = (_timeout % 1000) * 1000; + if(setSocketOption(SO_SNDTIMEO, (char *)&timeout_tv, sizeof(struct timeval)) >= 0) + { + _lastWriteTimeout = _timeout; + } + } + } + if(select(socketFileDescriptor + 1, NULL, &set, NULL, &tv) < 0) { return 0; } @@ -477,6 +477,18 @@ size_t WiFiClient::write(Stream &stream) int WiFiClient::read(uint8_t *buf, size_t size) { + if(_lastReadTimeout != _timeout){ + if(fd() >= 0){ + struct timeval timeout_tv; + timeout_tv.tv_sec = _timeout / 1000; + timeout_tv.tv_usec = (_timeout % 1000) * 1000; + if(setSocketOption(SO_RCVTIMEO, (char *)&timeout_tv, sizeof(struct timeval)) >= 0) + { + _lastReadTimeout = _timeout; + } + } + } + int res = -1; if (_rxBuffer) { res = _rxBuffer->read(buf, size); diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/WiFi/src/WiFiClient.h index cdb0e0539e9..06e77c7cd1d 100644 --- a/libraries/WiFi/src/WiFiClient.h +++ b/libraries/WiFi/src/WiFiClient.h @@ -33,7 +33,7 @@ class ESPLwIPClient : public Client public: virtual int connect(IPAddress ip, uint16_t port, int32_t timeout) = 0; virtual int connect(const char *host, uint16_t port, int32_t timeout) = 0; - virtual int setTimeout(uint32_t seconds) = 0; + virtual void setConnectionTimeout(uint32_t milliseconds) = 0; }; class WiFiClient : public ESPLwIPClient @@ -43,6 +43,8 @@ class WiFiClient : public ESPLwIPClient std::shared_ptr _rxBuffer; bool _connected; int _timeout; + int _lastWriteTimeout; + int _lastReadTimeout; public: WiFiClient *next; @@ -91,7 +93,7 @@ class WiFiClient : public ESPLwIPClient int getSocketOption(int level, int option, const void* value, size_t size); int setOption(int option, int *value); int getOption(int option, int *value); - int setTimeout(uint32_t seconds); + void setConnectionTimeout(uint32_t milliseconds); int setNoDelay(bool nodelay); bool getNoDelay(); diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index 505940015f9..bf80d37393b 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -373,7 +373,6 @@ bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap) wifi_sta_config(&conf); if(WiFi.getMode() & WIFI_MODE_STA){ - _useStaticIp = false; if(eraseap){ if(esp_wifi_set_config((wifi_interface_t)ESP_IF_WIFI_STA, &conf)){ log_e("clear config failed!"); diff --git a/libraries/WiFi/src/WiFiScan.cpp b/libraries/WiFi/src/WiFiScan.cpp index 37e86a198df..e3604c9723f 100644 --- a/libraries/WiFi/src/WiFiScan.cpp +++ b/libraries/WiFi/src/WiFiScan.cpp @@ -141,11 +141,6 @@ void * WiFiScanClass::_getScanInfoByIndex(int i) */ int16_t WiFiScanClass::scanComplete() { - if (WiFiScanClass::_scanStarted && (millis()-WiFiScanClass::_scanStarted) > WiFiScanClass::_scanTimeout) { //Check is scan was started and if the delay expired, return WIFI_SCAN_FAILED in this case - WiFiGenericClass::clearStatusBits(WIFI_SCANNING_BIT); - return WIFI_SCAN_FAILED; - } - if(WiFiGenericClass::getStatusBits() & WIFI_SCAN_DONE_BIT) { return WiFiScanClass::_scanCount; } @@ -153,6 +148,11 @@ int16_t WiFiScanClass::scanComplete() if(WiFiGenericClass::getStatusBits() & WIFI_SCANNING_BIT) { return WIFI_SCAN_RUNNING; } + // last one to avoid time affecting Async mode + if (WiFiScanClass::_scanStarted && (millis()-WiFiScanClass::_scanStarted) > WiFiScanClass::_scanTimeout) { //Check is scan was started and if the delay expired, return WIFI_SCAN_FAILED in this case + WiFiGenericClass::clearStatusBits(WIFI_SCANNING_BIT); + return WIFI_SCAN_FAILED; + } return WIFI_SCAN_FAILED; } diff --git a/libraries/WiFi/src/WiFiServer.h b/libraries/WiFi/src/WiFiServer.h index b9db726b9b7..c51986701c4 100644 --- a/libraries/WiFi/src/WiFiServer.h +++ b/libraries/WiFi/src/WiFiServer.h @@ -45,7 +45,7 @@ class WiFiServer : public Server { log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port); } ~WiFiServer(){ end();} - WiFiClient available() __attribute__((deprecated("Renamed to accept()."))); + WiFiClient available(); WiFiClient accept(); void begin(uint16_t port=0); void begin(uint16_t port, int reuse_enable); diff --git a/libraries/WiFi/src/WiFiUdp.cpp b/libraries/WiFi/src/WiFiUdp.cpp index 0d75739afb9..6b053bbbd14 100644 --- a/libraries/WiFi/src/WiFiUdp.cpp +++ b/libraries/WiFi/src/WiFiUdp.cpp @@ -44,11 +44,12 @@ uint8_t WiFiUDP::begin(IPAddress address, uint16_t port){ server_port = port; - tx_buffer = new char[1460]; + tx_buffer = (char *)malloc(1460); if(!tx_buffer){ log_e("could not create tx buffer: %d", errno); return 0; } + tx_buffer_len = 0; if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ log_e("could not create socket: %d", errno); @@ -100,7 +101,7 @@ uint8_t WiFiUDP::beginMulticast(IPAddress a, uint16_t p){ void WiFiUDP::stop(){ if(tx_buffer){ - delete[] tx_buffer; + free(tx_buffer); tx_buffer = NULL; } tx_buffer_len = 0; @@ -136,13 +137,12 @@ int WiFiUDP::beginPacket(){ // allocate tx_buffer if is necessary if(!tx_buffer){ - tx_buffer = new char[1460]; + tx_buffer = (char *)malloc(1460); if(!tx_buffer){ log_e("could not create tx buffer: %d", errno); return 0; } } - tx_buffer_len = 0; // check whereas socket is already open diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp index 4d4702ba84d..2f9da58f9ad 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.cpp @@ -54,6 +54,8 @@ WiFiClientSecure::WiFiClientSecure(int sock) { _connected = false; _timeout = 30000; // Same default as ssl_client + _lastReadTimeout = 0; + _lastWriteTimeout = 0; sslclient = new sslclient_context; ssl_init(sslclient); @@ -94,6 +96,8 @@ void WiFiClientSecure::stop() sslclient->socket = -1; _connected = false; _peek = -1; + _lastReadTimeout = 0; + _lastWriteTimeout = 0; } stop_ssl_socket(sslclient, _CA_cert, _cert, _private_key); } @@ -199,6 +203,16 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) if (!_connected) { return 0; } + if(_lastWriteTimeout != _timeout){ + struct timeval timeout_tv; + timeout_tv.tv_sec = _timeout / 1000; + timeout_tv.tv_usec = (_timeout % 1000) * 1000; + if(setSocketOption(SO_SNDTIMEO, (char *)&timeout_tv, sizeof(struct timeval)) >= 0) + { + _lastWriteTimeout = _timeout; + } + } + int res = send_ssl_data(sslclient, buf, size); if (res < 0) { stop(); @@ -209,6 +223,18 @@ size_t WiFiClientSecure::write(const uint8_t *buf, size_t size) int WiFiClientSecure::read(uint8_t *buf, size_t size) { + if(_lastReadTimeout != _timeout){ + if(fd() >= 0){ + struct timeval timeout_tv; + timeout_tv.tv_sec = _timeout / 1000; + timeout_tv.tv_usec = (_timeout % 1000) * 1000; + if(setSocketOption(SO_RCVTIMEO, (char *)&timeout_tv, sizeof(struct timeval)) >= 0) + { + _lastReadTimeout = _timeout; + } + } + } + int peeked = 0; int avail = available(); if ((!buf && size) || avail <= 0) { @@ -375,25 +401,8 @@ void WiFiClientSecure::setAlpnProtocols(const char **alpn_protos) { _alpn_protos = alpn_protos; } -int WiFiClientSecure::setTimeout(uint32_t seconds) -{ - _timeout = seconds * 1000; - if (sslclient->socket >= 0) { - struct timeval tv; - tv.tv_sec = seconds; - tv.tv_usec = 0; - if(setSocketOption(SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)) < 0) { - return -1; - } - return setSocketOption(SO_SNDTIMEO, (char *)&tv, sizeof(struct timeval)); - } - else { - return 0; - } -} int WiFiClientSecure::fd() const { return sslclient->socket; } - diff --git a/libraries/WiFiClientSecure/src/WiFiClientSecure.h b/libraries/WiFiClientSecure/src/WiFiClientSecure.h index 6c967fbd0e6..8c130f450cc 100644 --- a/libraries/WiFiClientSecure/src/WiFiClientSecure.h +++ b/libraries/WiFiClientSecure/src/WiFiClientSecure.h @@ -80,7 +80,6 @@ class WiFiClientSecure : public WiFiClient void setAlpnProtocols(const char **alpn_protos); const mbedtls_x509_crt* getPeerCertificate() { return mbedtls_ssl_get_peer_cert(&sslclient->ssl_ctx); }; bool getFingerprintSHA256(uint8_t sha256_result[32]) { return get_peer_fingerprint(sslclient, sha256_result); }; - int setTimeout(uint32_t seconds); int fd() const; operator bool() diff --git a/platform.txt b/platform.txt index 00dcde59e69..0ff2eae7395 100644 --- a/platform.txt +++ b/platform.txt @@ -147,7 +147,7 @@ recipe.hooks.prebuild.6.pattern.windows=cmd /c if not exist "{build.path}\build_ # Set -DARDUINO_CORE_BUILD only on core file compilation file_opts.path={build.path}/file_opts recipe.hooks.prebuild.set_core_build_flag.pattern=/usr/bin/env bash -c ": > '{file_opts.path}'" -recipe.hooks.core.prebuild.set_core_build_flag.pattern=/usr/bin/env bash -c "echo '-DARDUINO_CORE_BUILD' > '{file_opts.path}'" +recipe.hooks.core.prebuild.set_core_build_flag.pattern=/usr/bin/env bash -c "echo -DARDUINO_CORE_BUILD > '{file_opts.path}'" recipe.hooks.core.postbuild.set_core_build_flag.pattern=/usr/bin/env bash -c ": > '{file_opts.path}'" recipe.hooks.prebuild.set_core_build_flag.pattern.windows=cmd /c type nul > "{file_opts.path}" diff --git a/tools/partitions/default_ffat_8MB.csv b/tools/partitions/default_ffat_8MB.csv new file mode 100644 index 00000000000..2791bf7912e --- /dev/null +++ b/tools/partitions/default_ffat_8MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x330000, +app1, app, ota_1, 0x340000,0x330000, +ffat, data, fat, 0x670000,0x180000, +coredump, data, coredump,0x7F0000,0x10000, diff --git a/tools/partitions/large_ffat_8MB.csv b/tools/partitions/large_ffat_8MB.csv new file mode 100644 index 00000000000..20632d6c512 --- /dev/null +++ b/tools/partitions/large_ffat_8MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x140000, +app1, app, ota_1, 0x150000,0x140000, +ffat, data, fat, 0x290000,0x560000, +coredump, data, coredump,0x7F0000,0x10000, diff --git a/tools/partitions/large_spiffs_8MB.csv b/tools/partitions/large_spiffs_8MB.csv new file mode 100644 index 00000000000..ecf87c6d280 --- /dev/null +++ b/tools/partitions/large_spiffs_8MB.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x140000, +app1, app, ota_1, 0x150000,0x140000, +spiffs, data, spiffs, 0x290000,0x560000, +coredump, data, coredump,0x7F0000,0x10000, diff --git a/variants/adafruit_camera_esp32s3/bootloader-tinyuf2.bin b/variants/adafruit_camera_esp32s3/bootloader-tinyuf2.bin index 721a1a1c70c..f0169612e13 100644 Binary files a/variants/adafruit_camera_esp32s3/bootloader-tinyuf2.bin and b/variants/adafruit_camera_esp32s3/bootloader-tinyuf2.bin differ diff --git a/variants/adafruit_camera_esp32s3/pins_arduino.h b/variants/adafruit_camera_esp32s3/pins_arduino.h index 26c72ad392c..62132dcadc3 100644 --- a/variants/adafruit_camera_esp32s3/pins_arduino.h +++ b/variants/adafruit_camera_esp32s3/pins_arduino.h @@ -24,7 +24,7 @@ static const uint8_t LED_BUILTIN = PIN_NEOPIXEL+SOC_GPIO_PIN_COUNT; #define RGB_BRIGHTNESS 64 -//static const uint8_t TFT_BACKLIGHT = 41; +static const uint8_t TFT_BACKLIGHT = 45; static const uint8_t TFT_DC = 40; static const uint8_t TFT_CS = 39; static const uint8_t TFT_RESET = 38; @@ -32,10 +32,10 @@ static const uint8_t TFT_RST = 38; static const uint8_t SD_CS = 48; static const uint8_t SD_CHIP_SELECT = 48; -static const uint8_t SPEAKER = 41; +static const uint8_t SPEAKER = 46; -static const uint8_t SDA = 33; -static const uint8_t SCL = 34; +static const uint8_t SCL = 33; +static const uint8_t SDA = 34; static const uint8_t SS = 48; static const uint8_t MOSI = 35; @@ -55,19 +55,16 @@ static const uint8_t DAC2 = 18; #define AWEXP_SPKR_SD 0 #define AWEXP_BUTTON_SEL 1 -#define AWEXP_BACKLIGHT 2 -#define AWEXP_CAM_PWDN 7 #define AWEXP_SD_DET 8 #define AWEXP_SD_PWR 9 -#define AWEXP_CAM_RST 10 #define AWEXP_BUTTON_OK 11 #define AWEXP_BUTTON_RIGHT 12 #define AWEXP_BUTTON_UP 13 #define AWEXP_BUTTON_LEFT 14 #define AWEXP_BUTTON_DOWN 15 -#define PWDN_GPIO_NUM -1 // connected through expander -#define RESET_GPIO_NUM -1 // connected through expander +#define RESET_GPIO_NUM 47 +#define PWDN_GPIO_NUM 21 #define XCLK_GPIO_NUM 8 #define SIOD_GPIO_NUM SDA #define SIOC_GPIO_NUM SCL diff --git a/variants/adafruit_camera_esp32s3/tinyuf2.bin b/variants/adafruit_camera_esp32s3/tinyuf2.bin index 21e91284e05..0247a171331 100644 Binary files a/variants/adafruit_camera_esp32s3/tinyuf2.bin and b/variants/adafruit_camera_esp32s3/tinyuf2.bin differ diff --git a/variants/adafruit_camera_esp32s3/variant.cpp b/variants/adafruit_camera_esp32s3/variant.cpp index dd3170f994a..06e5c24cb76 100644 --- a/variants/adafruit_camera_esp32s3/variant.cpp +++ b/variants/adafruit_camera_esp32s3/variant.cpp @@ -31,6 +31,15 @@ extern "C" { // Initialize variant/board, called before setup() void initVariant(void) { - + pinMode(TFT_BACKLIGHT, OUTPUT); + digitalWrite(TFT_BACKLIGHT, LOW); + pinMode(SD_CS, OUTPUT); + digitalWrite(SD_CS, HIGH); + pinMode(TFT_CS, OUTPUT); + digitalWrite(TFT_CS, HIGH); + pinMode(TFT_RESET, OUTPUT); + digitalWrite(TFT_RESET, LOW); + delay(1); + digitalWrite(TFT_RESET, HIGH); } } diff --git a/variants/adafruit_metro_esp32s3/bootloader-tinyuf2.bin b/variants/adafruit_metro_esp32s3/bootloader-tinyuf2.bin index 73e8c06b33b..2ed855b65a5 100644 Binary files a/variants/adafruit_metro_esp32s3/bootloader-tinyuf2.bin and b/variants/adafruit_metro_esp32s3/bootloader-tinyuf2.bin differ diff --git a/variants/adafruit_metro_esp32s3/pins_arduino.h b/variants/adafruit_metro_esp32s3/pins_arduino.h index 9963d1aa476..e9769f113f6 100644 --- a/variants/adafruit_metro_esp32s3/pins_arduino.h +++ b/variants/adafruit_metro_esp32s3/pins_arduino.h @@ -14,7 +14,7 @@ #define BUILTIN_LED LED_BUILTIN // backward compatibility // Neopixel -#define PIN_NEOPIXEL 45 +#define PIN_NEOPIXEL 46 // RGB_BUILTIN and RGB_BRIGHTNESS can be used in new Arduino API neopixelWrite() and digitalWrite() for blinking #define RGB_BUILTIN (PIN_NEOPIXEL+SOC_GPIO_PIN_COUNT) #define RGB_BRIGHTNESS 64 diff --git a/variants/adafruit_metro_esp32s3/tinyuf2.bin b/variants/adafruit_metro_esp32s3/tinyuf2.bin index d57e5b75b55..25a5ba66b1e 100644 Binary files a/variants/adafruit_metro_esp32s3/tinyuf2.bin and b/variants/adafruit_metro_esp32s3/tinyuf2.bin differ diff --git a/variants/adafruit_metro_esp32s3/variant.cpp b/variants/adafruit_metro_esp32s3/variant.cpp index 811a6d508c9..485f08b4aef 100644 --- a/variants/adafruit_metro_esp32s3/variant.cpp +++ b/variants/adafruit_metro_esp32s3/variant.cpp @@ -30,7 +30,8 @@ extern "C" { // Initialize variant/board, called before setup() void initVariant(void) { - // default SD_CS to input pullup + // default SD_CS to input pullup (we cannot have built in pullup since its + // a strapping pin!) pinMode(SS, INPUT_PULLUP); } diff --git a/variants/esp32s3_powerfeather/pins_arduino.h b/variants/esp32s3_powerfeather/pins_arduino.h index d1c486901c7..2066cf3e002 100644 --- a/variants/esp32s3_powerfeather/pins_arduino.h +++ b/variants/esp32s3_powerfeather/pins_arduino.h @@ -9,12 +9,12 @@ #define USB_PRODUCT "ESP32-S3 PowerFeather" #define USB_SERIAL "" -static const uint8_t ALARM = 7; +static const uint8_t ALARM = 21; static const uint8_t INT = 5; static const uint8_t LED = 46; static const uint8_t BTN = 0; -static const uint8_t EN = 13; +static const uint8_t EN = 7; static const uint8_t TX = 44; static const uint8_t RX = 42; @@ -37,6 +37,8 @@ static const uint8_t A5 = 1; static const uint8_t D5 = 15; static const uint8_t D6 = 16; +static const uint8_t D7 = 37; +static const uint8_t D8 = 6; static const uint8_t D9 = 17; static const uint8_t D10 = 18; static const uint8_t D11 = 45; diff --git a/variants/sensebox_mcu_esp32s2/variant.cpp b/variants/sensebox_mcu_esp32s2/variant.cpp index 7da523dc5eb..311f69b8d35 100644 --- a/variants/sensebox_mcu_esp32s2/variant.cpp +++ b/variants/sensebox_mcu_esp32s2/variant.cpp @@ -49,7 +49,6 @@ void initVariant(void) //enable PD-Sensor by default pinMode(PD_ENABLE, OUTPUT); - analogReadResolution(12); digitalWrite(PD_ENABLE, HIGH); }