Compare commits

...

47 Commits

Author SHA1 Message Date
2fba81223e Added instructions for installation with boards manager (#1630)
* Added instructions for installation with boards manager (stolen directly from esp8266)

* changed to production link instead of dev

* Added to main README. Made mods to images as requested.

* Added links for development package
2018-07-26 08:10:46 +02:00
e51f7a5b87 fix compilation errors in idf 2018-07-25 22:39:32 +02:00
7d2560cbbf roll back the while loop in _parseForm 2018-07-25 20:59:56 +02:00
17065dfd3a Added a define to format the spiffs in SPIFFS_Test.ino (#1662)
* Added a define to format the spiffs in SPIFFS_Test.ino

* Uncommented the define

* Matched define names
2018-07-25 18:44:37 +02:00
2f5b3c0c56 Functions _uploadReadByte and _parseForm were modified in order to (#1677)
speed up uploading data. Now there is no need to call time consuming
client.connected() method.
2018-07-25 17:37:15 +02:00
1fe3ee87b6 Feature/selective compilation (#1671)
* Selective compilation

* Optimized component.mk

* Autoconnect WiFi now forces WiFi
2018-07-25 13:02:37 +02:00
328523f5e3 Memory leak (#1672)
When a package of size 0 arrives, "buf" is created, but never released. (Sorry, that was my mistake in the last patch)
2018-07-25 12:56:41 +02:00
Bin
7761ebd9f2 Add M5Stack-FIRE board (#1647)
* Add M5Stack-FIRE board

* updated m5stack-fire boards.txt

* remove pins 16 and 17
2018-07-25 12:56:04 +02:00
f9a382ab9f fix some compilation error and warnings in i2c 2018-07-24 22:06:50 +02:00
d854dc1bf6 Create WiFiClientEnterprise.ino (#1640)
Sketch for ESP32 boards that allow them to connect to WPA/WPA2 Enterprise Networks.
2018-07-24 19:57:57 +02:00
f1f8d7e306 Packet with zero data length (#1659)
If you receive a package with a data length of zero, parsePacket returns 0, but rx_buffer will exist. So if another parsePacket with no read access returns to zeros, there is still data that can be read. This example would not work: https://www.arduino.cc/en/Reference/EthernetUDPParsePacket

Also I added a check if rx_buffer exit when you try to flush it.
2018-07-24 19:52:42 +02:00
da798c7db0 Add TTGO LoRa32 with OLED Version 1.x Board (#1663)
* Add ttgo-lora32-v1 folder to variants folder

* Add ttgo-lora32-v1 info to boards.txt

* Add defs to pins_arduino.h for I2C OLED and SPI LoRa radio pinouts as per @stickbreaker
2018-07-24 19:49:38 +02:00
8d7fb58672 Fix for spurious interrupts during I2C communications (#1665)
This version no longer needs an interrupt for each byte transferred. It only needs interrupts for START, STOP, FIFO empty/Full or error conditions.  This dramatically reduces the interrupt overhead.  I think the prior version was causing an interrupt overload condition where the ISR was not able to process every interrupt as they happened.
2018-07-24 19:43:45 +02:00
2fda054bea [OTA Timeout] Added ability set OTA timeout in the OTA client (#1669) 2018-07-24 19:40:18 +02:00
Luc
e157ec06a7 expose post args during upload (#1650) 2018-07-17 10:58:03 +02:00
05d72f963d fix WiFi STA going into loop in some cases of disconnect 2018-07-16 22:50:52 +02:00
b14f82b65f Release notes formatting update (#1634) 2018-07-16 20:47:30 +02:00
c830511f01 EEPROM library: Move #include of Arduino.h to header file (#1641)
EEPROM.h uses data types which are declared through Arduino.h but that file does not contain an #include directive for Arduino.h. This does not cause any problems when the EEPROM library is #included from a .ino file because the Arduino IDE automatically adds an #include directive for Arduino.h but this is not the case for .cpp files. If a .cpp file has an #include directive for EEPROM.h that does not follow an #include directive for Arduino.h then compilation fails:

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:91:5: error: 'float_t' does not name a type

     float_t readFloat(int address);

     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:92:5: error: 'double_t' does not name a type

     double_t readDouble(int address);

     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:95:5: error: 'String' does not name a type

     String readString(int address);

     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:110:36: error: 'float_t' has not been declared

     size_t writeFloat(int address, float_t value);

                                    ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:111:37: error: 'double_t' has not been declared

     size_t writeDouble(int address, double_t value);

                                     ^

E:\arduino\hardware\espressif\esp32\libraries\EEPROM/EEPROM.h:114:37: error: 'String' has not been declared

     size_t writeString(int address, String value);
2018-07-16 20:44:36 +02:00
cbd4dc53a6 Add ALKS board variant (#1643)
* Initial support for ALKS variant
2018-07-16 20:43:35 +02:00
44f5a4dbc8 Fix Client returning disconnected because of VFS errors 2018-07-16 20:08:27 +02:00
e63aa40650 Enable PSRAM builds when used as IDF component 2018-07-15 10:20:01 +02:00
28a410dd50 Spurious Interrupts Temporary fix 20180711 (#1625)
the 'eject' ERROR is and indication of an interrupt triggering without an source.  I am working to eliminate these serviceable interrupt.  This update increase stability on a HelTek Wifi Lora 32 board. with a SSD1306 OLED.  This update fixes a glaring error in the interrupt allocation code, the Interrupt mask was wrong.  I also dynamically adjust the FiFo thresholds based on Bus clockrate. The change to FiFo thresholds has reduced the number for 'eject' events.  I also change 'eject' from and ERROR to DEBUG.  An 'eject' event does not compromise i2c transmissions. It happens after a transaction has completed. 

Chuck.
2018-07-12 15:18:26 +02:00
ddfeae90d0 Fix AsyncUDP server exception 2018-07-11 20:46:54 +02:00
ff90778173 Fix HTTP client returning disconnected when there is still data avalable 2018-07-10 21:06:20 +02:00
4e9d1ee237 Fix connected to be wrongly reported in WiFiClient 2018-07-10 21:05:44 +02:00
c1a94b5326 Fix wrong event description 2018-07-10 16:13:34 +02:00
3e160587f3 Fix WiFi Client not properly reporting connected state 2018-07-10 15:01:40 +02:00
79010b6498 Add XinaBox CW02 to supported boards (#1620)
* Create pins_arduino.h

* Update boards.txt

* Update pins_arduino.h
2018-07-10 13:43:21 +02:00
9925772db0 * update 'version' in platform.txt (#1619) 2018-07-10 11:26:19 +02:00
c77aed4ac4 Allow using argument with attachInterrupt (#1535)
* Allow using argument with attachInterrupt

* formatting

replace tabs with spaces

* fix bug more then 1 interrupt

* leftover

* add example

* make attachInterruptArg public

* update example

* leftover
2018-07-07 11:26:58 +02:00
901a341949 BluetoothSerial: set COD to be compatible with macOS (#1304) (#1556) 2018-07-07 11:25:10 +02:00
9f6d0d2958 EEPROM.readstring was returning an extra character (#1609) 2018-07-07 10:19:44 +02:00
9efecc1be0 Implement RX buffer for WiFi client to speed up small reads 2018-07-05 22:31:58 +02:00
b0c6991bcf Small adjustments to the web server 2018-07-05 22:31:19 +02:00
8afdd71b3a Add missing event string to WiFi events 2018-07-05 22:30:54 +02:00
871dd183d8 Print to debug the IP address obtained by DHCP 2018-07-05 16:04:07 +02:00
05111bbde7 fix case where library source subfolders are not compiled when used as component 2018-07-05 14:27:17 +02:00
bad53905e8 Prevent exceptions in WiFi if not yet started 2018-07-05 12:28:15 +02:00
95b87545e7 Make Stream functions if File to not wait for timeout
Fixes: https://github.com/espressif/arduino-esp32/issues/1597
2018-07-05 11:51:58 +02:00
9f8f05735b * relnotes handling update (#1592)
* script exec fails on curl error
2018-07-04 15:46:46 +02:00
a835bb26c4 Add missing flag to fix psram issues
Thanks @igrr
2018-07-04 12:11:25 +02:00
5e46c9bae6 Add Wrover Support and Option to enable SPIRAM 2018-07-03 23:03:50 +02:00
659c8ad528 Fix TelnetToSerial sketch 2018-07-03 21:51:24 +02:00
2fe965259a "fix" SPI 2018-07-03 21:23:04 +02:00
0161e28614 Added OTAWebUpdater Doc (#1583) 2018-07-03 20:43:18 +02:00
4e5cbdaa7f Add declarations for all Serial, SPI and Wire buses 2018-07-03 20:41:03 +02:00
12ca9e8b52 Port UART reset fix from ESP-IDF (#1408) 2018-07-03 17:54:08 +02:00
52 changed files with 1828 additions and 412 deletions

View File

@ -106,8 +106,147 @@ 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_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
default y
config ARDUINO_SELECTIVE_SPIFFS
bool "Enable SPIFFS"
depends on ARDUINO_SELECTIVE_COMPILATION
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
default y
endmenu

View File

@ -9,7 +9,7 @@ endif
BOOT_APP_BIN_FLASH_CMD = $(ESPTOOLPY_SERIAL) write_flash $(BOOT_APP_BIN_OFFSET) $(BOOT_APP_BIN_PATH)
ESPTOOL_ALL_FLASH_ARGS += $(BOOT_APP_BIN_OFFSET) $(BOOT_APP_BIN_PATH)
CPPFLAGS += -DARDUINO=10800 -DESP32=1 -DARDUINO_ARCH_ESP32=1
CPPFLAGS += -DARDUINO=10800 -DESP32=1 -DARDUINO_ARCH_ESP32=1 -DBOARD_HAS_PSRAM
boot-app0:
@echo "Rebooting to APP0"

View File

@ -19,7 +19,11 @@ Most of the framework is implemented. Most noticable is the missing analogWrite.
## Installation Instructions
- Using Arduino IDE
#### [Latest release ![Release Version](https://img.shields.io/github/release/espressif/arduino-esp32/all.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/)
- Using Arduino IDE Boards Manager (preferred)
+ [Instructions for Boards Manager](docs/arduino-ide/boards_manager.md)
- Using Arduino IDE with the development repository
+ [Instructions for Windows](docs/arduino-ide/windows.md)
+ [Instructions for Mac](docs/arduino-ide/mac.md)
+ [Instructions for Debian/Ubuntu Linux](docs/arduino-ide/debian_ubuntu.md)
@ -28,6 +32,7 @@ Most of the framework is implemented. Most noticable is the missing analogWrite.
- [Using PlatformIO](docs/platformio.md)
- [Building with make](docs/make.md)
- [Using as ESP-IDF component](docs/esp-idf_component.md)
- [Using OTAWebUpdater](docs/OTAWebUpdate/OTAWebUpdate.md)
#### Decoding exceptions

View File

@ -4,6 +4,63 @@ menu.FlashMode=Flash Mode
menu.FlashSize=Flash Size
menu.PartitionScheme=Partition Scheme
menu.DebugLevel=Core Debug Level
menu.PSRAM=PSRAM
##############################################################
ttgo-lora32-v1.name=TTGO LoRa32-OLED V1
ttgo-lora32-v1.upload.tool=esptool
ttgo-lora32-v1.upload.maximum_size=1310720
ttgo-lora32-v1.upload.maximum_data_size=294912
ttgo-lora32-v1.upload.wait_for_upload_port=true
ttgo-lora32-v1.serial.disableDTR=true
ttgo-lora32-v1.serial.disableRTS=true
ttgo-lora32-v1.build.mcu=esp32
ttgo-lora32-v1.build.core=esp32
ttgo-lora32-v1.build.variant=ttgo-lora32-v1
ttgo-lora32-v1.build.board=TTGO_LoRa32_V1
ttgo-lora32-v1.build.f_cpu=240000000L
ttgo-lora32-v1.build.flash_mode=dio
ttgo-lora32-v1.build.flash_size=4MB
ttgo-lora32-v1.build.boot=dio
ttgo-lora32-v1.build.partitions=default
ttgo-lora32-v1.menu.FlashFreq.80=80MHz
ttgo-lora32-v1.menu.FlashFreq.80.build.flash_freq=80m
ttgo-lora32-v1.menu.FlashFreq.40=40MHz
ttgo-lora32-v1.menu.FlashFreq.40.build.flash_freq=40m
ttgo-lora32-v1.menu.UploadSpeed.921600=921600
ttgo-lora32-v1.menu.UploadSpeed.921600.upload.speed=921600
ttgo-lora32-v1.menu.UploadSpeed.115200=115200
ttgo-lora32-v1.menu.UploadSpeed.115200.upload.speed=115200
ttgo-lora32-v1.menu.UploadSpeed.256000.windows=256000
ttgo-lora32-v1.menu.UploadSpeed.256000.upload.speed=256000
ttgo-lora32-v1.menu.UploadSpeed.230400.windows.upload.speed=256000
ttgo-lora32-v1.menu.UploadSpeed.230400=230400
ttgo-lora32-v1.menu.UploadSpeed.230400.upload.speed=230400
ttgo-lora32-v1.menu.UploadSpeed.460800.linux=460800
ttgo-lora32-v1.menu.UploadSpeed.460800.macosx=460800
ttgo-lora32-v1.menu.UploadSpeed.460800.upload.speed=460800
ttgo-lora32-v1.menu.UploadSpeed.512000.windows=512000
ttgo-lora32-v1.menu.UploadSpeed.512000.upload.speed=512000
ttgo-lora32-v1.menu.DebugLevel.none=None
ttgo-lora32-v1.menu.DebugLevel.none.build.code_debug=0
ttgo-lora32-v1.menu.DebugLevel.error=Error
ttgo-lora32-v1.menu.DebugLevel.error.build.code_debug=1
ttgo-lora32-v1.menu.DebugLevel.warn=Warn
ttgo-lora32-v1.menu.DebugLevel.warn.build.code_debug=2
ttgo-lora32-v1.menu.DebugLevel.info=Info
ttgo-lora32-v1.menu.DebugLevel.info.build.code_debug=3
ttgo-lora32-v1.menu.DebugLevel.debug=Debug
ttgo-lora32-v1.menu.DebugLevel.debug.build.code_debug=4
ttgo-lora32-v1.menu.DebugLevel.verbose=Verbose
ttgo-lora32-v1.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
@ -28,6 +85,12 @@ esp32.build.flash_freq=40m
esp32.build.flash_mode=dio
esp32.build.boot=dio
esp32.build.partitions=default
esp32.build.defines=
esp32.menu.PSRAM.disabled=Disabled
esp32.menu.PSRAM.disabled.build.defines=
esp32.menu.PSRAM.enabled=Enabled
esp32.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
esp32.menu.PartitionScheme.default=Default
esp32.menu.PartitionScheme.default.build.partitions=default
@ -94,6 +157,164 @@ esp32.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
cw02.name=XinaBox CW02
cw02.upload.tool=esptool
cw02.upload.maximum_size=1310720
cw02.upload.maximum_data_size=294912
cw02.upload.wait_for_upload_port=true
cw02.serial.disableDTR=true
cw02.serial.disableRTS=true
cw02.build.mcu=esp32
cw02.build.core=esp32
cw02.build.variant=xinabox
cw02.build.board=ESP32_DEV
cw02.build.f_cpu=240000000L
cw02.build.flash_size=4MB
cw02.build.flash_freq=40m
cw02.build.flash_mode=dio
cw02.build.boot=dio
cw02.build.partitions=default
cw02.menu.FlashMode.qio=QIO
cw02.menu.FlashMode.qio.build.flash_mode=dio
cw02.menu.FlashMode.qio.build.boot=qio
cw02.menu.FlashMode.dio=DIO
cw02.menu.FlashMode.dio.build.flash_mode=dio
cw02.menu.FlashMode.dio.build.boot=dio
cw02.menu.FlashMode.qout=QOUT
cw02.menu.FlashMode.qout.build.flash_mode=dout
cw02.menu.FlashMode.qout.build.boot=qout
cw02.menu.FlashMode.dout=DOUT
cw02.menu.FlashMode.dout.build.flash_mode=dout
cw02.menu.FlashMode.dout.build.boot=dout
cw02.menu.FlashFreq.80=80MHz
cw02.menu.FlashFreq.80.build.flash_freq=80m
cw02.menu.FlashFreq.40=40MHz
cw02.menu.FlashFreq.40.build.flash_freq=40m
cw02.menu.FlashSize.4M=4MB (32Mb)
cw02.menu.FlashSize.4M.build.flash_size=4MB
cw02.menu.FlashSize.2M=2MB (16Mb)
cw02.menu.FlashSize.2M.build.flash_size=2MB
cw02.menu.FlashSize.2M.build.partitions=minimal
cw02.menu.UploadSpeed.921600=921600
cw02.menu.UploadSpeed.921600.upload.speed=921600
cw02.menu.UploadSpeed.115200=115200
cw02.menu.UploadSpeed.115200.upload.speed=115200
cw02.menu.UploadSpeed.256000.windows=256000
cw02.menu.UploadSpeed.256000.upload.speed=256000
cw02.menu.UploadSpeed.230400.windows.upload.speed=256000
cw02.menu.UploadSpeed.230400=230400
cw02.menu.UploadSpeed.230400.upload.speed=230400
cw02.menu.UploadSpeed.460800.linux=460800
cw02.menu.UploadSpeed.460800.macosx=460800
cw02.menu.UploadSpeed.460800.upload.speed=460800
cw02.menu.UploadSpeed.512000.windows=512000
cw02.menu.UploadSpeed.512000.upload.speed=512000
cw02.menu.DebugLevel.none=None
cw02.menu.DebugLevel.none.build.code_debug=0
cw02.menu.DebugLevel.error=Error
cw02.menu.DebugLevel.error.build.code_debug=1
cw02.menu.DebugLevel.warn=Warn
cw02.menu.DebugLevel.warn.build.code_debug=2
cw02.menu.DebugLevel.info=Info
cw02.menu.DebugLevel.info.build.code_debug=3
cw02.menu.DebugLevel.debug=Debug
cw02.menu.DebugLevel.debug.build.code_debug=4
cw02.menu.DebugLevel.verbose=Verbose
cw02.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
esp32wrover.name=ESP32 Wrover Module
esp32wrover.upload.tool=esptool
esp32wrover.upload.maximum_size=1310720
esp32wrover.upload.maximum_data_size=327680
esp32wrover.upload.wait_for_upload_port=true
esp32wrover.serial.disableDTR=true
esp32wrover.serial.disableRTS=true
esp32wrover.build.mcu=esp32
esp32wrover.build.core=esp32
esp32wrover.build.variant=esp32
esp32wrover.build.board=ESP32_DEV
esp32wrover.build.f_cpu=240000000L
esp32wrover.build.flash_size=4MB
esp32wrover.build.flash_freq=40m
esp32wrover.build.flash_mode=dio
esp32wrover.build.boot=dio
esp32wrover.build.partitions=default
esp32wrover.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
esp32wrover.menu.PartitionScheme.default=Default
esp32wrover.menu.PartitionScheme.default.build.partitions=default
esp32wrover.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
esp32wrover.menu.PartitionScheme.minimal.build.partitions=minimal
esp32wrover.menu.PartitionScheme.no_ota=No OTA (Large APP)
esp32wrover.menu.PartitionScheme.no_ota.build.partitions=no_ota
esp32wrover.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
esp32wrover.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
esp32wrover.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
esp32wrover.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
esp32wrover.menu.FlashMode.qio=QIO
esp32wrover.menu.FlashMode.qio.build.flash_mode=dio
esp32wrover.menu.FlashMode.qio.build.boot=qio
esp32wrover.menu.FlashMode.dio=DIO
esp32wrover.menu.FlashMode.dio.build.flash_mode=dio
esp32wrover.menu.FlashMode.dio.build.boot=dio
esp32wrover.menu.FlashMode.qout=QOUT
esp32wrover.menu.FlashMode.qout.build.flash_mode=dout
esp32wrover.menu.FlashMode.qout.build.boot=qout
esp32wrover.menu.FlashMode.dout=DOUT
esp32wrover.menu.FlashMode.dout.build.flash_mode=dout
esp32wrover.menu.FlashMode.dout.build.boot=dout
esp32wrover.menu.FlashFreq.80=80MHz
esp32wrover.menu.FlashFreq.80.build.flash_freq=80m
esp32wrover.menu.FlashFreq.40=40MHz
esp32wrover.menu.FlashFreq.40.build.flash_freq=40m
esp32wrover.menu.UploadSpeed.921600=921600
esp32wrover.menu.UploadSpeed.921600.upload.speed=921600
esp32wrover.menu.UploadSpeed.115200=115200
esp32wrover.menu.UploadSpeed.115200.upload.speed=115200
esp32wrover.menu.UploadSpeed.256000.windows=256000
esp32wrover.menu.UploadSpeed.256000.upload.speed=256000
esp32wrover.menu.UploadSpeed.230400.windows.upload.speed=256000
esp32wrover.menu.UploadSpeed.230400=230400
esp32wrover.menu.UploadSpeed.230400.upload.speed=230400
esp32wrover.menu.UploadSpeed.460800.linux=460800
esp32wrover.menu.UploadSpeed.460800.macosx=460800
esp32wrover.menu.UploadSpeed.460800.upload.speed=460800
esp32wrover.menu.UploadSpeed.512000.windows=512000
esp32wrover.menu.UploadSpeed.512000.upload.speed=512000
esp32wrover.menu.DebugLevel.none=None
esp32wrover.menu.DebugLevel.none.build.code_debug=0
esp32wrover.menu.DebugLevel.error=Error
esp32wrover.menu.DebugLevel.error.build.code_debug=1
esp32wrover.menu.DebugLevel.warn=Warn
esp32wrover.menu.DebugLevel.warn.build.code_debug=2
esp32wrover.menu.DebugLevel.info=Info
esp32wrover.menu.DebugLevel.info.build.code_debug=3
esp32wrover.menu.DebugLevel.debug=Debug
esp32wrover.menu.DebugLevel.debug.build.code_debug=4
esp32wrover.menu.DebugLevel.verbose=Verbose
esp32wrover.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
pico32.name=ESP32 Pico Kit
pico32.upload.tool=esptool
@ -115,6 +336,7 @@ pico32.build.flash_freq=80m
pico32.build.flash_mode=dio
pico32.build.boot=dio
pico32.build.partitions=default
pico32.build.defines=
pico32.menu.UploadSpeed.921600=921600
pico32.menu.UploadSpeed.921600.upload.speed=921600
@ -166,6 +388,7 @@ esp32thing.build.flash_mode=dio
esp32thing.build.flash_size=4MB
esp32thing.build.boot=dio
esp32thing.build.partitions=default
esp32thing.build.defines=
esp32thing.menu.FlashFreq.80=80MHz
esp32thing.menu.FlashFreq.80.build.flash_freq=80m
@ -209,6 +432,7 @@ nina_w10.build.partitions=minimal
nina_w10.build.flash_mode=dio
nina_w10.build.flash_size=2MB
nina_w10.build.flash_freq=40m
nina_w10.build.defines=
nina_w10.menu.UploadSpeed.921600=921600
nina_w10.menu.UploadSpeed.921600.upload.speed=921600
@ -247,6 +471,7 @@ widora-air.build.flash_mode=dio
widora-air.build.flash_size=16MB
widora-air.build.boot=dio
widora-air.build.partitions=default
widora-air.build.defines=
widora-air.menu.FlashFreq.80=80MHz
widora-air.menu.FlashFreq.80.build.flash_freq=80m
@ -290,6 +515,7 @@ esp320.build.flash_mode=qio
esp320.build.flash_size=4MB
esp320.build.boot=dio
esp320.build.partitions=default
esp320.build.defines=
esp320.menu.FlashFreq.80=80MHz
esp320.menu.FlashFreq.80.build.flash_freq=80m
@ -333,6 +559,7 @@ nano32.build.flash_mode=dio
nano32.build.flash_size=4MB
nano32.build.boot=dio
nano32.build.partitions=default
nano32.build.defines=
nano32.menu.FlashFreq.80=80MHz
nano32.menu.FlashFreq.80.build.flash_freq=80m
@ -376,6 +603,7 @@ lolin32.build.flash_mode=dio
lolin32.build.flash_size=4MB
lolin32.build.boot=dio
lolin32.build.partitions=default
lolin32.build.defines=
lolin32.menu.FlashFreq.80=80MHz
lolin32.menu.FlashFreq.80.build.flash_freq=80m
@ -428,6 +656,7 @@ pocket_32.build.flash_mode=dio
pocket_32.build.flash_size=4MB
pocket_32.build.boot=dio
pocket_32.build.partitions=default
pocket_32.build.defines=
pocket_32.menu.FlashFreq.80=80MHz
pocket_32.menu.FlashFreq.80.build.flash_freq=80m
@ -471,6 +700,7 @@ WeMosBat.build.flash_mode=dio
WeMosBat.build.flash_size=4MB
WeMosBat.build.boot=dio
WeMosBat.build.partitions=default
WeMosBat.build.defines=
WeMosBat.menu.FlashFreq.80=80MHz
WeMosBat.menu.FlashFreq.80.build.flash_freq=80m
@ -527,6 +757,7 @@ espea32.build.flash_mode=dio
espea32.build.flash_size=4MB
espea32.build.boot=dio
espea32.build.partitions=default
espea32.build.defines=
espea32.menu.FlashFreq.80=80MHz
espea32.menu.FlashFreq.80.build.flash_freq=80m
@ -570,6 +801,7 @@ quantum.build.flash_mode=qio
quantum.build.flash_size=16MB
quantum.build.boot=dio
quantum.build.partitions=default
quantum.build.defines=
quantum.menu.FlashFreq.80=80MHz
quantum.menu.FlashFreq.80.build.flash_freq=80m
@ -613,6 +845,7 @@ node32s.build.flash_mode=dio
node32s.build.flash_size=4MB
node32s.build.boot=dio
node32s.build.partitions=default
node32s.build.defines=
node32s.menu.FlashFreq.80=80MHz
node32s.menu.FlashFreq.80.build.flash_freq=80m
@ -656,6 +889,7 @@ hornbill32dev.build.flash_mode=dio
hornbill32dev.build.flash_size=4MB
hornbill32dev.build.boot=dio
hornbill32dev.build.partitions=default
hornbill32dev.build.defines=
hornbill32dev.menu.FlashFreq.80=80MHz
hornbill32dev.menu.FlashFreq.80.build.flash_freq=80m
@ -698,6 +932,7 @@ hornbill32minima.build.flash_mode=dio
hornbill32minima.build.flash_size=4MB
hornbill32minima.build.boot=dio
hornbill32minima.build.partitions=default
hornbill32minima.build.defines=
hornbill32minima.menu.FlashFreq.80=80MHz
hornbill32minima.menu.FlashFreq.80.build.flash_freq=80m
@ -741,6 +976,7 @@ firebeetle32.build.flash_mode=dio
firebeetle32.build.flash_size=4MB
firebeetle32.build.boot=dio
firebeetle32.build.partitions=default
firebeetle32.build.defines=
firebeetle32.menu.FlashFreq.80=80MHz
firebeetle32.menu.FlashFreq.80.build.flash_freq=80m
@ -784,6 +1020,7 @@ intorobot-fig.build.flash_mode=dio
intorobot-fig.build.flash_size=4MB
intorobot-fig.build.boot=dio
intorobot-fig.build.partitions=default
intorobot-fig.build.defines=
intorobot-fig.menu.FlashFreq.80=80MHz
intorobot-fig.menu.FlashFreq.80.build.flash_freq=80m
@ -827,6 +1064,7 @@ onehorse32dev.build.flash_mode=dout
onehorse32dev.build.flash_size=4MB
onehorse32dev.build.boot=dio
onehorse32dev.build.partitions=default
onehorse32dev.build.defines=
onehorse32dev.menu.FlashFreq.80=80MHz
onehorse32dev.menu.FlashFreq.80.build.flash_freq=80m
@ -870,6 +1108,7 @@ featheresp32.build.flash_mode=dio
featheresp32.build.flash_size=4MB
featheresp32.build.boot=dio
featheresp32.build.partitions=default
featheresp32.build.defines=
featheresp32.menu.FlashFreq.80=80MHz
featheresp32.menu.FlashFreq.80.build.flash_freq=80m
@ -926,6 +1165,7 @@ nodemcu-32s.build.flash_mode=dio
nodemcu-32s.build.flash_size=4MB
nodemcu-32s.build.boot=dio
nodemcu-32s.build.partitions=default
nodemcu-32s.build.defines=
nodemcu-32s.menu.FlashFreq.80=80MHz
nodemcu-32s.menu.FlashFreq.80.build.flash_freq=80m
@ -969,6 +1209,7 @@ mhetesp32devkit.build.flash_mode=dio
mhetesp32devkit.build.flash_size=4MB
mhetesp32devkit.build.boot=dio
mhetesp32devkit.build.partitions=default
mhetesp32devkit.build.defines=
mhetesp32devkit.menu.FlashFreq.80=80MHz
mhetesp32devkit.menu.FlashFreq.80.build.flash_freq=80m
@ -1034,6 +1275,7 @@ mhetesp32minikit.build.flash_mode=dio
mhetesp32minikit.build.flash_size=4MB
mhetesp32minikit.build.boot=dio
mhetesp32minikit.build.partitions=default
mhetesp32minikit.build.defines=
mhetesp32minikit.menu.FlashFreq.80=80MHz
mhetesp32minikit.menu.FlashFreq.80.build.flash_freq=80m
@ -1099,6 +1341,7 @@ esp32vn-iot-uno.build.flash_mode=dio
esp32vn-iot-uno.build.flash_size=4MB
esp32vn-iot-uno.build.boot=dio
esp32vn-iot-uno.build.partitions=default
esp32vn-iot-uno.build.defines=
esp32vn-iot-uno.menu.FlashFreq.80=80MHz
esp32vn-iot-uno.menu.FlashFreq.80.build.flash_freq=80m
@ -1142,6 +1385,7 @@ esp32doit-devkit-v1.build.flash_mode=dio
esp32doit-devkit-v1.build.flash_size=4MB
esp32doit-devkit-v1.build.boot=dio
esp32doit-devkit-v1.build.partitions=default
esp32doit-devkit-v1.build.defines=
esp32doit-devkit-v1.menu.FlashFreq.80=80MHz
esp32doit-devkit-v1.menu.FlashFreq.80.build.flash_freq=80m
@ -1196,6 +1440,7 @@ esp32-evb.build.flash_mode=dio
esp32-evb.build.flash_size=4MB
esp32-evb.build.boot=dio
esp32-evb.build.partitions=default
esp32-evb.build.defines=
esp32-evb.menu.FlashFreq.80=80MHz
esp32-evb.menu.FlashFreq.80.build.flash_freq=80m
@ -1228,6 +1473,7 @@ esp32-gateway.build.flash_mode=dio
esp32-gateway.build.flash_size=4MB
esp32-gateway.build.boot=dio
esp32-gateway.build.partitions=default
esp32-gateway.build.defines=
esp32-gateway.menu.FlashFreq.80=80MHz
esp32-gateway.menu.FlashFreq.80.build.flash_freq=80m
@ -1260,6 +1506,7 @@ espino32.build.flash_mode=dio
espino32.build.flash_size=4MB
espino32.build.boot=dio
espino32.build.partitions=default
espino32.build.defines=
espino32.menu.FlashFreq.80=80MHz
espino32.menu.FlashFreq.80.build.flash_freq=80m
@ -1303,6 +1550,7 @@ m5stack-core-esp32.build.flash_size=4MB
m5stack-core-esp32.build.flash_mode=dio
m5stack-core-esp32.build.boot=dio
m5stack-core-esp32.build.partitions=default
m5stack-core-esp32.build.defines=
m5stack-core-esp32.menu.FlashMode.qio=QIO
m5stack-core-esp32.menu.FlashMode.qio.build.flash_mode=dio
@ -1361,6 +1609,64 @@ m5stack-core-esp32.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
m5stack-fire.name=M5Stack-FIRE
m5stack-fire.upload.tool=esptool
m5stack-fire.upload.maximum_size=1310720
m5stack-fire.upload.maximum_data_size=327680
m5stack-fire.upload.wait_for_upload_port=true
m5stack-fire.serial.disableDTR=true
m5stack-fire.serial.disableRTS=true
m5stack-fire.build.mcu=esp32
m5stack-fire.build.core=esp32
m5stack-fire.build.variant=m5stack_fire
m5stack-fire.build.board=M5STACK_FIRE
m5stack-fire.build.f_cpu=240000000L
m5stack-fire.build.flash_size=16MB
m5stack-fire.build.flash_freq=80m
m5stack-fire.build.flash_mode=dio
m5stack-fire.build.boot=dio
m5stack-fire.build.partitions=default
m5stack-fire.build.defines=
m5stack-fire.menu.PSRAM.enabled=Enabled
m5stack-fire.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
m5stack-fire.menu.PSRAM.disabled=Disabled
m5stack-fire.menu.PSRAM.disabled.build.defines=
m5stack-fire.menu.UploadSpeed.921600=921600
m5stack-fire.menu.UploadSpeed.921600.upload.speed=921600
m5stack-fire.menu.UploadSpeed.115200=115200
m5stack-fire.menu.UploadSpeed.115200.upload.speed=115200
m5stack-fire.menu.UploadSpeed.256000.windows=256000
m5stack-fire.menu.UploadSpeed.256000.upload.speed=256000
m5stack-fire.menu.UploadSpeed.230400.windows.upload.speed=256000
m5stack-fire.menu.UploadSpeed.230400=230400
m5stack-fire.menu.UploadSpeed.230400.upload.speed=230400
m5stack-fire.menu.UploadSpeed.460800.linux=460800
m5stack-fire.menu.UploadSpeed.460800.macosx=460800
m5stack-fire.menu.UploadSpeed.460800.upload.speed=460800
m5stack-fire.menu.UploadSpeed.512000.windows=512000
m5stack-fire.menu.UploadSpeed.512000.upload.speed=512000
m5stack-fire.menu.DebugLevel.none=None
m5stack-fire.menu.DebugLevel.none.build.code_debug=0
m5stack-fire.menu.DebugLevel.error=Error
m5stack-fire.menu.DebugLevel.error.build.code_debug=1
m5stack-fire.menu.DebugLevel.warn=Warn
m5stack-fire.menu.DebugLevel.warn.build.code_debug=2
m5stack-fire.menu.DebugLevel.info=Info
m5stack-fire.menu.DebugLevel.info.build.code_debug=3
m5stack-fire.menu.DebugLevel.debug=Debug
m5stack-fire.menu.DebugLevel.debug.build.code_debug=4
m5stack-fire.menu.DebugLevel.verbose=Verbose
m5stack-fire.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
odroid_esp32.name=ODROID ESP32
odroid_esp32.upload.tool=esptool
@ -1381,6 +1687,7 @@ odroid_esp32.build.flash_size=16MB
odroid_esp32.build.flash_mode=dio
odroid_esp32.build.boot=dio
odroid_esp32.build.partitions=default
odroid_esp32.build.defines=
odroid_esp32.menu.FlashMode.qio=QIO
odroid_esp32.menu.FlashMode.qio.build.flash_mode=dio
@ -1459,6 +1766,7 @@ heltec_wifi_kit_32.build.flash_mode=dio
heltec_wifi_kit_32.build.flash_size=4MB
heltec_wifi_kit_32.build.boot=dio
heltec_wifi_kit_32.build.partitions=default
heltec_wifi_kit_32.build.defines=
heltec_wifi_kit_32.menu.FlashFreq.80=80MHz
heltec_wifi_kit_32.menu.FlashFreq.80.build.flash_freq=80m
@ -1502,6 +1810,7 @@ heltec_wifi_lora_32.build.flash_mode=dio
heltec_wifi_lora_32.build.flash_size=4MB
heltec_wifi_lora_32.build.boot=dio
heltec_wifi_lora_32.build.partitions=default
heltec_wifi_lora_32.build.defines=
heltec_wifi_lora_32.menu.FlashFreq.80=80MHz
heltec_wifi_lora_32.menu.FlashFreq.80.build.flash_freq=80m
@ -1545,6 +1854,7 @@ espectro32.build.flash_size=4MB
espectro32.build.flash_mode=dio
espectro32.build.boot=dio
espectro32.build.partitions=default
espectro32.build.defines=
espectro32.menu.FlashMode.qio=QIO
espectro32.menu.FlashMode.qio.build.flash_mode=dio
@ -1620,6 +1930,7 @@ CoreESP32.build.flash_mode=dio
CoreESP32.build.flash_size=4MB
CoreESP32.build.boot=dio
CoreESP32.build.partitions=default
CoreESP32.build.defines=
CoreESP32.menu.FlashFreq.80=80MHz
CoreESP32.menu.FlashFreq.80.build.flash_freq=80m
@ -1643,6 +1954,96 @@ CoreESP32.menu.UploadSpeed.512000.upload.speed=512000
##############################################################
alksesp32.name=ALKS ESP32
alksesp32.upload.tool=esptool
alksesp32.upload.maximum_size=1310720
alksesp32.upload.maximum_data_size=327680
alksesp32.upload.wait_for_upload_port=true
alksesp32.serial.disableDTR=true
alksesp32.serial.disableRTS=true
alksesp32.build.mcu=esp32
alksesp32.build.core=esp32
alksesp32.build.variant=alksesp32
alksesp32.build.board=ALKS
alksesp32.build.f_cpu=240000000L
alksesp32.build.flash_size=4MB
alksesp32.build.flash_freq=40m
alksesp32.build.flash_mode=dio
alksesp32.build.boot=dio
alksesp32.build.partitions=default
alksesp32.build.defines=
alksesp32.menu.PartitionScheme.default=Default
alksesp32.menu.PartitionScheme.default.build.partitions=default
alksesp32.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
alksesp32.menu.PartitionScheme.minimal.build.partitions=minimal
alksesp32.menu.PartitionScheme.no_ota=No OTA (Large APP)
alksesp32.menu.PartitionScheme.no_ota.build.partitions=no_ota
alksesp32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
alksesp32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
alksesp32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
alksesp32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
alksesp32.menu.FlashMode.qio=QIO
alksesp32.menu.FlashMode.qio.build.flash_mode=dio
alksesp32.menu.FlashMode.qio.build.boot=qio
alksesp32.menu.FlashMode.dio=DIO
alksesp32.menu.FlashMode.dio.build.flash_mode=dio
alksesp32.menu.FlashMode.dio.build.boot=dio
alksesp32.menu.FlashMode.qout=QOUT
alksesp32.menu.FlashMode.qout.build.flash_mode=dout
alksesp32.menu.FlashMode.qout.build.boot=qout
alksesp32.menu.FlashMode.dout=DOUT
alksesp32.menu.FlashMode.dout.build.flash_mode=dout
alksesp32.menu.FlashMode.dout.build.boot=dout
alksesp32.menu.FlashFreq.80=80MHz
alksesp32.menu.FlashFreq.80.build.flash_freq=80m
alksesp32.menu.FlashFreq.40=40MHz
alksesp32.menu.FlashFreq.40.build.flash_freq=40m
alksesp32.menu.FlashSize.4M=4MB (32Mb)
alksesp32.menu.FlashSize.4M.build.flash_size=4MB
alksesp32.menu.FlashSize.2M=2MB (16Mb)
alksesp32.menu.FlashSize.2M.build.flash_size=2MB
alksesp32.menu.FlashSize.2M.build.partitions=minimal
alksesp32.menu.UploadSpeed.921600=921600
alksesp32.menu.UploadSpeed.921600.upload.speed=921600
alksesp32.menu.UploadSpeed.115200=115200
alksesp32.menu.UploadSpeed.115200.upload.speed=115200
alksesp32.menu.UploadSpeed.256000.windows=256000
alksesp32.menu.UploadSpeed.256000.upload.speed=256000
alksesp32.menu.UploadSpeed.230400.windows.upload.speed=256000
alksesp32.menu.UploadSpeed.230400=230400
alksesp32.menu.UploadSpeed.230400.upload.speed=230400
alksesp32.menu.UploadSpeed.460800.linux=460800
alksesp32.menu.UploadSpeed.460800.macosx=460800
alksesp32.menu.UploadSpeed.460800.upload.speed=460800
alksesp32.menu.UploadSpeed.512000.windows=512000
alksesp32.menu.UploadSpeed.512000.upload.speed=512000
alksesp32.menu.DebugLevel.none=None
alksesp32.menu.DebugLevel.none.build.code_debug=0
alksesp32.menu.DebugLevel.error=Error
alksesp32.menu.DebugLevel.error.build.code_debug=1
alksesp32.menu.DebugLevel.warn=Warn
alksesp32.menu.DebugLevel.warn.build.code_debug=2
alksesp32.menu.DebugLevel.info=Info
alksesp32.menu.DebugLevel.info.build.code_debug=3
alksesp32.menu.DebugLevel.debug=Debug
alksesp32.menu.DebugLevel.debug.build.code_debug=4
alksesp32.menu.DebugLevel.verbose=Verbose
alksesp32.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
wipy3.name=WiPy 3.0
wipy3.upload.tool=esptool
@ -1663,6 +2064,7 @@ wipy3.build.flash_mode=dio
wipy3.build.flash_size=8MB
wipy3.build.boot=dio
wipy3.build.partitions=default
wipy3.build.defines=
wipy3.menu.FlashFreq.80=80MHz
wipy3.menu.FlashFreq.80.build.flash_freq=80m
@ -1696,4 +2098,3 @@ wipy3.menu.DebugLevel.debug=Debug
wipy3.menu.DebugLevel.debug.build.code_debug=4
wipy3.menu.DebugLevel.verbose=Verbose
wipy3.menu.DebugLevel.verbose.build.code_debug=5

View File

@ -1,4 +1,6 @@
ARDUINO_CORE_LIBS := $(patsubst $(COMPONENT_PATH)/%,%,$(sort $(dir $(wildcard $(COMPONENT_PATH)/libraries/*/*/))))
ARDUINO_LIBRARIES_LIST := $(patsubst $(COMPONENT_PATH)/libraries/%,%,$(wildcard $(COMPONENT_PATH)/libraries/*))
ARDUINO_SINGLE_LIBRARY_FILES = $(patsubst $(COMPONENT_PATH)/%,%,$(sort $(dir $(wildcard $(COMPONENT_PATH)/libraries/$(MODULE)/*/)) $(dir $(wildcard $(COMPONENT_PATH)/libraries/$(MODULE)/*/*/)) $(dir $(wildcard $(COMPONENT_PATH)/libraries/$(MODULE)/*/*/*/)) $(dir $(wildcard $(COMPONENT_PATH)/libraries/$(MODULE)/*/*/*/*/)) $(dir $(wildcard $(COMPONENT_PATH)/libraries/$(MODULE)/*/*/*/*/*/))))
ARDUINO_CORE_LIBS := $(foreach MODULE,$(ARDUINO_LIBRARIES_LIST),$(if $(CONFIG_ARDUINO_SELECTIVE_COMPILATION),$(if $(CONFIG_ARDUINO_SELECTIVE_$(MODULE)),$(ARDUINO_SINGLE_LIBRARY_FILES)),$(ARDUINO_SINGLE_LIBRARY_FILES)))
COMPONENT_ADD_INCLUDEDIRS := cores/esp32 variants/esp32 $(ARDUINO_CORE_LIBS)
COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64

View File

@ -7,6 +7,8 @@
#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) {}

View File

@ -79,6 +79,8 @@ protected:
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
extern HardwareSerial Serial;
extern HardwareSerial Serial1;
extern HardwareSerial Serial2;
#endif
#endif

View File

@ -70,7 +70,12 @@ const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
};
typedef void (*voidFuncPtr)(void);
static voidFuncPtr __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
typedef void (*voidFuncPtrArg)(void*);
typedef struct {
voidFuncPtr fn;
void* arg;
} InterruptHandle_t;
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
#include "driver/rtc_io.h"
@ -193,7 +198,7 @@ extern int IRAM_ATTR __digitalRead(uint8_t pin)
static intr_handle_t gpio_intr_handle = NULL;
static void IRAM_ATTR __onPinInterrupt(void *arg)
static void IRAM_ATTR __onPinInterrupt()
{
uint32_t gpio_intr_status_l=0;
uint32_t gpio_intr_status_h=0;
@ -207,8 +212,12 @@ static void IRAM_ATTR __onPinInterrupt(void *arg)
if(gpio_intr_status_l) {
do {
if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
if(__pinInterruptHandlers[pin]) {
__pinInterruptHandlers[pin]();
if(__pinInterruptHandlers[pin].fn) {
if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
}
}
} while(++pin<32);
@ -217,15 +226,19 @@ static void IRAM_ATTR __onPinInterrupt(void *arg)
pin=32;
do {
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
if(__pinInterruptHandlers[pin]) {
__pinInterruptHandlers[pin]();
if(__pinInterruptHandlers[pin].fn) {
if(__pinInterruptHandlers[pin].arg){
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
} else {
__pinInterruptHandlers[pin].fn();
}
}
}
} while(++pin<GPIO_PIN_COUNT);
}
}
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
{
static bool interrupt_initialized = false;
@ -233,7 +246,8 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
interrupt_initialized = true;
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle);
}
__pinInterruptHandlers[pin] = userFunc;
__pinInterruptHandlers[pin].fn = (voidFuncPtr)userFunc;
__pinInterruptHandlers[pin].arg = arg;
esp_intr_disable(gpio_intr_handle);
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
GPIO.pin[pin].int_ena = 1;
@ -244,10 +258,15 @@ extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type)
esp_intr_enable(gpio_intr_handle);
}
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) {
__attachInterruptArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type);
}
extern void __detachInterrupt(uint8_t pin)
{
esp_intr_disable(gpio_intr_handle);
__pinInterruptHandlers[pin] = NULL;
__pinInterruptHandlers[pin].fn = NULL;
__pinInterruptHandlers[pin].arg = NULL;
GPIO.pin[pin].int_ena = 0;
GPIO.pin[pin].int_type = 0;
esp_intr_enable(gpio_intr_handle);
@ -258,5 +277,6 @@ extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pi
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
extern void attachInterruptArg(uint8_t pin, voidFuncPtr handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));

View File

@ -79,6 +79,7 @@ void digitalWrite(uint8_t pin, uint8_t val);
int digitalRead(uint8_t pin);
void attachInterrupt(uint8_t pin, void (*)(void), int mode);
void attachInterruptArg(uint8_t pin, void (*)(void), void * arg, int mode);
void detachInterrupt(uint8_t pin);
#ifdef __cplusplus

View File

@ -33,6 +33,22 @@
#define DR_REG_I2C_EXT_BASE_FIXED 0x60013000
#define DR_REG_I2C1_EXT_BASE_FIXED 0x60027000
/* Stickbreaker ISR mode debug support
ENABLE_I2C_DEBUG_BUFFER
Enable debug interrupt history buffer, setting this define will result in 1544 bytes of RAM
being used whenever CORE_DEBUG_LEVEL is higher than WARNING. Unless you are debugging
a problem in the I2C subsystem I would recommend you leave it commented out.
*/
//#define ENABLE_I2C_DEBUG_BUFFER
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER)
#define INTBUFFMAX 64
static uint32_t intBuff[INTBUFFMAX][3][2];
static uint32_t intPos[2]= {0,0};
#endif
// start from tools/sdk/include/soc/soc/i2c_struct.h
typedef union {
@ -65,6 +81,17 @@ typedef union {
uint32_t val;
} I2C_FIFO_CONF_t;
typedef union {
struct {
uint32_t rx_fifo_start_addr: 5; /*This is the offset address of the last receiving data as described in nonfifo_rx_thres_register.*/
uint32_t rx_fifo_end_addr: 5; /*This is the offset address of the first receiving data as described in nonfifo_rx_thres_register.*/
uint32_t tx_fifo_start_addr: 5; /*This is the offset address of the first sending data as described in nonfifo_tx_thres register.*/
uint32_t tx_fifo_end_addr: 5; /*This is the offset address of the last sending data as described in nonfifo_tx_thres register.*/
uint32_t reserved20: 12;
};
uint32_t val;
} I2C_FIFO_ST_t;
// end from tools/sdk/include/soc/soc/i2c_struct.h
// sync between dispatch(i2cProcQueue) and worker(i2c_isr_handler_default)
@ -130,9 +157,7 @@ typedef struct {
uint8_t *data; // datapointer for read/write buffer
uint16_t length; // size of data buffer
uint16_t position; // current position for next char in buffer (<length)
uint16_t cmdBytesNeeded; // used to control number of I2C_COMMAND_t blocks added to queu
uint16_t queueLength; // number of data bytes needing moved, used to control
// current queuePos for fifo fills
uint16_t cmdBytesNeeded; // used to control number of I2C_COMMAND_t blocks added to queue
I2C_DATA_CTRL_t ctrl;
EventGroupHandle_t queueEvent; // optional user supplied for Async feedback EventBits
} I2C_DATA_QUEUE_t;
@ -152,9 +177,10 @@ struct i2c_struct_t {
// maybe use it to trigger callback for OnRequest()
intr_handle_t intr_handle; /*!< I2C interrupt handle*/
I2C_DATA_QUEUE_t * dq;
uint16_t queueCount;
uint16_t queuePos;
uint16_t byteCnt;
uint16_t queueCount; // number of dq entries in queue.
uint16_t queuePos; // current queue that still has or needs data (out/in)
uint16_t errorByteCnt; // count of bytes moved (both in and out)
uint16_t errorQueue; // errorByteCnt is in this queue,(for error locus)
uint32_t exitCode;
};
@ -179,8 +205,8 @@ static i2c_t _i2c_bus_array[2] = {
#define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock)
static i2c_t _i2c_bus_array[2] = {
{(volatile i2c_dev_t *)(DR_REG_I2C_EXT_BASE_FIXED), NULL, 0, -1, -1, I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0},
{(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE_FIXED), NULL, 1, -1, -1,I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0}
{(volatile i2c_dev_t *)(DR_REG_I2C_EXT_BASE_FIXED), NULL, 0, -1, -1, I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0},
{(volatile i2c_dev_t *)(DR_REG_I2C1_EXT_BASE_FIXED), NULL, 1, -1, -1,I2C_NONE,I2C_NONE,I2C_ERROR_OK,NULL,NULL,NULL,0,0,0,0,0}
};
#endif
@ -204,13 +230,6 @@ static void IRAM_ATTR i2cSetCmd(i2c_t * i2c, uint8_t index, uint8_t op_code, uin
i2c->dev->command[index].val = cmd.val;
}
/* Stickbreaker ISR mode debug support
*/
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
#define INTBUFFMAX 64
static uint32_t intBuff[INTBUFFMAX][3][2];
static uint32_t intPos[2]= {0,0};
#endif
/* Stickbreaker ISR mode debug support
*/
@ -236,8 +255,7 @@ void IRAM_ATTR dumpCmdQueue(i2c_t *i2c)
*/
static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
{
/* this function is call on initial i2cProcQueue()
or when a I2C_END_DETECT_INT occures
/* this function is called on initial i2cProcQueue() or when a I2C_END_DETECT_INT occurs
*/
uint16_t cmdIdx = 0;
uint16_t qp = i2c->queuePos;
@ -261,14 +279,14 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
I2C_DATA_QUEUE_t *tdq=&i2c->dq[qp]; // simpler coding
if((!tdq->ctrl.startCmdSent) && (cmdIdx < 14)) { // has this dq element's START command been added?
// <14 testing if ReSTART END is causeing the Timeout
// (cmdIdx<14) because a START op cannot directly precede an END op, else a time out cascade occurs
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_RSTART, 0, false, false, false);
tdq->ctrl.startCmdSent=1;
done = (cmdIdx>14);
}
//CMD WRITE ADDRESS
if((!done)&&(tdq->ctrl.startCmdSent)) { // have to leave room for continue, and START must have been sent!
if((!done)&&(tdq->ctrl.startCmdSent)) { // have to leave room for continue(END), and START must have been sent!
if(!tdq->ctrl.addrCmdSent) {
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_WRITE, tdq->ctrl.addrReq, false, false, true); //load address in cmdlist, validate (low) ack
tdq->ctrl.addrCmdSent=1;
@ -282,26 +300,24 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
If END is used, when refilling the cmd[] next time, no entries from END to [15] can be used.
AND the cmd[] must be filled starting at [0] with commands. Either fill all 15 [0]..[14] and leave the
END in [15] or include a STOP in one of the positions [0]..[14]. Any entries after a STOP are IGNORED byte the StateMachine.
END in [15] or include a STOP in one of the positions [0]..[14]. Any entries after a STOP are IGNORED by the StateMachine.
The END operation does not complete until ctr->trans_start=1 has been issued.
So, only refill from [0]..[14], leave [15] for a continuation if necessary.
As a corrilary, once END exists in [15], you do not need to overwrite it for the
So, only refill from [0]..[14], leave [15] for a continuation(END) if necessary.
As a corollary, once END exists in [15], you do not need to overwrite it for the
next continuation. It is never modified. But, I update it every time because it might
actually be the first time!
23NOV17 START cannot proceed END. if START is in[14], END cannot be in [15].
so, AND if END is moved to [14], [14] and [15] can nolonger be use for anything other than END.
So, if END is moved to [14], [14] and [15] can no longer be used for anything other than END.
If a START is found in [14] then a prior READ or WRITE must be expanded so that there is no START element in [14].
*/
if((!done)&&(tdq->ctrl.addrCmdSent)) { //room in command[] for at least One data (read/Write) cmd
uint8_t blkSize=0; // max is 255? does numBytes =0 actually mean 256? haven't tried it.
//log_e("needed=%2d index=%d",*neededRead,cmdIdx);
uint8_t blkSize=0; // max is 255
while(( tdq->cmdBytesNeeded > tdq->ctrl.mode )&&(!done )) { // more bytes needed and room in cmd queue, leave room for END
blkSize = (tdq->cmdBytesNeeded > 255)?255:(tdq->cmdBytesNeeded - tdq->ctrl.mode); // Last read cmd needs different ACK setting, so leave 1 byte remainer on reads
tdq->cmdBytesNeeded -= blkSize; //
blkSize = (tdq->cmdBytesNeeded > 255)?255:(tdq->cmdBytesNeeded - tdq->ctrl.mode); // Last read cmd needs different ACK setting, so leave 1 byte remainder on reads
tdq->cmdBytesNeeded -= blkSize;
if(tdq->ctrl.mode==1) { //read mode
i2cSetCmd(i2c, (cmdIdx)++, I2C_CMD_READ, blkSize,false,false,false); // read cmd, this can't be the last read.
ena_rx=true; // need to enable rxFifo IRQ
@ -341,20 +357,10 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
done = false; // reuse it
uint16_t i = 13; // start working back until a READ/WRITE has >1 numBytes
cmdIdx =15;
// log_e("before Stretch");
// dumpCmdQueue(i2c);
while(!done) {
i2c->dev->command[i+1].val = i2c->dev->command[i].val; // push it down
if (((i2c->dev->command[i].op_code == 1)||(i2c->dev->command[i].op_code==2))) {
/* just try a num_bytes =0;
&&(i2c->dev->command[i].byte_num>1)){ // found the one to expand
i2c->dev->command[i+1].byte_num =1;
// the -= in the following statment caused unintential consequences.
// The op_code field value changed from 2 to 4, so the manual cludge was needed
// i2c->dev->command[i].byte_num -= 1;
uint32_t temp = i2c->dev->command[i].val;
temp = (temp&0xFFFFFF00) | ((temp & 0xFF)-1);
i2c->dev->command[i].val = temp;
/* add a dummy read/write cmd[] with num_bytes set to zero,just a place holder in the cmd[]list
*/
i2c->dev->command[i].byte_num = 0;
done = true;
@ -369,18 +375,15 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
}
}
}
// log_e("after Stretch");
// dumpCmdQueue(i2c);
}
if(cmdIdx==15) { //need continuation, even if STOP is in 14, it will not matter
// cmd buffer is almost full, Add END as a continuation feature
// log_e("END at %d, left=%d",cmdIdx,neededRead);
i2cSetCmd(i2c, (cmdIdx)++,I2C_CMD_END, 0,false,false,false);
i2c->dev->int_ena.end_detect=1; //maybe?
i2c->dev->int_clr.end_detect=1; //maybe?
i2c->dev->int_ena.end_detect=1;
i2c->dev->int_clr.end_detect=1;
done = true;
}
@ -389,7 +392,6 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
qp++;
if(qp < i2c->queueCount) {
tdq = &i2c->dq[qp];
// log_e("inc to next queue=%d",qp);
} else {
done = true;
}
@ -397,7 +399,7 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
}
}// while(!done)
if(INTS) { // don't want to prematurely enable fifo ints until ISR is ready to handle it.
if(INTS) { // don't want to prematurely enable fifo ints until ISR is ready to handle them.
if(ena_rx) {
i2c->dev->int_ena.rx_fifo_full = 1;
}
@ -411,18 +413,7 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
*/
static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
{
/* need to test overlapping RX->TX fifo operations,
Currently, this function attempts to queue all possible tx elements into the Fifo.
What happens when WRITE 10, READ 20, Write 10?
(Write Addr, Write 10),(Write addr, Read 20) (Write addr, Write 10).
I know everything will work up to the End of the Read 20, but I am unsure
what will happen to the third command, will the Read 20 overwrite the previously
queued (write addr, write 10) of the Third command? I need to test!
*/
/*11/15/2017 will assume that I cannot queue tx after a READ until READ completes
11/23/2017 Seems to be a TX fifo problem, the SM sends 0x40 for last rxbyte, I
enable txEmpty, filltx fires, but the SM has already sent a bogus byte out the BUS.
I am going so see if I can overlap Tx/Rx/Tx in the fifo
/*
12/01/2017 The Fifo's are independent, 32 bytes of tx and 32 bytes of Rx.
overlap is not an issue, just keep them full/empty the status_reg.xx_fifo_cnt
tells the truth. And the INT's fire correctly
@ -476,7 +467,7 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
}
}
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER)
// update debug buffer tx counts
cnt += intBuff[intPos[i2c->num]][1][i2c->num]>>16;
@ -489,7 +480,8 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
}
}
if(!full || (a >= i2c->queueCount)) { // disable IRQ, the next dq will re-enable it
if(a >= i2c->queueCount ) { // disable IRQ, the next dq will re-enable it
// (a >= i2c->queueCount) means no more data is available
i2c->dev->int_ena.tx_fifo_empty= 0;
}
@ -501,22 +493,31 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
static void IRAM_ATTR emptyRxFifo(i2c_t * i2c)
{
uint32_t d, cnt=0, moveCnt;
I2C_DATA_QUEUE_t *tdq =&i2c->dq[i2c->queuePos];
moveCnt = i2c->dev->status_reg.rx_fifo_cnt;//no need to check the reg until this many are read
while((moveCnt > 0)&&(i2c->queuePos < i2c->queueCount)){ // data to move
I2C_DATA_QUEUE_t *tdq =&i2c->dq[i2c->queuePos]; //short cut
if(tdq->ctrl.mode == 1){ // read command
if(moveCnt > (tdq->length - tdq->position)) { //make sure they go in this dq
// part of these reads go into the next dq
moveCnt = (tdq->length - tdq->position);
}
if(tdq->ctrl.mode==1) { // read
while(moveCnt > 0) {
} else {// error
log_e("RxEmpty(%d) call on TxBuffer? dq=%d",moveCnt,i2c->queuePos);
return;
}
while(moveCnt > 0) {
d = i2c->dev->fifo_data.val;
moveCnt--;
cnt++;
tdq->data[tdq->position++] = (d&0xFF);
}
if(tdq->position >= tdq->length ){ // inc queuePos until next READ command or end of queue
i2c->queuePos++;
while((i2c->queuePos < i2c->queueCount)&&(i2c->dq[i2c->queuePos].ctrl.mode !=1)){
i2c->queuePos++;
}
if(i2c->queuePos < i2c->queueCount){ // found new place to store rx data
tdq = &i2c->dq[i2c->queuePos]; // update shortcut
// see if any more chars showed up while empting Fifo.
moveCnt = i2c->dev->status_reg.rx_fifo_cnt;
if(moveCnt > (tdq->length - tdq->position)) { //make sure they go in this dq
@ -524,16 +525,13 @@ static void IRAM_ATTR emptyRxFifo(i2c_t * i2c)
moveCnt = (tdq->length - tdq->position);
}
}
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
}
}
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO)&& (defined ENABLE_I2C_DEBUG_BUFFER)
// update Debug rxCount
cnt += (intBuff[intPos[i2c->num]][1][i2c->num])&&0xffFF;
intBuff[intPos[i2c->num]][1][i2c->num] = (intBuff[intPos[i2c->num]][1][i2c->num]&0xFFFF0000)|cnt;
#endif
} else {
log_e("RxEmpty(%d) call on TxBuffer? dq=%d",moveCnt,i2c->queuePos);
// dumpI2c(i2c);
}
//log_e("emptied %d",*index);
}
static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal)
@ -559,13 +557,11 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
i2c->error = I2C_ERROR;
}
uint32_t exitCode = EVENT_DONE | eventCode |(Fatal?EVENT_ERROR:0);
if(i2c->dq[i2c->queuePos].ctrl.mode == 1) {
if((i2c->queuePos < i2c->queueCount) && (i2c->dq[i2c->queuePos].ctrl.mode == 1)) {
emptyRxFifo(i2c); // grab last few characters
}
i2c->dev->int_ena.val = 0; // shut down interrupts
i2c->dev->int_clr.val = 0x1FFFF;
i2c->dev->int_clr.val = 0x1FFF;
i2c->stage = I2C_DONE;
i2c->exitCode = exitCode; //true eventcode
@ -582,22 +578,79 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
}
}
/* 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.
This function obliterates the need to interrupt monitor each byte transferred, at high bitrates
the byte interrupts were overwhelming the OS. Spurious Interrupts were being generated.
it update errorByteCnt, errorQueue.
*/
static void IRAM_ATTR i2c_update_error_byte_cnt(i2c_t * i2c)
{
uint16_t a=0; // start at top of DQ, count how many bytes added to tx fifo, and received from rx_fifo.
uint16_t bc = 0;
I2C_DATA_QUEUE_t *tdq;
i2c->errorByteCnt = 0;
while( a < i2c->queueCount){ // add up all bytes loaded into fifo's
tdq = &i2c->dq[a];
i2c->errorByteCnt += tdq->ctrl.addrSent;
i2c->errorByteCnt += tdq->position;
a++;
}
// log_v("errorByteCnt=%d",i2c->errorByteCnt);
// now errorByteCnt contains total bytes moved into and out of FIFO's
// but, there may still be bytes waiting in Fifo's
i2c->errorByteCnt -= i2c->dev->status_reg.tx_fifo_cnt; // waiting to go out;
i2c->errorByteCnt += i2c->dev->status_reg.rx_fifo_cnt; // already received
// now walk thru DQ again, find which byte is 'current'
bool done = false;
bc = i2c->errorByteCnt;
i2c->errorQueue = 0;
while(( i2c->errorQueue < i2c->queueCount)&&( !done )){
tdq = &i2c->dq[i2c->errorQueue];
if(bc>0){ // not found yet
if( tdq->ctrl.addrSent >= bc){ // in address
done = true;
continue;
} else {
bc -= tdq->ctrl.addrSent;
if( tdq->position >= bc) { // data nak
done = true;
continue;
} else { // count down
bc -= tdq->position;
}
}
} else {
done= true;
continue;
}
i2c->errorQueue++;
}
// log_v("errorByteCnt=%d errorQueue=%d",i2c->errorByteCnt,i2c->errorQueue);
i2c->errorByteCnt = bc;
}
static void IRAM_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&0x1FFF;
uint32_t activeInt = p_i2c->dev->int_status.val&0x7FF;
//portBASE_TYPE HPTaskAwoken = pdFALSE,xResult;
if(p_i2c->stage==I2C_DONE) { //get Out
log_e("eject int=%p, ena=%p",activeInt,p_i2c->dev->int_ena.val);
if(p_i2c->stage==I2C_DONE) { //get Out, can't service, not configured
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
uint32_t raw = p_i2c->dev->int_raw.val;
#endif
p_i2c->dev->int_ena.val = 0;
p_i2c->dev->int_clr.val = activeInt; //0x1FFF;
p_i2c->dev->int_clr.val = 0x1FFF;
log_v("eject raw=%p, int=%p",raw,activeInt);
return;
}else if(!activeInt){ //spurious interrupt, possibly bus relate 20180711
log_v("r=0x%x s=0x%x %d",p_i2c->dev->int_raw.val,p_i2c->dev->int_status.val,p_i2c->stage);
}
while (activeInt != 0) { // Ordering of 'if(activeInt)' statements is important, don't change
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER)
if(activeInt==(intBuff[intPos[p_i2c->num]][0][p_i2c->num]&0x1fff)) {
intBuff[intPos[p_i2c->num]][0][p_i2c->num] = (((intBuff[intPos[p_i2c->num]][0][p_i2c->num]>>16)+1)<<16)|activeInt;
} else {
@ -610,10 +663,8 @@ static void IRAM_ATTR i2c_isr_handler_default(void* arg)
intBuff[intPos[p_i2c->num]][2][p_i2c->num] = xTaskGetTickCountFromISR(); // when IRQ fired
#endif
//uint32_t oldInt =activeInt;
if (activeInt & I2C_TRANS_START_INT_ST_M) {
// p_i2c->byteCnt=0;
if(p_i2c->stage==I2C_STARTUP) {
p_i2c->stage=I2C_RUNNING;
}
@ -636,40 +687,14 @@ static void IRAM_ATTR i2c_isr_handler_default(void* arg)
activeInt &=~I2C_RXFIFO_FULL_INT_ST;
}
if(activeInt & I2C_MASTER_TRAN_COMP_INT_ST) { // each byte the master sends/recv
p_i2c->dev->int_clr.master_tran_comp = 1;
p_i2c->byteCnt++;
if(p_i2c->byteCnt > p_i2c->dq[p_i2c->queuePos].queueLength) { // simulate Trans_start
p_i2c->byteCnt -= p_i2c->dq[p_i2c->queuePos].queueLength;
if(p_i2c->dq[p_i2c->queuePos].ctrl.mode==1) { // grab last characters for this dq
emptyRxFifo(p_i2c);
p_i2c->dev->int_clr.rx_fifo_full=1;
p_i2c->dev->int_ena.rx_fifo_full=1;
}
p_i2c->queuePos++; //inc to next dq
if(p_i2c->queuePos < p_i2c->queueCount) { // load next dq address field + data
p_i2c->dev->int_ena.tx_fifo_empty=1;
}
}
activeInt &=~I2C_MASTER_TRAN_COMP_INT_ST;
}
if (activeInt & I2C_ACK_ERR_INT_ST_M) {//fatal error, abort i2c service
if (p_i2c->mode == I2C_MASTER) {
// log_e("AcK Err byteCnt=%d, queuepos=%d",p_i2c->byteCnt,p_i2c->queuePos);
if(p_i2c->byteCnt==1) {
i2cIsrExit(p_i2c,EVENT_ERROR_NAK,true);
} else if((p_i2c->byteCnt == 2) && (p_i2c->dq[p_i2c->queuePos].ctrl.addrReq == 2)) {
i2c_update_error_byte_cnt(p_i2c); // calc which byte caused ack Error, check if address or data
log_v("AcK Err errorByteCnt=%d, errorQueue=%d queuepos=%d",p_i2c->errorByteCnt,p_i2c->errorQueue, p_i2c->queuePos);
if(p_i2c->errorByteCnt <= p_i2c->dq[p_i2c->errorQueue].ctrl.addrReq) { // address
i2cIsrExit(p_i2c,EVENT_ERROR_NAK,true);
} else {
i2cIsrExit(p_i2c,EVENT_ERROR_DATA_NAK,true);
i2cIsrExit(p_i2c,EVENT_ERROR_DATA_NAK,true); //data
}
}
return;
@ -680,9 +705,15 @@ static void IRAM_ATTR i2c_isr_handler_default(void* arg)
// the Statemachine only has a 13.1ms max timout, some Devices >500ms
p_i2c->dev->int_clr.time_out =1;
activeInt &=~I2C_TIME_OUT_INT_ST;
// since a timeout occurred, capture the rxFifo data
emptyRxFifo(p_i2c);
p_i2c->dev->int_clr.rx_fifo_full=1;
p_i2c->dev->int_ena.rx_fifo_full=1; //why?
}
if (activeInt & I2C_TRANS_COMPLETE_INT_ST_M) {
p_i2c->dev->int_clr.trans_complete = 1;
i2cIsrExit(p_i2c,EVENT_DONE,false);
return; // no more work to do
/*
@ -729,7 +760,7 @@ functional with Silicon date=0x16042000
static i2c_err_t i2cAddQueue(i2c_t * i2c,uint8_t mode, uint16_t i2cDeviceAddr, uint8_t *dataPtr, uint16_t dataLen,bool sendStop, EventGroupHandle_t event)
{
// need to grab a MUTEX for exclusive Queue,
// what out if ISR is running?
// what about if ISR is running?
if(i2c==NULL) {
return I2C_ERROR_DEV;
@ -745,7 +776,6 @@ static i2c_err_t i2cAddQueue(i2c_t * i2c,uint8_t mode, uint16_t i2cDeviceAddr, u
dqx.ctrl.mode = mode;
dqx.ctrl.stop= sendStop;
dqx.ctrl.addrReq = ((i2cDeviceAddr&0xFC00)==0x7800)?2:1; // 10bit or 7bit address
dqx.queueLength = dataLen + dqx.ctrl.addrReq;
dqx.queueEvent = event;
if(event) { // an eventGroup exist, so, initialize it
@ -788,7 +818,7 @@ i2c_err_t i2cAddQueueRead(i2c_t * i2c, uint16_t i2cDeviceAddr, uint8_t *dataPtr,
// readBit.
// this might cause an internal register pointer problem with 10bit
// devices, But, Don't have any to test agains.
// devices, But, Don't have any to test against.
// this is the Industry Standard specification.
if((i2cDeviceAddr &0xFC00)==0x7800) { // ten bit read
@ -839,7 +869,7 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
*/
i2c->stage = I2C_DONE; // until ready
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER)
for(uint16_t i=0; i<INTBUFFMAX; i++) {
intBuff[i][0][i2c->num] = 0;
intBuff[i][1][i2c->num] = 0;
@ -863,30 +893,14 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
i2c_err_t reason = I2C_ERROR_OK;
i2c->mode = I2C_MASTER;
i2c->dev->ctr.trans_start=0; // Pause Machine
i2c->dev->timeout.tout = 0xFFFFF; // max 13ms
I2C_FIFO_CONF_t f;
f.val = i2c->dev->fifo_conf.val;
f.rx_fifo_rst = 1; // fifo in reset
f.tx_fifo_rst = 1; // fifo in reset
f.nonfifo_en = 0; // use fifo mode
// need to adjust threshold based on I2C clock rate, at 100k, 30 usually works,
// sometimes the emptyRx() actually moves 31 bytes
// it hasn't overflowed yet, I cannot tell if the new byte is added while
// emptyRX() is executing or before?
f.rx_fifo_full_thrhd = 30; // 30 bytes before INT is issued
f.fifo_addr_cfg_en = 0; // no directed access
i2c->dev->fifo_conf.val = f.val; // post them all
i2c->dev->int_clr.val = 0x1FFF; // kill them All!
f.rx_fifo_rst = 0; // release fifo
f.tx_fifo_rst = 0;
i2c->dev->fifo_conf.val = f.val; // post them all
i2c->dev->int_clr.val = 0xFFFFFFFF; // kill them All!
i2c->dev->ctr.ms_mode = 1; // master!
i2c->queuePos=0;
i2c->byteCnt=0;
i2c->errorByteCnt=0;
i2c->errorQueue = 0;
uint32_t totalBytes=0; // total number of bytes to be Moved!
// convert address field to required I2C format
while(i2c->queuePos < i2c->queueCount) { // need to push these address modes upstream, to AddQueue
@ -901,26 +915,48 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
|tdq->ctrl.mode;
}
tdq->ctrl.addr = taddr; // all fixed with R/W bit
totalBytes += tdq->queueLength; // total number of byte to be moved!
totalBytes += tdq->length + tdq->ctrl.addrReq; // total number of byte to be moved!
}
i2c->queuePos=0;
fillCmdQueue(i2c,false); // don't enable Tx/RX irq's
// start adding command[], END irq will keep it full
//Data Fifo will be filled after trans_start is issued
i2c->exitCode=0;
I2C_FIFO_CONF_t f;
f.val = i2c->dev->fifo_conf.val;
f.rx_fifo_rst = 1; // fifo in reset
f.tx_fifo_rst = 1; // fifo in reset
f.nonfifo_en = 0; // use fifo mode
f.nonfifo_tx_thres = 31;
// need to adjust threshold based on I2C clock rate, at 100k, 30 usually works,
// sometimes the emptyRx() actually moves 31 bytes
// it hasn't overflowed yet, I cannot tell if the new byte is added while
// emptyRX() is executing or before?
// let i2cSetFrequency() set thrhds
// f.rx_fifo_full_thrhd = 30; // 30 bytes before INT is issued
// f.tx_fifo_empty_thrhd = 0;
f.fifo_addr_cfg_en = 0; // no directed access
i2c->dev->fifo_conf.val = f.val; // post them all
f.rx_fifo_rst = 0; // release fifo
f.tx_fifo_rst = 0;
i2c->dev->fifo_conf.val = f.val; // post them all
i2c->stage = I2C_STARTUP; // everything configured, now start the I2C StateMachine, and
// As soon as interrupts are enabled, the ISR will start handling them.
// it should receive a TXFIFO_EMPTY immediately, even before it
// receives the TRANS_START
i2c->dev->int_ena.val =
I2C_ACK_ERR_INT_ENA | // (BIT(10)) Causes Fatal Error Exit
I2C_TRANS_START_INT_ENA | // (BIT(9)) Triggered by trans_start=1, initial,END
I2C_TIME_OUT_INT_ENA | //(BIT(8)) Trigger by SLAVE SCL stretching, NOT an ERROR
I2C_TRANS_COMPLETE_INT_ENA | // (BIT(7)) triggered by STOP, successful exit
I2C_MASTER_TRAN_COMP_INT_ENA | // (BIT(6)) counts each byte xfer'd, inc's queuePos
// I2C_MASTER_TRAN_COMP_INT_ENA | // (BIT(6)) counts each byte xfer'd, inc's queuePos
I2C_ARBITRATION_LOST_INT_ENA | // (BIT(5)) cause fatal error exit
I2C_SLAVE_TRAN_COMP_INT_ENA | // (BIT(4)) unhandled
I2C_END_DETECT_INT_ENA | // (BIT(3)) refills cmd[] list
@ -936,9 +972,9 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
ESP_INTR_FLAG_LOWMED; //< Low and medium prio interrupts. These can be handled in C.
if(i2c->num) {
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT1_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x1FFF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT1_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x7FF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
} else {
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT0_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x1FFF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
ret = esp_intr_alloc_intrstatus(ETS_I2C_EXT0_INTR_SOURCE, flags, (uint32_t)&i2c->dev->int_status.val, 0x7FF, &i2c_isr_handler_default,i2c, &i2c->intr_handle);
}
if(ret!=ESP_OK) {
@ -950,28 +986,26 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
//hang until it completes.
// how many ticks should it take to transfer totalBytes thru the I2C hardware,
// add user supplied timeOutMillis to Calc Value
// 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;
//log_e("before startup @tick=%d will wait=%d",xTaskGetTickCount(),ticksTimeOut);
i2c->dev->ctr.trans_start=1; // go for it
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
portTickType tBefore=xTaskGetTickCount();
#endif
uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut);
// wait for ISR to complete the transfer, or until timeOut in case of bus fault, hardware problem
//log_e("after WaitBits=%x @tick=%d",eBits,xTaskGetTickCount());
uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut);
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
portTickType tAfter=xTaskGetTickCount();
#endif
uint32_t b;
// if xEventGroupSetBitsFromISR() failed, the ISR could have succeeded but never been
// able to mark the success
@ -979,13 +1013,14 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
// log_e("EventGroup Failed:%p!=%p",eBits,i2c->exitCode);
eBits=i2c->exitCode;
}
if((eBits&EVENT_ERROR)||(!(eBits & EVENT_DONE))){ // need accurate errorByteCnt for debug
i2c_update_error_byte_cnt(i2c);
}
if(!(eBits==EVENT_DONE)&&(eBits&~(EVENT_ERROR_NAK|EVENT_ERROR_DATA_NAK|EVENT_ERROR|EVENT_DONE))) { // not only Done, therefore error, exclude ADDR NAK, DATA_NAK
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
i2cDumpI2c(i2c);
i2cDumpInts(i2c->num);
#else
log_n("I2C exitCode=0x%x",eBits);
#endif
}
@ -1016,11 +1051,12 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
i2c->stage = I2C_DONE;
i2c->dev->int_ena.val =0;
i2c->dev->int_clr.val = 0x1FFF;
if((i2c->queuePos==0)&&(i2c->byteCnt==0)) { // Bus Busy no bytes Moved
i2c_update_error_byte_cnt(i2c);
if(i2c->errorByteCnt == 0) { // Bus Busy no bytes Moved
reason = I2C_ERROR_BUSY;
eBits = eBits | EVENT_ERROR_BUS_BUSY|EVENT_ERROR|EVENT_DONE;
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
log_e(" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
log_d(" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
i2cDumpI2c(i2c);
i2cDumpInts(i2c->num);
#endif
@ -1028,19 +1064,25 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
reason = I2C_ERROR_TIMEOUT;
eBits = eBits | EVENT_ERROR_TIMEOUT|EVENT_ERROR|EVENT_DONE;
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
log_e(" Gross Timeout Dead start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
log_d(" Gross Timeout Dead start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
i2cDumpI2c(i2c);
i2cDumpInts(i2c->num);
#endif
}
}
// offloading all EventGroups to dispatch, EventGroups in ISR is not always successful
// 11/20/2017
// if error, need to trigger all succeeding dataQueue events with the EVENT_ERROR_PREV
b = 0;
/* offloading all EventGroups to dispatch, EventGroups in ISR is not always successful
11/20/2017
if error, need to trigger all succeeding dataQueue events with the EVENT_ERROR_PREV
07/22/2018
Need to use the queueEvent value to identify transaction blocks, if an error occurs,
all subsequent queue items with the same queueEvent value will receive the EVENT_ERROR_PREV.
But, ProcQue should re-queue queue items that have a different queueEvent value(different transaction)
This change will support multi-thread i2c usage. Use the queueEvent as the transaction event
identifier.
*/
uint32_t b = 0;
while(b < i2c->queueCount) {
if(i2c->dq[b].ctrl.mode==1 && readCount) {
@ -1159,6 +1201,7 @@ i2c_err_t i2cDetachSDA(i2c_t * i2c, int8_t sda)
// 24Nov17 only supports Master Mode
i2c_t * i2cInit(uint8_t i2c_num, int8_t sda, int8_t scl, uint32_t frequency) //before this is called, pins should be detached, else glitch
{
log_v("num=%d sda=%d scl=%d freq=%d",i2c_num, sda, scl, frequency);
if(i2c_num > 1) {
return NULL;
}
@ -1326,12 +1369,23 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
if(i2c == NULL) {
return I2C_ERROR_DEV;
}
I2C_FIFO_CONF_t f;
uint32_t period = (APB_CLK_FREQ/clk_speed) / 2;
uint32_t halfPeriod = period/2;
uint32_t quarterPeriod = period/4;
I2C_MUTEX_LOCK();
// Adjust Fifo thresholds based on frequency
f.val = i2c->dev->fifo_conf.val;
uint32_t a = (clk_speed / 50000L )+1;
if (a > 24) a=24;
f.rx_fifo_full_thrhd = 32 - a;
f.tx_fifo_empty_thrhd = a;
i2c->dev->fifo_conf.val = f.val; // set thresholds
log_v("Fifo threshold=%d",a);
//the clock num during SCL is low level
i2c->dev->scl_low_period.period = period;
//the clock num during SCL is high level
@ -1381,7 +1435,12 @@ void i2cDumpDqData(i2c_t * i2c)
I2C_DATA_QUEUE_t *tdq;
while(a<i2c->queueCount) {
tdq=&i2c->dq[a];
log_e("[%d] %x %c %s buf@=%p, len=%d, pos=%d, eventH=%p bits=%x",a,tdq->ctrl.addr,(tdq->ctrl.mode)?'R':'W',(tdq->ctrl.stop)?"STOP":"",tdq->data,tdq->length,tdq->position,tdq->queueEvent,(tdq->queueEvent)?xEventGroupGetBits(tdq->queueEvent):0);
log_e("[%d] %sbit %x %c %s buf@=%p, len=%d, pos=%d, eventH=%p bits=%x",a,
(tdq->ctrl.addr>0x100)?"10":"7",
(tdq->ctrl.addr>0x100)?(((tdq->ctrl.addr&0x600)>>1)|(tdq->ctrl.addr&0xff)):(tdq->ctrl.addr>>1),
(tdq->ctrl.mode)?'R':'W',
(tdq->ctrl.stop)?"STOP":"",
tdq->data,tdq->length,tdq->position,tdq->queueEvent,(tdq->queueEvent)?xEventGroupGetBits(tdq->queueEvent):0);
uint16_t offset = 0;
while(offset<tdq->length) {
memset(buff,' ',140);
@ -1403,8 +1462,6 @@ void i2cDumpDqData(i2c_t * i2c)
}
a++;
}
#else
log_n("Enable Core Debug Level \"Error\"");
#endif
}
@ -1424,7 +1481,8 @@ void i2cDumpI2c(i2c_t * i2c)
log_e("dq=%p",i2c->dq);
log_e("queueCount=%d",i2c->queueCount);
log_e("queuePos=%d",i2c->queuePos);
log_e("byteCnt=%d",i2c->byteCnt);
log_e("errorByteCnt=%d",i2c->errorByteCnt);
log_e("errorQueue=%d",i2c->errorQueue);
if(i2c->dq) {
i2cDumpDqData(i2c);
}
@ -1432,7 +1490,8 @@ void i2cDumpI2c(i2c_t * i2c)
void i2cDumpInts(uint8_t num)
{
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
#if (ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO) && (defined ENABLE_I2C_DEBUG_BUFFER)
uint32_t b;
log_e("%u row count INTR TX RX",num);
for(uint32_t a=1; a<=INTBUFFMAX; a++) {
@ -1442,15 +1501,15 @@ void i2cDumpInts(uint8_t num)
}
}
#else
log_n("enable Core Debug Level \"Error\"");
log_i("Debug Buffer not Enabled");
#endif
}
/* todo
24Nov17
Need to think about not usings I2C_MASTER_TRAN_COMP_INT_ST to adjust queuePos. This
INT triggers every byte. The only reason to know which byte is being transfered is
the status_reg.tx_fifo_cnt and a .txQueued to do this in the fillRxFifo(). The
same mechanism could work if an error occured in i2cErrorExit().
22JUL18
need to add multi-thread capability, use dq.queueEvent as the group marker. When multiple threads
transactions are present in the same queue, and an error occurs, abort all succeeding unserviced transactions
with the same dq.queueEvent value. Succeeding unserviced transactions with different dq.queueEvent values
can be re-queued and processed independently.
*/

View File

@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp32-hal.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -24,6 +23,7 @@
#include "esp_timer.h"
#include "esp_bt.h"
#include <sys/time.h>
#include "esp32-hal.h"
//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

View File

@ -1,6 +1,5 @@
#include "esp32-hal.h"
#include "sdkconfig.h"
#if CONFIG_SPIRAM_SUPPORT
#include "esp_spiram.h"

View File

@ -15,6 +15,10 @@
#ifndef _ESP32_HAL_PSRAM_H_
#define _ESP32_HAL_PSRAM_H_
#ifdef __cplusplus
extern "C" {
#endif
bool psramInit();
bool psramFound();
@ -22,4 +26,8 @@ void *ps_malloc(size_t size);
void *ps_calloc(size_t n, size_t size);
void *ps_realloc(void *ptr, size_t size);
#ifdef __cplusplus
}
#endif
#endif /* _ESP32_HAL_PSRAM_H_ */

View File

@ -315,11 +315,14 @@ void uartFlush(uart_t* uart)
UART_MUTEX_LOCK();
while(uart->dev->status.txfifo_cnt);
uart->dev->conf0.txfifo_rst = 1;
uart->dev->conf0.txfifo_rst = 0;
//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));
}
uart->dev->conf0.rxfifo_rst = 1;
uart->dev->conf0.rxfifo_rst = 0;
UART_MUTEX_UNLOCK();
}

View File

@ -33,6 +33,7 @@ extern "C" {
#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)
@ -60,7 +61,12 @@ void yield(void);
#include "esp32-hal-timer.h"
#include "esp32-hal-bt.h"
#include "esp32-hal-psram.h"
#include "esp_system.h"
#ifndef BOARD_HAS_PSRAM
#ifdef CONFIG_SPIRAM_SUPPORT
#undef CONFIG_SPIRAM_SUPPORT
#endif
#endif
//returns chip temperature in Celsius
float temperatureRead();

View File

@ -0,0 +1,59 @@
# Over the Air through Web browser
OTAWebUpdate is done with a web browser that can be useful in the following typical scenarios:
- Once the application developed and loading directly from Arduino IDE is inconvenient or not possible
- after deployment if user is unable to expose Firmware for OTA from external update server
- provide updates after deployment to small quantity of modules when setting an update server is not practicable
## Requirements
- The ESP and the computer must be connected to the same network
## Implementation
The sample implementation has been done using:
- example sketch OTAWebUpdater.ino
- ESP32 (Dev Module)
You can use another module also if it meets Flash chip size of the sketch
1-Before you begin, please make sure that you have the following software installed:
- Arduino IDE
- Host software depending on O/S you use:
- Avahi http://avahi.org/ for Linux
- Bonjour http://www.apple.com/support/bonjour/ for Windows
- Mac OSX and iOS - support is already built in / no any extra s/w is required
Prepare the sketch and configuration for initial upload with a serial port
- Start Arduino IDE and load sketch OTAWebUpdater.ino available under File > Examples > OTAWebUpdater.ino
- Update ssid and pass in the sketch so the module can join your Wi-Fi network
- Open File > Preferences, look for “Show verbose output during:” and check out “compilation” option
![verbrose](esp32verbose.PNG)
- Upload sketch (Ctrl+U)
- Now open web browser and enter the url, i.e. http://esp32.local. Once entered, browser should display a form
![login](esp32login.PNG)
> username= admin
> password= admin
**Note**-*If entering “http://ESP32.local” does not work, try replacing “ESP32” with modules IP address.This workaround is useful in case the host software installed does not work*.
Now click on Login button and browser will display a upload form
![upload](esp32upload.PNG)
For Uploading the New Firmware you need to provide the Binary File of your Code.
Exporting Binary file of the Firmware (Code)
- Open up the Arduino IDE
- Open up the Code, for Exporting up Binary file
- Now go to Sketch > export compiled Binary
![export](exportTobinary.PNG)
- Binary file is exported to the same Directory where your code is present
Once you are comfortable with this procedure go ahead and modify OTAWebUpdater.ino sketch to print some additional messages, compile it, Export new binary file and upload it using web browser to see entered changes on a Serial Monitor

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,15 @@
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).
- 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.
- 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).
#### [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/)
Stable release link: `https://dl.espressif.com/dl/package_esp32_index.json`
#### [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/)
Development release link: `https://dl.espressif.com/dl/package_esp32_dev_index.json`

View File

@ -4,18 +4,23 @@
#include <ESPmDNS.h>
#include <Update.h>
const char* host = "ESP32";
const char* host = "esp32";
const char* ssid = "xxx";
const char* password = "xxxx";
WebServer server(80);
const char* loginIndex = "<form name='loginForm'>"
/*
* Login page
*/
const char* loginIndex =
"<form name='loginForm'>"
"<table width='20%' bgcolor='A09F9F' align='center'>"
"<tr>"
"<td colspan=2><center><font size=4><b>ESP32 Login Page</b></font></center>"
"<td colspan=2>"
"<center><font size=4><b>ESP32 Login Page</b></font></center>"
"<br>"
"</td>"
"<br>"
"<br>"
@ -31,7 +36,6 @@ const char* loginIndex = "<form name='loginForm'>"
"<br>"
"<br>"
"</tr>"
"<tr>"
"<td><input type='submit' onclick='check(this.form)' value='Login'></td>"
"</tr>"
@ -47,16 +51,16 @@ const char* loginIndex = "<form name='loginForm'>"
"else"
"{"
" alert('Error Password or Username')/*displays error message*/"
"}"
"}"
"</script>";
/*
* Server Index Page
*/
const char* serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
@ -91,6 +95,10 @@ const char* serverIndex = "<script src='https://ajax.googleapis.com/ajax/libs/jq
"});"
"});"
"</script>";
/*
* setup function
*/
void setup(void) {
Serial.begin(115200);

View File

@ -20,6 +20,7 @@ ArduinoOTAClass::ArduinoOTAClass()
, _size(0)
, _cmd(0)
, _ota_port(0)
, _ota_timeout(1000)
, _start_callback(NULL)
, _end_callback(NULL)
, _error_callback(NULL)
@ -260,8 +261,9 @@ void ArduinoOTAClass::_runUpdate() {
}
uint32_t written = 0, total = 0, tried = 0;
while (!Update.isFinished() && client.connected()) {
size_t waited = 1000;
size_t waited = _ota_timeout;
size_t available = client.available();
while (!available && waited){
delay(1);
@ -387,6 +389,10 @@ int ArduinoOTAClass::getCommand() {
return _cmd;
}
void ArduinoOTAClass::setTimeout(int timeoutInMillis) {
_ota_timeout = timeoutInMillis;
}
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA)
ArduinoOTAClass ArduinoOTA;
#endif

View File

@ -7,7 +7,6 @@
#define INT_BUFFER_SIZE 16
typedef enum {
OTA_IDLE,
OTA_WAITAUTH,
@ -75,6 +74,8 @@ class ArduinoOTAClass
//Gets update command type after OTA has started. Either U_FLASH or U_SPIFFS
int getCommand();
void setTimeout(int timeoutInMillis);
private:
int _port;
String _password;
@ -88,6 +89,7 @@ class ArduinoOTAClass
int _size;
int _cmd;
int _ota_port;
int _ota_timeout;
IPAddress _ota_ip;
String _md5;

View File

@ -286,6 +286,8 @@ AsyncUDPPacket::AsyncUDPPacket(AsyncUDP *udp, pbuf *pb, const ip_addr_t *raddr,
_len = pb->len;
_index = 0;
pbuf_ref(_pb);
//memcpy(&_remoteIp, raddr, sizeof(ip_addr_t));
_remoteIp.type = raddr->type;
_localIp.type = _remoteIp.type;

View File

@ -136,6 +136,16 @@ static bool _init_bt(const char *deviceName)
}
esp_bt_dev_set_device_name(deviceName);
// the default BTA_DM_COD_LOUDSPEAKER does not work with the macOS BT stack
esp_bt_cod_t cod;
cod.major = 0b00001;
cod.minor = 0b000100;
cod.service = 0b00000010110;
if (esp_bt_gap_set_cod(cod, ESP_BT_INIT_COD) != ESP_OK) {
log_e("%s set cod failed\n", __func__);
return false;
}
return true;
}

View File

@ -24,7 +24,6 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Arduino.h"
#include "EEPROM.h"
#include <esp_log.h>
@ -296,9 +295,9 @@ String EEPROMClass::readString (int address)
if (address + len > _size)
return String(0);
char value[len + 1];
char value[len];
memcpy((uint8_t*) value, _data + address, len);
value[len + 1] = 0;
value[len] = 0;
return String(value);
}

View File

@ -29,6 +29,7 @@
#ifndef EEPROM_FLASH_PARTITION_NAME
#define EEPROM_FLASH_PARTITION_NAME "eeprom"
#endif
#include <Arduino.h>
extern "C" {
#include <stddef.h>

View File

@ -0,0 +1,45 @@
#include <Arduino.h>
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};
Button button1 = {23, 0, false};
Button button2 = {18, 0, false};
void IRAM_ATTR isr(void* arg) {
Button* s = static_cast<Button*>(arg);
s->numberKeyPresses += 1;
s->pressed = true;
}
void IRAM_ATTR isr() {
button2.numberKeyPresses += 1;
button2.pressed = true;
}
void setup() {
Serial.begin(115200);
pinMode(button1.PIN, INPUT_PULLUP);
attachInterruptArg(button1.PIN, isr, &button1, FALLING);
pinMode(button2.PIN, INPUT_PULLUP);
attachInterrupt(button2.PIN, isr, FALLING);
}
void loop() {
if (button1.pressed) {
Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
button1.pressed = false;
}
if (button2.pressed) {
Serial.printf("Button 2 has been pressed %u times\n", button2.numberKeyPresses);
button2.pressed = false;
}
static uint32_t lastMillis = 0;
if (millis() - lastMillis > 10000) {
lastMillis = millis();
detachInterrupt(button1.PIN);
}
}

View File

@ -47,7 +47,9 @@ enum SeekMode {
class File : public Stream
{
public:
File(FileImplPtr p = FileImplPtr()) : _p(p) {}
File(FileImplPtr p = FileImplPtr()) : _p(p) {
_timeout = 0;
}
size_t write(uint8_t) override;
size_t write(const uint8_t *buf, size_t size) override;

View File

@ -252,7 +252,7 @@ void HTTPClient::end(void)
bool HTTPClient::connected()
{
if(_tcp) {
return (_tcp->connected() || (_tcp->available() > 0));
return ((_tcp->available() > 0) || _tcp->connected());
}
return false;
}

View File

@ -1,6 +1,11 @@
#include "FS.h"
#include "SPIFFS.h"
/* You only need to format SPIFFS the first time you run a
test or else use the SPIFFS plugin to create a partition
https://github.com/me-no-dev/arduino-esp32fs-plugin */
#define FORMAT_SPIFFS_IF_FAILED true
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\r\n", dirname);
@ -151,7 +156,7 @@ void testFileIO(fs::FS &fs, const char * path){
void setup(){
Serial.begin(115200);
if(!SPIFFS.begin()){
if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){
Serial.println("SPIFFS Mount Failed");
return;
}

View File

@ -32,6 +32,10 @@
#define DEBUG_OUTPUT Serial
#endif
#ifndef WEBSERVER_MAX_POST_ARGS
#define WEBSERVER_MAX_POST_ARGS 32
#endif
static const char Content_Type[] PROGMEM = "Content-Type";
static const char filename[] PROGMEM = "filename";
@ -355,14 +359,14 @@ void WebServer::_uploadWriteByte(uint8_t b){
_currentUpload->buf[_currentUpload->currentSize++] = b;
}
uint8_t WebServer::_uploadReadByte(WiFiClient& client){
int WebServer::_uploadReadByte(WiFiClient& client){
int res = client.read();
if(res == -1){
while(!client.available() && client.connected())
yield();
delay(2);
res = client.read();
}
return (uint8_t)res;
return res;
}
bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
@ -383,8 +387,9 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
client.readStringUntil('\n');
//start reading the form
if (line == ("--"+boundary)){
RequestArgument* postArgs = new RequestArgument[32];
int postArgsLen = 0;
if(_postArgs) delete[] _postArgs;
_postArgs = new RequestArgument[WEBSERVER_MAX_POST_ARGS];
_postArgsLen = 0;
while(1){
String argName;
String argValue;
@ -445,7 +450,7 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
DEBUG_OUTPUT.println();
#endif
RequestArgument& arg = postArgs[postArgsLen++];
RequestArgument& arg = _postArgs[_postArgsLen++];
arg.key = argName;
arg.value = argValue;
@ -472,19 +477,20 @@ bool WebServer::_parseForm(WiFiClient& client, String boundary, uint32_t len){
if(_currentHandler && _currentHandler->canUpload(_currentUri))
_currentHandler->upload(*this, _currentUri, *_currentUpload);
_currentUpload->status = UPLOAD_FILE_WRITE;
uint8_t argByte = _uploadReadByte(client);
int argByte = _uploadReadByte(client);
readfile:
while(argByte != 0x0D){
if (!client.connected()) return _parseFormUploadAborted();
if(argByte < 0) return _parseFormUploadAborted();
_uploadWriteByte(argByte);
argByte = _uploadReadByte(client);
}
argByte = _uploadReadByte(client);
if (!client.connected()) return _parseFormUploadAborted();
if(argByte < 0) return _parseFormUploadAborted();
if (argByte == 0x0A){
argByte = _uploadReadByte(client);
if (!client.connected()) return _parseFormUploadAborted();
if(argByte < 0) return _parseFormUploadAborted();
if ((char)argByte != '-'){
//continue reading the file
_uploadWriteByte(0x0D);
@ -492,7 +498,7 @@ readfile:
goto readfile;
} else {
argByte = _uploadReadByte(client);
if (!client.connected()) return _parseFormUploadAborted();
if(argByte < 0) return _parseFormUploadAborted();
if ((char)argByte != '-'){
//continue reading the file
_uploadWriteByte(0x0D);
@ -552,22 +558,25 @@ readfile:
}
int iarg;
int totalArgs = ((32 - postArgsLen) < _currentArgCount)?(32 - postArgsLen):_currentArgCount;
int totalArgs = ((WEBSERVER_MAX_POST_ARGS - _postArgsLen) < _currentArgCount)?(WEBSERVER_MAX_POST_ARGS - _postArgsLen):_currentArgCount;
for (iarg = 0; iarg < totalArgs; iarg++){
RequestArgument& arg = postArgs[postArgsLen++];
RequestArgument& arg = _postArgs[_postArgsLen++];
arg.key = _currentArgs[iarg].key;
arg.value = _currentArgs[iarg].value;
}
if (_currentArgs) delete[] _currentArgs;
_currentArgs = new RequestArgument[postArgsLen];
for (iarg = 0; iarg < postArgsLen; iarg++){
_currentArgs = new RequestArgument[_postArgsLen];
for (iarg = 0; iarg < _postArgsLen; iarg++){
RequestArgument& arg = _currentArgs[iarg];
arg.key = postArgs[iarg].key;
arg.value = postArgs[iarg].value;
arg.key = _postArgs[iarg].key;
arg.value = _postArgs[iarg].value;
}
_currentArgCount = iarg;
if (postArgs)
delete[] postArgs;
if (_postArgs) {
delete[] _postArgs;
_postArgs=nullptr;
_postArgsLen = 0;
}
return true;
}
#ifdef DEBUG_ESP_HTTP_SERVER

View File

@ -54,6 +54,8 @@ WebServer::WebServer(IPAddress addr, int port)
, _lastHandler(nullptr)
, _currentArgCount(0)
, _currentArgs(nullptr)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0)
, _currentHeaders(nullptr)
, _contentLength(0)
@ -72,6 +74,8 @@ WebServer::WebServer(int port)
, _lastHandler(nullptr)
, _currentArgCount(0)
, _currentArgs(nullptr)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0)
, _currentHeaders(nullptr)
, _contentLength(0)
@ -94,11 +98,13 @@ WebServer::~WebServer() {
void WebServer::begin() {
close();
_server.begin();
_server.setNoDelay(true);
}
void WebServer::begin(uint16_t port) {
close();
_server.begin(port);
_server.setNoDelay(true);
}
String WebServer::_extractParam(String& authReq,const String& param,const char delimit){
@ -505,6 +511,10 @@ void WebServer::_streamFileCore(const size_t fileSize, const String & fileName,
String WebServer::arg(String name) {
for (int j = 0; j < _postArgsLen; ++j) {
if ( _postArgs[j].key == name )
return _postArgs[j].value;
}
for (int i = 0; i < _currentArgCount; ++i) {
if ( _currentArgs[i].key == name )
return _currentArgs[i].value;
@ -529,6 +539,10 @@ int WebServer::args() {
}
bool WebServer::hasArg(String name) {
for (int j = 0; j < _postArgsLen; ++j) {
if (_postArgs[j].key == name)
return true;
}
for (int i = 0; i < _currentArgCount; ++i) {
if (_currentArgs[i].key == name)
return true;

View File

@ -34,10 +34,10 @@ enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END,
enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE };
enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH };
#define HTTP_DOWNLOAD_UNIT_SIZE 1460
#define HTTP_DOWNLOAD_UNIT_SIZE 1436
#ifndef HTTP_UPLOAD_BUFLEN
#define HTTP_UPLOAD_BUFLEN 2048
#define HTTP_UPLOAD_BUFLEN 1436
#endif
#define HTTP_MAX_DATA_WAIT 5000 //ms to wait for the client to send the request
@ -147,7 +147,7 @@ protected:
bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
bool _parseFormUploadAborted();
void _uploadWriteByte(uint8_t b);
uint8_t _uploadReadByte(WiFiClient& client);
int _uploadReadByte(WiFiClient& client);
void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
bool _collectHeader(const char* headerName, const char* headerValue);
@ -179,6 +179,9 @@ protected:
int _currentArgCount;
RequestArgument* _currentArgs;
int _postArgsLen;
RequestArgument* _postArgs;
std::unique_ptr<HTTPUpload> _currentUpload;
int _headerKeysCount;

View File

@ -0,0 +1,63 @@
//Sketch edited by: Martin Chlebovec
//Personal website: https://arduino.php5.sk
#include "esp_wpa2.h"
#include <WiFi.h>
#define EAP_IDENTITY "login@university.domain" //eduroam login --> identity@youruniversity.domain
#define EAP_PASSWORD "password" //your Eduroam password
String line; //variable for response
const char* ssid = "eduroam"; // Eduroam SSID
const char* host = "arduino.php5.sk"; //external server domain for HTTP connection after authentification
void setup() {
Serial.begin(115200);
delay(10);
Serial.println();
Serial.print("Connecting to network: ");
Serial.println(ssid);
WiFi.disconnect(true); //disconnect form wifi to set new wifi connection
esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)EAP_IDENTITY, strlen(EAP_IDENTITY)); //provide identity
esp_wifi_sta_wpa2_ent_set_username((uint8_t *)EAP_IDENTITY, strlen(EAP_IDENTITY)); //provide username
esp_wifi_sta_wpa2_ent_set_password((uint8_t *)EAP_PASSWORD, strlen(EAP_PASSWORD)); //provide password
esp_wpa2_config_t config = WPA2_CONFIG_INIT_DEFAULT(); //set config to default (fixed for 2018 and Arduino 1.8.5+)
esp_wifi_sta_wpa2_ent_enable(&config); //set config to enable function (fixed for 2018 and Arduino 1.8.5+)
WiFi.begin(ssid); //connect to Eduroam function
WiFi.setHostname("ESP32Name"); //set Hostname for your device - not neccesary
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address set: ");
Serial.println(WiFi.localIP()); //print LAN IP
}
void loop() {
delay(5000);
if (WiFi.status() != WL_CONNECTED) { //if we lost connection, retry
WiFi.begin(ssid);
delay(500);
}
Serial.print("Connecting to website: ");
Serial.println(host);
WiFiClient client;
if (!client.connect(host, 80)) { // HTTP connection on port 80
Serial.println("Connection lost! - Failed response");
}
String url = "/rele/rele1.txt"; //read .txt file
Serial.print("Requesting URL: ");
Serial.println(url);
client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println("Client timed out! - retry");
}
}
while(client.available()) {
line = client.readStringUntil('\n');
Serial.println(line);
}
Serial.println();
Serial.println("End connection");
client.stop();
}

View File

@ -31,8 +31,6 @@ const char* password = "**********";
WiFiServer server(23);
WiFiClient serverClients[MAX_SRV_CLIENTS];
HardwareSerial Serial1(2); // UART1/Serial1 pins 16,17
void setup() {
Serial.begin(115200);
Serial.println("\nConnecting");
@ -62,7 +60,7 @@ void setup() {
}
//start UART and the server
Serial1.begin(9600);
Serial2.begin(9600);
server.begin();
server.setNoDelay(true);
@ -98,7 +96,7 @@ void loop() {
if (serverClients[i] && serverClients[i].connected()){
if(serverClients[i].available()){
//get data from the telnet client and push it to the UART
while(serverClients[i].available()) Serial1.write(serverClients[i].read());
while(serverClients[i].available()) Serial2.write(serverClients[i].read());
}
}
else {
@ -108,10 +106,10 @@ void loop() {
}
}
//check UART for data
if(Serial1.available()){
size_t len = Serial1.available();
if(Serial2.available()){
size_t len = Serial2.available();
uint8_t sbuf[len];
Serial1.readBytes(sbuf, len);
Serial2.readBytes(sbuf, len);
//push UART data to all connected telnet clients
for(i = 0; i < MAX_SRV_CLIENTS; i++){
if (serverClients[i] && serverClients[i].connected()){

View File

@ -184,6 +184,11 @@ bool WiFiAPClass::softAPdisconnect(bool wifioff)
{
bool ret;
wifi_config_t conf;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return ESP_ERR_INVALID_STATE;
}
*conf.ap.ssid = 0;
*conf.ap.password = 0;
conf.ap.authmode = WIFI_AUTH_OPEN; // auth must be open if pass=0
@ -204,6 +209,9 @@ bool WiFiAPClass::softAPdisconnect(bool wifioff)
uint8_t WiFiAPClass::softAPgetStationNum()
{
wifi_sta_list_t clients;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return 0;
}
if(esp_wifi_ap_get_sta_list(&clients) == ESP_OK) {
return clients.num;
}
@ -217,6 +225,9 @@ uint8_t WiFiAPClass::softAPgetStationNum()
IPAddress WiFiAPClass::softAPIP()
{
tcpip_adapter_ip_info_t ip;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ip);
return IPAddress(ip.ip.addr);
}
@ -229,7 +240,9 @@ IPAddress WiFiAPClass::softAPIP()
*/
uint8_t* WiFiAPClass::softAPmacAddress(uint8_t* mac)
{
if(WiFiGenericClass::getMode() != WIFI_MODE_NULL){
esp_wifi_get_mac(WIFI_IF_AP, mac);
}
return mac;
}
@ -241,6 +254,9 @@ String WiFiAPClass::softAPmacAddress(void)
{
uint8_t mac[6];
char macStr[18] = { 0 };
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return String();
}
esp_wifi_get_mac(WIFI_IF_AP, mac);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@ -253,9 +269,12 @@ String WiFiAPClass::softAPmacAddress(void)
*/
const char * WiFiAPClass::softAPgetHostname()
{
const char * hostname;
const char * hostname = NULL;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return hostname;
}
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_AP, &hostname)) {
return NULL;
return hostname;
}
return hostname;
}
@ -267,6 +286,9 @@ const char * WiFiAPClass::softAPgetHostname()
*/
bool WiFiAPClass::softAPsetHostname(const char * hostname)
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false;
}
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_AP, hostname) == ESP_OK;
}
@ -276,6 +298,9 @@ bool WiFiAPClass::softAPsetHostname(const char * hostname)
*/
bool WiFiAPClass::softAPenableIpV6()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false;
}
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_AP) == ESP_OK;
}
@ -286,6 +311,9 @@ bool WiFiAPClass::softAPenableIpV6()
IPv6Address WiFiAPClass::softAPIPv6()
{
static ip6_addr_t addr;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPv6Address();
}
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_AP, &addr)) {
return IPv6Address();
}

View File

@ -31,6 +31,118 @@
#undef write
#undef read
class WiFiClientRxBuffer {
private:
size_t _size;
uint8_t *_buffer;
size_t _pos;
size_t _fill;
int _fd;
bool _failed;
size_t r_available()
{
if(_fd < 0){
return 0;
}
int count;
int res = lwip_ioctl_r(_fd, FIONREAD, &count);
if(res < 0) {
_failed = true;
return 0;
}
return count;
}
size_t fillBuffer()
{
if(!_buffer){
_buffer = (uint8_t *)malloc(_size);
}
if(_fill && _pos == _fill){
_fill = 0;
_pos = 0;
}
if(!_buffer || _size <= _fill || !r_available()) {
return 0;
}
int res = recv(_fd, _buffer + _fill, _size - _fill, MSG_DONTWAIT);
if(res < 0 && errno != EWOULDBLOCK) {
_failed = true;
return 0;
}
_fill += res;
return res;
}
public:
WiFiClientRxBuffer(int fd, size_t size=1436)
:_size(size)
,_buffer(NULL)
,_pos(0)
,_fill(0)
,_fd(fd)
,_failed(false)
{
//_buffer = (uint8_t *)malloc(_size);
}
~WiFiClientRxBuffer()
{
free(_buffer);
}
bool failed(){
return _failed;
}
int read(uint8_t * dst, size_t len){
if(!dst || !len || (_pos == _fill && !fillBuffer())){
return -1;
}
size_t a = _fill - _pos;
if(len <= a || ((len - a) <= (_size - _fill) && fillBuffer() >= (len - a))){
if(len == 1){
*dst = _buffer[_pos];
} else {
memcpy(dst, _buffer + _pos, len);
}
_pos += len;
return len;
}
size_t left = len;
size_t toRead = a;
uint8_t * buf = dst;
memcpy(buf, _buffer + _pos, toRead);
_pos += toRead;
left -= toRead;
buf += toRead;
while(left){
if(!fillBuffer()){
return len - left;
}
a = _fill - _pos;
toRead = (a > left)?left:a;
memcpy(buf, _buffer + _pos, toRead);
_pos += toRead;
left -= toRead;
buf += toRead;
}
return len;
}
int peek(){
if(_pos == _fill && !fillBuffer()){
return -1;
}
return _buffer[_pos];
}
size_t available(){
return _fill - _pos + r_available();
}
};
class WiFiClientSocketHandle {
private:
int sockfd;
@ -58,6 +170,7 @@ WiFiClient::WiFiClient():_connected(false),next(NULL)
WiFiClient::WiFiClient(int fd):_connected(true),next(NULL)
{
clientSocketHandle.reset(new WiFiClientSocketHandle(fd));
_rxBuffer.reset(new WiFiClientRxBuffer(fd));
}
WiFiClient::~WiFiClient()
@ -69,6 +182,7 @@ WiFiClient & WiFiClient::operator=(const WiFiClient &other)
{
stop();
clientSocketHandle = other.clientSocketHandle;
_rxBuffer = other._rxBuffer;
_connected = other._connected;
return *this;
}
@ -76,6 +190,7 @@ WiFiClient & WiFiClient::operator=(const WiFiClient &other)
void WiFiClient::stop()
{
clientSocketHandle = NULL;
_rxBuffer = NULL;
_connected = false;
}
@ -100,6 +215,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
return 0;
}
clientSocketHandle.reset(new WiFiClientSocketHandle(sockfd));
_rxBuffer.reset(new WiFiClientRxBuffer(sockfd));
_connected = true;
return 1;
}
@ -260,11 +376,9 @@ size_t WiFiClient::write(Stream &stream)
int WiFiClient::read(uint8_t *buf, size_t size)
{
if(!available()) {
return -1;
}
int res = recv(fd(), buf, size, MSG_DONTWAIT);
if(res < 0 && errno != EWOULDBLOCK) {
int res = -1;
res = _rxBuffer->read(buf, size);
if(_rxBuffer->failed()) {
log_e("%d", errno);
stop();
}
@ -273,16 +387,12 @@ int WiFiClient::read(uint8_t *buf, size_t size)
int WiFiClient::peek()
{
if(!available()) {
return -1;
}
uint8_t data = 0;
int res = recv(fd(), &data, 1, MSG_PEEK);
if(res < 0 && errno != EWOULDBLOCK) {
int res = _rxBuffer->peek();
if(_rxBuffer->failed()) {
log_e("%d", errno);
stop();
}
return data;
return res;
}
int WiFiClient::available()
@ -290,14 +400,12 @@ int WiFiClient::available()
if(!_connected) {
return 0;
}
int count;
int res = lwip_ioctl_r(fd(), FIONREAD, &count);
if(res < 0) {
int res = _rxBuffer->available();
if(_rxBuffer->failed()) {
log_e("%d", errno);
stop();
return 0;
}
return count;
return res;
}
// Though flushing means to send all pending data,
@ -330,24 +438,25 @@ uint8_t WiFiClient::connected()
if (_connected) {
uint8_t dummy;
int res = recv(fd(), &dummy, 0, MSG_DONTWAIT);
if (res < 0) {
switch (errno) {
case EWOULDBLOCK:
case ENOENT: //caused by vfs
_connected = true;
break;
case ENOTCONN:
case EPIPE:
case ECONNRESET:
case ECONNREFUSED:
case ECONNABORTED:
_connected = false;
log_d("Disconnected: RES: %d, ERR: %d", res, errno);
break;
default:
log_i("Unexpected: RES: %d, ERR: %d", res, errno);
_connected = true;
break;
}
}
else {
_connected = true;
}
}
return _connected;
}

View File

@ -28,11 +28,13 @@
#include <memory>
class WiFiClientSocketHandle;
class WiFiClientRxBuffer;
class WiFiClient : public Client
{
protected:
std::shared_ptr<WiFiClientSocketHandle> clientSocketHandle;
std::shared_ptr<WiFiClientRxBuffer> _rxBuffer;
bool _connected;
public:

View File

@ -334,7 +334,7 @@ void WiFiGenericClass::removeEvent(wifi_event_id_t id)
* @param arg
*/
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_LOST_IP", "STA_WPS_ER_SUCCESS", "STA_WPS_ER_FAILED", "STA_WPS_ER_TIMEOUT", "STA_WPS_ER_PIN", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_PROBEREQRECVED", "GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "MAX"};
const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "STA_STOP", "STA_CONNECTED", "STA_DISCONNECTED", "STA_AUTHMODE_CHANGE", "STA_GOT_IP", "STA_LOST_IP", "STA_WPS_ER_SUCCESS", "STA_WPS_ER_FAILED", "STA_WPS_ER_TIMEOUT", "STA_WPS_ER_PIN", "AP_START", "AP_STOP", "AP_STACONNECTED", "AP_STADISCONNECTED", "AP_STAIPASSIGNED", "AP_PROBEREQRECVED", "GOT_IP6", "ETH_START", "ETH_STOP", "ETH_CONNECTED", "ETH_DISCONNECTED", "ETH_GOT_IP", "MAX"};
#endif
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_WARN
const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "UNSPECIFIED", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT" };
@ -365,17 +365,29 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
} else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
WiFiSTAClass::_setStatus(WL_CONNECTION_LOST);
} else if(reason == WIFI_REASON_AUTH_EXPIRE) {
if(WiFi.getAutoReconnect()){
WiFi.begin();
}
} else {
WiFiSTAClass::_setStatus(WL_DISCONNECTED);
}
clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT);
if(reason >= WIFI_REASON_BEACON_TIMEOUT && reason != WIFI_REASON_AUTH_FAIL && WiFi.getAutoReconnect()){
if(((reason == WIFI_REASON_AUTH_EXPIRE) ||
(reason >= WIFI_REASON_BEACON_TIMEOUT && reason != WIFI_REASON_AUTH_FAIL)) &&
WiFi.getAutoReconnect())
{
WiFi.enableSTA(false);
WiFi.enableSTA(true);
WiFi.begin();
}
} else if(event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr);
uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr);
uint8_t * gw = (uint8_t *)&(event->event_info.got_ip.ip_info.gw.addr);
log_d("STA IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u",
ip[0], ip[1], ip[2], ip[3],
mask[0], mask[1], mask[2], mask[3],
gw[0], gw[1], gw[2], gw[3]);
#endif
WiFiSTAClass::_setStatus(WL_CONNECTED);
setStatusBits(STA_HAS_IP_BIT | STA_CONNECTED_BIT);
} else if(event->event_id == SYSTEM_EVENT_STA_LOST_IP) {
@ -403,6 +415,15 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
} else if(event->event_id == SYSTEM_EVENT_ETH_DISCONNECTED) {
clearStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT | ETH_HAS_IP6_BIT);
} else if(event->event_id == SYSTEM_EVENT_ETH_GOT_IP) {
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr);
uint8_t * mask = (uint8_t *)&(event->event_info.got_ip.ip_info.netmask.addr);
uint8_t * gw = (uint8_t *)&(event->event_info.got_ip.ip_info.gw.addr);
log_d("ETH IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u",
ip[0], ip[1], ip[2], ip[3],
mask[0], mask[1], mask[2], mask[3],
gw[0], gw[1], gw[2], gw[3]);
#endif
setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP_BIT);
} else if(event->event_id == SYSTEM_EVENT_GOT_IP6) {

View File

@ -399,6 +399,9 @@ uint8_t WiFiSTAClass::waitForConnectResult()
*/
IPAddress WiFiSTAClass::localIP()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
return IPAddress(ip.ip.addr);
@ -412,7 +415,9 @@ IPAddress WiFiSTAClass::localIP()
*/
uint8_t* WiFiSTAClass::macAddress(uint8_t* mac)
{
if(WiFiGenericClass::getMode() != WIFI_MODE_NULL){
esp_wifi_get_mac(WIFI_IF_STA, mac);
}
return mac;
}
@ -424,6 +429,9 @@ String WiFiSTAClass::macAddress(void)
{
uint8_t mac[6];
char macStr[18] = { 0 };
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return String();
}
esp_wifi_get_mac(WIFI_IF_STA, mac);
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@ -436,6 +444,9 @@ String WiFiSTAClass::macAddress(void)
*/
IPAddress WiFiSTAClass::subnetMask()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
return IPAddress(ip.netmask.addr);
@ -447,6 +458,9 @@ IPAddress WiFiSTAClass::subnetMask()
*/
IPAddress WiFiSTAClass::gatewayIP()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
tcpip_adapter_ip_info_t ip;
tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip);
return IPAddress(ip.gw.addr);
@ -459,6 +473,9 @@ IPAddress WiFiSTAClass::gatewayIP()
*/
IPAddress WiFiSTAClass::dnsIP(uint8_t dns_no)
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPAddress();
}
ip_addr_t dns_ip = dns_getserver(dns_no);
return IPAddress(dns_ip.u_addr.ip4.addr);
}
@ -469,6 +486,9 @@ IPAddress WiFiSTAClass::dnsIP(uint8_t dns_no)
*/
String WiFiSTAClass::SSID() const
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return String();
}
wifi_ap_record_t info;
if(!esp_wifi_sta_get_ap_info(&info)) {
return String(reinterpret_cast<char*>(info.ssid));
@ -482,6 +502,9 @@ String WiFiSTAClass::SSID() const
*/
String WiFiSTAClass::psk() const
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return String();
}
wifi_config_t conf;
esp_wifi_get_config(WIFI_IF_STA, &conf);
return String(reinterpret_cast<char*>(conf.sta.password));
@ -495,6 +518,9 @@ uint8_t* WiFiSTAClass::BSSID(void)
{
static uint8_t bssid[6];
wifi_ap_record_t info;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return NULL;
}
if(!esp_wifi_sta_get_ap_info(&info)) {
memcpy(bssid, info.bssid, 6);
return reinterpret_cast<uint8_t*>(bssid);
@ -523,6 +549,9 @@ String WiFiSTAClass::BSSIDstr(void)
*/
int8_t WiFiSTAClass::RSSI(void)
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return 0;
}
wifi_ap_record_t info;
if(!esp_wifi_sta_get_ap_info(&info)) {
return info.rssi;
@ -536,7 +565,10 @@ int8_t WiFiSTAClass::RSSI(void)
*/
const char * WiFiSTAClass::getHostname()
{
const char * hostname;
const char * hostname = NULL;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return hostname;
}
if(tcpip_adapter_get_hostname(TCPIP_ADAPTER_IF_STA, &hostname)){
return NULL;
}
@ -550,6 +582,9 @@ const char * WiFiSTAClass::getHostname()
*/
bool WiFiSTAClass::setHostname(const char * hostname)
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false;
}
return tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, hostname) == 0;
}
@ -559,6 +594,9 @@ bool WiFiSTAClass::setHostname(const char * hostname)
*/
bool WiFiSTAClass::enableIpV6()
{
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return false;
}
return tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA) == 0;
}
@ -569,6 +607,9 @@ bool WiFiSTAClass::enableIpV6()
IPv6Address WiFiSTAClass::localIPv6()
{
static ip6_addr_t addr;
if(WiFiGenericClass::getMode() == WIFI_MODE_NULL){
return IPv6Address();
}
if(tcpip_adapter_get_ip6_linklocal(TCPIP_ADAPTER_IF_STA, &addr)){
return IPv6Address();
}

View File

@ -221,8 +221,10 @@ int WiFiUDP::parsePacket(){
}
remote_ip = IPAddress(si_other.sin_addr.s_addr);
remote_port = ntohs(si_other.sin_port);
if (len > 0) {
rx_buffer = new cbuf(len);
rx_buffer->write(buf, len);
}
delete[] buf;
return len;
}
@ -264,6 +266,7 @@ int WiFiUDP::peek(){
}
void WiFiUDP::flush(){
if(!rx_buffer) return;
cbuf *b = rx_buffer;
rx_buffer = 0;
delete b;

View File

@ -364,3 +364,4 @@ void TwoWire::dumpI2C()
}
TwoWire Wire = TwoWire(0);
TwoWire Wire1 = TwoWire(1);

View File

@ -134,6 +134,7 @@ public:
};
extern TwoWire Wire;
extern TwoWire Wire1;
/*

View File

@ -49,7 +49,8 @@ build.flash_size=4MB
build.flash_mode=dio
build.boot=bootloader
build.code_debug=0
build.extra_flags=-DESP32 -DCORE_DEBUG_LEVEL={build.code_debug}
build.defines=
build.extra_flags=-DESP32 -DCORE_DEBUG_LEVEL={build.code_debug} {build.defines}
# These can be overridden in platform.local.txt
compiler.c.extra_flags=

View File

@ -36,6 +36,8 @@ function downloadAndMergePackageJSON()
#curl --verbose -sH "Authorization: token $curlAuthToken" -L -o "$old_json" "$jsonLink"
curl -L -o "$old_json" "$jsonLink?access_token=$curlAuthToken"
if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
#curl -L -o "$old_json" "$jsonLink"
@ -227,6 +229,7 @@ find $outdir -name '*.DS_Store' -exec rm -f {} \;
# handles tool paths differently when package is installed in hardware folder
echo " - updating platform.txt..."
cat $srcdir/platform.txt | \
sed "s/version=.*/version=$ver$extent/g" | \
sed 's/runtime.tools.xtensa-esp32-elf-gcc.path={runtime.platform.path}\/tools\/xtensa-esp32-elf//g' | \
sed 's/tools.esptool.path={runtime.platform.path}\/tools\/esptool/tools.esptool.path=\{runtime.tools.esptool.path\}/g' \
> $outdir/platform.txt
@ -255,10 +258,7 @@ echo " - creating package ZIP archive (${package_name_zip})..."
pushd $releaseDir >/dev/null
zip -qr $package_name_zip $package_name
if [ $? -ne 0 ]; then
echo " !error: failed to create ${package_name_zip} (ZIP errno: $?) => aborting"
exit 1
fi
if [ $? -ne 0 ]; then echo " !error: failed to create ${package_name_zip} (ZIP errno: $?) => aborting"; exit 1; fi
# Calculate SHA sum and size of ZIP archive
sha=`shasum -a 256 $package_name_zip | cut -f 1 -d ' '`
@ -296,6 +296,7 @@ set +e
releasesJson=$releaseDir/releases.json
curl -sH "Authorization: token $curlAuth" https://api.github.com/repos/$TRAVIS_REPO_SLUG/releases > $releasesJson
if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
prev_release=$(jq -e -r '. | map(select(.draft == false and .prerelease == false)) | sort_by(.created_at | - fromdateiso8601) | .[0].tag_name' ${releasesJson})
prev_any_release=$(jq -e -r '. | map(select(.draft == false)) | sort_by(.created_at | - fromdateiso8601) | .[0].tag_name' ${releasesJson})
@ -314,8 +315,8 @@ set -e
rm -f "$releasesJson"
echo " previous Release: $prev_release"
echo " previous (?Pre-)release: $prev_any_release"
echo " previous Pre-release: $prev_pre_release"
echo " previous (any)release: $prev_any_release"
# add generated items to JSON package-definition contents
jq_arg=".packages[0].platforms[0].version = \"$ver\" | \

View File

@ -1,5 +1,11 @@
#!/bin/bash
json_escape () {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
#printf '%s' "$1" | php -r 'echo json_encode(file_get_contents("php://stdin"));'
}
set -e
#Cmdline options
@ -77,6 +83,11 @@ shopt -u nocasematch
# other lines: converted to bullets
# empty lines ignored
# if '* ' found as a first char pair, it's converted to '- ' to keep bulleting unified
echo
echo Preparing release notes
echo -----------------------
echo "Tag's message:"
relNotesRaw=`git show -s --format=%b $varTagName`
readarray -t msgArray <<<"$relNotesRaw"
@ -85,58 +96,124 @@ if [ $arrLen > 3 ]; then
ind=3
while [ $ind -lt $arrLen ]; do
if [ $ind -eq 3 ]; then
releaseNotes="#### ${msgArray[ind]}\\n"
releaseNotes="#### ${msgArray[ind]}"
releaseNotes+=$'\r\n'
else
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
if [ ${#oneLine} -gt 0 ]; then
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
releaseNotes+="$oneLine\\n"
releaseNotes+="$oneLine"
releaseNotes+=$'\r\n'
#debug output
echo " ${oneLine}"
fi
fi
let ind=$ind+1
done
else
releaseNotes="#### Release of $varTagName\\n"
releaseNotes="#### Release of $varTagName"
releaseNotes+=$'\r\n'
#debug output
echo " Release of $varTagName"
fi
# - list of commits (commits.txt must exit in the output dir)
commitFile=$varAssetsDir/commits.txt
if [ -e "$commitFile" ]; then
if [ -s "$commitFile" ]; then
releaseNotes+="\\n##### Commits\\n"
releaseNotes+=$'\r\n##### Commits\r\n'
echo
echo "Commits:"
IFS=$'\n'
for next in `cat $commitFile`
do
IFS=' ' read -r commitId commitMsg <<< "$next"
releaseNotes+="- [$commitId](https://github.com/$varRepoSlug/commit/$commitId) $commitMsg\\n"
commitLine="- [$commitId](https://github.com/$varRepoSlug/commit/$commitId) $commitMsg"
echo " $commitLine"
releaseNotes+="$commitLine"
releaseNotes+=$'\r\n'
done
rm -f $commitFile
fi
releaseNotes=$(perl -pe 's/\r?\n/\\n/' <<< ${releaseNotes})
# Check possibly existing release for current tag
echo "Checking for possible releases of current tag $varTagName..."
# (eg build invoked by Create New Release GHUI button -> GH default release pack created immediatelly including default assests)
echo
echo "Processing GitHub release record for $varTagName:"
echo "-------------------------------------------------"
echo " - check $varTagName possible existence..."
# (eg build invoked by Create New Release GHUI button -> GH default release pack created immediately including default assests)
HTTP_RESPONSE=$(curl -L --silent --write-out "HTTPSTATUS:%{http_code}" https://api.github.com/repos/$varRepoSlug/releases/tags/$varTagName?access_token=$varAccessToken)
if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
HTTP_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')
HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
echo " HTTP server response code: $HTTP_STATUS"
echo " ---> GitHub server HTTP response: $HTTP_STATUS"
# if the release exists, append/update recent files to its assets vector
if [ $HTTP_STATUS -eq 200 ]; then
releaseId=$(echo $HTTP_BODY | jq -r '.id')
echo " - $varTagName release found (id $releaseId)"
#Merge release notes and overwrite pre-release flag. all other attributes remain unchanged:
# 1. take existing notes from server (added by release creator)
releaseNotesGH=$(echo $HTTP_BODY | jq -r '.body')
# - strip possibly trailing CR
if [ "${releaseNotesGH: -1}" == $'\r' ]; then
releaseNotesTemp="${releaseNotesGH:0:-1}"
else
releaseNotesTemp="$releaseNotesGH"
fi
# - add CRLF to make relnotes consistent for JSON encoding
releaseNotesTemp+=$'\r\n'
# 2. #append generated relnotes (usually commit oneliners)
releaseNotes="$releaseNotesTemp$releaseNotes"
# 3. JSON-encode whole string for GH API transfer
releaseNotes=$(json_escape "$releaseNotes")
# 4. remove extra quotes returned by python (dummy but whatever)
releaseNotes=${releaseNotes:1:-1}
#Update current GH release record
echo " - updating release notes and pre-release flag:"
curlData="{\"body\": \"$releaseNotes\",\"prerelease\": $varPrerelease}"
echo " <data.begin>$curlData<data.end>"
echo
#echo "DEBUG: curl --data \"$curlData\" https://api.github.com/repos/$varRepoSlug/releases/$releaseId?access_token=$varAccessToken"
curl --data "$curlData" https://api.github.com/repos/$varRepoSlug/releases/$releaseId?access_token=$varAccessToken
if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
echo " - $varTagName release record successfully updated"
#... or create a new release record
else
releaseNotes=$(json_escape "$releaseNotes")
releaseNotes=${releaseNotes:1:-1}
echo " - release $varTagName not found, creating a new record:"
curlData="{\"tag_name\": \"$varTagName\",\"target_commitish\": \"master\",\"name\": \"v$varTagName\",\"body\": \"$releaseNotes\",\"draft\": false,\"prerelease\": $varPrerelease}"
echo " <data.begin>$curlData<data.end>"
#echo "DEBUG: curl --data \"${curlData}\" https://api.github.com/repos/${varRepoSlug}/releases?access_token=$varAccessToken | jq -r '.id'"
releaseId=$(curl --data "$curlData" https://api.github.com/repos/$varRepoSlug/releases?access_token=$varAccessToken | jq -r '.id')
echo " - new release created for $varTagName (id $releaseId)"
if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
echo " - $varTagName release record successfully created (id $releaseId)"
fi
# Assets defined by dir contents
@ -149,22 +226,26 @@ if [ ! -z $varAssetsDir ]; then
done
fi
echo
echo varAssets: $varAssets
#Upload additional assets
if [ ! -z $varAssets ]; then
echo
echo "Uploading assets:"
echo "-----------------"
echo " Files to upload:"
echo " $varAssets"
echo
curlAuth="Authorization: token $varAccessToken"
for filename in $(echo $varAssets | tr ";" "\n")
do
echo
echo Uploading $filename...
echo " - ${filename}:"
curl -X POST -sH "$curlAuth" -H "Content-Type: application/octet-stream" --data-binary @"$filename" https://uploads.github.com/repos/$varRepoSlug/releases/$releaseId/assets?name=$(basename $filename)
if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
echo
echo "OK"
echo
done
fi
echo
echo

View File

@ -0,0 +1,82 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
#define ALKSESP32 // tell library to not map pins again
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t D0 = 40;
static const uint8_t D1 = 41;
static const uint8_t D2 = 15;
static const uint8_t D3 = 2;
static const uint8_t D4 = 0;
static const uint8_t D5 = 4;
static const uint8_t D6 = 16;
static const uint8_t D7 = 17;
static const uint8_t D8 = 5;
static const uint8_t D9 = 18;
static const uint8_t D10 = 19;
static const uint8_t D11 = 21;
static const uint8_t D12 = 22;
static const uint8_t D13 = 23;
static const uint8_t A0 = 32;
static const uint8_t A1 = 33;
static const uint8_t A2 = 25;
static const uint8_t A3 = 26;
static const uint8_t A4 = 27;
static const uint8_t A5 = 14;
static const uint8_t A6 = 12;
static const uint8_t A7 = 15;
static const uint8_t L_R = 22;
static const uint8_t L_G = 17;
static const uint8_t L_Y = 23;
static const uint8_t L_B = 5;
static const uint8_t L_RGB_R = 4;
static const uint8_t L_RGB_G = 21;
static const uint8_t L_RGB_B = 16;
static const uint8_t SW1 = 15;
static const uint8_t SW2 = 2;
static const uint8_t SW3 = 0;
static const uint8_t POT1 = 32;
static const uint8_t POT2 = 33;
static const uint8_t PIEZO1 = 19;
static const uint8_t PIEZO2 = 18;
static const uint8_t PHOTO = 25;
static const uint8_t DHT_PIN = 26;
static const uint8_t S1 = 4;
static const uint8_t S2 = 16;
static const uint8_t S3 = 18;
static const uint8_t S4 = 19;
static const uint8_t S5 = 21;
static const uint8_t SDA = 27;
static const uint8_t SCL = 14;
static const uint8_t SS = 19;
static const uint8_t MOSI = 21;
static const uint8_t MISO = 22;
static const uint8_t SCK = 23;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
#endif /* Pins_Arduino_h */

View File

@ -0,0 +1,52 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 20
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t SDA = 21;
static const uint8_t SCL = 22;
static const uint8_t SS = 5;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 19;
static const uint8_t SCK = 18;
static const uint8_t G23 = 23;
static const uint8_t G19 = 19;
static const uint8_t G18 = 18;
static const uint8_t G3 = 3;
static const uint8_t G16 = 16;
static const uint8_t G21 = 21;
static const uint8_t G2 = 2;
static const uint8_t G12 = 12;
static const uint8_t G15 = 15;
static const uint8_t G35 = 35;
static const uint8_t G36 = 36;
static const uint8_t G25 = 25;
static const uint8_t G26 = 26;
static const uint8_t G1 = 1;
static const uint8_t G17 = 17;
static const uint8_t G22 = 22;
static const uint8_t G5 = 5;
static const uint8_t G13 = 13;
static const uint8_t G0 = 0;
static const uint8_t G34 = 34;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
static const uint8_t ADC1 = 35;
static const uint8_t ADC2 = 36;
#endif /* Pins_Arduino_h */

View File

@ -0,0 +1,77 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
// I2C OLED Display works with SSD1306 driver
#define OLED_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
// SPI LoRa Radio
#define LORA_SCK 5 // GPIO5 - SX1276 SCK
#define LORA_MISO 19 // GPIO19 - SX1276 MISO
#define LORA_MOSI 27 // GPIO27 - SX1276 MOSI
#define LORA_CS 18 // GPIO18 - SX1276 CS
#define LORA_RST 14 // GPIO14 - SX1276 RST
#define LORA_IRQ 26 // GPIO26 - SX1276 IRQ (interrupt request)
static const uint8_t LED_BUILTIN = 2;
#define BUILTIN_LED LED_BUILTIN // backward compatibility
static const uint8_t KEY_BUILTIN = 0;
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t SDA = 21;
static const uint8_t SCL = 22;
static const uint8_t SS = 18;
static const uint8_t MOSI = 27;
static const uint8_t MISO = 19;
static const uint8_t SCK = 5;
static const uint8_t A0 = 36;
static const uint8_t A1 = 37;
static const uint8_t A2 = 38;
static const uint8_t A3 = 39;
static const uint8_t A4 = 32;
static const uint8_t A5 = 33;
static const uint8_t A6 = 34;
static const uint8_t A7 = 35;
static const uint8_t A10 = 4;
static const uint8_t A11 = 0;
static const uint8_t A12 = 2;
static const uint8_t A13 = 15;
static const uint8_t A14 = 13;
static const uint8_t A15 = 12;
static const uint8_t A16 = 14;
static const uint8_t A17 = 27;
static const uint8_t A18 = 25;
static const uint8_t A19 = 26;
static const uint8_t T0 = 4;
static const uint8_t T1 = 0;
static const uint8_t T2 = 2;
static const uint8_t T3 = 15;
static const uint8_t T4 = 13;
static const uint8_t T5 = 12;
static const uint8_t T6 = 14;
static const uint8_t T7 = 27;
static const uint8_t T8 = 32;
static const uint8_t T9 = 33;
static const uint8_t DAC1 = 26;
static const uint8_t DAC2 = 25;
#endif /* Pins_Arduino_h */

View File

@ -0,0 +1,28 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define EXTERNAL_NUM_INTERRUPTS 16
#define NUM_DIGITAL_PINS 40
#define NUM_ANALOG_INPUTS 16
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<40)?(p):-1)
#define digitalPinHasPWM(p) (p < 34)
static const uint8_t LED_BUILTIN = 27;
#define BUILTIN_LED LED_BUILTIN // backward compatibility
static const uint8_t TX = 1;
static const uint8_t RX = 3;
static const uint8_t SDA = 21;
static const uint8_t SCL = 22;
static const uint8_t SS = 5;
static const uint8_t MOSI = 23;
static const uint8_t MISO = 19;
static const uint8_t SCK = 18;
#endif /* Pins_Arduino_h */