Compare commits

...

432 Commits

Author SHA1 Message Date
7edf81ed1a Fixed warning 2022-08-19 16:24:43 +02:00
19333fd774 Downgrade for old compiler 2022-07-11 16:03:50 +02:00
a3d5e78b83 Fix to compile under cpp23 again successfully 2022-06-22 14:53:37 +02:00
2b2f7cd936 Updated to newest IDF with new GCC 2022-06-13 20:34:19 +02:00
8bb0f29958 add missing c++ guard 2022-05-23 23:58:16 +02:00
a2c33507ba Cleanup arduino useless bullshit 2022-05-23 23:54:26 +02:00
c7da12b153 Removed useless shitty bullshit Arduino.h 2022-05-23 23:41:24 +02:00
c85a4725a9 Cleanup arduino useless bullshit 2022-05-23 23:28:35 +02:00
e1540e64a6 Fix compiler warnings 2022-03-17 18:12:53 +01:00
a1fa8dc1eb Changes needed to compile again with new idf 2022-03-17 14:45:21 +01:00
0bfbfd527d Fixes to work again with old idf too 2022-03-05 15:26:17 +01:00
9f58515d7f Fix compiling after esp-idf update by removing openssl as dependency 2022-03-04 16:23:40 +01:00
f9d142def6 Fixes after idf rebase 2022-02-24 14:54:57 +01:00
59d3f4bd4f Fixed shitty arduino compile with newer idf 2022-01-29 21:10:02 +01:00
40409a3e4f Fixed compiling with newest idf again 2022-01-11 13:52:54 +01:00
6c49028af8 Removed arduino's shitty serial functionality 2021-12-21 19:25:39 +01:00
aa9f5dc65a Removed again some bullshit arduino bullshit components (hal-timer) 2021-11-21 17:55:42 +01:00
ce4aa4606c add toString for i2c errors 2021-11-03 21:17:52 +01:00
f607edea13 proper return types 2021-11-03 19:02:30 +01:00
c9ca6f199b HardwareSerial int8 vs uint8 fixes 2021-10-04 13:22:53 +02:00
b0223be116 Removed shitty random utilities 2021-09-05 21:09:19 +02:00
8e447f5cd5 Removed arduino's delay() 2021-08-09 16:15:21 +02:00
a84e0538ff Removed more arduino bullshit defines 2021-07-29 16:41:57 +02:00
ff9ec961c1 Removed retarted arduino binary.h 2021-06-28 21:19:49 +02:00
f5e23bfbbd Added SPI to CMakeLists.txt 2021-06-28 19:40:16 +02:00
50e1f1ffa1 Removed shitty arduino bluetooth components 2021-05-27 20:51:53 +02:00
5fdfe5e1b9 Dont prepend filename if esp-idf already does it 2021-05-12 16:42:40 +02:00
e9cdb0d111 Changed arduino logtag 2021-05-12 16:05:54 +02:00
ecc9bb3eb0 Fix compiler warning by removing more bullshit arduino code 2021-05-08 17:05:45 +02:00
07b177e4a5 shitty arduino log now uses esp log 2021-05-06 21:24:18 +02:00
67dfea558a Remove shitty arduino logging system 2021-05-05 12:53:37 +02:00
d237cc9df6 Removed shitty Print and shitty Printable interfaces 2021-04-21 21:57:49 +02:00
c5d5f95c1b Removed shitty base64 arduino code 2021-04-21 20:09:33 +02:00
561bca1e67 Removed shitty cencode 2021-04-17 22:44:41 +02:00
0f38a07a20 Removed IPAddress bullshit 2021-04-05 21:20:48 +02:00
899e7e01d4 Removed more low quality code to fix warnings 2021-03-06 08:59:42 +01:00
4458870228 64bit millis() preparations 2021-03-03 15:19:46 +01:00
e385dd8abc Dont include log header by default everywhere 2021-03-03 15:19:46 +01:00
acf3b3948a Fixed 2021-03-03 15:19:46 +01:00
a4a32ef88a Removed more shitty garbage stuff 2021-03-03 15:19:46 +01:00
9ff721dede Removed more bullshit components which got replaced by proper C++ code 2021-03-03 15:19:45 +01:00
9bd3e02d0f Increase stack size 2021-03-03 15:18:59 +01:00
35bea57d10 Removed more bullshit useless dumb code 2021-03-03 15:18:59 +01:00
2e19b9ff5b Removed bullshit shitty files from shitty arduino developers who write shitty code 2021-03-03 15:18:56 +01:00
bbb21bbf55 Removed tools to avoid outdated autocompletions in IDE 2021-03-03 15:14:32 +01:00
dfe251e9a2 Fixed dependencies 2021-02-15 02:07:30 +01:00
a56728a16b Added missing dependency 2021-01-13 16:10:45 +01:00
f41438597d Fixed to get compiling again with newest esp-idf 2021-01-07 18:44:25 +01:00
dcf9895955 esp-idf fixes 2020-12-16 19:01:29 +01:00
7d3f49940f Update esptool for Big Sur 2020-12-07 10:17:52 +02:00
9bc8420e2f Update boards.txt 2020-12-01 18:00:24 +02:00
c1b06cc120 Fix possible race condition in uart attach (#4569) 2020-12-01 16:36:44 +02:00
93c6226177 Separate Provisioning library from WiFi library to avoid unnecessary compilation while using WiFi library (#4550) 2020-11-19 00:13:14 +02:00
b5651491e5 Ignore mklittlefs 2020-11-18 19:11:42 +02:00
a25ccb2ef7 Fix Wire.begin causing divide by zero
Fixes: https://github.com/espressif/arduino-esp32/issues/4530
2020-11-17 02:30:12 +02:00
5b5b61c018 rework persist reboot 2020-11-17 02:04:56 +02:00
cbafe67ee1 Fix PSRAM on S2 2020-11-17 01:13:23 +02:00
e0f8b845fb Merge branch 'master' into idf-release/v4.2 2020-11-15 21:47:59 +02:00
1eb2c6d3dc Merge pull request #4542 from lbernstone/adc_vref
Fix deprecated vref function
2020-11-15 21:31:36 +02:00
564733137a Merge pull request #4541 from lbernstone/SD_MMC_v4.2
Updated SD_MMC init to match changes upstream
2020-11-15 21:31:12 +02:00
e5555c72e5 Fix deprecated vref function 2020-11-15 12:16:02 -07:00
104d28bd9c Merge pull request #4540 from loick111/feature/custom_variants_dir_idf4.2
Allow custom variants directory
2020-11-15 21:10:52 +02:00
934553d290 Updated SD_MMC init to match changes upstream 2020-11-15 12:00:55 -07:00
f7fe024744 Allow custom variants directory 2020-11-15 19:56:05 +01:00
adafd9d7c0 Merge pull request #4538 from loick111/feature/custom_variants_dir
The goal is to allow custom configuration for `variants_dir` to define our own board variant directly in the project.

With this functionnality, we are now allowed to define in our projects a custom board **AND** a custom variant.
https://docs.platformio.org/en/latest/platforms/creating_board.html#custom-embedded-boards

Here is an example of how to define a custom board with custom variant:
```
my_project
├── boards
│   └── custom_esp32dev.json
└── variants
    └── custom-esp32dev
        └── pins_arduino.h
```

custom_esp32dev.json
```json
{
  "build": {
    "arduino":{
      "ldscript": "esp32_out.ld"
    },
    "core": "esp32",
    "extra_flags": "-DARDUINO_ESP32_DEV",
    "f_cpu": "240000000L",
    "f_flash": "40000000L",
    "flash_mode": "dio",
    "mcu": "esp32",
    "variants_dir": "variants",
    "variant": "custom-esp32dev"
  },
  "connectivity": [
    "wifi",
    "bluetooth",
    "ethernet",
    "can"
  ],
  "debug": {
    "openocd_board": "esp-wroom-32.cfg"
  },
  "frameworks": [
    "arduino",
    "espidf"
  ],
  "name": "My Custom Espressif ESP32 Dev Module",
  "upload": {
    "flash_size": "4MB",
    "maximum_ram_size": 327680,
    "maximum_size": 4194304,
    "require_upload_port": true,
    "speed": 460800
  },
  "url": "https://en.wikipedia.org/wiki/ESP32",
  "vendor": "Espressif"
}
```
2020-11-15 20:43:43 +02:00
ac9fdeffe4 Allow custom variants directory 2020-11-15 16:20:02 +01:00
29e3b640a8 Update IDF to 494a124d9 2020-11-15 12:25:38 +02:00
91025f8515 Merge branch 'master' into idf-release/v4.2 2020-11-15 12:04:09 +02:00
e41fb08b2a Update esptool to work on BigSur 2020-11-15 08:53:07 +02:00
d8b1fc81c0 Added usedBytes to match other filesystems (#4534) 2020-11-15 08:48:21 +02:00
378b6ac032 Fix issue in webserver with Chrome based browsers
https://github.com/espressif/arduino-esp32/issues/3652
2020-11-15 08:46:23 +02:00
a2e0e865dd Provisioning Fixes (#4522) 2020-11-12 14:31:59 +02:00
9debb9fc76 Merge branch 'master' into idf-release/v4.2 2020-11-10 20:52:25 +02:00
b6cc108d49 Update WiFiProv.cpp (#4519)
Do not pollute the global namespace with generic names like 'config' by declaring global variables 'static'.
2020-11-10 20:51:10 +02:00
8816bb5505 Added #define LED_BUILTIN to all pins_arduino.h that need it. (#4520) 2020-11-10 20:50:35 +02:00
3274602eb0 Notify the batteryLevel change (#4517) 2020-11-10 13:02:00 +02:00
5d62ba56f6 Idf release/v4.2 - corrections of LITTLEFS and tools (#4515)
* Update package_esp32_index.template.json

Fix of wrong file type

* Update LITTLEFS.cpp

Suppress warnings fix.
2020-11-10 10:19:34 +02:00
2d0e772674 add 2 variants (#4514)
* add variants

* add boards
2020-11-10 10:18:42 +02:00
2063a606e9 Merge branch 'master' into idf-release/v4.2 2020-11-09 17:08:38 +02:00
534f0810a6 fix bitWrite macro (#4507)
Fixes https://github.com/espressif/arduino-esp32/issues/4466
2020-11-09 17:08:13 +02:00
28a8073069 Fix issue 4095 (#4503)
pgmspace.h missing 'pgm_get_far_address'
2020-11-08 04:55:59 +02:00
ca6405658a Merge branch 'master' into idf-release/v4.2 2020-11-06 22:28:28 +02:00
486a4c66c4 SDCARD: First sector always written twice if multiple sectors are updated 2020-11-06 22:20:20 +02:00
70bd58b00b Update Arduino.h 2020-11-06 22:07:24 +02:00
f1cbd3b74b Create esp_arduino_version.h 2020-11-06 22:02:40 +02:00
ad07d36932 Update README.md 2020-11-06 17:21:12 +02:00
e55d657e9f Try to free some memory 2020-11-06 15:45:10 +02:00
ef5c73f1ed Merge branch 'master' into idf-release/v4.2 2020-11-06 14:17:30 +02:00
c6a8da61f7 Allow faster reuse of socket, to be able to restart WifiServer. (#4306)
See #3960 for more details of the problem and the solution. I only implemented what was proposed in this ticket, as it solves my problem, which was the same as in this ticket. Credits for the code going to @etrinh ;-)

This also is a more consistence behaviour compared to esp8266, where it also is possible to restart the wifiserver immediately on the same port.
2020-11-06 14:16:50 +02:00
591c43880a RE: Change check for BT_ENABLE to really be a check for BLUEDROID_ENABLED (#4497)
* Change check for CONFIG_BT_ENABLE to really be a check for CONFIG_BLUEDROID_ENABLED

Which is really what should have been tested.  This allows use of
the Arduino layer with the newer Nimble stack for those that don't want
to use Bluedroid.

In support of https://github.com/meshtastic/Meshtastic-device/issues/266

* Change check for CONFIG_BT_ENABLE to really be a check for CONFIG_BLUEDROID_ENABLED

Which is really what should have been tested.  This allows use of
the Arduino layer with the newer Nimble stack for those that don't want
to use Bluedroid.

In support of https://github.com/meshtastic/Meshtastic-device/issues/266

* wifi prov changes

* merge fixes

Co-authored-by: geeksville <kevinh@geeksville.com>
2020-11-06 14:00:06 +02:00
dd1a15478f add TimerCAM and CoreInk board (#4498) 2020-11-06 13:30:57 +02:00
8767419289 Merge branch 'master' into idf-release/v4.2 2020-11-06 13:27:35 +02:00
bcb7012a32 Change variants folder T-Beam (#4496) 2020-11-06 12:42:18 +02:00
78783c5183 fix psram init 2020-11-06 12:20:20 +02:00
1bb7abe271 Make setHostname return true 2020-11-05 20:37:07 +02:00
3968821834 HttpClient uses Serial.printf() (#4488)
changed to log_d()
2020-11-04 14:49:33 +02:00
ec5ec746d9 skip bt tests for esp32s2 2020-11-04 04:08:22 +02:00
a4aaec6a23 Merge branch 'master' into idf-release/v4.2 2020-11-04 02:31:29 +02:00
976aca4781 more fixes 2020-11-04 02:31:08 +02:00
90f869e772 Fix BUG: Parsing of first line fails (#4484)
..because a firstLine = false; is missing ;)
2020-11-04 02:24:01 +02:00
72c25f2fdb Update WiFiProv.ino 2020-11-04 02:21:38 +02:00
a07f3c16a5 Add missing config 2020-11-04 02:16:30 +02:00
37af4c9d2f more fixes 2020-11-04 01:53:38 +02:00
5e3189f2f1 fix some merge errors 2020-11-04 01:33:52 +02:00
b76c95206c Adding LITTLEFS after esp_littlefs (IDF) is built-in (#4483)
Tools idea: https://github.com/lorol/arduino-esp32fs-plugin
2020-11-04 01:20:58 +02:00
8ae5be5659 Add esp-rainmaker support for ESP32 2020-11-04 01:19:31 +02:00
6ffe081fd2 Update IDF master to 357a27760 2020-11-04 01:19:29 +02:00
2d0b8c7e81 Update IDF and Camera 2020-11-04 01:19:07 +02:00
9a37a020d2 Fix Arduino PIN counts 2020-11-04 01:19:05 +02:00
cf93d473fb Make esp32-hal-tinyusb.h conditional on tinyusb (#4155) 2020-11-04 01:19:05 +02:00
659e9a51dd Update IDF and Tools 2020-11-04 01:19:01 +02:00
8900e8fca9 Update .gitignore 2020-11-04 01:18:31 +02:00
064aa692f9 Update platform.txt 2020-11-04 01:18:31 +02:00
57c96aa4e3 Add camera support
first automated cmake build
2020-11-04 01:18:31 +02:00
f8b72db3c6 Try with speed optimization as opposed to debug. Coremark 240 -> 430 2020-11-04 01:18:28 +02:00
100001389b Added ESP32-Wrover-Kit with distinct build.board (#4118)
* Added ESP32-Wrover-Kit with distinct build.board

* Fixed broken values

* Update boards.txt

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-11-04 01:18:27 +02:00
8c85642b04 Add board microS2 (#4314) 2020-11-04 01:16:22 +02:00
bae722f1c1 Makes ethernet get an IP when connected (#4234) 2020-11-04 01:16:22 +02:00
fa852c955f Update WiFiMulti.cpp (#4099)
Fix for https://github.com/espressif/arduino-esp32/issues/3914 by syncing with https://github.com/espressif/arduino-esp32/blob/esp32s2/libraries/WiFi/src/WiFiSTA.cpp#L161
2020-11-04 01:16:22 +02:00
1ded874ce1 Update USB.cpp 2020-11-04 01:16:22 +02:00
470cbedd8a Update boards.txt 2020-11-04 01:16:22 +02:00
7f2bf4e401 Update platform.txt 2020-11-04 01:16:22 +02:00
ad07421931 Update install-platformio-esp32.sh 2020-11-04 01:16:22 +02:00
537384da7d Update platform.txt
Provided by @ESP32DE
2020-11-04 01:16:22 +02:00
394c32ddfc Update IDF, tools and toolchains 2020-11-04 01:16:17 +02:00
86c87aaeee Some fixes 2020-11-04 01:15:33 +02:00
0ac788f666 Add option to select the core used for Arduino and it's events 2020-11-04 01:15:32 +02:00
e25ef9e6d0 Update CMakeLists.txt 2020-11-04 01:15:32 +02:00
9e2b2bff70 Update HardwareSerial.h 2020-11-04 01:14:42 +02:00
17581ec74d Added UM FeatherS2 and UM ProS2 boards to boards.txt (#4188)
* Added UM FeatherS2 and UM ProS2 boards to boards.txt
Updated the name of TinyPICO to UM TinyPICO in boards.txt

* Added VID/PID/Product names for TinyPICO, ProS2 & FeatherS2
Setup variant folders for each board

* Removed unneeded stuff from FeatherS2 & ProS2 menu options

* Added Serial CDC output default for FeatherS2 and ProS2

* Removed unneeded stuff from FeatherS2 & ProS2 menu options

* Rebase from upstream and fixed Serial Output settings for FeatherS2 and ProS2

Co-authored-by: Seon Rozenblum <seonr@3sprockets.com>
2020-11-04 01:14:41 +02:00
31ab456a3a Update CMakeLists.txt 2020-11-04 01:11:29 +02:00
681b1214cf Improve CDC Logging support 2020-11-04 01:11:29 +02:00
d777949bf5 Create USB_NOT.h 2020-11-04 01:11:28 +02:00
1a7a928b64 Add option USB CDC to be used for Serial (starting USB early) 2020-11-04 01:11:28 +02:00
4967f19513 Add support for custom VID/PID and Board name to show in ArduinoIDE ports list 2020-11-04 01:11:28 +02:00
2a94977f60 Update tinyusb 2020-11-04 01:11:28 +02:00
e325872f4e Update USB.cpp 2020-11-04 01:11:28 +02:00
e687951c0f Some CDC and BTSerial compatibility fixes 2020-11-04 01:11:28 +02:00
8cc9e955dc Add debug output to CDC 2020-11-04 01:11:28 +02:00
29e3d0e75f Handle persistent reboot better in CDC 2020-11-04 01:11:28 +02:00
7f54a357a4 Change driver attach api and remove DFU from CDC 2020-11-04 01:11:28 +02:00
c9ae74f012 Update TinyUSB 2020-11-04 01:11:27 +02:00
c6c3be12b9 Update USBCDC.cpp 2020-11-04 01:11:27 +02:00
e9f1b5e838 Update libtinyusb.a 2020-11-04 01:11:27 +02:00
ec7a51b263 Fix compilation issues 2020-11-04 01:11:27 +02:00
6cd0d7c3db Fix DTR/RTS state for ESP32S2 native USB 2020-11-04 01:11:27 +02:00
1879a5c93d Update CMakeLists.txt 2020-11-04 01:11:27 +02:00
1b67e41c82 Add files to cmakelists and disconnect CDC if unplugged 2020-11-04 01:11:27 +02:00
f43352b752 Add TinyUSB HAL and CDC 2020-11-04 01:10:37 +02:00
47b34df897 Update IDF Libs 2020-11-04 01:10:37 +02:00
7611f483ae Update TinyUSB Lib 2020-11-04 01:10:35 +02:00
1e48761177 Fix GPIO Interrupts 2020-11-04 01:10:35 +02:00
06125d22e1 Fixing static IP configuration so it doesn't get overwritten by DHCP as part of WiFi.begin(). (#4103)
Fixing DHCP client stop if WiFi.config() is called before WiFi.begin() (as done in WiFiClientStaticIP.ino)
2020-11-04 01:10:35 +02:00
cf713a88c8 Update libtinyusb.a 2020-11-04 01:10:35 +02:00
e094e19f17 Add missing DFU driver 2020-11-04 01:10:35 +02:00
0df54ea169 Try custom device descriptors 2020-11-04 01:10:34 +02:00
93c97aac1c again 2020-11-04 01:10:34 +02:00
232ab09694 change endpoints 2020-11-04 01:10:33 +02:00
146878768c TinyUSB adjust 2020-11-04 01:10:32 +02:00
1f53f28481 Update pins_arduino.h 2020-11-04 01:10:32 +02:00
5a2580db7e Fix swapped USB pins issue 2020-11-04 01:10:32 +02:00
298a6f8910 Update CMakeLists.txt 2020-11-04 01:10:31 +02:00
eda687069a what happened to no-stub? 2020-11-04 01:09:00 +02:00
9612ac89b7 how about now? 2020-11-04 01:09:00 +02:00
c32a9be28b what if functions are in the core? 2020-11-04 01:08:59 +02:00
832edd2c63 try to fix linking errors 2020-11-04 01:08:58 +02:00
908ee03db4 hopefully all is here now 2020-11-04 01:08:57 +02:00
76637cbd5b Once again 2020-11-04 01:08:56 +02:00
f2e1016ea5 Update TinyUSB 2020-11-04 01:08:55 +02:00
8ac2a69553 Add support for no-stub usb s2 flashing 2020-11-04 01:08:54 +02:00
5dbcf201b8 Pull latest IDF and enable TinyUSB 2020-11-04 01:07:49 +02:00
604abf0a96 Disable modem sleep by default on S2 for now. 2020-11-04 01:07:47 +02:00
dc707a3121 add psram to malloc only if interrupts are not in IRAM 2020-11-04 01:07:21 +02:00
b499befa9b fix psram always init 2020-11-04 01:07:21 +02:00
895fba0ded fix issue with rtc wdt 2020-11-04 01:07:20 +02:00
67e7706728 update idf libs, disable WDT on S2, use malloc for PSRAM 2020-11-04 01:07:19 +02:00
99b5be0037 Disable IRAM ISRs and functions by default 2020-11-04 01:07:18 +02:00
3397208d12 Update esp32-hal-gpio.c 2020-11-04 01:06:45 +02:00
131c87b127 Update main.cpp 2020-11-04 01:06:45 +02:00
87c9a8a8fa some i2c fixes 2020-11-04 01:06:44 +02:00
90e77cdaaf Update WPS.ino 2020-11-04 01:06:44 +02:00
59264b0254 Update WiFiProv.ino 2020-11-04 01:06:44 +02:00
d1e7aefed7 Update WiFiBlueToothSwitch.ino 2020-11-04 01:06:08 +02:00
ae27682601 Update WiFiClientEvents.ino 2020-11-04 01:06:08 +02:00
dd64404823 more example fixes 2020-11-04 01:06:08 +02:00
146c493b30 fix wrong bootloader path in pio scripts 2020-11-04 01:06:08 +02:00
1f204676e6 fix some examples 2020-11-04 01:06:08 +02:00
ecc96060da fix WiFi 2020-11-04 01:04:59 +02:00
a761281d8c Fix PSRAM support 2020-11-04 00:57:18 +02:00
5abe013f78 Update esp32-hal-uart.c 2020-11-04 00:57:18 +02:00
92aa3b5e14 Update esp32-hal-uart.c 2020-11-04 00:57:18 +02:00
61132a7172 Fix Serial 2020-11-04 00:57:18 +02:00
4b9f70236f Update HardwareSerial.cpp 2020-11-04 00:56:45 +02:00
ce64a26ce3 Add I2C IDF Wrapper 2020-11-04 00:56:45 +02:00
77015e05be fix compile errors for esp32 2020-11-04 00:56:45 +02:00
0c5f0f8bf8 fix peripherals 2020-11-04 00:56:45 +02:00
3f89e22174 Update on-push.sh 2020-11-04 00:56:45 +02:00
986b2a2699 Update install-platformio-esp32.sh 2020-11-04 00:56:45 +02:00
55eca6830d fix py script 2020-11-04 00:56:45 +02:00
39c1de2e6d new try at pio 2020-11-04 00:56:45 +02:00
703ce7ed14 does not work 2020-11-04 00:56:44 +02:00
df0c8aedda how about now? 2020-11-04 00:56:44 +02:00
40665eaf3a try outputing the map 2020-11-04 00:56:44 +02:00
bac6aece9e Update on-push.sh 2020-11-04 00:56:44 +02:00
f6d705f577 Update platformio-build-esp32.py 2020-11-04 00:56:44 +02:00
d2bf40c0b3 Update platformio-build-esp32.py 2020-11-04 00:56:44 +02:00
4aefc0ea3b try pio again 2020-11-04 00:56:44 +02:00
bcadf08fa6 Update on-push.sh 2020-11-04 00:55:56 +02:00
92772e2aba Update on-push.sh 2020-11-04 00:55:56 +02:00
edee32ac07 Update WiFiTelnetToSerial.ino 2020-11-04 00:55:56 +02:00
cd9f890400 skip more examples 2020-11-04 00:55:56 +02:00
66b3e68bc4 Update esp32-hal-i2c.c 2020-11-04 00:55:56 +02:00
d64a825b0a Update SD_Update.ino 2020-11-04 00:55:56 +02:00
2fcb386dcf Create .skip.esp32s2 2020-11-04 00:55:56 +02:00
fbac930d7c skip some examples 2020-11-04 00:55:56 +02:00
d349cdc08f Update SPI_Multiple_Buses.ino 2020-11-04 00:55:55 +02:00
a0b8025ad8 Update TouchRead.ino 2020-11-04 00:55:55 +02:00
5784081147 disable BT Serial examples for S2 2020-11-04 00:55:55 +02:00
d3c5f26fa4 Update ResetReason.ino 2020-11-04 00:55:55 +02:00
bcae3a4def Update on-push.sh 2020-11-04 00:55:55 +02:00
7e06b32ce3 try s2 ci 2020-11-04 00:55:55 +02:00
2326f91bc9 fix provision compilation 2020-11-04 00:55:55 +02:00
c070e7152b fix cmake check 2020-11-04 00:54:09 +02:00
3735cfe548 Update app_httpd.cpp 2020-11-04 00:54:09 +02:00
d9c7b589a0 some compile fixes 2020-11-04 00:54:09 +02:00
5570003949 Update CameraWebServer.ino 2020-11-04 00:52:50 +02:00
96b9e89015 Update esp32-hal-gpio.c 2020-11-04 00:52:50 +02:00
c6b03a3f94 Add S2 variant 2020-11-04 00:52:50 +02:00
0a262244e6 Initial Commit 2020-11-04 00:52:28 +02:00
ebe0d9a6cb Add fixes 2020-11-04 00:29:15 +02:00
970fef63c0 Pass ethernet events to the main handler 2020-11-04 00:28:42 +02:00
f14a85311f get smart config to work as well 2020-11-04 00:28:41 +02:00
92db9730e0 make ETH work 2020-11-04 00:28:41 +02:00
ee535efb5c Update package_esp32_index.template.json 2020-11-04 00:28:41 +02:00
96679576d0 Update CMakeLists.txt 2020-11-04 00:28:41 +02:00
1bf59ac227 Initial IDF-4.0 port
SmartConfig and ETH need some work to adapt to the new API
2020-11-04 00:28:05 +02:00
be4d3b6cb8 Try to fix issue with GIT 2.29.0 2020-11-03 22:22:35 +02:00
60606e5ad0 Update on-release.sh 2020-11-03 21:53:22 +02:00
22b427df0f IDF release/v3.3 (#3672)
ESP-IDF release/v3.3: 66d3783c8
esp-face: 420fc7e
esp32-camera: 0107093
2020-11-03 21:20:00 +02:00
6e5be78838 Update install-arduino-ide.sh 2020-11-03 21:12:05 +02:00
e2452c0dfc Added isKey method to Preferences (#4441)
Checks to see if a string is a key in the namespace. 

Fixes #4440
2020-11-03 17:03:04 +02:00
56a7ae8712 Trailing spaces (#3738)
* fix typo in WiFiMulti

* clean up trailing spaces

* clean up script file used in cleaning

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-11-02 22:11:26 +02:00
e4b008e712 Handle stream timeouts properly, for slow HTTP/HTTPS links (#3752)
This patch fixes update timeouts (error #6) on slow HTTP/HTTPS links.
2020-11-02 22:01:27 +02:00
76afaf2d6b Add more options to the AI thinker cam. (#4253)
* Add more options to the AI thinker cam.

The reason is power saving and compatibility of cheap chines clones with crappy flash chips.
2020-11-02 21:21:22 +02:00
dccb4e8608 improve & fix BLEScan when wantDuplicates (#3995)
* improve & fix BLEScan when too many BLE devices
- when wantDuplicates, no need to check duplicate and no more insert into vector
- delete advertisedDevice when not insert into vector, fix memory leak
- add showParse when you just want raw advertised data
2020-11-02 20:41:50 +02:00
c2346c37da Add initial support for arm64 toolchain. (#4117)
Closes #4111.
gcc: I was not able to find an arm64 build on espressif's website so I choosed to put the armhf version, even if this should works this is only ok as temporary, arm64 runs better on arm64 than armhf :)
esptool: being interpreted python its ok
mkspiff: need igrr/mkspiffs#74 to be merged and artifacts added in /package/package_esp32_index.template.json.
2020-11-02 20:39:31 +02:00
3491ca7845 Add virtual beginMulticast(...) stub to UDP class (#4061)
https://github.com/arduino/ArduinoCore-sam/pull/6/files

It is used here:
https://github.com/arduino-libraries/ArduinoMDNS/blob/master/MDNS.cpp#L150
2020-11-02 20:26:50 +02:00
0e341a6192 Add sdkconfig option CONFIG_ARDUINO_UDP_TASK_PRIORITY, which sets the task priority for the UDP vtask." (#4131) 2020-11-02 20:21:59 +02:00
76cd2e2375 Fix BLE connection handling (#4137)
Remove device from Peer list if connection fails.

Only call onConnect callback if connection was successful.

Only call onDisconnect callback if the connection was previously connected (ESP_GATTC_DISCONNECT_EVT is fired on a unsuccessful connection attempt also).

Resolves a number of issues with phantom events and callbacks being fired.
2020-11-02 20:20:40 +02:00
9f7ff009c6 Fix parameter to BLEDevice::updatePeerDevice (#4133)
::addPeerDevice and ::removePeerDevice are called with m_appId, so should ::updatePeerDevice as all use the same parameter for the underlying map's key.
2020-11-02 20:20:16 +02:00
704b71dabe Fix header parsing
fixes #4454

closes #4455
2020-11-02 20:10:22 +02:00
7c0572172c Fix for issue #4158: BLEAdvertising - Crash with stack trace originating in Bluedroid (#4182)
* Fix for issue #4158: Crash with stack trace originating in Bluedroid
Improved configuration of scan response data in 'BLEAdvertising' avoids the crash:
- Added member variable 'm_scanRespData' to configure scan response differently from advertising data
- Initialization of 'm_scanRespData' in BLEAdvertising constructor
- Use of 'm_scanRespData' within BLEAdvertising::start() to configure the scan response
- 'Flags' and 'Appearance' are cleared in the scan response data
- With this fix, device names of up to 29 characters can be used without causing a crash.
2020-11-02 19:39:20 +02:00
f57c36782f Add sendContent overload that takes a const char* and a length (#4276)
The web server currently lacks the ability to send a buffer. Only strings are supported.

This PR adds an overload to sendContent.
2020-11-02 19:17:02 +02:00
3054bdf5a5 HTTPUpdateServer library (#4244) 2020-11-02 19:16:23 +02:00
1014ba40af Update ISSUE_TEMPLATE.md (#4416)
Make options list into a table
2020-11-02 18:59:46 +02:00
d6b91872cb Fix for espressif#3460 issue (#4424)
Fixes: #3460

This code has been run in production for 1 month and it looks stable, no data dropped and it definitely fixes the issue described. I think that this can be merged to avoid using custom package referencing in PlatformIO that has been used in quite a few projects for now.

Co-authored-by: Ivan Golubic <ivan@mvt-solutions.com>
2020-11-02 18:59:03 +02:00
d6b383f84b Merge pull request #4429 from Bmooij/feature/Add_flash_helper_constructor_to_Uri
Add flash helper constructor to Uri
2020-11-02 18:56:08 +02:00
cadbad8850 Add partition label argument to Update and ArduinoOTA classThe UpdateClass in the Updater component has the ability to update data toa SPIFFS partition. It selects the first available partition using theESP-IDF esp_partition_find_first() function.That behaviour is problematic if one has multiple SPIFFS partitions.This change allows a user to pass the label argument (defaults to NULL)to UpdateClass::begin() so a specific SPIFFS partition can be updated.Additionally, ArduinoOTA can set this partition label using thenew method ArduinoOTAClass::setPartitionLabel which is optional.This change does not break compatibility. (#4442)
The UpdateClass in the Updater component has the ability to update data to
a SPIFFS partition. It selects the first available partition using the
ESP-IDF esp_partition_find_first() function.
That behaviour is problematic if one has multiple SPIFFS partitions.

This change allows a user to pass the label argument (defaults to NULL)
to UpdateClass::begin() so a specific SPIFFS partition can be updated.

Additionally, ArduinoOTA can set this partition label using the
new method ArduinoOTAClass::setPartitionLabel which is optional.

This change does not break compatibility.
2020-11-02 18:49:24 +02:00
3cbfa2ffef Add partition label argument to SPIFFS (#4443)
* Add partition label argument to SPIFFSSPIFFS currently assumes there is only ever one partition.This change allows a user to pass the label argument (defaults to NULL)to SPIFFS::begin() so a specific SPIFFS partition can be referenced.This change does not break compatibility.
2020-11-02 18:47:36 +02:00
360e04fa36 Fixing BLE GATT Characteristic notification and Characteristic Descriptor read (#4464)
* BLERemoteChar: fix descriptor 2902 write for characteristic notifications

When registering a notification on a characteristic, the 2902 descriptor
(CCCD) value is set to 1 (or 2 for indication).
According to the BLUETOOTH CORE SPECIFICATION Version 5.2, Revision Date
2019-12-31, section 4.12.3 "Write Characteristic Descriptors" (page 1588),
the characteristic descriptor write must expect a response.
Currently, the descriptor write is performed without expecting a reponse,
which prevents the notification to be functional with some BLE stacks.
This commit modify the write to expect the response.

Signed-off-by: Jimmy Durand Wesolowski <jimmy.durand.wesolowski@commsolid.com>

* BLERemoteChar: forward GATT client event to characteristic descriptors

This commits prevents a permanent wait when calling BLERemoteDescriptor
readValue function, on the m_semaphoreReadDescrEvt semaphore.

ESP32 BLE stack calls to remote characteristic
- notification,
- value read
- value write
and remote characteristic descriptor
- value read
are asynchronous.

When such a call is performed by this library, a semaphore is taken prior
to the BLE stack read or write operation, and waited on after it.

Releasing the semaphore is done by the characteristic event handling
function (gattClientEventHandler), when the appropriate event is received.

However, the characteristic descriptor events are discarded, and the
value read semaphore is never released.

This commits forwards the GATT client events from the remote
characteristic down to their remote characteristic descriptor, and
implements their event handling.

Adding a semaphore for the remote characteristic descriptor value write
will be done in a separate commit.

Signed-off-by: Jimmy Durand Wesolowski <jimmy.durand.wesolowski@commsolid.com>

* BLERemoteDescriptor: add semaphore to characteristic descriptor write

This adds a semaphore to characteristic descriptor value write, to mimic
the value read function, and to ensure completion of the operation before
we carry on.

Signed-off-by: Jimmy Durand Wesolowski <jimmy.durand.wesolowski@commsolid.com>

Co-authored-by: Jimmy Durand Wesolowski <jimmy.durand.wesolowski@commsolid.com>
2020-11-02 18:36:25 +02:00
57145ade6f Small description comment correction (#4471)
esp8266 --> esp32
2020-11-02 18:35:23 +02:00
f39024675c Don't convert to null-terminated string prior to writeValue (#4473)
fixes: #4472
2020-11-02 18:34:57 +02:00
f7fb00632e #4293 added missing '<tr>' (#4450)
Fixes issue #4293
2020-10-27 15:35:54 +02:00
7e40de226f Fixes #4435 - WiFiClient improperly treats zero data available for read as an error (#4448) 2020-10-27 12:01:41 +02:00
ae240a3902 Add flash helper constructor to Uri 2020-10-19 16:20:49 +02:00
1287c52933 Add missing "-mlongcalls" flag to PlatformIO build script (#4420)
Fixes possible issues with assembly files in external libraries
2020-10-16 21:58:05 +03:00
25bd585c25 Corrections of Stream.Find, FindUntil and added FindMulti - like AVR-Core Libraries (#3442)
* Corrections of Find, FindUntil and FindMulti

Find has some bug that is not working with Ethernet.find() so, I copied code from Stream.h and Stream.cpp in AVR-CORE library and now it's working perfectly.
I don't know where was the error, but an Ethernet.find compiled to MEGA2560 was working but not working when compiled to esp32, after corrections of code (copy of AVR-Core libraries) it's working perfect.
So probably has some error on original ESP32-Core library.

Below is part of code that was working with MEGA2560 and not with ESP32 libraries.
client.find never return TRUE with ESP32 original library and with AVR it's works.

boolean esp32_fw_update(EthernetClient &client, DecodedHeader &header, const String &field_filename, const String &field_crc) {

  char bound[header.boundary.length()+3];
  char term[]="\r\n";
  
  strcpy(bound,header.boundary.c_str());
  strcat(bound,term);
  while (client.find(bound)) { 
    String line=client.readStringUntil('\r');

* Update Stream.h

* Update Stream.cpp

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-10-14 15:20:40 +03:00
d79a1f3d10 Add an aditional (void *) arg to the RMT callback (much like Ticker() et.al.). (#3345)
* Add an aditional (void *) arg to the RMT callback - to allow more flexible handling of the callback (e.g. by passing a private struct or a class pointer). Same pattern as used by the Ticker() and many others. Example updated & new example with a trapoline added.

* Fix example for new API

* Fix lint warnings

* Add a second missed example.

* Correct timeout & improve socket error handling.
2020-10-14 14:41:50 +03:00
831f0ac29a Rename eep -> partitions.bin & hex -> bin (#4143)
This is in line with the
[arduino platform specification](https://arduino.github.io/arduino-cli/platform-specification/#recipes-for-extraction-of-executable-files-and-other-binary-data)
specifying that the file extension after recipe.objcopy is arbitrary and
that the AVR platform uses `eep` & `hex`, while the esp32 platform seems
to have file extensions `partition.bin` & `bin`
2020-10-14 14:34:14 +03:00
ee3bb16c77 Fix support for following redirects added by ee88c42c3b (#4240) (#4385) 2020-10-14 14:32:47 +03:00
d8dca9c73b bugfix (#4389) 2020-10-14 14:30:32 +03:00
c3f3497048 fixed some typos (#4395) 2020-10-14 14:27:49 +03:00
18c3345451 fix typos in WiFiSTA.cpp (#4396)
* fix typos

* made return value description a bit more helpful
2020-10-14 14:27:19 +03:00
b07f1c11fe Updated Readme.md (#4400)
* Updated Readme.md

Added links to latest release. Made it look a lot cleaner.

* Update README.md
2020-10-14 14:26:41 +03:00
2685a5dd7b Certificate isn't be free in case parse failure. (#4412)
I met problem while I was working with the WiFiClientSecure.
I tried to found the source of the problem, and I found it in the sll_client.cpp.
Please check my contribution.

I've open this problem in #4335 but received no response.
2020-10-14 14:25:26 +03:00
675a40b257 Fix Not by reference. But the value was updated. (#3279) 2020-10-03 03:41:03 +03:00
3570d48eb9 Added the DoIT ESPduino-32 board (#1520) 2020-10-03 03:06:40 +03:00
f76ec4f50b adds debugging to dnsserver (#1046) 2020-10-03 02:59:55 +03:00
fb6d5ad234 Add Inex OpenKB Board (#4002)
Please add OpenKB Board Product from INEX Co. Ltd.

https://inex.co.th/shop/openkb.html
2020-10-03 02:20:10 +03:00
219ff3005b Add missing slashes in HTTPUpdate examples (#4238)
I spent quite a while today figuring out how to get an OTA update over HTTPS on a custom port working. A part of my problem was not putting a slash before the .bin filename, since it wasn't there in the example. This produced invalid HTTP requests. Adding the slash would make it clear that it needs to be there.

Given that the URL in line 53 contains the same words "server" and "file.bin", one might assume that in line 55, the slash after the port number would get added automatically, however I have found out that without a slash you get an invalid request. Adding the slash removes any doubt.
2020-10-03 02:13:27 +03:00
ccab428e4d Added definitions for TTGO-LoRA32-V2.1.6 (#4205) 2020-10-03 02:06:11 +03:00
d2d24a14e0 add board WiFiduino32 (#4218) 2020-10-03 02:04:10 +03:00
af11921535 Add support for S.ODI_Ultra_v1.0 (#4372)
Add a new Dev Board S.ODI Ultra v1 in esp32 library
2020-10-03 01:59:53 +03:00
82112384ca Fix missing headers when compiling as IDF component with Cmake (#4377)
* HttpsOTAUpdate introduced new IDF component requirements.
These have been added to CMakeLists.txt to correct compilation errors when using Cmake.
2020-10-01 15:45:52 +03:00
99aa866477 Update MDNSResponder::addService to return a boolean (#4365)
I was playing with the mDNS service and noticed the method MDNSResponder::addService could return a Boolean with the way it is implemented just like other functions in this library.

This would be handy to know at a higher level weather or not the service was added correctly to the mDNS server of the ESP32.
2020-10-01 15:44:24 +03:00
82670b96f8 Fix for missed scan response data (BLEScan). (#4358)
This is a fix for missing scan responses after a first successfull scan.

While running the BLE_scan.ino sketch with wantDuplicates=false, i got
only one result with correct advertising and scan response length (31,26):

pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), false);
pBLEScan->start(scanTime, false);
...
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 31 + 26, addr type: 1

All following calls to start() just returned the advertising data without
scan response data:

pBLEScan->start(scanTime, false);
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 31 + 0, addr type: 1

With "wantDuplicates=true" i got:

pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), true);
pBLEScan->start(scanTime, false);
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 31 + 26, addr type: 1
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 31 + 26, addr type: 1
[W][BLEScan.cpp:73] handleGAPEvent(): ESP_GAP_SEARCH_INQ_CMPL_EVT
Devices found: 1
Scan done!
pBLEScan->start(scanTime, false);
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 31 + 0, addr type: 1
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 0 + 26, addr type: 1
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 31 + 0, addr type: 1
[W][BLEScan.cpp:109] handleGAPEvent(): bytes length: 0 + 26, addr type: 1

Explicitly initializing m_scan_params.scan_duplicate of BLEScan solves
this issue (In my case the un-initialized value was
m_scan_params.scan_duplicate == 1073599044).

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-10-01 15:43:30 +03:00
9e7b13e46d WebServer.handleClient delay (#4350)
* If WebServer.handleClient is run in a tight loop, it will starve other processes.  So, if there is no connection, throw in a delay(1).  Fixes #4348

* Made a variable to control the delay behavior
2020-10-01 15:42:23 +03:00
2243081f85 add I2C_RX_FIFO_OVF_INT_ST handling to i2c_isr_handler_default (#4342)
Fixes crash on ESP32 when I2C FiFo overflows and interrupt function is unable to handle crash and throws this error:
[E][esp32-hal-i2c.c:1013] i2c_isr_handler_default(): unknown int=4

Co-authored-by: 0xDEADBEEF <0xde4dbeef@gmail.com>
2020-10-01 15:40:42 +03:00
1f4491f4ee Updated AzureIoT submodule. (#4322) 2020-10-01 15:38:56 +03:00
aa529eb5a0 Fix getString() freeze on empty responses (#4317) 2020-10-01 15:36:23 +03:00
a9cb7c6d6f mismatched parameter names. Fixes #4310 (#4313) 2020-10-01 15:35:40 +03:00
45d47e2be0 Fix duplicated pin constant (#4282)
G22 was defined twice, changing the first one to G21
2020-10-01 15:31:56 +03:00
99c94bb482 Set SD state to idle before unregister (reduces power) (#4272) 2020-10-01 15:31:16 +03:00
f98fc7ee9f fix hwSerial tx only flush (#4263) 2020-10-01 15:30:45 +03:00
0957776855 Reinit updater md5 related fields (#4260)
MD5 cleanup on begin
Typos
2020-10-01 15:29:58 +03:00
d93245d0f5 add m5stack-core2 board (#4255)
* add m5stack-core2 board
2020-10-01 15:28:40 +03:00
c917ed2504 shallow clone to make installation faster (#4246)
shallow clone (board and submodules) to make installation faster
2020-10-01 14:43:48 +03:00
ee88c42c3b Add support for following redirects in HTTPClient (#4240) 2020-10-01 14:41:54 +03:00
837cc3d271 Added SparkFun ESP32 Thing Plus board (#4224) 2020-10-01 14:39:39 +03:00
9b2ae12fb7 Added D pin numbers (#4220)
Source: https://wiki.dfrobot.com/FireBeetle_ESP32_IOT_Microcontroller(V3.0)__Supports_Wi-Fi_&_Bluetooth__SKU__DFR0478
2020-10-01 14:39:01 +03:00
86e221d087 Update HelloServer.ino (#4219)
Change name esp8266 for esp32 in welcome message
2020-10-01 14:38:26 +03:00
663effa00e Update Parsing.cpp (#4217)
* Update Parsing.cpp

When uploading TLS cert files the end of file "-----END CERTIFICATE-----" (or any kind of file with the sequence "CRLF--") is taken as posible end boundary. Then it is compared to the start boundary string. As it is expected, comparison turns to be false, and the whole end boundary string is put to _currentUpload->buf through _uploadWriteByte(). Here you have the problem: if you read boundary.length() bytes from HTTP request and you have some of the actual end boundary bytes in it, when you put all those bytes into _currentUpload->buf you are making a mistake. You will miss the actual end boundary string because some of those bytes were put in _currentUpload->buf.

* Update Parsing.cpp
2020-10-01 14:37:59 +03:00
6f237a8415 Fix ttgo twatch & tbeam board definition error (#4212) 2020-10-01 14:36:32 +03:00
c3c38a8eb5 Enable precompiled libraries (#4209)
The latest versions of Arduino IDE shifted the responsibility for precompiled libraries support to the core developers, which breaks precompiled library support in esp32 Arduino core. See https://github.com/arduino/ArduinoCore-avr/pull/52 for more details:

```
In this new version of the builder we are not doing any heuristics to find the right spot where the ldflags should be inserted (this was causing many bugs on its own); instead, we fully trust the core makers to add explicit support to precompiled libs.
```

This chage re-enables precompiled library support in the esp32 Arduino core.
2020-10-01 14:32:20 +03:00
8fcc914853 Added facility to invert the polarity of input UART bits. (#4200) 2020-10-01 13:58:48 +03:00
d03f8f1277 Update pins_arduino.h (#4190) 2020-10-01 13:54:01 +03:00
882b12c44e rmdir causes issues in SPIFFS. Fixes #4138, albeit not very cleanly (#4154)
SPIFFS causes crashes if you attempt to rmdir. Since there are no true directories in spiffs, this ought to be a noop. It looks like @me-no-dev worked around this by using unlink instead of rmdir, which works in fatfs and doesn't panic spiffs. This behavior is not universal. In order to get littlefs working, it would be good to get this back to conformity. Rather than digging deep into the upstream spiffs, I just check the mountpoint and noop if it is "/spiffs". So, if the user has changed the mountpoint, this will not work, but I think it's a pretty good tradeoff.
2020-10-01 13:52:24 +03:00
93d850f783 Fixed comment with correct FQDN (#4152) 2020-10-01 13:51:36 +03:00
4f48caca2c Set scan_duplicate in BLE scan params (#4126)
This value is uninitialised and as such can be a random (and invalid) value. It's needs to be set per the espressif documentation here:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_ble.html#_CPPv4N21esp_ble_scan_params_t14scan_duplicateE

This PR sets it to DUPLICATE_DISABLE. Chosen as this is needed to ensure all scan data is populated in the scan callback, per this comment in the IDF:

https://github.com/espressif/esp-idf/blob/master/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c#L3591

"//if scan duplicate is enabled, the adv packet without scan response is allowed to report to higher layer"

We **don't** want it to report to the higher layer (ie BLEScan.cpp) **unless** it has the active scan response.

Seems to resolve #3770 #3677 and possibly others.
2020-10-01 13:45:45 +03:00
80e9e42c3b Fix issue #3522 (WiFi does not restart after stopped) (#4114)
This commit fixes issue https://github.com/espressif/arduino-esp32/issues/3522 where WiFi service fails to start after a WiFi.disconnect(true) or a WiFi.mode(WIFI_OFF).
2020-09-30 15:34:10 +03:00
494061af26 WebServer: Fix OOB write (#4088)
Successful exploitation could lead to arbitrary code execution.

The bug can be reproduced by running the following in a browser:
```
const formData = new FormData();
for (let i = 0;i < 33;++i) { formData.append("foo", i.toString()); }
await fetch("http://esp.local", { method: 'POST', body: formData });
```
2020-09-30 15:28:28 +03:00
2fd3d042b2 Fix #4046 Details below: (#4086)
Informed by the discussion in the bug and the code in 'that other branch'
the fix was clear.  Just set a flag if we start handling a write, and
use that flag to guard the long write complete call.
2020-09-30 15:27:35 +03:00
b551310c37 Minor change but could confuse some (#4084) 2020-09-30 15:26:38 +03:00
f30edd040e Update CaptivePortal.ino (#4080)
* Update CaptivePortal.ino

Illegal SSID used for SoftAP

* Fixed ordering problem.  Now actually works
2020-09-30 15:26:15 +03:00
b7c5e502e7 Add static pin support (#4078) 2020-09-30 15:25:42 +03:00
fa8a1c38d5 fix #4071 (#4072)
SPIFFS File object evaluates as true even if the file could not be opened.
2020-09-30 15:24:59 +03:00
d56267bd8c Update GetChipID.ino (#4070)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-09-30 15:24:29 +03:00
1f6b0b35f8 Have BLECLient gattc event handlers verify conn_id (#4064)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-09-30 15:21:59 +03:00
342b9cf2d8 Fix handling of registerForNotify in BLERemoteCharacteristic.cpp (#4063) 2020-09-30 15:20:28 +03:00
11d071b1c8 Fix to allow more than one certificate to be loaded (espressif#3248). (#4056)
Co-authored-by: Mark Hale <mark.hale@physics.org>
2020-09-30 15:19:41 +03:00
f48d9016fd Update T_Watch board properties and add revision selection (#4025)
Co-authored-by: lewis he <lewisxhe@outlook.com>
2020-09-30 15:18:17 +03:00
a55265f74b Fix clockCyclesPerMicrosecond Change from fixed value to current value (#3993) 2020-09-30 15:16:20 +03:00
c1a7198e7d Don't change owner if take() doesnt succeed (#3987) 2020-09-30 15:15:47 +03:00
4d4a1fde36 Added HealthyPi 4 Board Support (#3985)
Co-authored-by: Ashwin <ashwin@circuitects.com>
2020-09-30 15:14:39 +03:00
d219e56872 Update pins_arduino.h (#3908)
Update in accordance with Firebeetle's official firebeetle32 pins_arduino.h. Without it, digital pins weren't definable, and analogue pins didnt line up.

Taken from http://download.dfrobot.top/FireBeetle/DFRobot_FireBeetle-ESP32-0.0.9.zip
2020-09-30 15:07:26 +03:00
19ccc479c3 WIFI_PS_MAX_MODEM feature requested #3896 (#3900) 2020-09-30 15:06:58 +03:00
c18d50cb91 Use esp_partition_* functions in Updater.cpp (#3898)
Background

The current implementation of Update() uses the spi_flash_* api to write and read from flash. These functions ignore the partition->encrypted flag and always write raw data to flash even if the partition is marked as encrypted.

Changes in this PR

Update() now uses the esp_partition_* api.
Wrapper functions for esp_partition_* added to ESP.cpp. This was done to maintain a consistent approach to the way the spi_flash_* functions were used. I note though that not all of the esp-idf functions are used are wrapped, for example esp_ota_get_next_update_partition() so it may be that these should not be added?
The current implementation of Update() changes the first (magic) byte of firmware to 0xFF on write, and then when the firmware is completely written changes it back to ESP_IMAGE_HEADER_MAGIC. This works without erasing the sector because flash bits can be changed from 1->0 (but not 0->1). If the flash is encrypted then the actual data written to flash will not be all ones, so this approach will not work. In addition, encrypted flash must be written in 16 byte blocks. So, instead of changing the first byte the changed code stashes the first 16 bytes, and starts writing at the 17th byte, leaving the first 16 bytes as 0xFF. Then, in _enablePartition() the stashed bytes can be successfully written.
Benefits

Whilst it's not possible to use encrypted flash directly from either the Arduino IDE or PIO it's reasonably straightforward to compile and flash a bootloader with the necessary support from a simple esp-idf project and then use ArduinoOTA for subsequent updates. This PR enables the use of this workflow until such time as encrypted flash is supported, and is a first (small) step toward adding support.
Regardless of the above, the esp_partition_* api is recommended over the api_flash_* api.
Application code should mostly use these esp_partition_* API functions instead of lower level spi_flash_* API functions. Partition table API functions do bounds checking and calculate correct offsets in flash, based on data stored in a partition table.
2020-09-30 15:06:19 +03:00
80418fadcf Fixes UART detach. Fixes #3878 (#3894)
* Fixes UART detach.  Fixes #3878

* 0 is not a good holder value for pins!

* 0 is not a good holder value for pins!
2020-09-30 15:04:18 +03:00
8b6d020352 added new board Logsens V1p1 (#3880)
* Added new board variant for Imbrios LogSens V1.1

Imbrios LogSens V1.1 new board variant

* added new board Imbrios LogSens V1.1

Added new board details: Imbrios LogSens V1.1
2020-09-30 15:01:51 +03:00
5197916983 Fix BLEClient disconnect bug (#3876)
By default the disconnect is broadcasted to every clients. So if you call disconnect on one connected client, they'll all be disconnected if we don't filter the event by conn_id.
2020-09-30 15:01:02 +03:00
7e9d42da68 ESP.getChipModel() and ESP.getChipCores() (#3847)
* ESP.getChipModel() returns model of the chip

* ESP.getChipCores() returns the core count.

* Example gives chip model, revision and core count.

* Read efuse for chipmodel

Co-authored-by: Martijn Scheepers <ms@SDNengineering.nl>
2020-09-30 14:57:36 +03:00
e34e0b45de Fixed bug where mutex would not be unlocked (#3837)
Fixed bug where uartResizeRxBuffer() did not unlock mutex if creation of queue failed.
2020-09-30 14:56:41 +03:00
ef2b54547e Fix issue #3833, data parsing of Eddystone TLM data frame (#3836)
* Fix issue #3833, data parsing of Eddystone TLM data frame    
Add Beacon scanner example to show usage of BLEEddystoneTLM class and  BLEEddystoneURL class     
Add EddystoneTLM beacon example    
Add EddystoneURL beacon example

* Fix buffer size for .toString()
2020-09-30 14:55:58 +03:00
9856f0cc28 Update RMTLoopback.ino (#3823)
BUGFIX: avoids assertion in xEventGroupWaitBits()
(/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/event_groups.c:350 (xEventGroupWaitBits)- assert failed!)
2020-09-30 14:52:22 +03:00
daa8c55667 add new board mpython (#3814) 2020-09-30 14:49:57 +03:00
af7ec4ead1 fix EEPROM class example (#3786) 2020-09-30 14:43:05 +03:00
9e65ed1af1 Process compiler.libraries.ldflags (#3783)
Add support for the v1.8.6 compiler.libraries.ldflags:

https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification

This fixes the issue reported here:

https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/BSEC-1-4-7-4-compilation-error-on-ESP32-1-0-3-rc1/td-p/9120
2020-09-30 14:42:04 +03:00
7a92f89d12 Set TLS cert options before calling connect on client, so verify works (#3774)
When connecting using transportTraits, the CA and client certificates are ignored after the initial _client->connect() is called. This is because on connect, WiFiClientSecure will call start_ssl_client with _CA_Cert and other cert options set to null unless setCACert, setCertificate etc. are called before connect. Running _transportTraits->verify after connect therefore does exactly nothing. It's easy to verify that this is the case by passing a CACert to HTTPClient with verbose logging enabled - the logs will say "WARNING: Use certificates for a more secure communication!" which is only present when both PSK and CA are null. This change fixes the issue.
2020-09-30 14:41:03 +03:00
5871ca9ce9 UpdateClass::printError now accepts the Print object (#3763) 2020-09-30 14:39:25 +03:00
0dfa5babc2 fix typo in WiFiMulti (#3737) 2020-09-30 14:37:21 +03:00
e4b2ce4e81 DNS resolving timeout change to prevent stack overlapping (#3731)
Real DNS resolving timeout used by lwip library is 14[s] (7[s] for DNS1 + 7[s] for DNS2). Function WiFiGenericClass::hostByName() has timeout set to lower value (only 4[s]), so callback function may be called after this low timeout and it may overlappe stack memory used now by other function.
Fixes #3722
2020-09-30 14:35:53 +03:00
7af4490fcc Update SPI.h 2020-09-30 14:34:37 +03:00
4204869ec9 Extend Print class for 64bit integers. (#3688)
* Extend Print class for 64bit integers.

modulo 32bit and 64bit tuned for code size.

* Fix 32bit long used in long long printNumber.
2020-09-30 14:31:36 +03:00
ab23e8a656 Greatly reduces error rate (half, or 0 zero errors, depends on in/out ranges) for round-trip mapping at the same performance. (#3655)
(Based on "improved_map" from ESP8266's Servo.cpp)
2020-09-30 14:28:51 +03:00
5999b7ba46 removed double delete of characteristics (#3521) 2020-09-30 14:25:31 +03:00
7b613c1238 Added documentation regarding delay() resolution in esp-idf component (#3014) 2020-09-30 14:17:53 +03:00
cee2359e33 Update pins_arduino.h (#4211)
fix some mistake
2020-09-28 10:24:06 +03:00
37a7fb3d6a Update PlatformIO CI script (#4307) 2020-08-31 18:06:34 +03:00
9d547a8a44 Provisioning fixes for: 1.Space 2.Provisioned (#4291) 2020-08-25 11:03:06 +03:00
1fd5cd79c5 Add OTA update feature
This sketch provide functionality for OTA firmware upgrade.
2020-08-25 11:01:58 +03:00
4d98cea085 Add Wire:setPins(sda, scl)
Fixes: https://github.com/espressif/arduino-esp32/issues/3779
2020-07-19 02:21:15 +03:00
b92c58d74b M5Stack's product offering includes various ESP32-based camera devices. (#4030)
They are all broadly similar, all being based on the ESP32-D0WD core, but have
some subtle differences between variants around PSRAM inclusion and camera pin
mappings.

The ESP32CAM "unit" product (SKU: U007) has no PSRAM and maps the
"Pixel Data 0" (Y2 GPIO/OV2640 D2) camera pin to IO17 rather than IO32 as is
the case with most other M5Stack ESP32 camera devices.

The ESP32CAM also requires the "hmirror" and "vflip" camera configuration
bits setting in order to capture a true image.

The relevant M5Stack pin configuration documentation can be found here:
https://docs.m5stack.com/#/en/unit/esp32cam?id=pinmap
2020-06-01 01:41:56 +03:00
35d9759fa6 Fix for issue 3974 m_connectedCount incorrectly decremented when no connection exists
There is no need to decrement if nothing was removed from removePeerDevice

Reference issue:
#3974
2020-06-01 01:35:01 +03:00
09bff5027d Add a new board of KITS for IoT education (#3703)
* Add 'KITS Edu ESP32' board definition

add 'KITS Edu ESP32' board definition

* Modify board name

the board name was modified.

* Change the board name

Finally, we decided the board name.

- 'KITS ESP32 EDU'

Co-authored-by: Hamson Park <hamson.park@koreaits.com>
Co-authored-by: Hamson Park <hspark3235@gmail.com>
2020-05-29 11:46:25 +03:00
79f77afc98 update M5Camera pins (#4021)
* change m5camera pins

* add M5Camera version B pins

* add M5Camera version B pins
2020-05-22 12:59:33 +03:00
594ee6d249 Update SD_MMC.cpp (#4020)
According to ESP-IDF API
dc14d027ce/docs/en/api-reference/peripherals/sdmmc_host.rst :

"To configure the bus width, set the width field of :cpp:class:`sdmmc_slot_config_t`. For example, to set 1-line mode:

sdmmc_slot_config_t slot = SDMMC_SLOT_CONFIG_DEFAULT();
slot.width = 1;
"
2020-05-22 11:07:40 +03:00
934841e236 Added missing wifi_provisioning dependency. (#4003)
Co-authored-by: Paul <Paul.Martinsen@NumberEightInnovation.com>
2020-05-22 10:30:21 +03:00
49b76649f1 HardwareSerial bugfix & improvement (#3713)
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-05-05 17:55:58 +03:00
5d9bb5cf50 Allow using custom linker scripts (#3735)
Co-authored-by: Ivan Kravets <me@ikravets.com>
2020-05-04 16:47:14 +03:00
c8215315ae Add M5Stack-ATOM Board (#3883)
* Add M5Stack-ATOM Board

* Add M5Stack-ATOM Board

* Add M5Stack-ATOM Board

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-04-23 13:39:31 +03:00
4d118b36a2 Minor modifications in provisioning (#3919) 2020-04-21 14:39:26 +03:00
2c9b648502 Add support of unified provisioning to Arduino
1. WiFiProv.ino sketch is added that allows arduino users to do provisioning via SoftAP or BLE. WiFi.beginProvision( ) API is designed for provisioning in Arduino.
2. In WiFiProv.h provisioning class is defined.
3. WiFiProv.cpp contains implementation for provisioning class.
4. README.md file is added which contains detail information for working.
2020-04-15 23:37:55 +03:00
5508689ea3 Update install-platformio-esp32.sh 2020-04-13 12:47:34 +03:00
0f772270fb add new board Handbit (#3807)
* add handbit

* add handbit pins_arduino

* Update boards.txt
2020-03-12 10:16:50 +02:00
13e02063d6 Move _STREAM_BOUNDARY before _STREAM_PART (#3720)
The boundary delimiter (_STREAM_BOUNDARY) needs to be send before the
body part (_STREAM_PART) too follow RFC2046. This caused ffplay/ffmpeg
to fail to open the MJPEG stream.
2020-02-14 11:03:38 +02:00
9b75c65fc7 Add Senses's WEIZEN board from Senses IoT platform (#3687)
* Add Senses's WEIZEN board from Senses IoT platform

* Add Senses's WEIZEN board (updated variant)
2020-01-29 17:08:14 +02:00
109ba7a3b4 Revert "std::shared_ptr Memory Leak (#3680)" (#3682)
This reverts commit b2c678877c.
2020-01-29 12:30:08 +02:00
b2c678877c std::shared_ptr Memory Leak (#3680)
* std::shared_ptr Memory Leak

clientSocketHande and _rxBuffer are std::shared_ptr, the stop() call was not correctly releasing them and the operator= had similar problems fix for #3679

* operator= second attempt

* operator= third time
2020-01-29 12:18:54 +02:00
ed220bd042 Minimize HardwareSerial Receive and Transmit delays (#3664)
* Minimize HardwareSerial Receive and Transmit delays

* Remove uartRxFifoToQueue from esp-hal-uart.h

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-01-27 00:38:06 +02:00
80f9f9aeec fix removeApbChangeCallback() error in spiStopBus() (#3675)
* fix removeApbChangeCallback() error in spiStopBus()

spiStartBus() was using spiStopBus() to init the hardware, one of spiStopBus() functions is to unregister the runtime CPU clock speed change callback. But, spiStartBus() only wanted to init the hardware.  This patch separates the hardware init into a standalone function spiInitBus() that both spiStartBus() and spiStopBus() call.

* Update esp32-hal-spi.c

capitalization problem
2020-01-27 00:20:19 +02:00
b50a1755c8 Use python3 in CI 2020-01-25 15:26:16 +02:00
bb0a194bb7 fix WiFiClient.connected() (#3654)
WiFiClient.connected() was hanging thinking there was still a connection when the remote had already closed. The one-liner in this patch addresses recv() returning 0 and errno==128. I couldn't find the corresponding errno for 128 but its caught by the case statement which includes EPIPE, ENOTCONN, ECONNRESET and ECONNABORTED so I assume its one of those. Broken pipe maybe?
```c
[D][WiFiClient.cpp:511] connected(): Disconnected: RES: 0, ERR: 128
```
EDIT: added comment to reflect that recv() can set errno when it returns 0.
2020-01-21 12:36:03 +02:00
ed59ae6482 Update README.md (#3653) 2020-01-21 12:35:05 +02:00
b4a9684a74 Fix SerialBT.flush (#3579)
* Fix flush

flush should not flush the read buffer, it should wait till all output is drained from the write buffer.

* Update BluetoothSerial.cpp

Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
2020-01-20 22:34:57 +02:00
1977370e6f IDF release/v3.3 (#3339)
* IDF release/v3.3 46b12a560

* fix build

* IDF release/v3.3 367c3c09c
2020-01-20 22:07:04 +02:00
307b1368dd Implement BTSerial onData to dynamically receive packets from SPP (#3649) 2020-01-20 19:43:52 +02:00
32d5654aa6 Implement rmtLoop to be able to continuously send pulses (#3650)
Number of pulses is limited to the reserved RMT memory for the channel. Very useful for PWM, Servo and other repeatable signals.
2020-01-20 19:43:13 +02:00
7637a739cc Fix recent commit d8b2098 (PR #3377) which includes esp_adc_cal component but does not update CMakeLists.txt (#3648) 2020-01-20 18:40:40 +02:00
cd85239252 Added file.close to examples (#3611) 2020-01-20 16:47:40 +02:00
ac9d04a400 Add BLEDevice::stopAdvertising() helper method to compliment startAdvertising(). (#3624) 2020-01-20 16:31:12 +02:00
2195109ecc Added the channel parameter to the scan fucntion in order to select which channel to scan. (#3638)
The default value is 0 (= all channels) to preserve backward compatibility.
2020-01-20 16:13:10 +02:00
8d938c849d Add HONEYLemon board (#3640)
* add board HONEYLemon
2020-01-20 16:12:02 +02:00
cb005fc8b5 Extend BLEDevice::setPower() to include powerType parameter. It's optional and set to ESP_BLE_PWR_TYPE_DEFAULT for compatibility. (#3623)
Extend BLEDevice::setPower() to include powerType parameter. It's optional and set to ESP_BLE_PWR_TYPE_DEFAULT for compatibility.
2020-01-20 16:09:02 +02:00
89351e3ade Update WiFiClient.cpp (#3608)
fixed the connected() function so that it only checks errno if recv returns a value of -1.

"in the even of an error, errno is set to indicate the error" --manpage

This fixes the ESP32 Webserver when dealing with a modern webserver with a slow SD card.
2020-01-20 16:08:17 +02:00
86de90fe24 Added partition and flash size menus for VintLabs boards (#3602)
add the partition and flash size menus for the VintLabs board definitions.
2020-01-20 16:07:53 +02:00
5960cd3e2a update coreESP32 boards.txt (#3569) 2020-01-20 16:06:55 +02:00
82e208c8c9 Fixed incorrect board name for TinyPICO - You can now use this to detect it's a TinyPICO at compile time.... (#3567)
#ifdef ARDUINO_TINYPICO
   // It's a TinyPICO!
#endif
2020-01-20 16:06:25 +02:00
e7c9813625 Added Piranha ESP-32 and Metro ESP-32 boards (#3542)
Added two boards from iarduino.ru based on ESP-32
2020-01-20 16:06:06 +02:00
dd78794311 Update CaptivePortal.ino (#3628)
Small change to insure wifi starts off and avoid crashing
2020-01-20 16:04:21 +02:00
0607d36734 HardwareSerial::write(const char*, ...) API compatibility to AVR, ESP8266, et al (#3585)
* API compatibility to AVR, ESP8266, et al

* Add non-blocking HardwareSerial::read(buffer, size) extension (ESP8266 portability)

* Refactor for fewer indirect calls.
2020-01-20 15:54:50 +02:00
6e77f7f3e5 Setting loging level to VERBOSE on Semaphore::take (#3545) 2020-01-20 15:50:19 +02:00
915d45de7d Defined BLE setAdvertisementType (#3535)
Currently we have no way to set BLE Advertisement Type.
We have an initial value of ADV_TYPE_IND and the member is private.

iBeacon should advertise with ADV_TYPE_NONCONN_IND.
esp-idf's example code specifies this value.

93a8603c54/examples/bluetooth/bluedroid/ble/ble_ibeacon/main/ibeacon_demo.c (L57)
2020-01-20 15:42:38 +02:00
lj
c2b37d95e0 Updated BLERemoteCharacteristic to exposre esp_gatt_auth_req_t parame… (#3531)
* Updated BLERemoteCharacteristic to exposre esp_gatt_auth_req_t parameter for readValue and writeValue.

* Updated BLERemoteCharacteristic/Descriptor to expose a setAuth method to allow tweaking the authentication request type for that remotecharacteristic/descriptor without the need to add auth on each read/write.
2020-01-20 15:40:13 +02:00
2f13a960ac Add WIFI_REASON_CONNECTION_FAIL in WiFiGeneric.cpp (#3529)
`WIFI_REASON_CONNECTION_FAIL` has been added to `wifi_err_reason_t` some time ago:  
cec3fca4ad/tools/sdk/include/esp32/esp_wifi_types.h (L95)

But it was still missing from `system_event_reasons` in `WiFiGeneric.cpp` sometimes causing panics here:  
cec3fca4ad/libraries/WiFi/src/WiFiGeneric.cpp (L348)
2020-01-20 15:38:58 +02:00
579e04be25 Cleanup SPI_Multiple_Buses (#3527)
* Utilize prepoc symbols for SPI pins
* Adjusts for GPIO pins when ALTERNATE_PINS is set
2020-01-20 15:37:47 +02:00
5443d7ca93 Add TTGO T Journal Camera module & improve commenting (#3515)
Added pinout for TTGO T Journal device and improved the intent of comments.
2020-01-20 15:33:38 +02:00
7b3c1dfd50 Fix inability to use all buffers in RMT (#3512)
With the >= used let's say you have four RMT inputs, each using 2 channels wide for their receive buffer. This is 4*2 = 8 buffers which is the number of hardware buffers (MAX_CHANNELS). But, for the fourth input the starting buffer will be 6 (this is correct, the buffers used for each input are 0-1, 2-3, 4-5, 6-7). But, 6+2 = 8 which  is MAX_CHANNELS. This is valid but the >= would match against it and abort. It is correct to only abort if the value i+j is only greater than MAX_CHANNELS. Thus, a simple one character fix. Delete the equals sign.
2020-01-20 15:31:44 +02:00
85ef51ffbc BLE: reception support multiple service data (#3502)
* BLE: reception support multiple service data

* fix prev commit, i not inicialized
2020-01-20 15:30:29 +02:00
36075257c2 WString explicit converters to reduce Flash size (#3497)
* WString explicit converters to reduce Flash size

This is a port from the same patch for ESP8266: https://github.com/esp8266/Arduino/pull/6759/files
2020-01-20 15:29:16 +02:00
7de1717640 Fix replacing of headers with overlapping names. Fixes issue #3483 (#3487)
If two headers with overlapping names are added while replace == true, like in:
```cpp
http.addHeader("api_token",  "pMXFOLpinQqajaRQJYMeWObg2XYmcX1");
http.addHeader("token", "1234");
```
then replacing went wrong. This is fixed with this PR.
2020-01-20 15:27:51 +02:00
8869d39d79 Created variant for LilyGo TTGO LoRa32-OLED V2 (#3479)
Hi,

I have added a variant for the LilyGo TTGO LoRa32-OLED V2, which is similar to the LilyGo TTGO LoRa32-OLED V1 but with a different pinout. This will be useful for PlatformIO users, specially because I am also adding the board there as well.

Cheers.
2020-01-20 15:24:19 +02:00
Bob
cfe8526ec8 Add Uri with support for regexUri and globUri (#3441)
* Add Uri with support for staticUri, regexUri and globUri

* Add newline to end of files

* Update example

* Suppress gcc warnings (unused params)
2020-01-20 15:21:01 +02:00
c09ec5bd3d Added MGBOT IOTIK 32A and IOTIK 32B boards (#3427) 2020-01-20 15:19:35 +02:00
d8b2098461 Use IDF's ADC Driver and Add analogReadMilliVolts (#3377) 2020-01-20 15:18:56 +02:00
3fc974f3aa bugfix(touchpad):swap touch8 and touch9 #3584 (#3620) 2020-01-09 08:11:40 +02:00
9ad860758c Fix Memory leak in addApbChangeCallback() (#3560)
* `ledcWriteTone()` added a `apbcallback()` evertime the tone value was non zero.  
* `addApbChangeCallback()` did not detect duplicate callbacks.
* changed the apbcallback list to a double link to support roll forward, roll back execution.  This made the sequences of clock change callback start with the newest registered -> to oldest on the `before` then oldest -> newest after the clock change.  This made the UART debug log output have minimal gibberish during the clock change.
* change how the UART callback handled the MUTEX because if any `apbchangeCallback()` executed a `log_x()` a deadlock would occur.

This fixes #3555
2019-12-30 21:35:29 +02:00
cec3fca4ad Fix BluetoothSerial crash when restart (#3471)
* Update esp32-hal-bt.c

BluetoothSerial crash when restart:  this is because the BT controller remains in state  ESP_BT_CONTROLLER_STATUS_INITED instead of state  ESP_BT_CONTROLLER_STATUS_IDLE after the end() method.
in file esp_bt.h it is specified

> @brief Enable BT controller.
>                Due to a known issue, you cannot call esp_bt_controller_enable() a second time
>                 to change the controller mode dynamically. To change controller mode, call
>                esp_bt_controller_disable() and then call esp_bt_controller_enable() with the new mode.

after **esp_bt_controller_disable()** the controller remains in state INITED so we do call the **esp_bt_controller_deinit()** function to put the controller into state IDLE.

i have modified the **esp32-hal-bt.c** file
line 57 and next
(i have insert the esp_bt_controller_deinit() function so the controller go into Idle state)
```c++
bool btStop(){
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_IDLE){
		log_i("bt stopped");
        return true;
    }
    if(esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_ENABLED){
		log_i("bt 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){
		log_i("inited");
		if (esp_bt_controller_deinit()) {
			log_e("BT deint failed");
			return false;
		}
		while (esp_bt_controller_get_status() == ESP_BT_CONTROLLER_STATUS_INITED);
        return true;
    }
    log_e("BT Stop failed");
    return false;
}
```

* Update esp32-hal-bt.c

remove while to avoid infinite loop
2019-11-11 18:31:09 +01:00
dac493fb92 SPI: Fix discarded-qalifiers warning when compiling with all warnings (#3458)
* SPI: Fix discarded-qalifiers warning when compiling with all warnings

This fixes an error introduced with changeset b847f41 which
tightened the use of const for read-only data. The helper
funtion __transferBytes also requires the const qualifier on
outgoing data. Without this change a warning is displayed
when compiling with the Arduino IDE set to display "All"
compiler warnings.

Tests:
 - Build an ESP32 SPI sketch that uses static const data to send
   to an SPI device using the SPI.transferBytes() API

* SPI:Ensure all local functions are marked static

This audits all functions in the esp32-hal-xpi.c module and
ensures that any functions entirely local to the module are
marked as static.

Tests:
 - Build with Arduino set to show all warnings and ensure none
   are displayed

* SPI: Remove unused local __spiTranslate24 function

This removes the __spiTranslate24() function which is unused.
2019-11-11 17:44:49 +01:00
bc3d11364f Fixed incorrect usage of xEventGroupWaitBits (#3446)
* Fixed incorrect usage of xEventGroupWaitBits

* Added parentheses and `!= 0`
2019-11-11 17:34:01 +01:00
f41beb92bf Fixed so configTime will not crash if tcpip is not initialized (#3470) 2019-11-11 15:50:56 +01:00
8c4ca5a235 Update BLE_client.ino (#3463)
fix typo
2019-11-11 15:49:34 +01:00
b3085d4a8b Add menu items Partition Scheme and Debug Level for node32s (#3455) 2019-11-11 15:47:26 +01:00
547c2d3346 Root CA of webserver has changed, minor changes (#3447) 2019-11-11 15:45:26 +01:00
7d2632c024 Implement Tx only Flush (#3433)
* add option to Flush() to only clear txQueue

Add the option to cause Flush() to just wait for tx data to clear the tx fifo and uart, leave the rx queue and rx fifo as is.

* support tx only flush()

* support tx only Flush()

* support txOnly for Flush()

* compatibility to Stream()

* compatibility for Stream()

* default value error

* default value error

* Update esp32-hal-uart.h

* Update esp32-hal-uart.c

* Update HardwareSerial.cpp

* sp

* correctly implement flushTxOnly()
2019-11-11 15:37:35 +01:00
e59355df71 Docs for lib builder (#3415)
* Docs for lib builder

* Typos and such
2019-11-11 15:30:52 +01:00
ec63d09e54 Fix WiFiGeneric event handler (#3412) 2019-11-11 14:24:50 +01:00
xk
188560e7f3 Some event log messages were off by one. (#3391)
This event name was missing in the list:
d5e2bb12ca/tools/sdk/include/esp32/esp_event_legacy.h (L43)

E.g., it was giving
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 24 - ETH_GOT_IP
When it should have been
[D][WiFiGeneric.cpp:337] _eventCallback(): Event: 24 - ETH_DISCONNECTED
2019-11-11 14:21:24 +01:00
91e095f5a7 Add an error message in case of invalid configured dependency mbedTLS. (#3364)
Especially if the user wants to use the library as component in IDF,
there are some pitfalls while doing make menuconfig. One is this missing
dependency which will now fail with a better error message with a hint to
the user how to fix it.

refs #2154 #3215
2019-10-17 09:48:36 +03:00
c8d8dc2265 Added partition size options for TinyPICO (#3358) 2019-10-15 01:32:40 +03:00
b847f41e24 SPI: Ensure all read-only data pointers are marked as const (#3356)
This changes all SPI functions that take data pointers which are
not modified so that the declaration is const. This allows them
to be used with const data (i.e. held in flash). No functional
changes are required.

The defnitions of spiWrite() and spiTransferBytes()  in
esp-hal-spi.h/c have been updated to be consistent.

Tests:
 - Build a simple sketch using SPI.writePattern() and
   SPI.transferBytes()  which uses const data and verify that the
   attached device functions as expected.
2019-10-14 20:39:27 +03:00
611ba8ea8a Update README.md (#3353) 2019-10-14 20:38:04 +03:00
0cab2483e6 Added a description README.md for libraries (#3349) 2019-10-14 20:37:09 +03:00
Luc
79e4339582 Remove warnings if no debug enabled (#3334) 2019-10-08 10:35:42 +03:00
a35035f827 fix authrization problem (#3329)
I compiled the sample "WebServer -> HttpAdvancedAuth". But the right username and password can not login in. I found the file "Webserver.h" may be have some problem. So I fix it. Please check it.
2019-10-08 10:34:36 +03:00
9ef3e2d2a6 Allow sketches to have custom partitions (#3328)
Add a file named `partitions.csv` to your sketch folder and define the partitions inside. In order to not get `Sketch too big`, please select appropriate partition scheme from the board menu
2019-10-07 02:07:15 +03:00
0cdfb0b193 Add support for WiFi long range mode (#3190)
* Add support for WiFi long range mode

* Update WiFiGeneric.cpp
2019-10-06 17:43:15 +03:00
e50613622e Fix typo in SPIFFS and FFAT examples (#3322)
* fix typo in SPIFFS example

* fix typo in FFAT example
2019-10-06 17:29:28 +03:00
24b277ad92 Add readFloat to BLE (#3321)
* Add readFloat

* Add readFloat to BLE
2019-10-06 17:28:53 +03:00
c2b3f2d6af Make yield() overridable (#2991) 2019-10-04 12:49:39 +03:00
8fb8e7d060 CI can be used on windows desktop with msys 2019-10-02 20:03:43 +03:00
048b26547a Update boards_manager.md 2019-10-02 16:06:15 +03:00
b10ed77aaf Update boards_manager.md 2019-10-02 15:58:58 +03:00
1961 changed files with 8593 additions and 399540 deletions

View File

@ -15,9 +15,9 @@ git submodule update --init --recursive
REPO_SRCS=`find cores/esp32/ libraries/ -name 'examples' -prune -o -name '*.c' -print -o -name '*.cpp' -print | sort`
# find all source files named in CMakeLists.txt COMPONENT_SRCS
CMAKE_SRCS=`cmake --trace-expand -C CMakeLists.txt 2>&1 | grep COMPONENT_SRCS | sed 's/.\+COMPONENT_SRCS //' | sed 's/ )//' | tr ' ;' '\n' | sort`
CMAKE_SRCS=`cmake --trace-expand -C CMakeLists.txt 2>&1 | grep set\(srcs | cut -d'(' -f3 | sed 's/ )//' | sed 's/srcs //' | tr ' ;' '\n' | sort`
if ! diff -u0 --label "Repo Files" --label "COMPONENT_SRCS" <(echo "$REPO_SRCS") <(echo "$CMAKE_SRCS"); then
if ! diff -u0 --label "Repo Files" --label "srcs" <(echo "$REPO_SRCS") <(echo "$CMAKE_SRCS"); then
echo "Source files in repo (-) and source files in CMakeLists.txt (+) don't match"
echo "Edit CMakeLists.txt as appropriate to add/remove source files from COMPONENT_SRCS"
exit 1

View File

@ -23,9 +23,9 @@ if [ ! -d "$ARDUINO_ESP32_PATH" ]; then
git clone https://github.com/espressif/arduino-esp32.git esp32 > /dev/null 2>&1
fi
echo "Updating Submodules ..."
#echo "Updating Submodules ..."
cd esp32
git submodule update --init --recursive > /dev/null 2>&1
#git submodule update --init --recursive > /dev/null 2>&1
echo "Installing Platform Tools ..."
cd tools && python get.py

View File

@ -40,21 +40,30 @@ ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
if [ "$OS_IS_MACOS" == "1" ]; then
export ARDUINO_IDE_PATH="/Applications/Arduino.app/Contents/Java"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
elif [ "$OS_IS_WINDOWS" == "1" ]; then
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Documents/Arduino"
else
export ARDUINO_IDE_PATH="$HOME/arduino_ide"
export ARDUINO_USR_PATH="$HOME/Arduino"
fi
# Updated as of Nov 3rd 2020
ARDUINO_IDE_URL="https://github.com/espressif/arduino-esp32/releases/download/1.0.4/arduino-nightly-"
# Currently not working
#ARDUINO_IDE_URL="https://www.arduino.cc/download.php?f=/arduino-nightly-"
if [ ! -d "$ARDUINO_IDE_PATH" ]; then
echo "Installing Arduino IDE on $OS_NAME ..."
echo "Downloading 'arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
echo "Downloading '$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT' to 'arduino.$ARCHIVE_FORMAT' ..."
if [ "$OS_IS_LINUX" == "1" ]; then
wget -O "arduino.$ARCHIVE_FORMAT" "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
wget -O "arduino.$ARCHIVE_FORMAT" "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
tar xf "arduino.$ARCHIVE_FORMAT" > /dev/null
mv arduino-nightly "$ARDUINO_IDE_PATH"
else
curl -o "arduino.$ARCHIVE_FORMAT" -L "https://www.arduino.cc/download.php?f=/arduino-nightly-$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
curl -o "arduino.$ARCHIVE_FORMAT" -L "$ARDUINO_IDE_URL$OS_NAME.$ARCHIVE_FORMAT" > /dev/null 2>&1
echo "Extracting 'arduino.$ARCHIVE_FORMAT' ..."
unzip "arduino.$ARCHIVE_FORMAT" > /dev/null
if [ "$OS_IS_MACOS" == "1" ]; then
@ -107,9 +116,10 @@ function build_sketch(){ # build_sketch <fqbn> <path-to-ino> [extra-options]
$win_opts $xtra_opts "$sketch"
}
function count_sketches() # count_sketches <examples-path>
function count_sketches() # count_sketches <examples-path> <target-mcu>
{
local examples="$1"
local target="$2"
rm -rf sketches.txt
if [ ! -d "$examples" ]; then
touch sketches.txt
@ -124,7 +134,7 @@ function count_sketches() # count_sketches <examples-path>
if [[ "${sketchdirname}.ino" != "$sketchname" ]]; then
continue
fi;
if [[ -f "$sketchdir/.test.skip" ]]; then
if [[ -f "$sketchdir/.skip.$target" ]]; then
continue
fi
echo $sketch >> sketches.txt
@ -133,24 +143,25 @@ function count_sketches() # count_sketches <examples-path>
return $sketchnum
}
function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total-chunks> [extra-options]
function build_sketches() # build_sketches <fqbn> <target-mcu> <examples-path> <chunk> <total-chunks> [extra-options]
{
local fqbn=$1
local examples=$2
local chunk_idex=$3
local chunks_num=$4
local xtra_opts=$5
local target="$2"
local examples=$3
local chunk_idex=$4
local chunks_num=$5
local xtra_opts=$6
if [ "$#" -lt 2 ]; then
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_sketches <fqbn> <examples-path> [<chunk> <total-chunks>] [extra-options]"
echo "USAGE: build_sketches <fqbn> <target-mcu <examples-path> [<chunk> <total-chunks>] [extra-options]"
return 1
fi
if [ "$#" -lt 4 ]; then
if [ "$#" -lt 5 ]; then
chunk_idex="0"
chunks_num="1"
xtra_opts=$3
xtra_opts=$4
fi
if [ "$chunks_num" -le 0 ]; then
@ -199,7 +210,7 @@ function build_sketches() # build_sketches <fqbn> <examples-path> <chunk> <total
local sketchdirname=$(basename $sketchdir)
local sketchname=$(basename $sketch)
if [ "${sketchdirname}.ino" != "$sketchname" ] \
|| [ -f "$sketchdir/.test.skip" ]; then
|| [ -f "$sketchdir/.skip.$target" ]; then
continue
fi
sketchnum=$(($sketchnum + 1))

View File

@ -1,6 +1,7 @@
#!/bin/bash
export PLATFORMIO_ESP32_PATH="$HOME/.platformio/packages/framework-arduinoespressif32"
PLATFORMIO_ESP32_URL="https://github.com/platformio/platform-espressif32.git#feature/idf-v4.0"
echo "Installing Python Wheel ..."
pip install wheel > /dev/null 2>&1
@ -9,40 +10,36 @@ echo "Installing PlatformIO ..."
pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1
echo "Installing Platform ESP32 ..."
python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1
python -m platformio platform install $PLATFORMIO_ESP32_URL > /dev/null 2>&1
echo "Replacing the framework version ..."
if [[ "$OSTYPE" == "darwin"* ]]; then
sed 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json" > "platform.json"
mv -f "platform.json" "$HOME/.platformio/platforms/espressif32/platform.json"
else
sed -i 's/https:\/\/github\.com\/espressif\/arduino-esp32\.git/*/' "$HOME/.platformio/platforms/espressif32/platform.json"
fi
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..."
ln -s $GITHUB_WORKSPACE "$PLATFORMIO_ESP32_PATH"
else
echo "Cloning Core Repository ..."
git clone https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
git clone --recursive https://github.com/espressif/arduino-esp32.git "$PLATFORMIO_ESP32_PATH" > /dev/null 2>&1
fi
echo "PlatformIO for ESP32 has been installed"
echo ""
function build_pio_sketch(){ # build_pio_sketch <board> <path-to-ino>
if [ "$#" -lt 2 ]; then
function build_pio_sketch(){ # build_pio_sketch <board> <options> <path-to-ino>
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketch <board> <path-to-ino>"
echo "USAGE: build_pio_sketch <board> <options> <path-to-ino>"
return 1
fi
local board="$1"
local sketch="$2"
local options="$2"
local sketch="$3"
local sketch_dir=$(dirname "$sketch")
echo ""
echo "Compiling '"$(basename "$sketch")"' ..."
python -m platformio ci --board "$board" "$sketch_dir" --project-option="board_build.partitions = huge_app.csv"
python -m platformio ci --board "$board" "$sketch_dir" --project-option="$options"
}
function count_sketches() # count_sketches <examples-path>
@ -71,20 +68,21 @@ function count_sketches() # count_sketches <examples-path>
return $sketchnum
}
function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chunk> <total-chunks>
function build_pio_sketches() # build_pio_sketches <board> <options> <examples-path> <chunk> <total-chunks>
{
if [ "$#" -lt 2 ]; then
if [ "$#" -lt 3 ]; then
echo "ERROR: Illegal number of parameters"
echo "USAGE: build_pio_sketches <board> <examples-path> [<chunk> <total-chunks>]"
echo "USAGE: build_pio_sketches <board> <options> <examples-path> [<chunk> <total-chunks>]"
return 1
fi
local board=$1
local examples=$2
local chunk_idex=$3
local chunks_num=$4
local options="$2"
local examples=$3
local chunk_idex=$4
local chunks_num=$5
if [ "$#" -lt 4 ]; then
if [ "$#" -lt 5 ]; then
chunk_idex="0"
chunks_num="1"
fi
@ -143,7 +141,7 @@ function build_pio_sketches() # build_pio_sketches <board> <examples-path> <chun
|| [ "$sketchnum" -gt "$end_index" ]; then
continue
fi
build_pio_sketch "$board" "$sketch"
build_pio_sketch "$board" "$options" "$sketch"
local result=$?
if [ $result -ne 0 ]; then
return $result

View File

@ -30,42 +30,62 @@ elif [ "$CHUNK_INDEX" -eq "$CHUNKS_CNT" ]; then
BUILD_PIO=1
fi
echo "Updating submodules ..."
git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
#echo "Updating submodules ..."
#git -C "$GITHUB_WORKSPACE" submodule update --init --recursive > /dev/null 2>&1
if [ "$BUILD_PIO" -eq 0 ]; then
# ArduinoIDE Test
# ArduinoIDE ESP32 Test
TARGET="esp32"
FQBN="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
source ./.github/scripts/install-arduino-ide.sh
source ./.github/scripts/install-arduino-core-esp32.sh
if [ "$OS_IS_WINDOWS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
elif [ "$OS_IS_MACOS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
else
# CMake Test
if [ "$CHUNK_INDEX" -eq 0 ]; then
bash "$ARDUINO_ESP32_PATH/.github/scripts/check-cmakelists.sh"
fi
build_sketches "$FQBN" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi
# ArduinoIDE ESP32S2 Test
TARGET="esp32s2"
FQBN="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
if [ "$OS_IS_WINDOWS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
elif [ "$OS_IS_MACOS" == "1" ]; then
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_sketch "$FQBN" "$ARDUINO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
else
build_sketches "$FQBN" "$TARGET" "$ARDUINO_ESP32_PATH/libraries" "$CHUNK_INDEX" "$CHUNKS_CNT"
fi
else
# PlatformIO Test
source ./.github/scripts/install-platformio-esp32.sh
# PlatformIO ESP32 Test
BOARD="esp32dev"
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/AzureIoT/examples/GetStarted/GetStarted.ino" && \
build_pio_sketch "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
#build_pio_sketches esp32dev "$PLATFORMIO_ESP32_PATH/libraries"
OPTIONS="board_build.partitions = huge_app.csv"
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BluetoothSerial/examples/SerialToSerialBT/SerialToSerialBT.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/BLE/examples/BLE_server/BLE_server.ino" && \
build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/ESP32/examples/Camera/CameraWebServer/CameraWebServer.ino"
# PlatformIO ESP32 Test
# OPTIONS="board_build.mcu = esp32s2"
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient/WiFiClient.ino" && \
# build_pio_sketch "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries/WiFiClientSecure/examples/WiFiClientSecure/WiFiClientSecure.ino"
python -m platformio ci --board "$BOARD" "$PLATFORMIO_ESP32_PATH/libraries/WiFi/examples/WiFiClient" --project-option="board_build.mcu = esp32s2" --project-option="board_build.partitions = huge_app.csv"
#build_pio_sketches "$BOARD" "$OPTIONS" "$PLATFORMIO_ESP32_PATH/libraries"
fi

View File

@ -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`

View File

@ -19,6 +19,9 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh ${{ matrix.chunk }} 15
@ -32,6 +35,9 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh
@ -45,5 +51,8 @@ jobs:
steps:
- uses: actions/checkout@v1
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Build Sketches
run: bash ./.github/scripts/on-push.sh 1 1 #equal and non-zero to trigger PIO

View File

@ -11,6 +11,9 @@ jobs:
steps:
- uses: actions/checkout@master
- uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Build Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5
.gitignore vendored
View File

@ -1,4 +1,5 @@
tools/xtensa-esp32-elf
tools/xtensa-esp32s2-elf
tools/dist
tools/esptool
tools/esptool.exe
@ -12,3 +13,7 @@ tools/mkspiffs/mkspiffs.exe
.vs/
__vm/
*.vcxproj*
.vscode/
platform.sloeber.txt
boards.sloeber.txt
tools/mklittlefs

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "libraries/AzureIoT"]
path = libraries/AzureIoT
url = https://github.com/VSChina/ESP32_AzureIoT_Arduino

View File

@ -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,204 +10,40 @@ 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/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/WiFiScan.cpp
libraries/WiFi/src/WiFiServer.cpp
libraries/WiFi/src/WiFiSTA.cpp
libraries/WiFi/src/WiFiUdp.cpp
libraries/Wire/src/Wire.cpp
)
set(AZURE_SRCS
libraries/AzureIoT/src/az_iot/azureiotcerts.c
libraries/AzureIoT/src/az_iot/c-utility/pal/agenttime.c
libraries/AzureIoT/src/az_iot/c-utility/pal/dns_async.c
libraries/AzureIoT/src/az_iot/c-utility/pal/freertos/lock.c
libraries/AzureIoT/src/az_iot/c-utility/pal/freertos/threadapi.c
libraries/AzureIoT/src/az_iot/c-utility/pal/freertos/tickcounter.c
libraries/AzureIoT/src/az_iot/c-utility/pal/lwip/sntp_lwip.c
libraries/AzureIoT/src/az_iot/c-utility/pal/socket_async.c
libraries/AzureIoT/src/az_iot/c-utility/pal/src/platform_openssl_compact.c
libraries/AzureIoT/src/az_iot/c-utility/pal/src/tlsio_openssl_compact.c
libraries/AzureIoT/src/az_iot/c-utility/pal/tlsio_options.c
libraries/AzureIoT/src/az_iot/c-utility/src/base64.c
libraries/AzureIoT/src/az_iot/c-utility/src/buffer.c
libraries/AzureIoT/src/az_iot/c-utility/src/connection_string_parser.c
libraries/AzureIoT/src/az_iot/c-utility/src/consolelogger.c
libraries/AzureIoT/src/az_iot/c-utility/src/constbuffer.c
libraries/AzureIoT/src/az_iot/c-utility/src/constmap.c
libraries/AzureIoT/src/az_iot/c-utility/src/crt_abstractions.c
libraries/AzureIoT/src/az_iot/c-utility/src/doublylinkedlist.c
libraries/AzureIoT/src/az_iot/c-utility/src/gballoc.c
libraries/AzureIoT/src/az_iot/c-utility/src/gb_stdio.c
libraries/AzureIoT/src/az_iot/c-utility/src/gb_time.c
libraries/AzureIoT/src/az_iot/c-utility/src/hmac.c
libraries/AzureIoT/src/az_iot/c-utility/src/hmacsha256.c
libraries/AzureIoT/src/az_iot/c-utility/src/httpapiex.c
libraries/AzureIoT/src/az_iot/c-utility/src/httpapiexsas.c
libraries/AzureIoT/src/az_iot/c-utility/src/httpheaders.c
libraries/AzureIoT/src/az_iot/c-utility/src/http_proxy_io.c
libraries/AzureIoT/src/az_iot/c-utility/src/map.c
libraries/AzureIoT/src/az_iot/c-utility/src/optionhandler.c
libraries/AzureIoT/src/az_iot/c-utility/src/sastoken.c
libraries/AzureIoT/src/az_iot/c-utility/src/sha1.c
libraries/AzureIoT/src/az_iot/c-utility/src/sha224.c
libraries/AzureIoT/src/az_iot/c-utility/src/sha384-512.c
libraries/AzureIoT/src/az_iot/c-utility/src/singlylinkedlist.c
libraries/AzureIoT/src/az_iot/c-utility/src/strings.c
libraries/AzureIoT/src/az_iot/c-utility/src/string_tokenizer.c
libraries/AzureIoT/src/az_iot/c-utility/src/urlencode.c
libraries/AzureIoT/src/az_iot/c-utility/src/usha.c
libraries/AzureIoT/src/az_iot/c-utility/src/vector.c
libraries/AzureIoT/src/az_iot/c-utility/src/xio.c
libraries/AzureIoT/src/az_iot/c-utility/src/xlogging.c
libraries/AzureIoT/src/az_iot/iothub_client/src/blob.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothub_client_authorization.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothub_client.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothub_client_ll.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothub_client_retry_control.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothub_message.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothubtransport.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothubtransportmqtt.c
libraries/AzureIoT/src/az_iot/iothub_client/src/iothubtransport_mqtt_common.c
libraries/AzureIoT/src/az_iot/iothub_client/src/version.c
libraries/AzureIoT/src/az_iot/umqtt/src/mqtt_client.c
libraries/AzureIoT/src/az_iot/umqtt/src/mqtt_codec.c
libraries/AzureIoT/src/az_iot/umqtt/src/mqtt_message.c
libraries/AzureIoT/src/AzureIotHub.cpp
libraries/AzureIoT/src/Esp32MQTTClient.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(COMPONENT_SRCS ${CORE_SRCS} ${LIBRARY_SRCS} ${AZURE_SRCS} ${BLE_SRCS})
set(COMPONENT_ADD_INCLUDEDIRS
set(includedirs
variants/esp32/
cores/esp32/
libraries/ArduinoOTA/src
libraries/AsyncUDP/src
libraries/AzureIoT/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/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(COMPONENT_PRIV_INCLUDEDIRS cores/esp32/libb64)
set(srcs ${CORE_SRCS} ${LIBRARY_SRCS} ${BLE_SRCS})
set(requires spi_flash mbedtls esp_adc_cal wifi_provisioning)
set(priv_requires nvs_flash bootloader_support tinyusb espcpputils fmt)
set(COMPONENT_REQUIRES spi_flash mbedtls mdns ethernet)
set(COMPONENT_PRIV_REQUIRES fatfs nvs_flash app_update spiffs bootloader_support openssl bt)
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
register_component()
set_source_files_properties(libraries/AzureIoT/src/az_iot/iothub_client/src/iothubtransport_mqtt_common.c
PROPERTIES COMPILE_FLAGS
-Wno-maybe-uninitialized
)
if(IDF_TARGET STREQUAL "esp32")
target_compile_options(${COMPONENT_TARGET} PUBLIC -DARDUINO=10812 -DARDUINO_ESP32_DEV -DARDUINO_ARCH_ESP32 -DARDUINO_BOARD="ESP32_DEV" -DARDUINO_VARIANT="esp32" -DESP32)
endif()
if(IDF_TARGET STREQUAL "esp32s2")
target_compile_options(${COMPONENT_TARGET} PUBLIC -DARDUINO=10812 -DARDUINO_ESP32S2_DEV -DARDUINO_ARCH_ESP32 -DARDUINO_BOARD="ESP32S2_DEV" -DARDUINO_VARIANT="esp32s2" -DESP32)
endif()

View File

@ -5,83 +5,19 @@ config ENABLE_ARDUINO_DEPENDS
select LWIP_SO_RCVBUF
select ETHERNET
select WIFI_ENABLED
select ESP32_PHY_CALIBRATION_AND_DATA_STORAGE
select ESP32_PHY_CALIBRATION_AND_DATA_STORAGE if IDF_TARGET_ESP32
select MEMMAP_SMP
default "y"
config AUTOSTART_ARDUINO
bool "Autostart Arduino setup and loop on boot"
config ARDUINO_ISR_IRAM
bool "Run interrupts in IRAM"
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
Enabling this option will Attach all interrupts with the IRAm flag.
It will also make some HAL function, like, digitalRead/Write and more
be loaded into IRAM for access inside ISRs.
Beware that this is a very dangerous setting. Enable it only if you
are fully aware of the consequences.
config DISABLE_HAL_LOCKS
bool "Disable mutex locks for HAL"
@ -142,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
@ -289,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

View File

@ -11,9 +11,11 @@
- [ESP32Dev Board PINMAP](#esp32dev-board-pinmap)
### Development Status
[Latest stable release ![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg?style=plastic) ![Release Date](https://img.shields.io/github/release-date/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) ![Downloads](https://img.shields.io/github/downloads/espressif/arduino-esp32/latest/total.svg?style=plastic)
[Latest development release ![Development Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic) ![Development Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) ![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)
Latest Stable Release [![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) [![Release Date](https://img.shields.io/github/release-date/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) [![Downloads](https://img.shields.io/github/downloads/espressif/arduino-esp32/latest/total.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/)
Latest Development Release [![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) [![Release Date](https://img.shields.io/github/release-date-pre/espressif/arduino-esp32.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/) [![Downloads](https://img.shields.io/github/downloads-pre/espressif/arduino-esp32/latest/total.svg?style=plastic)](https://github.com/espressif/arduino-esp32/releases/latest/)
### Installation Instructions
- Using Arduino IDE Boards Manager (preferred)
@ -36,12 +38,12 @@ You can use [EspExceptionDecoder](https://github.com/me-no-dev/EspExceptionDecod
### Issue/Bug report template
Before reporting an issue, make sure you've searched for similar one that was already created. Also make sure to go through all the issues labelled as [for reference](https://github.com/espressif/arduino-esp32/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3A%22for%20reference%22%20).
Finally, if you're sure no one else had the issue, follow the [ISSUE_TEMPLATE](docs/ISSUE_TEMPLATE.md) while reporting any issue.
Finally, if you are sure no one else had the issue, follow the [ISSUE_TEMPLATE](docs/ISSUE_TEMPLATE.md) while reporting any issue.
### ESP32Dev Board PINMAP
![Pin Functions](docs/esp32_pinmap.png)
### Hint
### Tip
Sometimes to program ESP32 via serial you must keep GPIO0 LOW during the programming process

2868
boards.txt

File diff suppressed because it is too large Load Diff

View File

@ -1,187 +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;
void setup(void);
void loop(void);
long random(long, long);
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_ */

View File

@ -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

View File

@ -1,318 +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 "rom/spi_flash.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>
/**
* 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)
{
multi_heap_info_t info;
heap_caps_get_info(&info, MALLOC_CAP_SPIRAM);
return info.total_free_bytes + info.total_allocated_bytes;
}
uint32_t EspClass::getFreePsram(void)
{
return heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
}
uint32_t EspClass::getMinFreePsram(void)
{
return heap_caps_get_minimum_free_size(MALLOC_CAP_SPIRAM);
}
uint32_t EspClass::getMaxAllocPsram(void)
{
return heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM);
}
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;
}

View File

@ -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 IRAM_ATTR EspClass::getCycleCount()
{
uint32_t ccount;
__asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount));
return ccount;
}
extern EspClass ESP;
#endif //ESP_H

View File

@ -6,7 +6,7 @@
*/
#include "FunctionalInterrupt.h"
#include "Arduino.h"
#include "esp32-hal.h"
typedef void (*voidFuncPtr)(void);
typedef void (*voidFuncPtrArg)(void*);
@ -16,7 +16,7 @@ extern "C"
extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional);
}
void IRAM_ATTR interruptFunctional(void* arg)
void ARDUINO_ISR_ATTR interruptFunctional(void* arg)
{
InterruptArgStructure* localArg = (InterruptArgStructure*)arg;
if (localArg->interruptFunction)

View File

@ -1,158 +0,0 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "pins_arduino.h"
#include "HardwareSerial.h"
#ifndef RX1
#define RX1 9
#endif
#ifndef TX1
#define TX1 10
#endif
#ifndef RX2
#define RX2 16
#endif
#ifndef TX2
#define TX2 17
#endif
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
HardwareSerial Serial(0);
HardwareSerial Serial1(1);
HardwareSerial Serial2(2);
#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) {
rxPin = 3;
txPin = 1;
}
if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
rxPin = RX1;
txPin = TX1;
}
if(_uart_nr == 2 && rxPin < 0 && txPin < 0) {
rxPin = RX2;
txPin = TX2;
}
_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(0);
}
}
}
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;
}
void HardwareSerial::flush()
{
uartFlush(_uart);
}
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;
}

View File

@ -1,106 +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);
void flush(void);
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t 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;
};
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
extern HardwareSerial Serial;
extern HardwareSerial Serial1;
extern HardwareSerial Serial2;
#endif
#endif

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -1,63 +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 "rom/md5_hash.h"
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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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() {
}

View File

@ -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_ */

338
cores/esp32/USB.cpp Normal file
View File

@ -0,0 +1,338 @@
// Copyright 2015-2020 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 "esp32-hal-tinyusb.h"
#include "USB.h"
#if CONFIG_USB_ENABLED
#ifndef USB_VID
#define USB_VID USB_ESPRESSIF_VID
#endif
#ifndef USB_PID
#define USB_PID 0x0002
#endif
#ifndef USB_MANUFACTURER
#define USB_MANUFACTURER "Espressif Systems"
#endif
#ifndef USB_PRODUCT
#define USB_PRODUCT ARDUINO_BOARD
#endif
#ifndef USB_SERIAL
#define USB_SERIAL "0"
#endif
extern "C" {
#include "tinyusb.h"
}
#if CFG_TUD_DFU_RT
static uint16_t load_dfu_descriptor(uint8_t * dst, uint8_t * itf)
{
#define DFU_ATTR_CAN_DOWNLOAD 1
#define DFU_ATTR_CAN_UPLOAD 2
#define DFU_ATTR_MANIFESTATION_TOLERANT 4
#define DFU_ATTR_WILL_DETACH 8
#define DFU_ATTRS (DFU_ATTR_CAN_DOWNLOAD | DFU_ATTR_CAN_UPLOAD | DFU_ATTR_MANIFESTATION_TOLERANT)
uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB DFU_RT");
uint8_t descriptor[TUD_DFU_RT_DESC_LEN] = {
// Interface number, string index, attributes, detach timeout, transfer size */
TUD_DFU_RT_DESCRIPTOR(*itf, str_index, DFU_ATTRS, 700, 64)
};
*itf+=1;
memcpy(dst, descriptor, TUD_DFU_RT_DESC_LEN);
return TUD_DFU_RT_DESC_LEN;
}
// Invoked on DFU_DETACH request to reboot to the bootloader
void tud_dfu_rt_reboot_to_dfu(void)
{
usb_persist_restart(RESTART_BOOTLOADER_DFU);
}
#endif /* CFG_TUD_DFU_RT */
ESP_EVENT_DEFINE_BASE(ARDUINO_USB_EVENTS);
static esp_event_loop_handle_t arduino_usb_event_loop_handle = NULL;
esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait){
if(arduino_usb_event_loop_handle == NULL){
return ESP_FAIL;
}
return esp_event_post_to(arduino_usb_event_loop_handle, event_base, event_id, event_data, event_data_size, ticks_to_wait);
}
esp_err_t arduino_usb_event_handler_register_with(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler, void *event_handler_arg){
if(arduino_usb_event_loop_handle == NULL){
return ESP_FAIL;
}
return esp_event_handler_register_with(arduino_usb_event_loop_handle, event_base, event_id, event_handler, event_handler_arg);
}
static bool tinyusb_device_mounted = false;
static bool tinyusb_device_suspended = false;
// Invoked when device is mounted (configured)
void tud_mount_cb(void){
tinyusb_device_mounted = true;
arduino_usb_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STARTED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
}
// Invoked when device is unmounted
void tud_umount_cb(void){
tinyusb_device_mounted = false;
arduino_usb_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
}
// Invoked when usb bus is suspended
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
void tud_suspend_cb(bool remote_wakeup_en){
tinyusb_device_suspended = true;
arduino_usb_event_data_t p = {0};
p.suspend.remote_wakeup_en = remote_wakeup_en;
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_SUSPEND_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
}
// Invoked when usb bus is resumed
void tud_resume_cb(void){
tinyusb_device_suspended = false;
arduino_usb_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_EVENTS, ARDUINO_USB_RESUME_EVENT, &p, sizeof(arduino_usb_event_data_t), portMAX_DELAY);
}
ESPUSB::ESPUSB(size_t task_stack_size, uint8_t event_task_priority)
:vid(USB_VID)
,pid(USB_PID)
,product_name(USB_PRODUCT)
,manufacturer_name(USB_MANUFACTURER)
,serial_number(USB_SERIAL)
,fw_version(0x0100)
,usb_version(0x0200)// at least 2.1 or 3.x for BOS & webUSB
,usb_class(TUSB_CLASS_MISC)
,usb_subclass(MISC_SUBCLASS_COMMON)
,usb_protocol(MISC_PROTOCOL_IAD)
,usb_attributes(TUSB_DESC_CONFIG_ATT_SELF_POWERED)
,usb_power_ma(500)
,webusb_enabled(false)
,webusb_url("espressif.github.io/arduino-esp32/webusb.html")
,_started(false)
,_task_stack_size(task_stack_size)
,_event_task_priority(event_task_priority)
{
if (!arduino_usb_event_loop_handle) {
esp_event_loop_args_t event_task_args = {
.queue_size = 5,
.task_name = "arduino_usb_events",
.task_priority = _event_task_priority,
.task_stack_size = _task_stack_size,
.task_core_id = tskNO_AFFINITY
};
if (esp_event_loop_create(&event_task_args, &arduino_usb_event_loop_handle) != ESP_OK) {
log_e("esp_event_loop_create failed");
}
}
}
ESPUSB::~ESPUSB(){
if (arduino_usb_event_loop_handle) {
esp_event_loop_delete(arduino_usb_event_loop_handle);
arduino_usb_event_loop_handle = NULL;
}
}
bool ESPUSB::begin(){
if(!_started){
tinyusb_device_config_t tinyusb_device_config = {
.vid = vid,
.pid = pid,
.product_name = product_name.c_str(),
.manufacturer_name = manufacturer_name.c_str(),
.serial_number = serial_number.c_str(),
.fw_version = fw_version,
.usb_version = usb_version,
.usb_class = usb_class,
.usb_subclass = usb_subclass,
.usb_protocol = usb_protocol,
.usb_attributes = usb_attributes,
.usb_power_ma = usb_power_ma,
.webusb_enabled = webusb_enabled,
.webusb_url = webusb_url.c_str()
};
_started = tinyusb_init(&tinyusb_device_config) == ESP_OK;
}
return _started;
}
void ESPUSB::onEvent(esp_event_handler_t callback){
onEvent(ARDUINO_USB_ANY_EVENT, callback);
}
void ESPUSB::onEvent(arduino_usb_event_t event, esp_event_handler_t callback){
arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, event, callback, this);
}
ESPUSB::operator bool() const
{
return _started && tinyusb_device_mounted;
}
bool ESPUSB::enableDFU(){
#if CFG_TUD_DFU_RT
return tinyusb_enable_interface(USB_INTERFACE_DFU, TUD_DFU_RT_DESC_LEN, load_dfu_descriptor) == ESP_OK;
#endif /* CFG_TUD_DFU_RT */
return false;
}
bool ESPUSB::VID(uint16_t v){
if(!_started){
vid = v;
}
return !_started;
}
uint16_t ESPUSB::VID(void){
return vid;
}
bool ESPUSB::PID(uint16_t p){
if(!_started){
pid = p;
}
return !_started;
}
uint16_t ESPUSB::PID(void){
return pid;
}
bool ESPUSB::firmwareVersion(uint16_t version){
if(!_started){
fw_version = version;
}
return !_started;
}
uint16_t ESPUSB::firmwareVersion(void){
return fw_version;
}
bool ESPUSB::usbVersion(uint16_t version){
if(!_started){
usb_version = version;
}
return !_started;
}
uint16_t ESPUSB::usbVersion(void){
return usb_version;
}
bool ESPUSB::usbPower(uint16_t mA){
if(!_started){
usb_power_ma = mA;
}
return !_started;
}
uint16_t ESPUSB::usbPower(void){
return usb_power_ma;
}
bool ESPUSB::usbClass(uint8_t _class){
if(!_started){
usb_class = _class;
}
return !_started;
}
uint8_t ESPUSB::usbClass(void){
return usb_class;
}
bool ESPUSB::usbSubClass(uint8_t subClass){
if(!_started){
usb_subclass = subClass;
}
return !_started;
}
uint8_t ESPUSB::usbSubClass(void){
return usb_subclass;
}
bool ESPUSB::usbProtocol(uint8_t protocol){
if(!_started){
usb_protocol = protocol;
}
return !_started;
}
uint8_t ESPUSB::usbProtocol(void){
return usb_protocol;
}
bool ESPUSB::usbAttributes(uint8_t attr){
if(!_started){
usb_attributes = attr;
}
return !_started;
}
uint8_t ESPUSB::usbAttributes(void){
return usb_attributes;
}
bool ESPUSB::webUSB(bool enabled){
if(!_started){
webusb_enabled = enabled;
}
return !_started;
}
bool ESPUSB::webUSB(void){
return webusb_enabled;
}
bool ESPUSB::productName(const char * name){
if(!_started){
product_name = name;
}
return !_started;
}
const char * ESPUSB::productName(void){
return product_name.c_str();
}
bool ESPUSB::manufacturerName(const char * name){
if(!_started){
manufacturer_name = name;
}
return !_started;
}
const char * ESPUSB::manufacturerName(void){
return manufacturer_name.c_str();
}
bool ESPUSB::serialNumber(const char * name){
if(!_started){
serial_number = name;
}
return !_started;
}
const char * ESPUSB::serialNumber(void){
return serial_number.c_str();
}
bool ESPUSB::webUSBURL(const char * name){
if(!_started){
webusb_url = name;
}
return !_started;
}
const char * ESPUSB::webUSBURL(void){
return webusb_url.c_str();
}
ESPUSB USB;
#endif /* CONFIG_USB_ENABLED */

118
cores/esp32/USB.h Normal file
View File

@ -0,0 +1,118 @@
// Copyright 2015-2020 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
#include "sdkconfig.h"
#if CONFIG_USB_ENABLED
#include "Arduino.h"
#include "USBCDC.h"
#include "esp_event.h"
ESP_EVENT_DECLARE_BASE(ARDUINO_USB_EVENTS);
typedef enum {
ARDUINO_USB_ANY_EVENT = ESP_EVENT_ANY_ID,
ARDUINO_USB_STARTED_EVENT = 0,
ARDUINO_USB_STOPPED_EVENT,
ARDUINO_USB_SUSPEND_EVENT,
ARDUINO_USB_RESUME_EVENT,
ARDUINO_USB_MAX_EVENT,
} arduino_usb_event_t;
typedef union {
struct {
bool remote_wakeup_en;
} suspend;
} arduino_usb_event_data_t;
class ESPUSB {
public:
ESPUSB(size_t event_task_stack_size=2048, uint8_t event_task_priority=5);
~ESPUSB();
void onEvent(esp_event_handler_t callback);
void onEvent(arduino_usb_event_t event, esp_event_handler_t callback);
bool VID(uint16_t v);
uint16_t VID(void);
bool PID(uint16_t p);
uint16_t PID(void);
bool firmwareVersion(uint16_t version);
uint16_t firmwareVersion(void);
bool usbVersion(uint16_t version);
uint16_t usbVersion(void);
bool usbPower(uint16_t mA);
uint16_t usbPower(void);
bool usbClass(uint8_t _class);
uint8_t usbClass(void);
bool usbSubClass(uint8_t subClass);
uint8_t usbSubClass(void);
bool usbProtocol(uint8_t protocol);
uint8_t usbProtocol(void);
bool usbAttributes(uint8_t attr);
uint8_t usbAttributes(void);
bool webUSB(bool enabled);
bool webUSB(void);
bool productName(const char * name);
const char * productName(void);
bool manufacturerName(const char * name);
const char * manufacturerName(void);
bool serialNumber(const char * name);
const char * serialNumber(void);
bool webUSBURL(const char * name);
const char * webUSBURL(void);
bool enableDFU();
bool begin();
operator bool() const;
private:
uint16_t vid;
uint16_t pid;
String product_name;
String manufacturer_name;
String serial_number;
uint16_t fw_version;
uint16_t usb_version;
uint8_t usb_class;
uint8_t usb_subclass;
uint8_t usb_protocol;
uint8_t usb_attributes;
uint16_t usb_power_ma;
bool webusb_enabled;
String webusb_url;
bool _started;
size_t _task_stack_size;
uint8_t _event_task_priority;
};
extern ESPUSB USB;
#endif /* CONFIG_USB_ENABLED */

338
cores/esp32/USBCDC.cpp Normal file
View File

@ -0,0 +1,338 @@
// Copyright 2015-2020 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 "esp32-hal-tinyusb.h"
#include "USB.h"
#include "USBCDC.h"
#if CONFIG_USB_ENABLED
ESP_EVENT_DEFINE_BASE(ARDUINO_USB_CDC_EVENTS);
esp_err_t arduino_usb_event_post(esp_event_base_t event_base, int32_t event_id, void *event_data, size_t event_data_size, TickType_t ticks_to_wait);
esp_err_t arduino_usb_event_handler_register_with(esp_event_base_t event_base, int32_t event_id, esp_event_handler_t event_handler, void *event_handler_arg);
extern "C" {
#include "tinyusb.h"
}
#if CFG_TUD_CDC
#define MAX_USB_CDC_DEVICES 2
USBCDC * devices[MAX_USB_CDC_DEVICES] = {NULL, NULL};
static uint16_t load_cdc_descriptor(uint8_t * dst, uint8_t * itf)
{
uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB CDC");
// Interface number, string index, attributes, detach timeout, transfer size */
uint8_t descriptor[TUD_CDC_DESC_LEN] = {
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(*itf, str_index, 0x85, 64, 0x03, 0x84, 64)
};
*itf+=2;
memcpy(dst, descriptor, TUD_CDC_DESC_LEN);
return TUD_CDC_DESC_LEN;
}
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
{
if(itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL){
devices[itf]->_onLineState(dtr, rts);
}
}
void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding)
{
if(itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL){
devices[itf]->_onLineCoding(p_line_coding->bit_rate, p_line_coding->stop_bits, p_line_coding->parity, p_line_coding->data_bits);
}
}
void tud_cdc_rx_cb(uint8_t itf)
{
if(itf < MAX_USB_CDC_DEVICES && devices[itf] != NULL){
devices[itf]->_onRX();
}
}
static size_t tinyusb_cdc_write(uint8_t itf, const uint8_t *buffer, size_t size){
if(itf >= MAX_USB_CDC_DEVICES){
return 0;
}
if(!tud_cdc_n_connected(itf)){
return 0;
}
size_t tosend = size, sofar = 0;
while(tosend){
uint32_t space = tud_cdc_n_write_available(itf);
if(!space){
vTaskDelay(1 / portTICK_PERIOD_MS);
continue;
}
if(tosend < space){
space = tosend;
}
uint32_t sent = tud_cdc_n_write(itf, buffer + sofar, space);
if(!sent){
return sofar;
}
sofar += sent;
tosend -= sent;
tud_cdc_n_write_flush(itf);
}
return sofar;
}
static void ARDUINO_ISR_ATTR cdc0_write_char(char c)
{
tinyusb_cdc_write(0, (const uint8_t *)&c, 1);
}
//void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char);
static void usb_unplugged_cb(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
((USBCDC*)arg)->_onUnplugged();
}
USBCDC::USBCDC(uint8_t itfn) : itf(itfn), bit_rate(0), stop_bits(0), parity(0), data_bits(0), dtr(false), rts(false), connected(false), reboot_enable(true), rx_queue(NULL) {
tinyusb_enable_interface(USB_INTERFACE_CDC, TUD_CDC_DESC_LEN, load_cdc_descriptor);
if(itf < MAX_USB_CDC_DEVICES){
devices[itf] = this;
arduino_usb_event_handler_register_with(ARDUINO_USB_EVENTS, ARDUINO_USB_STOPPED_EVENT, usb_unplugged_cb, this);
}
}
void USBCDC::onEvent(esp_event_handler_t callback){
onEvent(ARDUINO_USB_CDC_ANY_EVENT, callback);
}
void USBCDC::onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback){
arduino_usb_event_handler_register_with(ARDUINO_USB_CDC_EVENTS, event, callback, this);
}
size_t USBCDC::setRxBufferSize(size_t rx_queue_len){
if(rx_queue){
return 0;
}
rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
if(!rx_queue){
return 0;
}
return rx_queue_len;
}
void USBCDC::begin(unsigned long baud)
{
setRxBufferSize(256);//default if not preset
}
void USBCDC::end()
{
}
void USBCDC::_onUnplugged(void){
if(connected){
connected = false;
dtr = false;
rts = false;
arduino_usb_cdc_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_DISCONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
}
enum { CDC_LINE_IDLE, CDC_LINE_1, CDC_LINE_2, CDC_LINE_3 };
void USBCDC::_onLineState(bool _dtr, bool _rts){
static uint8_t lineState = CDC_LINE_IDLE;
dtr = _dtr;
rts = _rts;
if(reboot_enable){
if(!dtr && rts){
if(lineState == CDC_LINE_IDLE){
lineState++;
} else {
lineState = CDC_LINE_IDLE;
}
} else if(dtr && rts){
if(lineState == CDC_LINE_1){
lineState++;
} else {
lineState = CDC_LINE_IDLE;
}
} else if(dtr && !rts){
if(lineState == CDC_LINE_2){
lineState++;
} else {
lineState = CDC_LINE_IDLE;
}
} else if(!dtr && !rts){
if(lineState == CDC_LINE_3){
usb_persist_restart(RESTART_BOOTLOADER);
} else {
lineState = CDC_LINE_IDLE;
}
}
}
if(lineState == CDC_LINE_IDLE){
if(dtr && rts && !connected){
connected = true;
arduino_usb_cdc_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_CONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
} else if(!dtr && !rts && connected){
connected = false;
arduino_usb_cdc_event_data_t p = {0};
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_DISCONNECTED_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
arduino_usb_cdc_event_data_t l = {0};
l.line_state.dtr = dtr;
l.line_state.rts = rts;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_LINE_STATE_EVENT, &l, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
}
void USBCDC::_onLineCoding(uint32_t _bit_rate, uint8_t _stop_bits, uint8_t _parity, uint8_t _data_bits){
if(bit_rate != _bit_rate || data_bits != _data_bits || stop_bits != _stop_bits || parity != _parity){
bit_rate = _bit_rate;
data_bits = _data_bits;
stop_bits = _stop_bits;
parity = _parity;
arduino_usb_cdc_event_data_t p = {0};
p.line_coding.bit_rate = bit_rate;
p.line_coding.data_bits = data_bits;
p.line_coding.stop_bits = stop_bits;
p.line_coding.parity = parity;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_LINE_CODING_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
}
void USBCDC::_onRX(){
uint8_t buf[CONFIG_USB_CDC_RX_BUFSIZE+1];
uint32_t count = tud_cdc_n_read(itf, buf, CONFIG_USB_CDC_RX_BUFSIZE);
for(uint32_t i=0; i<count; i++){
if(rx_queue == NULL || !xQueueSend(rx_queue, buf+i, 0)){
return;
}
}
arduino_usb_cdc_event_data_t p = {0};
p.rx.len = count;
arduino_usb_event_post(ARDUINO_USB_CDC_EVENTS, ARDUINO_USB_CDC_RX_EVENT, &p, sizeof(arduino_usb_cdc_event_data_t), portMAX_DELAY);
}
void USBCDC::enableReboot(bool enable){
reboot_enable = enable;
}
bool USBCDC::rebootEnabled(void){
return reboot_enable;
}
int USBCDC::available(void)
{
if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){
return -1;
}
return uxQueueMessagesWaiting(rx_queue);
}
int USBCDC::peek(void)
{
if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){
return -1;
}
uint8_t c;
if(xQueuePeek(rx_queue, &c, 0)) {
return c;
}
return -1;
}
int USBCDC::read(void)
{
if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){
return -1;
}
uint8_t c = 0;
if(xQueueReceive(rx_queue, &c, 0)) {
return c;
}
return -1;
}
size_t USBCDC::read(uint8_t *buffer, size_t size)
{
if(itf >= MAX_USB_CDC_DEVICES || rx_queue == NULL){
return -1;
}
uint8_t c = 0;
size_t count = 0;
while(count < size && xQueueReceive(rx_queue, &c, 0)){
buffer[count++] = c;
}
return count;
}
void USBCDC::flush(void)
{
if(itf >= MAX_USB_CDC_DEVICES){
return;
}
tud_cdc_n_write_flush(itf);
}
int USBCDC::availableForWrite(void)
{
if(itf >= MAX_USB_CDC_DEVICES){
return -1;
}
return tud_cdc_n_write_available(itf);
}
size_t USBCDC::write(const uint8_t *buffer, size_t size)
{
return tinyusb_cdc_write(itf, buffer, size);
}
size_t USBCDC::write(uint8_t c)
{
return write(&c, 1);
}
uint32_t USBCDC::baudRate()
{
return bit_rate;
}
void USBCDC::setDebugOutput(bool en)
{
if(en) {
uartSetDebug(NULL);
ets_install_putc1((void (*)(char)) &cdc0_write_char);
} else {
ets_install_putc1(NULL);
}
}
USBCDC::operator bool() const
{
if(itf >= MAX_USB_CDC_DEVICES){
return false;
}
return connected;
}
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
USBCDC Serial(0);
#endif
#endif /* CONFIG_USB_CDC_ENABLED */
#endif /* CONFIG_USB_ENABLED */

132
cores/esp32/USBCDC.h Normal file
View File

@ -0,0 +1,132 @@
// Copyright 2015-2020 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
#include <inttypes.h>
#include "esp32-hal.h"
#if CONFIG_USB_CDC_ENABLED
#include "esp_event.h"
ESP_EVENT_DECLARE_BASE(ARDUINO_USB_CDC_EVENTS);
typedef enum {
ARDUINO_USB_CDC_ANY_EVENT = ESP_EVENT_ANY_ID,
ARDUINO_USB_CDC_CONNECTED_EVENT = 0,
ARDUINO_USB_CDC_DISCONNECTED_EVENT,
ARDUINO_USB_CDC_LINE_STATE_EVENT,
ARDUINO_USB_CDC_LINE_CODING_EVENT,
ARDUINO_USB_CDC_RX_EVENT,
ARDUINO_USB_CDC_MAX_EVENT,
} arduino_usb_cdc_event_t;
typedef union {
struct {
bool dtr;
bool rts;
} line_state;
struct {
uint32_t bit_rate;
uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits
uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
} line_coding;
struct {
size_t len;
} rx;
} arduino_usb_cdc_event_data_t;
class USBCDC
{
public:
USBCDC(uint8_t itf=0);
void onEvent(esp_event_handler_t callback);
void onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback);
size_t setRxBufferSize(size_t);
void begin(unsigned long baud=0);
void end();
int available(void);
int availableForWrite(void);
int peek(void);
int read(void);
size_t read(uint8_t *buffer, size_t size);
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);
void flush(void);
inline size_t read(char * buffer, size_t size)
{
return read((uint8_t*) buffer, 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();
void setDebugOutput(bool);
operator bool() const;
void enableReboot(bool enable);
bool rebootEnabled(void);
//internal methods
void _onDFU(void);
void _onLineState(bool _dtr, bool _rts);
void _onLineCoding(uint32_t _bit_rate, uint8_t _stop_bits, uint8_t _parity, uint8_t _data_bits);
void _onRX(void);
void _onUnplugged(void);
protected:
uint8_t itf;
uint32_t bit_rate;
uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits
uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
bool dtr;
bool rts;
bool connected;
bool reboot_enable;
xQueueHandle rx_queue;
};
#if ARDUINO_SERIAL_PORT //Serial used for USB CDC
extern USBCDC Serial;
#endif
#endif /* CONFIG_USB_CDC_ENABLED */

View File

@ -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

View File

@ -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);
}

View File

@ -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;
//}

View File

@ -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;

View File

@ -1,335 +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 String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// 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 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

View File

@ -1 +0,0 @@
#include "lwip/apps/sntp.h"

View File

@ -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());
}

View File

@ -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_ */

View File

@ -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

View File

@ -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();
}

View File

@ -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

View File

@ -13,105 +13,76 @@
// limitations under the License.
#include "esp32-hal-adc.h"
#include "esp32-hal-log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "rom/ets_sys.h"
#include "esp_attr.h"
#include "esp_intr.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "driver/adc.h"
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp_adc_cal.h"
#include "esp32/rom/ets_sys.h"
#include "esp_intr_alloc.h"
#define DEFAULT_VREF 1100
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
static uint16_t __analogVRef = 0;
static uint8_t __analogVRefPin = 0;
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.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
#include "esp32-hal-gpio.h"
static uint8_t __analogAttenuation = 3;//11db
static uint8_t __analogWidth = 3;//12 bits
static uint8_t __analogCycles = 8;
static uint8_t __analogSamples = 0;//1 sample
static uint8_t __analogClockDiv = 1;
// Width of returned answer ()
static uint8_t __analogReturnedWidth = 12;
void __analogSetClockDiv(uint8_t clockDiv){
if(!clockDiv){
clockDiv = 1;
}
__analogClockDiv = clockDiv;
adc_set_clk_div(__analogClockDiv);
}
void __analogSetAttenuation(adc_attenuation_t attenuation)
{
__analogAttenuation = attenuation & 3;
}
#if CONFIG_IDF_TARGET_ESP32
void __analogSetWidth(uint8_t bits){
if(bits < 9){
bits = 9;
} else if(bits > 12){
bits = 12;
}
__analogReturnedWidth = bits;
__analogWidth = bits - 9;
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR2_BIT_WIDTH, __analogWidth, SENS_SAR2_BIT_WIDTH_S);
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_BIT, __analogWidth, SENS_SAR2_SAMPLE_BIT_S);
adc1_config_width(__analogWidth);
}
#endif
void __analogSetCycles(uint8_t cycles){
__analogCycles = cycles;
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_CYCLE, __analogCycles, SENS_SAR1_SAMPLE_CYCLE_S);
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_CYCLE, __analogCycles, SENS_SAR2_SAMPLE_CYCLE_S);
}
void __analogSetSamples(uint8_t samples){
if(!samples){
return;
}
__analogSamples = samples - 1;
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_NUM, __analogSamples, SENS_SAR1_SAMPLE_NUM_S);
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_NUM, __analogSamples, SENS_SAR2_SAMPLE_NUM_S);
}
void __analogSetClockDiv(uint8_t clockDiv){
if(!clockDiv){
return;
}
__analogClockDiv = clockDiv;
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_CLK_DIV, __analogClockDiv, SENS_SAR1_CLK_DIV_S);
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_CLK_DIV, __analogClockDiv, SENS_SAR2_CLK_DIV_S);
}
void __analogSetAttenuation(adc_attenuation_t attenuation)
{
__analogAttenuation = attenuation & 3;
uint32_t att_data = 0;
int i = 10;
while(i--){
att_data |= __analogAttenuation << (i * 2);
}
WRITE_PERI_REG(SENS_SAR_ATTEN1_REG, att_data & 0xFFFF);//ADC1 has 8 channels
WRITE_PERI_REG(SENS_SAR_ATTEN2_REG, att_data);
}
void IRAM_ATTR __analogInit(){
void __analogInit(){
static bool initialized = false;
if(initialized){
return;
}
__analogSetAttenuation(__analogAttenuation);
__analogSetCycles(__analogCycles);
__analogSetSamples(__analogSamples + 1);//in samples
__analogSetClockDiv(__analogClockDiv);
__analogSetWidth(__analogWidth + 9);//in bits
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_FORCE_M); //SAR ADC1 controller (in RTC) is started by SW
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD_FORCE_M); //SAR ADC1 pad enable bitmap is controlled by SW
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_FORCE_M); //SAR ADC2 controller (in RTC) is started by SW
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD_FORCE_M); //SAR ADC2 pad enable bitmap is controlled by SW
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M); //force XPD_SAR=0, use XPD_FSM
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_CTRL_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); //clear FSM
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==
initialized = true;
__analogSetClockDiv(__analogClockDiv);
#if CONFIG_IDF_TARGET_ESP32
__analogSetWidth(__analogWidth + 9);//in bits
#endif
}
void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
@ -120,23 +91,23 @@ void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
if(channel < 0 || attenuation > 3){
return ;
}
__analogInit();
if(channel > 7){
SET_PERI_REG_BITS(SENS_SAR_ATTEN2_REG, 3, attenuation, ((channel - 10) * 2));
if(channel > 9){
adc2_config_channel_atten(channel - 10, attenuation);
} else {
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, attenuation, (channel * 2));
adc1_config_channel_atten(channel, attenuation);
}
__analogInit();
}
bool IRAM_ATTR __adcAttachPin(uint8_t pin){
bool __adcAttachPin(uint8_t pin){
int8_t channel = digitalPinToAnalogChannel(pin);
if(channel < 0){
return false;//not adc pin
log_e("Pin %u is not ADC pin!", pin);
return false;
}
int8_t pad = digitalPinToTouchChannel(pin);
if(pad >= 0){
#if CONFIG_IDF_TARGET_ESP32
uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
if(touch & (1 << pad)){
touch &= ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S))
@ -144,6 +115,7 @@ bool IRAM_ATTR __adcAttachPin(uint8_t pin){
| (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, touch);
}
#endif
} else if(pin == 25){
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);//stop dac1
} else if(pin == 26){
@ -151,86 +123,120 @@ bool IRAM_ATTR __adcAttachPin(uint8_t pin){
}
pinMode(pin, ANALOG);
__analogInit();
__analogSetPinAttenuation(pin, __analogAttenuation);
return true;
}
bool IRAM_ATTR __adcStart(uint8_t pin){
int8_t channel = digitalPinToAnalogChannel(pin);
if(channel < 0){
return false;//not adc pin
}
if(channel > 9){
channel -= 10;
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
} else {
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
}
return true;
}
bool IRAM_ATTR __adcBusy(uint8_t pin){
int8_t channel = digitalPinToAnalogChannel(pin);
if(channel < 0){
return false;//not adc pin
}
if(channel > 7){
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0);
}
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0);
}
uint16_t IRAM_ATTR __adcEnd(uint8_t pin)
{
uint16_t value = 0;
int8_t channel = digitalPinToAnalogChannel(pin);
if(channel < 0){
return 0;//not adc pin
}
if(channel > 7){
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
} else {
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
}
// Shift result if necessary
uint8_t from = __analogWidth + 9;
if (from == __analogReturnedWidth) {
return value;
}
if (from > __analogReturnedWidth) {
return value >> (from - __analogReturnedWidth);
}
return value << (__analogReturnedWidth - from);
}
uint16_t IRAM_ATTR __analogRead(uint8_t pin)
{
if(!__adcAttachPin(pin) || !__adcStart(pin)){
return 0;
}
return __adcEnd(pin);
}
void __analogReadResolution(uint8_t bits)
{
if(!bits || bits > 16){
return;
}
#if CONFIG_IDF_TARGET_ESP32
__analogSetWidth(bits); // hadware from 9 to 12
__analogReturnedWidth = bits; // software from 1 to 16
#endif
}
uint16_t __analogRead(uint8_t pin)
{
int8_t channel = digitalPinToAnalogChannel(pin);
int value = 0;
esp_err_t r = ESP_OK;
if(channel < 0){
log_e("Pin %u is not ADC pin!", pin);
return value;
}
__adcAttachPin(pin);
if(channel > 9){
channel -= 10;
r = adc2_get_raw( channel, __analogWidth, &value);
if ( r == ESP_OK ) {
return value;
} else if ( r == ESP_ERR_INVALID_STATE ) {
log_e("GPIO%u: %s: ADC2 not initialized yet.", pin, esp_err_to_name(r));
} else if ( r == ESP_ERR_TIMEOUT ) {
log_e("GPIO%u: %s: ADC2 is in use by Wi-Fi.", pin, esp_err_to_name(r));
} else {
log_e("GPIO%u: %s", pin, esp_err_to_name(r));
}
} else {
return adc1_get_raw(channel);
}
return value;
}
uint32_t __analogReadMilliVolts(uint8_t pin){
int8_t channel = digitalPinToAnalogChannel(pin);
if(channel < 0){
log_e("Pin %u is not ADC pin!", pin);
return 0;
}
#if CONFIG_IDF_TARGET_ESP32
if(!__analogVRef){
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
log_d("eFuse Two Point: Supported");
__analogVRef = DEFAULT_VREF;
}
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
log_d("eFuse Vref: Supported");
__analogVRef = DEFAULT_VREF;
}
if(!__analogVRef){
__analogVRef = DEFAULT_VREF;
if(__analogVRefPin){
esp_adc_cal_characteristics_t chars;
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);
log_d("Vref to GPIO%u: %u", __analogVRefPin, __analogVRef);
}
}
}
}
uint8_t unit = 1;
if(channel > 9){
unit = 2;
}
uint16_t adc_reading = __analogRead(pin);
if(__analogCharacteristics[unit - 1] == NULL){
__analogCharacteristics[unit - 1] = calloc(1, sizeof(esp_adc_cal_characteristics_t));
if(__analogCharacteristics[unit - 1] == NULL){
return 0;
}
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, __analogAttenuation, __analogWidth, __analogVRef, __analogCharacteristics[unit - 1]);
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
} else if(__analogVRef != DEFAULT_VREF){
log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, __analogCharacteristics[unit - 1]->vref);
} else {
log_i("ADC%u: Characterized using Default Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
}
}
return esp_adc_cal_raw_to_voltage(adc_reading, __analogCharacteristics[unit - 1]);
#else
uint16_t adc_reading = __analogRead(pin);
uint16_t max_reading = 8191;
uint16_t max_mv = 1100;
switch(__analogAttenuation){
case 3: max_mv = 3900; break;
case 2: max_mv = 2200; break;
case 1: max_mv = 1500; break;
default: break;
}
return (adc_reading * max_mv) / max_reading;
#endif
}
#if CONFIG_IDF_TARGET_ESP32
void __analogSetVRefPin(uint8_t pin){
if(pin <25 || pin > 27){
pin = 0;
}
__analogVRefPin = pin;
}
int __hallRead() //hall sensor without LNA
@ -256,18 +262,20 @@ int __hallRead() //hall sensor without LNA
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL1_REG, SENS_HALL_PHASE_FORCE);
return (Sens_Vp1 - Sens_Vp0) - (Sens_Vn1 - Sens_Vn0);
}
#endif
extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead")));
extern uint32_t analogReadMilliVolts(uint8_t pin) __attribute__ ((weak, alias("__analogReadMilliVolts")));
extern void analogReadResolution(uint8_t bits) __attribute__ ((weak, alias("__analogReadResolution")));
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
extern void analogSetCycles(uint8_t cycles) __attribute__ ((weak, alias("__analogSetCycles")));
extern void analogSetSamples(uint8_t samples) __attribute__ ((weak, alias("__analogSetSamples")));
extern void analogSetClockDiv(uint8_t clockDiv) __attribute__ ((weak, alias("__analogSetClockDiv")));
extern void analogSetAttenuation(adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetAttenuation")));
extern void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetPinAttenuation")));
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
extern bool adcAttachPin(uint8_t pin) __attribute__ ((weak, alias("__adcAttachPin")));
extern bool adcStart(uint8_t pin) __attribute__ ((weak, alias("__adcStart")));
extern bool adcBusy(uint8_t pin) __attribute__ ((weak, alias("__adcBusy")));
extern uint16_t adcEnd(uint8_t pin) __attribute__ ((weak, alias("__adcEnd")));
#if CONFIG_IDF_TARGET_ESP32
extern void analogSetVRefPin(uint8_t pin) __attribute__ ((weak, alias("__analogSetVRefPin")));
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
#endif

View File

@ -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,
@ -38,6 +40,11 @@ typedef enum {
* */
uint16_t analogRead(uint8_t pin);
/*
* Get MilliVolts value for pin
* */
uint32_t analogReadMilliVolts(uint8_t pin);
/*
* Set the resolution of analogRead return values. Default is 12 bits (range from 0 to 4096).
* If between 9 and 12, it will equal the set hardware resolution, else value will be shifted.
@ -47,31 +54,6 @@ uint16_t analogRead(uint8_t pin);
*/
void analogReadResolution(uint8_t bits);
/*
* Sets the sample bits and read resolution
* Default is 12bit (0 - 4095)
* Range is 9 - 12
* */
void analogSetWidth(uint8_t bits);
/*
* Set number of cycles per sample
* Default is 8 and seems to do well
* Range is 1 - 255
* */
void analogSetCycles(uint8_t cycles);
/*
* Set number of samples in the range.
* Default is 1
* Range is 1 - 255
* This setting splits the range into
* "samples" pieces, which could look
* like the sensitivity has been multiplied
* that many times
* */
void analogSetSamples(uint8_t samples);
/*
* Set the divider for the ADC clock.
* Default is 1
@ -91,40 +73,30 @@ void analogSetAttenuation(adc_attenuation_t attenuation);
* */
void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
/*
* Get value for HALL sensor (without LNA)
* connected to pins 36(SVP) and 39(SVN)
* */
int hallRead();
/*
* Non-Blocking API (almost)
*
* Note: ADC conversion can run only for single pin at a time.
* That means that if you want to run ADC on two pins on the same bus,
* you need to run them one after another. Probably the best use would be
* to start conversion on both buses in parallel.
* */
/*
* Attach pin to ADC (will also clear any other analog mode that could be on)
* */
bool adcAttachPin(uint8_t pin);
#if CONFIG_IDF_TARGET_ESP32
/*
* Start ADC conversion on attached pin's bus
* Sets the sample bits and read resolution
* Default is 12bit (0 - 4095)
* Range is 9 - 12
* */
bool adcStart(uint8_t pin);
void analogSetWidth(uint8_t bits);
/*
* Check if conversion on the pin's ADC bus is currently running
* Set pin to use for ADC calibration if the esp is not already calibrated (25, 26 or 27)
* */
bool adcBusy(uint8_t pin);
void analogSetVRefPin(uint8_t pin);
/*
* Get the result of the conversion (will wait if it have not finished)
* Get value for HALL sensor (without LNA)
* connected to pins 36(SVP) and 39(SVN)
* */
uint16_t adcEnd(uint8_t pin);
int hallRead();
#endif
#ifdef __cplusplus
}

View File

@ -1,91 +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){
return true;
}
log_e("BT Stop failed");
return false;
}
#else
bool btStarted()
{
return false;
}
bool btStart()
{
return false;
}
bool btStop()
{
return false;
}
#endif
#endif

View File

@ -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_ */

View File

@ -21,22 +21,35 @@
#include "esp_log.h"
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "rom/rtc.h"
#include "soc/apb_ctrl_reg.h"
#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+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/rtc.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/rtc.h"
#endif
typedef struct apb_change_cb_s {
struct apb_change_cb_s * prev;
struct apb_change_cb_s * next;
void * arg;
apb_change_cb_t cb;
} apb_change_t;
const uint32_t MHZ = 1000000;
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;
@ -53,10 +66,20 @@ static void triggerApbChangeCallback(apb_change_ev_t ev_type, uint32_t old_apb,
initApbChangeCallback();
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
apb_change_t * r = apb_change_callbacks;
if( r != NULL ){
if(ev_type == APB_BEFORE_CHANGE )
while(r != NULL){
r->cb(r->arg, ev_type, old_apb, new_apb);
r=r->next;
}
else { // run backwards through chain
while(r->next != NULL) r = r->next; // find first added
while( r != NULL){
r->cb(r->arg, ev_type, old_apb, new_apb);
r=r->prev;
}
}
}
xSemaphoreGive(apb_change_lock);
}
@ -68,6 +91,7 @@ bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
return false;
}
c->next = NULL;
c->prev = NULL;
c->arg = arg;
c->cb = cb;
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
@ -75,18 +99,20 @@ bool addApbChangeCallback(void * arg, apb_change_cb_t cb){
apb_change_callbacks = c;
} else {
apb_change_t * r = apb_change_callbacks;
if(r->cb != cb || r->arg != arg){
while(r->next){
r = r->next;
if(r->cb == cb && r->arg == arg){
// 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",(unsigned int)c->cb,(unsigned int)c->arg);
free(c);
goto unlock_and_exit;
xSemaphoreGive(apb_change_lock);
return false;
}
else {
c->next = apb_change_callbacks;
apb_change_callbacks-> prev = c;
apb_change_callbacks = c;
}
}
r->next = c;
}
}
unlock_and_exit:
xSemaphoreGive(apb_change_lock);
return true;
}
@ -95,24 +121,21 @@ bool removeApbChangeCallback(void * arg, apb_change_cb_t cb){
initApbChangeCallback();
xSemaphoreTake(apb_change_lock, portMAX_DELAY);
apb_change_t * r = apb_change_callbacks;
if(r == NULL){
// 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",(unsigned int)cb,(unsigned int)arg);
xSemaphoreGive(apb_change_lock);
return false;
}
if(r->cb == cb && r->arg == arg){
else {
// patch links
if(r->prev) r->prev->next = r->next;
else { // this is first link
apb_change_callbacks = r->next;
}
if(r->next) r->next->prev = r->prev;
free(r);
} else {
while(r->next && (r->next->cb != cb || r->next->arg != arg)){
r = r->next;
}
if(r->next == NULL || r->next->cb != cb || r->next->arg != arg){
xSemaphoreGive(apb_change_lock);
return false;
}
apb_change_t * c = r->next;
r->next = c->next;
free(c);
}
xSemaphoreGive(apb_change_lock);
return true;
@ -132,6 +155,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
uint32_t capb, apb;
//Get XTAL Frequency and calculate min CPU MHz
rtc_xtal_freq_t xtal = rtc_clk_xtal_freq_get();
#if CONFIG_IDF_TARGET_ESP32
if(xtal > RTC_XTAL_FREQ_AUTO){
if(xtal < RTC_XTAL_FREQ_40M) {
if(cpu_freq_mhz <= xtal && cpu_freq_mhz != xtal && cpu_freq_mhz != (xtal/2)){
@ -143,6 +167,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
return false;
}
}
#endif
if(cpu_freq_mhz > xtal && cpu_freq_mhz != 240 && cpu_freq_mhz != 160 && cpu_freq_mhz != 80){
if(xtal >= RTC_XTAL_FREQ_40M){
log_e("Bad frequency: %u MHz! Options are: 240, 160, 80, %u, %u and %u MHz", cpu_freq_mhz, xtal, xtal/2, xtal/4);
@ -151,6 +176,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
}
return false;
}
#if CONFIG_IDF_TARGET_ESP32
//check if cpu supports the frequency
if(cpu_freq_mhz == 240){
//Check if ESP32 is rated for a CPU frequency of 160MHz only
@ -160,6 +186,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
cpu_freq_mhz = 160;
}
}
#endif
//Get current CPU clock configuration
rtc_clk_cpu_freq_get_config(&cconf);
//return if frequency has not changed
@ -186,7 +213,7 @@ bool setCpuFrequencyMhz(uint32_t cpu_freq_mhz){
//Update REF_TICK (uncomment if REF_TICK is different than 1MHz)
//if(conf.freq_mhz < 80){
// ESP_REG(APB_CTRL_XTAL_TICK_CONF_REG) = conf.freq_mhz / (REF_CLK_FREQ / MHZ) - 1;
//}
// }
//Update APB Freq REG
rtc_clk_apb_freq_update(apb);
//Update esp_timer divisor

View File

@ -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_ */

View File

@ -12,43 +12,46 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp32-hal-dac.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "rom/ets_sys.h"
#include "esp32-hal.h"
#include "esp_attr.h"
#include "esp_intr.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_periph.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "driver/dac.h"
#include "esp32-hal-gpio.h"
void IRAM_ATTR __dacWrite(uint8_t pin, uint8_t value)
#if CONFIG_IDF_TARGET_ESP32
#define DAC1 25
#define DAC2 26
#elif CONFIG_IDF_TARGET_ESP32S2
#define DAC1 17
#define DAC2 18
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
void ARDUINO_ISR_ATTR __dacWrite(uint8_t pin, uint8_t value)
{
if(pin < 25 || pin > 26){
if(pin < DAC1 || pin > DAC2){
return;//not dac pin
}
pinMode(pin, ANALOG);
uint8_t channel = pin - 25;
//Disable Tone
uint8_t channel = pin - DAC1;
#if CONFIG_IDF_TARGET_ESP32
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL1_REG, SENS_SW_TONE_EN);
if (channel) {
//Disable Channel Tone
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN2_M);
//Set the Dac value
SET_PERI_REG_BITS(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_DAC, value, RTC_IO_PDAC2_DAC_S); //dac_output
//Channel output enable
SET_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE);
} else {
//Disable Channel Tone
CLEAR_PERI_REG_MASK(SENS_SAR_DAC_CTRL2_REG, SENS_DAC_CW_EN1_M);
//Set the Dac value
SET_PERI_REG_BITS(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_DAC, value, RTC_IO_PDAC1_DAC_S); //dac_output
//Channel output enable
SET_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE);
#elif CONFIG_IDF_TARGET_ESP32S2
SENS.sar_dac_ctrl1.dac_clkgate_en = 1;
#endif
RTCIO.pad_dac[channel].dac_xpd_force = 1;
RTCIO.pad_dac[channel].xpd_dac = 1;
if (channel == 0) {
SENS.sar_dac_ctrl2.dac_cw_en1 = 0;
} else if (channel == 1) {
SENS.sar_dac_ctrl2.dac_cw_en2 = 0;
}
RTCIO.pad_dac[channel].dac = value;
}
extern void dacWrite(uint8_t pin, uint8_t value) __attribute__ ((weak, alias("__dacWrite")));

View File

@ -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

View File

@ -12,21 +12,48 @@
// 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"
#include "freertos/task.h"
#include "rom/ets_sys.h"
#include "esp_attr.h"
#include "esp_intr.h"
#include "rom/gpio.h"
#include "soc/gpio_reg.h"
#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+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/ets_sys.h"
#include "esp32/rom/gpio.h"
#include "esp_intr_alloc.h"
#define GPIO_FUNC 2
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/gpio.h"
#include "esp_intr_alloc.h"
#include "soc/periph_defs.h"
#define GPIO_FUNC 1
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#include "rom/gpio.h"
#include "esp_intr.h"
#endif
#if CONFIG_IDF_TARGET_ESP32
const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26};
#elif CONFIG_IDF_TARGET_ESP32S2
const int8_t esp32_adc2gpio[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
#endif
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT]={
#if CONFIG_IDF_TARGET_ESP32
{0x44, 11, 11, 1},
{0x88, -1, -1, -1},
{0x40, 12, 12, 2},
@ -59,14 +86,64 @@ const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
{0, -1, -1, -1},
{0, -1, -1, -1},
{0, -1, -1, -1},
{0x1c, 9, 4, 9},
{0x20, 8, 5, 8},
{0x1c, 9, 4, 8},
{0x20, 8, 5, 9},
{0x14, 4, 6, -1},
{0x18, 5, 7, -1},
{0x04, 0, 0, -1},
{0x08, 1, 1, -1},
{0x0c, 2, 2, -1},
{0x10, 3, 3, -1}
#elif CONFIG_IDF_TARGET_ESP32S2
{0x04, 0, -1, -1},
{0x08, 1, 0, 1},
{0x0c, 2, 1, 2},
{0x10, 3, 2, 3},
{0x14, 4, 3, 4},
{0x18, 5, 4, 5},
{0x1c, 6, 5, 6},
{0x20, 7, 6, 7},
{0x24, 8, 7, 8},
{0x28, 9, 8, 9},//FSPI_HD
{0x2c, 10, 9, 10},//FSPI_CS0 / FSPI_D4
{0x30, 11, 10, 11},//FSPI_D / FSPI_D5
{0x34, 12, 11, 12},//FSPI_CLK / FSPI_D6
{0x38, 13, 12, 13},//FSPI_Q / FSPI_D7
{0x3c, 14, 13, 14},//FSPI_WP / FSPI_DQS
{0x40, 15, 14, -1},//32K+ / RTS0
{0x44, 16, 15, -1},//32K- / CTS0
{0x48, 17, 16, -1},//DAC1 / TXD1
{0x4c, 18, 17, -1},//DAC2 / RXD1
{0x50, 19, 18, -1},//USB D- / RTS1
{0x54, 20, 19, -1},//USB D+ / CTS1
{0x58, 21, -1, -1},//SDA?
{ 0, -1, -1, -1},//UNAVAILABLE
{ 0, -1, -1, -1},//UNAVAILABLE
{ 0, -1, -1, -1},//UNAVAILABLE
{ 0, -1, -1, -1},//UNAVAILABLE
{0x6c, -1, -1, -1},//RESERVED SPI_CS1
{0x70, -1, -1, -1},//RESERVED SPI_HD
{0x74, -1, -1, -1},//RESERVED SPI_WP
{0x78, -1, -1, -1},//RESERVED SPI_CS0
{0x7c, -1, -1, -1},//RESERVED SPI_CLK
{0x80, -1, -1, -1},//RESERVED SPI_Q
{0x84, -1, -1, -1},//RESERVED SPI_D
{0x88, -1, -1, -1},//FSPI_HD
{0x8c, -1, -1, -1},//FSPI_CS0
{0x90, -1, -1, -1},//FSPI_D
{0x94, -1, -1, -1},//FSPI_CLK
{0x98, -1, -1, -1},//FSPI_Q
{0x9c, -1, -1, -1},//FSPI_WP
{0xa0, -1, -1, -1},//MTCK
{0xa4, -1, -1, -1},//MTDO
{0xa8, -1, -1, -1},//MTDI
{0xac, -1, -1, -1},//MTMS
{0xb0, -1, -1, -1},//TXD0
{0xb4, -1, -1, -1},//RXD0
{0xb8, -1, -1, -1},//SCL?
{0xbc, -1, -1, -1},//INPUT ONLY
{0, -1, -1, -1}
#endif
};
typedef void (*voidFuncPtr)(void);
@ -76,56 +153,57 @@ typedef struct {
void* arg;
bool functional;
} InterruptHandle_t;
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
static InterruptHandle_t __pinInterruptHandlers[SOC_GPIO_PIN_COUNT] = {0,};
#include "driver/rtc_io.h"
extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
extern void ARDUINO_ISR_ATTR __pinMode(uint8_t pin, uint8_t mode)
{
if(!digitalPinIsValid(pin)) {
return;
}
uint32_t rtc_reg = rtc_gpio_desc[pin].reg;
int8_t rtc_io = esp32_gpioMux[pin].rtc;
uint32_t rtc_reg = (rtc_io != -1)?rtc_io_desc[rtc_io].reg:0;
if(mode == ANALOG) {
if(!rtc_reg) {
return;//not rtc pin
}
//lock rtc
uint32_t reg_val = ESP_REG(rtc_reg);
if(reg_val & rtc_gpio_desc[pin].mux){
return;//already in adc mode
#if CONFIG_IDF_TARGET_ESP32S2
SENS.sar_io_mux_conf.iomux_clk_gate_en = 1;
#endif
SET_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, (rtc_io_desc[rtc_io].mux));
SET_PERI_REG_BITS(rtc_io_desc[rtc_io].reg, RTC_IO_TOUCH_PAD1_FUN_SEL_V, 0, rtc_io_desc[rtc_io].func);
RTCIO.pin[rtc_io].pad_driver = 0;//OD = 1
RTCIO.enable_w1tc.w1tc = (1U << rtc_io);
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].ie);
if (rtc_io_desc[rtc_io].pullup) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pullup);
}
reg_val &= ~(
(RTC_IO_TOUCH_PAD1_FUN_SEL_V << rtc_gpio_desc[pin].func)
|rtc_gpio_desc[pin].ie
|rtc_gpio_desc[pin].pullup
|rtc_gpio_desc[pin].pulldown);
ESP_REG(RTC_GPIO_ENABLE_W1TC_REG) = (1 << (rtc_gpio_desc[pin].rtc_num + RTC_GPIO_ENABLE_W1TC_S));
ESP_REG(rtc_reg) = reg_val | rtc_gpio_desc[pin].mux;
//unlock rtc
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = ((uint32_t)2 << MCU_SEL_S) | ((uint32_t)2 << FUN_DRV_S) | FUN_IE;
if (rtc_io_desc[rtc_io].pulldown) {
CLEAR_PERI_REG_MASK(rtc_io_desc[rtc_io].reg, rtc_io_desc[rtc_io].pulldown);
}
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = ((uint32_t)GPIO_FUNC << MCU_SEL_S) | ((uint32_t)2 << FUN_DRV_S) | FUN_IE;
return;
}
//RTC pins PULL settings
if(rtc_reg) {
//lock rtc
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].mux);
if(mode & PULLUP) {
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_gpio_desc[pin].pullup) & ~(rtc_gpio_desc[pin].pulldown);
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pullup) & ~(rtc_io_desc[rtc_io].pulldown);
} else if(mode & PULLDOWN) {
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_gpio_desc[pin].pulldown) & ~(rtc_gpio_desc[pin].pullup);
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_io_desc[rtc_io].pulldown) & ~(rtc_io_desc[rtc_io].pullup);
} else {
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_io_desc[rtc_io].pullup | rtc_io_desc[rtc_io].pulldown);
}
//unlock rtc
}
uint32_t pinFunction = 0, pinControl = 0;
//lock gpio
if(mode & INPUT) {
if(pin < 32) {
GPIO.enable_w1tc = ((uint32_t)1 << pin);
@ -133,9 +211,8 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
}
} else if(mode & OUTPUT) {
if(pin > 33){
//unlock gpio
return;//pins above 33 can be only inputs
if(pin >= NUM_OUPUT_PINS){
return;
} else if(pin < 32) {
GPIO.enable_w1ts = ((uint32_t)1 << pin);
} else {
@ -153,9 +230,17 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
pinFunction |= FUN_IE;//input enable but required for output as well?
if(mode & (INPUT | OUTPUT)) {
#if CONFIG_IDF_TARGET_ESP32
pinFunction |= ((uint32_t)2 << MCU_SEL_S);
#elif CONFIG_IDF_TARGET_ESP32S2
pinFunction |= ((uint32_t)1 << MCU_SEL_S);
#endif
} else if(mode == SPECIAL) {
pinFunction |= ((uint32_t)(((pin)==1||(pin)==3)?0:1) << MCU_SEL_S);
#if CONFIG_IDF_TARGET_ESP32
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:1) << MCU_SEL_S);
#elif CONFIG_IDF_TARGET_ESP32S2
pinFunction |= ((uint32_t)(((pin)==RX||(pin)==TX)?0:2) << MCU_SEL_S);
#endif
} else {
pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S);
}
@ -167,31 +252,30 @@ extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
}
GPIO.pin[pin].val = pinControl;
//unlock gpio
}
extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val)
extern void ARDUINO_ISR_ATTR __digitalWrite(uint8_t pin, uint8_t val)
{
if(val) {
if(pin < 32) {
GPIO.out_w1ts = ((uint32_t)1 << pin);
} else if(pin < 34) {
} else if(pin < NUM_OUPUT_PINS) {
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
}
} else {
if(pin < 32) {
GPIO.out_w1tc = ((uint32_t)1 << pin);
} else if(pin < 34) {
} else if(pin < NUM_OUPUT_PINS) {
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
}
}
}
extern int IRAM_ATTR __digitalRead(uint8_t pin)
extern int ARDUINO_ISR_ATTR __digitalRead(uint8_t pin)
{
if(pin < 32) {
return (GPIO.in >> pin) & 0x1;
} else if(pin < 40) {
} else if(pin < GPIO_PIN_COUNT) {
return (GPIO.in1.val >> (pin - 32)) & 0x1;
}
return 0;
@ -199,7 +283,7 @@ extern int IRAM_ATTR __digitalRead(uint8_t pin)
static intr_handle_t gpio_intr_handle = NULL;
static void IRAM_ATTR __onPinInterrupt()
static void ARDUINO_ISR_ATTR __onPinInterrupt()
{
uint32_t gpio_intr_status_l=0;
uint32_t gpio_intr_status_h=0;
@ -247,7 +331,7 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
if(!interrupt_initialized) {
interrupt_initialized = true;
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle);
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __onPinInterrupt, NULL, &gpio_intr_handle);
}
// if new attach without detach remove old info
@ -260,11 +344,15 @@ extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc,
__pinInterruptHandlers[pin].functional = functional;
esp_intr_disable(gpio_intr_handle);
#if CONFIG_IDF_TARGET_ESP32
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
#endif
GPIO.pin[pin].int_ena = 1;
#if CONFIG_IDF_TARGET_ESP32
} else { //PRO_CPU
GPIO.pin[pin].int_ena = 4;
}
#endif
GPIO.pin[pin].int_type = intr_type;
esp_intr_enable(gpio_intr_handle);
}

View File

@ -24,7 +24,18 @@
extern "C" {
#endif
#include "esp32-hal.h"
#include "stdint.h"
#include "soc/soc_caps.h"
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
#define NUM_OUPUT_PINS 45
#define PIN_DAC1 17
#define PIN_DAC2 18
#else
#define NUM_OUPUT_PINS 34
#define PIN_DAC1 25
#define PIN_DAC2 26
#endif
#define LOW 0x0
#define HIGH 0x1
@ -64,15 +75,15 @@ typedef struct {
int8_t touch; /*!< Touch Channel number (-1 if not Touch pin) */
} esp32_gpioMux_t;
extern const esp32_gpioMux_t esp32_gpioMux[40];
extern const esp32_gpioMux_t esp32_gpioMux[SOC_GPIO_PIN_COUNT];
extern const int8_t esp32_adc2gpio[20];
#define digitalPinIsValid(pin) ((pin) < 40 && esp32_gpioMux[(pin)].reg)
#define digitalPinCanOutput(pin) ((pin) < 34 && esp32_gpioMux[(pin)].reg)
#define digitalPinToRtcPin(pin) (((pin) < 40)?esp32_gpioMux[(pin)].rtc:-1)
#define digitalPinToAnalogChannel(pin) (((pin) < 40)?esp32_gpioMux[(pin)].adc:-1)
#define digitalPinToTouchChannel(pin) (((pin) < 40)?esp32_gpioMux[(pin)].touch:-1)
#define digitalPinToDacChannel(pin) (((pin) == 25)?0:((pin) == 26)?1:-1)
#define digitalPinIsValid(pin) ((pin) < SOC_GPIO_PIN_COUNT && esp32_gpioMux[(pin)].reg)
#define digitalPinCanOutput(pin) ((pin) < NUM_OUPUT_PINS && esp32_gpioMux[(pin)].reg)
#define digitalPinToRtcPin(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].rtc:-1)
#define digitalPinToAnalogChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].adc:-1)
#define digitalPinToTouchChannel(pin) (((pin) < SOC_GPIO_PIN_COUNT)?esp32_gpioMux[(pin)].touch:-1)
#define digitalPinToDacChannel(pin) (((pin) == PIN_DAC1)?0:((pin) == PIN_DAC2)?1:-1)
void pinMode(uint8_t pin, uint8_t mode);
void digitalWrite(uint8_t pin, uint8_t val);

View File

@ -12,19 +12,41 @@
// 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 "rom/ets_sys.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+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#endif
#include "driver/gpio.h"
#if CONFIG_IDF_TARGET_ESP32
//#define I2C_DEV(i) (volatile i2c_dev_t *)((i)?DR_REG_I2C1_EXT_BASE:DR_REG_I2C_EXT_BASE)
//#define I2C_DEV(i) ((i2c_dev_t *)(REG_I2C_BASE(i)))
#define I2C_SCL_IDX(p) ((p==0)?I2CEXT0_SCL_OUT_IDX:((p==1)?I2CEXT1_SCL_OUT_IDX:0))
@ -169,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;
@ -227,7 +249,7 @@ static i2c_t _i2c_bus_array[2] = {
/* Stickbreaker ISR mode debug support
*/
static void IRAM_ATTR i2cDumpCmdQueue(i2c_t *i2c)
static void ARDUINO_ISR_ATTR i2cDumpCmdQueue(i2c_t *i2c)
{
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR)&&(defined ENABLE_I2C_DEBUG_BUFFER)
static const char * const cmdName[] ={"RSTART","WRITE","READ","STOP","END"};
@ -316,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
@ -357,7 +379,7 @@ static void i2cDumpInts(uint8_t num)
#endif
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&&(defined ENABLE_I2C_DEBUG_BUFFER)
static void IRAM_ATTR i2cDumpStatus(i2c_t * i2c){
static void ARDUINO_ISR_ATTR i2cDumpStatus(i2c_t * i2c){
typedef union {
struct {
uint32_t ack_rec: 1; /*This register stores the value of ACK bit.*/
@ -431,7 +453,7 @@ if(i != fifoPos){// actual data
}
#endif
static void IRAM_ATTR i2cTriggerDumps(i2c_t * i2c, uint8_t trigger, const char locus[]){
static void ARDUINO_ISR_ATTR i2cTriggerDumps(i2c_t * i2c, uint8_t trigger, const char locus[]){
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&&(defined ENABLE_I2C_DEBUG_BUFFER)
if( trigger ){
log_i("%s",locus);
@ -478,7 +500,7 @@ static void i2cApbChangeCallback(void * arg, apb_change_ev_t ev_type, uint32_t o
}
/* End of CPU Clock change Support
*/
static void IRAM_ATTR i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bool ack_val, bool ack_exp, bool ack_check)
static void ARDUINO_ISR_ATTR i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uint8_t byte_num, bool ack_val, bool ack_exp, bool ack_check)
{
I2C_COMMAND_t cmd;
cmd.val=0;
@ -491,7 +513,7 @@ static void IRAM_ATTR i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uin
}
static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
static void ARDUINO_ISR_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
{
/* this function is called on initial i2cProcQueue() or when a I2C_END_DETECT_INT occurs
*/
@ -649,7 +671,7 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
}
}
static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
static void ARDUINO_ISR_ATTR fillTxFifo(i2c_t * i2c)
{
/*
12/01/2017 The Fifo's are independent, 32 bytes of tx and 32 bytes of Rx.
@ -741,7 +763,7 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
}
static void IRAM_ATTR emptyRxFifo(i2c_t * i2c)
static void ARDUINO_ISR_ATTR emptyRxFifo(i2c_t * i2c)
{
uint32_t d, cnt=0, moveCnt;
@ -800,7 +822,7 @@ static void IRAM_ATTR emptyRxFifo(i2c_t * i2c)
#endif
}
static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal)
static void ARDUINO_ISR_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal)
{
switch(eventCode) {
@ -845,7 +867,7 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
}
static void IRAM_ATTR i2c_update_error_byte_cnt(i2c_t * i2c)
static void ARDUINO_ISR_ATTR i2c_update_error_byte_cnt(i2c_t * i2c)
{
/* i2c_update_error_byte_cnt 07/18/2018
Only called after an error has occurred, so, most of the time this function is never used.
@ -892,7 +914,7 @@ static void IRAM_ATTR i2c_update_error_byte_cnt(i2c_t * i2c)
i2c->errorByteCnt = bc;
}
static void IRAM_ATTR i2c_isr_handler_default(void* arg)
static void ARDUINO_ISR_ATTR i2c_isr_handler_default(void* arg)
{
i2c_t* p_i2c = (i2c_t*) arg; // recover data
uint32_t activeInt = p_i2c->dev->int_status.val&0x7FF;
@ -945,6 +967,14 @@ static void IRAM_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
@ -1122,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
@ -1239,7 +1269,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
if(!i2c->intr_handle) { // create ISR for either peripheral
// log_i("create ISR %d",i2c->num);
uint32_t ret = 0;
uint32_t flags = ESP_INTR_FLAG_IRAM | //< ISR can be called if cache is disabled
uint32_t flags = ARDUINO_ISR_FLAG | //< ISR can be called if cache is disabled
ESP_INTR_FLAG_LOWMED | //< Low and medium prio interrupts. These can be handled in C.
ESP_INTR_FLAG_SHARED; //< Reduce resource requirements, Share interrupts
@ -1266,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
@ -1757,7 +1787,137 @@ uint32_t i2cGetStatus(i2c_t * i2c){
}
else return 0;
}
#else
#include "driver/i2c.h"
#define ACK_CHECK_EN 1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
struct i2c_struct_t {
i2c_port_t num;
};
static i2c_t * i2c_ports[2] = {NULL, NULL};
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));
if(out == NULL){
log_e("malloc failed");
return NULL;
}
out->num = (i2c_port_t)i2c_num;
i2c_ports[i2c_num] = out;
} else {
out = i2c_ports[i2c_num];
i2c_driver_delete((i2c_port_t)i2c_num);
}
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.scl_io_num = (gpio_num_t)scl;
conf.sda_io_num = (gpio_num_t)sda;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = clk_speed;
esp_err_t ret = i2c_param_config(out->num, &conf);
if (ret != ESP_OK) {
log_e("i2c_param_config failed");
free(out);
i2c_ports[i2c_num] = NULL;
return NULL;
}
ret = i2c_driver_install(out->num, conf.mode, 0, 0, 0);
if (ret != ESP_OK) {
log_e("i2c_driver_install failed");
free(out);
i2c_ports[i2c_num] = NULL;
return NULL;
}
return out;
}
i2c_err_t i2cWrite(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis){
esp_err_t ret = ESP_OK;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_WRITE, ACK_CHECK_EN);
i2c_master_write(cmd, buff, size, ACK_CHECK_EN);
//if send stop?
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c->num, cmd, timeOutMillis / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
return ret;
}
i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, bool sendStop, uint16_t timeOutMillis, uint32_t *readCount){
esp_err_t ret = ESP_OK;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (address << 1) | I2C_MASTER_READ, ACK_CHECK_EN);
if (size > 1) {
i2c_master_read(cmd, buff, size - 1, ACK_VAL);
}
i2c_master_read_byte(cmd, buff + size - 1, NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c->num, cmd, timeOutMillis / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if(ret == ESP_OK){
*readCount = size;
}
return ret;
}
void i2cRelease(i2c_t *i2c){
log_w("");
return;
}
i2c_err_t i2cFlush(i2c_t *i2c){
esp_err_t ret = i2c_reset_tx_fifo(i2c->num);
if(ret != ESP_OK){
return ret;
}
return i2c_reset_rx_fifo(i2c->num);
}
i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed){
log_w("");
return ESP_OK;
}
uint32_t i2cGetFrequency(i2c_t * i2c){
log_w("");
return 0;
}
uint32_t i2cGetStatus(i2c_t * i2c){
log_w("");
return 0;
}
//Functions below should be used only if well understood
//Might be deprecated and removed in future
i2c_err_t i2cAttachSCL(i2c_t * i2c, int8_t scl){
return ESP_FAIL;
}
i2c_err_t i2cDetachSCL(i2c_t * i2c, int8_t scl){
return ESP_FAIL;
}
i2c_err_t i2cAttachSDA(i2c_t * i2c, int8_t sda){
return ESP_FAIL;
}
i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda){
return ESP_FAIL;
}
#endif /* CONFIG_IDF_TARGET_ESP32 */
/* todo
22JUL18

View File

@ -16,11 +16,30 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "rom/ets_sys.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+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/ets_sys.h"
#define LAST_CHAN (15)
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#define LAST_CHAN (7)
#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#endif
#if CONFIG_DISABLE_HAL_LOCKS
#define LEDC_MUTEX_LOCK()
@ -28,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;
SemaphoreHandle_t _ledc_sys_lock = NULL;
#endif
/*
@ -55,18 +74,19 @@ xSemaphoreHandle _ledc_sys_lock;
static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){
if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){
uint32_t iarg = (uint32_t)arg;
uint8_t chan = iarg;
uint8_t group=(chan/8), timer=((chan/2)%4);
uint16_t iarg = *(uint16_t*)arg;
uint8_t chan = 0;
old_apb /= 1000000;
new_apb /= 1000000;
while(iarg){ // run though all active channels, adjusting timing configurations
if(iarg & 1) {// this channel is active
uint8_t group=(chan/8), timer=((chan/2)%4);
if(LEDC_TIMER(group, timer).conf.tick_sel){
LEDC_MUTEX_LOCK();
uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider;
uint32_t div_num = (new_apb * old_div) / old_apb;
if(div_num > LEDC_DIV_NUM_HSTIMER0_V){
new_apb = REF_CLK_FREQ / 1000000;
div_num = (new_apb * old_div) / old_apb;
div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb;
if(div_num > LEDC_DIV_NUM_HSTIMER0_V) {
div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible
}
@ -77,6 +97,13 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
LEDC_TIMER(group, timer).conf.clock_divider = div_num;
LEDC_MUTEX_UNLOCK();
}
else {
log_d("using REF_CLK chan=%d",chan);
}
}
iarg = iarg >> 1;
chan++;
}
}
}
@ -85,11 +112,14 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
{
uint8_t group=(chan/8), timer=((chan/2)%4);
static bool tHasStarted = false;
static uint16_t _activeChannels = 0;
if(!tHasStarted) {
tHasStarted = true;
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
LEDC.conf.apb_clk_sel = 1;//LS use apb clock
addApbChangeCallback((void*)&_activeChannels, _on_apb_change);
#if !CONFIG_DISABLE_HAL_LOCKS
_ledc_sys_lock = xSemaphoreCreateMutex();
#endif
@ -98,15 +128,18 @@ static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, boo
LEDC_TIMER(group, timer).conf.clock_divider = div_num;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part.
LEDC_TIMER(group, timer).conf.duty_resolution = bit_num;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20.
LEDC_TIMER(group, timer).conf.tick_sel = apb_clk;//apb clock
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_TIMER(group, timer).conf.low_speed_update = 1;//This bit is only useful for low speed timer channels, reserved for high speed timers
#if CONFIG_IDF_TARGET_ESP32
}
#endif
LEDC_TIMER(group, timer).conf.pause = 0;
LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset.
LEDC_TIMER(group, timer).conf.rst = 0;
LEDC_MUTEX_UNLOCK();
uint32_t iarg = chan;
addApbChangeCallback((void*)iarg, _on_apb_change);
_activeChannels |= (1 << chan); // mark as active for APB callback
}
//max div_num 0x3FFFF (262143)
@ -166,17 +199,21 @@ static void _ledcSetupChannel(uint8_t chan, uint8_t idle_level)
LEDC_CHAN(group, channel).duty.duty = 0;
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
#if CONFIG_IDF_TARGET_ESP32
} else {
LEDC_CHAN(group, channel).conf0.clk_en = 0;
}
#endif
LEDC_MUTEX_UNLOCK();
}
double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
{
if(chan > 15) {
if(chan > LAST_CHAN) {
return 0;
}
double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
@ -186,7 +223,7 @@ double ledcSetup(uint8_t chan, double freq, uint8_t bit_num)
void ledcWrite(uint8_t chan, uint32_t duty)
{
if(chan > 15) {
if(chan > LAST_CHAN) {
return;
}
uint8_t group=(chan/8), channel=(chan%8);
@ -195,26 +232,34 @@ void ledcWrite(uint8_t chan, uint32_t duty)
if(duty) {
LEDC_CHAN(group, channel).conf0.sig_out_en = 1;//This is the output enable control bit for channel
LEDC_CHAN(group, channel).conf1.duty_start = 1;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
#if CONFIG_IDF_TARGET_ESP32
} else {
LEDC_CHAN(group, channel).conf0.clk_en = 1;
}
#endif
} else {
LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel
LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware.
#if CONFIG_IDF_TARGET_ESP32
if(group) {
#endif
LEDC_CHAN(group, channel).conf0.low_speed_update = 1;
#if CONFIG_IDF_TARGET_ESP32
} else {
LEDC_CHAN(group, channel).conf0.clk_en = 0;
}
#endif
}
LEDC_MUTEX_UNLOCK();
}
uint32_t ledcRead(uint8_t chan)
{
if(chan > 15) {
if(chan > LAST_CHAN) {
return 0;
}
return LEDC.channel_group[chan/8].channel[chan%8].duty.duty >> 4;
@ -230,7 +275,7 @@ double ledcReadFreq(uint8_t chan)
double ledcWriteTone(uint8_t chan, double freq)
{
if(chan > 15) {
if(chan > LAST_CHAN) {
return 0;
}
if(!freq) {
@ -257,11 +302,15 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){
void ledcAttachPin(uint8_t pin, uint8_t chan)
{
if(chan > 15) {
if(chan > LAST_CHAN) {
return;
}
pinMode(pin, OUTPUT);
#if CONFIG_IDF_TARGET_ESP32S2
pinMatrixOutAttach(pin, LEDC_LS_SIG_OUT0_IDX + chan, false, false);
#else
pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false);
#endif
}
void ledcDetachPin(uint8_t pin)

View File

@ -20,6 +20,8 @@ extern "C"
#endif
#include "sdkconfig.h"
#include "esp_timer.h"
#include "esp_log.h"
#define ARDUHAL_LOG_LEVEL_NONE (0)
#define ARDUHAL_LOG_LEVEL_ERROR (1)
@ -71,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 "[" #letter "][%s:%u] %s(): " format ARDUHAL_LOG_RESET_COLOR "\r\n", 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

View File

@ -14,33 +14,46 @@
#include "esp32-hal-matrix.h"
#include "esp_attr.h"
#include "esp32-hal.h"
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/gpio.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/gpio.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/gpio.h"
#endif
#define MATRIX_DETACH_OUT_SIG 0x100
#define MATRIX_DETACH_IN_LOW_PIN 0x30
#define MATRIX_DETACH_IN_LOW_HIGH 0x38
void IRAM_ATTR pinMatrixOutAttach(uint8_t pin, uint8_t function, bool invertOut, bool invertEnable)
void ARDUINO_ISR_ATTR pinMatrixOutAttach(uint8_t pin, uint8_t function, bool invertOut, bool invertEnable)
{
gpio_matrix_out(pin, function, invertOut, invertEnable);
}
void IRAM_ATTR pinMatrixOutDetach(uint8_t pin, bool invertOut, bool invertEnable)
void ARDUINO_ISR_ATTR pinMatrixOutDetach(uint8_t pin, bool invertOut, bool invertEnable)
{
gpio_matrix_out(pin, MATRIX_DETACH_OUT_SIG, invertOut, invertEnable);
}
void IRAM_ATTR pinMatrixInAttach(uint8_t pin, uint8_t signal, bool inverted)
void ARDUINO_ISR_ATTR pinMatrixInAttach(uint8_t pin, uint8_t signal, bool inverted)
{
gpio_matrix_in(pin, signal, inverted);
}
void IRAM_ATTR pinMatrixInDetach(uint8_t signal, bool high, bool inverted)
void ARDUINO_ISR_ATTR pinMatrixInDetach(uint8_t signal, bool high, bool inverted)
{
gpio_matrix_in(high?MATRIX_DETACH_IN_LOW_HIGH:MATRIX_DETACH_IN_LOW_PIN, signal, inverted);
}
/*
void IRAM_ATTR intrMatrixAttach(uint32_t source, uint32_t inum){
void ARDUINO_ISR_ATTR intrMatrixAttach(uint32_t source, uint32_t inum){
intr_matrix_set(PRO_CPU_NUM, source, inum);
}
*/

View File

@ -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);

View File

@ -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
@ -31,9 +30,20 @@
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "rom/rtc.h"
#include "esp_task_wdt.h"
#include "esp32-hal.h"
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/rtc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/rtc.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/rtc.h"
#endif
//Undocumented!!! Get chip temperature in Farenheit
//Source: https://github.com/pcbreflux/espressif/blob/master/esp32/arduino/sketchbook/ESP32_int_temp_sensor/ESP32_int_temp_sensor.ino
@ -44,107 +54,19 @@ float temperatureRead()
return (temprature_sens_read() - 32) / 1.8;
}
void yield()
void __yield()
{
vPortYield();
}
#if CONFIG_AUTOSTART_ARDUINO
void yield() __attribute__ ((weak, alias("__yield")));
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 IRAM_ATTR micros()
unsigned long ARDUINO_ISR_ATTR micros()
{
return (unsigned long) (esp_timer_get_time());
}
unsigned long IRAM_ATTR millis()
{
return (unsigned long) (esp_timer_get_time() / 1000ULL);
}
void delay(uint32_t ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}
void IRAM_ATTR delayMicroseconds(uint32_t us)
void ARDUINO_ISR_ATTR delayMicroseconds(uint32_t us)
{
uint32_t m = micros();
if(us){
@ -160,83 +82,3 @@ void IRAM_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
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 * IRAM_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;
}

View 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

View File

@ -1,11 +1,40 @@
// 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"
#if CONFIG_SPIRAM_SUPPORT
#include "esp_spiram.h"
#include <stdbool.h>
#include <stddef.h>
#if CONFIG_SPIRAM_SUPPORT || CONFIG_SPIRAM
#include "soc/efuse_reg.h"
#include "esp_heap_caps.h"
#include "esp_system.h"
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/spiram.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/spiram.h"
#include "esp32s2/rom/cache.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "esp_spiram.h"
#endif
static volatile bool spiramDetected = false;
static volatile bool spiramFailed = false;
@ -17,6 +46,7 @@ bool psramInit(){
if (spiramFailed) {
return false;
}
#if CONFIG_IDF_TARGET_ESP32
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
uint32_t pkg_ver = chip_ver & 0x7;
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5 || pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
@ -24,14 +54,21 @@ 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();
Cache_Enable_DCache(0);
#endif
if (esp_spiram_init() != ESP_OK) {
spiramFailed = true;
log_w("PSRAM init failed!");
#if CONFIG_IDF_TARGET_ESP32
pinMatrixOutDetach(16, false, false);
pinMatrixOutDetach(17, false, false);
#endif
return false;
}
esp_spiram_init_cache();
if (!esp_spiram_test()) {
spiramFailed = true;
log_e("PSRAM test failed!");
@ -42,31 +79,34 @@ bool psramInit(){
log_e("PSRAM could not be added to the heap!");
return false;
}
#if CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL && !CONFIG_ARDUINO_ISR_IRAM
heap_caps_malloc_extmem_enable(CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL);
#endif
#endif
spiramDetected = true;
log_d("PSRAM enabled");
return true;
}
bool IRAM_ATTR psramFound(){
bool ARDUINO_ISR_ATTR psramFound(){
return spiramDetected;
}
void IRAM_ATTR *ps_malloc(size_t size){
void ARDUINO_ISR_ATTR *ps_malloc(size_t size){
if(!spiramDetected){
return NULL;
}
return heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}
void IRAM_ATTR *ps_calloc(size_t n, size_t size){
void ARDUINO_ISR_ATTR *ps_calloc(size_t n, size_t size){
if(!spiramDetected){
return NULL;
}
return heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
}
void IRAM_ATTR *ps_realloc(void *ptr, size_t size){
void ARDUINO_ISR_ATTR *ps_realloc(void *ptr, size_t size){
if(!spiramDetected){
return NULL;
}
@ -79,19 +119,19 @@ bool psramInit(){
return false;
}
bool IRAM_ATTR psramFound(){
bool ARDUINO_ISR_ATTR psramFound(){
return false;
}
void IRAM_ATTR *ps_malloc(size_t size){
void ARDUINO_ISR_ATTR *ps_malloc(size_t size){
return NULL;
}
void IRAM_ATTR *ps_calloc(size_t n, size_t size){
void ARDUINO_ISR_ATTR *ps_calloc(size_t n, size_t size){
return NULL;
}
void IRAM_ATTR *ps_realloc(void *ptr, size_t size){
void ARDUINO_ISR_ATTR *ps_realloc(void *ptr, size_t size){
return NULL;
}

View File

@ -19,6 +19,17 @@
extern "C" {
#endif
#include "sdkconfig.h"
#ifndef BOARD_HAS_PSRAM
#ifdef CONFIG_SPIRAM_SUPPORT
#undef CONFIG_SPIRAM_SUPPORT
#endif
#ifdef CONFIG_SPIRAM
#undef CONFIG_SPIRAM
#endif
#endif
bool psramInit();
bool psramFound();

View File

@ -17,20 +17,31 @@
#include "freertos/semphr.h"
#include "esp32-hal.h"
#include "esp32-hal-log.h"
#include "esp8266-compat.h"
#include "soc/gpio_reg.h"
#include "soc/gpio_reg.h"
#include "esp32-hal-rmt.h"
#include "driver/periph_ctrl.h"
#include "soc/rmt_struct.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
*/
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#define MAX_CHANNELS 8
#elif CONFIG_IDF_TARGET_ESP32S2
#define MAX_CHANNELS 4
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#define MAX_DATA_PER_CHANNEL 64
#define MAX_DATA_PER_ITTERATION 62
#define _ABS(a) (a>0?a:-a)
@ -94,24 +105,30 @@ 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] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
static SemaphoreHandle_t g_rmt_objlocks[MAX_CHANNELS] = {
NULL, NULL, NULL, NULL,
#if CONFIG_IDF_TARGET_ESP32
NULL, NULL, NULL, NULL
#endif
};
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},
{ 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, 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
};
/**
@ -121,26 +138,26 @@ 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
*/
static void _initPin(int pin, int channel, bool tx_not_rx);
static bool _rmtSendOnce(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
static bool _rmtSendOnce(rmt_obj_t* rmt, rmt_data_t* data, size_t size, bool continuous);
static void IRAM_ATTR _rmt_isr(void* arg);
static void ARDUINO_ISR_ATTR _rmt_isr(void* arg);
static rmt_obj_t* _rmtAllocate(int pin, int from, int size);
static void _initPin(int pin, int channel, bool tx_not_rx);
static int IRAM_ATTR _rmt_get_mem_len(uint8_t channel);
static int ARDUINO_ISR_ATTR _rmt_get_mem_len(uint8_t channel);
static void IRAM_ATTR _rmt_tx_mem_first(uint8_t ch);
static void ARDUINO_ISR_ATTR _rmt_tx_mem_first(uint8_t ch);
static void IRAM_ATTR _rmt_tx_mem_second(uint8_t ch);
static void ARDUINO_ISR_ATTR _rmt_tx_mem_second(uint8_t ch);
/**
@ -234,6 +251,20 @@ bool rmtDeinit(rmt_obj_t *rmt)
return true;
}
bool rmtLoop(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
{
if (!rmt) {
return false;
}
int allocated_size = MAX_DATA_PER_CHANNEL * rmt->buffers;
if (size > allocated_size) {
return false;
}
return _rmtSendOnce(rmt, data, size, true);
}
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
{
if (!rmt) {
@ -249,7 +280,7 @@ bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
RMT_MUTEX_LOCK(channel);
// setup interrupt handler if not yet installed for half and full tx
if (!intr_handle) {
esp_intr_alloc(ETS_RMT_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, _rmt_isr, NULL, &intr_handle);
esp_intr_alloc(ETS_RMT_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, _rmt_isr, NULL, &intr_handle);
}
rmt->data_size = size - MAX_DATA_PER_ITTERATION;
@ -282,10 +313,10 @@ bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
RMT_MUTEX_UNLOCK(channel);
// start the transation
return _rmtSendOnce(rmt, data, MAX_DATA_PER_ITTERATION);
return _rmtSendOnce(rmt, data, MAX_DATA_PER_ITTERATION, false);
} else {
// use one-go mode if data fits one buffer
return _rmtSendOnce(rmt, data, size);
return _rmtSendOnce(rmt, data, size, false);
}
}
@ -309,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) {
@ -342,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;
@ -350,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;
@ -376,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) {
@ -483,7 +529,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
break;
}
}
if (i == MAX_CHANNELS || i+j >= MAX_CHANNELS || j != buffers) {
if (i == MAX_CHANNELS || i+j > MAX_CHANNELS || j != buffers) {
xSemaphoreGive(g_rmt_block_lock);
return NULL;
}
@ -508,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:
@ -518,17 +566,23 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
RMT.conf_ch[channel].conf0.mem_size = buffers;
RMT.conf_ch[channel].conf0.carrier_en = 0;
RMT.conf_ch[channel].conf0.carrier_out_lv = 0;
#if CONFIG_IDF_TARGET_ESP32
RMT.conf_ch[channel].conf0.mem_pd = 0;
#endif
RMT.conf_ch[channel].conf0.idle_thres = 0x80;
RMT.conf_ch[channel].conf1.rx_en = 0;
RMT.conf_ch[channel].conf1.tx_conti_mode = 0;
#if CONFIG_IDF_TARGET_ESP32
RMT.conf_ch[channel].conf1.ref_cnt_rst = 0;
#else
RMT.conf_ch[channel].conf1.chk_rx_carrier_en = 0;
#endif
RMT.conf_ch[channel].conf1.rx_filter_en = 0;
RMT.conf_ch[channel].conf1.rx_filter_thres = 0;
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) {
@ -543,7 +597,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
// install interrupt if at least one channel is active
if (!intr_handle) {
esp_intr_alloc(ETS_RMT_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, _rmt_isr, NULL, &intr_handle);
esp_intr_alloc(ETS_RMT_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, _rmt_isr, NULL, &intr_handle);
}
RMT_MUTEX_UNLOCK(channel);
@ -553,7 +607,7 @@ rmt_obj_t* rmtInit(int pin, bool tx_not_rx, rmt_reserve_memsize_t memsize)
/**
* Private methods definitions
*/
bool _rmtSendOnce(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
bool _rmtSendOnce(rmt_obj_t* rmt, rmt_data_t* data, size_t size, bool continuous)
{
if (!rmt) {
return false;
@ -571,6 +625,7 @@ bool _rmtSendOnce(rmt_obj_t* rmt, rmt_data_t* data, size_t size)
}
RMT_MUTEX_LOCK(channel);
RMT.conf_ch[channel].conf1.tx_conti_mode = continuous;
RMT.conf_ch[channel].conf1.mem_rd_rst = 1;
RMT.conf_ch[channel].conf1.tx_start = 1;
RMT_MUTEX_UNLOCK(channel);
@ -610,7 +665,7 @@ static void _initPin(int pin, int channel, bool tx_not_rx)
}
static void IRAM_ATTR _rmt_isr(void* arg)
static void ARDUINO_ISR_ATTR _rmt_isr(void* arg)
{
int intr_val = RMT.int_st.val;
size_t ch;
@ -643,7 +698,7 @@ static void IRAM_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;
@ -700,7 +755,7 @@ static void IRAM_ATTR _rmt_isr(void* arg)
}
}
static void IRAM_ATTR _rmt_tx_mem_second(uint8_t ch)
static void ARDUINO_ISR_ATTR _rmt_tx_mem_second(uint8_t ch)
{
DEBUG_INTERRUPT_START(4)
uint32_t* data = g_rmt_objects[ch].data_ptr;
@ -752,7 +807,7 @@ static void IRAM_ATTR _rmt_tx_mem_second(uint8_t ch)
DEBUG_INTERRUPT_END(4);
}
static void IRAM_ATTR _rmt_tx_mem_first(uint8_t ch)
static void ARDUINO_ISR_ATTR _rmt_tx_mem_first(uint8_t ch)
{
DEBUG_INTERRUPT_START(2);
uint32_t* data = g_rmt_objects[ch].data_ptr;
@ -803,16 +858,19 @@ static void IRAM_ATTR _rmt_tx_mem_first(uint8_t ch)
DEBUG_INTERRUPT_END(2);
}
static int IRAM_ATTR _rmt_get_mem_len(uint8_t channel)
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;
}
}

View File

@ -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 {
@ -73,6 +73,12 @@ float rmtSetTick(rmt_obj_t* rmt, float tick);
*/
bool rmtWrite(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
/**
* Loop data up to the reserved memsize continuously
*
*/
bool rmtLoop(rmt_obj_t* rmt, rmt_data_t* data, size_t size);
/**
* Initiates async receive, event flag indicates data received
*
@ -84,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 */

View File

@ -16,10 +16,25 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "rom/ets_sys.h"
#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+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/ets_sys.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#endif
#if CONFIG_DISABLE_HAL_LOCKS
@ -28,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){
@ -69,6 +84,9 @@ uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-31
prescale = 0xFF;
}
SD_MUTEX_LOCK();
#ifndef CONFIG_IDF_TARGET_ESP32
SIGMADELTA.misc.function_clk_en = 1;
#endif
SIGMADELTA.channel[channel].prescale = prescale;
SIGMADELTA.cg.clk_en = 0;
SIGMADELTA.cg.clk_en = 1;

View File

@ -12,15 +12,14 @@
// 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"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "rom/ets_sys.h"
#include "esp_attr.h"
#include "esp_intr.h"
#include "rom/gpio.h"
#include "soc/spi_reg.h"
#include "soc/spi_struct.h"
#include "soc/io_mux_reg.h"
@ -28,6 +27,55 @@
#include "soc/dport_reg.h"
#include "soc/rtc.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/gpio.h"
#include "esp_intr_alloc.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#include "esp32s2/rom/ets_sys.h"
#include "esp32s2/rom/gpio.h"
#include "esp_intr_alloc.h"
#else
#error Target CONFIG_IDF_TARGET is not supported
#endif
#else // ESP32 Before IDF 4.0
#include "rom/ets_sys.h"
#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
SemaphoreHandle_t lock;
#endif
uint8_t num;
};
#if CONFIG_IDF_TARGET_ESP32S2
// ESP32S2
#define SPI_COUNT (3)
#define SPI_CLK_IDX(p) ((p==0)?SPICLK_OUT_MUX_IDX:((p==1)?FSPICLK_OUT_MUX_IDX:((p==2)?SPI3_CLK_OUT_MUX_IDX:0)))
#define SPI_MISO_IDX(p) ((p==0)?SPIQ_OUT_IDX:((p==1)?FSPIQ_OUT_IDX:((p==2)?SPI3_Q_OUT_IDX:0)))
#define SPI_MOSI_IDX(p) ((p==0)?SPID_IN_IDX:((p==1)?FSPID_IN_IDX:((p==2)?SPI3_D_IN_IDX:0)))
#define SPI_SPI_SS_IDX(n) ((n==0)?SPICS0_OUT_IDX:((n==1)?SPICS1_OUT_IDX:0))
#define SPI_HSPI_SS_IDX(n) ((n==0)?SPI3_CS0_OUT_IDX:((n==1)?SPI3_CS1_OUT_IDX:((n==2)?SPI3_CS2_OUT_IDX:SPI3_CS0_OUT_IDX)))
#define SPI_FSPI_SS_IDX(n) ((n==0)?FSPICS0_OUT_IDX:((n==1)?FSPICS1_OUT_IDX:((n==2)?FSPICS2_OUT_IDX:VSPICS0_OUT_IDX)))
#define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):0)))
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI1_INTR_SOURCE:((u==1)?ETS_SPI2_INTR_SOURCE:((u==2)?ETS_SPI3_INTR_SOURCE:0)))
#else
// ESP32
#define SPI_COUNT (4)
#define SPI_CLK_IDX(p) ((p==0)?SPICLK_OUT_IDX:((p==1)?SPICLK_OUT_IDX:((p==2)?HSPICLK_OUT_IDX:((p==3)?VSPICLK_OUT_IDX:0))))
#define SPI_MISO_IDX(p) ((p==0)?SPIQ_OUT_IDX:((p==1)?SPIQ_OUT_IDX:((p==2)?HSPIQ_OUT_IDX:((p==3)?VSPIQ_OUT_IDX:0))))
#define SPI_MOSI_IDX(p) ((p==0)?SPID_IN_IDX:((p==1)?SPID_IN_IDX:((p==2)?HSPID_IN_IDX:((p==3)?VSPID_IN_IDX:0))))
@ -37,36 +85,41 @@
#define SPI_VSPI_SS_IDX(n) ((n==0)?VSPICS0_OUT_IDX:((n==1)?VSPICS1_OUT_IDX:((n==2)?VSPICS2_OUT_IDX:VSPICS0_OUT_IDX)))
#define SPI_SS_IDX(p, n) ((p==0)?SPI_SPI_SS_IDX(n):((p==1)?SPI_SPI_SS_IDX(n):((p==2)?SPI_HSPI_SS_IDX(n):((p==3)?SPI_VSPI_SS_IDX(n):0))))
#define SPI_INUM(u) (2)
#define SPI_INTR_SOURCE(u) ((u==0)?ETS_SPI0_INTR_SOURCE:((u==1)?ETS_SPI1_INTR_SOURCE:((u==2)?ETS_SPI2_INTR_SOURCE:((p==3)?ETS_SPI3_INTR_SOURCE:0))))
struct spi_struct_t {
spi_dev_t * dev;
#if !CONFIG_DISABLE_HAL_LOCKS
xSemaphoreHandle lock;
#endif
uint8_t num;
};
#if CONFIG_DISABLE_HAL_LOCKS
#define SPI_MUTEX_LOCK()
#define SPI_MUTEX_UNLOCK()
static spi_t _spi_bus_array[4] = {
static spi_t _spi_bus_array[] = {
#if CONFIG_IDF_TARGET_ESP32S2
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 0},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 2}
#else
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), 0},
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), 1},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), 2},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), 3}
#endif
};
#else
#define SPI_MUTEX_LOCK() do {} while (xSemaphoreTake(spi->lock, portMAX_DELAY) != pdPASS)
#define SPI_MUTEX_UNLOCK() xSemaphoreGive(spi->lock)
static spi_t _spi_bus_array[4] = {
static spi_t _spi_bus_array[] = {
#if CONFIG_IDF_TARGET_ESP32S2
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 0},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 1},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 2}
#else
{(volatile spi_dev_t *)(DR_REG_SPI0_BASE), NULL, 0},
{(volatile spi_dev_t *)(DR_REG_SPI1_BASE), NULL, 1},
{(volatile spi_dev_t *)(DR_REG_SPI2_BASE), NULL, 2},
{(volatile spi_dev_t *)(DR_REG_SPI3_BASE), NULL, 3}
#endif
};
#endif
@ -76,6 +129,14 @@ void spiAttachSCK(spi_t * spi, int8_t sck)
return;
}
if(sck < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
sck = 36;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
sck = 14;
} else if(spi->num == VSPI) {
@ -83,6 +144,7 @@ void spiAttachSCK(spi_t * spi, int8_t sck)
} else {
sck = 6;
}
#endif
}
pinMode(sck, OUTPUT);
pinMatrixOutAttach(sck, SPI_CLK_IDX(spi->num), false, false);
@ -94,6 +156,14 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
return;
}
if(miso < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
miso = 37;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
miso = 12;
} else if(spi->num == VSPI) {
@ -101,6 +171,7 @@ void spiAttachMISO(spi_t * spi, int8_t miso)
} else {
miso = 7;
}
#endif
}
SPI_MUTEX_LOCK();
pinMode(miso, INPUT);
@ -114,6 +185,14 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi)
return;
}
if(mosi < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
mosi = 35;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
mosi = 13;
} else if(spi->num == VSPI) {
@ -121,6 +200,7 @@ void spiAttachMOSI(spi_t * spi, int8_t mosi)
} else {
mosi = 8;
}
#endif
}
pinMode(mosi, OUTPUT);
pinMatrixOutAttach(mosi, SPI_MOSI_IDX(spi->num), false, false);
@ -132,6 +212,14 @@ void spiDetachSCK(spi_t * spi, int8_t sck)
return;
}
if(sck < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
sck = 36;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
sck = 14;
} else if(spi->num == VSPI) {
@ -139,6 +227,7 @@ void spiDetachSCK(spi_t * spi, int8_t sck)
} else {
sck = 6;
}
#endif
}
pinMatrixOutDetach(sck, false, false);
pinMode(sck, INPUT);
@ -150,6 +239,14 @@ void spiDetachMISO(spi_t * spi, int8_t miso)
return;
}
if(miso < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
miso = 37;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
miso = 12;
} else if(spi->num == VSPI) {
@ -157,6 +254,7 @@ void spiDetachMISO(spi_t * spi, int8_t miso)
} else {
miso = 7;
}
#endif
}
pinMatrixInDetach(SPI_MISO_IDX(spi->num), false, false);
pinMode(miso, INPUT);
@ -168,6 +266,14 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi)
return;
}
if(mosi < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
mosi = 35;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
mosi = 13;
} else if(spi->num == VSPI) {
@ -175,6 +281,7 @@ void spiDetachMOSI(spi_t * spi, int8_t mosi)
} else {
mosi = 8;
}
#endif
}
pinMatrixOutDetach(mosi, false, false);
pinMode(mosi, INPUT);
@ -190,6 +297,14 @@ void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss)
}
if(ss < 0) {
cs_num = 0;
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
ss = 34;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
ss = 15;
} else if(spi->num == VSPI) {
@ -197,6 +312,7 @@ void spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss)
} else {
ss = 11;
}
#endif
}
pinMode(ss, OUTPUT);
pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, cs_num), false, false);
@ -209,6 +325,14 @@ void spiDetachSS(spi_t * spi, int8_t ss)
return;
}
if(ss < 0) {
#if CONFIG_IDF_TARGET_ESP32S2
if(spi->num == FSPI) {
ss = 34;
} else {
log_e("HSPI Does not have default pins on ESP32S2!");
return;
}
#else
if(spi->num == HSPI) {
ss = 15;
} else if(spi->num == VSPI) {
@ -216,6 +340,7 @@ void spiDetachSS(spi_t * spi, int8_t ss)
} else {
ss = 11;
}
#endif
}
pinMatrixOutDetach(ss, false, false);
pinMode(ss, INPUT);
@ -227,7 +352,11 @@ void spiEnableSSPins(spi_t * spi, uint8_t cs_mask)
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.val &= ~(cs_mask & SPI_CS_MASK_ALL);
#else
spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL);
#endif
SPI_MUTEX_UNLOCK();
}
@ -237,7 +366,11 @@ void spiDisableSSPins(spi_t * spi, uint8_t cs_mask)
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.val |= (cs_mask & SPI_CS_MASK_ALL);
#else
spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL);
#endif
SPI_MUTEX_UNLOCK();
}
@ -269,7 +402,11 @@ void spiSSSet(spi_t * spi)
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.cs_keep_active = 1;
#else
spi->dev->pin.cs_keep_active = 1;
#endif
SPI_MUTEX_UNLOCK();
}
@ -279,7 +416,11 @@ void spiSSClear(spi_t * spi)
return;
}
SPI_MUTEX_LOCK();
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.cs_keep_active = 0;
#else
spi->dev->pin.cs_keep_active = 0;
#endif
SPI_MUTEX_UNLOCK();
}
@ -306,7 +447,11 @@ uint8_t spiGetDataMode(spi_t * spi)
if(!spi) {
return 0;
}
#if CONFIG_IDF_TARGET_ESP32S2
bool idleEdge = spi->dev->misc.ck_idle_edge;
#else
bool idleEdge = spi->dev->pin.ck_idle_edge;
#endif
bool outEdge = spi->dev->user.ck_out_edge;
if(idleEdge) {
if(outEdge) {
@ -328,20 +473,36 @@ void spiSetDataMode(spi_t * spi, uint8_t dataMode)
SPI_MUTEX_LOCK();
switch (dataMode) {
case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 0;
break;
case SPI_MODE0:
default:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 0;
break;
}
@ -384,28 +545,39 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb
}
}
void spiStopBus(spi_t * spi)
static void spiInitBus(spi_t * spi)
{
if(!spi) {
return;
}
SPI_MUTEX_LOCK();
spi->dev->slave.trans_done = 0;
spi->dev->slave.slave_mode = 0;
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.val = 0;
#else
spi->dev->pin.val = 0;
#endif
spi->dev->user.val = 0;
spi->dev->user1.val = 0;
spi->dev->ctrl.val = 0;
spi->dev->ctrl1.val = 0;
spi->dev->ctrl2.val = 0;
spi->dev->clock.val = 0;
SPI_MUTEX_UNLOCK();
}
void spiStopBus(spi_t * spi)
{
if(!spi) {
return;
}
removeApbChangeCallback(spi, _on_apb_change);
SPI_MUTEX_LOCK();
spiInitBus(spi);
SPI_MUTEX_UNLOCK();
}
spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder)
{
if(spi_num > 3){
if(spi_num >= SPI_COUNT){
return NULL;
}
@ -420,23 +592,32 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
}
#endif
if(spi_num == HSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST);
} else if(spi_num == VSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_2);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_2);
#if CONFIG_IDF_TARGET_ESP32S2
if(spi_num == FSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI2_RST);
} else if(spi_num == HSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST);
} else {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_1);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_1);
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
}
spiStopBus(spi);
spiSetDataMode(spi, dataMode);
spiSetBitOrder(spi, bitOrder);
spiSetClockDiv(spi, clockDiv);
#else
if(spi_num == HSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI2_RST);
} else if(spi_num == VSPI) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI3_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI3_RST);
} else {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI01_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI01_RST);
}
#endif
SPI_MUTEX_LOCK();
spiInitBus(spi);
spi->dev->user.usr_mosi = 1;
spi->dev->user.usr_miso = 1;
spi->dev->user.doutdin = 1;
@ -447,6 +628,10 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_
}
SPI_MUTEX_UNLOCK();
spiSetDataMode(spi, dataMode);
spiSetBitOrder(spi, bitOrder);
spiSetClockDiv(spi, clockDiv);
addApbChangeCallback(spi, _on_apb_change);
return spi;
}
@ -459,7 +644,12 @@ void spiWaitReady(spi_t * spi)
while(spi->dev->cmd.usr);
}
void spiWrite(spi_t * spi, uint32_t *data, uint8_t len)
#if CONFIG_IDF_TARGET_ESP32S2
#define usr_mosi_dbitlen usr_mosi_bit_len
#define usr_miso_dbitlen usr_miso_bit_len
#endif
void spiWrite(spi_t * spi, const uint32_t *data, uint8_t len)
{
if(!spi) {
return;
@ -532,17 +722,7 @@ uint8_t spiTransferByte(spi_t * spi, uint8_t data)
return data;
}
uint32_t __spiTranslate24(uint32_t data)
{
union {
uint32_t l;
uint8_t b[4];
} out;
out.l = data;
return out.b[2] | (out.b[1] << 8) | (out.b[0] << 16);
}
uint32_t __spiTranslate32(uint32_t data)
static uint32_t __spiTranslate32(uint32_t data)
{
union {
uint32_t l;
@ -630,7 +810,7 @@ uint32_t spiTransferLong(spi_t * spi, uint32_t data)
return data;
}
void __spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t bytes)
static void __spiTransferBytes(spi_t * spi, const uint8_t * data, uint8_t * out, uint32_t bytes)
{
if(!spi) {
return;
@ -671,7 +851,7 @@ void __spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t byt
}
}
void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size)
void spiTransferBytes(spi_t * spi, const uint8_t * data, uint8_t * out, uint32_t size)
{
if(!spi) {
return;
@ -723,20 +903,36 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
spi->dev->clock.val = clockDiv;
switch (dataMode) {
case SPI_MODE1:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE2:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 1;
break;
case SPI_MODE3:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 1;
#else
spi->dev->pin.ck_idle_edge = 1;
#endif
spi->dev->user.ck_out_edge = 0;
break;
case SPI_MODE0:
default:
#if CONFIG_IDF_TARGET_ESP32S2
spi->dev->misc.ck_idle_edge = 0;
#else
spi->dev->pin.ck_idle_edge = 0;
#endif
spi->dev->user.ck_out_edge = 0;
break;
}
@ -765,7 +961,7 @@ void spiEndTransaction(spi_t * spi)
SPI_MUTEX_UNLOCK();
}
void IRAM_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
void ARDUINO_ISR_ATTR spiWriteByteNL(spi_t * spi, uint8_t data)
{
if(!spi) {
return;
@ -791,7 +987,7 @@ uint8_t spiTransferByteNL(spi_t * spi, uint8_t data)
return data;
}
void IRAM_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
void ARDUINO_ISR_ATTR spiWriteShortNL(spi_t * spi, uint16_t data)
{
if(!spi) {
return;
@ -826,7 +1022,7 @@ uint16_t spiTransferShortNL(spi_t * spi, uint16_t data)
return data;
}
void IRAM_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
void ARDUINO_ISR_ATTR spiWriteLongNL(spi_t * spi, uint32_t data)
{
if(!spi) {
return;
@ -861,7 +1057,7 @@ uint32_t spiTransferLongNL(spi_t * spi, uint32_t data)
return data;
}
void spiWriteNL(spi_t * spi, const void * data_in, size_t len){
void spiWriteNL(spi_t * spi, const void * data_in, uint32_t len){
size_t longs = len >> 2;
if(len & 3){
longs++;
@ -887,7 +1083,7 @@ void spiWriteNL(spi_t * spi, const void * data_in, size_t len){
}
}
void spiTransferBytesNL(spi_t * spi, const void * data_in, uint8_t * data_out, size_t len){
void spiTransferBytesNL(spi_t * spi, const void * data_in, uint8_t * data_out, uint32_t len){
if(!spi) {
return;
}
@ -974,7 +1170,7 @@ void spiTransferBitsNL(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits)
}
}
void IRAM_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, size_t len){
void ARDUINO_ISR_ATTR spiWritePixelsNL(spi_t * spi, const void * data_in, uint32_t len){
size_t longs = len >> 2;
if(len & 3){
longs++;

View File

@ -19,6 +19,7 @@
extern "C" {
#endif
#include "sdkconfig.h"
#include <stdint.h>
#include <stdbool.h>
@ -26,7 +27,9 @@ extern "C" {
#define FSPI 1 //SPI bus attached to the flash (can use the same data lines but different SS)
#define HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#if CONFIG_IDF_TARGET_ESP32
#define VSPI 3 //SPI bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
#endif
// This defines are not representing the real Divider of the ESP32
// the Defines match to an AVR Arduino on 16MHz for better compatibility
@ -54,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
@ -96,7 +99,7 @@ void spiSetClockDiv(spi_t * spi, uint32_t clockDiv);
void spiSetDataMode(spi_t * spi, uint8_t dataMode);
void spiSetBitOrder(spi_t * spi, uint8_t bitOrder);
void spiWrite(spi_t * spi, uint32_t *data, uint8_t len);
void spiWrite(spi_t * spi, const uint32_t *data, uint8_t len);
void spiWriteByte(spi_t * spi, uint8_t data);
void spiWriteWord(spi_t * spi, uint16_t data);
void spiWriteLong(spi_t * spi, uint32_t data);
@ -105,7 +108,7 @@ void spiTransfer(spi_t * spi, uint32_t *out, uint8_t len);
uint8_t spiTransferByte(spi_t * spi, uint8_t data);
uint16_t spiTransferWord(spi_t * spi, uint16_t data);
uint32_t spiTransferLong(spi_t * spi, uint32_t data);
void spiTransferBytes(spi_t * spi, uint8_t * data, uint8_t * out, uint32_t size);
void spiTransferBytes(spi_t * spi, const uint8_t * data, uint8_t * out, uint32_t size);
void spiTransferBits(spi_t * spi, uint32_t data, uint32_t * out, uint8_t bits);
/*
@ -115,11 +118,11 @@ void spiTransaction(spi_t * spi, uint32_t clockDiv, uint8_t dataMode, uint8_t bi
void spiSimpleTransaction(spi_t * spi);
void spiEndTransaction(spi_t * spi);
void spiWriteNL(spi_t * spi, const void * data, uint32_t len);
void spiWriteNL(spi_t * spi, const void * data_in, uint32_t len);
void spiWriteByteNL(spi_t * spi, uint8_t data);
void spiWriteShortNL(spi_t * spi, uint16_t data);
void spiWriteLongNL(spi_t * spi, uint32_t data);
void spiWritePixelsNL(spi_t * spi, const void * data, uint32_t len);
void spiWritePixelsNL(spi_t * spi, const void * data_in, uint32_t len);
#define spiTransferNL(spi, data, len) spiTransferBytesNL(spi, data, data, len)
uint8_t spiTransferByteNL(spi_t * spi, uint8_t data);

View File

@ -1,91 +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"
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)
{
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)
{
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;
}

View File

@ -1,308 +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 "rom/ets_sys.h"
#include "soc/timer_group_struct.h"
#include "soc/dport_reg.h"
#include "esp_attr.h"
#include "esp_intr.h"
#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 IRAM_ATTR __timerISR(void * arg){
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;
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) {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_TIMERGROUP1_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP1_RST);
TIMERG1.int_ena.val &= ~BIT(timer->timer);
} else {
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_TIMERGROUP_CLK_EN);
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP_RST);
TIMERG0.int_ena.val &= ~BIT(timer->timer);
}
timer->dev->config.enable = 0;
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){
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);
} else {
TIMERG0.int_ena.val &= ~BIT(timer->timer);
}
__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)(ESP_INTR_FLAG_IRAM|ESP_INTR_FLAG_LOWMED|ESP_INTR_FLAG_EDGE), __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();
}

View File

@ -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_ */

View File

@ -0,0 +1,697 @@
#include "sdkconfig.h"
#if CONFIG_USB_ENABLED
#include <stdlib.h>
#include "esp_log.h"
#include "soc/soc.h"
#include "soc/efuse_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/usb_struct.h"
#include "soc/usb_reg.h"
#include "soc/usb_wrap_reg.h"
#include "soc/usb_wrap_struct.h"
#include "soc/periph_defs.h"
#include "soc/timer_group_struct.h"
#include "soc/system_reg.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "driver/periph_ctrl.h"
#include "esp_efuse.h"
#include "esp_efuse_table.h"
#include "tinyusb.h"
#include "esp32-hal.h"
#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];
static bool WEBUSB_ENABLED = false;
static tusb_str_t WEBUSB_URL = "";
static tusb_str_t USB_DEVICE_PRODUCT = "";
static tusb_str_t USB_DEVICE_MANUFACTURER = "";
static tusb_str_t USB_DEVICE_SERIAL = "";
static uint8_t USB_DEVICE_ATTRIBUTES = 0;
static uint16_t USB_DEVICE_POWER = 0;
/*
* Device Descriptor
* */
static tusb_desc_device_t tinyusb_device_descriptor = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0,
.bDeviceClass = 0,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE,
.idVendor = 0,
.idProduct = 0,
.bcdDevice = 0,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
/*
* String Descriptors
* */
#define MAX_STRING_DESCRIPTORS 20
static uint32_t tinyusb_string_descriptor_len = 4;
static char * tinyusb_string_descriptor[MAX_STRING_DESCRIPTORS] = {
// array of pointer to string descriptors
"\x09\x04", // 0: is supported language is English (0x0409)
USB_DEVICE_MANUFACTURER,// 1: Manufacturer
USB_DEVICE_PRODUCT, // 2: Product
USB_DEVICE_SERIAL, // 3: Serials, should use chip ID
};
/* Microsoft OS 2.0 registry property descriptor
Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx
device should create DeviceInterfaceGUIDs. It can be done by driver and
in case of real PnP solution device should expose MS "Microsoft OS 2.0
registry property descriptor". Such descriptor can insert any record
into Windows registry per device/configuration/interface. In our case it
will insert "DeviceInterfaceGUIDs" multistring property.
GUID is freshly generated and should be OK to use.
https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/
(Section Microsoft OS compatibility descriptors)
*/
#define MS_OS_20_DESC_LEN 0xB2
static uint8_t const tinyusb_ms_os_20_descriptor[] =
{
// Set header: length, type, windows version, total length
U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN),
// Configuration subset header: length, type, configuration index, reserved, configuration total length
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A),
// Function Subset header: length, type, first interface, reserved, subset length
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible
// MS OS 2.0 Registry property descriptor: length, type
U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY),
U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00,
U16_TO_U8S_LE(0x0050), // wPropertyDataLength
//bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
'{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00,
'0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00,
'8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00,
'8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
};
TU_VERIFY_STATIC(sizeof(tinyusb_ms_os_20_descriptor) == MS_OS_20_DESC_LEN, "Incorrect size");
/*
* BOS Descriptor (required for webUSB)
* */
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN)
enum {
VENDOR_REQUEST_WEBUSB = 1,
VENDOR_REQUEST_MICROSOFT = 2
};
static uint8_t const tinyusb_bos_descriptor[] = {
// total length, number of device caps
TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 2),
// Vendor Code, iLandingPage
TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1),
// Microsoft OS 2.0 descriptor
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT)
};
/*
* URL Descriptor (required for webUSB)
* */
typedef struct TU_ATTR_PACKED {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bScheme;
char url[127];
} tinyusb_desc_webusb_url_t;
static tinyusb_desc_webusb_url_t tinyusb_url_descriptor = {
.bLength = 3,
.bDescriptorType = 3, // WEBUSB URL type
.bScheme = 1, // URL Scheme Prefix: 0: "http://", 1: "https://", 255: ""
.url = ""
};
/*
* Configuration Descriptor
* */
static tinyusb_descriptor_cb_t tinyusb_loaded_interfaces_callbacks[USB_INTERFACE_MAX];
static uint32_t tinyusb_loaded_interfaces_mask = 0;
static uint8_t tinyusb_loaded_interfaces_num = 0;
static uint16_t tinyusb_config_descriptor_len = 0;
static uint8_t * tinyusb_config_descriptor = NULL;
/*
* Endpoint Usage Tracking
* */
typedef union {
struct {
uint32_t in:16;
uint32_t out:16;
};
uint32_t val;
} tinyusb_endpoints_usage_t;
static tinyusb_endpoints_usage_t tinyusb_endpoints;
/*
* TinyUSB Callbacks
* */
/**
* @brief Invoked when received GET CONFIGURATION DESCRIPTOR.
*/
uint8_t const *tud_descriptor_configuration_cb(uint8_t index)
{
//log_d("%u", index);
return tinyusb_config_descriptor;
}
/**
* @brief Invoked when received GET DEVICE DESCRIPTOR.
*/
uint8_t const *tud_descriptor_device_cb(void)
{
//log_d("");
return (uint8_t const *)&tinyusb_device_descriptor;
}
/**
* @brief Invoked when received GET STRING DESCRIPTOR request.
*/
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid)
{
//log_d("%u (0x%x)", index, langid);
static uint16_t _desc_str[127];
uint8_t chr_count;
if (index == 0) {
memcpy(&_desc_str[1], tinyusb_string_descriptor[0], 2);
chr_count = 1;
} else {
// Convert ASCII string into UTF-16
if (index >= tinyusb_string_descriptor_len) {
return NULL;
}
const char *str = tinyusb_string_descriptor[index];
// Cap at max char
chr_count = strlen(str);
if (chr_count > 126) {
chr_count = 126;
}
for (uint8_t i = 0; i < chr_count; i++) {
_desc_str[1 + i] = str[i];
}
}
// first byte is len, second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
return _desc_str;
}
/**
* @brief Invoked when received GET BOS DESCRIPTOR request.
*/
uint8_t const * tud_descriptor_bos_cb(void)
{
//log_d("");
return tinyusb_bos_descriptor;
}
__attribute__ ((weak)) bool tinyusb_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request){ return false; }
__attribute__ ((weak)) bool tinyusb_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request){ return true; }
/**
* @brief Handle WebUSB and Vendor requests.
*/
bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request)
{
if(WEBUSB_ENABLED && (request->bRequest == VENDOR_REQUEST_WEBUSB
|| (request->bRequest == VENDOR_REQUEST_MICROSOFT && request->wIndex == 7))){
if(request->bRequest == VENDOR_REQUEST_WEBUSB){
// match vendor request in BOS descriptor
// Get landing page url
tinyusb_url_descriptor.bLength = 3 + strlen(WEBUSB_URL);
snprintf(tinyusb_url_descriptor.url, 127, "%s", WEBUSB_URL);
return tud_control_xfer(rhport, request, (void*) &tinyusb_url_descriptor, tinyusb_url_descriptor.bLength);
}
// Get Microsoft OS 2.0 compatible descriptor
uint16_t total_len;
memcpy(&total_len, tinyusb_ms_os_20_descriptor + 8, 2);
return tud_control_xfer(rhport, request, (void*) tinyusb_ms_os_20_descriptor, total_len);
}
return tinyusb_vendor_control_request_cb(rhport, request);
}
bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request)
{
if(!WEBUSB_ENABLED || !(request->bRequest == VENDOR_REQUEST_WEBUSB
|| (request->bRequest == VENDOR_REQUEST_MICROSOFT && request->wIndex == 7))){
return tinyusb_vendor_control_complete_cb(rhport, request);
}
return true;
}
/*
* Required Callbacks
* */
#if CFG_TUD_HID
__attribute__ ((weak)) const uint8_t * tud_hid_descriptor_report_cb(void){return NULL;}
__attribute__ ((weak)) uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen){return 0;}
__attribute__ ((weak)) void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, const uint8_t * buffer, uint16_t bufsize){}
#endif
#if CFG_TUD_MSC
__attribute__ ((weak)) bool tud_msc_test_unit_ready_cb(uint8_t lun){return false;}
__attribute__ ((weak)) void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]){}
__attribute__ ((weak)) void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size){}
__attribute__ ((weak)) int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize){return -1;}
__attribute__ ((weak)) int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize){return -1;}
__attribute__ ((weak)) int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize){return -1;}
#endif
/*
* Private API
* */
static bool usb_persist_enabled = false;
static restart_type_t usb_persist_mode = RESTART_NO_PERSIST;
static bool tinyusb_reserve_in_endpoint(uint8_t endpoint){
if(endpoint > 6 || (tinyusb_endpoints.in & BIT(endpoint)) != 0){
return false;
}
tinyusb_endpoints.in |= BIT(endpoint);
return true;
}
static bool tinyusb_reserve_out_endpoint(uint8_t endpoint){
if(endpoint > 6 || (tinyusb_endpoints.out & BIT(endpoint)) != 0){
return false;
}
tinyusb_endpoints.out |= BIT(endpoint);
return true;
}
static bool tinyusb_has_available_fifos(void){
uint8_t max_endpoints = 4, active_endpoints = 0;
if (tinyusb_loaded_interfaces_mask & BIT(USB_INTERFACE_CDC)) {
max_endpoints = 5; //CDC endpoint 0x85 is actually not linked to FIFO and not used
}
for(uint8_t i=1; i<7; i++){
if((tinyusb_endpoints.in & BIT(i)) != 0){
active_endpoints++;
}
}
return active_endpoints < max_endpoints;
}
static uint16_t tinyusb_load_descriptor(tinyusb_interface_t interface, uint8_t * dst, uint8_t * itf)
{
if(tinyusb_loaded_interfaces_callbacks[interface]){
return tinyusb_loaded_interfaces_callbacks[interface](dst, itf);
}
return 0;
}
static bool tinyusb_load_enabled_interfaces(){
tinyusb_config_descriptor_len += TUD_CONFIG_DESC_LEN;
tinyusb_config_descriptor = (uint8_t *)malloc(tinyusb_config_descriptor_len);
if (tinyusb_config_descriptor == NULL) {
log_e("Descriptor Malloc Failed");
return false;
}
uint8_t * dst = tinyusb_config_descriptor + TUD_CONFIG_DESC_LEN;
for(int i=0; i<USB_INTERFACE_MAX; i++){
if (tinyusb_loaded_interfaces_mask & (1U << i)) {
uint16_t len = tinyusb_load_descriptor((tinyusb_interface_t)i, dst, &tinyusb_loaded_interfaces_num);
if (!len) {
log_e("Descriptor Load Failed");
return false;
} else {
if(i == USB_INTERFACE_CDC){
if(!tinyusb_reserve_out_endpoint(3) ||!tinyusb_reserve_in_endpoint(4) || !tinyusb_reserve_in_endpoint(5)){
log_e("CDC Reserve Endpoints Failed");
return false;
}
}
dst += len;
}
}
}
uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB Device");
uint8_t descriptor[TUD_CONFIG_DESC_LEN] = {
//num configs, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, tinyusb_loaded_interfaces_num, str_index, tinyusb_config_descriptor_len, USB_DEVICE_ATTRIBUTES, USB_DEVICE_POWER)
};
memcpy(tinyusb_config_descriptor, descriptor, TUD_CONFIG_DESC_LEN);
if ((tinyusb_loaded_interfaces_mask == (BIT(USB_INTERFACE_CDC) | BIT(USB_INTERFACE_DFU))) || (tinyusb_loaded_interfaces_mask == BIT(USB_INTERFACE_CDC))) {
usb_persist_enabled = true;
log_d("USB Persist enabled");
}
log_d("Load Done: if_num: %u, descr_len: %u, if_mask: 0x%x", tinyusb_loaded_interfaces_num, tinyusb_config_descriptor_len, tinyusb_loaded_interfaces_mask);
return true;
}
static inline char nibble_to_hex_char(uint8_t b)
{
if (b < 0xa) {
return '0' + b;
} else {
return 'a' + b - 0xa;
}
}
static void set_usb_serial_num(void)
{
/* Get the MAC address */
const uint32_t mac0 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_0_REG, EFUSE_MAC_0);
const uint32_t mac1 = REG_GET_FIELD(EFUSE_RD_MAC_SPI_SYS_1_REG, EFUSE_MAC_1);
uint8_t mac_bytes[6];
memcpy(mac_bytes, &mac0, 4);
memcpy(mac_bytes + 4, &mac1, 2);
/* Convert to UTF16 string */
uint8_t* srl = (uint8_t*)USB_DEVICE_SERIAL;
for (int i = 0; i < 6; ++i) {
uint8_t b = mac_bytes[5 - i]; /* printing from the MSB */
if (i) {
*srl++ = ':';
}
*srl++ = nibble_to_hex_char(b >> 4);
*srl++ = nibble_to_hex_char(b & 0xf);
}
*srl++ = '\0';
}
static void tinyusb_apply_device_config(tinyusb_device_config_t *config){
if(config->product_name){
snprintf(USB_DEVICE_PRODUCT, 126, "%s", config->product_name);
}
if(config->manufacturer_name){
snprintf(USB_DEVICE_MANUFACTURER, 126, "%s", config->manufacturer_name);
}
if(config->serial_number && config->serial_number[0]){
snprintf(USB_DEVICE_SERIAL, 126, "%s", config->serial_number);
} else {
set_usb_serial_num();
}
if(config->webusb_url){
snprintf(WEBUSB_URL, 126, "%s", config->webusb_url);
}
WEBUSB_ENABLED = config->webusb_enabled;
USB_DEVICE_ATTRIBUTES = config->usb_attributes;
USB_DEVICE_POWER = config->usb_power_ma;
tinyusb_device_descriptor.bcdUSB = config->usb_version;
tinyusb_device_descriptor.idVendor = config->vid;
tinyusb_device_descriptor.idProduct = config->pid;
tinyusb_device_descriptor.bcdDevice = config->fw_version;
tinyusb_device_descriptor.bDeviceClass = config->usb_class;
tinyusb_device_descriptor.bDeviceSubClass = config->usb_subclass;
tinyusb_device_descriptor.bDeviceProtocol = config->usb_protocol;
}
static void IRAM_ATTR usb_persist_shutdown_handler(void)
{
if(usb_persist_mode != RESTART_NO_PERSIST){
if (usb_persist_enabled) {
usb_dc_prepare_persist();
}
if (usb_persist_mode == RESTART_BOOTLOADER) {
//USB CDC Download
if (usb_persist_enabled) {
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
}
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
} else if (usb_persist_mode == RESTART_BOOTLOADER_DFU) {
//DFU Download
chip_usb_set_persist_flags(USBDC_BOOT_DFU);
REG_WRITE(RTC_CNTL_OPTION1_REG, RTC_CNTL_FORCE_DOWNLOAD_BOOT);
} else if (usb_persist_enabled) {
//USB Persist reboot
chip_usb_set_persist_flags(USBDC_PERSIST_ENA);
}
}
}
// USB Device Driver task
// This top level thread processes all usb events and invokes callbacks
static void usb_device_task(void *param) {
(void)param;
while(1) tud_task(); // RTOS forever loop
}
/*
* PUBLIC API
* */
esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb)
{
if((interface >= USB_INTERFACE_MAX) || (tinyusb_loaded_interfaces_mask & (1U << interface))){
log_e("Interface %u not enabled", interface);
return ESP_FAIL;
}
tinyusb_loaded_interfaces_mask |= (1U << interface);
tinyusb_config_descriptor_len += descriptor_len;
tinyusb_loaded_interfaces_callbacks[interface] = cb;
log_d("Interface %u enabled", interface);
return ESP_OK;
}
esp_err_t tinyusb_init(tinyusb_device_config_t *config) {
static bool initialized = false;
if(initialized){
return ESP_OK;
}
initialized = true;
tinyusb_endpoints.val = 0;
tinyusb_apply_device_config(config);
if (!tinyusb_load_enabled_interfaces()) {
initialized = false;
return ESP_FAIL;
}
bool usb_did_persist = (USB_WRAP.date.val == USBDC_PERSIST_ENA);
if(usb_did_persist && usb_persist_enabled){
// Enable USB/IO_MUX peripheral reset, if coming from persistent reboot
REG_CLR_BIT(RTC_CNTL_USB_CONF_REG, RTC_CNTL_IO_MUX_RESET_DISABLE);
REG_CLR_BIT(RTC_CNTL_USB_CONF_REG, RTC_CNTL_USB_RESET_DISABLE);
} else {
// Reset USB module
periph_module_reset(PERIPH_USB_MODULE);
periph_module_enable(PERIPH_USB_MODULE);
}
if (esp_register_shutdown_handler(usb_persist_shutdown_handler) != ESP_OK) {
initialized = false;
return ESP_FAIL;
}
tinyusb_config_t tusb_cfg = {
.external_phy = false // In the most cases you need to use a `false` value
};
esp_err_t err = tinyusb_driver_install(&tusb_cfg);
if (err != ESP_OK) {
initialized = false;
return err;
}
xTaskCreate(usb_device_task, "usbd", 4096, NULL, configMAX_PRIORITIES - 1, NULL);
return err;
}
void usb_persist_restart(restart_type_t mode)
{
if (mode < RESTART_TYPE_MAX) {
usb_persist_mode = mode;
esp_restart();
}
}
uint8_t tinyusb_add_string_descriptor(const char * str){
if(str == NULL || tinyusb_string_descriptor_len >= MAX_STRING_DESCRIPTORS){
return 0;
}
uint8_t index = tinyusb_string_descriptor_len;
tinyusb_string_descriptor[tinyusb_string_descriptor_len++] = (char*)str;
return index;
}
uint8_t tinyusb_get_free_duplex_endpoint(void){
if(!tinyusb_has_available_fifos()){
log_e("No available IN endpoints");
return 0;
}
for(uint8_t i=1; i<7; i++){
if((tinyusb_endpoints.in & BIT(i)) == 0 && (tinyusb_endpoints.out & BIT(i)) == 0){
tinyusb_endpoints.in |= BIT(i);
tinyusb_endpoints.out |= BIT(i);
return i;
}
}
log_e("No available duplex endpoints");
return 0;
}
uint8_t tinyusb_get_free_in_endpoint(void){
if(!tinyusb_has_available_fifos()){
log_e("No available IN endpoints");
return 0;
}
for(uint8_t i=1; i<7; i++){
if((tinyusb_endpoints.in & BIT(i)) == 0 && (tinyusb_endpoints.out & BIT(i)) != 0){
tinyusb_endpoints.in |= BIT(i);
return i;
}
}
for(uint8_t i=1; i<7; i++){
if((tinyusb_endpoints.in & BIT(i)) == 0){
tinyusb_endpoints.in |= BIT(i);
return i;
}
}
return 0;
}
uint8_t tinyusb_get_free_out_endpoint(void){
for(uint8_t i=1; i<7; i++){
if((tinyusb_endpoints.out & BIT(i)) == 0 && (tinyusb_endpoints.in & BIT(i)) != 0){
tinyusb_endpoints.out |= BIT(i);
return i;
}
}
for(uint8_t i=1; i<7; i++){
if((tinyusb_endpoints.out & BIT(i)) == 0){
tinyusb_endpoints.out |= BIT(i);
return i;
}
}
return 0;
}
/*
void usb_dw_reg_dump(void)
{
#define USB_PRINT_REG(r) printf("USB0." #r " = 0x%x;\n", USB0.r)
#define USB_PRINT_IREG(i, r) printf("USB0.in_ep_reg[%u]." #r " = 0x%x;\n", i, USB0.in_ep_reg[i].r)
#define USB_PRINT_OREG(i, r) printf("USB0.out_ep_reg[%u]." #r " = 0x%x;\n", i, USB0.out_ep_reg[i].r)
uint8_t i;
USB_PRINT_REG(gotgctl);
USB_PRINT_REG(gotgint);
USB_PRINT_REG(gahbcfg);
USB_PRINT_REG(gusbcfg);
USB_PRINT_REG(grstctl);
USB_PRINT_REG(gintsts);
USB_PRINT_REG(gintmsk);
USB_PRINT_REG(grxstsr);
USB_PRINT_REG(grxstsp);
USB_PRINT_REG(grxfsiz);
USB_PRINT_REG(gnptxsts);
USB_PRINT_REG(gpvndctl);
USB_PRINT_REG(ggpio);
USB_PRINT_REG(guid);
USB_PRINT_REG(gsnpsid);
USB_PRINT_REG(ghwcfg1);
USB_PRINT_REG(ghwcfg2);
USB_PRINT_REG(ghwcfg3);
USB_PRINT_REG(ghwcfg4);
USB_PRINT_REG(glpmcfg);
USB_PRINT_REG(gpwrdn);
USB_PRINT_REG(gdfifocfg);
USB_PRINT_REG(gadpctl);
USB_PRINT_REG(hptxfsiz);
USB_PRINT_REG(hcfg);
USB_PRINT_REG(hfir);
USB_PRINT_REG(hfnum);
USB_PRINT_REG(hptxsts);
USB_PRINT_REG(haint);
USB_PRINT_REG(haintmsk);
USB_PRINT_REG(hflbaddr);
USB_PRINT_REG(hprt);
USB_PRINT_REG(dcfg);
USB_PRINT_REG(dctl);
USB_PRINT_REG(dsts);
USB_PRINT_REG(diepmsk);
USB_PRINT_REG(doepmsk);
USB_PRINT_REG(daint);
USB_PRINT_REG(daintmsk);
USB_PRINT_REG(dtknqr1);
USB_PRINT_REG(dtknqr2);
USB_PRINT_REG(dvbusdis);
USB_PRINT_REG(dvbuspulse);
USB_PRINT_REG(dtknqr3_dthrctl);
USB_PRINT_REG(dtknqr4_fifoemptymsk);
USB_PRINT_REG(deachint);
USB_PRINT_REG(deachintmsk);
USB_PRINT_REG(pcgctrl);
USB_PRINT_REG(pcgctrl1);
USB_PRINT_REG(gnptxfsiz);
for (i = 0; i < 4; i++) {
printf("USB0.dieptxf[%u] = 0x%x;\n", i, USB0.dieptxf[i]);
}
// for (i = 0; i < 16; i++) {
// printf("USB0.diepeachintmsk[%u] = 0x%x;\n", i, USB0.diepeachintmsk[i]);
// }
// for (i = 0; i < 16; i++) {
// printf("USB0.doepeachintmsk[%u] = 0x%x;\n", i, USB0.doepeachintmsk[i]);
// }
for (i = 0; i < 7; i++) {
printf("// EP %u:\n", i);
USB_PRINT_IREG(i, diepctl);
USB_PRINT_IREG(i, diepint);
USB_PRINT_IREG(i, dieptsiz);
USB_PRINT_IREG(i, diepdma);
USB_PRINT_IREG(i, dtxfsts);
USB_PRINT_OREG(i, doepctl);
USB_PRINT_OREG(i, doepint);
USB_PRINT_OREG(i, doeptsiz);
USB_PRINT_OREG(i, doepdma);
}
}
*/
#endif /* CONFIG_USB_ENABLED */

View File

@ -0,0 +1,103 @@
// Copyright 2015-2020 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
#include "esp32-hal.h"
#if CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_USB_ENABLED
#ifdef __cplusplus
extern "C" {
#endif
#include "tinyusb.h"
typedef struct {
uint16_t vid;
uint16_t pid;
const char * product_name;
const char * manufacturer_name;
const char * serial_number;
uint16_t fw_version;
uint16_t usb_version;
uint8_t usb_class;
uint8_t usb_subclass;
uint8_t usb_protocol;
uint8_t usb_attributes;
uint16_t usb_power_ma;
bool webusb_enabled;
const char * webusb_url;
} tinyusb_device_config_t;
#define TINYUSB_CONFIG_DEFAULT() { \
.vid = USB_ESPRESSIF_VID, \
.pid = 0x0002, \
.product_name = CONFIG_USB_DESC_PRODUCT_STRING, \
.manufacturer_name = CONFIG_USB_DESC_MANUFACTURER_STRING, \
.serial_number = CONFIG_USB_DESC_SERIAL_STRING, \
.fw_version = CONFIG_USB_DESC_BCDDEVICE, \
.usb_version = 0x0200, \
.usb_class = TUSB_CLASS_MISC, \
.usb_subclass = MISC_SUBCLASS_COMMON, \
.usb_protocol = MISC_PROTOCOL_IAD, \
.usb_attributes = TUSB_DESC_CONFIG_ATT_SELF_POWERED, \
.usb_power_ma = 500, \
.webusb_enabled = false, \
.webusb_url = "espressif.github.io/arduino-esp32/webusb.html" \
}
esp_err_t tinyusb_init(tinyusb_device_config_t *config);
/*
* USB Persistence API
* */
typedef enum {
RESTART_NO_PERSIST,
RESTART_PERSIST,
RESTART_BOOTLOADER,
RESTART_BOOTLOADER_DFU,
RESTART_TYPE_MAX
} restart_type_t;
void usb_persist_restart(restart_type_t mode);
// The following definitions and functions are to be used only by the drivers
typedef enum {
USB_INTERFACE_CDC,
USB_INTERFACE_DFU,
USB_INTERFACE_HID,
USB_INTERFACE_VENDOR,
USB_INTERFACE_MSC,
USB_INTERFACE_MIDI,
USB_INTERFACE_CUSTOM,
USB_INTERFACE_MAX
} tinyusb_interface_t;
typedef uint16_t (*tinyusb_descriptor_cb_t)(uint8_t * dst, uint8_t * itf);
esp_err_t tinyusb_enable_interface(tinyusb_interface_t interface, uint16_t descriptor_len, tinyusb_descriptor_cb_t cb);
uint8_t tinyusb_add_string_descriptor(const char * str);
uint8_t tinyusb_get_free_duplex_endpoint(void);
uint8_t tinyusb_get_free_in_endpoint(void);
uint8_t tinyusb_get_free_out_endpoint(void);
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_USB_ENABLED */
#endif /* CONFIG_IDF_TARGET_ESP32S2 */

View File

@ -12,15 +12,34 @@
// 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"
#include "rom/ets_sys.h"
#include "esp_attr.h"
#include "esp_intr.h"
#include "soc/rtc_io_reg.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/sens_reg.h"
#include "soc/sens_struct.h"
#include "driver/touch_sensor.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
#include "esp32-hal-gpio.h"
static uint16_t __touchSleepCycles = 0x1000;
static uint16_t __touchMeasureCycles = 0x1000;
@ -29,8 +48,9 @@ typedef void (*voidFuncPtr)(void);
static voidFuncPtr __touchInterruptHandlers[10] = {0,};
static intr_handle_t touch_intr_handle = NULL;
void IRAM_ATTR __touchISR(void * arg)
void ARDUINO_ISR_ATTR __touchISR(void * arg)
{
#if CONFIG_IDF_TARGET_ESP32
uint32_t pad_intr = READ_PERI_REG(SENS_SAR_TOUCH_CTRL2_REG) & 0x3ff;
uint32_t rtc_intr = READ_PERI_REG(RTC_CNTL_INT_ST_REG);
uint8_t i = 0;
@ -47,16 +67,21 @@ void IRAM_ATTR __touchISR(void * arg)
}
}
}
#endif
}
void __touchSetCycles(uint16_t measure, uint16_t sleep)
{
__touchSleepCycles = sleep;
__touchMeasureCycles = measure;
#if CONFIG_IDF_TARGET_ESP32
//Touch pad SleepCycle Time
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_SLEEP_CYCLES, __touchSleepCycles, SENS_TOUCH_SLEEP_CYCLES_S);
//Touch Pad Measure Time
SET_PERI_REG_BITS(SENS_SAR_TOUCH_CTRL1_REG, SENS_TOUCH_MEAS_DELAY, __touchMeasureCycles, SENS_TOUCH_MEAS_DELAY_S);
#else
touch_pad_set_meas_time(sleep, measure);
#endif
}
void __touchInit()
@ -66,15 +91,27 @@ void __touchInit()
return;
}
initialized = true;
#if CONFIG_IDF_TARGET_ESP32
SET_PERI_REG_BITS(RTC_IO_TOUCH_CFG_REG, RTC_IO_TOUCH_XPD_BIAS, 1, RTC_IO_TOUCH_XPD_BIAS_S);
SET_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_MEAS_EN_CLR);
//clear touch enable
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, 0x0);
SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_TOUCH_SLP_TIMER_EN);
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __touchISR, NULL, &touch_intr_handle);
esp_intr_alloc(ETS_RTC_CORE_INTR_SOURCE, (int)ARDUINO_ISR_FLAG, __touchISR, NULL, &touch_intr_handle);
#else
touch_pad_init();
touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V5);
touch_pad_set_idle_channel_connect(TOUCH_PAD_CONN_GND);
__touchSetCycles(__touchMeasureCycles, __touchSleepCycles);
touch_pad_denoise_t denoise = {
.grade = TOUCH_PAD_DENOISE_BIT4,
.cap_level = TOUCH_PAD_DENOISE_CAP_L4,
};
touch_pad_denoise_set_config(&denoise);
touch_pad_denoise_enable();
touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
touch_pad_fsm_start();
#endif
}
uint16_t __touchRead(uint8_t pin)
@ -88,6 +125,7 @@ uint16_t __touchRead(uint8_t pin)
__touchInit();
#if CONFIG_IDF_TARGET_ESP32
uint32_t v0 = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
//Disable Intr & enable touch pad
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG,
@ -119,6 +157,25 @@ uint16_t __touchRead(uint8_t pin)
//restore previous value
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, v0);
return touch_value;
#else
static uint32_t chan_mask = 0;
uint32_t value = 0;
if((chan_mask & (1 << pad)) == 0){
if(touch_pad_set_thresh((touch_pad_t)pad, TOUCH_PAD_THRESHOLD_MAX) != ESP_OK){
log_e("touch_pad_set_thresh failed");
} else if(touch_pad_config((touch_pad_t)pad) != ESP_OK){
log_e("touch_pad_config failed");
} else {
chan_mask |= (1 << pad);
}
}
if((chan_mask & (1 << pad)) != 0) {
if(touch_pad_read_raw_data((touch_pad_t)pad, &value) != ESP_OK){
log_e("touch_pad_read_raw_data failed");
}
}
return value;
#endif
}
void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t threshold)
@ -134,6 +191,7 @@ void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t thresh
__touchInterruptHandlers[pad] = userFunc;
#if CONFIG_IDF_TARGET_ESP32
//clear touch force ,select the Touch mode is Timer
CLEAR_PERI_REG_MASK(SENS_SAR_TOUCH_CTRL2_REG, SENS_TOUCH_START_EN_M|SENS_TOUCH_START_FORCE_M);
@ -161,6 +219,9 @@ void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), uint16_t thresh
(1 << (pad + SENS_TOUCH_PAD_WORKEN_S)) | \
(1 << (pad + SENS_TOUCH_PAD_OUTEN2_S)) | \
(1 << (pad + SENS_TOUCH_PAD_OUTEN1_S)));
#else
#endif
}
extern uint16_t touchRead(uint8_t pin) __attribute__ ((weak, alias("__touchRead")));

View File

@ -24,7 +24,7 @@
extern "C" {
#endif
#include "esp32-hal.h"
#include <stdint.h>
/*
* Set cycles that measurement operation takes

View File

@ -1,582 +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 "rom/ets_sys.h"
#include "esp_attr.h"
#include "esp_intr.h"
#include "rom/uart.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"
#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)))
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[3] = {
{(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL},
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL},
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL}
};
#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[3] = {
{(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL},
{(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL},
{(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL}
};
#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 IRAM_ATTR _uart_isr(void *arg)
{
uint8_t i, c;
BaseType_t xHigherPriorityTaskWoken;
uart_t* uart;
for(i=0;i<3;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;
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;
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
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;
uart->dev->conf1.rx_tout_thrhd = 2;
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)ESP_INTR_FLAG_IRAM, _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 > 39) {
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 > 39) {
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 > 2) {
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);
} 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);
} 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;
}
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 NULL;
}
}
UART_MUTEX_UNLOCK();
return new_size;
}
uint32_t uartAvailable(uart_t* uart)
{
if(uart == NULL || uart->queue == NULL) {
return 0;
}
return uxQueueMessagesWaiting(uart->queue);
}
uint32_t uartAvailableForWrite(uart_t* uart)
{
if(uart == NULL) {
return 0;
}
return 0x7f - uart->dev->status.txfifo_cnt;
}
uint8_t uartRead(uart_t* uart)
{
if(uart == NULL || uart->queue == NULL) {
return 0;
}
uint8_t c;
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(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);
uart->dev->fifo.rw_byte = c;
UART_MUTEX_UNLOCK();
}
void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len)
{
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
while(len) {
while(uart->dev->status.txfifo_cnt == 0x7F);
uart->dev->fifo.rw_byte = *data++;
len--;
}
UART_MUTEX_UNLOCK();
}
void uartFlush(uart_t* uart)
{
if(uart == NULL) {
return;
}
UART_MUTEX_LOCK();
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
//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);
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;
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;
if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) {
xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken);
}
}
// wait TX empty
while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out);
} else {
//todo:
// set baudrate
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 IRAM_ATTR uart0_write_char(char c)
{
while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
ESP_REG(DR_REG_UART_BASE) = c;
}
static void IRAM_ATTR uart1_write_char(char c)
{
while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F);
ESP_REG(DR_REG_UART1_BASE) = c;
}
static void IRAM_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;
}
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;
case 2:
ets_install_putc1((void (*)(char)) &uart2_write_char);
break;
default:
ets_install_putc1(NULL);
break;
}
}
void uartSetDebug(uart_t* uart)
{
if(uart == NULL || uart->num > 2) {
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, ...)
{
if(s_uart_debug_nr < 0){
return 0;
}
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(_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) {
return uart->dev->status.st_urx_out != 0;
}

View File

@ -1,84 +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 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_ */

View File

@ -20,101 +20,56 @@
#ifndef HAL_ESP32_HAL_H_
#define HAL_ESP32_HAL_H_
#ifdef __cplusplus
extern "C" {
//#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
#if CONFIG_ARDUINO_ISR_IRAM
#define ARDUINO_ISR_ATTR IRAM_ATTR
#define ARDUINO_ISR_FLAG ESP_INTR_FLAG_IRAM
#else
#define ARDUINO_ISR_ATTR
#define ARDUINO_ISR_FLAG (0)
#endif
#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"
#ifndef F_CPU
#define F_CPU (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ * 1000000U)
#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"
#ifndef BOARD_HAS_PSRAM
#ifdef CONFIG_SPIRAM_SUPPORT
#undef CONFIG_SPIRAM_SUPPORT
#endif
#endif
////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_ */

View File

@ -18,7 +18,7 @@
#define _ESP8266_COMPAT_H_
#define ICACHE_FLASH_ATTR
#define ICACHE_RAM_ATTR IRAM_ATTR
#define ICACHE_RAM_ATTR ARDUINO_ISR_ATTR
#endif /* _ESP8266_COMPAT_H_ */

View 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

View File

@ -1,7 +0,0 @@
libb64: Base64 Encoding/Decoding Routines
======================================
Authors:
-------
Chris Venter chris.venter@gmail.com http://rocketpod.blogspot.com

View File

@ -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.

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -1,30 +0,0 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h"
TaskHandle_t loopTaskHandle = NULL;
#if CONFIG_AUTOSTART_ARDUINO
bool loopTaskWDTEnabled;
void loopTask(void *pvParameters)
{
setup();
for(;;) {
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
loop();
}
}
extern "C" void app_main()
{
loopTaskWDTEnabled = false;
initArduino();
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
}
#endif

View File

@ -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)

View File

@ -28,8 +28,6 @@
#include <stdio.h>
#include <stdarg.h>
#include "Arduino.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -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);
//}

View File

@ -17,8 +17,10 @@
$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;

View 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);

View File

@ -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)
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)
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

View File

@ -1,13 +1,12 @@
Installation instructions using Arduino IDE Boards Manager
==========================================================
## Installation instructions using Arduino IDE Boards Manager
### ==========================================================
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 and 64 bit).
- 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 (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.
- Enter ```https://dl.espressif.com/dl/package_esp32_index.json``` into *Additional Board Manager URLs* field. You can add multiple URLs, separating them with commas.
- Enter one of the release links above into *Additional Board Manager URLs* field. You can add multiple URLs, separating them with commas.
- Open Boards Manager from Tools > Board menu and install *esp32* platform (and don't forget to select your ESP32 board from Tools > Board menu after installation).
Stable release link: `https://dl.espressif.com/dl/package_esp32_index.json`
Development release link: `https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json`

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