forked from espressif/arduino-esp32
Compare commits
350 Commits
esp32s2
...
old_versio
Author | SHA1 | Date | |
---|---|---|---|
7edf81ed1a | |||
19333fd774 | |||
a3d5e78b83 | |||
2b2f7cd936 | |||
8bb0f29958 | |||
a2c33507ba | |||
c7da12b153 | |||
c85a4725a9 | |||
e1540e64a6 | |||
a1fa8dc1eb | |||
0bfbfd527d | |||
9f58515d7f | |||
f9d142def6 | |||
59d3f4bd4f | |||
40409a3e4f | |||
6c49028af8 | |||
aa9f5dc65a | |||
ce4aa4606c | |||
f607edea13 | |||
c9ca6f199b | |||
b0223be116 | |||
8e447f5cd5 | |||
a84e0538ff | |||
ff9ec961c1 | |||
f5e23bfbbd | |||
50e1f1ffa1 | |||
5fdfe5e1b9 | |||
e9cdb0d111 | |||
ecc9bb3eb0 | |||
07b177e4a5 | |||
67dfea558a | |||
d237cc9df6 | |||
c5d5f95c1b | |||
561bca1e67 | |||
0f38a07a20 | |||
899e7e01d4 | |||
4458870228 | |||
e385dd8abc | |||
acf3b3948a | |||
a4a32ef88a | |||
9ff721dede | |||
9bd3e02d0f | |||
35bea57d10 | |||
2e19b9ff5b | |||
bbb21bbf55 | |||
dfe251e9a2 | |||
a56728a16b | |||
f41438597d | |||
dcf9895955 | |||
7d3f49940f | |||
9bc8420e2f | |||
c1b06cc120 | |||
93c6226177 | |||
b5651491e5 | |||
a25ccb2ef7 | |||
5b5b61c018 | |||
cbafe67ee1 | |||
e0f8b845fb | |||
1eb2c6d3dc | |||
564733137a | |||
e5555c72e5 | |||
104d28bd9c | |||
934553d290 | |||
f7fe024744 | |||
adafd9d7c0 | |||
ac9fdeffe4 | |||
29e3b640a8 | |||
91025f8515 | |||
e41fb08b2a | |||
d8b1fc81c0 | |||
378b6ac032 | |||
a2e0e865dd | |||
9debb9fc76 | |||
b6cc108d49 | |||
8816bb5505 | |||
3274602eb0 | |||
5d62ba56f6 | |||
2d0e772674 | |||
2063a606e9 | |||
534f0810a6 | |||
28a8073069 | |||
ca6405658a | |||
486a4c66c4 | |||
70bd58b00b | |||
f1cbd3b74b | |||
ad07d36932 | |||
e55d657e9f | |||
ef5c73f1ed | |||
c6a8da61f7 | |||
591c43880a | |||
dd1a15478f | |||
8767419289 | |||
bcb7012a32 | |||
78783c5183 | |||
1bb7abe271 | |||
3968821834 | |||
ec5ec746d9 | |||
a4aaec6a23 | |||
976aca4781 | |||
90f869e772 | |||
72c25f2fdb | |||
a07f3c16a5 | |||
37af4c9d2f | |||
5e3189f2f1 | |||
b76c95206c | |||
8ae5be5659 | |||
6ffe081fd2 | |||
2d0b8c7e81 | |||
9a37a020d2 | |||
cf93d473fb | |||
659e9a51dd | |||
8900e8fca9 | |||
064aa692f9 | |||
57c96aa4e3 | |||
f8b72db3c6 | |||
100001389b | |||
8c85642b04 | |||
bae722f1c1 | |||
fa852c955f | |||
1ded874ce1 | |||
470cbedd8a | |||
7f2bf4e401 | |||
ad07421931 | |||
537384da7d | |||
394c32ddfc | |||
86c87aaeee | |||
0ac788f666 | |||
e25ef9e6d0 | |||
9e2b2bff70 | |||
17581ec74d | |||
31ab456a3a | |||
681b1214cf | |||
d777949bf5 | |||
1a7a928b64 | |||
4967f19513 | |||
2a94977f60 | |||
e325872f4e | |||
e687951c0f | |||
8cc9e955dc | |||
29e3d0e75f | |||
7f54a357a4 | |||
c9ae74f012 | |||
c6c3be12b9 | |||
e9f1b5e838 | |||
ec7a51b263 | |||
6cd0d7c3db | |||
1879a5c93d | |||
1b67e41c82 | |||
f43352b752 | |||
47b34df897 | |||
7611f483ae | |||
1e48761177 | |||
06125d22e1 | |||
cf713a88c8 | |||
e094e19f17 | |||
0df54ea169 | |||
93c97aac1c | |||
232ab09694 | |||
146878768c | |||
1f53f28481 | |||
5a2580db7e | |||
298a6f8910 | |||
eda687069a | |||
9612ac89b7 | |||
c32a9be28b | |||
832edd2c63 | |||
908ee03db4 | |||
76637cbd5b | |||
f2e1016ea5 | |||
8ac2a69553 | |||
5dbcf201b8 | |||
604abf0a96 | |||
dc707a3121 | |||
b499befa9b | |||
895fba0ded | |||
67e7706728 | |||
99b5be0037 | |||
3397208d12 | |||
131c87b127 | |||
87c9a8a8fa | |||
90e77cdaaf | |||
59264b0254 | |||
d1e7aefed7 | |||
ae27682601 | |||
dd64404823 | |||
146c493b30 | |||
1f204676e6 | |||
ecc96060da | |||
a761281d8c | |||
5abe013f78 | |||
92aa3b5e14 | |||
61132a7172 | |||
4b9f70236f | |||
ce64a26ce3 | |||
77015e05be | |||
0c5f0f8bf8 | |||
3f89e22174 | |||
986b2a2699 | |||
55eca6830d | |||
39c1de2e6d | |||
703ce7ed14 | |||
df0c8aedda | |||
40665eaf3a | |||
bac6aece9e | |||
f6d705f577 | |||
d2bf40c0b3 | |||
4aefc0ea3b | |||
bcadf08fa6 | |||
92772e2aba | |||
edee32ac07 | |||
cd9f890400 | |||
66b3e68bc4 | |||
d64a825b0a | |||
2fcb386dcf | |||
fbac930d7c | |||
d349cdc08f | |||
a0b8025ad8 | |||
5784081147 | |||
d3c5f26fa4 | |||
bcae3a4def | |||
7e06b32ce3 | |||
2326f91bc9 | |||
c070e7152b | |||
3735cfe548 | |||
d9c7b589a0 | |||
5570003949 | |||
96b9e89015 | |||
c6b03a3f94 | |||
0a262244e6 | |||
ebe0d9a6cb | |||
970fef63c0 | |||
f14a85311f | |||
92db9730e0 | |||
ee535efb5c | |||
96679576d0 | |||
1bf59ac227 | |||
be4d3b6cb8 | |||
60606e5ad0 | |||
22b427df0f | |||
6e5be78838 | |||
e2452c0dfc | |||
56a7ae8712 | |||
e4b008e712 | |||
76afaf2d6b | |||
dccb4e8608 | |||
c2346c37da | |||
3491ca7845 | |||
0e341a6192 | |||
76cd2e2375 | |||
9f7ff009c6 | |||
704b71dabe | |||
7c0572172c | |||
f57c36782f | |||
3054bdf5a5 | |||
1014ba40af | |||
d6b91872cb | |||
d6b383f84b | |||
cadbad8850 | |||
3cbfa2ffef | |||
360e04fa36 | |||
57145ade6f | |||
f39024675c | |||
f7fb00632e | |||
7e40de226f | |||
ae240a3902 | |||
1287c52933 | |||
25bd585c25 | |||
d79a1f3d10 | |||
831f0ac29a | |||
ee3bb16c77 | |||
d8dca9c73b | |||
c3f3497048 | |||
18c3345451 | |||
b07f1c11fe | |||
2685a5dd7b | |||
675a40b257 | |||
3570d48eb9 | |||
f76ec4f50b | |||
fb6d5ad234 | |||
219ff3005b | |||
ccab428e4d | |||
d2d24a14e0 | |||
af11921535 | |||
82112384ca | |||
99aa866477 | |||
82670b96f8 | |||
9e7b13e46d | |||
2243081f85 | |||
1f4491f4ee | |||
aa529eb5a0 | |||
a9cb7c6d6f | |||
45d47e2be0 | |||
99c94bb482 | |||
f98fc7ee9f | |||
0957776855 | |||
d93245d0f5 | |||
c917ed2504 | |||
ee88c42c3b | |||
837cc3d271 | |||
9b2ae12fb7 | |||
86e221d087 | |||
663effa00e | |||
6f237a8415 | |||
c3c38a8eb5 | |||
8fcc914853 | |||
d03f8f1277 | |||
882b12c44e | |||
93d850f783 | |||
4f48caca2c | |||
80e9e42c3b | |||
494061af26 | |||
2fd3d042b2 | |||
b551310c37 | |||
f30edd040e | |||
b7c5e502e7 | |||
fa8a1c38d5 | |||
d56267bd8c | |||
1f6b0b35f8 | |||
342b9cf2d8 | |||
11d071b1c8 | |||
f48d9016fd | |||
a55265f74b | |||
c1a7198e7d | |||
4d4a1fde36 | |||
d219e56872 | |||
19ccc479c3 | |||
c18d50cb91 | |||
80418fadcf | |||
8b6d020352 | |||
5197916983 | |||
7e9d42da68 | |||
e34e0b45de | |||
ef2b54547e | |||
9856f0cc28 | |||
daa8c55667 | |||
af7ec4ead1 | |||
9e65ed1af1 | |||
7a92f89d12 | |||
5871ca9ce9 | |||
0dfa5babc2 | |||
e4b2ce4e81 | |||
7af4490fcc | |||
4204869ec9 | |||
ab23e8a656 | |||
5999b7ba46 | |||
7b613c1238 | |||
cee2359e33 | |||
37a7fb3d6a | |||
9d547a8a44 | |||
1fd5cd79c5 |
2
.github/scripts/install-platformio-esp32.sh
vendored
2
.github/scripts/install-platformio-esp32.sh
vendored
@ -13,7 +13,7 @@ echo "Installing Platform ESP32 ..."
|
||||
python -m platformio platform install $PLATFORMIO_ESP32_URL > /dev/null 2>&1
|
||||
|
||||
echo "Replacing the framework version ..."
|
||||
python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif32']['version'] = '*'; del data['packages']['framework-arduinoespressif32']['owner']; fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()"
|
||||
python -c "import json; import os; fp=open(os.path.expanduser('~/.platformio/platforms/espressif32/platform.json'), 'r+'); data=json.load(fp); data['packages']['framework-arduinoespressif32']['version'] = '*'; fp.seek(0); fp.truncate(); json.dump(data, fp); fp.close()"
|
||||
|
||||
if [ "$GITHUB_REPOSITORY" == "espressif/arduino-esp32" ]; then
|
||||
echo "Linking Core..."
|
||||
|
2
.github/scripts/on-release.sh
vendored
2
.github/scripts/on-release.sh
vendored
@ -330,7 +330,7 @@ fi
|
||||
if [ ! -z "$COMMITS_SINCE_RELEASE" ] && [ "$COMMITS_SINCE_RELEASE" != "null" ]; then
|
||||
echo "Getting commits since $COMMITS_SINCE_RELEASE ..."
|
||||
commitFile=$OUTPUT_DIR/commits.txt
|
||||
git -C "$GITHUB_WORKSPACE" log --oneline $COMMITS_SINCE_RELEASE.. > "$OUTPUT_DIR/commits.txt"
|
||||
git -C "$GITHUB_WORKSPACE" log --oneline "$COMMITS_SINCE_RELEASE..HEAD" > "$OUTPUT_DIR/commits.txt"
|
||||
releaseNotes+=$'\r\n##### Commits\r\n'
|
||||
IFS=$'\n'
|
||||
for next in `cat $commitFile`
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,3 +16,4 @@ __vm/
|
||||
.vscode/
|
||||
platform.sloeber.txt
|
||||
boards.sloeber.txt
|
||||
tools/mklittlefs
|
||||
|
117
CMakeLists.txt
117
CMakeLists.txt
@ -1,8 +1,5 @@
|
||||
set(CORE_SRCS
|
||||
cores/esp32/base64.cpp
|
||||
cores/esp32/cbuf.cpp
|
||||
cores/esp32/esp32-hal-adc.c
|
||||
cores/esp32/esp32-hal-bt.c
|
||||
cores/esp32/esp32-hal-cpu.c
|
||||
cores/esp32/esp32-hal-dac.c
|
||||
cores/esp32/esp32-hal-gpio.c
|
||||
@ -13,144 +10,34 @@ set(CORE_SRCS
|
||||
cores/esp32/esp32-hal-psram.c
|
||||
cores/esp32/esp32-hal-sigmadelta.c
|
||||
cores/esp32/esp32-hal-spi.c
|
||||
cores/esp32/esp32-hal-time.c
|
||||
cores/esp32/esp32-hal-timer.c
|
||||
cores/esp32/esp32-hal-tinyusb.c
|
||||
cores/esp32/esp32-hal-touch.c
|
||||
cores/esp32/esp32-hal-uart.c
|
||||
cores/esp32/esp32-hal-rmt.c
|
||||
cores/esp32/Esp.cpp
|
||||
cores/esp32/FunctionalInterrupt.cpp
|
||||
cores/esp32/HardwareSerial.cpp
|
||||
cores/esp32/IPAddress.cpp
|
||||
cores/esp32/IPv6Address.cpp
|
||||
cores/esp32/libb64/cdecode.c
|
||||
cores/esp32/libb64/cencode.c
|
||||
cores/esp32/main.cpp
|
||||
cores/esp32/MD5Builder.cpp
|
||||
cores/esp32/Print.cpp
|
||||
cores/esp32/stdlib_noniso.c
|
||||
cores/esp32/Stream.cpp
|
||||
cores/esp32/StreamString.cpp
|
||||
cores/esp32/USB.cpp
|
||||
cores/esp32/USBCDC.cpp
|
||||
cores/esp32/wiring_pulse.c
|
||||
cores/esp32/wiring_shift.c
|
||||
cores/esp32/WMath.cpp
|
||||
cores/esp32/WString.cpp
|
||||
)
|
||||
|
||||
set(LIBRARY_SRCS
|
||||
libraries/ArduinoOTA/src/ArduinoOTA.cpp
|
||||
libraries/AsyncUDP/src/AsyncUDP.cpp
|
||||
libraries/BluetoothSerial/src/BluetoothSerial.cpp
|
||||
libraries/DNSServer/src/DNSServer.cpp
|
||||
libraries/EEPROM/src/EEPROM.cpp
|
||||
libraries/ESPmDNS/src/ESPmDNS.cpp
|
||||
libraries/FFat/src/FFat.cpp
|
||||
libraries/FS/src/FS.cpp
|
||||
libraries/FS/src/vfs_api.cpp
|
||||
libraries/HTTPClient/src/HTTPClient.cpp
|
||||
libraries/HTTPUpdate/src/HTTPUpdate.cpp
|
||||
libraries/LITTLEFS/src/LITTLEFS.cpp
|
||||
libraries/NetBIOS/src/NetBIOS.cpp
|
||||
libraries/Preferences/src/Preferences.cpp
|
||||
libraries/SD_MMC/src/SD_MMC.cpp
|
||||
libraries/SD/src/SD.cpp
|
||||
libraries/SD/src/sd_diskio.cpp
|
||||
libraries/SD/src/sd_diskio_crc.c
|
||||
libraries/SimpleBLE/src/SimpleBLE.cpp
|
||||
libraries/SPIFFS/src/SPIFFS.cpp
|
||||
libraries/SPI/src/SPI.cpp
|
||||
libraries/Ticker/src/Ticker.cpp
|
||||
libraries/Update/src/Updater.cpp
|
||||
libraries/WebServer/src/WebServer.cpp
|
||||
libraries/WebServer/src/Parsing.cpp
|
||||
libraries/WebServer/src/detail/mimetable.cpp
|
||||
libraries/WiFiClientSecure/src/ssl_client.cpp
|
||||
libraries/WiFiClientSecure/src/WiFiClientSecure.cpp
|
||||
libraries/WiFi/src/ETH.cpp
|
||||
libraries/WiFi/src/WiFiAP.cpp
|
||||
libraries/WiFi/src/WiFiClient.cpp
|
||||
libraries/WiFi/src/WiFi.cpp
|
||||
libraries/WiFi/src/WiFiGeneric.cpp
|
||||
libraries/WiFi/src/WiFiMulti.cpp
|
||||
libraries/WiFi/src/WiFiProv.cpp
|
||||
libraries/WiFi/src/WiFiScan.cpp
|
||||
libraries/WiFi/src/WiFiServer.cpp
|
||||
libraries/WiFi/src/WiFiSTA.cpp
|
||||
libraries/WiFi/src/WiFiUdp.cpp
|
||||
libraries/Wire/src/Wire.cpp
|
||||
)
|
||||
|
||||
set(BLE_SRCS
|
||||
libraries/BLE/src/BLE2902.cpp
|
||||
libraries/BLE/src/BLE2904.cpp
|
||||
libraries/BLE/src/BLEAddress.cpp
|
||||
libraries/BLE/src/BLEAdvertisedDevice.cpp
|
||||
libraries/BLE/src/BLEAdvertising.cpp
|
||||
libraries/BLE/src/BLEBeacon.cpp
|
||||
libraries/BLE/src/BLECharacteristic.cpp
|
||||
libraries/BLE/src/BLECharacteristicMap.cpp
|
||||
libraries/BLE/src/BLEClient.cpp
|
||||
libraries/BLE/src/BLEDescriptor.cpp
|
||||
libraries/BLE/src/BLEDescriptorMap.cpp
|
||||
libraries/BLE/src/BLEDevice.cpp
|
||||
libraries/BLE/src/BLEEddystoneTLM.cpp
|
||||
libraries/BLE/src/BLEEddystoneURL.cpp
|
||||
libraries/BLE/src/BLEExceptions.cpp
|
||||
libraries/BLE/src/BLEHIDDevice.cpp
|
||||
libraries/BLE/src/BLERemoteCharacteristic.cpp
|
||||
libraries/BLE/src/BLERemoteDescriptor.cpp
|
||||
libraries/BLE/src/BLERemoteService.cpp
|
||||
libraries/BLE/src/BLEScan.cpp
|
||||
libraries/BLE/src/BLESecurity.cpp
|
||||
libraries/BLE/src/BLEServer.cpp
|
||||
libraries/BLE/src/BLEService.cpp
|
||||
libraries/BLE/src/BLEServiceMap.cpp
|
||||
libraries/BLE/src/BLEUtils.cpp
|
||||
libraries/BLE/src/BLEUUID.cpp
|
||||
libraries/BLE/src/BLEValue.cpp
|
||||
libraries/BLE/src/FreeRTOS.cpp
|
||||
libraries/BLE/src/GeneralUtils.cpp
|
||||
)
|
||||
|
||||
|
||||
set(includedirs
|
||||
variants/esp32/
|
||||
cores/esp32/
|
||||
libraries/ArduinoOTA/src
|
||||
libraries/AsyncUDP/src
|
||||
libraries/BLE/src
|
||||
libraries/BluetoothSerial/src
|
||||
libraries/DNSServer/src
|
||||
libraries/EEPROM/src
|
||||
libraries/ESP32/src
|
||||
libraries/ESPmDNS/src
|
||||
libraries/FFat/src
|
||||
libraries/FS/src
|
||||
libraries/HTTPClient/src
|
||||
libraries/HTTPUpdate/src
|
||||
libraries/LITTLEFS/src
|
||||
libraries/NetBIOS/src
|
||||
libraries/Preferences/src
|
||||
libraries/SD_MMC/src
|
||||
libraries/SD/src
|
||||
libraries/SimpleBLE/src
|
||||
libraries/SPIFFS/src
|
||||
libraries/SPI/src
|
||||
libraries/Ticker/src
|
||||
libraries/Update/src
|
||||
libraries/WebServer/src
|
||||
libraries/WiFiClientSecure/src
|
||||
libraries/WiFi/src
|
||||
libraries/Wire/src
|
||||
)
|
||||
|
||||
set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS})
|
||||
set(priv_includes cores/esp32/libb64)
|
||||
set(requires spi_flash mbedtls mdns esp_adc_cal)
|
||||
set(priv_requires fatfs nvs_flash app_update spiffs bootloader_support openssl bt tinyusb main)
|
||||
set(requires spi_flash mbedtls esp_adc_cal wifi_provisioning)
|
||||
set(priv_requires nvs_flash bootloader_support tinyusb espcpputils fmt)
|
||||
|
||||
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
|
||||
|
||||
|
@ -9,79 +9,6 @@ config ENABLE_ARDUINO_DEPENDS
|
||||
select MEMMAP_SMP
|
||||
default "y"
|
||||
|
||||
config AUTOSTART_ARDUINO
|
||||
bool "Autostart Arduino setup and loop on boot"
|
||||
default "n"
|
||||
help
|
||||
Enabling this option will implement app_main and start Arduino.
|
||||
All you need to implement in your main.cpp is setup() and loop()
|
||||
and include Arduino.h
|
||||
If disabled, you can call initArduino() to run any preparations
|
||||
required by the framework
|
||||
|
||||
choice ARDUINO_RUNNING_CORE
|
||||
bool "Core on which Arduino's setup() and loop() are running"
|
||||
default ARDUINO_RUN_CORE1
|
||||
help
|
||||
Select on which core Arduino's setup() and loop() functions run
|
||||
|
||||
config ARDUINO_RUN_CORE0
|
||||
bool "CORE 0"
|
||||
config ARDUINO_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
config ARDUINO_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
|
||||
endchoice
|
||||
|
||||
config ARDUINO_RUNNING_CORE
|
||||
int
|
||||
default 0 if ARDUINO_RUN_CORE0
|
||||
default 1 if ARDUINO_RUN_CORE1
|
||||
default -1 if ARDUINO_RUN_NO_AFFINITY
|
||||
|
||||
choice ARDUINO_EVENT_RUNNING_CORE
|
||||
bool "Core on which Arduino's event handler is running"
|
||||
default ARDUINO_EVENT_RUN_CORE1
|
||||
help
|
||||
Select on which core Arduino's WiFi.onEvent() run
|
||||
|
||||
config ARDUINO_EVENT_RUN_CORE0
|
||||
bool "CORE 0"
|
||||
config ARDUINO_EVENT_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
config ARDUINO_EVENT_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
|
||||
endchoice
|
||||
|
||||
config ARDUINO_EVENT_RUNNING_CORE
|
||||
int
|
||||
default 0 if ARDUINO_EVENT_RUN_CORE0
|
||||
default 1 if ARDUINO_EVENT_RUN_CORE1
|
||||
default -1 if ARDUINO_EVENT_RUN_NO_AFFINITY
|
||||
|
||||
choice ARDUINO_UDP_RUNNING_CORE
|
||||
bool "Core on which Arduino's UDP is running"
|
||||
default ARDUINO_UDP_RUN_CORE1
|
||||
help
|
||||
Select on which core Arduino's UDP run
|
||||
|
||||
config ARDUINO_UDP_RUN_CORE0
|
||||
bool "CORE 0"
|
||||
config ARDUINO_UDP_RUN_CORE1
|
||||
bool "CORE 1"
|
||||
config ARDUINO_UDP_RUN_NO_AFFINITY
|
||||
bool "BOTH"
|
||||
|
||||
endchoice
|
||||
|
||||
config ARDUINO_UDP_RUNNING_CORE
|
||||
int
|
||||
default 0 if ARDUINO_UDP_RUN_CORE0
|
||||
default 1 if ARDUINO_UDP_RUN_CORE1
|
||||
default -1 if ARDUINO_UDP_RUN_NO_AFFINITY
|
||||
|
||||
config ARDUINO_ISR_IRAM
|
||||
bool "Run interrupts in IRAM"
|
||||
default "n"
|
||||
@ -151,142 +78,15 @@ config ARDUHAL_ESP_LOG
|
||||
|
||||
endmenu
|
||||
|
||||
choice ARDUHAL_PARTITION_SCHEME
|
||||
bool "Used partition scheme"
|
||||
default ARDUHAL_PARTITION_SCHEME_DEFAULT
|
||||
help
|
||||
Specify which partition scheme to be used.
|
||||
|
||||
config ARDUHAL_PARTITION_SCHEME_DEFAULT
|
||||
bool "Default"
|
||||
config ARDUHAL_PARTITION_SCHEME_MINIMAL
|
||||
bool "Minimal (for 2MB FLASH)"
|
||||
config ARDUHAL_PARTITION_SCHEME_NO_OTA
|
||||
bool "No OTA (for large apps)"
|
||||
config ARDUHAL_PARTITION_SCHEME_HUGE_APP
|
||||
bool "Huge App (for very large apps)"
|
||||
config ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS
|
||||
bool "Minimal SPIFFS (for large apps with OTA)"
|
||||
endchoice
|
||||
|
||||
config ARDUHAL_PARTITION_SCHEME
|
||||
string
|
||||
default "default" if ARDUHAL_PARTITION_SCHEME_DEFAULT
|
||||
default "minimal" if ARDUHAL_PARTITION_SCHEME_MINIMAL
|
||||
default "no_ota" if ARDUHAL_PARTITION_SCHEME_NO_OTA
|
||||
default "huge_app" if ARDUHAL_PARTITION_SCHEME_HUGE_APP
|
||||
default "min_spiffs" if ARDUHAL_PARTITION_SCHEME_MIN_SPIFFS
|
||||
|
||||
|
||||
config AUTOCONNECT_WIFI
|
||||
bool "Autoconnect WiFi on boot"
|
||||
default "n"
|
||||
depends on AUTOSTART_ARDUINO
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
help
|
||||
If enabled, WiFi will connect to the last used SSID (if station was enabled),
|
||||
else connection will be started only after calling WiFi.begin(ssid, password)
|
||||
|
||||
config ARDUINO_SELECTIVE_COMPILATION
|
||||
bool "Include only specific Arduino libraries"
|
||||
default n
|
||||
|
||||
config ARDUINO_SELECTIVE_ArduinoOTA
|
||||
bool "Enable ArduinoOTA"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
select ARDUINO_SELECTIVE_ESPmDNS
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_AsyncUDP
|
||||
bool "Enable AsyncUDP"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_AzureIoT
|
||||
bool "Enable AzureIoT"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_HTTPClient
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_BLE
|
||||
bool "Enable BLE"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_BluetoothSerial
|
||||
bool "Enable BluetoothSerial"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_DNSServer
|
||||
bool "Enable DNSServer"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_EEPROM
|
||||
bool "Enable EEPROM"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_ESP32
|
||||
bool "Enable ESP32"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_ESPmDNS
|
||||
bool "Enable ESPmDNS"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_FFat
|
||||
bool "Enable FFat"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_FS
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_FS
|
||||
bool "Enable FS"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_HTTPClient
|
||||
bool "Enable HTTPClient"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
select ARDUINO_SELECTIVE_WiFiClientSecure
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_NetBIOS
|
||||
bool "Enable NetBIOS"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_Preferences
|
||||
bool "Enable Preferences"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_SD
|
||||
bool "Enable SD"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_FS
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_SD_MMC
|
||||
bool "Enable SD_MMC"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_FS
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_SimpleBLE
|
||||
bool "Enable SimpleBLE"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_SPI
|
||||
bool "Enable SPI"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
@ -298,33 +98,6 @@ config ARDUINO_SELECTIVE_SPIFFS
|
||||
select ARDUINO_SELECTIVE_FS
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_Ticker
|
||||
bool "Enable Ticker"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_Update
|
||||
bool "Enable Update"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_WebServer
|
||||
bool "Enable WebServer"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
select ARDUINO_SELECTIVE_FS
|
||||
|
||||
config ARDUINO_SELECTIVE_WiFi
|
||||
bool "Enable WiFi"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_WiFiClientSecure
|
||||
bool "Enable WiFiClientSecure"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
select ARDUINO_SELECTIVE_WiFi
|
||||
default y
|
||||
|
||||
config ARDUINO_SELECTIVE_Wire
|
||||
bool "Enable Wire"
|
||||
depends on ARDUINO_SELECTIVE_COMPILATION
|
||||
|
@ -11,9 +11,11 @@
|
||||
- [ESP32Dev Board PINMAP](#esp32dev-board-pinmap)
|
||||
|
||||
### Development Status
|
||||
[Latest stable release  ](https://github.com/espressif/arduino-esp32/releases/latest/) 
|
||||
|
||||
[Latest development release  ](https://github.com/espressif/arduino-esp32/releases/latest/) 
|
||||
Latest Stable Release [](https://github.com/espressif/arduino-esp32/releases/latest/) [](https://github.com/espressif/arduino-esp32/releases/latest/) [](https://github.com/espressif/arduino-esp32/releases/latest/)
|
||||
|
||||
Latest Development Release [](https://github.com/espressif/arduino-esp32/releases/latest/) [](https://github.com/espressif/arduino-esp32/releases/latest/) [](https://github.com/espressif/arduino-esp32/releases/latest/)
|
||||
|
||||
|
||||
### Installation Instructions
|
||||
- Using Arduino IDE Boards Manager (preferred)
|
||||
|
1243
boards.txt
1243
boards.txt
File diff suppressed because it is too large
Load Diff
@ -1,189 +0,0 @@
|
||||
/*
|
||||
Arduino.h - Main include file for the Arduino SDK
|
||||
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Arduino_h
|
||||
#define Arduino_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "esp8266-compat.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
|
||||
#include "stdlib_noniso.h"
|
||||
#include "binary.h"
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define HALF_PI 1.5707963267948966192313216916398
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105
|
||||
#define EULER 2.718281828459045235360287471352
|
||||
|
||||
#define SERIAL 0x0
|
||||
#define DISPLAY 0x1
|
||||
|
||||
#define LSBFIRST 0
|
||||
#define MSBFIRST 1
|
||||
|
||||
//Interrupt Modes
|
||||
#define RISING 0x01
|
||||
#define FALLING 0x02
|
||||
#define CHANGE 0x03
|
||||
#define ONLOW 0x04
|
||||
#define ONHIGH 0x05
|
||||
#define ONLOW_WE 0x0C
|
||||
#define ONHIGH_WE 0x0D
|
||||
|
||||
#define DEFAULT 1
|
||||
#define EXTERNAL 0
|
||||
|
||||
#ifndef __STRINGIFY
|
||||
#define __STRINGIFY(a) #a
|
||||
#endif
|
||||
|
||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||
#define sq(x) ((x)*(x))
|
||||
|
||||
#define sei()
|
||||
#define cli()
|
||||
#define interrupts() sei()
|
||||
#define noInterrupts() cli()
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
||||
|
||||
#define lowByte(w) ((uint8_t) ((w) & 0xff))
|
||||
#define highByte(w) ((uint8_t) ((w) >> 8))
|
||||
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||
|
||||
// avr-libc defines _NOP() since 1.6.2
|
||||
#ifndef _NOP
|
||||
#define _NOP() do { __asm__ volatile ("nop"); } while (0)
|
||||
#endif
|
||||
|
||||
#define bit(b) (1UL << (b))
|
||||
#define _BV(b) (1UL << (b))
|
||||
|
||||
#define digitalPinToPort(pin) (((pin)>31)?1:0)
|
||||
#define digitalPinToBitMask(pin) (1UL << (((pin)>31)?((pin)-32):(pin)))
|
||||
#define digitalPinToTimer(pin) (0)
|
||||
#define analogInPinToBit(P) (P)
|
||||
#define portOutputRegister(port) ((volatile uint32_t*)((port)?GPIO_OUT1_REG:GPIO_OUT_REG))
|
||||
#define portInputRegister(port) ((volatile uint32_t*)((port)?GPIO_IN1_REG:GPIO_IN_REG))
|
||||
#define portModeRegister(port) ((volatile uint32_t*)((port)?GPIO_ENABLE1_REG:GPIO_ENABLE_REG))
|
||||
|
||||
#define NOT_A_PIN -1
|
||||
#define NOT_A_PORT -1
|
||||
#define NOT_AN_INTERRUPT -1
|
||||
#define NOT_ON_TIMER 0
|
||||
|
||||
typedef bool boolean;
|
||||
typedef uint8_t byte;
|
||||
typedef unsigned int word;
|
||||
|
||||
#ifdef __cplusplus
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
|
||||
long random(long, long);
|
||||
#endif
|
||||
void randomSeed(unsigned long);
|
||||
long map(long, long, long, long, long);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void init(void);
|
||||
void initVariant(void);
|
||||
void initArduino(void);
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
||||
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "Stream.h"
|
||||
#include "Printable.h"
|
||||
#include "Print.h"
|
||||
#include "IPAddress.h"
|
||||
#include "Client.h"
|
||||
#include "Server.h"
|
||||
#include "Udp.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "Esp.h"
|
||||
|
||||
using std::abs;
|
||||
using std::isinf;
|
||||
using std::isnan;
|
||||
using std::max;
|
||||
using std::min;
|
||||
using ::round;
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
uint16_t makeWord(byte h, byte l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
extern "C" bool getLocalTime(struct tm * info, uint32_t ms = 5000);
|
||||
extern "C" void configTime(long gmtOffset_sec, int daylightOffset_sec,
|
||||
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
|
||||
extern "C" void configTzTime(const char* tz,
|
||||
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define _min(a,b) ((a)<(b)?(a):(b))
|
||||
#define _max(a,b) ((a)>(b)?(a):(b))
|
||||
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif /* _ESP32_CORE_ARDUINO_H_ */
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
Client.h - Base class that provides Client
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef client_h
|
||||
#define client_h
|
||||
#include "Print.h"
|
||||
#include "Stream.h"
|
||||
#include "IPAddress.h"
|
||||
|
||||
class Client: public Stream
|
||||
{
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) =0;
|
||||
virtual int connect(const char *host, uint16_t port) =0;
|
||||
virtual size_t write(uint8_t) =0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr)
|
||||
{
|
||||
return addr.raw_address();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -1,342 +0,0 @@
|
||||
/*
|
||||
Esp.cpp - ESP31B-specific APIs
|
||||
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Esp.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include <memory>
|
||||
#include <soc/soc.h>
|
||||
#include <soc/efuse_reg.h>
|
||||
#include <esp_partition.h>
|
||||
extern "C" {
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_image_format.h"
|
||||
}
|
||||
#include <MD5Builder.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/spi_flash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/spi_flash.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/spi_flash.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* User-defined Literals
|
||||
* usage:
|
||||
*
|
||||
* uint32_t = test = 10_MHz; // --> 10000000
|
||||
*/
|
||||
|
||||
unsigned long long operator"" _kHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000 * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GHz(unsigned long long x)
|
||||
{
|
||||
return x * 1000 * 1000 * 1000;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _kBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GBit(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _kB(unsigned long long x)
|
||||
{
|
||||
return x * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _MB(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024;
|
||||
}
|
||||
|
||||
unsigned long long operator"" _GB(unsigned long long x)
|
||||
{
|
||||
return x * 1024 * 1024 * 1024;
|
||||
}
|
||||
|
||||
|
||||
EspClass ESP;
|
||||
|
||||
void EspClass::deepSleep(uint32_t time_us)
|
||||
{
|
||||
esp_deep_sleep(time_us);
|
||||
}
|
||||
|
||||
void EspClass::restart(void)
|
||||
{
|
||||
esp_restart();
|
||||
}
|
||||
|
||||
uint32_t EspClass::getHeapSize(void)
|
||||
{
|
||||
multi_heap_info_t info;
|
||||
heap_caps_get_info(&info, MALLOC_CAP_INTERNAL);
|
||||
return info.total_free_bytes + info.total_allocated_bytes;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeHeap(void)
|
||||
{
|
||||
return heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getMinFreeHeap(void)
|
||||
{
|
||||
return heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getMaxAllocHeap(void)
|
||||
{
|
||||
return heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getPsramSize(void)
|
||||
{
|
||||
if(psramFound()){
|
||||
multi_heap_info_t info;
|
||||
heap_caps_get_info(&info, MALLOC_CAP_SPIRAM);
|
||||
return info.total_free_bytes + info.total_allocated_bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreePsram(void)
|
||||
{
|
||||
if(psramFound()){
|
||||
return heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getMinFreePsram(void)
|
||||
{
|
||||
if(psramFound()){
|
||||
return heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getMaxAllocPsram(void)
|
||||
{
|
||||
if(psramFound()){
|
||||
return heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t sketchSize(sketchSize_t response) {
|
||||
esp_image_metadata_t data;
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
if (!running) return 0;
|
||||
const esp_partition_pos_t running_pos = {
|
||||
.offset = running->address,
|
||||
.size = running->size,
|
||||
};
|
||||
data.start_addr = running_pos.offset;
|
||||
esp_image_verify(ESP_IMAGE_VERIFY, &running_pos, &data);
|
||||
if (response) {
|
||||
return running_pos.size - data.image_len;
|
||||
} else {
|
||||
return data.image_len;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t EspClass::getSketchSize () {
|
||||
return sketchSize(SKETCH_SIZE_TOTAL);
|
||||
}
|
||||
|
||||
String EspClass::getSketchMD5()
|
||||
{
|
||||
static String result;
|
||||
if (result.length()) {
|
||||
return result;
|
||||
}
|
||||
uint32_t lengthLeft = getSketchSize();
|
||||
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
if (!running) {
|
||||
log_e("Partition could not be found");
|
||||
|
||||
return String();
|
||||
}
|
||||
const size_t bufSize = SPI_FLASH_SEC_SIZE;
|
||||
std::unique_ptr<uint8_t[]> buf(new uint8_t[bufSize]);
|
||||
uint32_t offset = 0;
|
||||
if(!buf.get()) {
|
||||
log_e("Not enough memory to allocate buffer");
|
||||
|
||||
return String();
|
||||
}
|
||||
MD5Builder md5;
|
||||
md5.begin();
|
||||
while( lengthLeft > 0) {
|
||||
size_t readBytes = (lengthLeft < bufSize) ? lengthLeft : bufSize;
|
||||
if (!ESP.flashRead(running->address + offset, reinterpret_cast<uint32_t*>(buf.get()), (readBytes + 3) & ~3)) {
|
||||
log_e("Could not read buffer from flash");
|
||||
|
||||
return String();
|
||||
}
|
||||
md5.add(buf.get(), readBytes);
|
||||
lengthLeft -= readBytes;
|
||||
offset += readBytes;
|
||||
}
|
||||
md5.calculate();
|
||||
result = md5.toString();
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFreeSketchSpace () {
|
||||
const esp_partition_t* _partition = esp_ota_get_next_update_partition(NULL);
|
||||
if(!_partition){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _partition->size;
|
||||
}
|
||||
|
||||
uint8_t EspClass::getChipRevision(void)
|
||||
{
|
||||
esp_chip_info_t chip_info;
|
||||
esp_chip_info(&chip_info);
|
||||
return chip_info.revision;
|
||||
}
|
||||
|
||||
const char * EspClass::getSdkVersion(void)
|
||||
{
|
||||
return esp_get_idf_version();
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipSize(void)
|
||||
{
|
||||
esp_image_header_t fhdr;
|
||||
if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
return magicFlashChipSize(fhdr.spi_size);
|
||||
}
|
||||
|
||||
uint32_t EspClass::getFlashChipSpeed(void)
|
||||
{
|
||||
esp_image_header_t fhdr;
|
||||
if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
return 0;
|
||||
}
|
||||
return magicFlashChipSpeed(fhdr.spi_speed);
|
||||
}
|
||||
|
||||
FlashMode_t EspClass::getFlashChipMode(void)
|
||||
{
|
||||
esp_image_header_t fhdr;
|
||||
if(flashRead(0x1000, (uint32_t*)&fhdr, sizeof(esp_image_header_t)) && fhdr.magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
return FM_UNKNOWN;
|
||||
}
|
||||
return magicFlashChipMode(fhdr.spi_mode);
|
||||
}
|
||||
|
||||
uint32_t EspClass::magicFlashChipSize(uint8_t byte)
|
||||
{
|
||||
switch(byte & 0x0F) {
|
||||
case 0x0: // 8 MBit (1MB)
|
||||
return (1_MB);
|
||||
case 0x1: // 16 MBit (2MB)
|
||||
return (2_MB);
|
||||
case 0x2: // 32 MBit (4MB)
|
||||
return (4_MB);
|
||||
case 0x3: // 64 MBit (8MB)
|
||||
return (8_MB);
|
||||
case 0x4: // 128 MBit (16MB)
|
||||
return (16_MB);
|
||||
default: // fail?
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t EspClass::magicFlashChipSpeed(uint8_t byte)
|
||||
{
|
||||
switch(byte & 0x0F) {
|
||||
case 0x0: // 40 MHz
|
||||
return (40_MHz);
|
||||
case 0x1: // 26 MHz
|
||||
return (26_MHz);
|
||||
case 0x2: // 20 MHz
|
||||
return (20_MHz);
|
||||
case 0xf: // 80 MHz
|
||||
return (80_MHz);
|
||||
default: // fail?
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
FlashMode_t EspClass::magicFlashChipMode(uint8_t byte)
|
||||
{
|
||||
FlashMode_t mode = (FlashMode_t) byte;
|
||||
if(mode > FM_SLOW_READ) {
|
||||
mode = FM_UNKNOWN;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool EspClass::flashEraseSector(uint32_t sector)
|
||||
{
|
||||
return spi_flash_erase_sector(sector) == ESP_OK;
|
||||
}
|
||||
|
||||
// Warning: These functions do not work with encrypted flash
|
||||
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size)
|
||||
{
|
||||
return spi_flash_write(offset, (uint32_t*) data, size) == ESP_OK;
|
||||
}
|
||||
|
||||
bool EspClass::flashRead(uint32_t offset, uint32_t *data, size_t size)
|
||||
{
|
||||
return spi_flash_read(offset, (uint32_t*) data, size) == ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
uint64_t EspClass::getEfuseMac(void)
|
||||
{
|
||||
uint64_t _chipmacid = 0LL;
|
||||
esp_efuse_mac_get_default((uint8_t*) (&_chipmacid));
|
||||
return _chipmacid;
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
Esp.h - ESP31B-specific APIs
|
||||
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ESP_H
|
||||
#define ESP_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/**
|
||||
* AVR macros for WDT managment
|
||||
*/
|
||||
typedef enum {
|
||||
WDTO_0MS = 0, //!< WDTO_0MS
|
||||
WDTO_15MS = 15, //!< WDTO_15MS
|
||||
WDTO_30MS = 30, //!< WDTO_30MS
|
||||
WDTO_60MS = 60, //!< WDTO_60MS
|
||||
WDTO_120MS = 120, //!< WDTO_120MS
|
||||
WDTO_250MS = 250, //!< WDTO_250MS
|
||||
WDTO_500MS = 500, //!< WDTO_500MS
|
||||
WDTO_1S = 1000,//!< WDTO_1S
|
||||
WDTO_2S = 2000,//!< WDTO_2S
|
||||
WDTO_4S = 4000,//!< WDTO_4S
|
||||
WDTO_8S = 8000 //!< WDTO_8S
|
||||
} WDTO_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
FM_QIO = 0x00,
|
||||
FM_QOUT = 0x01,
|
||||
FM_DIO = 0x02,
|
||||
FM_DOUT = 0x03,
|
||||
FM_FAST_READ = 0x04,
|
||||
FM_SLOW_READ = 0x05,
|
||||
FM_UNKNOWN = 0xff
|
||||
} FlashMode_t;
|
||||
|
||||
typedef enum {
|
||||
SKETCH_SIZE_TOTAL = 0,
|
||||
SKETCH_SIZE_FREE = 1
|
||||
} sketchSize_t;
|
||||
|
||||
class EspClass
|
||||
{
|
||||
public:
|
||||
EspClass() {}
|
||||
~EspClass() {}
|
||||
void restart();
|
||||
|
||||
//Internal RAM
|
||||
uint32_t getHeapSize(); //total heap size
|
||||
uint32_t getFreeHeap(); //available heap
|
||||
uint32_t getMinFreeHeap(); //lowest level of free heap since boot
|
||||
uint32_t getMaxAllocHeap(); //largest block of heap that can be allocated at once
|
||||
|
||||
//SPI RAM
|
||||
uint32_t getPsramSize();
|
||||
uint32_t getFreePsram();
|
||||
uint32_t getMinFreePsram();
|
||||
uint32_t getMaxAllocPsram();
|
||||
|
||||
uint8_t getChipRevision();
|
||||
uint32_t getCpuFreqMHz(){ return getCpuFrequencyMhz(); }
|
||||
inline uint32_t getCycleCount() __attribute__((always_inline));
|
||||
const char * getSdkVersion();
|
||||
|
||||
void deepSleep(uint32_t time_us);
|
||||
|
||||
uint32_t getFlashChipSize();
|
||||
uint32_t getFlashChipSpeed();
|
||||
FlashMode_t getFlashChipMode();
|
||||
|
||||
uint32_t magicFlashChipSize(uint8_t byte);
|
||||
uint32_t magicFlashChipSpeed(uint8_t byte);
|
||||
FlashMode_t magicFlashChipMode(uint8_t byte);
|
||||
|
||||
uint32_t getSketchSize();
|
||||
String getSketchMD5();
|
||||
uint32_t getFreeSketchSpace();
|
||||
|
||||
bool flashEraseSector(uint32_t sector);
|
||||
bool flashWrite(uint32_t offset, uint32_t *data, size_t size);
|
||||
bool flashRead(uint32_t offset, uint32_t *data, size_t size);
|
||||
|
||||
uint64_t getEfuseMac();
|
||||
|
||||
};
|
||||
|
||||
uint32_t ARDUINO_ISR_ATTR EspClass::getCycleCount()
|
||||
{
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
extern EspClass ESP;
|
||||
|
||||
#endif //ESP_H
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "FunctionalInterrupt.h"
|
||||
#include "Arduino.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
typedef void (*voidFuncPtrArg)(void*);
|
||||
|
@ -1,207 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "pins_arduino.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
#ifndef RX1
|
||||
#define RX1 9
|
||||
#endif
|
||||
|
||||
#ifndef TX1
|
||||
#define TX1 10
|
||||
#endif
|
||||
|
||||
#ifndef RX2
|
||||
#define RX2 16
|
||||
#endif
|
||||
|
||||
#ifndef TX2
|
||||
#define TX2 17
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef RX1
|
||||
#define RX1 18
|
||||
#endif
|
||||
|
||||
#ifndef TX1
|
||||
#define TX1 17
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
|
||||
HardwareSerial Serial0(0);
|
||||
#else
|
||||
HardwareSerial Serial(0);
|
||||
#endif
|
||||
HardwareSerial Serial1(1);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
HardwareSerial Serial2(2);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
|
||||
|
||||
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms)
|
||||
{
|
||||
if(0 > _uart_nr || _uart_nr > 2) {
|
||||
log_e("Serial number is invalid, please use 0, 1 or 2");
|
||||
return;
|
||||
}
|
||||
if(_uart) {
|
||||
end();
|
||||
}
|
||||
if(_uart_nr == 0 && rxPin < 0 && txPin < 0) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
rxPin = 3;
|
||||
txPin = 1;
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
rxPin = 44;
|
||||
txPin = 43;
|
||||
#endif
|
||||
}
|
||||
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = RX1;
|
||||
txPin = TX1;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
|
||||
rxPin = RX2;
|
||||
txPin = TX2;
|
||||
}
|
||||
#endif
|
||||
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert);
|
||||
|
||||
if(!baud) {
|
||||
uartStartDetectBaudrate(_uart);
|
||||
time_t startMillis = millis();
|
||||
unsigned long detectedBaudRate = 0;
|
||||
while(millis() - startMillis < timeout_ms && !(detectedBaudRate = uartDetectBaudrate(_uart))) {
|
||||
yield();
|
||||
}
|
||||
|
||||
end();
|
||||
|
||||
if(detectedBaudRate) {
|
||||
delay(100); // Give some time...
|
||||
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert);
|
||||
} else {
|
||||
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
|
||||
_uart = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::updateBaudRate(unsigned long baud)
|
||||
{
|
||||
uartSetBaudRate(_uart, baud);
|
||||
}
|
||||
|
||||
void HardwareSerial::end()
|
||||
{
|
||||
if(uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(0);
|
||||
}
|
||||
uartEnd(_uart);
|
||||
_uart = 0;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
|
||||
return uartResizeRxBuffer(_uart, new_size);
|
||||
}
|
||||
|
||||
void HardwareSerial::setDebugOutput(bool en)
|
||||
{
|
||||
if(_uart == 0) {
|
||||
return;
|
||||
}
|
||||
if(en) {
|
||||
uartSetDebug(_uart);
|
||||
} else {
|
||||
if(uartGetDebug() == _uart_nr) {
|
||||
uartSetDebug(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int HardwareSerial::available(void)
|
||||
{
|
||||
return uartAvailable(_uart);
|
||||
}
|
||||
int HardwareSerial::availableForWrite(void)
|
||||
{
|
||||
return uartAvailableForWrite(_uart);
|
||||
}
|
||||
|
||||
int HardwareSerial::peek(void)
|
||||
{
|
||||
if (available()) {
|
||||
return uartPeek(_uart);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int HardwareSerial::read(void)
|
||||
{
|
||||
if(available()) {
|
||||
return uartRead(_uart);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read characters into buffer
|
||||
// terminates if size characters have been read, or no further are pending
|
||||
// returns the number of characters placed in the buffer
|
||||
// the buffer is NOT null terminated.
|
||||
size_t HardwareSerial::read(uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t avail = available();
|
||||
if (size < avail) {
|
||||
avail = size;
|
||||
}
|
||||
size_t count = 0;
|
||||
while(count < avail) {
|
||||
*buffer++ = uartRead(_uart);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void HardwareSerial::flush(void)
|
||||
{
|
||||
uartFlush(_uart);
|
||||
}
|
||||
|
||||
void HardwareSerial::flush(bool txOnly)
|
||||
{
|
||||
uartFlushTxOnly(_uart, txOnly);
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(uint8_t c)
|
||||
{
|
||||
uartWrite(_uart, c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t HardwareSerial::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
uartWriteBuf(_uart, buffer, size);
|
||||
return size;
|
||||
}
|
||||
uint32_t HardwareSerial::baudRate()
|
||||
|
||||
{
|
||||
return uartGetBaudRate(_uart);
|
||||
}
|
||||
HardwareSerial::operator bool() const
|
||||
{
|
||||
return true;
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
HardwareSerial.h - Hardware serial library for Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 28 September 2010 by Mark Sproul
|
||||
Modified 14 August 2012 by Alarus
|
||||
Modified 3 December 2013 by Matthijs Kooijman
|
||||
Modified 18 December 2014 by Ivan Grokhotkov (esp8266 platform support)
|
||||
Modified 31 March 2015 by Markus Sattler (rewrite the code for UART0 + UART1 support in ESP8266)
|
||||
Modified 25 April 2015 by Thomas Flayols (add configuration different from 8N1 in ESP8266)
|
||||
Modified 13 October 2018 by Jeroen Döll (add baudrate detection)
|
||||
Baudrate detection example usage (detection on Serial1):
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(100);
|
||||
Serial.println();
|
||||
|
||||
Serial1.begin(0, SERIAL_8N1, -1, -1, true, 11000UL); // Passing 0 for baudrate to detect it, the last parameter is a timeout in ms
|
||||
|
||||
unsigned long detectedBaudRate = Serial1.baudRate();
|
||||
if(detectedBaudRate) {
|
||||
Serial.printf("Detected baudrate is %lu\n", detectedBaudRate);
|
||||
} else {
|
||||
Serial.println("No baudrate detected, Serial1 will not work!");
|
||||
}
|
||||
}
|
||||
|
||||
Pay attention: the baudrate returned by baudRate() may be rounded, eg 115200 returns 115201
|
||||
*/
|
||||
|
||||
#ifndef HardwareSerial_h
|
||||
#define HardwareSerial_h
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "Stream.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
class HardwareSerial: public Stream
|
||||
{
|
||||
public:
|
||||
HardwareSerial(int uart_nr);
|
||||
|
||||
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL);
|
||||
void end();
|
||||
void updateBaudRate(unsigned long baud);
|
||||
int available(void);
|
||||
int availableForWrite(void);
|
||||
int peek(void);
|
||||
int read(void);
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
inline size_t read(char * buffer, size_t size)
|
||||
{
|
||||
return read((uint8_t*) buffer, size);
|
||||
}
|
||||
void flush(void);
|
||||
void flush( bool txOnly);
|
||||
size_t write(uint8_t);
|
||||
size_t write(const uint8_t *buffer, size_t size);
|
||||
inline size_t write(const char * buffer, size_t size)
|
||||
{
|
||||
return write((uint8_t*) buffer, size);
|
||||
}
|
||||
inline size_t write(const char * s)
|
||||
{
|
||||
return write((uint8_t*) s, strlen(s));
|
||||
}
|
||||
inline size_t write(unsigned long n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
inline size_t write(long n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
inline size_t write(unsigned int n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
inline size_t write(int n)
|
||||
{
|
||||
return write((uint8_t) n);
|
||||
}
|
||||
uint32_t baudRate();
|
||||
operator bool() const;
|
||||
|
||||
size_t setRxBufferSize(size_t);
|
||||
void setDebugOutput(bool);
|
||||
|
||||
protected:
|
||||
int _uart_nr;
|
||||
uart_t* _uart;
|
||||
};
|
||||
|
||||
extern void serialEventRun(void) __attribute__((weak));
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
|
||||
#ifndef ARDUINO_SERIAL_PORT
|
||||
#define ARDUINO_SERIAL_PORT 0
|
||||
#endif
|
||||
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
|
||||
#include "USB.h"
|
||||
#include "USBCDC.h"
|
||||
extern HardwareSerial Serial0;
|
||||
#else
|
||||
extern HardwareSerial Serial;
|
||||
#endif
|
||||
extern HardwareSerial Serial1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
extern HardwareSerial Serial2;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // HardwareSerial_h
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
IPAddress.cpp - Base class that provides IPAddress
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <IPAddress.h>
|
||||
#include <Print.h>
|
||||
|
||||
IPAddress::IPAddress()
|
||||
{
|
||||
_address.dword = 0;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
|
||||
{
|
||||
_address.bytes[0] = first_octet;
|
||||
_address.bytes[1] = second_octet;
|
||||
_address.bytes[2] = third_octet;
|
||||
_address.bytes[3] = fourth_octet;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint32_t address)
|
||||
{
|
||||
_address.dword = address;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
return *this;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(uint32_t address)
|
||||
{
|
||||
_address.dword = address;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const uint8_t* addr) const
|
||||
{
|
||||
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
|
||||
}
|
||||
|
||||
size_t IPAddress::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
for(int i = 0; i < 3; i++) {
|
||||
n += p.print(_address.bytes[i], DEC);
|
||||
n += p.print('.');
|
||||
}
|
||||
n += p.print(_address.bytes[3], DEC);
|
||||
return n;
|
||||
}
|
||||
|
||||
String IPAddress::toString() const
|
||||
{
|
||||
char szRet[16];
|
||||
sprintf(szRet,"%u.%u.%u.%u", _address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3]);
|
||||
return String(szRet);
|
||||
}
|
||||
|
||||
bool IPAddress::fromString(const char *address)
|
||||
{
|
||||
// TODO: add support for "a", "a.b", "a.b.c" formats
|
||||
|
||||
uint16_t acc = 0; // Accumulator
|
||||
uint8_t dots = 0;
|
||||
|
||||
while (*address)
|
||||
{
|
||||
char c = *address++;
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
acc = acc * 10 + (c - '0');
|
||||
if (acc > 255) {
|
||||
// Value out of [0..255] range
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (c == '.')
|
||||
{
|
||||
if (dots == 3) {
|
||||
// Too much dots (there must be 3 dots)
|
||||
return false;
|
||||
}
|
||||
_address.bytes[dots++] = acc;
|
||||
acc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid char
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (dots != 3) {
|
||||
// Too few dots (there must be 3 dots)
|
||||
return false;
|
||||
}
|
||||
_address.bytes[3] = acc;
|
||||
return true;
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
IPAddress.h - Base class that provides IPAddress
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef IPAddress_h
|
||||
#define IPAddress_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <WString.h>
|
||||
#include <Printable.h>
|
||||
|
||||
// A class to make it easier to handle and pass around IP addresses
|
||||
|
||||
class IPAddress: public Printable
|
||||
{
|
||||
private:
|
||||
union {
|
||||
uint8_t bytes[4]; // IPv4 address
|
||||
uint32_t dword;
|
||||
} _address;
|
||||
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address()
|
||||
{
|
||||
return _address.bytes;
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
IPAddress();
|
||||
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
|
||||
IPAddress(uint32_t address);
|
||||
IPAddress(const uint8_t *address);
|
||||
virtual ~IPAddress() {}
|
||||
|
||||
bool fromString(const char *address);
|
||||
bool fromString(const String &address) { return fromString(address.c_str()); }
|
||||
|
||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
||||
// to a four-byte uint8_t array is expected
|
||||
operator uint32_t() const
|
||||
{
|
||||
return _address.dword;
|
||||
}
|
||||
bool operator==(const IPAddress& addr) const
|
||||
{
|
||||
return _address.dword == addr._address.dword;
|
||||
}
|
||||
bool operator==(const uint8_t* addr) const;
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const
|
||||
{
|
||||
return _address.bytes[index];
|
||||
}
|
||||
uint8_t& operator[](int index)
|
||||
{
|
||||
return _address.bytes[index];
|
||||
}
|
||||
|
||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
||||
IPAddress& operator=(const uint8_t *address);
|
||||
IPAddress& operator=(uint32_t address);
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
String toString() const;
|
||||
|
||||
friend class EthernetClass;
|
||||
friend class UDP;
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
friend class DhcpClass;
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
const IPAddress INADDR_NONE(0, 0, 0, 0);
|
||||
|
||||
#endif
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
IPv6Address.cpp - Base class that provides IPv6Address
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <IPv6Address.h>
|
||||
#include <Print.h>
|
||||
|
||||
IPv6Address::IPv6Address()
|
||||
{
|
||||
memset(_address.bytes, 0, sizeof(_address.bytes));
|
||||
}
|
||||
|
||||
IPv6Address::IPv6Address(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
}
|
||||
|
||||
IPv6Address::IPv6Address(const uint32_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, (const uint8_t *)address, sizeof(_address.bytes));
|
||||
}
|
||||
|
||||
IPv6Address& IPv6Address::operator=(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address.bytes, address, sizeof(_address.bytes));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPv6Address::operator==(const uint8_t* addr) const
|
||||
{
|
||||
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
|
||||
}
|
||||
|
||||
size_t IPv6Address::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
for(int i = 0; i < 16; i+=2) {
|
||||
if(i){
|
||||
n += p.print(':');
|
||||
}
|
||||
n += p.printf("%02x", _address.bytes[i]);
|
||||
n += p.printf("%02x", _address.bytes[i+1]);
|
||||
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
String IPv6Address::toString() const
|
||||
{
|
||||
char szRet[40];
|
||||
sprintf(szRet,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
|
||||
_address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3],
|
||||
_address.bytes[4], _address.bytes[5], _address.bytes[6], _address.bytes[7],
|
||||
_address.bytes[8], _address.bytes[9], _address.bytes[10], _address.bytes[11],
|
||||
_address.bytes[12], _address.bytes[13], _address.bytes[14], _address.bytes[15]);
|
||||
return String(szRet);
|
||||
}
|
||||
|
||||
bool IPv6Address::fromString(const char *address)
|
||||
{
|
||||
//format 0011:2233:4455:6677:8899:aabb:ccdd:eeff
|
||||
if(strlen(address) != 39){
|
||||
return false;
|
||||
}
|
||||
char * pos = (char *)address;
|
||||
size_t i = 0;
|
||||
for(i = 0; i < 16; i+=2) {
|
||||
if(!sscanf(pos, "%2hhx", &_address.bytes[i]) || !sscanf(pos+2, "%2hhx", &_address.bytes[i+1])){
|
||||
return false;
|
||||
}
|
||||
pos += 5;
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
IPv6Address.h - Base class that provides IPv6Address
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef IPv6Address_h
|
||||
#define IPv6Address_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <WString.h>
|
||||
#include <Printable.h>
|
||||
|
||||
// A class to make it easier to handle and pass around IP addresses
|
||||
|
||||
class IPv6Address: public Printable
|
||||
{
|
||||
private:
|
||||
union {
|
||||
uint8_t bytes[16]; // IPv4 address
|
||||
uint32_t dword[4];
|
||||
} _address;
|
||||
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address()
|
||||
{
|
||||
return _address.bytes;
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
IPv6Address();
|
||||
IPv6Address(const uint8_t *address);
|
||||
IPv6Address(const uint32_t *address);
|
||||
virtual ~IPv6Address() {}
|
||||
|
||||
bool fromString(const char *address);
|
||||
bool fromString(const String &address) { return fromString(address.c_str()); }
|
||||
|
||||
operator const uint8_t*() const
|
||||
{
|
||||
return _address.bytes;
|
||||
}
|
||||
operator const uint32_t*() const
|
||||
{
|
||||
return _address.dword;
|
||||
}
|
||||
bool operator==(const IPv6Address& addr) const
|
||||
{
|
||||
return (_address.dword[0] == addr._address.dword[0])
|
||||
&& (_address.dword[1] == addr._address.dword[1])
|
||||
&& (_address.dword[2] == addr._address.dword[2])
|
||||
&& (_address.dword[3] == addr._address.dword[3]);
|
||||
}
|
||||
bool operator==(const uint8_t* addr) const;
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const
|
||||
{
|
||||
return _address.bytes[index];
|
||||
}
|
||||
uint8_t& operator[](int index)
|
||||
{
|
||||
return _address.bytes[index];
|
||||
}
|
||||
|
||||
// Overloaded copy operators to allow initialisation of IPv6Address objects from other types
|
||||
IPv6Address& operator=(const uint8_t *address);
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
String toString() const;
|
||||
|
||||
friend class UDP;
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,117 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
#include <MD5Builder.h>
|
||||
|
||||
uint8_t hex_char_to_byte(uint8_t c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
|
||||
(c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
|
||||
(c >= '0' && c<= '9') ? (c - (uint8_t)'0') : 0;
|
||||
}
|
||||
|
||||
void MD5Builder::begin(void)
|
||||
{
|
||||
memset(_buf, 0x00, 16);
|
||||
MD5Init(&_ctx);
|
||||
}
|
||||
|
||||
void MD5Builder::add(uint8_t * data, uint16_t len)
|
||||
{
|
||||
MD5Update(&_ctx, data, len);
|
||||
}
|
||||
|
||||
void MD5Builder::addHexString(const char * data)
|
||||
{
|
||||
uint16_t i, len = strlen(data);
|
||||
uint8_t * tmp = (uint8_t*)malloc(len/2);
|
||||
if(tmp == NULL) {
|
||||
return;
|
||||
}
|
||||
for(i=0; i<len; i+=2) {
|
||||
uint8_t high = hex_char_to_byte(data[i]);
|
||||
uint8_t low = hex_char_to_byte(data[i+1]);
|
||||
tmp[i/2] = (high & 0x0F) << 4 | (low & 0x0F);
|
||||
}
|
||||
add(tmp, len/2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
|
||||
{
|
||||
const int buf_size = 512;
|
||||
int maxLengthLeft = maxLen;
|
||||
uint8_t * buf = (uint8_t*) malloc(buf_size);
|
||||
|
||||
if(!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int bytesAvailable = stream.available();
|
||||
while((bytesAvailable > 0) && (maxLengthLeft > 0)) {
|
||||
|
||||
// determine number of bytes to read
|
||||
int readBytes = bytesAvailable;
|
||||
if(readBytes > maxLengthLeft) {
|
||||
readBytes = maxLengthLeft ; // read only until max_len
|
||||
}
|
||||
if(readBytes > buf_size) {
|
||||
readBytes = buf_size; // not read more the buffer can handle
|
||||
}
|
||||
|
||||
// read data and check if we got something
|
||||
int numBytesRead = stream.readBytes(buf, readBytes);
|
||||
if(numBytesRead< 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update MD5 with buffer payload
|
||||
MD5Update(&_ctx, buf, numBytesRead);
|
||||
|
||||
// update available number of bytes
|
||||
maxLengthLeft -= numBytesRead;
|
||||
bytesAvailable = stream.available();
|
||||
}
|
||||
free(buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MD5Builder::calculate(void)
|
||||
{
|
||||
MD5Final(_buf, &_ctx);
|
||||
}
|
||||
|
||||
void MD5Builder::getBytes(uint8_t * output)
|
||||
{
|
||||
memcpy(output, _buf, 16);
|
||||
}
|
||||
|
||||
void MD5Builder::getChars(char * output)
|
||||
{
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
sprintf(output + (i * 2), "%02x", _buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
String MD5Builder::toString(void)
|
||||
{
|
||||
char out[33];
|
||||
getChars(out);
|
||||
return String(out);
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __ESP8266_MD5_BUILDER__
|
||||
#define __ESP8266_MD5_BUILDER__
|
||||
|
||||
#include <WString.h>
|
||||
#include <Stream.h>
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/md5_hash.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/md5_hash.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/md5_hash.h"
|
||||
#endif
|
||||
|
||||
class MD5Builder
|
||||
{
|
||||
private:
|
||||
struct MD5Context _ctx;
|
||||
uint8_t _buf[16];
|
||||
public:
|
||||
void begin(void);
|
||||
void add(uint8_t * data, uint16_t len);
|
||||
void add(const char * data)
|
||||
{
|
||||
add((uint8_t*)data, strlen(data));
|
||||
}
|
||||
void add(char * data)
|
||||
{
|
||||
add((const char*)data);
|
||||
}
|
||||
void add(String data)
|
||||
{
|
||||
add(data.c_str());
|
||||
}
|
||||
void addHexString(const char * data);
|
||||
void addHexString(char * data)
|
||||
{
|
||||
addHexString((const char*)data);
|
||||
}
|
||||
void addHexString(String data)
|
||||
{
|
||||
addHexString(data.c_str());
|
||||
}
|
||||
bool addStream(Stream & stream, const size_t maxLen);
|
||||
void calculate(void);
|
||||
void getBytes(uint8_t * output);
|
||||
void getChars(char * output);
|
||||
String toString(void);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,324 +0,0 @@
|
||||
/*
|
||||
Print.cpp - Base class that provides print() and println()
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 23 November 2006 by David A. Mellis
|
||||
Modified December 2014 by Ivan Grokhotkov
|
||||
Modified May 2015 by Michael C. Miller - ESP31B progmem support
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "Arduino.h"
|
||||
|
||||
#include "Print.h"
|
||||
extern "C" {
|
||||
#include "time.h"
|
||||
}
|
||||
|
||||
// Public Methods //////////////////////////////////////////////////////////////
|
||||
|
||||
/* default implementation: may be overridden */
|
||||
size_t Print::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t n = 0;
|
||||
while(size--) {
|
||||
n += write(*buffer++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::printf(const char *format, ...)
|
||||
{
|
||||
char loc_buf[64];
|
||||
char * temp = loc_buf;
|
||||
va_list arg;
|
||||
va_list copy;
|
||||
va_start(arg, format);
|
||||
va_copy(copy, arg);
|
||||
int len = vsnprintf(temp, sizeof(loc_buf), format, copy);
|
||||
va_end(copy);
|
||||
if(len < 0) {
|
||||
va_end(arg);
|
||||
return 0;
|
||||
};
|
||||
if(len >= sizeof(loc_buf)){
|
||||
temp = (char*) malloc(len+1);
|
||||
if(temp == NULL) {
|
||||
va_end(arg);
|
||||
return 0;
|
||||
}
|
||||
len = vsnprintf(temp, len+1, format, arg);
|
||||
}
|
||||
va_end(arg);
|
||||
len = write((uint8_t*)temp, len);
|
||||
if(temp != loc_buf){
|
||||
free(temp);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t Print::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
return print(reinterpret_cast<const char *>(ifsh));
|
||||
}
|
||||
|
||||
size_t Print::print(const String &s)
|
||||
{
|
||||
return write(s.c_str(), s.length());
|
||||
}
|
||||
|
||||
size_t Print::print(const char str[])
|
||||
{
|
||||
return write(str);
|
||||
}
|
||||
|
||||
size_t Print::print(char c)
|
||||
{
|
||||
return write(c);
|
||||
}
|
||||
|
||||
size_t Print::print(unsigned char b, int base)
|
||||
{
|
||||
return print((unsigned long) b, base);
|
||||
}
|
||||
|
||||
size_t Print::print(int n, int base)
|
||||
{
|
||||
return print((long) n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(unsigned int n, int base)
|
||||
{
|
||||
return print((unsigned long) n, base);
|
||||
}
|
||||
|
||||
size_t Print::print(long n, int base)
|
||||
{
|
||||
if(base == 0) {
|
||||
return write(n);
|
||||
} else if(base == 10) {
|
||||
if(n < 0) {
|
||||
int t = print('-');
|
||||
n = -n;
|
||||
return printNumber(n, 10) + t;
|
||||
}
|
||||
return printNumber(n, 10);
|
||||
} else {
|
||||
return printNumber(n, base);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Print::print(unsigned long n, int base)
|
||||
{
|
||||
if(base == 0) {
|
||||
return write(n);
|
||||
} else {
|
||||
return printNumber(n, base);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Print::print(double n, int digits)
|
||||
{
|
||||
return printFloat(n, digits);
|
||||
}
|
||||
|
||||
size_t Print::println(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
size_t n = print(ifsh);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::print(const Printable& x)
|
||||
{
|
||||
return x.printTo(*this);
|
||||
}
|
||||
|
||||
size_t Print::print(struct tm * timeinfo, const char * format)
|
||||
{
|
||||
const char * f = format;
|
||||
if(!f){
|
||||
f = "%c";
|
||||
}
|
||||
char buf[64];
|
||||
size_t written = strftime(buf, 64, f, timeinfo);
|
||||
if(written == 0){
|
||||
return written;
|
||||
}
|
||||
return print(buf);
|
||||
}
|
||||
|
||||
size_t Print::println(void)
|
||||
{
|
||||
return print("\r\n");
|
||||
}
|
||||
|
||||
size_t Print::println(const String &s)
|
||||
{
|
||||
size_t n = print(s);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(const char c[])
|
||||
{
|
||||
size_t n = print(c);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(char c)
|
||||
{
|
||||
size_t n = print(c);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(unsigned char b, int base)
|
||||
{
|
||||
size_t n = print(b, base);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(int num, int base)
|
||||
{
|
||||
size_t n = print(num, base);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(unsigned int num, int base)
|
||||
{
|
||||
size_t n = print(num, base);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(long num, int base)
|
||||
{
|
||||
size_t n = print(num, base);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(unsigned long num, int base)
|
||||
{
|
||||
size_t n = print(num, base);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(double num, int digits)
|
||||
{
|
||||
size_t n = print(num, digits);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(const Printable& x)
|
||||
{
|
||||
size_t n = print(x);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::println(struct tm * timeinfo, const char * format)
|
||||
{
|
||||
size_t n = print(timeinfo, format);
|
||||
n += println();
|
||||
return n;
|
||||
}
|
||||
|
||||
// Private Methods /////////////////////////////////////////////////////////////
|
||||
|
||||
size_t Print::printNumber(unsigned long n, uint8_t base)
|
||||
{
|
||||
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
|
||||
char *str = &buf[sizeof(buf) - 1];
|
||||
|
||||
*str = '\0';
|
||||
|
||||
// prevent crash if called with base == 1
|
||||
if(base < 2) {
|
||||
base = 10;
|
||||
}
|
||||
|
||||
do {
|
||||
unsigned long m = n;
|
||||
n /= base;
|
||||
char c = m - base * n;
|
||||
*--str = c < 10 ? c + '0' : c + 'A' - 10;
|
||||
} while(n);
|
||||
|
||||
return write(str);
|
||||
}
|
||||
|
||||
size_t Print::printFloat(double number, uint8_t digits)
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
if(isnan(number)) {
|
||||
return print("nan");
|
||||
}
|
||||
if(isinf(number)) {
|
||||
return print("inf");
|
||||
}
|
||||
if(number > 4294967040.0) {
|
||||
return print("ovf"); // constant determined empirically
|
||||
}
|
||||
if(number < -4294967040.0) {
|
||||
return print("ovf"); // constant determined empirically
|
||||
}
|
||||
|
||||
// Handle negative numbers
|
||||
if(number < 0.0) {
|
||||
n += print('-');
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
double rounding = 0.5;
|
||||
for(uint8_t i = 0; i < digits; ++i) {
|
||||
rounding /= 10.0;
|
||||
}
|
||||
|
||||
number += rounding;
|
||||
|
||||
// Extract the integer part of the number and print it
|
||||
unsigned long int_part = (unsigned long) number;
|
||||
double remainder = number - (double) int_part;
|
||||
n += print(int_part);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if(digits > 0) {
|
||||
n += print(".");
|
||||
}
|
||||
|
||||
// Extract digits from the remainder one at a time
|
||||
while(digits-- > 0) {
|
||||
remainder *= 10.0;
|
||||
int toPrint = int(remainder);
|
||||
n += print(toPrint);
|
||||
remainder -= toPrint;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
Print.h - Base class that provides print() and println()
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Print_h
|
||||
#define Print_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "WString.h"
|
||||
#include "Printable.h"
|
||||
|
||||
#define DEC 10
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define BIN 2
|
||||
|
||||
class Print
|
||||
{
|
||||
private:
|
||||
int write_error;
|
||||
size_t printNumber(unsigned long, uint8_t);
|
||||
size_t printFloat(double, uint8_t);
|
||||
protected:
|
||||
void setWriteError(int err = 1)
|
||||
{
|
||||
write_error = err;
|
||||
}
|
||||
public:
|
||||
Print() :
|
||||
write_error(0)
|
||||
{
|
||||
}
|
||||
virtual ~Print() {}
|
||||
int getWriteError()
|
||||
{
|
||||
return write_error;
|
||||
}
|
||||
void clearWriteError()
|
||||
{
|
||||
setWriteError(0);
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
size_t write(const char *str)
|
||||
{
|
||||
if(str == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return write((const uint8_t *) str, strlen(str));
|
||||
}
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
size_t write(const char *buffer, size_t size)
|
||||
{
|
||||
return write((const uint8_t *) buffer, size);
|
||||
}
|
||||
|
||||
size_t printf(const char * format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
size_t print(const __FlashStringHelper *);
|
||||
size_t print(const String &);
|
||||
size_t print(const char[]);
|
||||
size_t print(char);
|
||||
size_t print(unsigned char, int = DEC);
|
||||
size_t print(int, int = DEC);
|
||||
size_t print(unsigned int, int = DEC);
|
||||
size_t print(long, int = DEC);
|
||||
size_t print(unsigned long, int = DEC);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(const Printable&);
|
||||
size_t print(struct tm * timeinfo, const char * format = NULL);
|
||||
|
||||
size_t println(const __FlashStringHelper *);
|
||||
size_t println(const String &s);
|
||||
size_t println(const char[]);
|
||||
size_t println(char);
|
||||
size_t println(unsigned char, int = DEC);
|
||||
size_t println(int, int = DEC);
|
||||
size_t println(unsigned int, int = DEC);
|
||||
size_t println(long, int = DEC);
|
||||
size_t println(unsigned long, int = DEC);
|
||||
size_t println(double, int = 2);
|
||||
size_t println(const Printable&);
|
||||
size_t println(struct tm * timeinfo, const char * format = NULL);
|
||||
size_t println(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
Printable.h - Interface class that allows printing of complex types
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Printable_h
|
||||
#define Printable_h
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class Print;
|
||||
|
||||
/** The Printable class provides a way for new classes to allow themselves to be printed.
|
||||
By deriving from Printable and implementing the printTo method, it will then be possible
|
||||
for users to print out instances of this class by passing them into the usual
|
||||
Print::print and Print::println methods.
|
||||
*/
|
||||
|
||||
class Printable
|
||||
{
|
||||
public:
|
||||
virtual ~Printable() {}
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
Server.h - Base class that provides Server
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef server_h
|
||||
#define server_h
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
class Server: public Print
|
||||
{
|
||||
public:
|
||||
virtual void begin(uint16_t port=0) =0;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,294 +0,0 @@
|
||||
/*
|
||||
Stream.cpp - adds parsing methods to Stream class
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Created July 2011
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Stream.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
||||
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
|
||||
|
||||
// private method to read stream with timeout
|
||||
int Stream::timedRead()
|
||||
{
|
||||
int c;
|
||||
_startMillis = millis();
|
||||
do {
|
||||
c = read();
|
||||
if(c >= 0) {
|
||||
return c;
|
||||
}
|
||||
} while(millis() - _startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// private method to peek stream with timeout
|
||||
int Stream::timedPeek()
|
||||
{
|
||||
int c;
|
||||
_startMillis = millis();
|
||||
do {
|
||||
c = peek();
|
||||
if(c >= 0) {
|
||||
return c;
|
||||
}
|
||||
} while(millis() - _startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// returns peek of the next digit in the stream or -1 if timeout
|
||||
// discards non-numeric characters
|
||||
int Stream::peekNextDigit()
|
||||
{
|
||||
int c;
|
||||
while(1) {
|
||||
c = timedPeek();
|
||||
if(c < 0) {
|
||||
return c; // timeout
|
||||
}
|
||||
if(c == '-') {
|
||||
return c;
|
||||
}
|
||||
if(c >= '0' && c <= '9') {
|
||||
return c;
|
||||
}
|
||||
read(); // discard non-numeric
|
||||
}
|
||||
}
|
||||
|
||||
// Public Methods
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
unsigned long Stream::getTimeout(void) {
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
// find returns true if the target string is found
|
||||
bool Stream::find(const char *target)
|
||||
{
|
||||
return findUntil(target, (char*) "");
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of given length is found
|
||||
// returns true if target string is found, false if timed out
|
||||
bool Stream::find(const char *target, size_t length)
|
||||
{
|
||||
return findUntil(target, length, NULL, 0);
|
||||
}
|
||||
|
||||
// as find but search ends if the terminator string is found
|
||||
bool Stream::findUntil(const char *target, const char *terminator)
|
||||
{
|
||||
return findUntil(target, strlen(target), terminator, strlen(terminator));
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of the given length is found
|
||||
// search terminated if the terminator string is found
|
||||
// returns true if target string is found, false if terminated or timed out
|
||||
bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen)
|
||||
{
|
||||
size_t index = 0; // maximum target string length is 64k bytes!
|
||||
size_t termIndex = 0;
|
||||
int c;
|
||||
|
||||
if(*target == 0) {
|
||||
return true; // return true if target is a null string
|
||||
}
|
||||
while((c = timedRead()) > 0) {
|
||||
|
||||
if(c != target[index]) {
|
||||
index = 0; // reset index if any char does not match
|
||||
}
|
||||
|
||||
if(c == target[index]) {
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
if(++index >= targetLen) { // return true if all chars in the target match
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(termLen > 0 && c == terminator[termIndex]) {
|
||||
if(++termIndex >= termLen) {
|
||||
return false; // return false if terminate string found before target string
|
||||
}
|
||||
} else {
|
||||
termIndex = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// function is terminated by the first character that is not a digit.
|
||||
long Stream::parseInt()
|
||||
{
|
||||
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
|
||||
}
|
||||
|
||||
// as above but a given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
long Stream::parseInt(char skipChar)
|
||||
{
|
||||
boolean isNegative = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0) {
|
||||
return 0; // zero returned if timeout
|
||||
}
|
||||
|
||||
do {
|
||||
if(c == skipChar) {
|
||||
} // ignore this charactor
|
||||
else if(c == '-') {
|
||||
isNegative = true;
|
||||
} else if(c >= '0' && c <= '9') { // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
}
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
} while((c >= '0' && c <= '9') || c == skipChar);
|
||||
|
||||
if(isNegative) {
|
||||
value = -value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// as parseInt but returns a floating point value
|
||||
float Stream::parseFloat()
|
||||
{
|
||||
return parseFloat(NO_SKIP_CHAR);
|
||||
}
|
||||
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
float Stream::parseFloat(char skipChar)
|
||||
{
|
||||
boolean isNegative = false;
|
||||
boolean isFraction = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
float fraction = 1.0;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0) {
|
||||
return 0; // zero returned if timeout
|
||||
}
|
||||
|
||||
do {
|
||||
if(c == skipChar) {
|
||||
} // ignore
|
||||
else if(c == '-') {
|
||||
isNegative = true;
|
||||
} else if(c == '.') {
|
||||
isFraction = true;
|
||||
} else if(c >= '0' && c <= '9') { // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
if(isFraction) {
|
||||
fraction *= 0.1;
|
||||
}
|
||||
}
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
} while((c >= '0' && c <= '9') || c == '.' || c == skipChar);
|
||||
|
||||
if(isNegative) {
|
||||
value = -value;
|
||||
}
|
||||
if(isFraction) {
|
||||
return value * fraction;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
// read characters from stream into buffer
|
||||
// terminates if length characters have been read, or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer
|
||||
// the buffer is NOT null terminated.
|
||||
//
|
||||
size_t Stream::readBytes(char *buffer, size_t length)
|
||||
{
|
||||
size_t count = 0;
|
||||
while(count < length) {
|
||||
int c = timedRead();
|
||||
if(c < 0) {
|
||||
break;
|
||||
}
|
||||
*buffer++ = (char) c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// as readBytes with terminator character
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
||||
{
|
||||
if(length < 1) {
|
||||
return 0;
|
||||
}
|
||||
size_t index = 0;
|
||||
while(index < length) {
|
||||
int c = timedRead();
|
||||
if(c < 0 || c == terminator) {
|
||||
break;
|
||||
}
|
||||
*buffer++ = (char) c;
|
||||
index++;
|
||||
}
|
||||
return index; // return number of characters, not including null terminator
|
||||
}
|
||||
|
||||
String Stream::readString()
|
||||
{
|
||||
String ret;
|
||||
int c = timedRead();
|
||||
while(c >= 0) {
|
||||
ret += (char) c;
|
||||
c = timedRead();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String Stream::readStringUntil(char terminator)
|
||||
{
|
||||
String ret;
|
||||
int c = timedRead();
|
||||
while(c >= 0 && c != terminator) {
|
||||
ret += (char) c;
|
||||
c = timedRead();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
Stream.h - base class for character-based streams.
|
||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#ifndef Stream_h
|
||||
#define Stream_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
// compatability macros for testing
|
||||
/*
|
||||
#define getInt() parseInt()
|
||||
#define getInt(skipChar) parseInt(skipchar)
|
||||
#define getFloat() parseFloat()
|
||||
#define getFloat(skipChar) parseFloat(skipChar)
|
||||
#define getString( pre_string, post_string, buffer, length)
|
||||
readBytesBetween( pre_string, terminator, buffer, length)
|
||||
*/
|
||||
|
||||
class Stream: public Print
|
||||
{
|
||||
protected:
|
||||
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
|
||||
unsigned long _startMillis; // used for timeout measurement
|
||||
int timedRead(); // private method to read stream with timeout
|
||||
int timedPeek(); // private method to peek stream with timeout
|
||||
int peekNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
|
||||
|
||||
public:
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
Stream():_startMillis(0)
|
||||
{
|
||||
_timeout = 1000;
|
||||
}
|
||||
virtual ~Stream() {}
|
||||
|
||||
// parsing methods
|
||||
|
||||
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
|
||||
unsigned long getTimeout(void);
|
||||
bool find(const char *target); // reads data from the stream until the target string is found
|
||||
bool find(uint8_t *target)
|
||||
{
|
||||
return find((char *) target);
|
||||
}
|
||||
// returns true if target string is found, false if timed out (see setTimeout)
|
||||
|
||||
bool find(const char *target, size_t length); // reads data from the stream until the target string of given length is found
|
||||
bool find(const uint8_t *target, size_t length)
|
||||
{
|
||||
return find((char *) target, length);
|
||||
}
|
||||
// returns true if target string is found, false if timed out
|
||||
|
||||
bool find(char target)
|
||||
{
|
||||
return find (&target, 1);
|
||||
}
|
||||
|
||||
bool findUntil(const char *target, const char *terminator); // as find but search ends if the terminator string is found
|
||||
bool findUntil(const uint8_t *target, const char *terminator)
|
||||
{
|
||||
return findUntil((char *) target, terminator);
|
||||
}
|
||||
|
||||
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); // as above but search ends if the terminate string is found
|
||||
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen)
|
||||
{
|
||||
return findUntil((char *) target, targetLen, terminate, termLen);
|
||||
}
|
||||
|
||||
long parseInt(); // returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// integer is terminated by the first character that is not a digit.
|
||||
|
||||
float parseFloat(); // float version of parseInt
|
||||
|
||||
virtual size_t readBytes(char *buffer, size_t length); // read chars from stream into buffer
|
||||
virtual size_t readBytes(uint8_t *buffer, size_t length)
|
||||
{
|
||||
return readBytes((char *) buffer, length);
|
||||
}
|
||||
// terminates if length characters have been read or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t readBytesUntil(char terminator, char *buffer, size_t length); // as readBytes with terminator character
|
||||
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length)
|
||||
{
|
||||
return readBytesUntil(terminator, (char *) buffer, length);
|
||||
}
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
// Arduino String functions to be added here
|
||||
virtual String readString();
|
||||
String readStringUntil(char terminator);
|
||||
|
||||
protected:
|
||||
long parseInt(char skipChar); // as above but the given skipChar is ignored
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
|
||||
float parseFloat(char skipChar); // as above but the given skipChar is ignored
|
||||
};
|
||||
|
||||
#endif
|
@ -1,67 +0,0 @@
|
||||
/**
|
||||
StreamString.cpp
|
||||
|
||||
Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "StreamString.h"
|
||||
|
||||
size_t StreamString::write(const uint8_t *data, size_t size) {
|
||||
if(size && data) {
|
||||
const unsigned int newlen = length() + size;
|
||||
if(reserve(newlen + 1)) {
|
||||
memcpy((void *) (wbuffer() + len()), (const void *) data, size);
|
||||
setLen(newlen);
|
||||
*(wbuffer() + newlen) = 0x00; // add null for string end
|
||||
return size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t StreamString::write(uint8_t data) {
|
||||
return concat((char) data);
|
||||
}
|
||||
|
||||
int StreamString::available() {
|
||||
return length();
|
||||
}
|
||||
|
||||
int StreamString::read() {
|
||||
if(length()) {
|
||||
char c = charAt(0);
|
||||
remove(0, 1);
|
||||
return c;
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StreamString::peek() {
|
||||
if(length()) {
|
||||
char c = charAt(0);
|
||||
return c;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void StreamString::flush() {
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
/**
|
||||
StreamString.h
|
||||
|
||||
Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#ifndef STREAMSTRING_H_
|
||||
#define STREAMSTRING_H_
|
||||
|
||||
|
||||
class StreamString: public Stream, public String
|
||||
{
|
||||
public:
|
||||
size_t write(const uint8_t *buffer, size_t size) override;
|
||||
size_t write(uint8_t data) override;
|
||||
|
||||
int available() override;
|
||||
int read() override;
|
||||
int peek() override;
|
||||
void flush() override;
|
||||
};
|
||||
|
||||
|
||||
#endif /* STREAMSTRING_H_ */
|
@ -75,7 +75,7 @@ static size_t tinyusb_cdc_write(uint8_t itf, const uint8_t *buffer, size_t size)
|
||||
while(tosend){
|
||||
uint32_t space = tud_cdc_n_write_available(itf);
|
||||
if(!space){
|
||||
delay(1);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
continue;
|
||||
}
|
||||
if(tosend < space){
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "Stream.h"
|
||||
#include "esp32-hal.h"
|
||||
#if CONFIG_USB_CDC_ENABLED
|
||||
|
||||
@ -49,7 +48,7 @@ typedef union {
|
||||
} rx;
|
||||
} arduino_usb_cdc_event_data_t;
|
||||
|
||||
class USBCDC: public Stream
|
||||
class USBCDC
|
||||
{
|
||||
public:
|
||||
USBCDC(uint8_t itf=0);
|
||||
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Udp.cpp: Library to send/receive UDP packets.
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* 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.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#ifndef udp_h
|
||||
#define udp_h
|
||||
|
||||
#include <Stream.h>
|
||||
#include <IPAddress.h>
|
||||
|
||||
class UDP: public Stream
|
||||
{
|
||||
|
||||
public:
|
||||
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual void stop() =0; // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port) =0;
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket() =0;
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t) =0;
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) =0;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket() =0;
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available() =0;
|
||||
// Read a single byte from the current packet
|
||||
virtual int read() =0;
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len) =0;
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) =0;
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek() =0;
|
||||
virtual void flush() =0; // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() =0;
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() =0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr)
|
||||
{
|
||||
return addr.raw_address();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -25,83 +25,83 @@
|
||||
#define toascii(__c) ((__c)&0177)
|
||||
|
||||
// WCharacter.h prototypes
|
||||
inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
|
||||
inline boolean isAlpha(int c) __attribute__((always_inline));
|
||||
inline boolean isAscii(int c) __attribute__((always_inline));
|
||||
inline boolean isWhitespace(int c) __attribute__((always_inline));
|
||||
inline boolean isControl(int c) __attribute__((always_inline));
|
||||
inline boolean isDigit(int c) __attribute__((always_inline));
|
||||
inline boolean isGraph(int c) __attribute__((always_inline));
|
||||
inline boolean isLowerCase(int c) __attribute__((always_inline));
|
||||
inline boolean isPrintable(int c) __attribute__((always_inline));
|
||||
inline boolean isPunct(int c) __attribute__((always_inline));
|
||||
inline boolean isSpace(int c) __attribute__((always_inline));
|
||||
inline boolean isUpperCase(int c) __attribute__((always_inline));
|
||||
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
|
||||
inline bool isAlphaNumeric(int c) __attribute__((always_inline));
|
||||
inline bool isAlpha(int c) __attribute__((always_inline));
|
||||
inline bool isAscii(int c) __attribute__((always_inline));
|
||||
inline bool isWhitespace(int c) __attribute__((always_inline));
|
||||
inline bool isControl(int c) __attribute__((always_inline));
|
||||
inline bool isDigit(int c) __attribute__((always_inline));
|
||||
inline bool isGraph(int c) __attribute__((always_inline));
|
||||
inline bool isLowerCase(int c) __attribute__((always_inline));
|
||||
inline bool isPrintable(int c) __attribute__((always_inline));
|
||||
inline bool isPunct(int c) __attribute__((always_inline));
|
||||
inline bool isSpace(int c) __attribute__((always_inline));
|
||||
inline bool isUpperCase(int c) __attribute__((always_inline));
|
||||
inline bool isHexadecimalDigit(int c) __attribute__((always_inline));
|
||||
inline int toAscii(int c) __attribute__((always_inline));
|
||||
inline int toLowerCase(int c) __attribute__((always_inline));
|
||||
inline int toUpperCase(int c) __attribute__((always_inline));
|
||||
|
||||
// Checks for an alphanumeric character.
|
||||
// It is equivalent to (isalpha(c) || isdigit(c)).
|
||||
inline boolean isAlphaNumeric(int c)
|
||||
inline bool isAlphaNumeric(int c)
|
||||
{
|
||||
return (isalnum(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for an alphabetic character.
|
||||
// It is equivalent to (isupper(c) || islower(c)).
|
||||
inline boolean isAlpha(int c)
|
||||
inline bool isAlpha(int c)
|
||||
{
|
||||
return (isalpha(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks whether c is a 7-bit unsigned char value
|
||||
// that fits into the ASCII character set.
|
||||
inline boolean isAscii(int c)
|
||||
inline bool isAscii(int c)
|
||||
{
|
||||
return ( isascii (c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for a blank character, that is, a space or a tab.
|
||||
inline boolean isWhitespace(int c)
|
||||
inline bool isWhitespace(int c)
|
||||
{
|
||||
return (isblank(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for a control character.
|
||||
inline boolean isControl(int c)
|
||||
inline bool isControl(int c)
|
||||
{
|
||||
return (iscntrl(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for a digit (0 through 9).
|
||||
inline boolean isDigit(int c)
|
||||
inline bool isDigit(int c)
|
||||
{
|
||||
return (isdigit(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for any printable character except space.
|
||||
inline boolean isGraph(int c)
|
||||
inline bool isGraph(int c)
|
||||
{
|
||||
return (isgraph(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for a lower-case character.
|
||||
inline boolean isLowerCase(int c)
|
||||
inline bool isLowerCase(int c)
|
||||
{
|
||||
return (islower(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for any printable character including space.
|
||||
inline boolean isPrintable(int c)
|
||||
inline bool isPrintable(int c)
|
||||
{
|
||||
return (isprint(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for any printable character which is not a space
|
||||
// or an alphanumeric character.
|
||||
inline boolean isPunct(int c)
|
||||
inline bool isPunct(int c)
|
||||
{
|
||||
return (ispunct(c) == 0 ? false : true);
|
||||
}
|
||||
@ -109,20 +109,20 @@ inline boolean isPunct(int c)
|
||||
// Checks for white-space characters. For the avr-libc library,
|
||||
// these are: space, formfeed ('\f'), newline ('\n'), carriage
|
||||
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
|
||||
inline boolean isSpace(int c)
|
||||
inline bool isSpace(int c)
|
||||
{
|
||||
return (isspace(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for an uppercase letter.
|
||||
inline boolean isUpperCase(int c)
|
||||
inline bool isUpperCase(int c)
|
||||
{
|
||||
return (isupper(c) == 0 ? false : true);
|
||||
}
|
||||
|
||||
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
|
||||
// 8 9 a b c d e f A B C D E F.
|
||||
inline boolean isHexadecimalDigit(int c)
|
||||
inline bool isHexadecimalDigit(int c)
|
||||
{
|
||||
return (isxdigit(c) == 0 ? false : true);
|
||||
}
|
||||
|
@ -24,61 +24,23 @@
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include <stdlib.h>
|
||||
#include "esp_system.h"
|
||||
}
|
||||
|
||||
void randomSeed(unsigned long seed)
|
||||
{
|
||||
if(seed != 0) {
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
//long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
// const long dividend = out_max - out_min;
|
||||
// const long divisor = in_max - in_min;
|
||||
// const long delta = x - in_min;
|
||||
|
||||
long random(long howbig)
|
||||
{
|
||||
uint32_t x = esp_random();
|
||||
uint64_t m = uint64_t(x) * uint64_t(howbig);
|
||||
uint32_t l = uint32_t(m);
|
||||
if (l < howbig) {
|
||||
uint32_t t = -howbig;
|
||||
if (t >= howbig) {
|
||||
t -= howbig;
|
||||
if (t >= howbig)
|
||||
t %= howbig;
|
||||
}
|
||||
while (l < t) {
|
||||
x = esp_random();
|
||||
m = uint64_t(x) * uint64_t(howbig);
|
||||
l = uint32_t(m);
|
||||
}
|
||||
}
|
||||
return m >> 32;
|
||||
}
|
||||
// return (delta * dividend + (divisor / 2)) / divisor + out_min;
|
||||
//}
|
||||
|
||||
long random(long howsmall, long howbig)
|
||||
{
|
||||
if(howsmall >= howbig) {
|
||||
return howsmall;
|
||||
}
|
||||
long diff = howbig - howsmall;
|
||||
return random(diff) + howsmall;
|
||||
}
|
||||
//unsigned int makeWord(unsigned int w)
|
||||
//{
|
||||
// return w;
|
||||
//}
|
||||
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max) {
|
||||
long divisor = (in_max - in_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)
|
||||
{
|
||||
return w;
|
||||
}
|
||||
|
||||
unsigned int makeWord(unsigned char h, unsigned char l)
|
||||
{
|
||||
return (h << 8) | l;
|
||||
}
|
||||
//unsigned int makeWord(unsigned char h, unsigned char l)
|
||||
//{
|
||||
// return (h << 8) | l;
|
||||
//}
|
||||
|
@ -1,861 +0,0 @@
|
||||
/*
|
||||
WString.cpp - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||
Modified by Ivan Grokhotkov, 2014 - esp8266 support
|
||||
Modified by Michael C. Miller, 2015 - esp8266 progmem support
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "WString.h"
|
||||
#include "stdlib_noniso.h"
|
||||
|
||||
/*********************************************/
|
||||
/* Constructors */
|
||||
/*********************************************/
|
||||
|
||||
String::String(const char *cstr) {
|
||||
init();
|
||||
if (cstr)
|
||||
copy(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
String::String(const String &value) {
|
||||
init();
|
||||
*this = value;
|
||||
}
|
||||
|
||||
String::String(const __FlashStringHelper *pstr) {
|
||||
init();
|
||||
*this = pstr; // see operator =
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String::String(String &&rval) {
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
|
||||
String::String(StringSumHelper &&rval) {
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
#endif
|
||||
|
||||
String::String(char c) {
|
||||
init();
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned char value, unsigned char base) {
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned char)];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(int value, unsigned char base) {
|
||||
init();
|
||||
char buf[2 + 8 * sizeof(int)];
|
||||
if (base == 10) {
|
||||
sprintf(buf, "%d", value);
|
||||
} else {
|
||||
itoa(value, buf, base);
|
||||
}
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned int value, unsigned char base) {
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned int)];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(long value, unsigned char base) {
|
||||
init();
|
||||
char buf[2 + 8 * sizeof(long)];
|
||||
if (base==10) {
|
||||
sprintf(buf, "%ld", value);
|
||||
} else {
|
||||
ltoa(value, buf, base);
|
||||
}
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned long value, unsigned char base) {
|
||||
init();
|
||||
char buf[1 + 8 * sizeof(unsigned long)];
|
||||
ultoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(float value, unsigned char decimalPlaces) {
|
||||
init();
|
||||
char buf[33];
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
}
|
||||
|
||||
String::String(double value, unsigned char decimalPlaces) {
|
||||
init();
|
||||
char buf[33];
|
||||
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
|
||||
}
|
||||
|
||||
String::~String() {
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Memory Management */
|
||||
// /*********************************************/
|
||||
|
||||
inline void String::init(void) {
|
||||
setSSO(false);
|
||||
setCapacity(0);
|
||||
setLen(0);
|
||||
setBuffer(nullptr);
|
||||
}
|
||||
|
||||
void String::invalidate(void) {
|
||||
if(!isSSO() && wbuffer())
|
||||
free(wbuffer());
|
||||
init();
|
||||
}
|
||||
|
||||
unsigned char String::reserve(unsigned int size) {
|
||||
if(buffer() && capacity() >= size)
|
||||
return 1;
|
||||
if(changeBuffer(size)) {
|
||||
if(len() == 0)
|
||||
wbuffer()[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char String::changeBuffer(unsigned int maxStrLen) {
|
||||
// Can we use SSO here to avoid allocation?
|
||||
if (maxStrLen < sizeof(sso.buff) - 1) {
|
||||
if (isSSO() || !buffer()) {
|
||||
// Already using SSO, nothing to do
|
||||
uint16_t oldLen = len();
|
||||
setSSO(true);
|
||||
setLen(oldLen);
|
||||
return 1;
|
||||
} else { // if bufptr && !isSSO()
|
||||
// Using bufptr, need to shrink into sso.buff
|
||||
char temp[sizeof(sso.buff)];
|
||||
memcpy(temp, buffer(), maxStrLen);
|
||||
free(wbuffer());
|
||||
uint16_t oldLen = len();
|
||||
setSSO(true);
|
||||
setLen(oldLen);
|
||||
memcpy(wbuffer(), temp, maxStrLen);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Fallthrough to normal allocator
|
||||
size_t newSize = (maxStrLen + 16) & (~0xf);
|
||||
// Make sure we can fit newsize in the buffer
|
||||
if (newSize > CAPACITY_MAX) {
|
||||
return false;
|
||||
}
|
||||
uint16_t oldLen = len();
|
||||
char *newbuffer = (char *) realloc(isSSO() ? nullptr : wbuffer(), newSize);
|
||||
if (newbuffer) {
|
||||
size_t oldSize = capacity() + 1; // include NULL.
|
||||
if (isSSO()) {
|
||||
// Copy the SSO buffer into allocated space
|
||||
memmove(newbuffer, sso.buff, sizeof(sso.buff));
|
||||
}
|
||||
if (newSize > oldSize)
|
||||
{
|
||||
memset(newbuffer + oldSize, 0, newSize - oldSize);
|
||||
}
|
||||
setSSO(false);
|
||||
setCapacity(newSize - 1);
|
||||
setLen(oldLen); // Needed in case of SSO where len() never existed
|
||||
setBuffer(newbuffer);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Copy and Move */
|
||||
// /*********************************************/
|
||||
|
||||
String & String::copy(const char *cstr, unsigned int length) {
|
||||
if(!reserve(length)) {
|
||||
invalidate();
|
||||
return *this;
|
||||
}
|
||||
setLen(length);
|
||||
memmove(wbuffer(), cstr, length + 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::copy(const __FlashStringHelper *pstr, unsigned int length) {
|
||||
if (!reserve(length)) {
|
||||
invalidate();
|
||||
return *this;
|
||||
}
|
||||
setLen(length);
|
||||
memcpy_P(wbuffer(), (PGM_P)pstr, length + 1); // We know wbuffer() cannot ever be in PROGMEM, so memcpy safe here
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
void String::move(String &rhs) {
|
||||
if(buffer()) {
|
||||
if(capacity() >= rhs.len()) {
|
||||
memmove(wbuffer(), rhs.buffer(), rhs.length() + 1);
|
||||
setLen(rhs.len());
|
||||
rhs.invalidate();
|
||||
return;
|
||||
} else {
|
||||
if (!isSSO()) {
|
||||
free(wbuffer());
|
||||
setBuffer(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rhs.isSSO()) {
|
||||
setSSO(true);
|
||||
memmove(sso.buff, rhs.sso.buff, sizeof(sso.buff));
|
||||
} else {
|
||||
setSSO(false);
|
||||
setBuffer(rhs.wbuffer());
|
||||
}
|
||||
setCapacity(rhs.capacity());
|
||||
setLen(rhs.len());
|
||||
rhs.setSSO(false);
|
||||
rhs.setCapacity(0);
|
||||
rhs.setLen(0);
|
||||
rhs.setBuffer(nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
String & String::operator =(const String &rhs) {
|
||||
if(this == &rhs)
|
||||
return *this;
|
||||
|
||||
if(rhs.buffer())
|
||||
copy(rhs.buffer(), rhs.len());
|
||||
else
|
||||
invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String & String::operator =(String &&rval) {
|
||||
if(this != &rval)
|
||||
move(rval);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator =(StringSumHelper &&rval) {
|
||||
if(this != &rval)
|
||||
move(rval);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
String & String::operator =(const char *cstr) {
|
||||
if(cstr)
|
||||
copy(cstr, strlen(cstr));
|
||||
else
|
||||
invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (const __FlashStringHelper *pstr)
|
||||
{
|
||||
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
|
||||
else invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* concat */
|
||||
// /*********************************************/
|
||||
|
||||
unsigned char String::concat(const String &s) {
|
||||
// Special case if we're concatting ourself (s += s;) since we may end up
|
||||
// realloc'ing the buffer and moving s.buffer in the method called
|
||||
if (&s == this) {
|
||||
unsigned int newlen = 2 * len();
|
||||
if (!s.buffer())
|
||||
return 0;
|
||||
if (s.len() == 0)
|
||||
return 1;
|
||||
if (!reserve(newlen))
|
||||
return 0;
|
||||
memmove(wbuffer() + len(), buffer(), len());
|
||||
setLen(newlen);
|
||||
wbuffer()[len()] = 0;
|
||||
return 1;
|
||||
} else {
|
||||
return concat(s.buffer(), s.len());
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char String::concat(const char *cstr, unsigned int length) {
|
||||
unsigned int newlen = len() + length;
|
||||
if(!cstr)
|
||||
return 0;
|
||||
if(length == 0)
|
||||
return 1;
|
||||
if(!reserve(newlen))
|
||||
return 0;
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char String::concat(const char *cstr) {
|
||||
if(!cstr)
|
||||
return 0;
|
||||
return concat(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
unsigned char String::concat(char c) {
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
return concat(buf, 1);
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned char num) {
|
||||
char buf[1 + 3 * sizeof(unsigned char)];
|
||||
sprintf(buf, "%d", num);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(int num) {
|
||||
char buf[2 + 3 * sizeof(int)];
|
||||
sprintf(buf, "%d", num);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned int num) {
|
||||
char buf[1 + 3 * sizeof(unsigned int)];
|
||||
utoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(long num) {
|
||||
char buf[2 + 3 * sizeof(long)];
|
||||
sprintf(buf, "%ld", num);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(unsigned long num) {
|
||||
char buf[1 + 3 * sizeof(unsigned long)];
|
||||
ultoa(num, buf, 10);
|
||||
return concat(buf, strlen(buf));
|
||||
}
|
||||
|
||||
unsigned char String::concat(float num) {
|
||||
char buf[20];
|
||||
char* string = dtostrf(num, 4, 2, buf);
|
||||
return concat(string, strlen(string));
|
||||
}
|
||||
|
||||
unsigned char String::concat(double num) {
|
||||
char buf[20];
|
||||
char* string = dtostrf(num, 4, 2, buf);
|
||||
return concat(string, strlen(string));
|
||||
}
|
||||
|
||||
unsigned char String::concat(const __FlashStringHelper * str) {
|
||||
if (!str) return 0;
|
||||
int length = strlen_P((PGM_P)str);
|
||||
if (length == 0) return 1;
|
||||
unsigned int newlen = len() + length;
|
||||
if (!reserve(newlen)) return 0;
|
||||
memcpy_P(wbuffer() + len(), (PGM_P)str, length + 1);
|
||||
setLen(newlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Concatenate */
|
||||
/*********************************************/
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(rhs.buffer(), rhs.len()))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!cstr || !a.concat(cstr, strlen(cstr)))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, char c) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(c))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, unsigned char num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, int num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, unsigned int num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, long num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, float num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator +(const StringSumHelper &lhs, double num) {
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if(!a.concat(num))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (!a.concat(rhs))
|
||||
a.invalidate();
|
||||
return a;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Comparison */
|
||||
// /*********************************************/
|
||||
|
||||
int String::compareTo(const String &s) const {
|
||||
if(!buffer() || !s.buffer()) {
|
||||
if(s.buffer() && s.len() > 0)
|
||||
return 0 - *(unsigned char *) s.buffer();
|
||||
if(buffer() && len() > 0)
|
||||
return *(unsigned char *) buffer();
|
||||
return 0;
|
||||
}
|
||||
return strcmp(buffer(), s.buffer());
|
||||
}
|
||||
|
||||
unsigned char String::equals(const String &s2) const {
|
||||
return (len() == s2.len() && compareTo(s2) == 0);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const char *cstr) const {
|
||||
if(len() == 0)
|
||||
return (cstr == NULL || *cstr == 0);
|
||||
if(cstr == NULL)
|
||||
return buffer()[0] == 0;
|
||||
return strcmp(buffer(), cstr) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<(const String &rhs) const {
|
||||
return compareTo(rhs) < 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>(const String &rhs) const {
|
||||
return compareTo(rhs) > 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<=(const String &rhs) const {
|
||||
return compareTo(rhs) <= 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>=(const String &rhs) const {
|
||||
return compareTo(rhs) >= 0;
|
||||
}
|
||||
|
||||
unsigned char String::equalsIgnoreCase(const String &s2) const {
|
||||
if(this == &s2)
|
||||
return 1;
|
||||
if(len() != s2.len())
|
||||
return 0;
|
||||
if(len() == 0)
|
||||
return 1;
|
||||
const char *p1 = buffer();
|
||||
const char *p2 = s2.buffer();
|
||||
while(*p1) {
|
||||
if(tolower(*p1++) != tolower(*p2++))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char String::equalsConstantTime(const String &s2) const {
|
||||
// To avoid possible time-based attacks present function
|
||||
// compares given strings in a constant time.
|
||||
if(len() != s2.len())
|
||||
return 0;
|
||||
//at this point lengths are the same
|
||||
if(len() == 0)
|
||||
return 1;
|
||||
//at this point lenghts are the same and non-zero
|
||||
const char *p1 = buffer();
|
||||
const char *p2 = s2.buffer();
|
||||
unsigned int equalchars = 0;
|
||||
unsigned int diffchars = 0;
|
||||
while(*p1) {
|
||||
if(*p1 == *p2)
|
||||
++equalchars;
|
||||
else
|
||||
++diffchars;
|
||||
++p1;
|
||||
++p2;
|
||||
}
|
||||
//the following should force a constant time eval of the condition without a compiler "logical shortcut"
|
||||
unsigned char equalcond = (equalchars == len());
|
||||
unsigned char diffcond = (diffchars == 0);
|
||||
return (equalcond & diffcond); //bitwise AND
|
||||
}
|
||||
|
||||
unsigned char String::startsWith(const String &s2) const {
|
||||
if(len() < s2.len())
|
||||
return 0;
|
||||
return startsWith(s2, 0);
|
||||
}
|
||||
|
||||
unsigned char String::startsWith(const String &s2, unsigned int offset) const {
|
||||
if(offset > (unsigned)(len() - s2.len()) || !buffer() || !s2.buffer())
|
||||
return 0;
|
||||
return strncmp(&buffer()[offset], s2.buffer(), s2.len()) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::endsWith(const String &s2) const {
|
||||
if(len() < s2.len() || !buffer() || !s2.buffer())
|
||||
return 0;
|
||||
return strcmp(&buffer()[len() - s2.len()], s2.buffer()) == 0;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Character Access */
|
||||
// /*********************************************/
|
||||
|
||||
char String::charAt(unsigned int loc) const {
|
||||
return operator[](loc);
|
||||
}
|
||||
|
||||
void String::setCharAt(unsigned int loc, char c) {
|
||||
if(loc < len())
|
||||
wbuffer()[loc] = c;
|
||||
}
|
||||
|
||||
char & String::operator[](unsigned int index) {
|
||||
static char dummy_writable_char;
|
||||
if(index >= len() || !buffer()) {
|
||||
dummy_writable_char = 0;
|
||||
return dummy_writable_char;
|
||||
}
|
||||
return wbuffer()[index];
|
||||
}
|
||||
|
||||
char String::operator[](unsigned int index) const {
|
||||
if(index >= len() || !buffer())
|
||||
return 0;
|
||||
return buffer()[index];
|
||||
}
|
||||
|
||||
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const {
|
||||
if(!bufsize || !buf)
|
||||
return;
|
||||
if(index >= len()) {
|
||||
buf[0] = 0;
|
||||
return;
|
||||
}
|
||||
unsigned int n = bufsize - 1;
|
||||
if(n > len() - index)
|
||||
n = len() - index;
|
||||
strncpy((char *) buf, buffer() + index, n);
|
||||
buf[n] = 0;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Search */
|
||||
// /*********************************************/
|
||||
|
||||
int String::indexOf(char c) const {
|
||||
return indexOf(c, 0);
|
||||
}
|
||||
|
||||
int String::indexOf(char ch, unsigned int fromIndex) const {
|
||||
if(fromIndex >= len())
|
||||
return -1;
|
||||
const char* temp = strchr(buffer() + fromIndex, ch);
|
||||
if(temp == NULL)
|
||||
return -1;
|
||||
return temp - buffer();
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2) const {
|
||||
return indexOf(s2, 0);
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2, unsigned int fromIndex) const {
|
||||
if(fromIndex >= len())
|
||||
return -1;
|
||||
const char *found = strstr(buffer() + fromIndex, s2.buffer());
|
||||
if(found == NULL)
|
||||
return -1;
|
||||
return found - buffer();
|
||||
}
|
||||
|
||||
int String::lastIndexOf(char theChar) const {
|
||||
return lastIndexOf(theChar, len() - 1);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(char ch, unsigned int fromIndex) const {
|
||||
if(fromIndex >= len())
|
||||
return -1;
|
||||
char tempchar = buffer()[fromIndex + 1];
|
||||
wbuffer()[fromIndex + 1] = '\0';
|
||||
char* temp = strrchr(wbuffer(), ch);
|
||||
wbuffer()[fromIndex + 1] = tempchar;
|
||||
if(temp == NULL)
|
||||
return -1;
|
||||
return temp - buffer();
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2) const {
|
||||
return lastIndexOf(s2, len() - s2.len());
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const {
|
||||
if(s2.len() == 0 || len() == 0 || s2.len() > len())
|
||||
return -1;
|
||||
if(fromIndex >= len())
|
||||
fromIndex = len() - 1;
|
||||
int found = -1;
|
||||
for(char *p = wbuffer(); p <= wbuffer() + fromIndex; p++) {
|
||||
p = strstr(p, s2.buffer());
|
||||
if(!p)
|
||||
break;
|
||||
if((unsigned int) (p - wbuffer()) <= fromIndex)
|
||||
found = p - buffer();
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
String String::substring(unsigned int left, unsigned int right) const {
|
||||
if(left > right) {
|
||||
unsigned int temp = right;
|
||||
right = left;
|
||||
left = temp;
|
||||
}
|
||||
String out;
|
||||
if(left >= len())
|
||||
return out;
|
||||
if(right > len())
|
||||
right = len();
|
||||
char temp = buffer()[right]; // save the replaced character
|
||||
wbuffer()[right] = '\0';
|
||||
out = wbuffer() + left; // pointer arithmetic
|
||||
wbuffer()[right] = temp; //restore character
|
||||
return out;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Modification */
|
||||
// /*********************************************/
|
||||
|
||||
void String::replace(char find, char replace) {
|
||||
if(!buffer())
|
||||
return;
|
||||
for(char *p = wbuffer(); *p; p++) {
|
||||
if(*p == find)
|
||||
*p = replace;
|
||||
}
|
||||
}
|
||||
|
||||
void String::replace(const String& find, const String& replace) {
|
||||
if(len() == 0 || find.len() == 0)
|
||||
return;
|
||||
int diff = replace.len() - find.len();
|
||||
char *readFrom = wbuffer();
|
||||
char *foundAt;
|
||||
if(diff == 0) {
|
||||
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
||||
memmove(foundAt, replace.buffer(), replace.len());
|
||||
readFrom = foundAt + replace.len();
|
||||
}
|
||||
} else if(diff < 0) {
|
||||
char *writeTo = wbuffer();
|
||||
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
||||
unsigned int n = foundAt - readFrom;
|
||||
memmove(writeTo, readFrom, n);
|
||||
writeTo += n;
|
||||
memmove(writeTo, replace.buffer(), replace.len());
|
||||
writeTo += replace.len();
|
||||
readFrom = foundAt + find.len();
|
||||
setLen(len() + diff);
|
||||
}
|
||||
memmove(writeTo, readFrom, strlen(readFrom)+1);
|
||||
} else {
|
||||
unsigned int size = len(); // compute size needed for result
|
||||
while((foundAt = strstr(readFrom, find.buffer())) != NULL) {
|
||||
readFrom = foundAt + find.len();
|
||||
size += diff;
|
||||
}
|
||||
if(size == len())
|
||||
return;
|
||||
if(size > capacity() && !changeBuffer(size))
|
||||
return; // XXX: tell user!
|
||||
int index = len() - 1;
|
||||
while(index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||
readFrom = wbuffer() + index + find.len();
|
||||
memmove(readFrom + diff, readFrom, len() - (readFrom - buffer()));
|
||||
int newLen = len() + diff;
|
||||
memmove(wbuffer() + index, replace.buffer(), replace.len());
|
||||
setLen(newLen);
|
||||
wbuffer()[newLen] = 0;
|
||||
index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void String::remove(unsigned int index) {
|
||||
// Pass the biggest integer as the count. The remove method
|
||||
// below will take care of truncating it at the end of the
|
||||
// string.
|
||||
remove(index, (unsigned int) -1);
|
||||
}
|
||||
|
||||
void String::remove(unsigned int index, unsigned int count) {
|
||||
if(index >= len()) {
|
||||
return;
|
||||
}
|
||||
if(count <= 0) {
|
||||
return;
|
||||
}
|
||||
if(count > len() - index) {
|
||||
count = len() - index;
|
||||
}
|
||||
char *writeTo = wbuffer() + index;
|
||||
unsigned int newlen = len() - count;
|
||||
setLen(newlen);
|
||||
memmove(writeTo, wbuffer() + index + count, newlen - index);
|
||||
wbuffer()[newlen] = 0;
|
||||
}
|
||||
|
||||
void String::toLowerCase(void) {
|
||||
if(!buffer())
|
||||
return;
|
||||
for(char *p = wbuffer(); *p; p++) {
|
||||
*p = tolower(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void String::toUpperCase(void) {
|
||||
if(!buffer())
|
||||
return;
|
||||
for(char *p = wbuffer(); *p; p++) {
|
||||
*p = toupper(*p);
|
||||
}
|
||||
}
|
||||
|
||||
void String::trim(void) {
|
||||
if(!buffer() || len() == 0)
|
||||
return;
|
||||
char *begin = wbuffer();
|
||||
while(isspace(*begin))
|
||||
begin++;
|
||||
char *end = wbuffer() + len() - 1;
|
||||
while(isspace(*end) && end >= begin)
|
||||
end--;
|
||||
unsigned int newlen = end + 1 - begin;
|
||||
setLen(newlen);
|
||||
if(begin > buffer())
|
||||
memmove(wbuffer(), begin, newlen);
|
||||
wbuffer()[newlen] = 0;
|
||||
}
|
||||
|
||||
// /*********************************************/
|
||||
// /* Parsing / Conversion */
|
||||
// /*********************************************/
|
||||
|
||||
long String::toInt(void) const {
|
||||
if (buffer())
|
||||
return atol(buffer());
|
||||
return 0;
|
||||
}
|
||||
|
||||
float String::toFloat(void) const {
|
||||
if (buffer())
|
||||
return atof(buffer());
|
||||
return 0;
|
||||
}
|
||||
|
||||
double String::toDouble(void) const
|
||||
{
|
||||
if (buffer())
|
||||
return atof(buffer());
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// global empty string to allow returning const String& with nothing
|
||||
|
||||
const String emptyString;
|
@ -1,362 +0,0 @@
|
||||
/*
|
||||
WString.h - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef String_class_h
|
||||
#define String_class_h
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <pgmspace.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// An inherited class for holding the result of a concatenation. These
|
||||
// result objects are assumed to be writable by subsequent concatenations.
|
||||
class StringSumHelper;
|
||||
|
||||
// an abstract class used as a means to proide a unique pointer type
|
||||
// but really has no body
|
||||
class __FlashStringHelper;
|
||||
#define FPSTR(pstr_pointer) (reinterpret_cast<const __FlashStringHelper *>(pstr_pointer))
|
||||
#define F(string_literal) (FPSTR(PSTR(string_literal)))
|
||||
|
||||
// The string class
|
||||
class String {
|
||||
// use a function pointer to allow for "if (s)" without the
|
||||
// complications of an operator bool(). for more information, see:
|
||||
// http://www.artima.com/cppsource/safebool.html
|
||||
typedef void (String::*StringIfHelperType)() const;
|
||||
void StringIfHelper() const {
|
||||
}
|
||||
|
||||
public:
|
||||
// constructors
|
||||
// creates a copy of the initial value.
|
||||
// if the initial value is null or invalid, or if memory allocation
|
||||
// fails, the string will be marked as invalid (i.e. "if (s)" will
|
||||
// be false).
|
||||
String(const char *cstr = "");
|
||||
String(const String &str);
|
||||
String(const __FlashStringHelper *str);
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String(String &&rval);
|
||||
String(StringSumHelper &&rval);
|
||||
#endif
|
||||
explicit String(char c);
|
||||
explicit String(unsigned char, unsigned char base = 10);
|
||||
explicit String(int, unsigned char base = 10);
|
||||
explicit String(unsigned int, unsigned char base = 10);
|
||||
explicit String(long, unsigned char base = 10);
|
||||
explicit String(unsigned long, unsigned char base = 10);
|
||||
explicit String(float, unsigned char decimalPlaces = 2);
|
||||
explicit String(double, unsigned char decimalPlaces = 2);
|
||||
~String(void);
|
||||
|
||||
// memory management
|
||||
// return true on success, false on failure (in which case, the string
|
||||
// is left unchanged). reserve(0), if successful, will validate an
|
||||
// invalid string (i.e., "if (s)" will be true afterwards)
|
||||
unsigned char reserve(unsigned int size);
|
||||
inline unsigned int length(void) const {
|
||||
if(buffer()) {
|
||||
return len();
|
||||
} else {
|
||||
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
|
||||
// invalid, or if the memory allocation fails, the string will be
|
||||
// marked as invalid ("if (s)" will be false).
|
||||
String & operator =(const String &rhs);
|
||||
String & operator =(const char *cstr);
|
||||
String & operator = (const __FlashStringHelper *str);
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String & operator =(String &&rval);
|
||||
String & operator =(StringSumHelper &&rval);
|
||||
#endif
|
||||
|
||||
// concatenate (works w/ built-in types)
|
||||
|
||||
// returns true on success, false on failure (in which case, the string
|
||||
// is left unchanged). if the argument is null or invalid, the
|
||||
// concatenation is considered unsuccessful.
|
||||
unsigned char concat(const String &str);
|
||||
unsigned char concat(const char *cstr);
|
||||
unsigned char concat(char c);
|
||||
unsigned char concat(unsigned char c);
|
||||
unsigned char concat(int num);
|
||||
unsigned char concat(unsigned int num);
|
||||
unsigned char concat(long num);
|
||||
unsigned char concat(unsigned long num);
|
||||
unsigned char concat(float num);
|
||||
unsigned char concat(double num);
|
||||
unsigned char concat(const __FlashStringHelper * str);
|
||||
|
||||
// if there's not enough memory for the concatenated value, the string
|
||||
// will be left unchanged (but this isn't signalled in any way)
|
||||
String & operator +=(const String &rhs) {
|
||||
concat(rhs);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(const char *cstr) {
|
||||
concat(cstr);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(char c) {
|
||||
concat(c);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(unsigned char num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(int num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(unsigned int num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(long num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(unsigned long num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(float num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator +=(double num) {
|
||||
concat(num);
|
||||
return (*this);
|
||||
}
|
||||
String & operator += (const __FlashStringHelper *str){
|
||||
concat(str);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, const String &rhs);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, const char *cstr);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, char c);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned char num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, int num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned int num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, long num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, unsigned long num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, float num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, double num);
|
||||
friend StringSumHelper & operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
|
||||
|
||||
// comparison (only works w/ Strings and "strings")
|
||||
operator StringIfHelperType() const {
|
||||
return buffer() ? &String::StringIfHelper : 0;
|
||||
}
|
||||
int compareTo(const String &s) const;
|
||||
unsigned char equals(const String &s) const;
|
||||
unsigned char equals(const char *cstr) const;
|
||||
unsigned char operator ==(const String &rhs) const {
|
||||
return equals(rhs);
|
||||
}
|
||||
unsigned char operator ==(const char *cstr) const {
|
||||
return equals(cstr);
|
||||
}
|
||||
unsigned char operator !=(const String &rhs) const {
|
||||
return !equals(rhs);
|
||||
}
|
||||
unsigned char operator !=(const char *cstr) const {
|
||||
return !equals(cstr);
|
||||
}
|
||||
unsigned char operator <(const String &rhs) const;
|
||||
unsigned char operator >(const String &rhs) const;
|
||||
unsigned char operator <=(const String &rhs) const;
|
||||
unsigned char operator >=(const String &rhs) const;
|
||||
unsigned char equalsIgnoreCase(const String &s) const;
|
||||
unsigned char equalsConstantTime(const String &s) const;
|
||||
unsigned char startsWith(const String &prefix) const;
|
||||
unsigned char startsWith(const char *prefix) const {
|
||||
return this->startsWith(String(prefix));
|
||||
}
|
||||
unsigned char startsWith(const __FlashStringHelper *prefix) const {
|
||||
return this->startsWith(String(prefix));
|
||||
}
|
||||
unsigned char startsWith(const String &prefix, unsigned int offset) const;
|
||||
unsigned char endsWith(const String &suffix) const;
|
||||
unsigned char endsWith(const char *suffix) const {
|
||||
return this->endsWith(String(suffix));
|
||||
}
|
||||
unsigned char endsWith(const __FlashStringHelper * suffix) const {
|
||||
return this->endsWith(String(suffix));
|
||||
}
|
||||
|
||||
// character access
|
||||
char charAt(unsigned int index) const;
|
||||
void setCharAt(unsigned int index, char c);
|
||||
char operator [](unsigned int index) const;
|
||||
char& operator [](unsigned int index);
|
||||
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
|
||||
void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const {
|
||||
getBytes((unsigned char *) buf, bufsize, index);
|
||||
}
|
||||
const char* c_str() const { return buffer(); }
|
||||
char* begin() { return wbuffer(); }
|
||||
char* end() { return wbuffer() + length(); }
|
||||
const char* begin() const { return c_str(); }
|
||||
const char* end() const { return c_str() + length(); }
|
||||
|
||||
// search
|
||||
int indexOf(char ch) const;
|
||||
int indexOf(char ch, unsigned int fromIndex) const;
|
||||
int indexOf(const String &str) const;
|
||||
int indexOf(const String &str, unsigned int fromIndex) const;
|
||||
int lastIndexOf(char ch) const;
|
||||
int lastIndexOf(char ch, unsigned int fromIndex) const;
|
||||
int lastIndexOf(const String &str) const;
|
||||
int lastIndexOf(const String &str, unsigned int fromIndex) const;
|
||||
String substring(unsigned int beginIndex) const {
|
||||
return substring(beginIndex, len());
|
||||
}
|
||||
;
|
||||
String substring(unsigned int beginIndex, unsigned int endIndex) const;
|
||||
|
||||
// modification
|
||||
void replace(char find, char replace);
|
||||
void replace(const String &find, const String &replace);
|
||||
void replace(const char *find, const String &replace) {
|
||||
this->replace(String(find), replace);
|
||||
}
|
||||
void replace(const __FlashStringHelper *find, const String &replace) {
|
||||
this->replace(String(find), replace);
|
||||
}
|
||||
void replace(const char *find, const char *replace) {
|
||||
this->replace(String(find), String(replace));
|
||||
}
|
||||
void replace(const __FlashStringHelper *find, const char *replace) {
|
||||
this->replace(String(find), String(replace));
|
||||
}
|
||||
void replace(const __FlashStringHelper *find, const __FlashStringHelper *replace) {
|
||||
this->replace(String(find), String(replace));
|
||||
}
|
||||
void remove(unsigned int index);
|
||||
void remove(unsigned int index, unsigned int count);
|
||||
void toLowerCase(void);
|
||||
void toUpperCase(void);
|
||||
void trim(void);
|
||||
|
||||
// parsing/conversion
|
||||
long toInt(void) const;
|
||||
float toFloat(void) const;
|
||||
double toDouble(void) const;
|
||||
|
||||
protected:
|
||||
// Contains the string info when we're not in SSO mode
|
||||
struct _ptr {
|
||||
char * buff;
|
||||
uint16_t cap;
|
||||
uint16_t len;
|
||||
};
|
||||
// This allows strings up up to 11 (10 + \0 termination) without any extra space.
|
||||
enum { SSOSIZE = sizeof(struct _ptr) + 4 - 1 }; // Characters to allocate space for SSO, must be 12 or more
|
||||
struct _sso {
|
||||
char buff[SSOSIZE];
|
||||
unsigned char len : 7; // Ensure only one byte is allocated by GCC for the bitfields
|
||||
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 {
|
||||
struct _ptr ptr;
|
||||
struct _sso sso;
|
||||
};
|
||||
// Accessor functions
|
||||
inline bool isSSO() const { return sso.isSSO; }
|
||||
inline unsigned int len() const { return isSSO() ? sso.len : ptr.len; }
|
||||
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 set) { sso.isSSO = set; }
|
||||
inline void setLen(int len) { if (isSSO()) sso.len = len; else ptr.len = len; }
|
||||
inline void setCapacity(int cap) { if (!isSSO()) ptr.cap = cap; }
|
||||
inline void setBuffer(char *buff) { if (!isSSO()) ptr.buff = buff; }
|
||||
// Buffer accessor functions
|
||||
inline const char *buffer() const { return (const char *)(isSSO() ? sso.buff : ptr.buff); }
|
||||
inline char *wbuffer() const { return isSSO() ? const_cast<char *>(sso.buff) : ptr.buff; } // Writable version of buffer
|
||||
|
||||
protected:
|
||||
void init(void);
|
||||
void invalidate(void);
|
||||
unsigned char changeBuffer(unsigned int maxStrLen);
|
||||
unsigned char concat(const char *cstr, unsigned int length);
|
||||
|
||||
// copy and move
|
||||
String & copy(const char *cstr, unsigned int length);
|
||||
String & copy(const __FlashStringHelper *pstr, unsigned int length);
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
void move(String &rhs);
|
||||
#endif
|
||||
};
|
||||
|
||||
class StringSumHelper: public String {
|
||||
public:
|
||||
StringSumHelper(const String &s) :
|
||||
String(s) {
|
||||
}
|
||||
StringSumHelper(const char *p) :
|
||||
String(p) {
|
||||
}
|
||||
StringSumHelper(char c) :
|
||||
String(c) {
|
||||
}
|
||||
StringSumHelper(unsigned char num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(int num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(unsigned int num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(long num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(unsigned long num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(float num) :
|
||||
String(num) {
|
||||
}
|
||||
StringSumHelper(double num) :
|
||||
String(num) {
|
||||
}
|
||||
};
|
||||
|
||||
extern const String emptyString;
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // String_class_h
|
@ -1 +0,0 @@
|
||||
#include "lwip/apps/sntp.h"
|
@ -1,64 +0,0 @@
|
||||
/**
|
||||
* base64.cpp
|
||||
*
|
||||
* Created on: 09.12.2015
|
||||
*
|
||||
* Copyright (c) 2015 Markus Sattler. All rights reserved.
|
||||
* This file is part of the ESP31B core for Arduino.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
extern "C" {
|
||||
#include "libb64/cdecode.h"
|
||||
#include "libb64/cencode.h"
|
||||
}
|
||||
#include "base64.h"
|
||||
|
||||
/**
|
||||
* convert input data to base64
|
||||
* @param data const uint8_t *
|
||||
* @param length size_t
|
||||
* @return String
|
||||
*/
|
||||
String base64::encode(const uint8_t * data, size_t length)
|
||||
{
|
||||
size_t size = base64_encode_expected_len(length) + 1;
|
||||
char * buffer = (char *) malloc(size);
|
||||
if(buffer) {
|
||||
base64_encodestate _state;
|
||||
base64_init_encodestate(&_state);
|
||||
int len = base64_encode_block((const char *) &data[0], length, &buffer[0], &_state);
|
||||
len = base64_encode_blockend((buffer + len), &_state);
|
||||
|
||||
String base64 = String(buffer);
|
||||
free(buffer);
|
||||
return base64;
|
||||
}
|
||||
return String("-FAIL-");
|
||||
}
|
||||
|
||||
/**
|
||||
* convert input data to base64
|
||||
* @param text const String&
|
||||
* @return String
|
||||
*/
|
||||
String base64::encode(const String& text)
|
||||
{
|
||||
return base64::encode((uint8_t *) text.c_str(), text.length());
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
#ifndef CORE_BASE64_H_
|
||||
#define CORE_BASE64_H_
|
||||
|
||||
class base64
|
||||
{
|
||||
public:
|
||||
static String encode(const uint8_t * data, size_t length);
|
||||
static String encode(const String& text);
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
#endif /* CORE_BASE64_H_ */
|
@ -1,534 +0,0 @@
|
||||
/*
|
||||
binary.h - Definitions for binary constants
|
||||
Copyright (c) 2006 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Binary_h
|
||||
#define Binary_h
|
||||
|
||||
#define B0 0
|
||||
#define B00 0
|
||||
#define B000 0
|
||||
#define B0000 0
|
||||
#define B00000 0
|
||||
#define B000000 0
|
||||
#define B0000000 0
|
||||
#define B00000000 0
|
||||
#define B1 1
|
||||
#define B01 1
|
||||
#define B001 1
|
||||
#define B0001 1
|
||||
#define B00001 1
|
||||
#define B000001 1
|
||||
#define B0000001 1
|
||||
#define B00000001 1
|
||||
#define B10 2
|
||||
#define B010 2
|
||||
#define B0010 2
|
||||
#define B00010 2
|
||||
#define B000010 2
|
||||
#define B0000010 2
|
||||
#define B00000010 2
|
||||
#define B11 3
|
||||
#define B011 3
|
||||
#define B0011 3
|
||||
#define B00011 3
|
||||
#define B000011 3
|
||||
#define B0000011 3
|
||||
#define B00000011 3
|
||||
#define B100 4
|
||||
#define B0100 4
|
||||
#define B00100 4
|
||||
#define B000100 4
|
||||
#define B0000100 4
|
||||
#define B00000100 4
|
||||
#define B101 5
|
||||
#define B0101 5
|
||||
#define B00101 5
|
||||
#define B000101 5
|
||||
#define B0000101 5
|
||||
#define B00000101 5
|
||||
#define B110 6
|
||||
#define B0110 6
|
||||
#define B00110 6
|
||||
#define B000110 6
|
||||
#define B0000110 6
|
||||
#define B00000110 6
|
||||
#define B111 7
|
||||
#define B0111 7
|
||||
#define B00111 7
|
||||
#define B000111 7
|
||||
#define B0000111 7
|
||||
#define B00000111 7
|
||||
#define B1000 8
|
||||
#define B01000 8
|
||||
#define B001000 8
|
||||
#define B0001000 8
|
||||
#define B00001000 8
|
||||
#define B1001 9
|
||||
#define B01001 9
|
||||
#define B001001 9
|
||||
#define B0001001 9
|
||||
#define B00001001 9
|
||||
#define B1010 10
|
||||
#define B01010 10
|
||||
#define B001010 10
|
||||
#define B0001010 10
|
||||
#define B00001010 10
|
||||
#define B1011 11
|
||||
#define B01011 11
|
||||
#define B001011 11
|
||||
#define B0001011 11
|
||||
#define B00001011 11
|
||||
#define B1100 12
|
||||
#define B01100 12
|
||||
#define B001100 12
|
||||
#define B0001100 12
|
||||
#define B00001100 12
|
||||
#define B1101 13
|
||||
#define B01101 13
|
||||
#define B001101 13
|
||||
#define B0001101 13
|
||||
#define B00001101 13
|
||||
#define B1110 14
|
||||
#define B01110 14
|
||||
#define B001110 14
|
||||
#define B0001110 14
|
||||
#define B00001110 14
|
||||
#define B1111 15
|
||||
#define B01111 15
|
||||
#define B001111 15
|
||||
#define B0001111 15
|
||||
#define B00001111 15
|
||||
#define B10000 16
|
||||
#define B010000 16
|
||||
#define B0010000 16
|
||||
#define B00010000 16
|
||||
#define B10001 17
|
||||
#define B010001 17
|
||||
#define B0010001 17
|
||||
#define B00010001 17
|
||||
#define B10010 18
|
||||
#define B010010 18
|
||||
#define B0010010 18
|
||||
#define B00010010 18
|
||||
#define B10011 19
|
||||
#define B010011 19
|
||||
#define B0010011 19
|
||||
#define B00010011 19
|
||||
#define B10100 20
|
||||
#define B010100 20
|
||||
#define B0010100 20
|
||||
#define B00010100 20
|
||||
#define B10101 21
|
||||
#define B010101 21
|
||||
#define B0010101 21
|
||||
#define B00010101 21
|
||||
#define B10110 22
|
||||
#define B010110 22
|
||||
#define B0010110 22
|
||||
#define B00010110 22
|
||||
#define B10111 23
|
||||
#define B010111 23
|
||||
#define B0010111 23
|
||||
#define B00010111 23
|
||||
#define B11000 24
|
||||
#define B011000 24
|
||||
#define B0011000 24
|
||||
#define B00011000 24
|
||||
#define B11001 25
|
||||
#define B011001 25
|
||||
#define B0011001 25
|
||||
#define B00011001 25
|
||||
#define B11010 26
|
||||
#define B011010 26
|
||||
#define B0011010 26
|
||||
#define B00011010 26
|
||||
#define B11011 27
|
||||
#define B011011 27
|
||||
#define B0011011 27
|
||||
#define B00011011 27
|
||||
#define B11100 28
|
||||
#define B011100 28
|
||||
#define B0011100 28
|
||||
#define B00011100 28
|
||||
#define B11101 29
|
||||
#define B011101 29
|
||||
#define B0011101 29
|
||||
#define B00011101 29
|
||||
#define B11110 30
|
||||
#define B011110 30
|
||||
#define B0011110 30
|
||||
#define B00011110 30
|
||||
#define B11111 31
|
||||
#define B011111 31
|
||||
#define B0011111 31
|
||||
#define B00011111 31
|
||||
#define B100000 32
|
||||
#define B0100000 32
|
||||
#define B00100000 32
|
||||
#define B100001 33
|
||||
#define B0100001 33
|
||||
#define B00100001 33
|
||||
#define B100010 34
|
||||
#define B0100010 34
|
||||
#define B00100010 34
|
||||
#define B100011 35
|
||||
#define B0100011 35
|
||||
#define B00100011 35
|
||||
#define B100100 36
|
||||
#define B0100100 36
|
||||
#define B00100100 36
|
||||
#define B100101 37
|
||||
#define B0100101 37
|
||||
#define B00100101 37
|
||||
#define B100110 38
|
||||
#define B0100110 38
|
||||
#define B00100110 38
|
||||
#define B100111 39
|
||||
#define B0100111 39
|
||||
#define B00100111 39
|
||||
#define B101000 40
|
||||
#define B0101000 40
|
||||
#define B00101000 40
|
||||
#define B101001 41
|
||||
#define B0101001 41
|
||||
#define B00101001 41
|
||||
#define B101010 42
|
||||
#define B0101010 42
|
||||
#define B00101010 42
|
||||
#define B101011 43
|
||||
#define B0101011 43
|
||||
#define B00101011 43
|
||||
#define B101100 44
|
||||
#define B0101100 44
|
||||
#define B00101100 44
|
||||
#define B101101 45
|
||||
#define B0101101 45
|
||||
#define B00101101 45
|
||||
#define B101110 46
|
||||
#define B0101110 46
|
||||
#define B00101110 46
|
||||
#define B101111 47
|
||||
#define B0101111 47
|
||||
#define B00101111 47
|
||||
#define B110000 48
|
||||
#define B0110000 48
|
||||
#define B00110000 48
|
||||
#define B110001 49
|
||||
#define B0110001 49
|
||||
#define B00110001 49
|
||||
#define B110010 50
|
||||
#define B0110010 50
|
||||
#define B00110010 50
|
||||
#define B110011 51
|
||||
#define B0110011 51
|
||||
#define B00110011 51
|
||||
#define B110100 52
|
||||
#define B0110100 52
|
||||
#define B00110100 52
|
||||
#define B110101 53
|
||||
#define B0110101 53
|
||||
#define B00110101 53
|
||||
#define B110110 54
|
||||
#define B0110110 54
|
||||
#define B00110110 54
|
||||
#define B110111 55
|
||||
#define B0110111 55
|
||||
#define B00110111 55
|
||||
#define B111000 56
|
||||
#define B0111000 56
|
||||
#define B00111000 56
|
||||
#define B111001 57
|
||||
#define B0111001 57
|
||||
#define B00111001 57
|
||||
#define B111010 58
|
||||
#define B0111010 58
|
||||
#define B00111010 58
|
||||
#define B111011 59
|
||||
#define B0111011 59
|
||||
#define B00111011 59
|
||||
#define B111100 60
|
||||
#define B0111100 60
|
||||
#define B00111100 60
|
||||
#define B111101 61
|
||||
#define B0111101 61
|
||||
#define B00111101 61
|
||||
#define B111110 62
|
||||
#define B0111110 62
|
||||
#define B00111110 62
|
||||
#define B111111 63
|
||||
#define B0111111 63
|
||||
#define B00111111 63
|
||||
#define B1000000 64
|
||||
#define B01000000 64
|
||||
#define B1000001 65
|
||||
#define B01000001 65
|
||||
#define B1000010 66
|
||||
#define B01000010 66
|
||||
#define B1000011 67
|
||||
#define B01000011 67
|
||||
#define B1000100 68
|
||||
#define B01000100 68
|
||||
#define B1000101 69
|
||||
#define B01000101 69
|
||||
#define B1000110 70
|
||||
#define B01000110 70
|
||||
#define B1000111 71
|
||||
#define B01000111 71
|
||||
#define B1001000 72
|
||||
#define B01001000 72
|
||||
#define B1001001 73
|
||||
#define B01001001 73
|
||||
#define B1001010 74
|
||||
#define B01001010 74
|
||||
#define B1001011 75
|
||||
#define B01001011 75
|
||||
#define B1001100 76
|
||||
#define B01001100 76
|
||||
#define B1001101 77
|
||||
#define B01001101 77
|
||||
#define B1001110 78
|
||||
#define B01001110 78
|
||||
#define B1001111 79
|
||||
#define B01001111 79
|
||||
#define B1010000 80
|
||||
#define B01010000 80
|
||||
#define B1010001 81
|
||||
#define B01010001 81
|
||||
#define B1010010 82
|
||||
#define B01010010 82
|
||||
#define B1010011 83
|
||||
#define B01010011 83
|
||||
#define B1010100 84
|
||||
#define B01010100 84
|
||||
#define B1010101 85
|
||||
#define B01010101 85
|
||||
#define B1010110 86
|
||||
#define B01010110 86
|
||||
#define B1010111 87
|
||||
#define B01010111 87
|
||||
#define B1011000 88
|
||||
#define B01011000 88
|
||||
#define B1011001 89
|
||||
#define B01011001 89
|
||||
#define B1011010 90
|
||||
#define B01011010 90
|
||||
#define B1011011 91
|
||||
#define B01011011 91
|
||||
#define B1011100 92
|
||||
#define B01011100 92
|
||||
#define B1011101 93
|
||||
#define B01011101 93
|
||||
#define B1011110 94
|
||||
#define B01011110 94
|
||||
#define B1011111 95
|
||||
#define B01011111 95
|
||||
#define B1100000 96
|
||||
#define B01100000 96
|
||||
#define B1100001 97
|
||||
#define B01100001 97
|
||||
#define B1100010 98
|
||||
#define B01100010 98
|
||||
#define B1100011 99
|
||||
#define B01100011 99
|
||||
#define B1100100 100
|
||||
#define B01100100 100
|
||||
#define B1100101 101
|
||||
#define B01100101 101
|
||||
#define B1100110 102
|
||||
#define B01100110 102
|
||||
#define B1100111 103
|
||||
#define B01100111 103
|
||||
#define B1101000 104
|
||||
#define B01101000 104
|
||||
#define B1101001 105
|
||||
#define B01101001 105
|
||||
#define B1101010 106
|
||||
#define B01101010 106
|
||||
#define B1101011 107
|
||||
#define B01101011 107
|
||||
#define B1101100 108
|
||||
#define B01101100 108
|
||||
#define B1101101 109
|
||||
#define B01101101 109
|
||||
#define B1101110 110
|
||||
#define B01101110 110
|
||||
#define B1101111 111
|
||||
#define B01101111 111
|
||||
#define B1110000 112
|
||||
#define B01110000 112
|
||||
#define B1110001 113
|
||||
#define B01110001 113
|
||||
#define B1110010 114
|
||||
#define B01110010 114
|
||||
#define B1110011 115
|
||||
#define B01110011 115
|
||||
#define B1110100 116
|
||||
#define B01110100 116
|
||||
#define B1110101 117
|
||||
#define B01110101 117
|
||||
#define B1110110 118
|
||||
#define B01110110 118
|
||||
#define B1110111 119
|
||||
#define B01110111 119
|
||||
#define B1111000 120
|
||||
#define B01111000 120
|
||||
#define B1111001 121
|
||||
#define B01111001 121
|
||||
#define B1111010 122
|
||||
#define B01111010 122
|
||||
#define B1111011 123
|
||||
#define B01111011 123
|
||||
#define B1111100 124
|
||||
#define B01111100 124
|
||||
#define B1111101 125
|
||||
#define B01111101 125
|
||||
#define B1111110 126
|
||||
#define B01111110 126
|
||||
#define B1111111 127
|
||||
#define B01111111 127
|
||||
#define B10000000 128
|
||||
#define B10000001 129
|
||||
#define B10000010 130
|
||||
#define B10000011 131
|
||||
#define B10000100 132
|
||||
#define B10000101 133
|
||||
#define B10000110 134
|
||||
#define B10000111 135
|
||||
#define B10001000 136
|
||||
#define B10001001 137
|
||||
#define B10001010 138
|
||||
#define B10001011 139
|
||||
#define B10001100 140
|
||||
#define B10001101 141
|
||||
#define B10001110 142
|
||||
#define B10001111 143
|
||||
#define B10010000 144
|
||||
#define B10010001 145
|
||||
#define B10010010 146
|
||||
#define B10010011 147
|
||||
#define B10010100 148
|
||||
#define B10010101 149
|
||||
#define B10010110 150
|
||||
#define B10010111 151
|
||||
#define B10011000 152
|
||||
#define B10011001 153
|
||||
#define B10011010 154
|
||||
#define B10011011 155
|
||||
#define B10011100 156
|
||||
#define B10011101 157
|
||||
#define B10011110 158
|
||||
#define B10011111 159
|
||||
#define B10100000 160
|
||||
#define B10100001 161
|
||||
#define B10100010 162
|
||||
#define B10100011 163
|
||||
#define B10100100 164
|
||||
#define B10100101 165
|
||||
#define B10100110 166
|
||||
#define B10100111 167
|
||||
#define B10101000 168
|
||||
#define B10101001 169
|
||||
#define B10101010 170
|
||||
#define B10101011 171
|
||||
#define B10101100 172
|
||||
#define B10101101 173
|
||||
#define B10101110 174
|
||||
#define B10101111 175
|
||||
#define B10110000 176
|
||||
#define B10110001 177
|
||||
#define B10110010 178
|
||||
#define B10110011 179
|
||||
#define B10110100 180
|
||||
#define B10110101 181
|
||||
#define B10110110 182
|
||||
#define B10110111 183
|
||||
#define B10111000 184
|
||||
#define B10111001 185
|
||||
#define B10111010 186
|
||||
#define B10111011 187
|
||||
#define B10111100 188
|
||||
#define B10111101 189
|
||||
#define B10111110 190
|
||||
#define B10111111 191
|
||||
#define B11000000 192
|
||||
#define B11000001 193
|
||||
#define B11000010 194
|
||||
#define B11000011 195
|
||||
#define B11000100 196
|
||||
#define B11000101 197
|
||||
#define B11000110 198
|
||||
#define B11000111 199
|
||||
#define B11001000 200
|
||||
#define B11001001 201
|
||||
#define B11001010 202
|
||||
#define B11001011 203
|
||||
#define B11001100 204
|
||||
#define B11001101 205
|
||||
#define B11001110 206
|
||||
#define B11001111 207
|
||||
#define B11010000 208
|
||||
#define B11010001 209
|
||||
#define B11010010 210
|
||||
#define B11010011 211
|
||||
#define B11010100 212
|
||||
#define B11010101 213
|
||||
#define B11010110 214
|
||||
#define B11010111 215
|
||||
#define B11011000 216
|
||||
#define B11011001 217
|
||||
#define B11011010 218
|
||||
#define B11011011 219
|
||||
#define B11011100 220
|
||||
#define B11011101 221
|
||||
#define B11011110 222
|
||||
#define B11011111 223
|
||||
#define B11100000 224
|
||||
#define B11100001 225
|
||||
#define B11100010 226
|
||||
#define B11100011 227
|
||||
#define B11100100 228
|
||||
#define B11100101 229
|
||||
#define B11100110 230
|
||||
#define B11100111 231
|
||||
#define B11101000 232
|
||||
#define B11101001 233
|
||||
#define B11101010 234
|
||||
#define B11101011 235
|
||||
#define B11101100 236
|
||||
#define B11101101 237
|
||||
#define B11101110 238
|
||||
#define B11101111 239
|
||||
#define B11110000 240
|
||||
#define B11110001 241
|
||||
#define B11110010 242
|
||||
#define B11110011 243
|
||||
#define B11110100 244
|
||||
#define B11110101 245
|
||||
#define B11110110 246
|
||||
#define B11110111 247
|
||||
#define B11111000 248
|
||||
#define B11111001 249
|
||||
#define B11111010 250
|
||||
#define B11111011 251
|
||||
#define B11111100 252
|
||||
#define B11111101 253
|
||||
#define B11111110 254
|
||||
#define B11111111 255
|
||||
|
||||
#endif
|
@ -1,196 +0,0 @@
|
||||
/*
|
||||
cbuf.cpp - Circular buffer implementation
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cbuf.h"
|
||||
|
||||
cbuf::cbuf(size_t size) :
|
||||
next(NULL), _size(size+1), _buf(new char[size+1]), _bufend(_buf + size + 1), _begin(_buf), _end(_begin)
|
||||
{
|
||||
}
|
||||
|
||||
cbuf::~cbuf()
|
||||
{
|
||||
delete[] _buf;
|
||||
}
|
||||
|
||||
size_t cbuf::resizeAdd(size_t addSize)
|
||||
{
|
||||
return resize(_size + addSize);
|
||||
}
|
||||
|
||||
size_t cbuf::resize(size_t newSize)
|
||||
{
|
||||
|
||||
size_t bytes_available = available();
|
||||
newSize += 1;
|
||||
// not lose any data
|
||||
// if data can be lost use remove or flush before resize
|
||||
if((newSize < bytes_available) || (newSize == _size)) {
|
||||
return _size;
|
||||
}
|
||||
|
||||
char *newbuf = new char[newSize];
|
||||
char *oldbuf = _buf;
|
||||
|
||||
if(!newbuf) {
|
||||
return _size;
|
||||
}
|
||||
|
||||
if(_buf) {
|
||||
read(newbuf, bytes_available);
|
||||
memset((newbuf + bytes_available), 0x00, (newSize - bytes_available));
|
||||
}
|
||||
|
||||
_begin = newbuf;
|
||||
_end = newbuf + bytes_available;
|
||||
_bufend = newbuf + newSize;
|
||||
_size = newSize;
|
||||
|
||||
_buf = newbuf;
|
||||
delete[] oldbuf;
|
||||
|
||||
return _size;
|
||||
}
|
||||
|
||||
size_t cbuf::available() const
|
||||
{
|
||||
if(_end >= _begin) {
|
||||
return _end - _begin;
|
||||
}
|
||||
return _size - (_begin - _end);
|
||||
}
|
||||
|
||||
size_t cbuf::size()
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
size_t cbuf::room() const
|
||||
{
|
||||
if(_end >= _begin) {
|
||||
return _size - (_end - _begin) - 1;
|
||||
}
|
||||
return _begin - _end - 1;
|
||||
}
|
||||
|
||||
int cbuf::peek()
|
||||
{
|
||||
if(empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return static_cast<int>(*_begin);
|
||||
}
|
||||
|
||||
size_t cbuf::peek(char *dst, size_t size)
|
||||
{
|
||||
size_t bytes_available = available();
|
||||
size_t size_to_read = (size < bytes_available) ? size : bytes_available;
|
||||
size_t size_read = size_to_read;
|
||||
char * begin = _begin;
|
||||
if(_end < _begin && size_to_read > (size_t) (_bufend - _begin)) {
|
||||
size_t top_size = _bufend - _begin;
|
||||
memcpy(dst, _begin, top_size);
|
||||
begin = _buf;
|
||||
size_to_read -= top_size;
|
||||
dst += top_size;
|
||||
}
|
||||
memcpy(dst, begin, size_to_read);
|
||||
return size_read;
|
||||
}
|
||||
|
||||
int cbuf::read()
|
||||
{
|
||||
if(empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char result = *_begin;
|
||||
_begin = wrap_if_bufend(_begin + 1);
|
||||
return static_cast<int>(result);
|
||||
}
|
||||
|
||||
size_t cbuf::read(char* dst, size_t size)
|
||||
{
|
||||
size_t bytes_available = available();
|
||||
size_t size_to_read = (size < bytes_available) ? size : bytes_available;
|
||||
size_t size_read = size_to_read;
|
||||
if(_end < _begin && size_to_read > (size_t) (_bufend - _begin)) {
|
||||
size_t top_size = _bufend - _begin;
|
||||
memcpy(dst, _begin, top_size);
|
||||
_begin = _buf;
|
||||
size_to_read -= top_size;
|
||||
dst += top_size;
|
||||
}
|
||||
memcpy(dst, _begin, size_to_read);
|
||||
_begin = wrap_if_bufend(_begin + size_to_read);
|
||||
return size_read;
|
||||
}
|
||||
|
||||
size_t cbuf::write(char c)
|
||||
{
|
||||
if(full()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*_end = c;
|
||||
_end = wrap_if_bufend(_end + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t cbuf::write(const char* src, size_t size)
|
||||
{
|
||||
size_t bytes_available = room();
|
||||
size_t size_to_write = (size < bytes_available) ? size : bytes_available;
|
||||
size_t size_written = size_to_write;
|
||||
if(_end >= _begin && size_to_write > (size_t) (_bufend - _end)) {
|
||||
size_t top_size = _bufend - _end;
|
||||
memcpy(_end, src, top_size);
|
||||
_end = _buf;
|
||||
size_to_write -= top_size;
|
||||
src += top_size;
|
||||
}
|
||||
memcpy(_end, src, size_to_write);
|
||||
_end = wrap_if_bufend(_end + size_to_write);
|
||||
return size_written;
|
||||
}
|
||||
|
||||
void cbuf::flush()
|
||||
{
|
||||
_begin = _buf;
|
||||
_end = _buf;
|
||||
}
|
||||
|
||||
size_t cbuf::remove(size_t size)
|
||||
{
|
||||
size_t bytes_available = available();
|
||||
if(size >= bytes_available) {
|
||||
flush();
|
||||
return 0;
|
||||
}
|
||||
size_t size_to_remove = (size < bytes_available) ? size : bytes_available;
|
||||
if(_end < _begin && size_to_remove > (size_t) (_bufend - _begin)) {
|
||||
size_t top_size = _bufend - _begin;
|
||||
_begin = _buf;
|
||||
size_to_remove -= top_size;
|
||||
}
|
||||
_begin = wrap_if_bufend(_begin + size_to_remove);
|
||||
return available();
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
cbuf.h - Circular buffer implementation
|
||||
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __cbuf_h
|
||||
#define __cbuf_h
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
class cbuf
|
||||
{
|
||||
public:
|
||||
cbuf(size_t size);
|
||||
~cbuf();
|
||||
|
||||
size_t resizeAdd(size_t addSize);
|
||||
size_t resize(size_t newSize);
|
||||
size_t available() const;
|
||||
size_t size();
|
||||
|
||||
size_t room() const;
|
||||
|
||||
inline bool empty() const
|
||||
{
|
||||
return _begin == _end;
|
||||
}
|
||||
|
||||
inline bool full() const
|
||||
{
|
||||
return wrap_if_bufend(_end + 1) == _begin;
|
||||
}
|
||||
|
||||
int peek();
|
||||
size_t peek(char *dst, size_t size);
|
||||
|
||||
int read();
|
||||
size_t read(char* dst, size_t size);
|
||||
|
||||
size_t write(char c);
|
||||
size_t write(const char* src, size_t size);
|
||||
|
||||
void flush();
|
||||
size_t remove(size_t size);
|
||||
|
||||
cbuf *next;
|
||||
|
||||
private:
|
||||
inline char* wrap_if_bufend(char* ptr) const
|
||||
{
|
||||
return (ptr == _bufend) ? _buf : ptr;
|
||||
}
|
||||
|
||||
size_t _size;
|
||||
char* _buf;
|
||||
const char* _bufend;
|
||||
char* _begin;
|
||||
char* _end;
|
||||
|
||||
};
|
||||
|
||||
#endif//__cbuf_h
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-adc.h"
|
||||
#include "esp32-hal-log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
@ -41,6 +42,7 @@ static uint8_t __analogVRefPin = 0;
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
#include "esp32-hal-gpio.h"
|
||||
|
||||
static uint8_t __analogAttenuation = 3;//11db
|
||||
static uint8_t __analogWidth = 3;//12 bits
|
||||
@ -183,7 +185,7 @@ uint32_t __analogReadMilliVolts(uint8_t pin){
|
||||
__analogVRef = DEFAULT_VREF;
|
||||
if(__analogVRefPin){
|
||||
esp_adc_cal_characteristics_t chars;
|
||||
if(adc2_vref_to_gpio(__analogVRefPin) == ESP_OK){
|
||||
if(adc_vref_to_gpio(ADC_UNIT_2, __analogVRefPin) == ESP_OK){
|
||||
__analogVRef = __analogRead(__analogVRefPin);
|
||||
esp_adc_cal_characterize(1, __analogAttenuation, __analogWidth, DEFAULT_VREF, &chars);
|
||||
__analogVRef = esp_adc_cal_raw_to_voltage(__analogVRef, &chars);
|
||||
|
@ -24,7 +24,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
//#include "esp32-hal.h"
|
||||
|
||||
typedef enum {
|
||||
ADC_0db,
|
||||
|
@ -1,99 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-bt.h"
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
|
||||
bool btInUse(){ return true; }
|
||||
|
||||
#ifdef CONFIG_BLUEDROID_ENABLED
|
||||
#include "esp_bt.h"
|
||||
|
||||
#ifdef CONFIG_CLASSIC_BT_ENABLED
|
||||
#define BT_MODE ESP_BT_MODE_BTDM
|
||||
#else
|
||||
#define BT_MODE ESP_BT_MODE_BLE
|
||||
#endif
|
||||
|
||||
bool btStarted(){
|
||||
return (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED);
|
||||
}
|
||||
|
||||
bool btStart(){
|
||||
esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
|
||||
return true;
|
||||
}
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){
|
||||
esp_bt_controller_init(&cfg);
|
||||
while(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){}
|
||||
}
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED){
|
||||
if (esp_bt_controller_enable(BT_MODE)) {
|
||||
log_e("BT Enable failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
|
||||
return true;
|
||||
}
|
||||
log_e("BT Start failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool btStop(){
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){
|
||||
return true;
|
||||
}
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
|
||||
if (esp_bt_controller_disable()) {
|
||||
log_e("BT Disable failed");
|
||||
return false;
|
||||
}
|
||||
while(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED);
|
||||
}
|
||||
if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED){
|
||||
if (esp_bt_controller_deinit()) {
|
||||
log_e("BT deint failed");
|
||||
return false;
|
||||
}
|
||||
vTaskDelay(1);
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_IDLE) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
log_e("BT Stop failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
bool btStarted()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool btStart()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool btStop()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,32 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ESP32_ESP32_HAL_BT_H_
|
||||
#define _ESP32_ESP32_HAL_BT_H_
|
||||
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool btStarted();
|
||||
bool btStart();
|
||||
bool btStop();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP32_ESP32_HAL_BT_H_ */
|
@ -25,6 +25,7 @@
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "esp32-hal-cpu.h"
|
||||
#include "esp32-hal-log.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
@ -48,7 +49,7 @@ typedef struct apb_change_cb_s {
|
||||
|
||||
|
||||
static apb_change_t * apb_change_callbacks = NULL;
|
||||
static xSemaphoreHandle apb_change_lock = NULL;
|
||||
static SemaphoreHandle_t apb_change_lock = NULL;
|
||||
|
||||
static void initApbChangeCallback(){
|
||||
static volatile bool initialized = false;
|
||||
@ -101,7 +102,7 @@ bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
|
||||
// look for duplicate callbacks
|
||||
while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
|
||||
if (r) {
|
||||
log_e("duplicate func=%08X arg=%08X",c->cb,c->arg);
|
||||
log_e("duplicate func=%08X arg=%08X",(unsigned int)c->cb,(unsigned int)c->arg);
|
||||
free(c);
|
||||
xSemaphoreGive(apb_change_lock);
|
||||
return false;
|
||||
@ -123,7 +124,7 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
|
||||
// look for matching callback
|
||||
while( (r != NULL ) && !((r->cb == cb) && ( r->arg == arg))) r = r->next;
|
||||
if ( r == NULL ) {
|
||||
log_e("not found func=%08X arg=%08X",cb,arg);
|
||||
log_e("not found func=%08X arg=%08X",(unsigned int)cb,(unsigned int)arg);
|
||||
xSemaphoreGive(apb_change_lock);
|
||||
return false;
|
||||
}
|
||||
|
@ -45,4 +45,16 @@ uint32_t getApbFrequency(); // In Hz
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef F_CPU
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#define F_CPU (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000U)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define F_CPU (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000U)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( (long int)getCpuFrequencyMhz() )
|
||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
||||
|
||||
#endif /* _ESP32_HAL_CPU_H_ */
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "driver/dac.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define DAC1 25
|
||||
|
@ -24,9 +24,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
void dacWrite(uint8_t pin, uint8_t value);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -21,6 +22,7 @@
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/rtc_io_periph.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
|
@ -24,7 +24,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "stdint.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
|
||||
|
@ -12,18 +12,24 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp32-hal-i2c.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "soc/i2c_reg.h"
|
||||
#include "soc/i2c_struct.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp32-hal-cpu.h" // cpu clock change support 31DEC2018
|
||||
#include "esp32-hal-log.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "esp32-hal-misc.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
@ -37,6 +43,7 @@
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#endif
|
||||
#include "driver/gpio.h"
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@ -184,7 +191,7 @@ typedef struct {
|
||||
struct i2c_struct_t {
|
||||
i2c_dev_t * dev;
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
xSemaphoreHandle lock;
|
||||
SemaphoreHandle_t lock;
|
||||
#endif
|
||||
uint8_t num;
|
||||
int8_t sda;
|
||||
@ -331,7 +338,7 @@ static void i2cDumpDqData(i2c_t * i2c)
|
||||
static void i2cDumpI2c(i2c_t * i2c)
|
||||
{
|
||||
log_e("i2c=%p",i2c);
|
||||
log_i("dev=%p date=%p",i2c->dev,i2c->dev->date);
|
||||
log_i("dev=%p date=%u",i2c->dev,i2c->dev->date);
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
log_i("lock=%p",i2c->lock);
|
||||
#endif
|
||||
@ -960,6 +967,14 @@ static void ARDUINO_ISR_ATTR i2c_isr_handler_default(void* arg)
|
||||
activeInt &=~I2C_RXFIFO_FULL_INT_ST;
|
||||
}
|
||||
|
||||
if(activeInt & I2C_RXFIFO_OVF_INT_ST) {
|
||||
emptyRxFifo(p_i2c);
|
||||
p_i2c->dev->int_clr.rx_fifo_full=1;
|
||||
p_i2c->dev->int_ena.rx_fifo_full=1; //why?
|
||||
|
||||
activeInt &=~I2C_RXFIFO_OVF_INT_ST;
|
||||
}
|
||||
|
||||
if (activeInt & I2C_ACK_ERR_INT_ST_M) {//fatal error, abort i2c service
|
||||
if (p_i2c->mode == I2C_MASTER) {
|
||||
i2c_update_error_byte_cnt(p_i2c); // calc which byte caused ack Error, check if address or data
|
||||
@ -1137,7 +1152,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
|
||||
if(multiMaster){// try to let the bus clear by its self
|
||||
uint32_t timeOutTick = millis();
|
||||
while((i2c->dev->status_reg.bus_busy)&&(millis()-timeOutTick<timeOutMillis())){
|
||||
delay(2); // allow task switch
|
||||
vTaskDelay(2 / portTICK_PERIOD_MS); // allow task switch
|
||||
}
|
||||
}
|
||||
if(i2c->dev->status_reg.bus_busy){ // still busy, so die
|
||||
@ -1281,7 +1296,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
|
||||
// how many ticks should it take to transfer totalBytes through the I2C hardware,
|
||||
// add user supplied timeOutMillis to Calculated Value
|
||||
|
||||
portTickType ticksTimeOut = ((totalBytes*10*1000)/(i2cGetFrequency(i2c))+timeOutMillis)/portTICK_PERIOD_MS;
|
||||
TickType_t ticksTimeOut = ((totalBytes*10*1000)/(i2cGetFrequency(i2c))+timeOutMillis)/portTICK_PERIOD_MS;
|
||||
|
||||
i2c->dev->ctr.trans_start=1; // go for it
|
||||
|
||||
@ -1790,6 +1805,10 @@ i2c_t * i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t clk_speed){
|
||||
if(i2c_num >= 2){
|
||||
return NULL;
|
||||
}
|
||||
if(!clk_speed){
|
||||
//originally does not change the speed, but getFrequency and setFrequency need to be implemented first.
|
||||
clk_speed = 100000;
|
||||
}
|
||||
i2c_t * out = NULL;
|
||||
if(i2c_ports[i2c_num] == NULL){
|
||||
out = (i2c_t*)malloc(sizeof(i2c_t));
|
||||
|
@ -17,9 +17,13 @@
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "esp32-hal-log.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "esp32-hal-cpu.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "esp32-hal-ledc.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
@ -43,7 +47,7 @@
|
||||
#else
|
||||
#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS)
|
||||
#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock)
|
||||
xSemaphoreHandle _ledc_sys_lock = NULL;
|
||||
SemaphoreHandle_t _ledc_sys_lock = NULL;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -21,6 +21,7 @@ extern "C"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#define ARDUHAL_LOG_LEVEL_NONE (0)
|
||||
#define ARDUHAL_LOG_LEVEL_ERROR (1)
|
||||
@ -72,86 +73,62 @@ extern "C"
|
||||
#define ARDUHAL_LOG_RESET_COLOR
|
||||
#endif
|
||||
|
||||
const char * pathToFileName(const char * path);
|
||||
int log_printf(const char *fmt, ...);
|
||||
#if CONFIG_LOG_LOCATION
|
||||
#define ARDUHAL_LOG_FORMAT(letter, format) format
|
||||
#else
|
||||
#define ARDUHAL_LOG_FORMAT(letter, format) "[%s:%u] %s(): " format, (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__
|
||||
#endif
|
||||
|
||||
#define ARDUHAL_SHORT_LOG_FORMAT(letter, format) ARDUHAL_LOG_COLOR_ ## letter format ARDUHAL_LOG_RESET_COLOR "\r\n"
|
||||
#define ARDUHAL_LOG_FORMAT(letter, format) ARDUHAL_LOG_COLOR_ ## letter "[%6u][" #letter "][%s:%u] %s(): " format ARDUHAL_LOG_RESET_COLOR "\r\n", (unsigned long) (esp_timer_get_time() / 1000ULL), pathToFileName(__FILE__), __LINE__, __FUNCTION__
|
||||
#define ARDUHAL_LOG_TAG "ARDUINO"
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
|
||||
#define log_v(format, ...) log_printf(ARDUHAL_LOG_FORMAT(V, format), ##__VA_ARGS__)
|
||||
#define isr_log_v(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(V, format), ##__VA_ARGS__)
|
||||
#define log_v(format, ...) ESP_LOGV(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(V, format), ##__VA_ARGS__)
|
||||
#define isr_log_v(format, ...) ESP_LOGV(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(V, format), ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_v(format, ...)
|
||||
#define isr_log_v(format, ...)
|
||||
#endif
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
|
||||
#define log_d(format, ...) log_printf(ARDUHAL_LOG_FORMAT(D, format), ##__VA_ARGS__)
|
||||
#define isr_log_d(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(D, format), ##__VA_ARGS__)
|
||||
#define log_d(format, ...) ESP_LOGD(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(D, format), ##__VA_ARGS__)
|
||||
#define isr_log_d(format, ...) ESP_LOGD(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(D, format), ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_d(format, ...)
|
||||
#define isr_log_d(format, ...)
|
||||
#endif
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
|
||||
#define log_i(format, ...) log_printf(ARDUHAL_LOG_FORMAT(I, format), ##__VA_ARGS__)
|
||||
#define isr_log_i(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(I, format), ##__VA_ARGS__)
|
||||
#define log_i(format, ...) ESP_LOGI(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(I, format), ##__VA_ARGS__)
|
||||
#define isr_log_i(format, ...) ESP_LOGI(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(I, format), ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_i(format, ...)
|
||||
#define isr_log_i(format, ...)
|
||||
#endif
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN
|
||||
#define log_w(format, ...) log_printf(ARDUHAL_LOG_FORMAT(W, format), ##__VA_ARGS__)
|
||||
#define isr_log_w(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(W, format), ##__VA_ARGS__)
|
||||
#define log_w(format, ...) ESP_LOGW(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(W, format), ##__VA_ARGS__)
|
||||
#define isr_log_w(format, ...) ESP_LOGW(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(W, format), ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_w(format, ...)
|
||||
#define isr_log_w(format, ...)
|
||||
#endif
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
|
||||
#define log_e(format, ...) log_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define isr_log_e(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define log_e(format, ...) ESP_LOGE(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define isr_log_e(format, ...) ESP_LOGE(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_e(format, ...)
|
||||
#define isr_log_e(format, ...)
|
||||
#endif
|
||||
|
||||
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_NONE
|
||||
#define log_n(format, ...) log_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define isr_log_n(format, ...) ets_printf(ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define log_n(format, ...) ESP_LOGE(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#define isr_log_n(format, ...) ESP_LOGE(ARDUHAL_LOG_TAG, ARDUHAL_LOG_FORMAT(E, format), ##__VA_ARGS__)
|
||||
#else
|
||||
#define log_n(format, ...)
|
||||
#define isr_log_n(format, ...)
|
||||
#endif
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifdef CONFIG_ARDUHAL_ESP_LOG
|
||||
#undef ESP_LOGE
|
||||
#undef ESP_LOGW
|
||||
#undef ESP_LOGI
|
||||
#undef ESP_LOGD
|
||||
#undef ESP_LOGV
|
||||
#undef ESP_EARLY_LOGE
|
||||
#undef ESP_EARLY_LOGW
|
||||
#undef ESP_EARLY_LOGI
|
||||
#undef ESP_EARLY_LOGD
|
||||
#undef ESP_EARLY_LOGV
|
||||
|
||||
#define ESP_LOGE(tag, ...) log_e(__VA_ARGS__)
|
||||
#define ESP_LOGW(tag, ...) log_w(__VA_ARGS__)
|
||||
#define ESP_LOGI(tag, ...) log_i(__VA_ARGS__)
|
||||
#define ESP_LOGD(tag, ...) log_d(__VA_ARGS__)
|
||||
#define ESP_LOGV(tag, ...) log_v(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGE(tag, ...) isr_log_e(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGW(tag, ...) isr_log_w(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGI(tag, ...) isr_log_i(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGD(tag, ...) isr_log_d(__VA_ARGS__)
|
||||
#define ESP_EARLY_LOGV(tag, ...) isr_log_v(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
|
@ -20,7 +20,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
void pinMatrixOutAttach(uint8_t pin, uint8_t function, bool invertOut, bool invertEnable);
|
||||
|
@ -13,6 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp32-hal-misc.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_attr.h"
|
||||
@ -21,9 +23,6 @@
|
||||
#include "esp_partition.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
#include "esp_ota_ops.h"
|
||||
#endif //CONFIG_APP_ROLLBACK_ENABLE
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
#include "esp_bt.h"
|
||||
#endif //CONFIG_BT_ENABLED
|
||||
@ -32,7 +31,6 @@
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
@ -63,101 +61,11 @@ void __yield()
|
||||
|
||||
void yield() __attribute__ ((weak, alias("__yield")));
|
||||
|
||||
#if CONFIG_AUTOSTART_ARDUINO
|
||||
|
||||
extern TaskHandle_t loopTaskHandle;
|
||||
extern bool loopTaskWDTEnabled;
|
||||
|
||||
void enableLoopWDT(){
|
||||
if(loopTaskHandle != NULL){
|
||||
if(esp_task_wdt_add(loopTaskHandle) != ESP_OK){
|
||||
log_e("Failed to add loop task to WDT");
|
||||
} else {
|
||||
loopTaskWDTEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void disableLoopWDT(){
|
||||
if(loopTaskHandle != NULL && loopTaskWDTEnabled){
|
||||
loopTaskWDTEnabled = false;
|
||||
if(esp_task_wdt_delete(loopTaskHandle) != ESP_OK){
|
||||
log_e("Failed to remove loop task from WDT");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feedLoopWDT(){
|
||||
esp_err_t err = esp_task_wdt_reset();
|
||||
if(err != ESP_OK){
|
||||
log_e("Failed to feed WDT! Error: %d", err);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void enableCore0WDT(){
|
||||
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
|
||||
if(idle_0 == NULL || esp_task_wdt_add(idle_0) != ESP_OK){
|
||||
log_e("Failed to add Core 0 IDLE task to WDT");
|
||||
}
|
||||
}
|
||||
|
||||
void disableCore0WDT(){
|
||||
TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
|
||||
if(idle_0 == NULL || esp_task_wdt_delete(idle_0) != ESP_OK){
|
||||
log_e("Failed to remove Core 0 IDLE task from WDT");
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
void enableCore1WDT(){
|
||||
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
|
||||
if(idle_1 == NULL || esp_task_wdt_add(idle_1) != ESP_OK){
|
||||
log_e("Failed to add Core 1 IDLE task to WDT");
|
||||
}
|
||||
}
|
||||
|
||||
void disableCore1WDT(){
|
||||
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
|
||||
if(idle_1 == NULL || esp_task_wdt_delete(idle_1) != ESP_OK){
|
||||
log_e("Failed to remove Core 1 IDLE task from WDT");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BaseType_t xTaskCreateUniversal( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID ){
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
if(xCoreID >= 0 && xCoreID < 2) {
|
||||
return xTaskCreatePinnedToCore(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID);
|
||||
} else {
|
||||
#endif
|
||||
return xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask);
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long ARDUINO_ISR_ATTR micros()
|
||||
{
|
||||
return (unsigned long) (esp_timer_get_time());
|
||||
}
|
||||
|
||||
unsigned long ARDUINO_ISR_ATTR millis()
|
||||
{
|
||||
return (unsigned long) (esp_timer_get_time() / 1000ULL);
|
||||
}
|
||||
|
||||
void delay(uint32_t ms)
|
||||
{
|
||||
vTaskDelay(ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
void ARDUINO_ISR_ATTR delayMicroseconds(uint32_t us)
|
||||
{
|
||||
uint32_t m = micros();
|
||||
@ -174,83 +82,3 @@ void ARDUINO_ISR_ATTR delayMicroseconds(uint32_t us)
|
||||
}
|
||||
}
|
||||
|
||||
void initVariant() __attribute__((weak));
|
||||
void initVariant() {}
|
||||
|
||||
void init() __attribute__((weak));
|
||||
void init() {}
|
||||
|
||||
bool verifyOta() __attribute__((weak));
|
||||
bool verifyOta() { return true; }
|
||||
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
//overwritten in esp32-hal-bt.c
|
||||
bool btInUse() __attribute__((weak));
|
||||
bool btInUse(){ return false; }
|
||||
#endif
|
||||
|
||||
void initArduino()
|
||||
{
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
esp_ota_img_states_t ota_state;
|
||||
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
|
||||
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
if (verifyOta()) {
|
||||
esp_ota_mark_app_valid_cancel_rollback();
|
||||
} else {
|
||||
log_e("OTA verification failed! Start rollback to the previous version ...");
|
||||
esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//init proper ref tick value for PLL (uncomment if REF_TICK is different than 1MHz)
|
||||
//ESP_REG(APB_CTRL_PLL_TICK_CONF_REG) = APB_CLK_FREQ / REF_CLK_FREQ - 1;
|
||||
#ifdef F_CPU
|
||||
setCpuFrequencyMhz(F_CPU/1000000);
|
||||
#endif
|
||||
#if CONFIG_SPIRAM_SUPPORT || CONFIG_SPIRAM
|
||||
psramInit();
|
||||
#endif
|
||||
esp_log_level_set("*", CONFIG_LOG_DEFAULT_LEVEL);
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if(err == ESP_ERR_NVS_NO_FREE_PAGES){
|
||||
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_NVS, NULL);
|
||||
if (partition != NULL) {
|
||||
err = esp_partition_erase_range(partition, 0, partition->size);
|
||||
if(!err){
|
||||
err = nvs_flash_init();
|
||||
} else {
|
||||
log_e("Failed to format the broken NVS partition!");
|
||||
}
|
||||
}
|
||||
}
|
||||
if(err) {
|
||||
log_e("Failed to initialize NVS! Error: %u", err);
|
||||
}
|
||||
#ifdef CONFIG_BT_ENABLED
|
||||
if(!btInUse()){
|
||||
esp_bt_controller_mem_release(ESP_BT_MODE_BTDM);
|
||||
}
|
||||
#endif
|
||||
init();
|
||||
initVariant();
|
||||
}
|
||||
|
||||
//used by hal log
|
||||
const char * ARDUINO_ISR_ATTR pathToFileName(const char * path)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t pos = 0;
|
||||
char * p = (char *)path;
|
||||
while(*p){
|
||||
i++;
|
||||
if(*p == '/' || *p == '\\'){
|
||||
pos = i;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return path+pos;
|
||||
}
|
||||
|
||||
|
16
cores/esp32/esp32-hal-misc.h
Normal file
16
cores/esp32/esp32-hal-misc.h
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void yield(void);
|
||||
|
||||
unsigned long micros();
|
||||
void delayMicroseconds(uint32_t us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -14,6 +14,9 @@
|
||||
|
||||
#include "esp32-hal.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#if CONFIG_SPIRAM_SUPPORT || CONFIG_SPIRAM
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "esp_heap_caps.h"
|
||||
@ -51,7 +54,6 @@ bool psramInit(){
|
||||
log_w("PSRAM not supported!");
|
||||
return false;
|
||||
}
|
||||
esp_spiram_init_cache();
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
extern void esp_config_data_cache_mode(void);
|
||||
esp_config_data_cache_mode();
|
||||
|
@ -17,11 +17,20 @@
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "esp32-hal-log.h"
|
||||
#include "esp8266-compat.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/rmt_struct.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include <esp_private/periph_ctrl.h>
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "hal/rmt_ll.h"
|
||||
#include "driver/rmt.h"
|
||||
#include "esp32-hal-rmt.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
|
||||
// RMTMEM address is declared in <target>.peripherals.ld
|
||||
extern rmt_mem_t RMTMEM;
|
||||
|
||||
/**
|
||||
* Internal macros
|
||||
@ -96,12 +105,13 @@ struct rmt_obj_s
|
||||
transaction_state_t tx_state;
|
||||
rmt_rx_data_cb_t cb;
|
||||
bool data_alloc;
|
||||
void * arg;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal variables for channel descriptors
|
||||
*/
|
||||
static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = {
|
||||
static SemaphoreHandle_t g_rmt_objlocks[MAX_CHANNELS] = {
|
||||
NULL, NULL, NULL, NULL,
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
NULL, NULL, NULL, NULL
|
||||
@ -109,15 +119,15 @@ static xSemaphoreHandle g_rmt_objlocks[MAX_CHANNELS] = {
|
||||
};
|
||||
|
||||
static rmt_obj_t g_rmt_objects[MAX_CHANNELS] = {
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
{ false, NULL, 0, 0, 0, 0, 0, NULL, E_NO_INTR, E_INACTIVE, NULL, false, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -128,7 +138,7 @@ static intr_handle_t intr_handle;
|
||||
|
||||
static bool periph_enabled = false;
|
||||
|
||||
static xSemaphoreHandle g_rmt_block_lock = NULL;
|
||||
static SemaphoreHandle_t g_rmt_block_lock = NULL;
|
||||
|
||||
/**
|
||||
* Internal method (private) declarations
|
||||
@ -330,6 +340,7 @@ bool rmtReadData(rmt_obj_t* rmt, uint32_t* data, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool rmtBeginReceive(rmt_obj_t* rmt)
|
||||
{
|
||||
if (!rmt) {
|
||||
@ -363,7 +374,7 @@ bool rmtReceiveCompleted(rmt_obj_t* rmt)
|
||||
}
|
||||
}
|
||||
|
||||
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb)
|
||||
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg)
|
||||
{
|
||||
if (!rmt && !cb) {
|
||||
return false;
|
||||
@ -371,6 +382,7 @@ bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb)
|
||||
int channel = rmt->channel;
|
||||
|
||||
RMT_MUTEX_LOCK(channel);
|
||||
rmt->arg = arg;
|
||||
rmt->intr_mode = E_RX_INTR;
|
||||
rmt->tx_state = E_FIRST_HALF;
|
||||
rmt->cb = cb;
|
||||
@ -397,6 +409,19 @@ bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rmtEnd(rmt_obj_t* rmt) {
|
||||
if (!rmt) {
|
||||
return false;
|
||||
}
|
||||
int channel = rmt->channel;
|
||||
|
||||
RMT_MUTEX_LOCK(channel);
|
||||
RMT.conf_ch[channel].conf1.rx_en = 1;
|
||||
RMT_MUTEX_UNLOCK(channel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag, bool waitForData, uint32_t timeout)
|
||||
{
|
||||
if (!rmt) {
|
||||
@ -529,6 +554,8 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
|
||||
rmt->tx_not_rx = tx_not_rx;
|
||||
rmt->buffers =buffers;
|
||||
rmt->channel = channel;
|
||||
rmt->arg = NULL;
|
||||
|
||||
_initPin(pin, channel, tx_not_rx);
|
||||
|
||||
// Initialize the registers in default mode:
|
||||
@ -555,6 +582,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
|
||||
RMT.conf_ch[channel].conf1.idle_out_lv = 0; // signal level for idle
|
||||
RMT.conf_ch[channel].conf1.idle_out_en = 1; // enable idle
|
||||
RMT.conf_ch[channel].conf1.ref_always_on = 0; // base clock
|
||||
|
||||
RMT.apb_conf.fifo_mask = 1;
|
||||
|
||||
if (tx_not_rx) {
|
||||
@ -670,7 +698,7 @@ static void ARDUINO_ISR_ATTR _rmt_isr(void* arg)
|
||||
}
|
||||
if (g_rmt_objects[ch].cb) {
|
||||
// actually received data ptr
|
||||
(g_rmt_objects[ch].cb)(data_received, _rmt_get_mem_len(ch));
|
||||
(g_rmt_objects[ch].cb)(data_received, _rmt_get_mem_len(ch), g_rmt_objects[ch].arg);
|
||||
|
||||
// restart the reception
|
||||
RMT.conf_ch[ch].conf1.mem_owner = 1;
|
||||
@ -834,12 +862,15 @@ static int ARDUINO_ISR_ATTR _rmt_get_mem_len(uint8_t channel)
|
||||
{
|
||||
int block_num = RMT.conf_ch[channel].conf0.mem_size;
|
||||
int item_block_len = block_num * 64;
|
||||
volatile rmt_item32_t* data = RMTMEM.chan[channel].data32;
|
||||
volatile uint32_t* data = &RMTMEM.chan[channel].data32->val;
|
||||
int idx;
|
||||
for(idx = 0; idx < item_block_len; idx++) {
|
||||
if(data[idx].duration0 == 0) {
|
||||
rmt_item32_t helper;
|
||||
helper.val = data[idx];
|
||||
|
||||
if(helper.duration0 == 0) {
|
||||
return idx;
|
||||
} else if(data[idx].duration1 == 0) {
|
||||
} else if(helper.duration1 == 0) {
|
||||
return idx + 1;
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ typedef enum {
|
||||
|
||||
typedef struct rmt_obj_s rmt_obj_t;
|
||||
|
||||
typedef void (*rmt_rx_data_cb_t)(uint32_t *data, size_t len);
|
||||
typedef void (*rmt_rx_data_cb_t)(uint32_t *data, size_t len, void *arg);
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
@ -90,8 +90,13 @@ bool rmtReadAsync(rmt_obj_t* rmt, rmt_data_t* data, size_t size, void* eventFlag
|
||||
* and callback with data from ISR
|
||||
*
|
||||
*/
|
||||
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb);
|
||||
bool rmtRead(rmt_obj_t* rmt, rmt_rx_data_cb_t cb, void * arg);
|
||||
|
||||
/***
|
||||
* Ends async receive started with rmtRead(); but does not
|
||||
* rmtDeInit().
|
||||
*/
|
||||
bool rmtEnd(rmt_obj_t* rmt);
|
||||
|
||||
/* Additional interface */
|
||||
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "soc/gpio_sd_reg.h"
|
||||
#include "soc/gpio_sd_struct.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp32-hal-cpu.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
@ -40,7 +43,7 @@
|
||||
#else
|
||||
#define SD_MUTEX_LOCK() do {} while (xSemaphoreTake(_sd_sys_lock, portMAX_DELAY) != pdPASS)
|
||||
#define SD_MUTEX_UNLOCK() xSemaphoreGive(_sd_sys_lock)
|
||||
xSemaphoreHandle _sd_sys_lock;
|
||||
SemaphoreHandle_t _sd_sys_lock;
|
||||
#endif
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
|
@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp32-hal-spi.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
@ -43,11 +45,14 @@
|
||||
#include "rom/gpio.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "esp32-hal-cpu.h"
|
||||
|
||||
struct spi_struct_t {
|
||||
spi_dev_t * dev;
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
xSemaphoreHandle lock;
|
||||
SemaphoreHandle_t lock;
|
||||
#endif
|
||||
uint8_t num;
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ extern "C" {
|
||||
struct spi_struct_t;
|
||||
typedef struct spi_struct_t spi_t;
|
||||
|
||||
spi_t * spiStartBus(uint8_t spi_num, uint32_t freq, uint8_t dataMode, uint8_t bitOrder);
|
||||
spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder);
|
||||
void spiStopBus(spi_t * spi);
|
||||
|
||||
//Attach/Detach Signal Pins
|
||||
|
@ -1,97 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "lwip/apps/sntp.h"
|
||||
//#include "tcpip_adapter.h"
|
||||
#include "esp_netif.h"
|
||||
|
||||
static void setTimeZone(long offset, int daylight)
|
||||
{
|
||||
char cst[17] = {0};
|
||||
char cdt[17] = "DST";
|
||||
char tz[33] = {0};
|
||||
|
||||
if(offset % 3600){
|
||||
sprintf(cst, "UTC%ld:%02u:%02u", offset / 3600, abs((offset % 3600) / 60), abs(offset % 60));
|
||||
} else {
|
||||
sprintf(cst, "UTC%ld", offset / 3600);
|
||||
}
|
||||
if(daylight != 3600){
|
||||
long tz_dst = offset - daylight;
|
||||
if(tz_dst % 3600){
|
||||
sprintf(cdt, "DST%ld:%02u:%02u", tz_dst / 3600, abs((tz_dst % 3600) / 60), abs(tz_dst % 60));
|
||||
} else {
|
||||
sprintf(cdt, "DST%ld", tz_dst / 3600);
|
||||
}
|
||||
}
|
||||
sprintf(tz, "%s%s", cst, cdt);
|
||||
setenv("TZ", tz, 1);
|
||||
tzset();
|
||||
}
|
||||
|
||||
/*
|
||||
* configTime
|
||||
* Source: https://github.com/esp8266/Arduino/blob/master/cores/esp8266/time.c
|
||||
* */
|
||||
void configTime(long gmtOffset_sec, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
|
||||
{
|
||||
//tcpip_adapter_init(); // Should not hurt anything if already inited
|
||||
esp_netif_init();
|
||||
if(sntp_enabled()){
|
||||
sntp_stop();
|
||||
}
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, (char*)server1);
|
||||
sntp_setservername(1, (char*)server2);
|
||||
sntp_setservername(2, (char*)server3);
|
||||
sntp_init();
|
||||
setTimeZone(-gmtOffset_sec, daylightOffset_sec);
|
||||
}
|
||||
|
||||
/*
|
||||
* configTzTime
|
||||
* sntp setup using TZ environment variable
|
||||
* */
|
||||
void configTzTime(const char* tz, const char* server1, const char* server2, const char* server3)
|
||||
{
|
||||
//tcpip_adapter_init(); // Should not hurt anything if already inited
|
||||
esp_netif_init();
|
||||
if(sntp_enabled()){
|
||||
sntp_stop();
|
||||
}
|
||||
sntp_setoperatingmode(SNTP_OPMODE_POLL);
|
||||
sntp_setservername(0, (char*)server1);
|
||||
sntp_setservername(1, (char*)server2);
|
||||
sntp_setservername(2, (char*)server3);
|
||||
sntp_init();
|
||||
setenv("TZ", tz, 1);
|
||||
tzset();
|
||||
}
|
||||
|
||||
bool getLocalTime(struct tm * info, uint32_t ms)
|
||||
{
|
||||
uint32_t start = millis();
|
||||
time_t now;
|
||||
while((millis()-start) <= ms) {
|
||||
time(&now);
|
||||
localtime_r(&now, info);
|
||||
if(info->tm_year > (2016 - 1900)){
|
||||
return true;
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,358 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/timer_group_struct.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_attr.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
|
||||
#define HWTIMER_LOCK() portENTER_CRITICAL(timer->lock)
|
||||
#define HWTIMER_UNLOCK() portEXIT_CRITICAL(timer->lock)
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t reserved0: 10;
|
||||
uint32_t alarm_en: 1; /*When set alarm is enabled*/
|
||||
uint32_t level_int_en: 1; /*When set level type interrupt will be generated during alarm*/
|
||||
uint32_t edge_int_en: 1; /*When set edge type interrupt will be generated during alarm*/
|
||||
uint32_t divider: 16; /*Timer clock (T0/1_clk) pre-scale value.*/
|
||||
uint32_t autoreload: 1; /*When set timer 0/1 auto-reload at alarming is enabled*/
|
||||
uint32_t increase: 1; /*When set timer 0/1 time-base counter increment. When cleared timer 0 time-base counter decrement.*/
|
||||
uint32_t enable: 1; /*When set timer 0/1 time-base counter is enabled*/
|
||||
};
|
||||
uint32_t val;
|
||||
} config;
|
||||
uint32_t cnt_low; /*Register to store timer 0/1 time-base counter current value lower 32 bits.*/
|
||||
uint32_t cnt_high; /*Register to store timer 0 time-base counter current value higher 32 bits.*/
|
||||
uint32_t update; /*Write any value will trigger a timer 0 time-base counter value update (timer 0 current value will be stored in registers above)*/
|
||||
uint32_t alarm_low; /*Timer 0 time-base counter value lower 32 bits that will trigger the alarm*/
|
||||
uint32_t alarm_high; /*Timer 0 time-base counter value higher 32 bits that will trigger the alarm*/
|
||||
uint32_t load_low; /*Lower 32 bits of the value that will load into timer 0 time-base counter*/
|
||||
uint32_t load_high; /*higher 32 bits of the value that will load into timer 0 time-base counter*/
|
||||
uint32_t reload; /*Write any value will trigger timer 0 time-base counter reload*/
|
||||
} hw_timer_reg_t;
|
||||
|
||||
typedef struct hw_timer_s {
|
||||
hw_timer_reg_t * dev;
|
||||
uint8_t num;
|
||||
uint8_t group;
|
||||
uint8_t timer;
|
||||
portMUX_TYPE lock;
|
||||
} hw_timer_t;
|
||||
|
||||
static hw_timer_t hw_timer[4] = {
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE),0,0,0,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x0024),1,0,1,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1000),2,1,0,portMUX_INITIALIZER_UNLOCKED},
|
||||
{(hw_timer_reg_t *)(DR_REG_TIMERGROUP0_BASE + 0x1024),3,1,1,portMUX_INITIALIZER_UNLOCKED}
|
||||
};
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
static voidFuncPtr __timerInterruptHandlers[4] = {0,0,0,0};
|
||||
|
||||
void ARDUINO_ISR_ATTR __timerISR(void * arg){
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t s0 = TIMERG0.int_st_timers.val;
|
||||
uint32_t s1 = TIMERG1.int_st_timers.val;
|
||||
TIMERG0.int_clr_timers.val = s0;
|
||||
TIMERG1.int_clr_timers.val = s1;
|
||||
#else
|
||||
uint32_t s0 = TIMERG0.int_st.val;
|
||||
uint32_t s1 = TIMERG1.int_st.val;
|
||||
TIMERG0.int_clr.val = s0;
|
||||
TIMERG1.int_clr.val = s1;
|
||||
#endif
|
||||
uint8_t status = (s1 & 3) << 2 | (s0 & 3);
|
||||
uint8_t i = 4;
|
||||
//restart the timers that should autoreload
|
||||
while(i--){
|
||||
hw_timer_reg_t * dev = hw_timer[i].dev;
|
||||
if((status & (1 << i)) && dev->config.autoreload){
|
||||
dev->config.alarm_en = 1;
|
||||
}
|
||||
}
|
||||
i = 4;
|
||||
//call callbacks
|
||||
while(i--){
|
||||
if(__timerInterruptHandlers[i] && (status & (1 << i))){
|
||||
__timerInterruptHandlers[i]();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t timerRead(hw_timer_t *timer){
|
||||
timer->dev->update = 1;
|
||||
uint64_t h = timer->dev->cnt_high;
|
||||
uint64_t l = timer->dev->cnt_low;
|
||||
return (h << 32) | l;
|
||||
}
|
||||
|
||||
uint64_t timerAlarmRead(hw_timer_t *timer){
|
||||
uint64_t h = timer->dev->alarm_high;
|
||||
uint64_t l = timer->dev->alarm_low;
|
||||
return (h << 32) | l;
|
||||
}
|
||||
|
||||
void timerWrite(hw_timer_t *timer, uint64_t val){
|
||||
timer->dev->load_high = (uint32_t) (val >> 32);
|
||||
timer->dev->load_low = (uint32_t) (val);
|
||||
timer->dev->reload = 1;
|
||||
}
|
||||
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t alarm_value, bool autoreload){
|
||||
timer->dev->alarm_high = (uint32_t) (alarm_value >> 32);
|
||||
timer->dev->alarm_low = (uint32_t) alarm_value;
|
||||
timer->dev->config.autoreload = autoreload;
|
||||
}
|
||||
|
||||
void timerSetConfig(hw_timer_t *timer, uint32_t config){
|
||||
timer->dev->config.val = config;
|
||||
}
|
||||
|
||||
uint32_t timerGetConfig(hw_timer_t *timer){
|
||||
return timer->dev->config.val;
|
||||
}
|
||||
|
||||
void timerSetCountUp(hw_timer_t *timer, bool countUp){
|
||||
timer->dev->config.increase = countUp;
|
||||
}
|
||||
|
||||
bool timerGetCountUp(hw_timer_t *timer){
|
||||
return timer->dev->config.increase;
|
||||
}
|
||||
|
||||
void timerSetAutoReload(hw_timer_t *timer, bool autoreload){
|
||||
timer->dev->config.autoreload = autoreload;
|
||||
}
|
||||
|
||||
bool timerGetAutoReload(hw_timer_t *timer){
|
||||
return timer->dev->config.autoreload;
|
||||
}
|
||||
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider){//2 to 65536
|
||||
if(!divider){
|
||||
divider = 0xFFFF;
|
||||
} else if(divider == 1){
|
||||
divider = 2;
|
||||
}
|
||||
int timer_en = timer->dev->config.enable;
|
||||
timer->dev->config.enable = 0;
|
||||
timer->dev->config.divider = divider;
|
||||
timer->dev->config.enable = timer_en;
|
||||
}
|
||||
|
||||
uint16_t timerGetDivider(hw_timer_t *timer){
|
||||
return timer->dev->config.divider;
|
||||
}
|
||||
|
||||
void timerStart(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 1;
|
||||
}
|
||||
|
||||
void timerStop(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
}
|
||||
|
||||
void timerRestart(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timer->dev->reload = 1;
|
||||
timer->dev->config.enable = 1;
|
||||
}
|
||||
|
||||
bool timerStarted(hw_timer_t *timer){
|
||||
return timer->dev->config.enable;
|
||||
}
|
||||
|
||||
void timerAlarmEnable(hw_timer_t *timer){
|
||||
timer->dev->config.alarm_en = 1;
|
||||
}
|
||||
|
||||
void timerAlarmDisable(hw_timer_t *timer){
|
||||
timer->dev->config.alarm_en = 0;
|
||||
}
|
||||
|
||||
bool timerAlarmEnabled(hw_timer_t *timer){
|
||||
return timer->dev->config.alarm_en;
|
||||
}
|
||||
|
||||
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
|
||||
hw_timer_t * timer = (hw_timer_t *)arg;
|
||||
if(ev_type == APB_BEFORE_CHANGE){
|
||||
timer->dev->config.enable = 0;
|
||||
} else {
|
||||
old_apb /= 1000000;
|
||||
new_apb /= 1000000;
|
||||
timer->dev->config.divider = (new_apb * timer->dev->config.divider) / old_apb;
|
||||
timer->dev->config.enable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
hw_timer_t * timerBegin(uint8_t num, uint16_t divider, bool countUp){
|
||||
if(num > 3){
|
||||
return NULL;
|
||||
}
|
||||
hw_timer_t * timer = &hw_timer[num];
|
||||
if(timer->group) {
|
||||
periph_module_enable(PERIPH_TIMG1_MODULE);
|
||||
} else {
|
||||
periph_module_enable(PERIPH_TIMG0_MODULE);
|
||||
}
|
||||
timer->dev->config.enable = 0;
|
||||
if(timer->group) {
|
||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_clr.val = BIT(timer->timer);
|
||||
#endif
|
||||
} else {
|
||||
TIMERG0.int_ena.val &= ~BIT(timer->timer);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_clr.val = BIT(timer->timer);
|
||||
#endif
|
||||
}
|
||||
#ifdef TIMER_GROUP_SUPPORTS_XTAL_CLOCK
|
||||
timer->dev->config.use_xtal = 0;
|
||||
#endif
|
||||
timerSetDivider(timer, divider);
|
||||
timerSetCountUp(timer, countUp);
|
||||
timerSetAutoReload(timer, false);
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
timerWrite(timer, 0);
|
||||
timer->dev->config.enable = 1;
|
||||
addApbChangeCallback(timer, _on_apb_change);
|
||||
return timer;
|
||||
}
|
||||
|
||||
void timerEnd(hw_timer_t *timer){
|
||||
timer->dev->config.enable = 0;
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
removeApbChangeCallback(timer, _on_apb_change);
|
||||
}
|
||||
|
||||
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge){
|
||||
// EDGE DOES NOT WORK CURRENTLY
|
||||
edge = false;
|
||||
|
||||
static bool initialized = false;
|
||||
static intr_handle_t intr_handle = NULL;
|
||||
if(intr_handle){
|
||||
esp_intr_disable(intr_handle);
|
||||
}
|
||||
if(fn == NULL){
|
||||
timer->dev->config.level_int_en = 0;
|
||||
timer->dev->config.edge_int_en = 0;
|
||||
timer->dev->config.alarm_en = 0;
|
||||
if(timer->num & 2){
|
||||
TIMERG1.int_ena.val &= ~BIT(timer->timer);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG1.int_clr_timers.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG1.int_clr.val = BIT(timer->timer);
|
||||
#endif
|
||||
} else {
|
||||
TIMERG0.int_ena.val &= ~BIT(timer->timer);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
TIMERG0.int_clr_timers.val |= BIT(timer->timer);
|
||||
#else
|
||||
TIMERG0.int_clr.val = BIT(timer->timer);
|
||||
#endif
|
||||
}
|
||||
__timerInterruptHandlers[timer->num] = NULL;
|
||||
} else {
|
||||
__timerInterruptHandlers[timer->num] = fn;
|
||||
timer->dev->config.level_int_en = edge?0:1;//When set, an alarm will generate a level type interrupt.
|
||||
timer->dev->config.edge_int_en = edge?1:0;//When set, an alarm will generate an edge type interrupt.
|
||||
int intr_source = 0;
|
||||
if(!edge){
|
||||
if(timer->group){
|
||||
intr_source = ETS_TG1_T0_LEVEL_INTR_SOURCE + timer->timer;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_LEVEL_INTR_SOURCE + timer->timer;
|
||||
}
|
||||
} else {
|
||||
if(timer->group){
|
||||
intr_source = ETS_TG1_T0_EDGE_INTR_SOURCE + timer->timer;
|
||||
} else {
|
||||
intr_source = ETS_TG0_T0_EDGE_INTR_SOURCE + timer->timer;
|
||||
}
|
||||
}
|
||||
if(!initialized){
|
||||
initialized = true;
|
||||
esp_intr_alloc(intr_source, (int)(ARDUINO_ISR_FLAG|ESP_INTR_FLAG_LOWMED), __timerISR, NULL, &intr_handle);
|
||||
} else {
|
||||
intr_matrix_set(esp_intr_get_cpu(intr_handle), intr_source, esp_intr_get_intno(intr_handle));
|
||||
}
|
||||
if(timer->group){
|
||||
TIMERG1.int_ena.val |= BIT(timer->timer);
|
||||
} else {
|
||||
TIMERG0.int_ena.val |= BIT(timer->timer);
|
||||
}
|
||||
}
|
||||
if(intr_handle){
|
||||
esp_intr_enable(intr_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void timerDetachInterrupt(hw_timer_t *timer){
|
||||
timerAttachInterrupt(timer, NULL, false);
|
||||
}
|
||||
|
||||
uint64_t timerReadMicros(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return timer_val * div / (getApbFrequency() / 1000000);
|
||||
}
|
||||
|
||||
double timerReadSeconds(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return (double)timer_val * div / getApbFrequency();
|
||||
}
|
||||
|
||||
uint64_t timerAlarmReadMicros(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerAlarmRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return timer_val * div / (getApbFrequency() / 1000000);
|
||||
}
|
||||
|
||||
double timerAlarmReadSeconds(hw_timer_t *timer){
|
||||
uint64_t timer_val = timerAlarmRead(timer);
|
||||
uint16_t div = timerGetDivider(timer);
|
||||
return (double)timer_val * div / getApbFrequency();
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
Arduino.h - Main include file for the Arduino SDK
|
||||
Copyright (c) 2005-2013 Arduino Team. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef MAIN_ESP32_HAL_TIMER_H_
|
||||
#define MAIN_ESP32_HAL_TIMER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
struct hw_timer_s;
|
||||
typedef struct hw_timer_s hw_timer_t;
|
||||
|
||||
hw_timer_t * timerBegin(uint8_t timer, uint16_t divider, bool countUp);
|
||||
void timerEnd(hw_timer_t *timer);
|
||||
|
||||
void timerSetConfig(hw_timer_t *timer, uint32_t config);
|
||||
uint32_t timerGetConfig(hw_timer_t *timer);
|
||||
|
||||
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);
|
||||
void timerDetachInterrupt(hw_timer_t *timer);
|
||||
|
||||
void timerStart(hw_timer_t *timer);
|
||||
void timerStop(hw_timer_t *timer);
|
||||
void timerRestart(hw_timer_t *timer);
|
||||
void timerWrite(hw_timer_t *timer, uint64_t val);
|
||||
void timerSetDivider(hw_timer_t *timer, uint16_t divider);
|
||||
void timerSetCountUp(hw_timer_t *timer, bool countUp);
|
||||
void timerSetAutoReload(hw_timer_t *timer, bool autoreload);
|
||||
|
||||
bool timerStarted(hw_timer_t *timer);
|
||||
uint64_t timerRead(hw_timer_t *timer);
|
||||
uint64_t timerReadMicros(hw_timer_t *timer);
|
||||
double timerReadSeconds(hw_timer_t *timer);
|
||||
uint16_t timerGetDivider(hw_timer_t *timer);
|
||||
bool timerGetCountUp(hw_timer_t *timer);
|
||||
bool timerGetAutoReload(hw_timer_t *timer);
|
||||
|
||||
void timerAlarmEnable(hw_timer_t *timer);
|
||||
void timerAlarmDisable(hw_timer_t *timer);
|
||||
void timerAlarmWrite(hw_timer_t *timer, uint64_t interruptAt, bool autoreload);
|
||||
|
||||
bool timerAlarmEnabled(hw_timer_t *timer);
|
||||
uint64_t timerAlarmRead(hw_timer_t *timer);
|
||||
uint64_t timerAlarmReadMicros(hw_timer_t *timer);
|
||||
double timerAlarmReadSeconds(hw_timer_t *timer);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAIN_ESP32_HAL_TIMER_H_ */
|
@ -30,6 +30,8 @@
|
||||
|
||||
#include "esp32-hal-tinyusb.h"
|
||||
#include "esp32s2/rom/usb/usb_persist.h"
|
||||
#include "esp32s2/rom/usb/usb_dc.h"
|
||||
#include "esp32s2/rom/usb/chip_usb_dw_wrapper.h"
|
||||
|
||||
typedef char tusb_str_t[127];
|
||||
|
||||
@ -457,27 +459,22 @@ static void IRAM_ATTR usb_persist_shutdown_handler(void)
|
||||
{
|
||||
if(usb_persist_mode != RESTART_NO_PERSIST){
|
||||
if (usb_persist_enabled) {
|
||||
REG_SET_BIT(RTC_CNTL_USB_CONF_REG, RTC_CNTL_IO_MUX_RESET_DISABLE);
|
||||
REG_SET_BIT(RTC_CNTL_USB_CONF_REG, RTC_CNTL_USB_RESET_DISABLE);
|
||||
usb_dc_prepare_persist();
|
||||
}
|
||||
if (usb_persist_mode == RESTART_BOOTLOADER) {
|
||||
//USB CDC Download
|
||||
if (usb_persist_enabled) {
|
||||
USB_WRAP.date.val = USBDC_PERSIST_ENA;
|
||||
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
|
||||
}
|
||||
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
|
||||
periph_module_disable(PERIPH_TIMG1_MODULE);
|
||||
} else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) {
|
||||
//DFU Download
|
||||
USB_WRAP.date.val = USBDC_BOOT_DFU;
|
||||
chip_usb_set_persist_flags(USBDC_BOOT_DFU);
|
||||
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
|
||||
periph_module_disable(PERIPH_TIMG0_MODULE);
|
||||
periph_module_disable(PERIPH_TIMG1_MODULE);
|
||||
} else if (usb_persist_enabled) {
|
||||
//USB Persist reboot
|
||||
USB_WRAP.date.val = USBDC_PERSIST_ENA;
|
||||
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
|
||||
}
|
||||
SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_PROCPU_RST);
|
||||
}
|
||||
}
|
||||
|
||||
@ -531,7 +528,7 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
||||
periph_module_enable(PERIPH_USB_MODULE);
|
||||
}
|
||||
|
||||
if (usb_persist_enabled && esp_register_shutdown_handler(usb_persist_shutdown_handler) != ESP_OK) {
|
||||
if (esp_register_shutdown_handler(usb_persist_shutdown_handler) != ESP_OK) {
|
||||
initialized = false;
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@ -550,11 +547,9 @@ esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
|
||||
|
||||
void usb_persist_restart(restart_type_t mode)
|
||||
{
|
||||
if (usb_persist_enabled && mode < RESTART_TYPE_MAX) {
|
||||
if (mode < RESTART_TYPE_MAX) {
|
||||
usb_persist_mode = mode;
|
||||
esp_restart();
|
||||
} else {
|
||||
log_e("Persistence is not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include "esp32-hal-touch.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
@ -31,13 +32,14 @@
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#else
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
#include "esp32-hal-gpio.h"
|
||||
|
||||
static uint16_t __touchSleepCycles = 0x1000;
|
||||
static uint16_t __touchMeasureCycles = 0x1000;
|
||||
|
@ -24,7 +24,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp32-hal.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Set cycles that measurement operation takes
|
||||
|
@ -1,711 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-uart.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_attr.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "soc/uart_struct.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#include "esp_system.h"
|
||||
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp32/rom/uart.h"
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#include "esp32s2/rom/ets_sys.h"
|
||||
#include "esp32s2/rom/uart.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#else
|
||||
#error Target CONFIG_IDF_TARGET is not supported
|
||||
#endif
|
||||
#else // ESP32 Before IDF 4.0
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
#include "esp_intr.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#define UART_PORTS_NUM 2
|
||||
#define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:0))
|
||||
#define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:0))
|
||||
#define UART_TXD_IDX(u) ((u==0)?U0TXD_OUT_IDX:( (u==1)?U1TXD_OUT_IDX:0))
|
||||
#define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:0))
|
||||
#else
|
||||
#define UART_PORTS_NUM 3
|
||||
#define UART_REG_BASE(u) ((u==0)?DR_REG_UART_BASE:( (u==1)?DR_REG_UART1_BASE:( (u==2)?DR_REG_UART2_BASE:0)))
|
||||
#define UART_RXD_IDX(u) ((u==0)?U0RXD_IN_IDX:( (u==1)?U1RXD_IN_IDX:( (u==2)?U2RXD_IN_IDX:0)))
|
||||
#define UART_TXD_IDX(u) ((u==0)?U0TXD_OUT_IDX:( (u==1)?U1TXD_OUT_IDX:( (u==2)?U2TXD_OUT_IDX:0)))
|
||||
#define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:((u==2)?ETS_UART2_INTR_SOURCE:0)))
|
||||
#endif
|
||||
|
||||
static int s_uart_debug_nr = 0;
|
||||
|
||||
struct uart_struct_t {
|
||||
uart_dev_t * dev;
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
xSemaphoreHandle lock;
|
||||
#endif
|
||||
uint8_t num;
|
||||
xQueueHandle queue;
|
||||
intr_handle_t intr_handle;
|
||||
};
|
||||
|
||||
#if CONFIG_DISABLE_HAL_LOCKS
|
||||
#define UART_MUTEX_LOCK()
|
||||
#define UART_MUTEX_UNLOCK()
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{&UART0, 0, NULL, NULL},
|
||||
{&UART1, 1, NULL, NULL},
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
{&UART2, 2, NULL, NULL}
|
||||
#endif
|
||||
};
|
||||
#else
|
||||
#define UART_MUTEX_LOCK() do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS)
|
||||
#define UART_MUTEX_UNLOCK() xSemaphoreGive(uart->lock)
|
||||
|
||||
static uart_t _uart_bus_array[] = {
|
||||
{&UART0, NULL, 0, NULL, NULL},
|
||||
{&UART1, NULL, 1, NULL, NULL},
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
{&UART2, NULL, 2, NULL, NULL}
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb);
|
||||
|
||||
static void ARDUINO_ISR_ATTR _uart_isr(void *arg)
|
||||
{
|
||||
uint8_t i, c;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
uart_t* uart;
|
||||
|
||||
for(i=0;i<UART_PORTS_NUM;i++){
|
||||
uart = &_uart_bus_array[i];
|
||||
if(uart->intr_handle == NULL){
|
||||
continue;
|
||||
}
|
||||
uart->dev->int_clr.rxfifo_full = 1;
|
||||
uart->dev->int_clr.frm_err = 1;
|
||||
uart->dev->int_clr.rxfifo_tout = 1;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
|
||||
c = uart->dev->fifo.rw_byte;
|
||||
#else
|
||||
uint32_t fifo_reg = UART_FIFO_AHB_REG(i);
|
||||
while(uart->dev->status.rxfifo_cnt) {
|
||||
c = ESP_REG(fifo_reg);
|
||||
#endif
|
||||
if(uart->queue != NULL) {
|
||||
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (xHigherPriorityTaskWoken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
void uartEnableInterrupt(uart_t* uart)
|
||||
{
|
||||
UART_MUTEX_LOCK();
|
||||
uart->dev->conf1.rxfifo_full_thrhd = 112;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uart->dev->conf1.rx_tout_thrhd = 2;
|
||||
#else
|
||||
uart->dev->mem_conf.rx_tout_thrhd = 2;
|
||||
#endif
|
||||
uart->dev->conf1.rx_tout_en = 1;
|
||||
uart->dev->int_ena.rxfifo_full = 1;
|
||||
uart->dev->int_ena.frm_err = 1;
|
||||
uart->dev->int_ena.rxfifo_tout = 1;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
|
||||
esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ARDUINO_ISR_FLAG, _uart_isr, NULL, &uart->intr_handle);
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartDisableInterrupt(uart_t* uart)
|
||||
{
|
||||
UART_MUTEX_LOCK();
|
||||
uart->dev->conf1.val = 0;
|
||||
uart->dev->int_ena.val = 0;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
|
||||
esp_intr_free(uart->intr_handle);
|
||||
uart->intr_handle = NULL;
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartDetachRx(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
pinMatrixInDetach(UART_RXD_IDX(uart->num), false, false);
|
||||
uartDisableInterrupt(uart);
|
||||
}
|
||||
|
||||
void uartDetachTx(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
pinMatrixOutDetach(UART_TXD_IDX(uart->num), false, false);
|
||||
}
|
||||
|
||||
void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted)
|
||||
{
|
||||
if(uart == NULL || rxPin >= GPIO_PIN_COUNT) {
|
||||
return;
|
||||
}
|
||||
pinMode(rxPin, INPUT);
|
||||
pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted);
|
||||
uartEnableInterrupt(uart);
|
||||
}
|
||||
|
||||
void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted)
|
||||
{
|
||||
if(uart == NULL || txPin >= GPIO_PIN_COUNT) {
|
||||
return;
|
||||
}
|
||||
pinMode(txPin, OUTPUT);
|
||||
pinMatrixOutAttach(txPin, UART_TXD_IDX(uart->num), inverted, false);
|
||||
}
|
||||
|
||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted)
|
||||
{
|
||||
if(uart_nr >= UART_PORTS_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(rxPin == -1 && txPin == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uart_t* uart = &_uart_bus_array[uart_nr];
|
||||
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(uart->lock == NULL) {
|
||||
uart->lock = xSemaphoreCreateMutex();
|
||||
if(uart->lock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(queueLen && uart->queue == NULL) {
|
||||
uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
|
||||
if(uart->queue == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(uart_nr == 1){
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
} else if(uart_nr == 2){
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
|
||||
#endif
|
||||
} else {
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
|
||||
}
|
||||
uartFlush(uart);
|
||||
uartSetBaudRate(uart, baudrate);
|
||||
UART_MUTEX_LOCK();
|
||||
uart->dev->conf0.val = config;
|
||||
#define TWO_STOP_BITS_CONF 0x3
|
||||
#define ONE_STOP_BITS_CONF 0x1
|
||||
|
||||
if ( uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) {
|
||||
uart->dev->conf0.stop_bit_num = ONE_STOP_BITS_CONF;
|
||||
uart->dev->rs485_conf.dl1_en = 1;
|
||||
}
|
||||
|
||||
// tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate)
|
||||
// Setting it to 0 prevents line idle time/delays when sending messages with small intervals
|
||||
uart->dev->idle_conf.tx_idle_num = 0; //
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
if(rxPin != -1) {
|
||||
uartAttachRx(uart, rxPin, inverted);
|
||||
}
|
||||
|
||||
if(txPin != -1) {
|
||||
uartAttachTx(uart, txPin, inverted);
|
||||
}
|
||||
addApbChangeCallback(uart, uart_on_apb_change);
|
||||
return uart;
|
||||
}
|
||||
|
||||
void uartEnd(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
removeApbChangeCallback(uart, uart_on_apb_change);
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
if(uart->queue != NULL) {
|
||||
vQueueDelete(uart->queue);
|
||||
uart->queue = NULL;
|
||||
}
|
||||
|
||||
uart->dev->conf0.val = 0;
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
uartDetachRx(uart);
|
||||
uartDetachTx(uart);
|
||||
}
|
||||
|
||||
size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) {
|
||||
if(uart == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
if(uart->queue != NULL) {
|
||||
vQueueDelete(uart->queue);
|
||||
uart->queue = xQueueCreate(new_size, sizeof(uint8_t));
|
||||
if(uart->queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
return new_size;
|
||||
}
|
||||
|
||||
uint32_t uartAvailable(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || uart->queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ;
|
||||
}
|
||||
|
||||
uint32_t uartAvailableForWrite(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return 0x7f - uart->dev->status.txfifo_cnt;
|
||||
}
|
||||
|
||||
void uartRxFifoToQueue(uart_t* uart)
|
||||
{
|
||||
uint8_t c;
|
||||
UART_MUTEX_LOCK();
|
||||
//disable interrupts
|
||||
uart->dev->int_ena.val = 0;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
|
||||
c = uart->dev->fifo.rw_byte;
|
||||
#else
|
||||
uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num);
|
||||
while (uart->dev->status.rxfifo_cnt) {
|
||||
c = ESP_REG(fifo_reg);
|
||||
#endif
|
||||
xQueueSend(uart->queue, &c, 0);
|
||||
}
|
||||
//enable interrupts
|
||||
uart->dev->int_ena.rxfifo_full = 1;
|
||||
uart->dev->int_ena.frm_err = 1;
|
||||
uart->dev->int_ena.rxfifo_tout = 1;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
uint8_t uartRead(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || uart->queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t c;
|
||||
if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0))
|
||||
{
|
||||
uartRxFifoToQueue(uart);
|
||||
}
|
||||
if(xQueueReceive(uart->queue, &c, 0)) {
|
||||
return c;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t uartPeek(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || uart->queue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t c;
|
||||
if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0))
|
||||
{
|
||||
uartRxFifoToQueue(uart);
|
||||
}
|
||||
if(xQueuePeek(uart->queue, &c, 0)) {
|
||||
return c;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uartWrite(uart_t* uart, uint8_t c)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
while(uart->dev->status.txfifo_cnt == 0x7F);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uart->dev->fifo.rw_byte = c;
|
||||
#else
|
||||
ESP_REG(UART_FIFO_AHB_REG(uart->num)) = c;
|
||||
#endif
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num);
|
||||
#endif
|
||||
while(len) {
|
||||
while(uart->dev->status.txfifo_cnt == 0x7F);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uart->dev->fifo.rw_byte = *data++;
|
||||
#else
|
||||
ESP_REG(fifo_reg) = *data++;
|
||||
#endif
|
||||
len--;
|
||||
}
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartFlush(uart_t* uart)
|
||||
{
|
||||
uartFlushTxOnly(uart,false);
|
||||
}
|
||||
|
||||
void uartFlushTxOnly(uart_t* uart, bool txOnly)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
|
||||
|
||||
if( !txOnly ){
|
||||
//Due to hardware issue, we can not use fifo_rst to reset uart fifo.
|
||||
//See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <<esp32_technical_reference_manual>> v2.6 or later.
|
||||
|
||||
// we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`.
|
||||
while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
|
||||
READ_PERI_REG(UART_FIFO_REG(uart->num));
|
||||
}
|
||||
|
||||
xQueueReset(uart->queue);
|
||||
}
|
||||
#else
|
||||
while(uart->dev->status.txfifo_cnt);
|
||||
uart->dev->conf0.txfifo_rst = 1;
|
||||
uart->dev->conf0.txfifo_rst = 0;
|
||||
#endif
|
||||
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return;
|
||||
}
|
||||
UART_MUTEX_LOCK();
|
||||
uint32_t clk_div = ((getApbFrequency()<<4)/baud_rate);
|
||||
uart->dev->clk_div.div_int = clk_div>>4 ;
|
||||
uart->dev->clk_div.div_frag = clk_div & 0xf;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb)
|
||||
{
|
||||
uart_t* uart = (uart_t*)arg;
|
||||
if(ev_type == APB_BEFORE_CHANGE){
|
||||
UART_MUTEX_LOCK();
|
||||
//disabple interrupt
|
||||
uart->dev->int_ena.val = 0;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
// read RX fifo
|
||||
uint8_t c;
|
||||
// BaseType_t xHigherPriorityTaskWoken;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) {
|
||||
c = uart->dev->fifo.rw_byte;
|
||||
#else
|
||||
uint32_t fifo_reg = UART_FIFO_AHB_REG(uart->num);
|
||||
while(uart->dev->status.rxfifo_cnt != 0) {
|
||||
c = ESP_REG(fifo_reg);
|
||||
#endif
|
||||
if(uart->queue != NULL ) {
|
||||
xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
// wait TX empty
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
|
||||
#else
|
||||
while(uart->dev->status.txfifo_cnt);
|
||||
#endif
|
||||
} else {
|
||||
//todo:
|
||||
// set baudrate
|
||||
UART_MUTEX_LOCK();
|
||||
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
|
||||
uint32_t baud_rate = ((old_apb<<4)/clk_div);
|
||||
clk_div = ((new_apb<<4)/baud_rate);
|
||||
uart->dev->clk_div.div_int = clk_div>>4 ;
|
||||
uart->dev->clk_div.div_frag = clk_div & 0xf;
|
||||
//enable interrupts
|
||||
uart->dev->int_ena.rxfifo_full = 1;
|
||||
uart->dev->int_ena.frm_err = 1;
|
||||
uart->dev->int_ena.rxfifo_tout = 1;
|
||||
uart->dev->int_clr.val = 0xffffffff;
|
||||
UART_MUTEX_UNLOCK();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t uartGetBaudRate(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F);
|
||||
if(!clk_div) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((getApbFrequency()<<4)/clk_div);
|
||||
}
|
||||
|
||||
static void ARDUINO_ISR_ATTR uart0_write_char(char c)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||
ESP_REG(DR_REG_UART_BASE) = c;
|
||||
#else
|
||||
while(UART0.status.txfifo_cnt == 0x7F);
|
||||
WRITE_PERI_REG(UART_FIFO_AHB_REG(0), c);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ARDUINO_ISR_ATTR uart1_write_char(char c)
|
||||
{
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||
ESP_REG(DR_REG_UART1_BASE) = c;
|
||||
#else
|
||||
while(UART1.status.txfifo_cnt == 0x7F);
|
||||
WRITE_PERI_REG(UART_FIFO_AHB_REG(1), c);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static void ARDUINO_ISR_ATTR uart2_write_char(char c)
|
||||
{
|
||||
while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
|
||||
ESP_REG(DR_REG_UART2_BASE) = c;
|
||||
}
|
||||
#endif
|
||||
|
||||
void uart_install_putc()
|
||||
{
|
||||
switch(s_uart_debug_nr) {
|
||||
case 0:
|
||||
ets_install_putc1((void (*)(char)) &uart0_write_char);
|
||||
break;
|
||||
case 1:
|
||||
ets_install_putc1((void (*)(char)) &uart1_write_char);
|
||||
break;
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
case 2:
|
||||
ets_install_putc1((void (*)(char)) &uart2_write_char);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ets_install_putc1(NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void uartSetDebug(uart_t* uart)
|
||||
{
|
||||
if(uart == NULL || uart->num >= UART_PORTS_NUM) {
|
||||
s_uart_debug_nr = -1;
|
||||
//ets_install_putc1(NULL);
|
||||
//return;
|
||||
} else
|
||||
if(s_uart_debug_nr == uart->num) {
|
||||
return;
|
||||
} else
|
||||
s_uart_debug_nr = uart->num;
|
||||
uart_install_putc();
|
||||
}
|
||||
|
||||
int uartGetDebug()
|
||||
{
|
||||
return s_uart_debug_nr;
|
||||
}
|
||||
|
||||
int log_printf(const char *format, ...)
|
||||
{
|
||||
static char loc_buf[64];
|
||||
char * temp = loc_buf;
|
||||
int len;
|
||||
va_list arg;
|
||||
va_list copy;
|
||||
va_start(arg, format);
|
||||
va_copy(copy, arg);
|
||||
len = vsnprintf(NULL, 0, format, arg);
|
||||
va_end(copy);
|
||||
if(len >= sizeof(loc_buf)){
|
||||
temp = (char*)malloc(len+1);
|
||||
if(temp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
vsnprintf(temp, len+1, format, arg);
|
||||
#if !CONFIG_DISABLE_HAL_LOCKS
|
||||
if(s_uart_debug_nr != -1 && _uart_bus_array[s_uart_debug_nr].lock){
|
||||
xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY);
|
||||
ets_printf("%s", temp);
|
||||
xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock);
|
||||
} else {
|
||||
ets_printf("%s", temp);
|
||||
}
|
||||
#else
|
||||
ets_printf("%s", temp);
|
||||
#endif
|
||||
va_end(arg);
|
||||
if(len >= sizeof(loc_buf)){
|
||||
free(temp);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two.
|
||||
* This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses.
|
||||
*/
|
||||
unsigned long uartBaudrateDetect(uart_t *uart, bool flg)
|
||||
{
|
||||
while(uart->dev->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num)
|
||||
if(flg) return 0;
|
||||
ets_delay_us(1000);
|
||||
}
|
||||
|
||||
UART_MUTEX_LOCK();
|
||||
unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12;
|
||||
UART_MUTEX_UNLOCK();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* To start detection of baud rate with the uart the auto_baud.en bit needs to be cleared and set. The bit period is
|
||||
* detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is
|
||||
* rounded to the closed real baudrate.
|
||||
*/
|
||||
void uartStartDetectBaudrate(uart_t *uart) {
|
||||
if(!uart) return;
|
||||
|
||||
uart->dev->auto_baud.glitch_filt = 0x08;
|
||||
uart->dev->auto_baud.en = 0;
|
||||
uart->dev->auto_baud.en = 1;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
uartDetectBaudrate(uart_t *uart)
|
||||
{
|
||||
static bool uartStateDetectingBaudrate = false;
|
||||
|
||||
if(!uartStateDetectingBaudrate) {
|
||||
uart->dev->auto_baud.glitch_filt = 0x08;
|
||||
uart->dev->auto_baud.en = 0;
|
||||
uart->dev->auto_baud.en = 1;
|
||||
uartStateDetectingBaudrate = true;
|
||||
}
|
||||
|
||||
unsigned long divisor = uartBaudrateDetect(uart, true);
|
||||
if (!divisor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uart->dev->auto_baud.en = 0;
|
||||
uartStateDetectingBaudrate = false; // Initialize for the next round
|
||||
|
||||
unsigned long baudrate = getApbFrequency() / divisor;
|
||||
|
||||
static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400};
|
||||
|
||||
size_t i;
|
||||
for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++) // find the nearest real baudrate
|
||||
{
|
||||
if (baudrate <= default_rates[i])
|
||||
{
|
||||
if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) {
|
||||
i--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return default_rates[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the status of the RX state machine, if the value is non-zero the state machine is active.
|
||||
*/
|
||||
bool uartRxActive(uart_t* uart) {
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
return uart->dev->status.st_urx_out != 0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MAIN_ESP32_HAL_UART_H_
|
||||
#define MAIN_ESP32_HAL_UART_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SERIAL_5N1 0x8000010
|
||||
#define SERIAL_6N1 0x8000014
|
||||
#define SERIAL_7N1 0x8000018
|
||||
#define SERIAL_8N1 0x800001c
|
||||
#define SERIAL_5N2 0x8000030
|
||||
#define SERIAL_6N2 0x8000034
|
||||
#define SERIAL_7N2 0x8000038
|
||||
#define SERIAL_8N2 0x800003c
|
||||
#define SERIAL_5E1 0x8000012
|
||||
#define SERIAL_6E1 0x8000016
|
||||
#define SERIAL_7E1 0x800001a
|
||||
#define SERIAL_8E1 0x800001e
|
||||
#define SERIAL_5E2 0x8000032
|
||||
#define SERIAL_6E2 0x8000036
|
||||
#define SERIAL_7E2 0x800003a
|
||||
#define SERIAL_8E2 0x800003e
|
||||
#define SERIAL_5O1 0x8000013
|
||||
#define SERIAL_6O1 0x8000017
|
||||
#define SERIAL_7O1 0x800001b
|
||||
#define SERIAL_8O1 0x800001f
|
||||
#define SERIAL_5O2 0x8000033
|
||||
#define SERIAL_6O2 0x8000037
|
||||
#define SERIAL_7O2 0x800003b
|
||||
#define SERIAL_8O2 0x800003f
|
||||
|
||||
struct uart_struct_t;
|
||||
typedef struct uart_struct_t uart_t;
|
||||
|
||||
uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted);
|
||||
void uartEnd(uart_t* uart);
|
||||
|
||||
uint32_t uartAvailable(uart_t* uart);
|
||||
uint32_t uartAvailableForWrite(uart_t* uart);
|
||||
uint8_t uartRead(uart_t* uart);
|
||||
uint8_t uartPeek(uart_t* uart);
|
||||
|
||||
void uartWrite(uart_t* uart, uint8_t c);
|
||||
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len);
|
||||
|
||||
void uartFlush(uart_t* uart);
|
||||
void uartFlushTxOnly(uart_t* uart, bool txOnly );
|
||||
|
||||
void uartSetBaudRate(uart_t* uart, uint32_t baud_rate);
|
||||
uint32_t uartGetBaudRate(uart_t* uart);
|
||||
|
||||
size_t uartResizeRxBuffer(uart_t* uart, size_t new_size);
|
||||
|
||||
void uartSetDebug(uart_t* uart);
|
||||
int uartGetDebug();
|
||||
|
||||
void uartStartDetectBaudrate(uart_t *uart);
|
||||
unsigned long uartDetectBaudrate(uart_t *uart);
|
||||
|
||||
bool uartRxActive(uart_t* uart);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MAIN_ESP32_HAL_UART_H_ */
|
@ -20,29 +20,21 @@
|
||||
#ifndef HAL_ESP32_HAL_H_
|
||||
#define HAL_ESP32_HAL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_sleep.h"
|
||||
//#include <stdint.h>
|
||||
//#include <stdbool.h>
|
||||
//#include <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <stdarg.h>
|
||||
//#include <inttypes.h>
|
||||
//#include <string.h>
|
||||
//#include <math.h>
|
||||
//#include "sdkconfig.h"
|
||||
//#include "esp_system.h"
|
||||
//#include "esp_sleep.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef F_CPU
|
||||
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
|
||||
#define F_CPU (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000U)
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define F_CPU (CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ * 1000000U)
|
||||
#endif
|
||||
#endif
|
||||
//#ifdef __cplusplus
|
||||
//extern "C" {
|
||||
//#endif
|
||||
|
||||
#if CONFIG_ARDUINO_ISR_IRAM
|
||||
#define ARDUINO_ISR_ATTR IRAM_ATTR
|
||||
@ -52,84 +44,32 @@ extern "C" {
|
||||
#define ARDUINO_ISR_FLAG (0)
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO_RUNNING_CORE
|
||||
#define ARDUINO_RUNNING_CORE CONFIG_ARDUINO_RUNNING_CORE
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINO_EVENT_RUNNING_CORE
|
||||
#define ARDUINO_EVENT_RUNNING_CORE CONFIG_ARDUINO_EVENT_RUNNING_CORE
|
||||
#endif
|
||||
|
||||
//forward declaration from freertos/portmacro.h
|
||||
void vPortYield(void);
|
||||
void yield(void);
|
||||
#define optimistic_yield(u)
|
||||
////forward declaration from freertos/portmacro.h
|
||||
//void vPortYield(void);
|
||||
//#define optimistic_yield(u)
|
||||
|
||||
#define ESP_REG(addr) *((volatile uint32_t *)(addr))
|
||||
#define NOP() asm volatile ("nop")
|
||||
|
||||
#include "esp32-hal-log.h"
|
||||
#include "esp32-hal-matrix.h"
|
||||
#include "esp32-hal-uart.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "esp32-hal-touch.h"
|
||||
#include "esp32-hal-dac.h"
|
||||
#include "esp32-hal-adc.h"
|
||||
#include "esp32-hal-spi.h"
|
||||
#include "esp32-hal-i2c.h"
|
||||
#include "esp32-hal-ledc.h"
|
||||
#include "esp32-hal-rmt.h"
|
||||
#include "esp32-hal-sigmadelta.h"
|
||||
#include "esp32-hal-timer.h"
|
||||
#include "esp32-hal-bt.h"
|
||||
#include "esp32-hal-psram.h"
|
||||
#include "esp32-hal-cpu.h"
|
||||
////#include "esp32-hal-log.h"
|
||||
////#include "esp32-hal-matrix.h"
|
||||
////#include "esp32-hal-gpio.h"
|
||||
////#include "esp32-hal-touch.h"
|
||||
////#include "esp32-hal-dac.h"
|
||||
////#include "esp32-hal-adc.h"
|
||||
////#include "esp32-hal-spi.h"
|
||||
////#include "esp32-hal-i2c.h"
|
||||
////#include "esp32-hal-ledc.h"
|
||||
////#include "esp32-hal-rmt.h"
|
||||
////#include "esp32-hal-sigmadelta.h"
|
||||
////#include "esp32-hal-psram.h"
|
||||
////#include "esp32-hal-cpu.h"
|
||||
|
||||
//returns chip temperature in Celsius
|
||||
float temperatureRead();
|
||||
////returns chip temperature in Celsius
|
||||
//float temperatureRead();
|
||||
|
||||
#if CONFIG_AUTOSTART_ARDUINO
|
||||
//enable/disable WDT for Arduino's setup and loop functions
|
||||
void enableLoopWDT();
|
||||
void disableLoopWDT();
|
||||
//feed WDT for the loop task
|
||||
void feedLoopWDT();
|
||||
#endif
|
||||
|
||||
//enable/disable WDT for the IDLE task on Core 0 (SYSTEM)
|
||||
void enableCore0WDT();
|
||||
void disableCore0WDT();
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
//enable/disable WDT for the IDLE task on Core 1 (Arduino)
|
||||
void enableCore1WDT();
|
||||
void disableCore1WDT();
|
||||
#endif
|
||||
|
||||
//if xCoreID < 0 or CPU is unicore, it will use xTaskCreate, else xTaskCreatePinnedToCore
|
||||
//allows to easily handle all possible situations without repetitive code
|
||||
BaseType_t xTaskCreateUniversal( TaskFunction_t pxTaskCode,
|
||||
const char * const pcName,
|
||||
const uint32_t usStackDepth,
|
||||
void * const pvParameters,
|
||||
UBaseType_t uxPriority,
|
||||
TaskHandle_t * const pxCreatedTask,
|
||||
const BaseType_t xCoreID );
|
||||
|
||||
unsigned long micros();
|
||||
unsigned long millis();
|
||||
void delay(uint32_t);
|
||||
void delayMicroseconds(uint32_t us);
|
||||
|
||||
#if !CONFIG_ESP32_PHY_AUTO_INIT
|
||||
void arduino_phy_init();
|
||||
#endif
|
||||
|
||||
#if !CONFIG_AUTOSTART_ARDUINO
|
||||
void initArduino();
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
#endif /* HAL_ESP32_HAL_H_ */
|
||||
|
46
cores/esp32/esp_arduino_version.h
Normal file
46
cores/esp32/esp_arduino_version.h
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Major version number (X.x.x) */
|
||||
#define ESP_ARDUINO_VERSION_MAJOR 2
|
||||
/** Minor version number (x.X.x) */
|
||||
#define ESP_ARDUINO_VERSION_MINOR 0
|
||||
/** Patch version number (x.x.X) */
|
||||
#define ESP_ARDUINO_VERSION_PATCH 0
|
||||
|
||||
/**
|
||||
* Macro to convert ARDUINO version number into an integer
|
||||
*
|
||||
* To be used in comparisons, such as ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0)
|
||||
*/
|
||||
#define ESP_ARDUINO_VERSION_VAL(major, minor, patch) ((major << 16) | (minor << 8) | (patch))
|
||||
|
||||
/**
|
||||
* Current ARDUINO version, as an integer
|
||||
*
|
||||
* To be used in comparisons, such as ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0)
|
||||
*/
|
||||
#define ESP_ARDUINO_VERSION ESP_ARDUINO_VERSION_VAL(ESP_ARDUINO_VERSION_MAJOR, \
|
||||
ESP_ARDUINO_VERSION_MINOR, \
|
||||
ESP_ARDUINO_VERSION_PATCH)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,7 +0,0 @@
|
||||
libb64: Base64 Encoding/Decoding Routines
|
||||
======================================
|
||||
|
||||
Authors:
|
||||
-------
|
||||
|
||||
Chris Venter chris.venter@gmail.com http://rocketpod.blogspot.com
|
@ -1,29 +0,0 @@
|
||||
Copyright-Only Dedication (based on United States law)
|
||||
or Public Domain Certification
|
||||
|
||||
The person or persons who have associated work with this document (the
|
||||
"Dedicator" or "Certifier") hereby either (a) certifies that, to the best of
|
||||
his knowledge, the work of authorship identified is in the public domain of the
|
||||
country from which the work is published, or (b) hereby dedicates whatever
|
||||
copyright the dedicators holds in the work of authorship identified below (the
|
||||
"Work") to the public domain. A certifier, moreover, dedicates any copyright
|
||||
interest he may have in the associated work, and for these purposes, is
|
||||
described as a "dedicator" below.
|
||||
|
||||
A certifier has taken reasonable steps to verify the copyright status of this
|
||||
work. Certifier recognizes that his good faith efforts may not shield him from
|
||||
liability if in fact the work certified is not in the public domain.
|
||||
|
||||
Dedicator makes this dedication for the benefit of the public at large and to
|
||||
the detriment of the Dedicator's heirs and successors. Dedicator intends this
|
||||
dedication to be an overt act of relinquishment in perpetuity of all present
|
||||
and future rights under copyright law, whether vested or contingent, in the
|
||||
Work. Dedicator understands that such relinquishment of all rights includes
|
||||
the relinquishment of all rights to enforce (by lawsuit or otherwise) those
|
||||
copyrights in the Work.
|
||||
|
||||
Dedicator recognizes that, once placed in the public domain, the Work may be
|
||||
freely reproduced, distributed, transmitted, used, modified, built upon, or
|
||||
otherwise exploited by anyone for any purpose, commercial or non-commercial,
|
||||
and in any way, including by methods that have not yet been invented or
|
||||
conceived.
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
cdecoder.c - c source to a base64 decoding algorithm implementation
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#include "cdecode.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static int base64_decode_value_signed(int8_t value_in){
|
||||
static const int8_t decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
|
||||
static const int8_t decoding_size = sizeof(decoding);
|
||||
value_in -= 43;
|
||||
if (value_in < 0 || value_in > decoding_size) return -1;
|
||||
return decoding[(int)value_in];
|
||||
}
|
||||
|
||||
void base64_init_decodestate(base64_decodestate* state_in){
|
||||
state_in->step = step_a;
|
||||
state_in->plainchar = 0;
|
||||
}
|
||||
|
||||
static int base64_decode_block_signed(const int8_t* code_in, const int length_in, int8_t* plaintext_out, base64_decodestate* state_in){
|
||||
const int8_t* codechar = code_in;
|
||||
int8_t* plainchar = plaintext_out;
|
||||
int8_t fragment;
|
||||
|
||||
*plainchar = state_in->plainchar;
|
||||
|
||||
switch (state_in->step){
|
||||
while (1){
|
||||
case step_a:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
state_in->step = step_a;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (int8_t)base64_decode_value_signed(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar = (fragment & 0x03f) << 2;
|
||||
case step_b:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
state_in->step = step_b;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (int8_t)base64_decode_value_signed(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x030) >> 4;
|
||||
*plainchar = (fragment & 0x00f) << 4;
|
||||
case step_c:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
state_in->step = step_c;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (int8_t)base64_decode_value_signed(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x03c) >> 2;
|
||||
*plainchar = (fragment & 0x003) << 6;
|
||||
case step_d:
|
||||
do {
|
||||
if (codechar == code_in+length_in){
|
||||
state_in->step = step_d;
|
||||
state_in->plainchar = *plainchar;
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
fragment = (int8_t)base64_decode_value_signed(*codechar++);
|
||||
} while (fragment < 0);
|
||||
*plainchar++ |= (fragment & 0x03f);
|
||||
}
|
||||
}
|
||||
/* control should not reach here */
|
||||
return plainchar - plaintext_out;
|
||||
}
|
||||
|
||||
static int base64_decode_chars_signed(const int8_t* code_in, const int length_in, int8_t* plaintext_out){
|
||||
base64_decodestate _state;
|
||||
base64_init_decodestate(&_state);
|
||||
int len = base64_decode_block_signed(code_in, length_in, plaintext_out, &_state);
|
||||
if(len > 0) plaintext_out[len] = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int base64_decode_value(char value_in){
|
||||
return base64_decode_value_signed(*((int8_t *) &value_in));
|
||||
}
|
||||
|
||||
int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in){
|
||||
return base64_decode_block_signed((int8_t *) code_in, length_in, (int8_t *) plaintext_out, state_in);
|
||||
}
|
||||
|
||||
int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out){
|
||||
return base64_decode_chars_signed((int8_t *) code_in, length_in, (int8_t *) plaintext_out);
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
cdecode.h - c header for a base64 decoding algorithm
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#ifndef BASE64_CDECODE_H
|
||||
#define BASE64_CDECODE_H
|
||||
|
||||
#define base64_decode_expected_len(n) ((n * 3) / 4)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
step_a, step_b, step_c, step_d
|
||||
} base64_decodestep;
|
||||
|
||||
typedef struct {
|
||||
base64_decodestep step;
|
||||
char plainchar;
|
||||
} base64_decodestate;
|
||||
|
||||
void base64_init_decodestate(base64_decodestate* state_in);
|
||||
|
||||
int base64_decode_value(char value_in);
|
||||
|
||||
int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
|
||||
|
||||
int base64_decode_chars(const char* code_in, const int length_in, char* plaintext_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* BASE64_CDECODE_H */
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
cencoder.c - c source to a base64 encoding algorithm implementation
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#include "cencode.h"
|
||||
|
||||
void base64_init_encodestate(base64_encodestate* state_in)
|
||||
{
|
||||
state_in->step = step_A;
|
||||
state_in->result = 0;
|
||||
}
|
||||
|
||||
char base64_encode_value(char value_in)
|
||||
{
|
||||
static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
if (value_in > 63) {
|
||||
return '=';
|
||||
}
|
||||
return encoding[(int)value_in];
|
||||
}
|
||||
|
||||
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
const char* plainchar = plaintext_in;
|
||||
const char* const plaintextend = plaintext_in + length_in;
|
||||
char* codechar = code_out;
|
||||
char result;
|
||||
char fragment;
|
||||
|
||||
result = state_in->result;
|
||||
|
||||
switch (state_in->step) {
|
||||
while (1) {
|
||||
case step_A:
|
||||
if (plainchar == plaintextend) {
|
||||
state_in->result = result;
|
||||
state_in->step = step_A;
|
||||
return codechar - code_out;
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result = (fragment & 0x0fc) >> 2;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x003) << 4;
|
||||
case step_B:
|
||||
if (plainchar == plaintextend) {
|
||||
state_in->result = result;
|
||||
state_in->step = step_B;
|
||||
return codechar - code_out;
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result |= (fragment & 0x0f0) >> 4;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x00f) << 2;
|
||||
case step_C:
|
||||
if (plainchar == plaintextend) {
|
||||
state_in->result = result;
|
||||
state_in->step = step_C;
|
||||
return codechar - code_out;
|
||||
}
|
||||
fragment = *plainchar++;
|
||||
result |= (fragment & 0x0c0) >> 6;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
result = (fragment & 0x03f) >> 0;
|
||||
*codechar++ = base64_encode_value(result);
|
||||
}
|
||||
}
|
||||
/* control should not reach here */
|
||||
return codechar - code_out;
|
||||
}
|
||||
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||
{
|
||||
char* codechar = code_out;
|
||||
|
||||
switch (state_in->step) {
|
||||
case step_B:
|
||||
*codechar++ = base64_encode_value(state_in->result);
|
||||
*codechar++ = '=';
|
||||
*codechar++ = '=';
|
||||
break;
|
||||
case step_C:
|
||||
*codechar++ = base64_encode_value(state_in->result);
|
||||
*codechar++ = '=';
|
||||
break;
|
||||
case step_A:
|
||||
break;
|
||||
}
|
||||
*codechar = 0x00;
|
||||
|
||||
return codechar - code_out;
|
||||
}
|
||||
|
||||
int base64_encode_chars(const char* plaintext_in, int length_in, char* code_out)
|
||||
{
|
||||
base64_encodestate _state;
|
||||
base64_init_encodestate(&_state);
|
||||
int len = base64_encode_block(plaintext_in, length_in, code_out, &_state);
|
||||
return len + base64_encode_blockend((code_out + len), &_state);
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
cencode.h - c header for a base64 encoding algorithm
|
||||
|
||||
This is part of the libb64 project, and has been placed in the public domain.
|
||||
For details, see http://sourceforge.net/projects/libb64
|
||||
*/
|
||||
|
||||
#ifndef BASE64_CENCODE_H
|
||||
#define BASE64_CENCODE_H
|
||||
|
||||
#define base64_encode_expected_len(n) ((((4 * n) / 3) + 3) & ~3)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
step_A, step_B, step_C
|
||||
} base64_encodestep;
|
||||
|
||||
typedef struct {
|
||||
base64_encodestep step;
|
||||
char result;
|
||||
int stepcount;
|
||||
} base64_encodestate;
|
||||
|
||||
void base64_init_encodestate(base64_encodestate* state_in);
|
||||
|
||||
char base64_encode_value(char value_in);
|
||||
|
||||
int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
|
||||
|
||||
int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
|
||||
|
||||
int base64_encode_chars(const char* plaintext_in, int length_in, char* code_out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* BASE64_CENCODE_H */
|
@ -1,50 +0,0 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "Arduino.h"
|
||||
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
|
||||
#include "USB.h"
|
||||
#endif
|
||||
|
||||
TaskHandle_t loopTaskHandle = NULL;
|
||||
|
||||
#if CONFIG_AUTOSTART_ARDUINO
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
void yieldIfNecessary(void){
|
||||
static uint64_t lastYield = 0;
|
||||
uint64_t now = millis();
|
||||
if((now - lastYield) > 2000) {
|
||||
lastYield = now;
|
||||
vTaskDelay(5); //delay 1 RTOS tick
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool loopTaskWDTEnabled;
|
||||
|
||||
void loopTask(void *pvParameters)
|
||||
{
|
||||
setup();
|
||||
for(;;) {
|
||||
#if CONFIG_FREERTOS_UNICORE
|
||||
yieldIfNecessary();
|
||||
#endif
|
||||
if(loopTaskWDTEnabled){
|
||||
esp_task_wdt_reset();
|
||||
}
|
||||
loop();
|
||||
if (serialEventRun) serialEventRun();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
|
||||
USB.begin();
|
||||
#endif
|
||||
loopTaskWDTEnabled = false;
|
||||
initArduino();
|
||||
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
|
||||
}
|
||||
|
||||
#endif
|
@ -53,6 +53,8 @@ typedef unsigned long prog_uint32_t;
|
||||
*(void * const *)(_addr); \
|
||||
})
|
||||
|
||||
#define pgm_get_far_address(x) ((uint32_t)(&(x)))
|
||||
|
||||
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
||||
#define pgm_read_word_near(addr) pgm_read_word(addr)
|
||||
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -29,22 +29,22 @@ extern uint32_t xthal_get_ccount();
|
||||
}
|
||||
|
||||
// max timeout is 27 seconds at 160MHz clock and 54 seconds at 80MHz clock
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
{
|
||||
const uint32_t max_timeout_us = clockCyclesToMicroseconds(UINT_MAX);
|
||||
if (timeout > max_timeout_us) {
|
||||
timeout = max_timeout_us;
|
||||
}
|
||||
const uint32_t timeout_cycles = microsecondsToClockCycles(timeout);
|
||||
const uint32_t start_cycle_count = xthal_get_ccount();
|
||||
WAIT_FOR_PIN_STATE(!state);
|
||||
WAIT_FOR_PIN_STATE(state);
|
||||
const uint32_t pulse_start_cycle_count = xthal_get_ccount();
|
||||
WAIT_FOR_PIN_STATE(!state);
|
||||
return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
|
||||
}
|
||||
//unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
//{
|
||||
// const uint32_t max_timeout_us = clockCyclesToMicroseconds(UINT_MAX);
|
||||
// if (timeout > max_timeout_us) {
|
||||
// timeout = max_timeout_us;
|
||||
// }
|
||||
// const uint32_t timeout_cycles = microsecondsToClockCycles(timeout);
|
||||
// const uint32_t start_cycle_count = xthal_get_ccount();
|
||||
// WAIT_FOR_PIN_STATE(!state);
|
||||
// WAIT_FOR_PIN_STATE(state);
|
||||
// const uint32_t pulse_start_cycle_count = xthal_get_ccount();
|
||||
// WAIT_FOR_PIN_STATE(!state);
|
||||
// return clockCyclesToMicroseconds(xthal_get_ccount() - pulse_start_cycle_count);
|
||||
//}
|
||||
|
||||
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
{
|
||||
return pulseIn(pin, state, timeout);
|
||||
}
|
||||
//unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
//{
|
||||
// return pulseIn(pin, state, timeout);
|
||||
//}
|
||||
|
@ -16,9 +16,11 @@
|
||||
Boston, MA 02111-1307 USA
|
||||
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
|
||||
*/
|
||||
|
||||
|
||||
#include "wiring_shift.h"
|
||||
#include "esp32-hal.h"
|
||||
#include "wiring_private.h"
|
||||
#include "esp32-hal-gpio.h"
|
||||
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
|
||||
uint8_t value = 0;
|
||||
|
9
cores/esp32/wiring_shift.h
Normal file
9
cores/esp32/wiring_shift.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#define LSBFIRST 0
|
||||
#define MSBFIRST 1
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
|
||||
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
|
@ -1,26 +1,28 @@
|
||||
Make your question, not a Statement, inclusive. Include all pertinent information:
|
||||
|
||||
What you are trying to do.
|
||||
Describe your system( Hardware, computer, O/S, core version, environment)
|
||||
Describe what is failing
|
||||
Show the shortest possible code that will duplicate the error
|
||||
Show the EXACT error message(it doesn't work is not enough)
|
||||
What you are trying to do
|
||||
Describe your system (Hardware, computer, O/S, core version, environment)
|
||||
Describe what is failing
|
||||
Show the shortest possible code that will duplicate the error
|
||||
Show the EXACT error message (it doesn't work is not enough)
|
||||
Then if someone is interested and knowledgeable you might get a answer. All of this work on your part shows us that you have worked to solve YOUR problem. The more complete your issue posting is, the more likely someone will volunteer their time to help you.
|
||||
|
||||
If you have a Guru Meditation Error or Backtrace, ***please decode it***:
|
||||
https://github.com/me-no-dev/EspExceptionDecoder
|
||||
[ExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecoder)
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
### Hardware:
|
||||
Board: ?ESP32 Dev Module? ?node32? ?ttgo_lora?
|
||||
Core Installation/update date: ?11/jul/2017?
|
||||
IDE name: ?Arduino IDE? ?Platform.io? ?IDF component?
|
||||
Flash Frequency: ?40Mhz?
|
||||
PSRAM enabled: ?no?
|
||||
Upload Speed: ?115200?
|
||||
Computer OS: ?Windows 10? ?Mac OSX? ?Ubuntu?
|
||||
|||||||
|
||||
|:---|---|---|---|---|---|
|
||||
|<B>Board</B>|ESP32 Dev Module|node32|ttgo_lora|ESP32-S2-Saola|Custom w/ ESP32-S2-WROVER 16MB|
|
||||
|<B>Version/Date</B>|1.0.4|2.0.0|0badbeef|11/jul/2017|today's master|
|
||||
|<B>IDE name</B>|Arduino IDE|Atom + Platform.io|IDF component|VSCode|
|
||||
|<B>Flash Frequency</B>|40Mhz|80Mhz|
|
||||
|<B>PSRAM enabled</B>|yes|no|
|
||||
|<B>Upload Speed</B>|115200|
|
||||
|<B>Computer OS</B>|Windows 10|Mac OSX|Ubuntu|
|
||||
|
||||
### Description:
|
||||
Describe your problem here
|
||||
|
@ -4,7 +4,7 @@
|
||||
- Stable release link: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json`
|
||||
- Development release link: `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json`
|
||||
|
||||
Starting with 1.6.4, Arduino allows installation of third-party platform packages using Boards Manager. We have packages available for Windows, Mac OS, and Linux (32, 64 bit and ARM).
|
||||
Starting with 1.6.4, Arduino allows installation of third-party platform packages using Boards Manager. We have packages available for Windows, Mac OS, and Linux (x86, amd64, armhf and arm64).
|
||||
|
||||
- Install the current upstream Arduino IDE at the 1.8 level or later. The current version is at the [Arduino website](http://www.arduino.cc/en/main/software).
|
||||
- Start Arduino and open Preferences window.
|
||||
|
@ -7,9 +7,9 @@ Installation instructions for Mac OS
|
||||
```bash
|
||||
mkdir -p ~/Documents/Arduino/hardware/espressif && \
|
||||
cd ~/Documents/Arduino/hardware/espressif && \
|
||||
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
|
||||
git clone https://github.com/espressif/arduino-esp32.git esp32 --depth 1 && \
|
||||
cd esp32 && \
|
||||
git submodule update --init --recursive && \
|
||||
git submodule update --init --recursive --depth 1 && \
|
||||
cd tools && \
|
||||
python get.py
|
||||
```
|
||||
|
@ -72,6 +72,11 @@ If you are writing code that does not require Arduino to compile and you want yo
|
||||
#endif
|
||||
```
|
||||
|
||||
## FreeRTOS Tick Rate (Hz)
|
||||
|
||||
You might notice that Arduino-esp32's `delay()` function will only work in multiples of 10ms. That is because, by default, esp-idf handles task events 100 times per second.
|
||||
To fix that behavior you need to set FreeRTOS tick rate to 1000Hz in `make menuconfig` -> `Component config` -> `FreeRTOS` -> `Tick rate`.
|
||||
|
||||
## Compilation Errors
|
||||
|
||||
As commits are made to esp-idf and submodules, the codebases can develop incompatibilities which cause compilation errors. If you have problems compiling, follow the instructions in [Issue #1142](https://github.com/espressif/arduino-esp32/issues/1142) to roll esp-idf back to a known good version.
|
||||
|
@ -1,68 +0,0 @@
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
const char* ssid = "..........";
|
||||
const char* password = "..........";
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println("Booting");
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("Connection Failed! Rebooting...");
|
||||
delay(5000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
// Port defaults to 3232
|
||||
// ArduinoOTA.setPort(3232);
|
||||
|
||||
// Hostname defaults to esp3232-[MAC]
|
||||
// ArduinoOTA.setHostname("myesp32");
|
||||
|
||||
// No authentication by default
|
||||
// ArduinoOTA.setPassword("admin");
|
||||
|
||||
// Password can be set with it's md5 value as well
|
||||
// MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
|
||||
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
|
||||
|
||||
ArduinoOTA
|
||||
.onStart([]() {
|
||||
String type;
|
||||
if (ArduinoOTA.getCommand() == U_FLASH)
|
||||
type = "sketch";
|
||||
else // U_SPIFFS
|
||||
type = "filesystem";
|
||||
|
||||
// NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
|
||||
Serial.println("Start updating " + type);
|
||||
})
|
||||
.onEnd([]() {
|
||||
Serial.println("\nEnd");
|
||||
})
|
||||
.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||||
})
|
||||
.onError([](ota_error_t error) {
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
|
||||
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
|
||||
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
|
||||
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
|
||||
else if (error == OTA_END_ERROR) Serial.println("End Failed");
|
||||
});
|
||||
|
||||
ArduinoOTA.begin();
|
||||
|
||||
Serial.println("Ready");
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ArduinoOTA.handle();
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <WebServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <Update.h>
|
||||
|
||||
const char* host = "esp32";
|
||||
const char* ssid = "xxx";
|
||||
const char* password = "xxxx";
|
||||
|
||||
WebServer server(80);
|
||||
|
||||
/*
|
||||
* Login page
|
||||
*/
|
||||
|
||||
const char* loginIndex =
|
||||
"<form name='loginForm'>"
|
||||
"<table width='20%' bgcolor='A09F9F' align='center'>"
|
||||
"<tr>"
|
||||
"<td colspan=2>"
|
||||
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
|
||||
"<br>"
|
||||
"</td>"
|
||||
"<br>"
|
||||
"<br>"
|
||||
"</tr>"
|
||||
"<td>Username:</td>"
|
||||
"<td><input type='text' size=25 name='userid'><br></td>"
|
||||
"</tr>"
|
||||
"<br>"
|
||||
"<br>"
|
||||
"<tr>"
|
||||
"<td>Password:</td>"
|
||||
"<td><input type='Password' size=25 name='pwd'><br></td>"
|
||||
"<br>"
|
||||
"<br>"
|
||||
"</tr>"
|
||||
"<tr>"
|
||||
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
|
||||
"</tr>"
|
||||
"</table>"
|
||||
"</form>"
|
||||
"<script>"
|
||||
"function check(form)"
|
||||
"{"
|
||||
"if(form.userid.value=='admin' && form.pwd.value=='admin')"
|
||||
"{"
|
||||
"window.open('/serverIndex')"
|
||||
"}"
|
||||
"else"
|
||||
"{"
|
||||
" alert('Error Password or Username')/*displays error message*/"
|
||||
"}"
|
||||
"}"
|
||||
"</script>";
|
||||
|
||||
/*
|
||||
* Server Index Page
|
||||
*/
|
||||
|
||||
const char* serverIndex =
|
||||
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
|
||||
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
|
||||
"<input type='file' name='update'>"
|
||||
"<input type='submit' value='Update'>"
|
||||
"</form>"
|
||||
"<div id='prg'>progress: 0%</div>"
|
||||
"<script>"
|
||||
"$('form').submit(function(e){"
|
||||
"e.preventDefault();"
|
||||
"var form = $('#upload_form')[0];"
|
||||
"var data = new FormData(form);"
|
||||
" $.ajax({"
|
||||
"url: '/update',"
|
||||
"type: 'POST',"
|
||||
"data: data,"
|
||||
"contentType: false,"
|
||||
"processData:false,"
|
||||
"xhr: function() {"
|
||||
"var xhr = new window.XMLHttpRequest();"
|
||||
"xhr.upload.addEventListener('progress', function(evt) {"
|
||||
"if (evt.lengthComputable) {"
|
||||
"var per = evt.loaded / evt.total;"
|
||||
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
|
||||
"}"
|
||||
"}, false);"
|
||||
"return xhr;"
|
||||
"},"
|
||||
"success:function(d, s) {"
|
||||
"console.log('success!')"
|
||||
"},"
|
||||
"error: function (a, b, c) {"
|
||||
"}"
|
||||
"});"
|
||||
"});"
|
||||
"</script>";
|
||||
|
||||
/*
|
||||
* setup function
|
||||
*/
|
||||
void setup(void) {
|
||||
Serial.begin(115200);
|
||||
|
||||
// Connect to WiFi network
|
||||
WiFi.begin(ssid, password);
|
||||
Serial.println("");
|
||||
|
||||
// Wait for connection
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
delay(500);
|
||||
Serial.print(".");
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print("Connected to ");
|
||||
Serial.println(ssid);
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
|
||||
/*use mdns for host name resolution*/
|
||||
if (!MDNS.begin(host)) { //http://esp32.local
|
||||
Serial.println("Error setting up MDNS responder!");
|
||||
while (1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
Serial.println("mDNS responder started");
|
||||
/*return index page which is stored in serverIndex */
|
||||
server.on("/", HTTP_GET, []() {
|
||||
server.sendHeader("Connection", "close");
|
||||
server.send(200, "text/html", loginIndex);
|
||||
});
|
||||
server.on("/serverIndex", HTTP_GET, []() {
|
||||
server.sendHeader("Connection", "close");
|
||||
server.send(200, "text/html", serverIndex);
|
||||
});
|
||||
/*handling uploading firmware file */
|
||||
server.on("/update", HTTP_POST, []() {
|
||||
server.sendHeader("Connection", "close");
|
||||
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
||||
ESP.restart();
|
||||
}, []() {
|
||||
HTTPUpload& upload = server.upload();
|
||||
if (upload.status == UPLOAD_FILE_START) {
|
||||
Serial.printf("Update: %s\n", upload.filename.c_str());
|
||||
if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size
|
||||
Update.printError(Serial);
|
||||
}
|
||||
} else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||
/* flashing firmware to ESP*/
|
||||
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
} else if (upload.status == UPLOAD_FILE_END) {
|
||||
if (Update.end(true)) { //true to set the size to the current progress
|
||||
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
|
||||
} else {
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
});
|
||||
server.begin();
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
server.handleClient();
|
||||
delay(1);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Ultrasound
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
ArduinoOTA KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
begin KEYWORD2
|
||||
setup KEYWORD2
|
||||
handle KEYWORD2
|
||||
onStart KEYWORD2
|
||||
onEnd KEYWORD2
|
||||
onError KEYWORD2
|
||||
onProgress KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
@ -1,9 +0,0 @@
|
||||
name=ArduinoOTA
|
||||
version=1.0
|
||||
author=Ivan Grokhotkov and Hristo Gochkov
|
||||
maintainer=Hristo Gochkov <hristo@espressif.com>
|
||||
sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download.
|
||||
paragraph=With this library you can enable your sketch to be upgraded over network. Includes mdns anounces to get discovered by the arduino IDE.
|
||||
category=Communication
|
||||
url=
|
||||
architectures=esp32
|
@ -1,383 +0,0 @@
|
||||
#ifndef LWIP_OPEN_SRC
|
||||
#define LWIP_OPEN_SRC
|
||||
#endif
|
||||
#include <functional>
|
||||
#include <WiFiUdp.h>
|
||||
#include "ArduinoOTA.h"
|
||||
#include "ESPmDNS.h"
|
||||
#include "MD5Builder.h"
|
||||
#include "Update.h"
|
||||
|
||||
|
||||
// #define OTA_DEBUG Serial
|
||||
|
||||
ArduinoOTAClass::ArduinoOTAClass()
|
||||
: _port(0)
|
||||
, _initialized(false)
|
||||
, _rebootOnSuccess(true)
|
||||
, _mdnsEnabled(true)
|
||||
, _state(OTA_IDLE)
|
||||
, _size(0)
|
||||
, _cmd(0)
|
||||
, _ota_port(0)
|
||||
, _ota_timeout(1000)
|
||||
, _start_callback(NULL)
|
||||
, _end_callback(NULL)
|
||||
, _error_callback(NULL)
|
||||
, _progress_callback(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
ArduinoOTAClass::~ArduinoOTAClass(){
|
||||
_udp_ota.stop();
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::onStart(THandlerFunction fn) {
|
||||
_start_callback = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::onEnd(THandlerFunction fn) {
|
||||
_end_callback = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::onProgress(THandlerFunction_Progress fn) {
|
||||
_progress_callback = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::onError(THandlerFunction_Error fn) {
|
||||
_error_callback = fn;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::setPort(uint16_t port) {
|
||||
if (!_initialized && !_port && port) {
|
||||
_port = port;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::setHostname(const char * hostname) {
|
||||
if (!_initialized && !_hostname.length() && hostname) {
|
||||
_hostname = hostname;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String ArduinoOTAClass::getHostname() {
|
||||
return _hostname;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::setPassword(const char * password) {
|
||||
if (!_initialized && !_password.length() && password) {
|
||||
MD5Builder passmd5;
|
||||
passmd5.begin();
|
||||
passmd5.add(password);
|
||||
passmd5.calculate();
|
||||
_password = passmd5.toString();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::setPasswordHash(const char * password) {
|
||||
if (!_initialized && !_password.length() && password) {
|
||||
_password = password;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::setRebootOnSuccess(bool reboot){
|
||||
_rebootOnSuccess = reboot;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArduinoOTAClass& ArduinoOTAClass::setMdnsEnabled(bool enabled){
|
||||
_mdnsEnabled = enabled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ArduinoOTAClass::begin() {
|
||||
if (_initialized){
|
||||
log_w("already initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_port) {
|
||||
_port = 3232;
|
||||
}
|
||||
|
||||
if(!_udp_ota.begin(_port)){
|
||||
log_e("udp bind failed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!_hostname.length()) {
|
||||
char tmp[20];
|
||||
uint8_t mac[6];
|
||||
WiFi.macAddress(mac);
|
||||
sprintf(tmp, "esp32-%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
_hostname = tmp;
|
||||
}
|
||||
if(_mdnsEnabled){
|
||||
MDNS.begin(_hostname.c_str());
|
||||
MDNS.enableArduino(_port, (_password.length() > 0));
|
||||
}
|
||||
_initialized = true;
|
||||
_state = OTA_IDLE;
|
||||
log_i("OTA server at: %s.local:%u", _hostname.c_str(), _port);
|
||||
}
|
||||
|
||||
int ArduinoOTAClass::parseInt(){
|
||||
char data[INT_BUFFER_SIZE];
|
||||
uint8_t index = 0;
|
||||
char value;
|
||||
while(_udp_ota.peek() == ' ') _udp_ota.read();
|
||||
while(index < INT_BUFFER_SIZE - 1){
|
||||
value = _udp_ota.peek();
|
||||
if(value < '0' || value > '9'){
|
||||
data[index++] = '\0';
|
||||
return atoi(data);
|
||||
}
|
||||
data[index++] = _udp_ota.read();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
String ArduinoOTAClass::readStringUntil(char end){
|
||||
String res = "";
|
||||
int value;
|
||||
while(true){
|
||||
value = _udp_ota.read();
|
||||
if(value <= 0 || value == end){
|
||||
return res;
|
||||
}
|
||||
res += (char)value;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void ArduinoOTAClass::_onRx(){
|
||||
if (_state == OTA_IDLE) {
|
||||
int cmd = parseInt();
|
||||
if (cmd != U_FLASH && cmd != U_SPIFFS)
|
||||
return;
|
||||
_cmd = cmd;
|
||||
_ota_port = parseInt();
|
||||
_size = parseInt();
|
||||
_udp_ota.read();
|
||||
_md5 = readStringUntil('\n');
|
||||
_md5.trim();
|
||||
if(_md5.length() != 32){
|
||||
log_e("bad md5 length");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_password.length()){
|
||||
MD5Builder nonce_md5;
|
||||
nonce_md5.begin();
|
||||
nonce_md5.add(String(micros()));
|
||||
nonce_md5.calculate();
|
||||
_nonce = nonce_md5.toString();
|
||||
|
||||
_udp_ota.beginPacket(_udp_ota.remoteIP(), _udp_ota.remotePort());
|
||||
_udp_ota.printf("AUTH %s", _nonce.c_str());
|
||||
_udp_ota.endPacket();
|
||||
_state = OTA_WAITAUTH;
|
||||
return;
|
||||
} else {
|
||||
_udp_ota.beginPacket(_udp_ota.remoteIP(), _udp_ota.remotePort());
|
||||
_udp_ota.print("OK");
|
||||
_udp_ota.endPacket();
|
||||
_ota_ip = _udp_ota.remoteIP();
|
||||
_state = OTA_RUNUPDATE;
|
||||
}
|
||||
} else if (_state == OTA_WAITAUTH) {
|
||||
int cmd = parseInt();
|
||||
if (cmd != U_AUTH) {
|
||||
log_e("%d was expected. got %d instead", U_AUTH, cmd);
|
||||
_state = OTA_IDLE;
|
||||
return;
|
||||
}
|
||||
_udp_ota.read();
|
||||
String cnonce = readStringUntil(' ');
|
||||
String response = readStringUntil('\n');
|
||||
if (cnonce.length() != 32 || response.length() != 32) {
|
||||
log_e("auth param fail");
|
||||
_state = OTA_IDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
String challenge = _password + ":" + String(_nonce) + ":" + cnonce;
|
||||
MD5Builder _challengemd5;
|
||||
_challengemd5.begin();
|
||||
_challengemd5.add(challenge);
|
||||
_challengemd5.calculate();
|
||||
String result = _challengemd5.toString();
|
||||
|
||||
if(result.equals(response)){
|
||||
_udp_ota.beginPacket(_udp_ota.remoteIP(), _udp_ota.remotePort());
|
||||
_udp_ota.print("OK");
|
||||
_udp_ota.endPacket();
|
||||
_ota_ip = _udp_ota.remoteIP();
|
||||
_state = OTA_RUNUPDATE;
|
||||
} else {
|
||||
_udp_ota.beginPacket(_udp_ota.remoteIP(), _udp_ota.remotePort());
|
||||
_udp_ota.print("Authentication Failed");
|
||||
log_w("Authentication Failed");
|
||||
_udp_ota.endPacket();
|
||||
if (_error_callback) _error_callback(OTA_AUTH_ERROR);
|
||||
_state = OTA_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArduinoOTAClass::_runUpdate() {
|
||||
if (!Update.begin(_size, _cmd)) {
|
||||
|
||||
log_e("Begin ERROR: %s", Update.errorString());
|
||||
|
||||
if (_error_callback) {
|
||||
_error_callback(OTA_BEGIN_ERROR);
|
||||
}
|
||||
_state = OTA_IDLE;
|
||||
return;
|
||||
}
|
||||
Update.setMD5(_md5.c_str());
|
||||
|
||||
if (_start_callback) {
|
||||
_start_callback();
|
||||
}
|
||||
if (_progress_callback) {
|
||||
_progress_callback(0, _size);
|
||||
}
|
||||
|
||||
WiFiClient client;
|
||||
if (!client.connect(_ota_ip, _ota_port)) {
|
||||
if (_error_callback) {
|
||||
_error_callback(OTA_CONNECT_ERROR);
|
||||
}
|
||||
_state = OTA_IDLE;
|
||||
}
|
||||
|
||||
uint32_t written = 0, total = 0, tried = 0;
|
||||
|
||||
while (!Update.isFinished() && client.connected()) {
|
||||
size_t waited = _ota_timeout;
|
||||
size_t available = client.available();
|
||||
while (!available && waited){
|
||||
delay(1);
|
||||
waited -=1 ;
|
||||
available = client.available();
|
||||
}
|
||||
if (!waited){
|
||||
if(written && tried++ < 3){
|
||||
log_i("Try[%u]: %u", tried, written);
|
||||
if(!client.printf("%u", written)){
|
||||
log_e("failed to respond");
|
||||
_state = OTA_IDLE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
log_e("Receive Failed");
|
||||
if (_error_callback) {
|
||||
_error_callback(OTA_RECEIVE_ERROR);
|
||||
}
|
||||
_state = OTA_IDLE;
|
||||
Update.abort();
|
||||
return;
|
||||
}
|
||||
if(!available){
|
||||
log_e("No Data: %u", waited);
|
||||
_state = OTA_IDLE;
|
||||
break;
|
||||
}
|
||||
tried = 0;
|
||||
static uint8_t buf[1460];
|
||||
if(available > 1460){
|
||||
available = 1460;
|
||||
}
|
||||
size_t r = client.read(buf, available);
|
||||
if(r != available){
|
||||
log_w("didn't read enough! %u != %u", r, available);
|
||||
}
|
||||
|
||||
written = Update.write(buf, r);
|
||||
if (written > 0) {
|
||||
if(written != r){
|
||||
log_w("didn't write enough! %u != %u", written, r);
|
||||
}
|
||||
if(!client.printf("%u", written)){
|
||||
log_w("failed to respond");
|
||||
}
|
||||
total += written;
|
||||
if(_progress_callback) {
|
||||
_progress_callback(total, _size);
|
||||
}
|
||||
} else {
|
||||
log_e("Write ERROR: %s", Update.errorString());
|
||||
}
|
||||
}
|
||||
|
||||
if (Update.end()) {
|
||||
client.print("OK");
|
||||
client.stop();
|
||||
delay(10);
|
||||
if (_end_callback) {
|
||||
_end_callback();
|
||||
}
|
||||
if(_rebootOnSuccess){
|
||||
//let serial/network finish tasks that might be given in _end_callback
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
}
|
||||
} else {
|
||||
if (_error_callback) {
|
||||
_error_callback(OTA_END_ERROR);
|
||||
}
|
||||
Update.printError(client);
|
||||
client.stop();
|
||||
delay(10);
|
||||
log_e("Update ERROR: %s", Update.errorString());
|
||||
_state = OTA_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void ArduinoOTAClass::end() {
|
||||
_initialized = false;
|
||||
_udp_ota.stop();
|
||||
if(_mdnsEnabled){
|
||||
MDNS.end();
|
||||
}
|
||||
_state = OTA_IDLE;
|
||||
log_i("OTA server stopped.");
|
||||
}
|
||||
|
||||
void ArduinoOTAClass::handle() {
|
||||
if (!_initialized) {
|
||||
return;
|
||||
}
|
||||
if (_state == OTA_RUNUPDATE) {
|
||||
_runUpdate();
|
||||
_state = OTA_IDLE;
|
||||
}
|
||||
if(_udp_ota.parsePacket()){
|
||||
_onRx();
|
||||
}
|
||||
_udp_ota.flush(); // always flush, even zero length packets must be flushed.
|
||||
}
|
||||
|
||||
int ArduinoOTAClass::getCommand() {
|
||||
return _cmd;
|
||||
}
|
||||
|
||||
void ArduinoOTAClass::setTimeout(int timeoutInMillis) {
|
||||
_ota_timeout = timeoutInMillis;
|
||||
}
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA)
|
||||
ArduinoOTAClass ArduinoOTA;
|
||||
#endif
|
@ -1,111 +0,0 @@
|
||||
#ifndef __ARDUINO_OTA_H
|
||||
#define __ARDUINO_OTA_H
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <functional>
|
||||
#include "Update.h"
|
||||
|
||||
#define INT_BUFFER_SIZE 16
|
||||
|
||||
typedef enum {
|
||||
OTA_IDLE,
|
||||
OTA_WAITAUTH,
|
||||
OTA_RUNUPDATE
|
||||
} ota_state_t;
|
||||
|
||||
typedef enum {
|
||||
OTA_AUTH_ERROR,
|
||||
OTA_BEGIN_ERROR,
|
||||
OTA_CONNECT_ERROR,
|
||||
OTA_RECEIVE_ERROR,
|
||||
OTA_END_ERROR
|
||||
} ota_error_t;
|
||||
|
||||
class ArduinoOTAClass
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(void)> THandlerFunction;
|
||||
typedef std::function<void(ota_error_t)> THandlerFunction_Error;
|
||||
typedef std::function<void(unsigned int, unsigned int)> THandlerFunction_Progress;
|
||||
|
||||
ArduinoOTAClass();
|
||||
~ArduinoOTAClass();
|
||||
|
||||
//Sets the service port. Default 3232
|
||||
ArduinoOTAClass& setPort(uint16_t port);
|
||||
|
||||
//Sets the device hostname. Default esp32-xxxxxx
|
||||
ArduinoOTAClass& setHostname(const char *hostname);
|
||||
String getHostname();
|
||||
|
||||
//Sets the password that will be required for OTA. Default NULL
|
||||
ArduinoOTAClass& setPassword(const char *password);
|
||||
|
||||
//Sets the password as above but in the form MD5(password). Default NULL
|
||||
ArduinoOTAClass& setPasswordHash(const char *password);
|
||||
|
||||
//Sets if the device should be rebooted after successful update. Default true
|
||||
ArduinoOTAClass& setRebootOnSuccess(bool reboot);
|
||||
|
||||
//Sets if the device should advertise itself to Arduino IDE. Default true
|
||||
ArduinoOTAClass& setMdnsEnabled(bool enabled);
|
||||
|
||||
//This callback will be called when OTA connection has begun
|
||||
ArduinoOTAClass& onStart(THandlerFunction fn);
|
||||
|
||||
//This callback will be called when OTA has finished
|
||||
ArduinoOTAClass& onEnd(THandlerFunction fn);
|
||||
|
||||
//This callback will be called when OTA encountered Error
|
||||
ArduinoOTAClass& onError(THandlerFunction_Error fn);
|
||||
|
||||
//This callback will be called when OTA is receiving data
|
||||
ArduinoOTAClass& onProgress(THandlerFunction_Progress fn);
|
||||
|
||||
//Starts the ArduinoOTA service
|
||||
void begin();
|
||||
|
||||
//Ends the ArduinoOTA service
|
||||
void end();
|
||||
|
||||
//Call this in loop() to run the service
|
||||
void handle();
|
||||
|
||||
//Gets update command type after OTA has started. Either U_FLASH or U_SPIFFS
|
||||
int getCommand();
|
||||
|
||||
void setTimeout(int timeoutInMillis);
|
||||
|
||||
private:
|
||||
int _port;
|
||||
String _password;
|
||||
String _hostname;
|
||||
String _nonce;
|
||||
WiFiUDP _udp_ota;
|
||||
bool _initialized;
|
||||
bool _rebootOnSuccess;
|
||||
bool _mdnsEnabled;
|
||||
ota_state_t _state;
|
||||
int _size;
|
||||
int _cmd;
|
||||
int _ota_port;
|
||||
int _ota_timeout;
|
||||
IPAddress _ota_ip;
|
||||
String _md5;
|
||||
|
||||
THandlerFunction _start_callback;
|
||||
THandlerFunction _end_callback;
|
||||
THandlerFunction_Error _error_callback;
|
||||
THandlerFunction_Progress _progress_callback;
|
||||
|
||||
void _runUpdate(void);
|
||||
void _onRx(void);
|
||||
int parseInt(void);
|
||||
String readStringUntil(char end);
|
||||
};
|
||||
|
||||
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA)
|
||||
extern ArduinoOTAClass ArduinoOTA;
|
||||
#endif
|
||||
|
||||
#endif /* __ARDUINO_OTA_H */
|
@ -1,51 +0,0 @@
|
||||
#include "WiFi.h"
|
||||
#include "AsyncUDP.h"
|
||||
|
||||
const char * ssid = "***********";
|
||||
const char * password = "***********";
|
||||
|
||||
AsyncUDP udp;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("WiFi Failed");
|
||||
while(1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
if(udp.connect(IPAddress(192,168,1,100), 1234)) {
|
||||
Serial.println("UDP connected");
|
||||
udp.onPacket([](AsyncUDPPacket packet) {
|
||||
Serial.print("UDP Packet Type: ");
|
||||
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
|
||||
Serial.print(", From: ");
|
||||
Serial.print(packet.remoteIP());
|
||||
Serial.print(":");
|
||||
Serial.print(packet.remotePort());
|
||||
Serial.print(", To: ");
|
||||
Serial.print(packet.localIP());
|
||||
Serial.print(":");
|
||||
Serial.print(packet.localPort());
|
||||
Serial.print(", Length: ");
|
||||
Serial.print(packet.length());
|
||||
Serial.print(", Data: ");
|
||||
Serial.write(packet.data(), packet.length());
|
||||
Serial.println();
|
||||
//reply to the client
|
||||
packet.printf("Got %u bytes of data", packet.length());
|
||||
});
|
||||
//Send unicast
|
||||
udp.print("Hello Server!");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
//Send broadcast on port 1234
|
||||
udp.broadcastTo("Anyone here?", 1234);
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
#include "WiFi.h"
|
||||
#include "AsyncUDP.h"
|
||||
|
||||
const char * ssid = "***********";
|
||||
const char * password = "***********";
|
||||
|
||||
AsyncUDP udp;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("WiFi Failed");
|
||||
while(1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
if(udp.listenMulticast(IPAddress(239,1,2,3), 1234)) {
|
||||
Serial.print("UDP Listening on IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
udp.onPacket([](AsyncUDPPacket packet) {
|
||||
Serial.print("UDP Packet Type: ");
|
||||
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
|
||||
Serial.print(", From: ");
|
||||
Serial.print(packet.remoteIP());
|
||||
Serial.print(":");
|
||||
Serial.print(packet.remotePort());
|
||||
Serial.print(", To: ");
|
||||
Serial.print(packet.localIP());
|
||||
Serial.print(":");
|
||||
Serial.print(packet.localPort());
|
||||
Serial.print(", Length: ");
|
||||
Serial.print(packet.length());
|
||||
Serial.print(", Data: ");
|
||||
Serial.write(packet.data(), packet.length());
|
||||
Serial.println();
|
||||
//reply to the client
|
||||
packet.printf("Got %u bytes of data", packet.length());
|
||||
});
|
||||
//Send multicast
|
||||
udp.print("Hello!");
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
//Send multicast
|
||||
udp.print("Anyone here?");
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
#include "WiFi.h"
|
||||
#include "AsyncUDP.h"
|
||||
|
||||
const char * ssid = "***********";
|
||||
const char * password = "***********";
|
||||
|
||||
AsyncUDP udp;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
|
||||
Serial.println("WiFi Failed");
|
||||
while(1) {
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
if(udp.listen(1234)) {
|
||||
Serial.print("UDP Listening on IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
udp.onPacket([](AsyncUDPPacket packet) {
|
||||
Serial.print("UDP Packet Type: ");
|
||||
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
|
||||
Serial.print(", From: ");
|
||||
Serial.print(packet.remoteIP());
|
||||
Serial.print(":");
|
||||
Serial.print(packet.remotePort());
|
||||
Serial.print(", To: ");
|
||||
Serial.print(packet.localIP());
|
||||
Serial.print(":");
|
||||
Serial.print(packet.localPort());
|
||||
Serial.print(", Length: ");
|
||||
Serial.print(packet.length());
|
||||
Serial.print(", Data: ");
|
||||
Serial.write(packet.data(), packet.length());
|
||||
Serial.println();
|
||||
//reply to the client
|
||||
packet.printf("Got %u bytes of data", packet.length());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
delay(1000);
|
||||
//Send broadcast
|
||||
udp.broadcast("Anyone here?");
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For Ultrasound
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
AsyncUDP KEYWORD1
|
||||
AsyncUDPPacket KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
connect KEYWORD2
|
||||
connected KEYWORD2
|
||||
listen KEYWORD2
|
||||
listenMulticast KEYWORD2
|
||||
close KEYWORD2
|
||||
write KEYWORD2
|
||||
broadcast KEYWORD2
|
||||
onPacket KEYWORD2
|
||||
data KEYWORD2
|
||||
length KEYWORD2
|
||||
localIP KEYWORD2
|
||||
localPort KEYWORD2
|
||||
remoteIP KEYWORD2
|
||||
remotePort KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user