Compare commits

...

69 Commits

Author SHA1 Message Date
80ea521940 Add support for 160MHz rated CPUs (#3135)
Some ESP32 chips are rated only to 160MHz. This change adds support for them and does not allow frequency to be switched to 240MHz
2019-09-05 12:30:43 +03:00
5c04de6f39 Fix packager 2019-09-05 11:22:40 +03:00
0d163a1ce2 Update IDF 3.2 to 7dd492319 + WiFi fix (#3177) 2019-09-05 11:08:45 +03:00
2a7e509978 Fix long Ticker period conversion: cast ms to uint64_t when calculating us (#3175)
* Fix long Ticker period conversion

* Simplify long Ticker period conversion fix by using 1000ULL
2019-09-05 10:34:47 +03:00
1b8c7e34f9 Try bash only examples build (#3164) 2019-09-01 18:45:55 +03:00
7a574399b1 Rework the sketch builder to match the IDE (#3146)
* Rework the sketch builder to match the IDE

* Link the board to the home folder

* Rename files for clarity

* move ci files to own subfolder

* Update Github CI to use the new script locations
2019-08-28 01:28:11 +03:00
fd089d8fd3 Pull in ESP8266 String::replace() fixes, others (#3143)
Pull in bugfixes from the ESP8266 repo for problems in the SSO
implementation of replace().  See the following patches for full
details:

54240d2cc5 (diff-8d9e71e16d437343017df828f0528f63)
78a1a66e6d (diff-8d9e71e16d437343017df828f0528f63)
4e9358445a (diff-8d9e71e16d437343017df828f0528f63)

Fixes #3140
2019-08-27 20:05:36 +03:00
f356ccd54a Added the pragma line to the top (#3139)
* Removed pragme in BLERemoteService.cpp

* Added the line at the top and changed to warning
2019-08-27 10:21:27 +03:00
6daf773464 Fix travis deploy generating bad json 2019-08-21 03:29:23 +03:00
70a896481d Update Both CIs to run parallel jobs (#3120) 2019-08-21 01:56:05 +03:00
390da0d090 bump CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM to improve RX performance (#3119) 2019-08-20 22:07:56 +03:00
d5e2bb12ca Update IDF to 90747cc8b (#3118) 2019-08-20 21:11:00 +03:00
f4acac4c2b Bugfix/http client (#2867)
* Fix persistance issue found, see ESP8266 issue #6152

* Correcting the parsing of the header for HTTP1.0

* Send 'Connection: Close' header in case of HTTP1.0

* Let reuse connection depend on protocol used: HTTP1.0 or HTTP1.1

* Fixed reuse, added null ptr checks, added check for _trainsportTraits in connect() in case _client was set null

* Fix reuse connection issues, similar to ESP8266 PR #6176
2019-08-20 17:18:09 +03:00
5137fc5c80 Ble notification/indication status and timeout (#2998)
* add timed wait

* Added Notification/Indication data and status callbacks

* imply null-object pattern for BLE callback
2019-08-20 17:15:30 +03:00
03066e42ef Flush UART RX queue too (#3009) 2019-08-20 16:48:52 +03:00
cd5257ad78 ESP.getCpuFreqMHz fix (#3007)
* ESP.getCpuFreqMHz was returning the CONFIG_ variable.  Now calls the getCpuFrequencyMhz function.

* Changed the Esp function to uint32_t to match
2019-08-20 16:48:26 +03:00
ee6336a312 links http -> https (#3010)
more secure
2019-08-20 16:47:43 +03:00
61f71930e9 The progress callback is now correctly invoked with Update.write (#3024)
The progress callback was only invoked with Update.writeStream before
2019-08-20 16:45:57 +03:00
ec40c4c96f Cast TimerWakeup conversion factor as ULL (#3027) 2019-08-20 16:45:18 +03:00
2bda4a9617 Fix BLE stop advertising not working (#3034)
BLEAdvertising::handleGAPEvent -> ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT should NOT call start()!
2019-08-20 16:44:50 +03:00
91b9fae111 Add generic IP utilities (#3038)
* Add generic IP calculations

Add:
calculateNetworkID(IPAddress ip, IPAddress subnet) => Calculate the network id using the ip and subnet (e.g. 192.168.0.0)
calculateBroadcast(IPAddress ip, IPAddress subnet) => Calculate the broadcast ip using the ip and subnet (e.g. 192.168.0.255)
calculateSubnetCIDR(IPAddress subnetMask) => Calculate the subnet CIDR using the subnet (e.g. 24)

Add:
broadcastIP() => Retrieve the network id (e.g. 192.168.0.0)
networkID() => Retrieve the broadcast IP (e.g. 192.168.0.255)
subnetCIDR() => Retrieve the subnet CIDR (e.g. 24)

Add:
broadcastIP() => Retrieve the network id (e.g. 192.168.0.0)
networkID() => Retrieve the broadcast IP (e.g. 192.168.0.255)
subnetCIDR() => Retrieve the subnet CIDR (e.g. 24)

Add:
softAPBroadcastIP() => Retrieve the network id (e.g. 192.168.0.0)
softAPNetwrokID() => Retrieve the broadcast IP (e.g. 192.168.0.255)
softAPSubnetCIDR() => Retrieve the subnet CIDR (e.g. 24)
2019-08-20 16:42:55 +03:00
2a1fde7736 Include stdint for uint16_t (#3069) 2019-08-20 16:39:31 +03:00
a12d609b22 Corrected count of characteristics to get (#3082)
Only space for 1 characteristic is allocated, requesting 10 leads to stack corruption.
2019-08-20 16:38:59 +03:00
73576674b8 add core installation 1.0.2 (#3064)
* add core installation 1.0.2

* added 1.0.3
2019-08-20 16:38:34 +03:00
007a93ec7e Update Print.cpp (#3060)
#2891
2019-08-20 16:36:04 +03:00
a5f3fc6fad Magicbit Variant (#3107)
* Updated magicbit variant

* Added LED_BUILTIN
2019-08-20 15:44:12 +03:00
65e256c40a Try github CI (#3115) 2019-08-20 15:32:47 +03:00
fa55a2c91d Update stale.yml 2019-08-01 18:55:47 +03:00
a070884441 Update stale.yml 2019-08-01 11:05:05 +03:00
a9c8b46b1a Update stale.yml 2019-07-31 16:43:58 +03:00
6954150176 Create stale.yml 2019-07-31 10:04:08 +03:00
548f712df2 Fix empty libs being included with the builder (#2997) 2019-07-17 16:48:51 +03:00
56ce580b0e Fix incorrect definition of FPSTR() and move from pgmspace.h to WString.h (#1371) (#2961) 2019-07-17 10:16:47 +03:00
509d31ba51 create variant for magicbit board (#2987)
* create varient for magicbit board

* update boards.txt
2019-07-17 10:10:45 +03:00
9e32cec9a2 Update IDF to a8916daeb (#2992) 2019-07-17 10:09:43 +03:00
3376ea1bd5 Added more menu settings for TinyPICO - Fash mode and Flash speed. Set Flash mode default to QIO (#2976) 2019-07-16 17:15:13 +03:00
1c7e329140 RMT: Fix in bitshift of NeoPixel example project (#2986)
Fixed bit shift in demo application of using RMT peripheral. Init data array to be transmitted was off by one, as for the first iteration (i==0) the mask was 1<<8, which results in shifted RGB value in color variable
Closes https://github.com/espressif/arduino-esp32/issues/2921
2019-07-16 17:14:28 +03:00
c17b212cd0 WPA2 connection fix (significant improvement to connection time) (#2989)
* Config fix test

* Also force config even if equal
2019-07-16 17:12:20 +03:00
7dbda4988b Update boards.txt (#2933)
* Update boards.txt

Adding ESP32-WROOM-32 8MB flash option

* Update boards.txt

Fixing partition size and typo

* Update boards.txt
2019-07-10 09:13:09 +03:00
d1134fd45e Fix issue with semaphores (#2974) 2019-07-10 09:11:35 +03:00
d5fdd715ef WiFiClient.cpp - Fix connect() behavior (#2784)
* WiFiClient.cpp - Fix connect() behavior

* lwip_connect_r() : check return code
2019-07-09 19:48:05 +03:00
ca7106e97e Added convert method to EEPROM to transfer data from partition to nvs (#2841)
* Added convert method to transfer data from partition to nvs

* Could have sworn I changed the return when I made the label

* Empty state should be 0xFF.  Fixed some logging levels

* Set result on success
2019-07-09 19:47:06 +03:00
87e5787cf7 Added support for TinyPICO in the boards list (#2901) 2019-07-09 19:40:34 +03:00
c13d11e7d1 fix empty reply from server error (#2903)
The flush causes an empty response a client side.

see https://github.com/espressif/arduino-esp32/issues/2902
2019-07-09 19:39:12 +03:00
b0d8d4dd44 Change some WiFi buffer settings to match esp-idf. See #2899 (#2912) 2019-07-09 19:36:45 +03:00
05de017bd5 BLE Library onRead Callback fix and Client disconnect feature (#2913)
* BLEServer::disconnect()

* Invoke Read callback first, to make data update possible before read
2019-07-09 19:35:07 +03:00
e1548e9b7e Fix hang on client disconnect during upload (#2914) 2019-07-09 19:34:24 +03:00
c29ec9da3d Removed partitioning comments from EEPROM class example (#2920)
* Remove partitioning comments

* Revert "Remove partitioning comments"

This reverts commit b3b03a81572d352816819cff772231ba037dc338.

* Removed partitioning comments from EEPROM example
2019-07-09 19:34:04 +03:00
b3783fba95 fixed typo (#2927) 2019-07-09 19:31:38 +03:00
a22ec4a978 Reduce flash usage up to 214k in one click (#2929)
* std::stringstream -> std::string

* Fix small issues

* Small fix 2
2019-07-09 19:31:17 +03:00
20498cf8b1 Expand gitignore to cover files created by Visual Micro (#2934)
* Expand gitignore to cover files created by Visual Micro's Arduino IDE for Visual Studio

(cherry picked from commit d6209c79ea16a26564fe27e74e5f277160129847)

* Also ignore VS project files

(cherry picked from commit e0ec212bd41e75a3570a6098a66ee66787db58db)
2019-07-09 19:28:04 +03:00
02e51728c4 Fix Timeout Bug in WebServer (#2938) 2019-07-09 19:27:24 +03:00
d2816b2f32 Fix Unused Variable Warning (#2940)
Some Debugging variables were enabled at ERROR level instead of DEBUG.  Specifically `tAfter` and `tBefore`
2019-07-09 19:24:35 +03:00
2e32022611 ESP8266 => ESP32 tidyup, set correct default port (#2948)
Tidied up references to the ESP8266, and set the correct default port for the ESP32.
2019-07-09 19:24:10 +03:00
74ffdac74a fix for BLE Library Compile Error #2866 (#2876) 2019-07-09 19:23:01 +03:00
4ee17ec3ee Fix warning -Wempty-body by adding braces to 'if' stmt body (#2951) 2019-07-09 19:21:57 +03:00
476660f763 Cleanup WiFiMulti (#2955)
* Use macros for switch case labels

* Fixed spelling error in "too"

* Fix spacing

* Inline private functions that are only called once
2019-07-09 19:21:01 +03:00
Luc
f558e69181 Fix warnings in platformio (#2960)
Fix : warning: converting to non-pointer type 'int' from NULL [-Wconversion-null]
Fix : warning: unused variable 'res' [-Wunused-variable]
2019-07-09 19:19:16 +03:00
5bf3aab527 Make a selective menuconfig option for FFat (#2966) 2019-07-09 19:14:53 +03:00
1aced120ba docs: fix typo (#2973) 2019-07-09 19:14:27 +03:00
7d7824701f Fix persistance issue found, see ESP8266 issue #6152 (#2851) 2019-06-05 14:00:00 +02:00
89feacb813 Fix map() division by zero (#2848) 2019-06-05 13:48:13 +02:00
aae6f24a37 Update (#2838)
Added PoE-ISO and DevKit-Lipo.
For the other boards added alternative Serial (Serial1/Serial2) pins.
2019-06-05 13:44:52 +02:00
43b781a158 Update AsyncUDP library.json (#2837)
* Fix https://github.com/platformio/platform-espressif32/issues/186

* Drop library.json
2019-06-05 13:43:15 +02:00
e055b28d1a Ignore Werror-maybe-uninitialized from Azure IoT Library (#2824)
Ignore the error about a potentially uninitialized variable
in the Azure library that will occur when compiling as a component
in ESP-IDF.
2019-06-05 13:42:08 +02:00
714ba948e6 Update BLERemoteCharacteristic.cpp (#2800)
Prevents the error that is generated on free on row 186
When calling the function readValue() sometimes it gave an error on this free.
2019-06-05 13:38:49 +02:00
e57de64a3c Fixed multi_heap_free failed during setting the value of the characteristic in BLE Library. (#2789) 2019-06-05 13:37:06 +02:00
fd5a2f08f9 Fix #2750 (#2763)
* Fix #2750

* Fixes for pull comments

* latest modifications following comments from me-no-dev

* Move SPIFFSFSImpl to .cpp file
2019-05-14 00:15:35 +03:00
e9389e3122 Fix AsyncUDP buffer error
fixes: https://github.com/espressif/arduino-esp32/issues/2685
2019-05-13 23:18:38 +03:00
212 changed files with 3174 additions and 1098 deletions

View File

@ -24,7 +24,7 @@ https://github.com/me-no-dev/EspExceptionDecoder
### Hardware: ### Hardware:
Board: ?ESP32 Dev Module? ?node32? ?ttgo_lora? Board: ?ESP32 Dev Module? ?node32? ?ttgo_lora?
Core Installation version: ?1.0.0? ?1.0.1-rc4? ?1.0.1? ?1.0.1-git? Core Installation version: ?1.0.0? ?1.0.1-rc4? ?1.0.1? ?1.0.1-git? ?1.0.2? ?1.0.3?
IDE name: ?Arduino IDE? ?Platform.io? ?IDF component? IDE name: ?Arduino IDE? ?Platform.io? ?IDF component?
Flash Frequency: ?40Mhz? Flash Frequency: ?40Mhz?
PSRAM enabled: ?no? ?yes? PSRAM enabled: ?no? ?yes?

64
.github/stale.yml vendored Normal file
View File

@ -0,0 +1,64 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 60
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
daysUntilClose: 14
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
exemptLabels:
- pinned
- security
- "to be implemented"
- "for reference"
- "move to PR"
- "enhancement"
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking as stale
staleLabel: stale
# Comment to post when marking as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed in 14 days if no further activity occurs. Thank you
for your contributions.
# Comment to post when removing the stale label.
# unmarkComment: >
# Your comment here.
# Comment to post when closing a stale Issue or Pull Request.
closeComment: >
This stale issue has been automatically closed. Thank you for your contributions.
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed

376
.github/workflows/main.yml vendored Normal file
View File

@ -0,0 +1,376 @@
name: ESP32 Arduino CI
on:
push:
branches:
- master
- release/*
pull_request:
jobs:
build-arduino-0:
name: Build Arduino IDE Tests 0
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Run CMake Check
run: ./tools/ci/check-cmakelists.sh
- name: Install Arduino IDE
env:
#ESP32_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 0 18
- name: Sketch Sizes
run: cat size.log
build-arduino-1:
name: Build Arduino IDE Tests 1
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 1 18
- name: Sketch Sizes
run: cat size.log
build-arduino-2:
name: Build Arduino IDE Tests 2
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 2 18
- name: Sketch Sizes
run: cat size.log
build-arduino-3:
name: Build Arduino IDE Tests 3
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 3 18
- name: Sketch Sizes
run: cat size.log
build-arduino-4:
name: Build Arduino IDE Tests 4
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 4 18
- name: Sketch Sizes
run: cat size.log
build-arduino-5:
name: Build Arduino IDE Tests 5
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 5 18
- name: Sketch Sizes
run: cat size.log
build-arduino-6:
name: Build Arduino IDE Tests 6
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 6 18
- name: Sketch Sizes
run: cat size.log
build-arduino-7:
name: Build Arduino IDE Tests 7
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 7 18
- name: Sketch Sizes
run: cat size.log
build-arduino-8:
name: Build Arduino IDE Tests 8
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 8 18
- name: Sketch Sizes
run: cat size.log
build-arduino-9:
name: Build Arduino IDE Tests 9
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 9 18
- name: Sketch Sizes
run: cat size.log
build-arduino-10:
name: Build Arduino IDE Tests 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 10 18
- name: Sketch Sizes
run: cat size.log
build-arduino-11:
name: Build Arduino IDE Tests 11
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 11 18
- name: Sketch Sizes
run: cat size.log
build-arduino-12:
name: Build Arduino IDE Tests 12
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 12 18
- name: Sketch Sizes
run: cat size.log
build-arduino-13:
name: Build Arduino IDE Tests 13
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 13 18
- name: Sketch Sizes
run: cat size.log
build-arduino-14:
name: Build Arduino IDE Tests 14
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 14 18
- name: Sketch Sizes
run: cat size.log
build-arduino-15:
name: Build Arduino IDE Tests 15
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 15 18
- name: Sketch Sizes
run: cat size.log
build-arduino-16:
name: Build Arduino IDE Tests 16
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 16 18
- name: Sketch Sizes
run: cat size.log
build-arduino-17:
name: Build Arduino IDE Tests 17
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-arduino-ide.sh
- name: Test Arduino IDE
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/test-arduino-ide.sh 17 18
- name: Sketch Sizes
run: cat size.log
build-platformio:
name: Build PlatformIO Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Pull submodules
run: git submodule update --init --recursive
- name: Install Python Wheel
run: pip install wheel
- name: Install GCC Toolchain
run: cd tools && python get.py
- name: Install PlatformIO
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
run: ./tools/ci/prep-platformio.sh
- name: Test PlatformIO
run: ./tools/ci/test-platformio.sh

7
.gitignore vendored
View File

@ -5,3 +5,10 @@ tools/esptool.exe
tools/mkspiffs/mkspiffs tools/mkspiffs/mkspiffs
tools/mkspiffs/mkspiffs.exe tools/mkspiffs/mkspiffs.exe
.DS_Store .DS_Store
#Ignore files built by Visual Studio/Visual Micro
[Dd]ebug*/
[Rr]elease*/
.vs/
__vm/
*.vcxproj*

View File

@ -1,8 +1,6 @@
sudo: false sudo: false
language: python language: python
python:
- "2.7"
os: os:
- linux - linux
@ -10,22 +8,55 @@ os:
git: git:
depth: false depth: false
env: before_install:
global: - git submodule update --init --recursive
stages:
- build
- deploy
jobs:
include:
- name: "Build Arduino 0"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/tools/ci/build-tests.sh 0 4
- name: "Build Arduino 1"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/tools/ci/build-tests.sh 1 4
- name: "Build Arduino 2"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/tools/ci/build-tests.sh 2 4
- name: "Build Arduino 3"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/tools/ci/build-tests.sh 3 4
- name: "Build PlatformIO"
if: tag IS blank AND (type = pull_request OR (type = push AND branch = master))
stage: build
script: $TRAVIS_BUILD_DIR/tools/ci/build-tests.sh 4 4
- name: "Package & Deploy"
if: tag IS present
stage: deploy
env:
- secure: "l/4Dt+KQ/mACtGAHDUsPr66fUte840PZoQ4xpPikqWZI0uARu4l+Ym7+sHinnT6fBqrj8AJeBYGz4nFa8NK4LutZn9mSD40w+sxl0wSV4oHV8rzKe3Cd8+sMG3+o33yWoikMNjSvqa73Q0rm+SgrlInNdZbuAyixL+a2alaWSnGPm4F2xwUGj+S33TOy5P/Xp77CYtCV5S8vzyk/eEdNhoF0GYePJVdfuzCOUjXMyT5OWxORkzzQ7Hnn/Ka/RDfV8Si4HgujLQBrK5q6iPnNBFqBSqilYBepSMn4opnOBpIm0SCgePz7XQEFC83buA7GUcnCnfg38bf+dCwHaODf1d1PmqVRYt2QmfinexXtM4afAtL0iBUDtvrfnXHzwW9w82VeZhpbJSVh9DUQvB0IlsZeCz9J9PUBAi3N+SMX+9l+BomYwRUlPuKY+Ef2JKk9q6mxtUkky5R0daAlVxEhpVdQks1rT+T+NMoDMemxQ3SKEiqAHh6EgHecruszffmZ71uLX9MpERpew0qN+UFiafws+jkTjx+3yF9yut0Hf9sMbeAYzzkGzRqJTUEBJ6B29Cql8M0yRXCNN/8wuuTHhG8esstozga4ZQoIVrq7mEAgup376PTcNfr1+imbbWVQ7lJdYIuDe6OS5V3OX6np11vgK/DbhfyzvQv9Z1zAGnM=" - secure: "l/4Dt+KQ/mACtGAHDUsPr66fUte840PZoQ4xpPikqWZI0uARu4l+Ym7+sHinnT6fBqrj8AJeBYGz4nFa8NK4LutZn9mSD40w+sxl0wSV4oHV8rzKe3Cd8+sMG3+o33yWoikMNjSvqa73Q0rm+SgrlInNdZbuAyixL+a2alaWSnGPm4F2xwUGj+S33TOy5P/Xp77CYtCV5S8vzyk/eEdNhoF0GYePJVdfuzCOUjXMyT5OWxORkzzQ7Hnn/Ka/RDfV8Si4HgujLQBrK5q6iPnNBFqBSqilYBepSMn4opnOBpIm0SCgePz7XQEFC83buA7GUcnCnfg38bf+dCwHaODf1d1PmqVRYt2QmfinexXtM4afAtL0iBUDtvrfnXHzwW9w82VeZhpbJSVh9DUQvB0IlsZeCz9J9PUBAi3N+SMX+9l+BomYwRUlPuKY+Ef2JKk9q6mxtUkky5R0daAlVxEhpVdQks1rT+T+NMoDMemxQ3SKEiqAHh6EgHecruszffmZ71uLX9MpERpew0qN+UFiafws+jkTjx+3yF9yut0Hf9sMbeAYzzkGzRqJTUEBJ6B29Cql8M0yRXCNN/8wuuTHhG8esstozga4ZQoIVrq7mEAgup376PTcNfr1+imbbWVQ7lJdYIuDe6OS5V3OX6np11vgK/DbhfyzvQv9Z1zAGnM="
- REMOTE_URL=https://github.com/$TRAVIS_REPO_SLUG/releases/download/$TRAVIS_TAG - REMOTE_URL=https://github.com/$TRAVIS_REPO_SLUG/releases/download/$TRAVIS_TAG
script: bash $TRAVIS_BUILD_DIR/tools/ci/build-release.sh -a$ESP32_GITHUB_TOKEN
script: before_deploy: git submodule update --init
- bash $TRAVIS_BUILD_DIR/tools/build.sh deploy:
- provider: script
deploy: skip_cleanup: true
provider: script script: bash $TRAVIS_BUILD_DIR/tools/ci/deploy-release.sh -t$TRAVIS_TAG -a$ESP32_GITHUB_TOKEN -s$TRAVIS_REPO_SLUG -drelease
skip_cleanup: true on:
script: bash $TRAVIS_BUILD_DIR/tools/deploy.sh -t$TRAVIS_TAG -a$ESP32_GITHUB_TOKEN -s$TRAVIS_REPO_SLUG -drelease tags: true
on:
tags: true
notifications: notifications:
email: email:

View File

@ -209,3 +209,8 @@ set(COMPONENT_REQUIRES spi_flash mbedtls mdns ethernet)
set(COMPONENT_PRIV_REQUIRES fatfs nvs_flash app_update spiffs bootloader_support openssl bt) set(COMPONENT_PRIV_REQUIRES fatfs nvs_flash app_update spiffs bootloader_support openssl bt)
register_component() register_component()
set_source_files_properties(libraries/AzureIoT/src/az_iot/iothub_client/src/iothubtransport_mqtt_common.c
PROPERTIES COMPILE_FLAGS
-Wno-maybe-uninitialized
)

View File

@ -232,6 +232,12 @@ config ARDUINO_SELECTIVE_ESPmDNS
select ARDUINO_SELECTIVE_WiFi select ARDUINO_SELECTIVE_WiFi
default y default y
config ARDUINO_SELECTIVE_FFat
bool "Enable FFat"
depends on ARDUINO_SELECTIVE_COMPILATION
select ARDUINO_SELECTIVE_FS
default y
config ARDUINO_SELECTIVE_FS config ARDUINO_SELECTIVE_FS
bool "Enable FS" bool "Enable FS"
depends on ARDUINO_SELECTIVE_COMPILATION depends on ARDUINO_SELECTIVE_COMPILATION

View File

@ -14,7 +14,7 @@
[Latest development release ![Development Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic) ![Development Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) ![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic) [Latest development release ![Development Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic) ![Development Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) ![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)
Most of the framework is implemented. Most noticable is the missing analogWrite. While analogWrite is on it's way, there are a few other options that you can use: Most of the framework is implemented. Most noticeable is the missing analogWrite. While analogWrite is on it's way, there are a few other options that you can use:
- 16 channels [LEDC](cores/esp32/esp32-hal-ledc.h) which is PWM - 16 channels [LEDC](cores/esp32/esp32-hal-ledc.h) which is PWM
- 8 channels [SigmaDelta](cores/esp32/esp32-hal-sigmadelta.h) which uses SigmaDelta modulation - 8 channels [SigmaDelta](cores/esp32/esp32-hal-sigmadelta.h) which uses SigmaDelta modulation
- 2 channels [DAC](cores/esp32/esp32-hal-dac.h) which gives real analog output - 2 channels [DAC](cores/esp32/esp32-hal-dac.h) which gives real analog output

View File

@ -44,6 +44,8 @@ esp32.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIF
esp32.menu.PartitionScheme.default.build.partitions=default esp32.menu.PartitionScheme.default.build.partitions=default
esp32.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) esp32.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
esp32.menu.PartitionScheme.defaultffat.build.partitions=default_ffat esp32.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
esp32.menu.PartitionScheme.default_8MB=8M Flash (3MB APP/1.5MB FAT)
esp32.menu.PartitionScheme.default_8MB.build.partitions=default_8MB
esp32.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) esp32.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
esp32.menu.PartitionScheme.minimal.build.partitions=minimal esp32.menu.PartitionScheme.minimal.build.partitions=minimal
esp32.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) esp32.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
@ -104,6 +106,9 @@ esp32.menu.FlashFreq.40.build.flash_freq=40m
esp32.menu.FlashSize.4M=4MB (32Mb) esp32.menu.FlashSize.4M=4MB (32Mb)
esp32.menu.FlashSize.4M.build.flash_size=4MB esp32.menu.FlashSize.4M.build.flash_size=4MB
esp32.menu.FlashSize.8M=8MB (64Mb)
esp32.menu.FlashSize.8M.build.flash_size=8MB
esp32.menu.FlashSize.8M.build.partitions=default_8MB
esp32.menu.FlashSize.2M=2MB (16Mb) esp32.menu.FlashSize.2M=2MB (16Mb)
esp32.menu.FlashSize.2M.build.flash_size=2MB esp32.menu.FlashSize.2M.build.flash_size=2MB
esp32.menu.FlashSize.2M.build.partitions=minimal esp32.menu.FlashSize.2M.build.partitions=minimal
@ -225,7 +230,6 @@ esp32wrover.menu.DebugLevel.verbose=Verbose
esp32wrover.menu.DebugLevel.verbose.build.code_debug=5 esp32wrover.menu.DebugLevel.verbose.build.code_debug=5
############################################################## ##############################################################
pico32.name=ESP32 Pico Kit pico32.name=ESP32 Pico Kit
pico32.upload.tool=esptool_py pico32.upload.tool=esptool_py
@ -279,6 +283,110 @@ pico32.menu.DebugLevel.verbose.build.code_debug=5
############################################################## ##############################################################
tinypico.name=TinyPICO
tinypico.upload.tool=esptool_py
tinypico.upload.maximum_size=1310720
tinypico.upload.maximum_data_size=327680
tinypico.upload.wait_for_upload_port=true
tinypico.serial.disableDTR=true
tinypico.serial.disableRTS=true
tinypico.build.mcu=esp32
tinypico.build.core=esp32
tinypico.build.variant=pico32
tinypico.build.board=ESP32_PICO
tinypico.build.f_cpu=240000000L
tinypico.build.flash_size=4MB
tinypico.build.flash_freq=80m
tinypico.build.flash_mode=dio
tinypico.build.boot=dio
tinypico.build.partitions=default
tinypico.build.defines=
tinypico.menu.UploadSpeed.921600=921600
tinypico.menu.UploadSpeed.921600.upload.speed=921600
tinypico.menu.UploadSpeed.115200=115200
tinypico.menu.UploadSpeed.115200.upload.speed=115200
tinypico.menu.UploadSpeed.256000.windows=256000
tinypico.menu.UploadSpeed.256000.upload.speed=256000
tinypico.menu.UploadSpeed.230400.windows.upload.speed=256000
tinypico.menu.UploadSpeed.230400=230400
tinypico.menu.UploadSpeed.230400.upload.speed=230400
tinypico.menu.UploadSpeed.460800.linux=460800
tinypico.menu.UploadSpeed.460800.macosx=460800
tinypico.menu.UploadSpeed.460800.upload.speed=460800
tinypico.menu.UploadSpeed.512000.windows=512000
tinypico.menu.UploadSpeed.512000.upload.speed=512000
tinypico.menu.FlashMode.qio=QIO
tinypico.menu.FlashMode.qio.build.flash_mode=dio
tinypico.menu.FlashMode.qio.build.boot=qio
tinypico.menu.FlashMode.dio=DIO
tinypico.menu.FlashMode.dio.build.flash_mode=dio
tinypico.menu.FlashMode.dio.build.boot=dio
tinypico.menu.FlashFreq.80=80MHz
tinypico.menu.FlashFreq.80.build.flash_freq=80m
tinypico.menu.FlashFreq.40=40MHz
tinypico.menu.FlashFreq.40.build.flash_freq=40m
tinypico.menu.PSRAM.enabled=Enabled
tinypico.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
tinypico.menu.PSRAM.disabled=Disabled
tinypico.menu.PSRAM.disabled.build.defines=
tinypico.menu.DebugLevel.none=None
tinypico.menu.DebugLevel.none.build.code_debug=0
tinypico.menu.DebugLevel.error=Error
tinypico.menu.DebugLevel.error.build.code_debug=1
tinypico.menu.DebugLevel.warn=Warn
tinypico.menu.DebugLevel.warn.build.code_debug=2
tinypico.menu.DebugLevel.info=Info
tinypico.menu.DebugLevel.info.build.code_debug=3
tinypico.menu.DebugLevel.debug=Debug
tinypico.menu.DebugLevel.debug.build.code_debug=4
tinypico.menu.DebugLevel.verbose=Verbose
tinypico.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
magicbit.name=MagicBit
magicbit.upload.tool=esptool_py
magicbit.upload.maximum_size=1310720
magicbit.upload.maximum_data_size=327680
magicbit.upload.wait_for_upload_port=true
magicbit.serial.disableDTR=true
magicbit.serial.disableRTS=true
magicbit.build.mcu=esp32
magicbit.build.core=esp32
magicbit.build.variant=magicbit
magicbit.build.board=ESP32_DEV
magicbit.build.f_cpu=240000000L
magicbit.build.flash_size=4MB
magicbit.build.flash_freq=40m
magicbit.build.flash_mode=dio
magicbit.build.boot=dio
magicbit.build.partitions=default
magicbit.menu.CPUFreq.240=240MHz (WiFi/BT)
magicbit.menu.CPUFreq.240.build.f_cpu=240000000L
magicbit.menu.CPUFreq.160=160MHz (WiFi/BT)
magicbit.menu.CPUFreq.160.build.f_cpu=160000000L
magicbit.menu.CPUFreq.80=80MHz (WiFi/BT)
magicbit.menu.CPUFreq.80.build.f_cpu=80000000L
magicbit.menu.CPUFreq.40=40MHz (40MHz XTAL)
magicbit.menu.UploadSpeed.921600=921600
magicbit.menu.UploadSpeed.921600.upload.speed=921600
magicbit.menu.UploadSpeed.115200=115200
magicbit.menu.UploadSpeed.115200.upload.speed=115200
##############################################################
turta_iot_node.name=Turta IoT Node turta_iot_node.name=Turta IoT Node
turta_iot_node.upload.tool=esptool_py turta_iot_node.upload.tool=esptool_py
@ -1953,6 +2061,121 @@ esp32-poe.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
############################################################## ##############################################################
esp32-poe-iso.name=OLIMEX ESP32-PoE-ISO
esp32-poe-iso.upload.tool=esptool_py
esp32-poe-iso.upload.maximum_size=1310720
esp32-poe-iso.upload.maximum_data_size=327680
esp32-poe-iso.upload.wait_for_upload_port=true
esp32-poe-iso.serial.disableDTR=true
esp32-poe-iso.serial.disableRTS=true
esp32-poe-iso.build.mcu=esp32
esp32-poe-iso.build.core=esp32
esp32-poe-iso.build.variant=esp32-poe-iso
esp32-poe-iso.build.board=ESP32_POE_ISO
esp32-poe-iso.build.f_cpu=240000000L
esp32-poe-iso.build.flash_mode=dio
esp32-poe-iso.build.flash_size=4MB
esp32-poe-iso.build.boot=dio
esp32-poe-iso.build.partitions=default
esp32-poe-iso.build.defines=
esp32-poe-iso.menu.FlashFreq.80=80MHz
esp32-poe-iso.menu.FlashFreq.80.build.flash_freq=80m
esp32-poe-iso.menu.FlashFreq.40=40MHz
esp32-poe-iso.menu.FlashFreq.40.build.flash_freq=40m
esp32-poe-iso.menu.UploadSpeed.115200=115200
esp32-poe-iso.menu.UploadSpeed.115200.upload.speed=115200
esp32-poe-iso.menu.PartitionScheme.default=Default
esp32-poe-iso.menu.PartitionScheme.default.build.partitions=default
esp32-poe-iso.menu.PartitionScheme.no_ota=No OTA (Large APP)
esp32-poe-iso.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32-poe-iso.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32-poe-iso.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32-poe-iso.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32-poe-iso.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
##############################################################
esp32-DevKitLipo.name=OLIMEX ESP32-DevKit-LiPo
esp32-DevKitLipo.upload.tool=esptool_py
esp32-DevKitLipo.upload.maximum_size=1310720
esp32-DevKitLipo.upload.maximum_data_size=327680
esp32-DevKitLipo.upload.wait_for_upload_port=true
esp32-DevKitLipo.serial.disableDTR=true
esp32-DevKitLipo.serial.disableRTS=true
esp32-DevKitLipo.build.mcu=esp32
esp32-DevKitLipo.build.core=esp32
esp32-DevKitLipo.build.variant=esp32-devkit-lipo
esp32-DevKitLipo.build.board=ESP32_DEVKIT_LIPO
esp32-DevKitLipo.build.f_cpu=240000000L
esp32-DevKitLipo.build.flash_size=4MB
esp32-DevKitLipo.build.flash_freq=40m
esp32-DevKitLipo.build.flash_mode=dio
esp32-DevKitLipo.build.boot=dio
esp32-DevKitLipo.build.partitions=default
esp32-DevKitLipo.build.defines=
esp32-DevKitLipo.menu.PartitionScheme.default=Default
esp32-DevKitLipo.menu.PartitionScheme.default.build.partitions=default
esp32-DevKitLipo.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
esp32-DevKitLipo.menu.PartitionScheme.minimal.build.partitions=minimal
esp32-DevKitLipo.menu.PartitionScheme.no_ota=No OTA (Large APP)
esp32-DevKitLipo.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32-DevKitLipo.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32-DevKitLipo.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA)
esp32-DevKitLipo.menu.PartitionScheme.huge_app.build.partitions=huge_app
esp32-DevKitLipo.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
esp32-DevKitLipo.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32-DevKitLipo.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32-DevKitLipo.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32-DevKitLipo.menu.PartitionScheme.fatflash=16M Fat
esp32-DevKitLipo.menu.PartitionScheme.fatflash.build.partitions=ffat
esp32-DevKitLipo.menu.FlashMode.qio=QIO
esp32-DevKitLipo.menu.FlashMode.qio.build.flash_mode=dio
esp32-DevKitLipo.menu.FlashMode.qio.build.boot=qio
esp32-DevKitLipo.menu.FlashMode.dio=DIO
esp32-DevKitLipo.menu.FlashMode.dio.build.flash_mode=dio
esp32-DevKitLipo.menu.FlashMode.dio.build.boot=dio
esp32-DevKitLipo.menu.FlashMode.qout=QOUT
esp32-DevKitLipo.menu.FlashMode.qout.build.flash_mode=dout
esp32-DevKitLipo.menu.FlashMode.qout.build.boot=qout
esp32-DevKitLipo.menu.FlashMode.dout=DOUT
esp32-DevKitLipo.menu.FlashMode.dout.build.flash_mode=dout
esp32-DevKitLipo.menu.FlashMode.dout.build.boot=dout
esp32-DevKitLipo.menu.FlashFreq.80=80MHz
esp32-DevKitLipo.menu.FlashFreq.80.build.flash_freq=80m
esp32-DevKitLipo.menu.FlashFreq.40=40MHz
esp32-DevKitLipo.menu.FlashFreq.40.build.flash_freq=40m
esp32-DevKitLipo.menu.UploadSpeed.921600=921600
esp32-DevKitLipo.menu.UploadSpeed.921600.upload.speed=921600
esp32-DevKitLipo.menu.UploadSpeed.115200=115200
esp32-DevKitLipo.menu.UploadSpeed.115200.upload.speed=115200
esp32-DevKitLipo.menu.UploadSpeed.256000.windows=256000
esp32-DevKitLipo.menu.UploadSpeed.256000.upload.speed=256000
esp32-DevKitLipo.menu.UploadSpeed.230400.windows.upload.speed=256000
esp32-DevKitLipo.menu.UploadSpeed.230400=230400
esp32-DevKitLipo.menu.UploadSpeed.230400.upload.speed=230400
esp32-DevKitLipo.menu.UploadSpeed.460800.linux=460800
esp32-DevKitLipo.menu.UploadSpeed.460800.macosx=460800
esp32-DevKitLipo.menu.UploadSpeed.460800.upload.speed=460800
esp32-DevKitLipo.menu.UploadSpeed.512000.windows=512000
esp32-DevKitLipo.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
espino32.name=ThaiEasyElec's ESPino32 espino32.name=ThaiEasyElec's ESPino32
espino32.upload.tool=esptool_py espino32.upload.tool=esptool_py
@ -2582,7 +2805,7 @@ heltec_wifi_lora_32_V2.menu.FlashFreq.40.build.flash_freq=40m
heltec_wifi_lora_32_V2.menu.FlashSize.8M=8MB (64Mb) heltec_wifi_lora_32_V2.menu.FlashSize.8M=8MB (64Mb)
heltec_wifi_lora_32_V2.menu.FlashSize.8M.build.flash_size=8MB heltec_wifi_lora_32_V2.menu.FlashSize.8M.build.flash_size=8MB
heltec_wifi_lora_32_V2.menu.FlashSize.2M.build.partitions=default_8MB heltec_wifi_lora_32_V2.menu.FlashSize.8M.build.partitions=default_8MB
heltec_wifi_lora_32_V2.menu.FlashSize.4M=4MB (32Mb) heltec_wifi_lora_32_V2.menu.FlashSize.4M=4MB (32Mb)
heltec_wifi_lora_32_V2.menu.FlashSize.4M.build.flash_size=4MB heltec_wifi_lora_32_V2.menu.FlashSize.4M.build.flash_size=4MB
heltec_wifi_lora_32_V2.menu.FlashSize.2M=2MB (16Mb) heltec_wifi_lora_32_V2.menu.FlashSize.2M=2MB (16Mb)

View File

@ -75,7 +75,7 @@ public:
uint32_t getMaxAllocPsram(); uint32_t getMaxAllocPsram();
uint8_t getChipRevision(); uint8_t getChipRevision();
uint8_t getCpuFreqMHz(){ return CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ; } uint32_t getCpuFreqMHz(){ return getCpuFrequencyMhz(); }
uint32_t getCycleCount(); uint32_t getCycleCount();
const char * getSdkVersion(); const char * getSdkVersion();

View File

@ -52,7 +52,7 @@ size_t Print::printf(const char *format, ...)
va_list copy; va_list copy;
va_start(arg, format); va_start(arg, format);
va_copy(copy, arg); va_copy(copy, arg);
size_t len = vsnprintf(NULL, 0, format, arg); size_t len = vsnprintf(NULL, 0, format, copy);
va_end(copy); va_end(copy);
if(len >= sizeof(loc_buf)){ if(len >= sizeof(loc_buf)){
temp = new char[len+1]; temp = new char[len+1];

View File

@ -65,9 +65,12 @@ long random(long howsmall, long howbig)
return random(diff) + howsmall; return random(diff) + howsmall;
} }
long map(long x, long in_min, long in_max, long out_min, long out_max) long map(long x, long in_min, long in_max, long out_min, long out_max) {
{ long divisor = (in_max - in_min);
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; if(divisor == 0){
return -1; //AVR returns -1, SAM returns 0
}
return (x - in_min) * (out_max - out_min) / divisor + out_min;
} }
unsigned int makeWord(unsigned int w) unsigned int makeWord(unsigned int w)

View File

@ -31,7 +31,7 @@
String::String(const char *cstr) { String::String(const char *cstr) {
init(); init();
if(cstr) if (cstr)
copy(cstr, strlen(cstr)); copy(cstr, strlen(cstr));
} }
@ -136,7 +136,7 @@ inline void String::init(void) {
} }
void String::invalidate(void) { void String::invalidate(void) {
if(!sso() && wbuffer()) if(!isSSO() && wbuffer())
free(wbuffer()); free(wbuffer());
init(); init();
} }
@ -154,17 +154,21 @@ unsigned char String::reserve(unsigned int size) {
unsigned char String::changeBuffer(unsigned int maxStrLen) { unsigned char String::changeBuffer(unsigned int maxStrLen) {
// Can we use SSO here to avoid allocation? // Can we use SSO here to avoid allocation?
if (maxStrLen < sizeof(sso_buf)) { if (maxStrLen < sizeof(sso.buff) - 1) {
if (sso() || !buffer()) { if (isSSO() || !buffer()) {
// Already using SSO, nothing to do // Already using SSO, nothing to do
uint16_t oldLen = len();
setSSO(true); setSSO(true);
setLen(oldLen);
return 1; return 1;
} else { // if bufptr && !sso() } else { // if bufptr && !isSSO()
// Using bufptr, need to shrink into sso_buff // Using bufptr, need to shrink into sso.buff
char temp[sizeof(sso_buf)]; char temp[sizeof(sso.buff)];
memcpy(temp, buffer(), maxStrLen); memcpy(temp, buffer(), maxStrLen);
free(wbuffer()); free(wbuffer());
uint16_t oldLen = len();
setSSO(true); setSSO(true);
setLen(oldLen);
memcpy(wbuffer(), temp, maxStrLen); memcpy(wbuffer(), temp, maxStrLen);
return 1; return 1;
} }
@ -176,12 +180,12 @@ unsigned char String::changeBuffer(unsigned int maxStrLen) {
return false; return false;
} }
uint16_t oldLen = len(); uint16_t oldLen = len();
char *newbuffer = (char *) realloc(sso() ? nullptr : wbuffer(), newSize); char *newbuffer = (char *) realloc(isSSO() ? nullptr : wbuffer(), newSize);
if(newbuffer) { if (newbuffer) {
size_t oldSize = capacity() + 1; // include NULL. size_t oldSize = capacity() + 1; // include NULL.
if (sso()) { if (isSSO()) {
// Copy the SSO buffer into allocated space // Copy the SSO buffer into allocated space
memcpy(newbuffer, sso_buf, sizeof(sso_buf)); memmove(newbuffer, sso.buff, sizeof(sso.buff));
} }
if (newSize > oldSize) if (newSize > oldSize)
{ {
@ -206,7 +210,7 @@ String & String::copy(const char *cstr, unsigned int length) {
return *this; return *this;
} }
setLen(length); setLen(length);
strcpy(wbuffer(), cstr); memmove(wbuffer(), cstr, length + 1);
return *this; return *this;
} }
@ -216,7 +220,7 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length) {
return *this; return *this;
} }
setLen(length); setLen(length);
strcpy_P(wbuffer(), (PGM_P)pstr); memcpy_P(wbuffer(), (PGM_P)pstr, length + 1); // We know wbuffer() cannot ever be in PROGMEM, so memcpy safe here
return *this; return *this;
} }
@ -224,20 +228,20 @@ String & String::copy(const __FlashStringHelper *pstr, unsigned int length) {
void String::move(String &rhs) { void String::move(String &rhs) {
if(buffer()) { if(buffer()) {
if(capacity() >= rhs.len()) { if(capacity() >= rhs.len()) {
strcpy(wbuffer(), rhs.buffer()); memmove(wbuffer(), rhs.buffer(), rhs.length() + 1);
setLen(rhs.len()); setLen(rhs.len());
rhs.invalidate(); rhs.invalidate();
return; return;
} else { } else {
if (!sso()) { if (!isSSO()) {
free(wbuffer()); free(wbuffer());
setBuffer(nullptr); setBuffer(nullptr);
} }
} }
} }
if (rhs.sso()) { if (rhs.isSSO()) {
setSSO(true); setSSO(true);
memmove(sso_buf, rhs.sso_buf, sizeof(sso_buf)); memmove(sso.buff, rhs.sso.buff, sizeof(sso.buff));
} else { } else {
setSSO(false); setSSO(false);
setBuffer(rhs.wbuffer()); setBuffer(rhs.wbuffer());
@ -309,7 +313,7 @@ unsigned char String::concat(const String &s) {
return 1; return 1;
if (!reserve(newlen)) if (!reserve(newlen))
return 0; return 0;
memcpy(wbuffer() + len(), buffer(), len()); memmove(wbuffer() + len(), buffer(), len());
setLen(newlen); setLen(newlen);
wbuffer()[len()] = 0; wbuffer()[len()] = 0;
return 1; return 1;
@ -326,7 +330,12 @@ unsigned char String::concat(const char *cstr, unsigned int length) {
return 1; return 1;
if(!reserve(newlen)) if(!reserve(newlen))
return 0; return 0;
strcpy(wbuffer() + len(), cstr); if (cstr >= wbuffer() && cstr < wbuffer() + len())
// compatible with SSO in ram #6155 (case "x += x.c_str()")
memmove(wbuffer() + len(), cstr, length + 1);
else
// compatible with source in flash #6367
memcpy_P(wbuffer() + len(), cstr, length + 1);
setLen(newlen); setLen(newlen);
return 1; return 1;
} }
@ -392,7 +401,7 @@ unsigned char String::concat(const __FlashStringHelper * str) {
if (length == 0) return 1; if (length == 0) return 1;
unsigned int newlen = len() + length; unsigned int newlen = len() + length;
if (!reserve(newlen)) return 0; if (!reserve(newlen)) return 0;
strcpy_P(wbuffer() + len(), (PGM_P)str); memcpy_P(wbuffer() + len(), (PGM_P)str, length + 1);
setLen(newlen); setLen(newlen);
return 1; return 1;
} }

View File

@ -27,6 +27,7 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <pgmspace.h> #include <pgmspace.h>
#include <stdint.h>
// An inherited class for holding the result of a concatenation. These // An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations. // result objects are assumed to be writable by subsequent concatenations.
@ -35,7 +36,8 @@ class StringSumHelper;
// an abstract class used as a means to proide a unique pointer type // an abstract class used as a means to proide a unique pointer type
// but really has no body // but really has no body
class __FlashStringHelper; class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal))) #define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
#define F(string_literal) (FPSTR(PSTR(string_literal)))
// The string class // The string class
class String { class String {
@ -81,6 +83,12 @@ class String {
return 0; return 0;
} }
} }
inline void clear(void) {
setLen(0);
}
inline bool isEmpty(void) const {
return length() == 0;
}
// creates a copy of the assigned value. if the value is null or // creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be // invalid, or if the memory allocation fails, the string will be
@ -97,7 +105,7 @@ class String {
// returns true on success, false on failure (in which case, the string // returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the // is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsucessful. // concatenation is considered unsuccessful.
unsigned char concat(const String &str); unsigned char concat(const String &str);
unsigned char concat(const char *cstr); unsigned char concat(const char *cstr);
unsigned char concat(char c); unsigned char concat(char c);
@ -198,7 +206,7 @@ class String {
unsigned char startsWith(const String &prefix, unsigned int offset) const; unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const; unsigned char endsWith(const String &suffix) const;
// character acccess // character access
char charAt(unsigned int index) const; char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c); void setCharAt(unsigned int index, char c);
char operator [](unsigned int index) const; char operator [](unsigned int index) const;
@ -249,27 +257,29 @@ class String {
uint16_t cap; uint16_t cap;
uint16_t len; uint16_t len;
}; };
// This allows strings up up to 11 (10 + \0 termination) without any extra space.
// SSO is handled by checking the last byte of sso_buff. enum { SSOSIZE = sizeof(struct _ptr) + 4 - 1 }; // Characters to allocate space for SSO, must be 12 or more
// When not in SSO mode, that byte is set to 0xff, while when in SSO mode it is always 0x00 (so it can serve as the string terminator as well as a flag) struct _sso {
// This allows strings up up to 12 (11 + \0 termination) without any extra space. char buff[SSOSIZE];
enum { SSOSIZE = sizeof(struct _ptr) + 4 }; // Characters to allocate space for SSO, must be 12 or more unsigned char len : 7; // Ensure only one byte is allocated by GCC for the bitfields
enum { CAPACITY_MAX = 65535 }; // If size of capacity changed, be sure to update this enum unsigned char isSSO : 1;
} __attribute__((packed)); // Ensure that GCC doesn't expand the flag byte to a 32-bit word for alignment issues
enum { CAPACITY_MAX = 65535 }; // If typeof(cap) changed from uint16_t, be sure to update this enum to the max value storable in the type
union { union {
struct _ptr ptr; struct _ptr ptr;
char sso_buf[SSOSIZE]; struct _sso sso;
}; };
// Accessor functions // Accessor functions
inline bool sso() const { return sso_buf[SSOSIZE - 1] == 0; } inline bool isSSO() const { return sso.isSSO; }
inline unsigned int len() const { return sso() ? strlen(sso_buf) : ptr.len; } inline unsigned int len() const { return isSSO() ? sso.len : ptr.len; }
inline unsigned int capacity() const { return sso() ? SSOSIZE - 1 : ptr.cap; } inline unsigned int capacity() const { return isSSO() ? (unsigned int)SSOSIZE - 1 : ptr.cap; } // Size of max string not including terminal NUL
inline void setSSO(bool sso) { sso_buf[SSOSIZE - 1] = sso ? 0x00 : 0xff; } inline void setSSO(bool set) { sso.isSSO = set; }
inline void setLen(int len) { if (!sso()) ptr.len = len; } inline void setLen(int len) { if (isSSO()) sso.len = len; else ptr.len = len; }
inline void setCapacity(int cap) { if (!sso()) ptr.cap = cap; } inline void setCapacity(int cap) { if (!isSSO()) ptr.cap = cap; }
inline void setBuffer(char *buff) { if (!sso()) ptr.buff = buff; } inline void setBuffer(char *buff) { if (!isSSO()) ptr.buff = buff; }
// Buffer accessor functions // Buffer accessor functions
inline const char *buffer() const { return (const char *)(sso() ? sso_buf : ptr.buff); } inline const char *buffer() const { return (const char *)(isSSO() ? sso.buff : ptr.buff); }
inline char *wbuffer() const { return sso() ? const_cast<char *>(sso_buf) : ptr.buff; } // Writable version of buffer inline char *wbuffer() const { return isSSO() ? const_cast<char *>(sso.buff) : ptr.buff; } // Writable version of buffer
protected: protected:
void init(void); void init(void);

View File

@ -23,6 +23,7 @@
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "rom/rtc.h" #include "rom/rtc.h"
#include "soc/apb_ctrl_reg.h" #include "soc/apb_ctrl_reg.h"
#include "soc/efuse_reg.h"
#include "esp32-hal.h" #include "esp32-hal.h"
#include "esp32-hal-cpu.h" #include "esp32-hal-cpu.h"
@ -150,6 +151,15 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
} }
return false; return false;
} }
//check if cpu supports the frequency
if(cpu_freq_mhz == 240){
//Check if ESP32 is rated for a CPU frequency of 160MHz only
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_LOW)) {
log_e("Can not switch to 240 MHz! Chip CPU frequency rated for 160MHz.");
cpu_freq_mhz = 160;
}
}
//Get current CPU clock configuration //Get current CPU clock configuration
rtc_clk_cpu_freq_get_config(&cconf); rtc_clk_cpu_freq_get_config(&cconf);
//return if frequency has not changed //return if frequency has not changed

View File

@ -1270,7 +1270,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
i2c->dev->ctr.trans_start=1; // go for it i2c->dev->ctr.trans_start=1; // go for it
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
portTickType tBefore=xTaskGetTickCount(); portTickType tBefore=xTaskGetTickCount();
#endif #endif
@ -1278,7 +1278,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut); uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut);
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
portTickType tAfter=xTaskGetTickCount(); portTickType tAfter=xTaskGetTickCount();
#endif #endif

View File

@ -343,6 +343,8 @@ void uartFlush(uart_t* uart)
READ_PERI_REG(UART_FIFO_REG(uart->num)); READ_PERI_REG(UART_FIFO_REG(uart->num));
} }
xQueueReset(uart->queue);
UART_MUTEX_UNLOCK(); UART_MUTEX_UNLOCK();
} }

View File

@ -32,7 +32,6 @@ typedef unsigned long prog_uint32_t;
#define PROGMEM #define PROGMEM
#define PGM_P const char * #define PGM_P const char *
#define PGM_VOID_P const void * #define PGM_VOID_P const void *
#define FPSTR(p) ((const char *)(p))
#define PSTR(s) (s) #define PSTR(s) (s)
#define _SFR_BYTE(n) (n) #define _SFR_BYTE(n) (n)

View File

@ -1,11 +1,11 @@
Installation instructions for using PlatformIO Installation instructions for using PlatformIO
================================================= =================================================
- [What is PlatformIO?](http://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp32) - [What is PlatformIO?](https://docs.platformio.org/en/latest/what-is-platformio.html?utm_source=github&utm_medium=arduino-esp32)
- [PlatformIO IDE](http://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp32) - [PlatformIO IDE](https://platformio.org/platformio-ide?utm_source=github&utm_medium=arduino-esp32)
- [PlatformIO Core](http://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp32) (command line tool) - [PlatformIO Core](https://docs.platformio.org/en/latest/core.html?utm_source=github&utm_medium=arduino-esp32) (command line tool)
- [Advanced usage](http://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32) - - [Advanced usage](https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32) -
custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version custom settings, uploading to SPIFFS, Over-the-Air (OTA), staging version
- [Integration with Cloud and Standalone IDEs](http://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp32) - - [Integration with Cloud and Standalone IDEs](https://docs.platformio.org/en/latest/ide.html?utm_source=github&utm_medium=arduino-esp32) -
Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode Cloud9, Codeanywhere, Eclipse Che (Codenvy), Atom, CLion, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, VIM, Visual Studio, and VSCode
- [Project Examples](http://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32#examples) - [Project Examples](https://docs.platformio.org/en/latest/platforms/espressif32.html?utm_source=github&utm_medium=arduino-esp32#examples)

View File

@ -1,17 +0,0 @@
{
"name":"AsyncUDP",
"description":"Asynchronous UDP Library for ESP32",
"keywords":"async,udp,server,client,multicast,broadcast",
"authors":
{
"name": "Hristo Gochkov",
"maintainer": true
},
"repository":
{
"type": "git",
"url": "https://github.com/me-no-dev/ESPAsyncUDP.git"
},
"frameworks": "arduino",
"platforms":"espressif"
}

View File

@ -682,8 +682,9 @@ void AsyncUDP::_recv(udp_pcb *upcb, pbuf *pb, const ip_addr_t *addr, uint16_t po
if(_handler) { if(_handler) {
AsyncUDPPacket packet(this, this_pb, addr, port, netif); AsyncUDPPacket packet(this, this_pb, addr, port, netif);
_handler(packet); _handler(packet);
} else {
pbuf_free(this_pb);
} }
pbuf_free(this_pb);
} }
} }

View File

@ -13,6 +13,7 @@
#include <iomanip> #include <iomanip>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <malloc.h>
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include "esp32-hal-log.h" #include "esp32-hal-log.h"
#endif #endif
@ -83,13 +84,11 @@ esp_bd_addr_t *BLEAddress::getNative() {
* @return The string representation of the address. * @return The string representation of the address.
*/ */
std::string BLEAddress::toString() { std::string BLEAddress::toString() {
std::stringstream stream; auto size = 18;
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[0] << ':'; char *res = (char*)malloc(size);
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[1] << ':'; snprintf(res, size, "%02x:%02x:%02x:%02x:%02x:%02x", m_address[0], m_address[1], m_address[2], m_address[3], m_address[4], m_address[5]);
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[2] << ':'; std::string ret(res);
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[3] << ':'; free(res);
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[4] << ':'; return ret;
stream << std::setfill('0') << std::setw(2) << std::hex << (int) ((uint8_t*) (m_address))[5];
return stream.str();
} // toString } // toString
#endif #endif

View File

@ -484,23 +484,29 @@ void BLEAdvertisedDevice::setTXPower(int8_t txPower) {
* @return A string representation of this device. * @return A string representation of this device.
*/ */
std::string BLEAdvertisedDevice::toString() { std::string BLEAdvertisedDevice::toString() {
std::stringstream ss; std::string res = "Name: " + getName() + ", Address: " + getAddress().toString();
ss << "Name: " << getName() << ", Address: " << getAddress().toString();
if (haveAppearance()) { if (haveAppearance()) {
ss << ", appearance: " << getAppearance(); char val[6];
snprintf(val, sizeof(val), "%d", getAppearance());
res += ", appearance: ";
res += val;
} }
if (haveManufacturerData()) { if (haveManufacturerData()) {
char *pHex = BLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().data(), getManufacturerData().length()); char *pHex = BLEUtils::buildHexData(nullptr, (uint8_t*)getManufacturerData().data(), getManufacturerData().length());
ss << ", manufacturer data: " << pHex; res += ", manufacturer data: ";
res += pHex;
free(pHex); free(pHex);
} }
if (haveServiceUUID()) { if (haveServiceUUID()) {
ss << ", serviceUUID: " << getServiceUUID().toString(); res += ", serviceUUID: " + getServiceUUID().toString();
} }
if (haveTXPower()) { if (haveTXPower()) {
ss << ", txPower: " << (int)getTXPower(); char val[4];
snprintf(val, sizeof(val), "%d", getTXPower());
res += ", txPower: ";
res += val;
} }
return ss.str(); return res;
} // toString } // toString
uint8_t* BLEAdvertisedDevice::getPayload() { uint8_t* BLEAdvertisedDevice::getPayload() {

View File

@ -262,7 +262,7 @@ void BLEAdvertising::stop() {
void BLEAdvertising::setDeviceAddress(esp_bd_addr_t addr, esp_ble_addr_type_t type) void BLEAdvertising::setDeviceAddress(esp_bd_addr_t addr, esp_ble_addr_type_t type)
{ {
log_v(">> setPrivateAddress") log_v(">> setPrivateAddress");
m_advParams.own_addr_type = type; m_advParams.own_addr_type = type;
esp_err_t errRc = esp_ble_gap_set_rand_addr((uint8_t*)addr); esp_err_t errRc = esp_ble_gap_set_rand_addr((uint8_t*)addr);
@ -271,7 +271,7 @@ void BLEAdvertising::setDeviceAddress(esp_bd_addr_t addr, esp_ble_addr_type_t ty
log_e("esp_ble_gap_set_rand_addr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc)); log_e("esp_ble_gap_set_rand_addr: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
return; return;
} }
log_v("<< setPrivateAddress") log_v("<< setPrivateAddress");
} // setPrivateAddress } // setPrivateAddress
/** /**
@ -505,7 +505,7 @@ void BLEAdvertising::handleGAPEvent(
} }
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: { case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT: {
log_i("STOP advertising"); log_i("STOP advertising");
start(); //start();
break; break;
} }
default: default:

View File

@ -22,6 +22,7 @@
#define NULL_HANDLE (0xffff) #define NULL_HANDLE (0xffff)
static BLECharacteristicCallbacks defaultCallback; //null-object-pattern
/** /**
* @brief Construct a characteristic * @brief Construct a characteristic
@ -40,7 +41,7 @@ BLECharacteristic::BLECharacteristic(BLEUUID uuid, uint32_t properties) {
m_bleUUID = uuid; m_bleUUID = uuid;
m_handle = NULL_HANDLE; m_handle = NULL_HANDLE;
m_properties = (esp_gatt_char_prop_t)0; m_properties = (esp_gatt_char_prop_t)0;
m_pCallbacks = nullptr; m_pCallbacks = &defaultCallback;
setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0); setBroadcastProperty((properties & PROPERTY_BROADCAST) != 0);
setReadProperty((properties & PROPERTY_READ) != 0); setReadProperty((properties & PROPERTY_READ) != 0);
@ -220,9 +221,7 @@ void BLECharacteristic::handleGATTServerEvent(
case ESP_GATTS_EXEC_WRITE_EVT: { case ESP_GATTS_EXEC_WRITE_EVT: {
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) { if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
m_value.commit(); m_value.commit();
if (m_pCallbacks != nullptr) { m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
}
} else { } else {
m_value.cancel(); m_value.cancel();
} }
@ -307,7 +306,7 @@ void BLECharacteristic::handleGATTServerEvent(
} }
} // Response needed } // Response needed
if (m_pCallbacks != nullptr && param->write.is_prep != true) { if (param->write.is_prep != true) {
m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler. m_pCallbacks->onWrite(this); // Invoke the onWrite callback handler.
} }
} // Match on handles. } // Match on handles.
@ -378,6 +377,10 @@ void BLECharacteristic::handleGATTServerEvent(
} }
} else { // read.is_long == false } else { // read.is_long == false
// If is.long is false then this is the first (or only) request to read data, so invoke the callback
// Invoke the read callback.
m_pCallbacks->onRead(this);
std::string value = m_value.getValue(); std::string value = m_value.getValue();
if (value.length() + 1 > maxOffset) { if (value.length() + 1 > maxOffset) {
@ -392,10 +395,6 @@ void BLECharacteristic::handleGATTServerEvent(
rsp.attr_value.offset = 0; rsp.attr_value.offset = 0;
memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len); memcpy(rsp.attr_value.value, value.data(), rsp.attr_value.len);
} }
if (m_pCallbacks != nullptr) { // If is.long is false then this is the first (or only) request to read data, so invoke the callback
m_pCallbacks->onRead(this); // Invoke the read callback.
}
} }
rsp.attr_value.handle = param->read.handle; rsp.attr_value.handle = param->read.handle;
rsp.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE; rsp.attr_value.auth_req = ESP_GATT_AUTH_REQ_NONE;
@ -480,10 +479,13 @@ void BLECharacteristic::notify(bool is_notification) {
assert(getService() != nullptr); assert(getService() != nullptr);
assert(getService()->getServer() != nullptr); assert(getService()->getServer() != nullptr);
m_pCallbacks->onNotify(this); // Invoke the notify callback.
GeneralUtils::hexDump((uint8_t*)m_value.getValue().data(), m_value.getValue().length()); GeneralUtils::hexDump((uint8_t*)m_value.getValue().data(), m_value.getValue().length());
if (getService()->getServer()->getConnectedCount() == 0) { if (getService()->getServer()->getConnectedCount() == 0) {
log_v("<< notify: No connected clients."); log_v("<< notify: No connected clients.");
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_NO_CLIENT, 0);
return; return;
} }
@ -494,12 +496,14 @@ void BLECharacteristic::notify(bool is_notification) {
if(is_notification) { if(is_notification) {
if (p2902 != nullptr && !p2902->getNotifications()) { if (p2902 != nullptr && !p2902->getNotifications()) {
log_v("<< notifications disabled; ignoring"); log_v("<< notifications disabled; ignoring");
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_NOTIFY_DISABLED, 0); // Invoke the notify callback.
return; return;
} }
} }
else{ else{
if (p2902 != nullptr && !p2902->getIndications()) { if (p2902 != nullptr && !p2902->getIndications()) {
log_v("<< indications disabled; ignoring"); log_v("<< indications disabled; ignoring");
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_DISABLED, 0); // Invoke the notify callback.
return; return;
} }
} }
@ -510,7 +514,7 @@ void BLECharacteristic::notify(bool is_notification) {
} }
size_t length = m_value.getValue().length(); size_t length = m_value.getValue().length();
if(!is_notification) if(!is_notification) // is indication
m_semaphoreConfEvt.take("indicate"); m_semaphoreConfEvt.take("indicate");
esp_err_t errRc = ::esp_ble_gatts_send_indicate( esp_err_t errRc = ::esp_ble_gatts_send_indicate(
getService()->getServer()->getGattsIf(), getService()->getServer()->getGattsIf(),
@ -519,10 +523,23 @@ void BLECharacteristic::notify(bool is_notification) {
if (errRc != ESP_OK) { if (errRc != ESP_OK) {
log_e("<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc)); log_e("<< esp_ble_gatts_send_ %s: rc=%d %s",is_notification?"notify":"indicate", errRc, GeneralUtils::errorToString(errRc));
m_semaphoreConfEvt.give(); m_semaphoreConfEvt.give();
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_GATT, errRc); // Invoke the notify callback.
return; return;
} }
if(!is_notification) if(!is_notification){ // is indication
m_semaphoreConfEvt.wait("indicate"); if(!m_semaphoreConfEvt.timedWait("indicate", indicationTimeout)){
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_TIMEOUT, 0); // Invoke the notify callback.
} else {
auto code = (esp_gatt_status_t) m_semaphoreConfEvt.value();
if(code == ESP_GATT_OK) {
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::SUCCESS_INDICATE, code); // Invoke the notify callback.
} else {
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::ERROR_INDICATE_FAILURE, code);
}
}
} else {
m_pCallbacks->onStatus(this, BLECharacteristicCallbacks::Status::SUCCESS_NOTIFY, 0); // Invoke the notify callback.
}
} }
log_v("<< notify"); log_v("<< notify");
} // Notify } // Notify
@ -551,7 +568,11 @@ void BLECharacteristic::setBroadcastProperty(bool value) {
*/ */
void BLECharacteristic::setCallbacks(BLECharacteristicCallbacks* pCallbacks) { void BLECharacteristic::setCallbacks(BLECharacteristicCallbacks* pCallbacks) {
log_v(">> setCallbacks: 0x%x", (uint32_t)pCallbacks); log_v(">> setCallbacks: 0x%x", (uint32_t)pCallbacks);
m_pCallbacks = pCallbacks; if (pCallbacks != nullptr){
m_pCallbacks = pCallbacks;
} else {
m_pCallbacks = &defaultCallback;
}
log_v("<< setCallbacks"); log_v("<< setCallbacks");
} // setCallbacks } // setCallbacks
@ -628,7 +649,9 @@ void BLECharacteristic::setValue(uint8_t* data, size_t length) {
log_e("Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN); log_e("Size %d too large, must be no bigger than %d", length, ESP_GATT_MAX_ATTR_LEN);
return; return;
} }
m_semaphoreSetValue.take();
m_value.setValue(data, length); m_value.setValue(data, length);
m_semaphoreSetValue.give();
log_v("<< setValue"); log_v("<< setValue");
} // setValue } // setValue
@ -715,17 +738,18 @@ void BLECharacteristic::setWriteProperty(bool value) {
* @return A string representation of the characteristic. * @return A string representation of the characteristic.
*/ */
std::string BLECharacteristic::toString() { std::string BLECharacteristic::toString() {
std::stringstream stringstream; std::string res = "UUID: " + m_bleUUID.toString() + ", handle : 0x";
stringstream << std::hex << std::setfill('0'); char hex[5];
stringstream << "UUID: " << m_bleUUID.toString() + ", handle: 0x" << std::setw(2) << m_handle; snprintf(hex, sizeof(hex), "%04x", m_handle);
stringstream << " " << res += hex;
((m_properties & ESP_GATT_CHAR_PROP_BIT_READ) ? "Read " : "") << res += " ";
((m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE) ? "Write " : "") << if (m_properties & ESP_GATT_CHAR_PROP_BIT_READ) res += "Read ";
((m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE_NR) ? "WriteNoResponse " : "") << if (m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE) res += "Write ";
((m_properties & ESP_GATT_CHAR_PROP_BIT_BROADCAST) ? "Broadcast " : "") << if (m_properties & ESP_GATT_CHAR_PROP_BIT_WRITE_NR) res += "WriteNoResponse ";
((m_properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY) ? "Notify " : "") << if (m_properties & ESP_GATT_CHAR_PROP_BIT_BROADCAST) res += "Broadcast ";
((m_properties & ESP_GATT_CHAR_PROP_BIT_INDICATE) ? "Indicate " : ""); if (m_properties & ESP_GATT_CHAR_PROP_BIT_NOTIFY) res += "Notify ";
return stringstream.str(); if (m_properties & ESP_GATT_CHAR_PROP_BIT_INDICATE) res += "Indicate ";
return res;
} // toString } // toString
@ -751,4 +775,27 @@ void BLECharacteristicCallbacks::onWrite(BLECharacteristic* pCharacteristic) {
log_d("BLECharacteristicCallbacks", "<< onWrite"); log_d("BLECharacteristicCallbacks", "<< onWrite");
} // onWrite } // onWrite
/**
* @brief Callback function to support a Notify request.
* @param [in] pCharacteristic The characteristic that is the source of the event.
*/
void BLECharacteristicCallbacks::onNotify(BLECharacteristic* pCharacteristic) {
log_d("BLECharacteristicCallbacks", ">> onNotify: default");
log_d("BLECharacteristicCallbacks", "<< onNotify");
} // onNotify
/**
* @brief Callback function to support a Notify/Indicate Status report.
* @param [in] pCharacteristic The characteristic that is the source of the event.
* @param [in] s Status of the notification/indication
* @param [in] code Additional code of underlying errors
*/
void BLECharacteristicCallbacks::onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code) {
log_d("BLECharacteristicCallbacks", ">> onStatus: default");
log_d("BLECharacteristicCallbacks", "<< onStatus");
} // onStatus
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */

View File

@ -90,6 +90,8 @@ public:
static const uint32_t PROPERTY_INDICATE = 1<<4; static const uint32_t PROPERTY_INDICATE = 1<<4;
static const uint32_t PROPERTY_WRITE_NR = 1<<5; static const uint32_t PROPERTY_WRITE_NR = 1<<5;
static const uint32_t indicationTimeout = 1000;
private: private:
friend class BLEServer; friend class BLEServer;
@ -117,6 +119,7 @@ private:
void setHandle(uint16_t handle); void setHandle(uint16_t handle);
FreeRTOS::Semaphore m_semaphoreCreateEvt = FreeRTOS::Semaphore("CreateEvt"); FreeRTOS::Semaphore m_semaphoreCreateEvt = FreeRTOS::Semaphore("CreateEvt");
FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt"); FreeRTOS::Semaphore m_semaphoreConfEvt = FreeRTOS::Semaphore("ConfEvt");
FreeRTOS::Semaphore m_semaphoreSetValue = FreeRTOS::Semaphore("SetValue");
}; // BLECharacteristic }; // BLECharacteristic
@ -129,9 +132,22 @@ private:
*/ */
class BLECharacteristicCallbacks { class BLECharacteristicCallbacks {
public: public:
typedef enum {
SUCCESS_INDICATE,
SUCCESS_NOTIFY,
ERROR_INDICATE_DISABLED,
ERROR_NOTIFY_DISABLED,
ERROR_GATT,
ERROR_NO_CLIENT,
ERROR_INDICATE_TIMEOUT,
ERROR_INDICATE_FAILURE
}Status;
virtual ~BLECharacteristicCallbacks(); virtual ~BLECharacteristicCallbacks();
virtual void onRead(BLECharacteristic* pCharacteristic); virtual void onRead(BLECharacteristic* pCharacteristic);
virtual void onWrite(BLECharacteristic* pCharacteristic); virtual void onWrite(BLECharacteristic* pCharacteristic);
virtual void onNotify(BLECharacteristic* pCharacteristic);
virtual void onStatus(BLECharacteristic* pCharacteristic, Status s, uint32_t code);
}; };
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */
#endif /* COMPONENTS_CPP_UTILS_BLECHARACTERISTIC_H_ */ #endif /* COMPONENTS_CPP_UTILS_BLECHARACTERISTIC_H_ */

View File

@ -116,17 +116,18 @@ void BLECharacteristicMap::setByUUID(BLECharacteristic* pCharacteristic, BLEUUID
* @return A string representation of the characteristic map. * @return A string representation of the characteristic map.
*/ */
std::string BLECharacteristicMap::toString() { std::string BLECharacteristicMap::toString() {
std::stringstream stringStream; std::string res;
stringStream << std::hex << std::setfill('0');
int count = 0; int count = 0;
char hex[5];
for (auto &myPair: m_uuidMap) { for (auto &myPair: m_uuidMap) {
if (count > 0) { if (count > 0) {res += "\n";}
stringStream << "\n"; snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
}
count++; count++;
stringStream << "handle: 0x" << std::setw(2) << myPair.first->getHandle() << ", uuid: " + myPair.first->getUUID().toString(); res += "handle: 0x";
res += hex;
res += ", uuid: " + myPair.first->getUUID().toString();
} }
return stringStream.str(); return res;
} // toString } // toString

View File

@ -184,10 +184,11 @@ void BLEClient::gattClientEventHandler(
if (m_pClientCallbacks != nullptr) { if (m_pClientCallbacks != nullptr) {
m_pClientCallbacks->onDisconnect(this); m_pClientCallbacks->onDisconnect(this);
} }
BLEDevice::removePeerDevice(m_appId, true);
esp_ble_gattc_app_unregister(m_gattc_if); esp_ble_gattc_app_unregister(m_gattc_if);
m_semaphoreOpenEvt.give(ESP_GATT_IF_NONE);
m_semaphoreRssiCmplEvt.give(); m_semaphoreRssiCmplEvt.give();
m_semaphoreSearchCmplEvt.give(1); m_semaphoreSearchCmplEvt.give(1);
BLEDevice::removePeerDevice(m_appId, true);
break; break;
} // ESP_GATTC_DISCONNECT_EVT } // ESP_GATTC_DISCONNECT_EVT
@ -515,14 +516,13 @@ uint16_t BLEClient::getMTU() {
* @return A string representation of this client. * @return A string representation of this client.
*/ */
std::string BLEClient::toString() { std::string BLEClient::toString() {
std::ostringstream ss; std::string res = "peer address: " + m_peerAddress.toString();
ss << "peer address: " << m_peerAddress.toString(); res += "\nServices:\n";
ss << "\nServices:\n";
for (auto &myPair : m_servicesMap) { for (auto &myPair : m_servicesMap) {
ss << myPair.second->toString() << "\n"; res += myPair.second->toString() + "\n";
// myPair.second is the value // myPair.second is the value
} }
return ss.str(); return res;
} // toString } // toString

View File

@ -15,7 +15,7 @@
#include <string.h> #include <string.h>
#include <map> #include <map>
#include <string> #include <string>
#include "BLEExceptions.h" //#include "BLEExceptions.h"
#include "BLERemoteService.h" #include "BLERemoteService.h"
#include "BLEService.h" #include "BLEService.h"
#include "BLEAddress.h" #include "BLEAddress.h"

View File

@ -255,10 +255,10 @@ void BLEDescriptor::setAccessPermissions(esp_gatt_perm_t perm) {
* @return A string representation of the descriptor. * @return A string representation of the descriptor.
*/ */
std::string BLEDescriptor::toString() { std::string BLEDescriptor::toString() {
std::stringstream stringstream; char hex[5];
stringstream << std::hex << std::setfill('0'); snprintf(hex, sizeof(hex), "%04x", m_handle);
stringstream << "UUID: " << m_bleUUID.toString() + ", handle: 0x" << std::setw(2) << m_handle; std::string res = "UUID: " + m_bleUUID.toString() + ", handle: 0x" + hex;
return stringstream.str(); return res;
} // toString } // toString

View File

@ -90,17 +90,18 @@ void BLEDescriptorMap::setByHandle(uint16_t handle, BLEDescriptor* pDescriptor)
* @return A string representation of the descriptor map. * @return A string representation of the descriptor map.
*/ */
std::string BLEDescriptorMap::toString() { std::string BLEDescriptorMap::toString() {
std::stringstream stringStream; std::string res;
stringStream << std::hex << std::setfill('0'); char hex[5];
int count = 0; int count = 0;
for (auto &myPair : m_uuidMap) { for (auto &myPair : m_uuidMap) {
if (count > 0) { if (count > 0) {res += "\n";}
stringStream << "\n"; snprintf(hex, sizeof(hex), "%04x", myPair.first->getHandle());
}
count++; count++;
stringStream << "handle: 0x" << std::setw(2) << myPair.first->getHandle() << ", uuid: " + myPair.first->getUUID().toString(); res += "handle: 0x";
res += hex;
res += ", uuid: " + myPair.first->getUUID().toString();
} }
return stringStream.str(); return res;
} // toString } // toString

View File

@ -479,9 +479,8 @@ gatts_event_handler BLEDevice::m_customGattsHandler = nullptr;
* @return A string representation of the nature of this device. * @return A string representation of the nature of this device.
*/ */
/* STATIC */ std::string BLEDevice::toString() { /* STATIC */ std::string BLEDevice::toString() {
std::ostringstream oss; std::string res = "BD Address: " + getAddress().toString();
oss << "BD Address: " << getAddress().toString(); return res;
return oss.str();
} // toString } // toString

View File

@ -7,7 +7,7 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED) #if defined(CONFIG_BT_ENABLED)
#include <string.h> #include <string.h>
#include <sstream> #include <stdio.h>
#include "esp32-hal-log.h" #include "esp32-hal-log.h"
#include "BLEEddystoneTLM.h" #include "BLEEddystoneTLM.h"
@ -54,62 +54,44 @@ uint32_t BLEEddystoneTLM::getTime() {
} // getTime } // getTime
std::string BLEEddystoneTLM::toString() { std::string BLEEddystoneTLM::toString() {
std::stringstream ss; std::string out = "";
std::string out = ""; uint32_t rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil);
uint32_t rawsec; char val[6];
ss << "Version ";
ss << std::dec << m_eddystoneData.version;
ss << "\n";
ss << "Battery Voltage "; out += "Version " + m_eddystoneData.version;
ss << std::dec << ENDIAN_CHANGE_U16(m_eddystoneData.volt); out += "\n";
ss << " mV\n"; out += "Battery Voltage " + ENDIAN_CHANGE_U16(m_eddystoneData.volt);
out += " mV\n";
ss << "Temperature "; out += "Temperature ";
ss << (float) m_eddystoneData.temp; snprintf(val, sizeof(val), "%d", m_eddystoneData.temp);
ss << " °C\n"; out += val;
out += ".0 °C\n";
ss << "Adv. Count "; out += "Adv. Count ";
ss << std::dec << ENDIAN_CHANGE_U32(m_eddystoneData.advCount); snprintf(val, sizeof(val), "%d", ENDIAN_CHANGE_U32(m_eddystoneData.advCount));
out += val;
out += "\n";
ss << "\n"; out += "Time ";
ss << "Time "; snprintf(val, sizeof(val), "%04d", rawsec / 864000);
out += val;
out += ".";
rawsec = ENDIAN_CHANGE_U32(m_eddystoneData.tmil); snprintf(val, sizeof(val), "%02d", (rawsec / 36000) % 24);
std::stringstream buffstream; out += val;
buffstream << "0000"; out += ":";
buffstream << std::dec << rawsec / 864000;
std::string buff = buffstream.str();
ss << buff.substr(buff.length() - 4, buff.length()); snprintf(val, sizeof(val), "%02d", (rawsec / 600) % 60);
ss << "."; out += val;
out += ":";
buffstream.str(""); snprintf(val, sizeof(val), "%02d", (rawsec / 10) % 60);
buffstream.clear(); out += val;
buffstream << "00"; out += "\n";
buffstream << std::dec << (rawsec / 36000) % 24;
buff = buffstream.str();
ss << buff.substr(buff.length()-2, buff.length());
ss << ":";
buffstream.str(""); return out;
buffstream.clear();
buffstream << "00";
buffstream << std::dec << (rawsec / 600) % 60;
buff = buffstream.str();
ss << buff.substr(buff.length() - 2, buff.length());
ss << ":";
buffstream.str("");
buffstream.clear();
buffstream << "00";
buffstream << std::dec << (rawsec / 10) % 60;
buff = buffstream.str();
ss << buff.substr(buff.length() - 2, buff.length());
ss << "\n";
return ss.str();
} // toString } // toString
/** /**

View File

@ -5,5 +5,5 @@
* Author: kolban * Author: kolban
*/ */
#include "BLEExceptions.h" //#include "BLEExceptions.h"

View File

@ -14,7 +14,7 @@
#include <esp_err.h> #include <esp_err.h>
#include <sstream> #include <sstream>
#include "BLEExceptions.h" //#include "BLEExceptions.h"
#include "BLEUtils.h" #include "BLEUtils.h"
#include "GeneralUtils.h" #include "GeneralUtils.h"
#include "BLERemoteDescriptor.h" #include "BLERemoteDescriptor.h"
@ -39,6 +39,7 @@ BLERemoteCharacteristic::BLERemoteCharacteristic(
m_charProp = charProp; m_charProp = charProp;
m_pRemoteService = pRemoteService; m_pRemoteService = pRemoteService;
m_notifyCallback = nullptr; m_notifyCallback = nullptr;
m_rawData = nullptr;
retrieveDescriptors(); // Get the descriptors for this characteristic retrieveDescriptors(); // Get the descriptors for this characteristic
log_v("<< BLERemoteCharacteristic"); log_v("<< BLERemoteCharacteristic");
@ -399,7 +400,7 @@ std::string BLERemoteCharacteristic::readValue() {
// Check to see that we are connected. // Check to see that we are connected.
if (!getRemoteService()->getClient()->isConnected()) { if (!getRemoteService()->getClient()->isConnected()) {
log_e("Disconnected"); log_e("Disconnected");
throw BLEDisconnectedException(); return std::string();
} }
m_semaphoreReadCharEvt.take("readValue"); m_semaphoreReadCharEvt.take("readValue");
@ -500,11 +501,16 @@ void BLERemoteCharacteristic::removeDescriptors() {
* @return a String representation. * @return a String representation.
*/ */
std::string BLERemoteCharacteristic::toString() { std::string BLERemoteCharacteristic::toString() {
std::ostringstream ss; std::string res = "Characteristic: uuid: " + m_uuid.toString();
ss << "Characteristic: uuid: " << m_uuid.toString() << char val[6];
", handle: " << getHandle() << " 0x" << std::hex << getHandle() << res += ", handle: ";
", props: " << BLEUtils::characteristicPropertiesToString(m_charProp); snprintf(val, sizeof(val), "%d", getHandle());
return ss.str(); res += val;
res += " 0x";
snprintf(val, sizeof(val), "%04x", getHandle());
res += val;
res += ", props: " + BLEUtils::characteristicPropertiesToString(m_charProp);
return res;
} // toString } // toString
@ -545,7 +551,7 @@ void BLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool resp
// Check to see that we are connected. // Check to see that we are connected.
if (!getRemoteService()->getClient()->isConnected()) { if (!getRemoteService()->getClient()->isConnected()) {
log_e("Disconnected"); log_e("Disconnected");
throw BLEDisconnectedException(); return;
} }
m_semaphoreWriteCharEvt.take("writeValue"); m_semaphoreWriteCharEvt.take("writeValue");

View File

@ -55,7 +55,7 @@ std::string BLERemoteDescriptor::readValue() {
// Check to see that we are connected. // Check to see that we are connected.
if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) { if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) {
log_e("Disconnected"); log_e("Disconnected");
throw BLEDisconnectedException(); return std::string();
} }
m_semaphoreReadDescrEvt.take("readValue"); m_semaphoreReadDescrEvt.take("readValue");
@ -113,9 +113,12 @@ uint32_t BLERemoteDescriptor::readUInt32() {
* @retun A string representation of this BLE Remote Descriptor. * @retun A string representation of this BLE Remote Descriptor.
*/ */
std::string BLERemoteDescriptor::toString() { std::string BLERemoteDescriptor::toString() {
std::stringstream ss; char val[6];
ss << "handle: " << getHandle() << ", uuid: " << getUUID().toString(); snprintf(val, sizeof(val), "%d", getHandle());
return ss.str(); std::string res = "handle: ";
res += val;
res += ", uuid: " + getUUID().toString();
return res;
} // toString } // toString
@ -130,7 +133,7 @@ void BLERemoteDescriptor::writeValue(uint8_t* data, size_t length, bool response
// Check to see that we are connected. // Check to see that we are connected.
if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) { if (!getRemoteCharacteristic()->getRemoteService()->getClient()->isConnected()) {
log_e("Disconnected"); log_e("Disconnected");
throw BLEDisconnectedException(); return;
} }
esp_err_t errRc = ::esp_ble_gattc_write_char_descr( esp_err_t errRc = ::esp_ble_gattc_write_char_descr(

View File

@ -14,6 +14,8 @@
#include <esp_err.h> #include <esp_err.h>
#include "esp32-hal-log.h" #include "esp32-hal-log.h"
#pragma GCC diagnostic warning "-Wunused-but-set-parameter"
BLERemoteService::BLERemoteService( BLERemoteService::BLERemoteService(
esp_gatt_id_t srvcId, esp_gatt_id_t srvcId,
BLEClient* pClient, BLEClient* pClient,
@ -164,7 +166,7 @@ void BLERemoteService::retrieveCharacteristics() {
uint16_t offset = 0; uint16_t offset = 0;
esp_gattc_char_elem_t result; esp_gattc_char_elem_t result;
while (true) { while (true) {
uint16_t count = 10; // this value is used as in parameter that allows to search max 10 chars with the same uuid uint16_t count = 1; // only room for 1 result allocated, so go one by one
esp_gatt_status_t status = ::esp_ble_gattc_get_all_char( esp_gatt_status_t status = ::esp_ble_gattc_get_all_char(
getClient()->getGattcIf(), getClient()->getGattcIf(),
getClient()->getConnId(), getClient()->getConnId(),
@ -228,7 +230,6 @@ std::map<std::string, BLERemoteCharacteristic*>* BLERemoteService::getCharacteri
* @brief This function is designed to get characteristics map when we have multiple characteristics with the same UUID * @brief This function is designed to get characteristics map when we have multiple characteristics with the same UUID
*/ */
void BLERemoteService::getCharacteristics(std::map<uint16_t, BLERemoteCharacteristic*>* pCharacteristicMap) { void BLERemoteService::getCharacteristics(std::map<uint16_t, BLERemoteCharacteristic*>* pCharacteristicMap) {
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
pCharacteristicMap = &m_characteristicMapByHandle; pCharacteristicMap = &m_characteristicMapByHandle;
} // Get the characteristics map. } // Get the characteristics map.
@ -317,15 +318,25 @@ void BLERemoteService::setValue(BLEUUID characteristicUuid, std::string value) {
* @return A string representation of this remote service. * @return A string representation of this remote service.
*/ */
std::string BLERemoteService::toString() { std::string BLERemoteService::toString() {
std::ostringstream ss; std::string res = "Service: uuid: " + m_uuid.toString();
ss << "Service: uuid: " + m_uuid.toString(); char val[6];
ss << ", start_handle: " << std::dec << m_startHandle << " 0x" << std::hex << m_startHandle << res += ", start_handle: ";
", end_handle: " << std::dec << m_endHandle << " 0x" << std::hex << m_endHandle; snprintf(val, sizeof(val), "%d", m_startHandle);
res += val;
snprintf(val, sizeof(val), "%04x", m_startHandle);
res += " 0x";
res += val;
res += ", end_handle: ";
snprintf(val, sizeof(val), "%d", m_endHandle);
res += val;
snprintf(val, sizeof(val), "%04x", m_endHandle);
res += " 0x";
res += val;
for (auto &myPair : m_characteristicMap) { for (auto &myPair : m_characteristicMap) {
ss << "\n" << myPair.second->toString(); res += "\n" + myPair.second->toString();
// myPair.second is the value // myPair.second is the value
} }
return ss.str(); return res;
} // toString } // toString

View File

@ -412,4 +412,9 @@ void BLEServer::updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval,
conn_params.timeout = timeout; // timeout = 400*10ms = 4000ms conn_params.timeout = timeout; // timeout = 400*10ms = 4000ms
esp_ble_gap_update_conn_params(&conn_params); esp_ble_gap_update_conn_params(&conn_params);
} }
void BLEServer::disconnect(uint16_t connId) {
esp_ble_gatts_close(m_gatts_if, connId);
}
#endif // CONFIG_BT_ENABLED #endif // CONFIG_BT_ENABLED

View File

@ -72,6 +72,7 @@ public:
BLEService* getServiceByUUID(const char* uuid); BLEService* getServiceByUUID(const char* uuid);
BLEService* getServiceByUUID(BLEUUID uuid); BLEService* getServiceByUUID(BLEUUID uuid);
bool connect(BLEAddress address); bool connect(BLEAddress address);
void disconnect(uint16_t connId);
uint16_t m_appId; uint16_t m_appId;
void updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout); void updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout);

View File

@ -381,10 +381,12 @@ BLECharacteristic* BLEService::getCharacteristic(BLEUUID uuid) {
* @return A string representation of this service. * @return A string representation of this service.
*/ */
std::string BLEService::toString() { std::string BLEService::toString() {
std::stringstream stringStream; std::string res = "UUID: " + getUUID().toString();
stringStream << "UUID: " << getUUID().toString() << char hex[5];
", handle: 0x" << std::hex << std::setfill('0') << std::setw(2) << getHandle(); snprintf(hex, sizeof(hex), "%04x", getHandle());
return stringStream.str(); res += ", handle: 0x";
res += hex;
return res;
} // toString } // toString

View File

@ -6,7 +6,7 @@
*/ */
#include "sdkconfig.h" #include "sdkconfig.h"
#if defined(CONFIG_BT_ENABLED) #if defined(CONFIG_BT_ENABLED)
#include <sstream> #include <stdio.h>
#include <iomanip> #include <iomanip>
#include "BLEService.h" #include "BLEService.h"
@ -73,12 +73,15 @@ void BLEServiceMap::setByHandle(uint16_t handle, BLEService* service) {
* @return A string representation of the service map. * @return A string representation of the service map.
*/ */
std::string BLEServiceMap::toString() { std::string BLEServiceMap::toString() {
std::stringstream stringStream; std::string res;
stringStream << std::hex << std::setfill('0'); char hex[5];
for (auto &myPair: m_handleMap) { for (auto &myPair: m_handleMap) {
stringStream << "handle: 0x" << std::setw(2) << myPair.first << ", uuid: " + myPair.second->getUUID().toString() << "\n"; res += "handle: 0x";
snprintf(hex, sizeof(hex), "%04x", myPair.first);
res += hex;
res += ", uuid: " + myPair.second->getUUID().toString() + "\n";
} }
return stringStream.str(); return res;
} // toString } // toString
void BLEServiceMap::handleGATTServerEvent( void BLEServiceMap::handleGATTServerEvent(

View File

@ -349,51 +349,38 @@ BLEUUID BLEUUID::to128() {
*/ */
std::string BLEUUID::toString() { std::string BLEUUID::toString() {
if (!m_valueSet) return "<NULL>"; // If we have no value, nothing to format. if (!m_valueSet) return "<NULL>"; // If we have no value, nothing to format.
// If the UUIDs are 16 or 32 bit, pad correctly. // If the UUIDs are 16 or 32 bit, pad correctly.
std::stringstream ss;
if (m_uuid.len == ESP_UUID_LEN_16) { // If the UUID is 16bit, pad correctly. if (m_uuid.len == ESP_UUID_LEN_16) { // If the UUID is 16bit, pad correctly.
ss << "0000" << char hex[5];
std::hex << snprintf(hex, sizeof(hex), "%04x", m_uuid.uuid.uuid16);
std::setfill('0') << return std::string(hex) + "-0000-1000-8000-00805f9b34fb";
std::setw(4) <<
m_uuid.uuid.uuid16 <<
"-0000-1000-8000-00805f9b34fb";
return ss.str(); // Return the string
} // End 16bit UUID } // End 16bit UUID
if (m_uuid.len == ESP_UUID_LEN_32) { // If the UUID is 32bit, pad correctly. if (m_uuid.len == ESP_UUID_LEN_32) { // If the UUID is 32bit, pad correctly.
ss << std::hex << char hex[9];
std::setfill('0') << snprintf(hex, sizeof(hex), "%08x", m_uuid.uuid.uuid32);
std::setw(8) << return std::string(hex) + "-0000-1000-8000-00805f9b34fb";
m_uuid.uuid.uuid32 <<
"-0000-1000-8000-00805f9b34fb";
return ss.str(); // return the string
} // End 32bit UUID } // End 32bit UUID
// The UUID is not 16bit or 32bit which means that it is 128bit. // The UUID is not 16bit or 32bit which means that it is 128bit.
// //
// UUID string format: // UUID string format:
// AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP // AABBCCDD-EEFF-GGHH-IIJJ-KKLLMMNNOOPP
ss << std::hex << std::setfill('0') << auto size = 35;
std::setw(2) << (int) m_uuid.uuid.uuid128[15] << char *hex = (char *)malloc(size);
std::setw(2) << (int) m_uuid.uuid.uuid128[14] << snprintf(hex, size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
std::setw(2) << (int) m_uuid.uuid.uuid128[13] << m_uuid.uuid.uuid128[15], m_uuid.uuid.uuid128[14],
std::setw(2) << (int) m_uuid.uuid.uuid128[12] << "-" << m_uuid.uuid.uuid128[13], m_uuid.uuid.uuid128[12],
std::setw(2) << (int) m_uuid.uuid.uuid128[11] << m_uuid.uuid.uuid128[11], m_uuid.uuid.uuid128[10],
std::setw(2) << (int) m_uuid.uuid.uuid128[10] << "-" << m_uuid.uuid.uuid128[9], m_uuid.uuid.uuid128[8],
std::setw(2) << (int) m_uuid.uuid.uuid128[9] << m_uuid.uuid.uuid128[7], m_uuid.uuid.uuid128[6],
std::setw(2) << (int) m_uuid.uuid.uuid128[8] << "-" << m_uuid.uuid.uuid128[5], m_uuid.uuid.uuid128[4],
std::setw(2) << (int) m_uuid.uuid.uuid128[7] << m_uuid.uuid.uuid128[3], m_uuid.uuid.uuid128[2],
std::setw(2) << (int) m_uuid.uuid.uuid128[6] << "-" << m_uuid.uuid.uuid128[1], m_uuid.uuid.uuid128[0]);
std::setw(2) << (int) m_uuid.uuid.uuid128[5] << std::string res(hex);
std::setw(2) << (int) m_uuid.uuid.uuid128[4] << free(hex);
std::setw(2) << (int) m_uuid.uuid.uuid128[3] << return res;
std::setw(2) << (int) m_uuid.uuid.uuid128[2] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[1] <<
std::setw(2) << (int) m_uuid.uuid.uuid128[0];
return ss.str();
} // toString } // toString
#endif /* CONFIG_BT_ENABLED */ #endif /* CONFIG_BT_ENABLED */

View File

@ -604,26 +604,32 @@ static const gattService_t g_gattServices[] = {
* @return A string representation of characteristic properties. * @return A string representation of characteristic properties.
*/ */
std::string BLEUtils::characteristicPropertiesToString(esp_gatt_char_prop_t prop) { std::string BLEUtils::characteristicPropertiesToString(esp_gatt_char_prop_t prop) {
std::stringstream stream; std::string res = "broadcast: ";
stream << res += ((prop & ESP_GATT_CHAR_PROP_BIT_BROADCAST)?"1":"0");
"broadcast: " << ((prop & ESP_GATT_CHAR_PROP_BIT_BROADCAST)?"1":"0") << res += ", read: ";
", read: " << ((prop & ESP_GATT_CHAR_PROP_BIT_READ)?"1":"0") << res += ((prop & ESP_GATT_CHAR_PROP_BIT_READ)?"1":"0");
", write_nr: " << ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE_NR)?"1":"0") << res += ", write_nr: ";
", write: " << ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE)?"1":"0") << res += ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE_NR)?"1":"0");
", notify: " << ((prop & ESP_GATT_CHAR_PROP_BIT_NOTIFY)?"1":"0") << res += ", write: ";
", indicate: " << ((prop & ESP_GATT_CHAR_PROP_BIT_INDICATE)?"1":"0") << res += ((prop & ESP_GATT_CHAR_PROP_BIT_WRITE)?"1":"0");
", auth: " << ((prop & ESP_GATT_CHAR_PROP_BIT_AUTH)?"1":"0"); res += ", notify: ";
return stream.str(); res += ((prop & ESP_GATT_CHAR_PROP_BIT_NOTIFY)?"1":"0");
res += ", indicate: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_INDICATE)?"1":"0");
res += ", auth: ";
res += ((prop & ESP_GATT_CHAR_PROP_BIT_AUTH)?"1":"0");
return res;
} // characteristicPropertiesToString } // characteristicPropertiesToString
/** /**
* @brief Convert an esp_gatt_id_t to a string. * @brief Convert an esp_gatt_id_t to a string.
*/ */
static std::string gattIdToString(esp_gatt_id_t gattId) { static std::string gattIdToString(esp_gatt_id_t gattId) {
std::stringstream stream; std::string res = "uuid: " + BLEUUID(gattId.uuid).toString() + ", inst_id: ";
stream << "uuid: " << BLEUUID(gattId.uuid).toString() << ", inst_id: " << (int)gattId.inst_id; char val[8];
//sprintf(buffer, "uuid: %s, inst_id: %d", uuidToString(gattId.uuid).c_str(), gattId.inst_id); snprintf(val, sizeof(val), "%d", (int)gattId.inst_id);
return stream.str(); res += val;
return res;
} // gattIdToString } // gattIdToString
@ -654,23 +660,23 @@ const char* BLEUtils::addressTypeToString(esp_ble_addr_type_t type) {
* @return std::string A string representation of the advertising flags. * @return std::string A string representation of the advertising flags.
*/ */
std::string BLEUtils::adFlagsToString(uint8_t adFlags) { std::string BLEUtils::adFlagsToString(uint8_t adFlags) {
std::stringstream ss; std::string res;
if (adFlags & (1 << 0)) { if (adFlags & (1 << 0)) {
ss << "[LE Limited Discoverable Mode] "; res += "[LE Limited Discoverable Mode] ";
} }
if (adFlags & (1 << 1)) { if (adFlags & (1 << 1)) {
ss << "[LE General Discoverable Mode] "; res += "[LE General Discoverable Mode] ";
} }
if (adFlags & (1 << 2)) { if (adFlags & (1 << 2)) {
ss << "[BR/EDR Not Supported] "; res += "[BR/EDR Not Supported] ";
} }
if (adFlags & (1 << 3)) { if (adFlags & (1 << 3)) {
ss << "[Simultaneous LE and BR/EDR to Same Device Capable (Controller)] "; res += "[Simultaneous LE and BR/EDR to Same Device Capable (Controller)] ";
} }
if (adFlags & (1 << 4)) { if (adFlags & (1 << 4)) {
ss << "[Simultaneous LE and BR/EDR to Same Device Capable (Host)] "; res += "[Simultaneous LE and BR/EDR to Same Device Capable (Host)] ";
} }
return ss.str(); return res;
} // adFlagsToString } // adFlagsToString
@ -802,13 +808,13 @@ char* BLEUtils::buildHexData(uint8_t* target, uint8_t* source, uint8_t length) {
* @return A string representation of a piece of memory. * @return A string representation of a piece of memory.
*/ */
std::string BLEUtils::buildPrintData(uint8_t* source, size_t length) { std::string BLEUtils::buildPrintData(uint8_t* source, size_t length) {
std::ostringstream ss; std::string res;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
char c = *source; char c = *source;
ss << (isprint(c) ? c : '.'); res += (isprint(c) ? c : '.');
source++; source++;
} }
return ss.str(); return res;
} // buildPrintData } // buildPrintData
@ -1848,14 +1854,22 @@ std::string BLEUtils::gattDescriptorUUIDToString(uint32_t descriptorUUID) {
* @return A string representation of an esp_gattc_service_elem_t. * @return A string representation of an esp_gattc_service_elem_t.
*/ */
std::string BLEUtils::gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement) { std::string BLEUtils::gattcServiceElementToString(esp_gattc_service_elem_t* pGATTCServiceElement) {
std::stringstream ss; std::string res;
char val[6];
ss << "[uuid: " << BLEUUID(pGATTCServiceElement->uuid).toString() << res += "[uuid: " + BLEUUID(pGATTCServiceElement->uuid).toString() + ", start_handle: ";
", start_handle: " << pGATTCServiceElement->start_handle << snprintf(val, sizeof(val), "%d", pGATTCServiceElement->start_handle);
" 0x" << std::hex << pGATTCServiceElement->start_handle << res += val;
", end_handle: " << std::dec << pGATTCServiceElement->end_handle << res += " 0x";
" 0x" << std::hex << pGATTCServiceElement->end_handle << "]"; snprintf(val, sizeof(val), "%04x", pGATTCServiceElement->start_handle);
return ss.str(); res += val;
res += ", end_handle: ";
snprintf(val, sizeof(val), "%d", pGATTCServiceElement->end_handle);
res += val;
res += " 0x";
snprintf(val, sizeof(val), "%04x", pGATTCServiceElement->end_handle);
res += val;
res += "]";
return res;
} // gattcServiceElementToString } // gattcServiceElementToString

View File

@ -78,6 +78,38 @@ uint32_t FreeRTOS::Semaphore::wait(std::string owner) {
return m_value; return m_value;
} // wait } // wait
/**
* @brief Wait for a semaphore to be released in a given period of time by trying to take it and
* then releasing it again. The value associated with the semaphore can be taken by value() call after return
* @param [in] owner A debug tag.
* @param [in] timeoutMs timeout to wait in ms.
* @return True if we took the semaphore within timeframe.
*/
bool FreeRTOS::Semaphore::timedWait(std::string owner, uint32_t timeoutMs) {
log_v(">> wait: Semaphore waiting: %s for %s", toString().c_str(), owner.c_str());
if (m_usePthreads && timeoutMs != portMAX_DELAY) {
assert(false); // We apparently don't have a timed wait for pthreads.
}
auto ret = pdTRUE;
if (m_usePthreads) {
pthread_mutex_lock(&m_pthread_mutex);
} else {
ret = xSemaphoreTake(m_semaphore, timeoutMs);
}
if (m_usePthreads) {
pthread_mutex_unlock(&m_pthread_mutex);
} else {
xSemaphoreGive(m_semaphore);
}
log_v("<< wait: Semaphore %s released: %d", toString().c_str(), ret);
return ret;
} // wait
FreeRTOS::Semaphore::Semaphore(std::string name) { FreeRTOS::Semaphore::Semaphore(std::string name) {
m_usePthreads = false; // Are we using pThreads or FreeRTOS? m_usePthreads = false; // Are we using pThreads or FreeRTOS?
@ -202,9 +234,12 @@ bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) {
* @return A string representation of the semaphore. * @return A string representation of the semaphore.
*/ */
std::string FreeRTOS::Semaphore::toString() { std::string FreeRTOS::Semaphore::toString() {
std::stringstream stringStream; char hex[9];
stringStream << "name: "<< m_name << " (0x" << std::hex << std::setfill('0') << (uint32_t)m_semaphore << "), owner: " << m_owner; std::string res = "name: " + m_name + " (0x";
return stringStream.str(); snprintf(hex, sizeof(hex), "%08x", (uint32_t)m_semaphore);
res += hex;
res += "), owner: " + m_owner;
return res;
} // toString } // toString

View File

@ -40,6 +40,8 @@ public:
bool take(uint32_t timeoutMs, std::string owner = "<Unknown>"); bool take(uint32_t timeoutMs, std::string owner = "<Unknown>");
std::string toString(); std::string toString();
uint32_t wait(std::string owner = "<Unknown>"); uint32_t wait(std::string owner = "<Unknown>");
bool timedWait(std::string owner = "<Unknown>", uint32_t timeoutMs = portMAX_DELAY);
uint32_t value(){ return m_value; };
private: private:
SemaphoreHandle_t m_semaphore; SemaphoreHandle_t m_semaphore;

View File

@ -332,9 +332,12 @@ void GeneralUtils::hexDump(const uint8_t* pData, uint32_t length) {
* @return A string representation of the IP address. * @return A string representation of the IP address.
*/ */
std::string GeneralUtils::ipToString(uint8_t *ip) { std::string GeneralUtils::ipToString(uint8_t *ip) {
std::stringstream s; auto size = 16;
s << (int) ip[0] << '.' << (int) ip[1] << '.' << (int) ip[2] << '.' << (int) ip[3]; char *val = (char*)malloc(size);
return s.str(); snprintf(val, size, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
std::string res(val);
free(val);
return res;
} // ipToString } // ipToString
@ -347,11 +350,14 @@ std::string GeneralUtils::ipToString(uint8_t *ip) {
std::vector<std::string> GeneralUtils::split(std::string source, char delimiter) { std::vector<std::string> GeneralUtils::split(std::string source, char delimiter) {
// See also: https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g // See also: https://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g
std::vector<std::string> strings; std::vector<std::string> strings;
std::istringstream iss(source); std::size_t current, previous = 0;
std::string s; current = source.find(delimiter);
while (std::getline(iss, s, delimiter)) { while (current != std::string::npos) {
strings.push_back(trim(s)); strings.push_back(trim(source.substr(previous, current - previous)));
previous = current + 1;
current = source.find(delimiter, previous);
} }
strings.push_back(trim(source.substr(previous, current - previous)));
return strings; return strings;
} // split } // split

View File

@ -1,37 +1,21 @@
/* /*
ESP32 eeprom_class example with EEPROM library ESP32 eeprom_class example with EEPROM library
This simple example demonstrates using EEPROM library to store different data in This simple example demonstrates using EEPROM library to store different data in
ESP32 Flash memory in a multiple user-defined EEPROM partition (0x1000 or 4KB max size or less). ESP32 Flash memory in a multiple user-defined EEPROM class objects.
Install 'ESP32 Partiton Manager' ONCE from https://github.com/francis94c/ESP32Partitions
And generate different partitions with 'partition_name'
Usage: EEPROMClass ANY_OBJECT_NAME("partition_name", size);
Generated partition that would work perfectly with this example
#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,
eeprom0, data, 0x99, 0x290000, 0x1000,
eeprom1, data, 0x9a, 0x291000, 0x500,
eeprom2, data, 0x9b, 0x292000, 0x100,
spiffs, data, spiffs, 0x293000, 0x16d000,
Created for arduino-esp32 on 25 Dec, 2017 Created for arduino-esp32 on 25 Dec, 2017
by Elochukwu Ifediora (fedy0) by Elochukwu Ifediora (fedy0)
converted to nvs by lbernstone - 06/22/2019
*/ */
#include "EEPROM.h" #include "EEPROM.h"
// Instantiate eeprom objects with parameter/argument names and size same as in the partition table // Instantiate eeprom objects with parameter/argument names and sizes
EEPROMClass NAMES("eeprom0", 0x500); EEPROMClass NAMES("eeprom0", 0x500);
EEPROMClass HEIGHT("eeprom1", 0x200); EEPROMClass HEIGHT("eeprom1", 0x200);
EEPROMClass AGE("eeprom2", 0x100); EEPROMClass AGE("eeprom2", 0x100);
void setup() { void setup() {
// put your setup code here, to run once:
Serial.begin(115200); Serial.begin(115200);
Serial.println("Testing EEPROMClass\n"); Serial.println("Testing EEPROMClass\n");
if (!NAMES.begin(NAMES.length())) { if (!NAMES.begin(NAMES.length())) {
@ -57,7 +41,7 @@ void setup() {
double height = 5.8; double height = 5.8;
uint32_t age = 47; uint32_t age = 47;
// Write: Variables ---> EEPROM partitions // Write: Variables ---> EEPROM stores
NAMES.put(0, name); NAMES.put(0, name);
HEIGHT.put(0, height); HEIGHT.put(0, height);
AGE.put(0, age); AGE.put(0, age);
@ -75,7 +59,7 @@ void setup() {
Serial.print("age: "); Serial.println(age); Serial.print("age: "); Serial.println(age);
Serial.println("------------------------------------\n"); Serial.println("------------------------------------\n");
// Read: Variables <--- EEPROM partitions // Read: Variables <--- EEPROM stores
NAMES.get(0, name); NAMES.get(0, name);
HEIGHT.get(0, height); HEIGHT.get(0, height);
AGE.get(0, age); AGE.get(0, age);
@ -87,6 +71,5 @@ void setup() {
} }
void loop() { void loop() {
// put your main code here, to run repeatedly: delay(0xFFFFFFFF);
} }

View File

@ -1,9 +1,9 @@
name=EEPROM name=EEPROM
version=1.0 version=1.0.3
author=Ivan Grokhotkov author=Ivan Grokhotkov
maintainer=Paolo Becchi <pbecchi@aerobusiness.it> maintainer=Paolo Becchi <pbecchi@aerobusiness.it>
sentence=Enables reading and writing data to the permanent FLASH storage, up to 4kb. sentence=Enables reading and writing data a sequential, addressable FLASH storage
paragraph= paragraph=
category=Data Storage category=Data Storage
url=http://arduino.cc/en/Reference/EEPROM url=http://arduino.cc/en/Reference/EEPROM
architectures=esp32 architectures=esp32

View File

@ -25,6 +25,7 @@
#include "EEPROM.h" #include "EEPROM.h"
#include <nvs.h> #include <nvs.h>
#include <esp_partition.h>
#include <esp_log.h> #include <esp_log.h>
EEPROMClass::EEPROMClass(void) EEPROMClass::EEPROMClass(void)
@ -111,7 +112,7 @@ bool EEPROMClass::begin(size_t size) {
log_e("Not enough memory to expand EEPROM!"); log_e("Not enough memory to expand EEPROM!");
return false; return false;
} }
memset(key_data, 0, size); memset(key_data, 0xFF, size);
if(key_size) { if(key_size) {
log_i("Expanding EEPROM from %d to %d", key_size, size); log_i("Expanding EEPROM from %d to %d", key_size, size);
// hold data while key is deleted // hold data while key is deleted
@ -214,6 +215,67 @@ uint16_t EEPROMClass::length ()
return _user_defined_size; return _user_defined_size;
} }
/*
Convert EEPROM partition into nvs blob
Call convert before you call begin
*/
uint16_t EEPROMClass::convert (bool clear, const char* EEPROMname, const char* nvsname)
{
uint16_t result = 0;
const esp_partition_t* mypart = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, EEPROMname);
if (mypart == NULL) {
log_i("EEPROM partition not found for conversion");
return result;
}
size_t size = mypart->size;
uint8_t* data = (uint8_t*) malloc(size);
if (!data) {
log_e("Not enough memory to convert EEPROM!");
goto exit;
}
if (esp_partition_read (mypart, 0, (void *) data, size) != ESP_OK) {
log_e("Unable to read EEPROM partition");
goto exit;
}
bool empty;
empty = true;
for (int x=0; x<size; x++) {
if (data[x] != 0xFF) {
empty = false;
break;
}
}
if (empty) {
log_i("EEPROM partition is empty, will not convert");
goto exit;
}
nvs_handle handle;
if (nvs_open(nvsname, NVS_READWRITE, &handle) != ESP_OK) {
log_e("Unable to open NVS");
goto exit;
}
esp_err_t err;
err = nvs_set_blob(handle, nvsname, data, size);
if (err != ESP_OK) {
log_e("Unable to add EEPROM data to NVS: %s", esp_err_to_name(err));
goto exit;
}
result = size;
if (clear) {
if (esp_partition_erase_range (mypart, 0, size) != ESP_OK) {
log_w("Unable to clear EEPROM partition");
}
}
exit:
free(data);
return result;
}
/* /*
Read 'value' from 'address' Read 'value' from 'address'
*/ */

View File

@ -47,6 +47,7 @@ class EEPROMClass {
void end(); void end();
uint8_t * getDataPtr(); uint8_t * getDataPtr();
uint16_t convert(bool clear, const char* EEPROMname = "eeprom", const char* nvsname = "eeprom");
template<typename T> template<typename T>
T &get(int address, T &t) { T &get(int address, T &t) {

View File

@ -19,7 +19,7 @@ Author:
Pranav Cherukupalli <cherukupallip@gmail.com> Pranav Cherukupalli <cherukupallip@gmail.com>
*/ */
#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */ #define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */ #define TIME_TO_SLEEP 5 /* Time ESP32 will go to sleep (in seconds) */
RTC_DATA_ATTR int bootCount = 0; RTC_DATA_ATTR int bootCount = 0;

View File

@ -62,7 +62,7 @@ void loop()
for (led=0; led<NR_OF_LEDS; led++) { for (led=0; led<NR_OF_LEDS; led++) {
for (col=0; col<3; col++ ) { for (col=0; col<3; col++ ) {
for (bit=0; bit<8; bit++){ for (bit=0; bit<8; bit++){
if ( (color[col] & (1<<(8-bit))) && (led == led_index) ) { if ( (color[col] & (1<<(7-bit))) && (led == led_index) ) {
led_data[i].level0 = 1; led_data[i].level0 = 1;
led_data[i].duration0 = 8; led_data[i].duration0 = 8;
led_data[i].level1 = 0; led_data[i].level1 = 0;

View File

@ -96,7 +96,6 @@ void loop(void)
req = req.substring(addr_start + 1, addr_end); req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: "); Serial.print("Request: ");
Serial.println(req); Serial.println(req);
client.flush();
String s; String s;
if (req == "/") if (req == "/")
@ -115,6 +114,7 @@ void loop(void)
} }
client.print(s); client.print(s);
client.stop();
Serial.println("Done with client"); Serial.println("Done with client");
} }

View File

@ -68,7 +68,7 @@ void F_Fat::end()
log_e("Unmounting FFat partition failed! Error: %d", err); log_e("Unmounting FFat partition failed! Error: %d", err);
return; return;
} }
_wl_handle = NULL; _wl_handle = 0;
_impl->mountpoint(NULL); _impl->mountpoint(NULL);
} }
} }
@ -109,7 +109,9 @@ size_t F_Fat::totalBytes()
BYTE pdrv = ff_diskio_get_pdrv_wl(_wl_handle); BYTE pdrv = ff_diskio_get_pdrv_wl(_wl_handle);
char drv[3] = {(char)(48+pdrv), ':', 0}; char drv[3] = {(char)(48+pdrv), ':', 0};
FRESULT res = f_getfree(drv, &free_clust, &fs); if ( f_getfree(drv, &free_clust, &fs) != FR_OK){
return 0;
}
tot_sect = (fs->n_fatent - 2) * fs->csize; tot_sect = (fs->n_fatent - 2) * fs->csize;
sect_size = CONFIG_WL_SECTOR_SIZE; sect_size = CONFIG_WL_SECTOR_SIZE;
return tot_sect * sect_size; return tot_sect * sect_size;
@ -123,7 +125,9 @@ size_t F_Fat::freeBytes()
BYTE pdrv = ff_diskio_get_pdrv_wl(_wl_handle); BYTE pdrv = ff_diskio_get_pdrv_wl(_wl_handle);
char drv[3] = {(char)(48+pdrv), ':', 0}; char drv[3] = {(char)(48+pdrv), ':', 0};
FRESULT res = f_getfree(drv, &free_clust, &fs); if ( f_getfree(drv, &free_clust, &fs) != FR_OK){
return 0;
}
free_sect = free_clust * fs->csize; free_sect = free_clust * fs->csize;
sect_size = CONFIG_WL_SECTOR_SIZE; sect_size = CONFIG_WL_SECTOR_SIZE;
return free_sect * sect_size; return free_sect * sect_size;

View File

@ -1,3 +1,4 @@
#include <HardwareSerial.h>
/** /**
* HTTPClient.cpp * HTTPClient.cpp
* *
@ -195,6 +196,11 @@ bool HTTPClient::begin(String url, const char* CAcert)
} }
_secure = true; _secure = true;
_transportTraits = TransportTraitsPtr(new TLSTraits(CAcert)); _transportTraits = TransportTraitsPtr(new TLSTraits(CAcert));
if(!_transportTraits) {
log_e("could not create transport traits");
return false;
}
return true; return true;
} }
@ -215,6 +221,11 @@ bool HTTPClient::begin(String url)
return begin(url, (const char*)NULL); return begin(url, (const char*)NULL);
} }
_transportTraits = TransportTraitsPtr(new TransportTraits()); _transportTraits = TransportTraitsPtr(new TransportTraits());
if(!_transportTraits) {
log_e("could not create transport traits");
return false;
}
return true; return true;
} }
#endif // HTTPCLIENT_1_1_COMPATIBLE #endif // HTTPCLIENT_1_1_COMPATIBLE
@ -333,7 +344,8 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, const char* CAcer
*/ */
void HTTPClient::end(void) void HTTPClient::end(void)
{ {
disconnect(); disconnect(false);
clear();
} }
@ -342,7 +354,7 @@ void HTTPClient::end(void)
* disconnect * disconnect
* close the TCP socket * close the TCP socket
*/ */
void HTTPClient::disconnect() void HTTPClient::disconnect(bool preserveClient)
{ {
if(connected()) { if(connected()) {
if(_client->available() > 0) { if(_client->available() > 0) {
@ -357,7 +369,9 @@ void HTTPClient::disconnect()
} else { } else {
log_d("tcp stop\n"); log_d("tcp stop\n");
_client->stop(); _client->stop();
_client = nullptr; if(!preserveClient) {
_client = nullptr;
}
#ifdef HTTPCLIENT_1_1_COMPATIBLE #ifdef HTTPCLIENT_1_1_COMPATIBLE
if(_tcpDeprecated) { if(_tcpDeprecated) {
_transportTraits.reset(nullptr); _transportTraits.reset(nullptr);
@ -456,6 +470,7 @@ void HTTPClient::setTimeout(uint16_t timeout)
void HTTPClient::useHTTP10(bool useHTTP10) void HTTPClient::useHTTP10(bool useHTTP10)
{ {
_useHTTP10 = useHTTP10; _useHTTP10 = useHTTP10;
_reuse = !useHTTP10;
} }
/** /**
@ -816,7 +831,8 @@ int HTTPClient::writeToStream(Stream * stream)
return returnError(HTTPC_ERROR_ENCODING); return returnError(HTTPC_ERROR_ENCODING);
} }
end(); // end();
disconnect(true);
return ret; return ret;
} }
@ -970,9 +986,12 @@ bool HTTPClient::hasHeader(const char* name)
*/ */
bool HTTPClient::connect(void) bool HTTPClient::connect(void)
{ {
if(connected()) { if(connected()) {
log_d("already connected, try reuse!"); if(_reuse) {
log_d("already connected, reusing connection");
} else {
log_d("already connected, try reuse!");
}
while(_client->available() > 0) { while(_client->available() > 0) {
_client->read(); _client->read();
} }
@ -980,8 +999,12 @@ bool HTTPClient::connect(void)
} }
#ifdef HTTPCLIENT_1_1_COMPATIBLE #ifdef HTTPCLIENT_1_1_COMPATIBLE
if(!_client) { if(_transportTraits && !_client) {
_tcpDeprecated = _transportTraits->create(); _tcpDeprecated = _transportTraits->create();
if(!_tcpDeprecated) {
log_e("failed to create client");
return false;
}
_client = _tcpDeprecated.get(); _client = _tcpDeprecated.get();
} }
#endif #endif
@ -1080,9 +1103,12 @@ int HTTPClient::handleHeaderResponse()
return HTTPC_ERROR_NOT_CONNECTED; return HTTPC_ERROR_NOT_CONNECTED;
} }
clear();
_canReuse = _reuse;
String transferEncoding; String transferEncoding;
_returnCode = -1;
_size = -1;
_transferEncoding = HTTPC_TE_IDENTITY; _transferEncoding = HTTPC_TE_IDENTITY;
unsigned long lastDataTime = millis(); unsigned long lastDataTime = millis();
@ -1097,6 +1123,9 @@ int HTTPClient::handleHeaderResponse()
log_v("RX: '%s'", headerLine.c_str()); log_v("RX: '%s'", headerLine.c_str());
if(headerLine.startsWith("HTTP/1.")) { if(headerLine.startsWith("HTTP/1.")) {
if(_canReuse) {
_canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0');
}
_returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt(); _returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
} else if(headerLine.indexOf(':')) { } else if(headerLine.indexOf(':')) {
String headerName = headerLine.substring(0, headerLine.indexOf(':')); String headerName = headerLine.substring(0, headerLine.indexOf(':'));
@ -1107,8 +1136,10 @@ int HTTPClient::handleHeaderResponse()
_size = headerValue.toInt(); _size = headerValue.toInt();
} }
if(headerName.equalsIgnoreCase("Connection")) { if(_canReuse && headerName.equalsIgnoreCase("Connection")) {
_canReuse = headerValue.equalsIgnoreCase("keep-alive"); if(headerValue.indexOf("close") >= 0 && headerValue.indexOf("keep-alive") < 0) {
_canReuse = false;
}
} }
if(headerName.equalsIgnoreCase("Transfer-Encoding")) { if(headerName.equalsIgnoreCase("Transfer-Encoding")) {

View File

@ -197,7 +197,7 @@ protected:
}; };
bool beginInternal(String url, const char* expectedProtocol); bool beginInternal(String url, const char* expectedProtocol);
void disconnect(); void disconnect(bool preserveClient = false);
void clear(); void clear();
int returnError(int error); int returnError(int error);
bool connect(void); bool connect(void);
@ -217,7 +217,7 @@ protected:
String _host; String _host;
uint16_t _port = 0; uint16_t _port = 0;
int32_t _connectTimeout = -1; int32_t _connectTimeout = -1;
bool _reuse = false; bool _reuse = true;
uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
bool _useHTTP10 = false; bool _useHTTP10 = false;
bool _secure = false; bool _secure = false;

View File

@ -96,7 +96,7 @@ void loop() {
client.setCACert(rootCACertificate); client.setCACert(rootCACertificate);
// Reading data over SSL may be slow, use an adequate timeout // Reading data over SSL may be slow, use an adequate timeout
client.setTimeout(12000); client.setTimeout(12000 / 1000); // timeout argument is defined in seconds for setTimeout
// The line below is optional. It can be used to blink the LED on the board during flashing // 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 // The LED will be on during download of one buffer of data from the network. The LED will

View File

@ -20,13 +20,33 @@ extern "C" {
#include <dirent.h> #include <dirent.h>
#include "esp_spiffs.h" #include "esp_spiffs.h"
} }
#include "SPIFFS.h" #include "SPIFFS.h"
using namespace fs; using namespace fs;
SPIFFSFS::SPIFFSFS(FSImplPtr impl) class SPIFFSImpl : public VFSImpl
: FS(impl) {
{} public:
SPIFFSImpl();
virtual ~SPIFFSImpl() { }
virtual bool exists(const char* path);
};
SPIFFSImpl::SPIFFSImpl()
{
}
bool SPIFFSImpl::exists(const char* path)
{
File f = open(path, "r");
return (f == true) && !f.isDirectory();
}
SPIFFSFS::SPIFFSFS() : FS(FSImplPtr(new SPIFFSImpl()))
{
}
bool SPIFFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles) bool SPIFFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles)
{ {
@ -98,16 +118,5 @@ size_t SPIFFSFS::usedBytes()
return used; return used;
} }
bool SPIFFSFS::exists(const char* path) SPIFFSFS SPIFFS;
{
File f = open(path, "r");
return (f == true) && !f.isDirectory();
}
bool SPIFFSFS::exists(const String& path)
{
return exists(path.c_str());
}
SPIFFSFS SPIFFS = SPIFFSFS(FSImplPtr(new VFSImpl()));

View File

@ -22,18 +22,17 @@ namespace fs
class SPIFFSFS : public FS class SPIFFSFS : public FS
{ {
public: public:
SPIFFSFS(FSImplPtr impl); SPIFFSFS();
bool begin(bool formatOnFail=false, const char * basePath="/spiffs", uint8_t maxOpenFiles=10); bool begin(bool formatOnFail=false, const char * basePath="/spiffs", uint8_t maxOpenFiles=10);
bool format(); bool format();
size_t totalBytes(); size_t totalBytes();
size_t usedBytes(); size_t usedBytes();
void end(); void end();
bool exists(const char* path);
bool exists(const String& path);
}; };
} }
extern fs::SPIFFSFS SPIFFS; extern fs::SPIFFSFS SPIFFS;
#endif /* _SPIFFS_H_ */
#endif

View File

@ -43,9 +43,9 @@ void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t
} }
esp_timer_create(&_timerConfig, &_timer); esp_timer_create(&_timerConfig, &_timer);
if (repeat) { if (repeat) {
esp_timer_start_periodic(_timer, milliseconds * 1000); esp_timer_start_periodic(_timer, milliseconds * 1000ULL);
} else { } else {
esp_timer_start_once(_timer, milliseconds * 1000); esp_timer_start_once(_timer, milliseconds * 1000ULL);
} }
} }

View File

@ -62,7 +62,7 @@ class UpdateClass {
If all bytes are written If all bytes are written
this call will write the config to eboot this call will write the config to eboot
and return true and return true
If there is already an update running but is not finished and !evenIfRemainanig If there is already an update running but is not finished and !evenIfRemaining
or there is an error or there is an error
this will clear everything and return false this will clear everything and return false
the last error is available through getError() the last error is available through getError()

View File

@ -189,6 +189,9 @@ bool UpdateClass::_writeBuffer(){
//this ensures that partially written firmware will not be bootable //this ensures that partially written firmware will not be bootable
_buffer[0] = 0xFF; _buffer[0] = 0xFF;
} }
if (!_progress && _progress_callback) {
_progress_callback(0, _size);
}
if(!ESP.flashEraseSector((_partition->address + _progress)/SPI_FLASH_SEC_SIZE)){ if(!ESP.flashEraseSector((_partition->address + _progress)/SPI_FLASH_SEC_SIZE)){
_abort(UPDATE_ERROR_ERASE); _abort(UPDATE_ERROR_ERASE);
return false; return false;
@ -204,6 +207,9 @@ bool UpdateClass::_writeBuffer(){
_md5.add(_buffer, _bufferLen); _md5.add(_buffer, _bufferLen);
_progress += _bufferLen; _progress += _bufferLen;
_bufferLen = 0; _bufferLen = 0;
if (_progress_callback) {
_progress_callback(_progress, _size);
}
return true; return true;
} }
@ -319,9 +325,6 @@ size_t UpdateClass::writeStream(Stream &data) {
_reset(); _reset();
return 0; return 0;
} }
if (_progress_callback) {
_progress_callback(0, _size);
}
if(_ledPin != -1) { if(_ledPin != -1) {
pinMode(_ledPin, OUTPUT); pinMode(_ledPin, OUTPUT);
@ -352,12 +355,6 @@ size_t UpdateClass::writeStream(Stream &data) {
if((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer()) if((_bufferLen == remaining() || _bufferLen == SPI_FLASH_SEC_SIZE) && !_writeBuffer())
return written; return written;
written += toRead; written += toRead;
if(_progress_callback) {
_progress_callback(_progress, _size);
}
}
if(_progress_callback) {
_progress_callback(_size, _size);
} }
return written; return written;
} }

View File

@ -303,6 +303,7 @@ void WebServer::_uploadWriteByte(uint8_t b){
} }
int WebServer::_uploadReadByte(WiFiClient& client){ int WebServer::_uploadReadByte(WiFiClient& client){
if (!client.connected()) return -1;
int res = client.read(); int res = client.read();
if(res < 0) { if(res < 0) {
// keep trying until you either read a valid byte or timeout // keep trying until you either read a valid byte or timeout

View File

@ -302,7 +302,9 @@ void WebServer::handleClient() {
// Wait for data from client to become available // Wait for data from client to become available
if (_currentClient.available()) { if (_currentClient.available()) {
if (_parseRequest(_currentClient)) { if (_parseRequest(_currentClient)) {
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT); // because HTTP_MAX_SEND_WAIT is expressed in milliseconds,
// it must be divided by 1000
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT / 1000);
_contentLength = CONTENT_LENGTH_NOT_SET; _contentLength = CONTENT_LENGTH_NOT_SET;
_handleRequest(); _handleRequest();

View File

@ -197,6 +197,33 @@ IPAddress ETHClass::dnsIP(uint8_t dns_no)
return IPAddress(dns_ip.u_addr.ip4.addr); return IPAddress(dns_ip.u_addr.ip4.addr);
} }
IPAddress ETHClass::broadcastIP()
{
tcpip_adapter_ip_info_t ip;
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
return IPAddress();
}
return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
}
IPAddress ETHClass::networkID()
{
tcpip_adapter_ip_info_t ip;
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
return IPAddress();
}
return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
}
uint8_t ETHClass::subnetCIDR()
{
tcpip_adapter_ip_info_t ip;
if(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_ETH, &ip)){
return (uint8_t)0;
}
return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr));
}
const char * ETHClass::getHostname() const char * ETHClass::getHostname()
{ {
const char * hostname; const char * hostname;

View File

@ -79,6 +79,10 @@ class ETHClass {
IPAddress gatewayIP(); IPAddress gatewayIP();
IPAddress dnsIP(uint8_t dns_no = 0); IPAddress dnsIP(uint8_t dns_no = 0);
IPAddress broadcastIP();
IPAddress networkID();
uint8_t subnetCIDR();
uint8_t * macAddress(uint8_t* mac); uint8_t * macAddress(uint8_t* mac);
String macAddress(); String macAddress();

View File

@ -235,6 +235,47 @@ IPAddress WiFiAPClass::softAPIP()
return IPAddress(ip.ip.addr); return IPAddress(ip.ip.addr);
} }
/**
* Get the softAP broadcast IP address.
* @return IPAddress softAP broadcastIP
*/
IPAddress WiFiAPClass::softAPBroadcastIP()
{
tcpip_adapter_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
}
/**
* Get the softAP network ID.
* @return IPAddress softAP networkID
*/
IPAddress WiFiAPClass::softAPNetworkID()
{
tcpip_adapter_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
}
/**
* Get the softAP subnet CIDR.
* @return uint8_t softAP subnetCIDR
*/
uint8_t WiFiAPClass::softAPSubnetCIDR()
{
tcpip_adapter_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return (uint8_t)0;
}
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr));
}
/** /**
* Get the softAP interface MAC address. * Get the softAP interface MAC address.

View File

@ -45,6 +45,10 @@ public:
IPAddress softAPIP(); IPAddress softAPIP();
IPAddress softAPBroadcastIP();
IPAddress softAPNetworkID();
uint8_t softAPSubnetCIDR();
bool softAPenableIpV6(); bool softAPenableIpV6();
IPv6Address softAPIPv6(); IPv6Address softAPIPv6();

View File

@ -226,14 +226,41 @@ int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout)
FD_SET(sockfd, &fdset); FD_SET(sockfd, &fdset);
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = timeout * 1000; tv.tv_usec = timeout * 1000;
lwip_connect_r(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
int res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv); int res = lwip_connect_r(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
if (res != 1) if (res < 0 && errno != EINPROGRESS) {
{ log_e("connect on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno));
log_e("select: %d",errno);
close(sockfd); close(sockfd);
return 0; return 0;
} }
res = select(sockfd + 1, nullptr, &fdset, nullptr, timeout<0 ? nullptr : &tv);
if (res < 0) {
log_e("select on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno));
close(sockfd);
return 0;
} else if (res == 0) {
log_i("select returned due to timeout %d ms for fd %d", timeout, sockfd);
close(sockfd);
return 0;
} else {
int sockerr;
socklen_t len = (socklen_t)sizeof(int);
res = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &sockerr, &len);
if (res < 0) {
log_e("getsockopt on fd %d, errno: %d, \"%s\"", sockfd, errno, strerror(errno));
close(sockfd);
return 0;
}
if (sockerr != 0) {
log_e("socket error on fd %d, errno: %d, \"%s\"", sockfd, sockerr, strerror(sockerr));
close(sockfd);
return 0;
}
}
fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) ); fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) & (~O_NONBLOCK) );
clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd)); clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd));
_rxBuffer.reset(new WiFiClientRxBuffer(sockfd)); _rxBuffer.reset(new WiFiClientRxBuffer(sockfd));

View File

@ -333,7 +333,9 @@ const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAV
#endif #endif
esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event) esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
{ {
if(event->event_id < 26) log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]); if(event->event_id < 26) {
log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]);
}
if(event->event_id == SYSTEM_EVENT_SCAN_DONE) { if(event->event_id == SYSTEM_EVENT_SCAN_DONE) {
WiFiScanClass::_scanDone(); WiFiScanClass::_scanDone();
@ -654,3 +656,45 @@ int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult)
return (uint32_t)aResult != 0; return (uint32_t)aResult != 0;
} }
IPAddress WiFiGenericClass::calculateNetworkID(IPAddress ip, IPAddress subnet) {
IPAddress networkID;
for (size_t i = 0; i < 4; i++)
networkID[i] = subnet[i] & ip[i];
return networkID;
}
IPAddress WiFiGenericClass::calculateBroadcast(IPAddress ip, IPAddress subnet) {
IPAddress broadcastIp;
for (int i = 0; i < 4; i++)
broadcastIp[i] = ~subnet[i] | ip[i];
return broadcastIp;
}
uint8_t WiFiGenericClass::calculateSubnetCIDR(IPAddress subnetMask) {
uint8_t CIDR = 0;
for (uint8_t i = 0; i < 4; i++) {
if (subnetMask[i] == 0x80) // 128
CIDR += 1;
else if (subnetMask[i] == 0xC0) // 192
CIDR += 2;
else if (subnetMask[i] == 0xE0) // 224
CIDR += 3;
else if (subnetMask[i] == 0xF0) // 242
CIDR += 4;
else if (subnetMask[i] == 0xF8) // 248
CIDR += 5;
else if (subnetMask[i] == 0xFC) // 252
CIDR += 6;
else if (subnetMask[i] == 0xFE) // 254
CIDR += 7;
else if (subnetMask[i] == 0xFF) // 255
CIDR += 8;
}
return CIDR;
}

View File

@ -108,6 +108,10 @@ class WiFiGenericClass
public: public:
static int hostByName(const char *aHostname, IPAddress &aResult); static int hostByName(const char *aHostname, IPAddress &aResult);
static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet);
static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet);
static uint8_t calculateSubnetCIDR(IPAddress subnetMask);
protected: protected:
friend class WiFiSTAClass; friend class WiFiSTAClass;
friend class WiFiScanClass; friend class WiFiScanClass;

View File

@ -34,22 +34,64 @@ WiFiMulti::WiFiMulti()
WiFiMulti::~WiFiMulti() WiFiMulti::~WiFiMulti()
{ {
APlistClean(); for(uint32_t i = 0; i < APlist.size(); i++) {
WifiAPlist_t entry = APlist[i];
if(entry.ssid) {
free(entry.ssid);
}
if(entry.passphrase) {
free(entry.passphrase);
}
}
APlist.clear();
} }
bool WiFiMulti::addAP(const char* ssid, const char *passphrase) bool WiFiMulti::addAP(const char* ssid, const char *passphrase)
{ {
return APlistAdd(ssid, passphrase); WifiAPlist_t newAP;
if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
// fail SSID too long or missing!
log_e("[WIFI][APlistAdd] no ssid or ssid too long");
return false;
}
if(passphrase && strlen(passphrase) > 63) {
// fail passphrase too long!
log_e("[WIFI][APlistAdd] passphrase too long");
return false;
}
newAP.ssid = strdup(ssid);
if(!newAP.ssid) {
log_e("[WIFI][APlistAdd] fail newAP.ssid == 0");
return false;
}
if(passphrase && *passphrase != 0x00) {
newAP.passphrase = strdup(passphrase);
if(!newAP.passphrase) {
log_e("[WIFI][APlistAdd] fail newAP.passphrase == 0");
free(newAP.ssid);
return false;
}
} else {
newAP.passphrase = NULL;
}
APlist.push_back(newAP);
log_i("[WIFI][APlistAdd] add SSID: %s", newAP.ssid);
return true;
} }
uint8_t WiFiMulti::run(uint32_t connectTimeout) uint8_t WiFiMulti::run(uint32_t connectTimeout)
{ {
int8_t scanResult; int8_t scanResult;
uint8_t status = WiFi.status(); uint8_t status = WiFi.status();
if(status == WL_CONNECTED) { if(status == WL_CONNECTED) {
for(uint32_t x = 0; x < APlist.size(); x++) { for(uint32_t x = 0; x < APlist.size(); x++) {
if(WiFi.SSID()==APlist[x].ssid){ if(WiFi.SSID()==APlist[x].ssid) {
return status; return status;
} }
} }
@ -119,7 +161,7 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID); WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
status = WiFi.status(); status = WiFi.status();
auto startTime = millis(); auto startTime = millis();
// wait for connection, fail, or timeout // wait for connection, fail, or timeout
while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) { while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) {
@ -128,17 +170,17 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
} }
switch(status) { switch(status) {
case 3: case WL_CONNECTED:
log_i("[WIFI] Connecting done."); log_i("[WIFI] Connecting done.");
log_d("[WIFI] SSID: %s", WiFi.SSID().c_str()); log_d("[WIFI] SSID: %s", WiFi.SSID().c_str());
log_d("[WIFI] IP: %s", WiFi.localIP().toString().c_str()); log_d("[WIFI] IP: %s", WiFi.localIP().toString().c_str());
log_d("[WIFI] MAC: %s", WiFi.BSSIDstr().c_str()); log_d("[WIFI] MAC: %s", WiFi.BSSIDstr().c_str());
log_d("[WIFI] Channel: %d", WiFi.channel()); log_d("[WIFI] Channel: %d", WiFi.channel());
break; break;
case 1: case WL_NO_SSID_AVAIL:
log_e("[WIFI] Connecting Failed AP not found."); log_e("[WIFI] Connecting Failed AP not found.");
break; break;
case 4: case WL_CONNECT_FAILED:
log_e("[WIFI] Connecting Failed."); log_e("[WIFI] Connecting Failed.");
break; break;
default: default:
@ -160,60 +202,3 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
return status; return status;
} }
// ##################################################################################
bool WiFiMulti::APlistAdd(const char* ssid, const char *passphrase)
{
WifiAPlist_t newAP;
if(!ssid || *ssid == 0x00 || strlen(ssid) > 31) {
// fail SSID to long or missing!
log_e("[WIFI][APlistAdd] no ssid or ssid to long");
return false;
}
if(passphrase && strlen(passphrase) > 63) {
// fail passphrase to long!
log_e("[WIFI][APlistAdd] passphrase to long");
return false;
}
newAP.ssid = strdup(ssid);
if(!newAP.ssid) {
log_e("[WIFI][APlistAdd] fail newAP.ssid == 0");
return false;
}
if(passphrase && *passphrase != 0x00) {
newAP.passphrase = strdup(passphrase);
if(!newAP.passphrase) {
log_e("[WIFI][APlistAdd] fail newAP.passphrase == 0");
free(newAP.ssid);
return false;
}
} else {
newAP.passphrase = NULL;
}
APlist.push_back(newAP);
log_i("[WIFI][APlistAdd] add SSID: %s", newAP.ssid);
return true;
}
void WiFiMulti::APlistClean(void)
{
for(uint32_t i = 0; i < APlist.size(); i++) {
WifiAPlist_t entry = APlist[i];
if(entry.ssid) {
free(entry.ssid);
}
if(entry.passphrase) {
free(entry.passphrase);
}
}
APlist.clear();
}

View File

@ -46,9 +46,6 @@ public:
private: private:
std::vector<WifiAPlist_t> APlist; std::vector<WifiAPlist_t> APlist;
bool APlistAdd(const char* ssid, const char *passphrase = NULL);
void APlistClean(void);
}; };
#endif /* WIFICLIENTMULTI_H_ */ #endif /* WIFICLIENTMULTI_H_ */

View File

@ -162,6 +162,8 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_
esp_wifi_set_config(WIFI_IF_STA, &conf); esp_wifi_set_config(WIFI_IF_STA, &conf);
} else if(status() == WL_CONNECTED){ } else if(status() == WL_CONNECTED){
return WL_CONNECTED; return WL_CONNECTED;
} else {
esp_wifi_set_config(WIFI_IF_STA, &conf);
} }
if(!_useStaticIp) { if(!_useStaticIp) {
@ -198,6 +200,12 @@ wl_status_t WiFiSTAClass::begin()
return WL_CONNECT_FAILED; return WL_CONNECT_FAILED;
} }
wifi_config_t current_conf;
if(esp_wifi_get_config(WIFI_IF_STA, &current_conf) != ESP_OK || esp_wifi_set_config(WIFI_IF_STA, &current_conf) != ESP_OK) {
log_e("config failed");
return WL_CONNECT_FAILED;
}
if(!_useStaticIp) { if(!_useStaticIp) {
if(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){ if(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){
log_e("dhcp client start failed!"); log_e("dhcp client start failed!");
@ -484,6 +492,48 @@ IPAddress WiFiSTAClass::dnsIP(uint8_t dns_no)
return IPAddress(dns_ip.u_addr.ip4.addr); return IPAddress(dns_ip.u_addr.ip4.addr);
} }
/**
* Get the broadcast ip address.
* @return IPAddress broadcastIP
*/
IPAddress WiFiSTAClass::broadcastIP()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
return WiFiGenericClass::calculateBroadcast(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
}
/**
* Get the network id.
* @return IPAddress networkID
*/
IPAddress WiFiSTAClass::networkID()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
return WiFiGenericClass::calculateNetworkID(IPAddress(ip.gw.addr), IPAddress(ip.netmask.addr));
}
/**
* Get the subnet CIDR.
* @return uint8_t subnetCIDR
*/
uint8_t WiFiSTAClass::subnetCIDR()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return (uint8_t)0;
}
tcpip_adapter_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
return WiFiGenericClass::calculateSubnetCIDR(IPAddress(ip.netmask.addr));
}
/** /**
* Return the current SSID associated with the network * Return the current SSID associated with the network
* @return SSID * @return SSID

View File

@ -64,6 +64,10 @@ public:
IPAddress subnetMask(); IPAddress subnetMask();
IPAddress gatewayIP(); IPAddress gatewayIP();
IPAddress dnsIP(uint8_t dns_no = 0); IPAddress dnsIP(uint8_t dns_no = 0);
IPAddress broadcastIP();
IPAddress networkID();
uint8_t subnetCIDR();
bool enableIpV6(); bool enableIpV6();
IPv6Address localIPv6(); IPv6Address localIPv6();

6
package/merge_packages.py Normal file → Executable file
View File

@ -36,7 +36,11 @@ def pkgVersionNormalized(versionString):
verParts = re.split('\.|-rc', verStr, flags=re.IGNORECASE) verParts = re.split('\.|-rc', verStr, flags=re.IGNORECASE)
if len(verParts) == 3: if len(verParts) == 3:
verStr = str(versionString) + '-rc' + str(sys.maxint) if (sys.version_info > (3, 0)): # Python 3
verStr = str(versionString) + '-rc' + str(sys.maxsize)
else: # Python 2
verStr = str(versionString) + '-rc' + str(sys.maxint)
elif len(verParts) != 4: elif len(verParts) != 4:
print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr) print("pkgVersionNormalized WARNING: unexpected version format: {0})".format(verStr), file=sys.stderr)

View File

@ -22,7 +22,7 @@ compiler.warning_flags.all=-Wall -Werror=all -Wextra
compiler.path={runtime.tools.xtensa-esp32-elf-gcc.path}/bin/ compiler.path={runtime.tools.xtensa-esp32-elf-gcc.path}/bin/
compiler.sdk.path={runtime.platform.path}/tools/sdk compiler.sdk.path={runtime.platform.path}/tools/sdk
compiler.cpreprocessor.flags=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/app_trace" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/asio" "-I{compiler.sdk.path}/include/bootloader_support" "-I{compiler.sdk.path}/include/bt" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/esp_adc_cal" "-I{compiler.sdk.path}/include/esp_event" "-I{compiler.sdk.path}/include/esp_http_client" "-I{compiler.sdk.path}/include/esp_http_server" "-I{compiler.sdk.path}/include/esp_https_ota" "-I{compiler.sdk.path}/include/esp_ringbuf" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freemodbus" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/heap" "-I{compiler.sdk.path}/include/idf_test" "-I{compiler.sdk.path}/include/jsmn" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/libsodium" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/lwip" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/micro-ecc" "-I{compiler.sdk.path}/include/mqtt" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/protobuf-c" "-I{compiler.sdk.path}/include/protocomm" "-I{compiler.sdk.path}/include/pthread" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/smartconfig_ack" "-I{compiler.sdk.path}/include/soc" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/spiffs" "-I{compiler.sdk.path}/include/tcp_transport" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/wear_levelling" "-I{compiler.sdk.path}/include/wifi_provisioning" "-I{compiler.sdk.path}/include/wpa_supplicant" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/esp32-camera" "-I{compiler.sdk.path}/include/esp-face" "-I{compiler.sdk.path}/include/fb_gfx" compiler.cpreprocessor.flags=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I{compiler.sdk.path}/include/config" "-I{compiler.sdk.path}/include/app_trace" "-I{compiler.sdk.path}/include/app_update" "-I{compiler.sdk.path}/include/asio" "-I{compiler.sdk.path}/include/bootloader_support" "-I{compiler.sdk.path}/include/bt" "-I{compiler.sdk.path}/include/coap" "-I{compiler.sdk.path}/include/console" "-I{compiler.sdk.path}/include/driver" "-I{compiler.sdk.path}/include/esp-tls" "-I{compiler.sdk.path}/include/esp32" "-I{compiler.sdk.path}/include/esp_adc_cal" "-I{compiler.sdk.path}/include/esp_event" "-I{compiler.sdk.path}/include/esp_http_client" "-I{compiler.sdk.path}/include/esp_http_server" "-I{compiler.sdk.path}/include/esp_https_ota" "-I{compiler.sdk.path}/include/esp_ringbuf" "-I{compiler.sdk.path}/include/ethernet" "-I{compiler.sdk.path}/include/expat" "-I{compiler.sdk.path}/include/fatfs" "-I{compiler.sdk.path}/include/freemodbus" "-I{compiler.sdk.path}/include/freertos" "-I{compiler.sdk.path}/include/heap" "-I{compiler.sdk.path}/include/idf_test" "-I{compiler.sdk.path}/include/jsmn" "-I{compiler.sdk.path}/include/json" "-I{compiler.sdk.path}/include/libsodium" "-I{compiler.sdk.path}/include/log" "-I{compiler.sdk.path}/include/lwip" "-I{compiler.sdk.path}/include/mbedtls" "-I{compiler.sdk.path}/include/mdns" "-I{compiler.sdk.path}/include/micro-ecc" "-I{compiler.sdk.path}/include/mqtt" "-I{compiler.sdk.path}/include/newlib" "-I{compiler.sdk.path}/include/nghttp" "-I{compiler.sdk.path}/include/nvs_flash" "-I{compiler.sdk.path}/include/openssl" "-I{compiler.sdk.path}/include/protobuf-c" "-I{compiler.sdk.path}/include/protocomm" "-I{compiler.sdk.path}/include/pthread" "-I{compiler.sdk.path}/include/sdmmc" "-I{compiler.sdk.path}/include/smartconfig_ack" "-I{compiler.sdk.path}/include/soc" "-I{compiler.sdk.path}/include/spi_flash" "-I{compiler.sdk.path}/include/spiffs" "-I{compiler.sdk.path}/include/tcp_transport" "-I{compiler.sdk.path}/include/tcpip_adapter" "-I{compiler.sdk.path}/include/ulp" "-I{compiler.sdk.path}/include/vfs" "-I{compiler.sdk.path}/include/wear_levelling" "-I{compiler.sdk.path}/include/wifi_provisioning" "-I{compiler.sdk.path}/include/wpa_supplicant" "-I{compiler.sdk.path}/include/xtensa-debug-module" "-I{compiler.sdk.path}/include/esp-face" "-I{compiler.sdk.path}/include/esp32-camera" "-I{compiler.sdk.path}/include/esp-face" "-I{compiler.sdk.path}/include/fb_gfx"
compiler.c.cmd=xtensa-esp32-elf-gcc compiler.c.cmd=xtensa-esp32-elf-gcc
compiler.c.flags=-std=gnu99 -Os -g3 -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wpointer-arith {compiler.warning_flags} -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -MMD -c compiler.c.flags=-std=gnu99 -Os -g3 -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wpointer-arith {compiler.warning_flags} -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -MMD -c

View File

@ -1,54 +0,0 @@
#!/bin/bash
#- set -e
if [ ! -z "$TRAVIS_TAG" ]; then
echo "No sketch builds & tests required for tagged TravisCI builds, exiting"
exit 0
fi
echo -e "travis_fold:start:sketch_test_env_prepare"
pip install pyserial
wget -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz
tar xf arduino.tar.xz
mv arduino-nightly $HOME/arduino_ide
mkdir -p $HOME/Arduino/libraries
cd $HOME/arduino_ide/hardware
mkdir espressif
cd espressif
ln -s $TRAVIS_BUILD_DIR esp32
cd esp32
git submodule update --init --recursive
cd tools
python get.py
cd $TRAVIS_BUILD_DIR
export PATH="$HOME/arduino_ide:$TRAVIS_BUILD_DIR/tools/xtensa-esp32-elf/bin:$PATH"
source tools/common.sh
echo -e "travis_fold:end:sketch_test_env_prepare"
echo -e "travis_fold:start:sketch_test"
build_sketches $HOME/arduino_ide $TRAVIS_BUILD_DIR/libraries "-l $HOME/Arduino/libraries"
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:sketch_test"
echo -e "travis_fold:start:size_report"
cat size.log
echo -e "travis_fold:end:size_report"
echo -e "travis_fold:start:platformio_test_env_prepare"
pip install -U https://github.com/platformio/platformio/archive/develop.zip && \
platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage && \
sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' ~/.platformio/platforms/espressif32/platform.json && \
ln -s $TRAVIS_BUILD_DIR ~/.platformio/packages/framework-arduinoespressif32
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:platformio_test_env_prepare"
echo -e "travis_fold:start:platformio_test"
platformio ci --board esp32dev libraries/WiFi/examples/WiFiClient && \
platformio ci --board esp32dev libraries/WiFiClientSecure/examples/WiFiClientSecure && \
platformio ci --board esp32dev libraries/BluetoothSerial/examples/SerialToSerialBT && \
platformio ci --board esp32dev libraries/BLE/examples/BLE_server && \
platformio ci --board esp32dev libraries/AzureIoT/examples/GetStarted && \
platformio ci --board esp32dev libraries/ESP32/examples/Camera/CameraWebServer --project-option="board_build.partitions = huge_app.csv"
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:platformio_test"

View File

@ -1,131 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# build.py — build a sketch using arduino-builder
#
# Wrapper script around arduino-builder which accepts some ESP8266-specific
# options and translates them into FQBN
#
# Copyright © 2016 Ivan Grokhotkov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
#
from __future__ import print_function
import sys
import os
import argparse
import subprocess
import tempfile
import shutil
def compile(tmp_dir, sketch, tools_dir, hardware_dir, ide_path, f, args):
cmd = ide_path + '/arduino-builder '
cmd += '-compile -logger=human '
cmd += '-build-path "' + tmp_dir + '" '
cmd += '-tools "' + ide_path + '/tools-builder" '
if args.library_path:
for lib_dir in args.library_path:
cmd += '-libraries "' + lib_dir + '" '
cmd += '-hardware "' + ide_path + '/hardware" '
if args.hardware_dir:
for hw_dir in args.hardware_dir:
cmd += '-hardware "' + hw_dir + '" '
else:
cmd += '-hardware "' + hardware_dir + '" '
# Debug=Serial,DebugLevel=Core____
cmd += '-fqbn=espressif:esp32:{board_name}:' \
'FlashFreq={flash_freq},' \
'PartitionScheme=huge_app,' \
'UploadSpeed=921600'.format(**vars(args))
cmd += ' '
cmd += '-ide-version=10607 '
cmd += '-warnings={warnings} '.format(**vars(args))
if args.verbose:
cmd += '-verbose '
cmd += sketch
if args.verbose:
print('Building: ' + cmd, file=f)
cmds = cmd.split(' ')
p = subprocess.Popen(cmds, stdout=f, stderr=subprocess.STDOUT)
p.wait()
return p.returncode
def parse_args():
parser = argparse.ArgumentParser(description='Sketch build helper')
parser.add_argument('-v', '--verbose', help='Enable verbose output',
action='store_true')
parser.add_argument('-i', '--ide_path', help='Arduino IDE path')
parser.add_argument('-p', '--build_path', help='Build directory')
parser.add_argument('-l', '--library_path', help='Additional library path',
action='append')
parser.add_argument('-d', '--hardware_dir', help='Additional hardware path',
action='append')
parser.add_argument('-b', '--board_name', help='Board name', default='esp32')
parser.add_argument('-w', '--warnings', help='Compilation warnings level',
default='none', choices=['none', 'all', 'more'])
parser.add_argument('-o', '--output_binary', help='File name for output binary')
parser.add_argument('-k', '--keep', action='store_true',
help='Don\'t delete temporary build directory')
parser.add_argument('--flash_freq', help='Flash frequency', default=40,
type=int, choices=[40, 80])
parser.add_argument('sketch_path', help='Sketch file path')
return parser.parse_args()
def main():
args = parse_args()
ide_path = args.ide_path
if not ide_path:
ide_path = os.environ.get('ARDUINO_IDE_PATH')
if not ide_path:
print("Please specify Arduino IDE path via --ide_path option"
"or ARDUINO_IDE_PATH environment variable.", file=sys.stderr)
return 2
sketch_path = args.sketch_path
tmp_dir = args.build_path
created_tmp_dir = False
if not tmp_dir:
tmp_dir = tempfile.mkdtemp()
created_tmp_dir = True
tools_dir = os.path.dirname(os.path.realpath(__file__)) + '/../tools'
# this is not the correct hardware folder to add.
hardware_dir = os.path.dirname(os.path.realpath(__file__)) + '/../cores'
output_name = tmp_dir + '/' + os.path.basename(sketch_path) + '.bin'
if args.verbose:
print("Sketch: ", sketch_path)
print("Build dir: ", tmp_dir)
print("Output: ", output_name)
if args.verbose:
f = sys.stdout
else:
f = open(tmp_dir + '/build.log', 'w')
res = compile(tmp_dir, sketch_path, tools_dir, hardware_dir, ide_path, f, args)
if res != 0:
return res
if args.output_binary is not None:
shutil.copy(output_name, args.output_binary)
if created_tmp_dir and not args.keep:
shutil.rmtree(tmp_dir, ignore_errors=True)
if __name__ == '__main__':
sys.exit(main())

View File

@ -1,9 +0,0 @@
#!/bin/bash
if [ ! -z "$TRAVIS_TAG" ]; then
# zip the package if tagged build
tools/build-release.sh -a$ESP32_GITHUB_TOKEN
else
# run cmake and sketch tests
tools/check_cmakelists.sh && tools/build-tests.sh
fi

View File

@ -1,5 +1,10 @@
#!/bin/bash #!/bin/bash
if [ -z "$TRAVIS_TAG" ]; then
echo "Skipping Packaging: Regular build"
exit 0
fi
############################################################ ############################################################
# $1 - download link # $1 - download link
# $2 - JSON output file # $2 - JSON output file

64
tools/ci/build-tests.sh Executable file
View File

@ -0,0 +1,64 @@
#!/bin/bash
if [ ! -z "$TRAVIS_TAG" ]; then
echo "Skipping Test: Tagged build"
exit 0
fi
CHUNK_INDEX=$1
CHUNKS_CNT=$2
BUILD_PIO=0
if [ "$#" -lt 2 ]; then
echo "Building all sketches"
CHUNK_INDEX=0
CHUNKS_CNT=1
BUILD_PIO=1
fi
if [ "$CHUNKS_CNT" -le 0 ]; then
CHUNK_INDEX=0
CHUNKS_CNT=1
BUILD_PIO=1
fi
if [ "$CHUNK_INDEX" -gt "$CHUNKS_CNT" ]; then
CHUNK_INDEX=$CHUNKS_CNT
fi
if [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
BUILD_PIO=1
fi
# CMake Test
if [ "$CHUNK_INDEX" -eq 0 ]; then
echo -e "travis_fold:start:check_cmakelists"
tools/ci/check-cmakelists.sh
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:check_cmakelists"
fi
if [ "$BUILD_PIO" -eq 0 ]; then
# ArduinoIDE Test
echo -e "travis_fold:start:prep_arduino_ide"
tools/ci/prep-arduino-ide.sh
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:prep_arduino_ide"
echo -e "travis_fold:start:test_arduino_ide"
tools/ci/test-arduino-ide.sh $CHUNK_INDEX $CHUNKS_CNT
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:test_arduino_ide"
echo -e "travis_fold:start:size_report"
cat size.log
echo -e "travis_fold:end:size_report"
else
# PlatformIO Test
echo -e "travis_fold:start:prep_platformio"
cd tools && python get.py && cd ..
tools/ci/prep-platformio.sh
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:prep_platformio"
echo -e "travis_fold:start:test_platformio"
tools/ci/test-platformio.sh
if [ $? -ne 0 ]; then exit 1; fi
echo -e "travis_fold:end:test_platformio"
fi

View File

@ -10,8 +10,10 @@ set -e
cd "`dirname $0`/.." # cd to arduino-esp32 root cd "`dirname $0`/.." # cd to arduino-esp32 root
# pull all submodules
git submodule update --init --recursive
# find all source files in repo # find all source files in repo
#REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name 'main.cpp' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort`
REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort` REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort`
# find all source files named in CMakeLists.txt COMPONENT_SRCS # find all source files named in CMakeLists.txt COMPONENT_SRCS

13
tools/ci/prep-arduino-ide.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/bash
pip install pyserial
wget -O arduino.tar.xz https://www.arduino.cc/download.php?f=/arduino-nightly-linux64.tar.xz
tar xf arduino.tar.xz
mv arduino-nightly $HOME/arduino_ide
mkdir -p $HOME/Arduino/libraries
mkdir -p $HOME/Arduino/hardware/espressif
cd $HOME/Arduino/hardware/espressif
ln -s $TRAVIS_BUILD_DIR esp32
cd esp32/tools
python get.py

6
tools/ci/prep-platformio.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
pip install -U https://github.com/platformio/platformio/archive/develop.zip && \
python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage && \
sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' ~/.platformio/platforms/espressif32/platform.json && \
ln -s $TRAVIS_BUILD_DIR ~/.platformio/packages/framework-arduinoespressif32

170
tools/ci/test-arduino-ide.sh Executable file
View File

@ -0,0 +1,170 @@
#!/bin/bash
CHUNK_INDEX=$1
CHUNKS_CNT=$2
if [ "$#" -lt 2 ]; then
echo "Building all sketches"
CHUNK_INDEX=0
CHUNKS_CNT=1
fi
if [ "$CHUNKS_CNT" -le 0 ]; then
echo "Chunks count must be positive number"
exit 1
fi
if [ "$CHUNK_INDEX" -ge "$CHUNKS_CNT" ]; then
echo "Chunk index must be less than chunks count"
exit 1
fi
export ARDUINO_BOARD_FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,CPUFreq=240,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,DebugLevel=none"
export ARDUINO_IDE_PATH=$HOME/arduino_ide
export ARDUINO_USR_PATH=$HOME/Arduino
export EXAMPLES_PATH=$TRAVIS_BUILD_DIR/libraries
export EXAMPLES_BUILD_DIR=$HOME/build.tmp
export EXAMPLES_CACHE_DIR=$HOME/cache.tmp
export EXAMPLES_BUILD_CMD="$ARDUINO_IDE_PATH/arduino-builder -compile -logger=human -core-api-version=\"10810\" -hardware \"$ARDUINO_IDE_PATH/hardware\" -hardware \"$ARDUINO_USR_PATH/hardware\" -tools \"$ARDUINO_IDE_PATH/tools-builder\" -built-in-libraries \"$ARDUINO_IDE_PATH/libraries\" -libraries \"$ARDUINO_USR_PATH/libraries\" -fqbn=$ARDUINO_BOARD_FQBN -warnings=\"all\" -build-cache \"$EXAMPLES_CACHE_DIR\" -build-path \"$EXAMPLES_BUILD_DIR\" -verbose"
export EXAMPLES_SIZE_BIN=$TRAVIS_BUILD_DIR/tools/xtensa-esp32-elf/bin/xtensa-esp32-elf-size
function print_size_info()
{
elf_file=$1
if [ -z "$elf_file" ]; then
printf "sketch iram0.text flash.text flash.rodata dram0.data dram0.bss dram flash\n"
return 0
fi
elf_name=$(basename $elf_file)
sketch_name="${elf_name%.*}"
# echo $sketch_name
declare -A segments
while read -a tokens; do
seg=${tokens[0]}
seg=${seg//./}
size=${tokens[1]}
addr=${tokens[2]}
if [ "$addr" -eq "$addr" -a "$addr" -ne "0" ] 2>/dev/null; then
segments[$seg]=$size
fi
done < <($EXAMPLES_SIZE_BIN --format=sysv $elf_file)
total_ram=$((${segments[dram0data]} + ${segments[dram0bss]}))
total_flash=$((${segments[iram0text]} + ${segments[flashtext]} + ${segments[dram0data]} + ${segments[flashrodata]}))
printf "%-32s %-8d %-8d %-8d %-8d %-8d %-8d %-8d\n" $sketch_name ${segments[iram0text]} ${segments[flashtext]} ${segments[flashrodata]} ${segments[dram0data]} ${segments[dram0bss]} $total_ram $total_flash
return 0
}
function build_sketch()
{
local sketch=$1
echo -e "\n------------ Building $sketch ------------\n";
rm -rf $EXAMPLES_BUILD_DIR/*
time ($EXAMPLES_BUILD_CMD $sketch >build.log)
local result=$?
if [ $result -ne 0 ]; then
echo "Build failed ($1)"
echo "Build log:"
cat build.log
return $result
fi
rm build.log
return 0
}
function count_sketches()
{
local sketches=$(find $EXAMPLES_PATH -name *.ino)
local sketchnum=0
rm -rf sketches.txt
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
continue
fi
echo $sketch >> sketches.txt
sketchnum=$(($sketchnum + 1))
done
return $sketchnum
}
function build_sketches()
{
mkdir -p $EXAMPLES_BUILD_DIR
mkdir -p $EXAMPLES_CACHE_DIR
mkdir -p $ARDUINO_USR_PATH/libraries
mkdir -p $ARDUINO_USR_PATH/hardware
local chunk_idex=$1
local chunks_num=$2
count_sketches
local sketchcount=$?
local sketches=$(cat sketches.txt)
local chunk_size=$(( $sketchcount / $chunks_num ))
local all_chunks=$(( $chunks_num * $chunk_size ))
if [ "$all_chunks" -lt "$sketchcount" ]; then
chunk_size=$(( $chunk_size + 1 ))
fi
local start_index=$(( $chunk_idex * $chunk_size ))
if [ "$sketchcount" -le "$start_index" ]; then
echo "Skipping job"
return 0
fi
local end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
if [ "$end_index" -gt "$sketchcount" ]; then
end_index=$sketchcount
fi
local start_num=$(( $start_index + 1 ))
#echo -e "Sketches: \n$sketches\n"
echo "Found $sketchcount Sketches";
echo "Chunk Count : $chunks_num"
echo "Chunk Size : $chunk_size"
echo "Start Sketch: $start_num"
echo "End Sketch : $end_index"
local sketchnum=0
print_size_info >size.log
for sketch in $sketches; do
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
#echo "Skipping $sketch, beacause it is not the main sketch file";
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
#echo "Skipping $sketch marked";
continue
fi
sketchnum=$(($sketchnum + 1))
if [ "$sketchnum" -le "$start_index" ]; then
#echo "Skipping $sketch index low"
continue
fi
if [ "$sketchnum" -gt "$end_index" ]; then
#echo "Skipping $sketch index high"
continue
fi
build_sketch $sketch
local result=$?
if [ $result -ne 0 ]; then
return $result
fi
print_size_info $EXAMPLES_BUILD_DIR/*.elf >>size.log
done
return 0
}
build_sketches $CHUNK_INDEX $CHUNKS_CNT
if [ $? -ne 0 ]; then exit 1; fi

9
tools/ci/test-platformio.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
python -m platformio ci --board esp32dev libraries/WiFi/examples/WiFiClient && \
python -m platformio ci --board esp32dev libraries/WiFiClientSecure/examples/WiFiClientSecure && \
python -m platformio ci --board esp32dev libraries/BluetoothSerial/examples/SerialToSerialBT && \
python -m platformio ci --board esp32dev libraries/BLE/examples/BLE_server && \
python -m platformio ci --board esp32dev libraries/AzureIoT/examples/GetStarted && \
python -m platformio ci --board esp32dev libraries/ESP32/examples/Camera/CameraWebServer --project-option="board_build.partitions = huge_app.csv"
if [ $? -ne 0 ]; then exit 1; fi

View File

@ -1,72 +0,0 @@
#!/usr/bin/env bash
function print_size_info()
{
elf_file=$1
if [ -z "$elf_file" ]; then
printf "sketch iram0.text flash.text flash.rodata dram0.data dram0.bss dram flash\n"
return 0
fi
elf_name=$(basename $elf_file)
sketch_name="${elf_name%.*}"
# echo $sketch_name
declare -A segments
while read -a tokens; do
seg=${tokens[0]}
seg=${seg//./}
size=${tokens[1]}
addr=${tokens[2]}
if [ "$addr" -eq "$addr" -a "$addr" -ne "0" ] 2>/dev/null; then
segments[$seg]=$size
fi
done < <(xtensa-esp32-elf-size --format=sysv $elf_file)
total_ram=$((${segments[dram0data]} + ${segments[dram0bss]}))
total_flash=$((${segments[iram0text]} + ${segments[flashtext]} + ${segments[dram0data]} + ${segments[flashrodata]}))
printf "%-28s %-8d %-8d %-8d %-8d %-8d %-8d %-8d\n" $sketch_name ${segments[iram0text]} ${segments[flashtext]} ${segments[flashrodata]} ${segments[dram0data]} ${segments[dram0bss]} $total_ram $total_flash
return 0
}
function build_sketches()
{
#set +e
local arduino=$1
local srcpath=$2
local build_arg=$3
local build_dir=build.tmp
mkdir -p $build_dir
local build_cmd="python tools/build.py -b esp32 -v -k -p $PWD/$build_dir $build_arg "
local sketches=$(find $srcpath -name *.ino)
print_size_info >size.log
export ARDUINO_IDE_PATH=$arduino
for sketch in $sketches; do
rm -rf $build_dir/*
local sketchdir=$(dirname $sketch)
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
echo "Skipping $sketch, beacause it is not the main sketch file";
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
echo -e "\n ------------ Skipping $sketch ------------ \n";
continue
fi
echo -e "\n ------------ Building $sketch ------------ \n";
# $arduino --verify $sketch;
#echo "$build_cmd $sketch"
time ($build_cmd $sketch >build.log)
local result=$?
if [ $result -ne 0 ]; then
echo "Build failed ($1)"
echo "Build log:"
cat build.log
return $result
fi
rm build.log
print_size_info $build_dir/*.elf >>size.log
done
#set -e
}

View File

@ -236,7 +236,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm
def parser(unparsed_args): def parser(unparsed_args):
parser = optparse.OptionParser( parser = optparse.OptionParser(
usage = "%prog [options]", usage = "%prog [options]",
description = "Transmit image over the air to the esp8266 module with OTA support." description = "Transmit image over the air to the esp32 module with OTA support."
) )
# destination ip and port # destination ip and port
@ -244,7 +244,7 @@ def parser(unparsed_args):
group.add_option("-i", "--ip", group.add_option("-i", "--ip",
dest = "esp_ip", dest = "esp_ip",
action = "store", action = "store",
help = "ESP8266 IP Address.", help = "ESP32 IP Address.",
default = False default = False
) )
group.add_option("-I", "--host_ip", group.add_option("-I", "--host_ip",
@ -256,8 +256,8 @@ def parser(unparsed_args):
group.add_option("-p", "--port", group.add_option("-p", "--port",
dest = "esp_port", dest = "esp_port",
type = "int", type = "int",
help = "ESP8266 ota Port. Default 8266", help = "ESP32 ota Port. Default 3232",
default = 8266 default = 3232
) )
group.add_option("-P", "--host_port", group.add_option("-P", "--host_port",
dest = "host_port", dest = "host_port",
@ -310,7 +310,7 @@ def parser(unparsed_args):
group.add_option("-t", "--timeout", group.add_option("-t", "--timeout",
dest = "timeout", dest = "timeout",
type = "int", type = "int",
help = "Timeout to wait for the ESP8266 to accept invitation", help = "Timeout to wait for the ESP32 to accept invitation",
default = 10 default = 10
) )
parser.add_option_group(group) parser.add_option_group(group)

View File

@ -152,6 +152,7 @@ env.Append(
join(FRAMEWORK_DIR, "tools", "sdk", "include", "wifi_provisioning"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "wifi_provisioning"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "wpa_supplicant"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "wpa_supplicant"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "xtensa-debug-module"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "xtensa-debug-module"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-face"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp32-camera"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp32-camera"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-face"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "esp-face"),
join(FRAMEWORK_DIR, "tools", "sdk", "include", "fb_gfx"), join(FRAMEWORK_DIR, "tools", "sdk", "include", "fb_gfx"),

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -91,3 +91,16 @@ bool bootloader_common_label_search(const char *list, char *label);
* - ESP_FAIL: An allocation error occurred. * - ESP_FAIL: An allocation error occurred.
*/ */
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256); esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);
/**
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
*/
void bootloader_common_vddsdio_configure();
/**
* @brief Set the flash CS setup and hold time.
*
* CS setup time is recomemded to be 1.5T, and CS hold time is recommended to be 2.5T.
* cs_setup = 1, cs_setup_time = 0; cs_hold = 1, cs_hold_time = 1
*/
void bootloader_common_set_flash_cs_timing();

Some files were not shown because too many files have changed in this diff Show More