Compare commits

...

25 Commits

Author SHA1 Message Date
30b3eebabc * merge only annotated tag messages into release notes (#1683) 2018-07-28 10:28:04 +03:00
3222e6490a add LOLIN D32 & D32 PRO Board support (#1688) 2018-07-28 10:27:26 +03:00
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
28 changed files with 1306 additions and 278 deletions

View File

@ -106,8 +106,147 @@ config AUTOCONNECT_WIFI
bool "Autoconnect WiFi on boot" bool "Autoconnect WiFi on boot"
default "n" default "n"
depends on AUTOSTART_ARDUINO depends on AUTOSTART_ARDUINO
select ARDUINO_SELECTIVE_WiFi
help help
If enabled, WiFi will connect to the last used SSID (if station was enabled), 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) 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 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) 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) 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: boot-app0:
@echo "Rebooting to 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 ## 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 Windows](docs/arduino-ide/windows.md)
+ [Instructions for Mac](docs/arduino-ide/mac.md) + [Instructions for Mac](docs/arduino-ide/mac.md)
+ [Instructions for Debian/Ubuntu Linux](docs/arduino-ide/debian_ubuntu.md) + [Instructions for Debian/Ubuntu Linux](docs/arduino-ide/debian_ubuntu.md)

View File

@ -8,6 +8,62 @@ 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
##############################################################
esp32.name=ESP32 Dev Module esp32.name=ESP32 Dev Module
esp32.upload.tool=esptool esp32.upload.tool=esptool
@ -527,6 +583,157 @@ nano32.menu.UploadSpeed.512000.upload.speed=512000
############################################################## ##############################################################
d32.name=LOLIN D32
d32.upload.tool=esptool
d32.upload.maximum_size=1310720
d32.upload.maximum_data_size=327680
d32.upload.wait_for_upload_port=true
d32.serial.disableDTR=true
d32.serial.disableRTS=true
d32.build.mcu=esp32
d32.build.core=esp32
d32.build.variant=d32
d32.build.board=LOLIN_D32
d32.build.f_cpu=240000000L
d32.build.flash_size=4MB
d32.build.flash_freq=40m
d32.build.flash_mode=dio
d32.build.boot=dio
d32.build.partitions=default
d32.build.defines=
d32.menu.PartitionScheme.default=Default
d32.menu.PartitionScheme.default.build.partitions=default
d32.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
d32.menu.PartitionScheme.minimal.build.partitions=minimal
d32.menu.PartitionScheme.no_ota=No OTA (Large APP)
d32.menu.PartitionScheme.no_ota.build.partitions=no_ota
d32.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
d32.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
d32.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
d32.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
d32.menu.FlashFreq.80=80MHz
d32.menu.FlashFreq.80.build.flash_freq=80m
d32.menu.FlashFreq.40=40MHz
d32.menu.FlashFreq.40.build.flash_freq=40m
d32.menu.UploadSpeed.921600=921600
d32.menu.UploadSpeed.921600.upload.speed=921600
d32.menu.UploadSpeed.115200=115200
d32.menu.UploadSpeed.115200.upload.speed=115200
d32.menu.UploadSpeed.256000.windows=256000
d32.menu.UploadSpeed.256000.upload.speed=256000
d32.menu.UploadSpeed.230400.windows.upload.speed=256000
d32.menu.UploadSpeed.230400=230400
d32.menu.UploadSpeed.230400.upload.speed=230400
d32.menu.UploadSpeed.460800.linux=460800
d32.menu.UploadSpeed.460800.macosx=460800
d32.menu.UploadSpeed.460800.upload.speed=460800
d32.menu.UploadSpeed.512000.windows=512000
d32.menu.UploadSpeed.512000.upload.speed=512000
d32.menu.DebugLevel.none=None
d32.menu.DebugLevel.none.build.code_debug=0
d32.menu.DebugLevel.error=Error
d32.menu.DebugLevel.error.build.code_debug=1
d32.menu.DebugLevel.warn=Warn
d32.menu.DebugLevel.warn.build.code_debug=2
d32.menu.DebugLevel.info=Info
d32.menu.DebugLevel.info.build.code_debug=3
d32.menu.DebugLevel.debug=Debug
d32.menu.DebugLevel.debug.build.code_debug=4
d32.menu.DebugLevel.verbose=Verbose
d32.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
d32_pro.name=LOLIN D32 PRO
d32_pro.upload.tool=esptool
d32_pro.upload.maximum_size=1310720
d32_pro.upload.maximum_data_size=327680
d32_pro.upload.wait_for_upload_port=true
d32_pro.serial.disableDTR=true
d32_pro.serial.disableRTS=true
d32_pro.build.mcu=esp32
d32_pro.build.core=esp32
d32_pro.build.variant=d32_pro
d32_pro.build.board=LOLIN_D32_PRO
d32_pro.build.f_cpu=240000000L
d32_pro.build.flash_size=4MB
d32_pro.build.flash_freq=40m
d32_pro.build.flash_mode=dio
d32_pro.build.boot=dio
d32_pro.build.partitions=default
d32_pro.build.defines=
d32_pro.menu.PSRAM.disabled=Disabled
d32_pro.menu.PSRAM.disabled.build.defines=
d32_pro.menu.PSRAM.enabled=Enabled
d32_pro.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
d32_pro.menu.PartitionScheme.default=Default
d32_pro.menu.PartitionScheme.default.build.partitions=default
d32_pro.menu.PartitionScheme.minimal=Minimal (2MB FLASH)
d32_pro.menu.PartitionScheme.minimal.build.partitions=minimal
d32_pro.menu.PartitionScheme.no_ota=No OTA (Large APP)
d32_pro.menu.PartitionScheme.no_ota.build.partitions=no_ota
d32_pro.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
d32_pro.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA)
d32_pro.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
d32_pro.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
d32_pro.menu.FlashFreq.80=80MHz
d32_pro.menu.FlashFreq.80.build.flash_freq=80m
d32_pro.menu.FlashFreq.40=40MHz
d32_pro.menu.FlashFreq.40.build.flash_freq=40m
d32_pro.menu.UploadSpeed.921600=921600
d32_pro.menu.UploadSpeed.921600.upload.speed=921600
d32_pro.menu.UploadSpeed.115200=115200
d32_pro.menu.UploadSpeed.115200.upload.speed=115200
d32_pro.menu.UploadSpeed.256000.windows=256000
d32_pro.menu.UploadSpeed.256000.upload.speed=256000
d32_pro.menu.UploadSpeed.230400.windows.upload.speed=256000
d32_pro.menu.UploadSpeed.230400=230400
d32_pro.menu.UploadSpeed.230400.upload.speed=230400
d32_pro.menu.UploadSpeed.460800.linux=460800
d32_pro.menu.UploadSpeed.460800.macosx=460800
d32_pro.menu.UploadSpeed.460800.upload.speed=460800
d32_pro.menu.UploadSpeed.512000.windows=512000
d32_pro.menu.UploadSpeed.512000.upload.speed=512000
d32_pro.menu.DebugLevel.none=None
d32_pro.menu.DebugLevel.none.build.code_debug=0
d32_pro.menu.DebugLevel.error=Error
d32_pro.menu.DebugLevel.error.build.code_debug=1
d32_pro.menu.DebugLevel.warn=Warn
d32_pro.menu.DebugLevel.warn.build.code_debug=2
d32_pro.menu.DebugLevel.info=Info
d32_pro.menu.DebugLevel.info.build.code_debug=3
d32_pro.menu.DebugLevel.debug=Debug
d32_pro.menu.DebugLevel.debug.build.code_debug=4
d32_pro.menu.DebugLevel.verbose=Verbose
d32_pro.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
lolin32.name=WEMOS LOLIN32 lolin32.name=WEMOS LOLIN32
lolin32.upload.tool=esptool lolin32.upload.tool=esptool
@ -1553,6 +1760,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.name=ODROID ESP32
odroid_esp32.upload.tool=esptool odroid_esp32.upload.tool=esptool
@ -1840,6 +2105,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.name=WiPy 3.0
wipy3.upload.tool=esptool wipy3.upload.tool=esptool
@ -1894,4 +2249,3 @@ wipy3.menu.DebugLevel.debug=Debug
wipy3.menu.DebugLevel.debug.build.code_debug=4 wipy3.menu.DebugLevel.debug.build.code_debug=4
wipy3.menu.DebugLevel.verbose=Verbose wipy3.menu.DebugLevel.verbose=Verbose
wipy3.menu.DebugLevel.verbose.build.code_debug=5 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/*/*/)) $(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_ADD_INCLUDEDIRS := cores/esp32 variants/esp32 $(ARDUINO_CORE_LIBS)
COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64 COMPONENT_PRIV_INCLUDEDIRS := cores/esp32/libb64

View File

@ -33,6 +33,22 @@
#define DR_REG_I2C_EXT_BASE_FIXED 0x60013000 #define DR_REG_I2C_EXT_BASE_FIXED 0x60013000
#define DR_REG_I2C1_EXT_BASE_FIXED 0x60027000 #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 // start from tools/sdk/include/soc/soc/i2c_struct.h
typedef union { typedef union {
@ -65,6 +81,17 @@ typedef union {
uint32_t val; uint32_t val;
} I2C_FIFO_CONF_t; } 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 // end from tools/sdk/include/soc/soc/i2c_struct.h
// sync between dispatch(i2cProcQueue) and worker(i2c_isr_handler_default) // sync between dispatch(i2cProcQueue) and worker(i2c_isr_handler_default)
@ -130,9 +157,7 @@ typedef struct {
uint8_t *data; // datapointer for read/write buffer uint8_t *data; // datapointer for read/write buffer
uint16_t length; // size of data buffer uint16_t length; // size of data buffer
uint16_t position; // current position for next char in buffer (<length) 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 cmdBytesNeeded; // used to control number of I2C_COMMAND_t blocks added to queue
uint16_t queueLength; // number of data bytes needing moved, used to control
// current queuePos for fifo fills
I2C_DATA_CTRL_t ctrl; I2C_DATA_CTRL_t ctrl;
EventGroupHandle_t queueEvent; // optional user supplied for Async feedback EventBits EventGroupHandle_t queueEvent; // optional user supplied for Async feedback EventBits
} I2C_DATA_QUEUE_t; } I2C_DATA_QUEUE_t;
@ -152,9 +177,10 @@ struct i2c_struct_t {
// maybe use it to trigger callback for OnRequest() // maybe use it to trigger callback for OnRequest()
intr_handle_t intr_handle; /*!< I2C interrupt handle*/ intr_handle_t intr_handle; /*!< I2C interrupt handle*/
I2C_DATA_QUEUE_t * dq; I2C_DATA_QUEUE_t * dq;
uint16_t queueCount; uint16_t queueCount; // number of dq entries in queue.
uint16_t queuePos; uint16_t queuePos; // current queue that still has or needs data (out/in)
uint16_t byteCnt; 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; uint32_t exitCode;
}; };
@ -179,8 +205,8 @@ static i2c_t _i2c_bus_array[2] = {
#define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock) #define I2C_MUTEX_UNLOCK() xSemaphoreGive(i2c->lock)
static i2c_t _i2c_bus_array[2] = { 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_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} {(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 #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; 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 /* 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) static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
{ {
/* this function is call on initial i2cProcQueue() /* this function is called on initial i2cProcQueue() or when a I2C_END_DETECT_INT occurs
or when a I2C_END_DETECT_INT occures
*/ */
uint16_t cmdIdx = 0; uint16_t cmdIdx = 0;
uint16_t qp = i2c->queuePos; 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 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? 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); i2cSetCmd(i2c, cmdIdx++, I2C_CMD_RSTART, 0, false, false, false);
tdq->ctrl.startCmdSent=1; tdq->ctrl.startCmdSent=1;
done = (cmdIdx>14); done = (cmdIdx>14);
} }
//CMD WRITE ADDRESS //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) { if(!tdq->ctrl.addrCmdSent) {
i2cSetCmd(i2c, cmdIdx++, I2C_CMD_WRITE, tdq->ctrl.addrReq, false, false, true); //load address in cmdlist, validate (low) ack i2cSetCmd(i2c, cmdIdx++, I2C_CMD_WRITE, tdq->ctrl.addrReq, false, false, true); //load address in cmdlist, validate (low) ack
tdq->ctrl.addrCmdSent=1; 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. 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 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. 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. So, only refill from [0]..[14], leave [15] for a continuation(END) if necessary.
As a corrilary, once END exists in [15], you do not need to overwrite it for the 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 next continuation. It is never modified. But, I update it every time because it might
actually be the first time! actually be the first time!
23NOV17 START cannot proceed END. if START is in[14], END cannot be in [15]. 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 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. if((!done)&&(tdq->ctrl.addrCmdSent)) { //room in command[] for at least One data (read/Write) cmd
//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 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 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; // tdq->cmdBytesNeeded -= blkSize;
if(tdq->ctrl.mode==1) { //read mode 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. 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 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 done = false; // reuse it
uint16_t i = 13; // start working back until a READ/WRITE has >1 numBytes uint16_t i = 13; // start working back until a READ/WRITE has >1 numBytes
cmdIdx =15; cmdIdx =15;
// log_e("before Stretch");
// dumpCmdQueue(i2c);
while(!done) { while(!done) {
i2c->dev->command[i+1].val = i2c->dev->command[i].val; // push it down 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))) { if (((i2c->dev->command[i].op_code == 1)||(i2c->dev->command[i].op_code==2))) {
/* just try a num_bytes =0; /* 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>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;
*/ */
i2c->dev->command[i].byte_num = 0; i2c->dev->command[i].byte_num = 0;
done = true; 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 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 // 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); i2cSetCmd(i2c, (cmdIdx)++,I2C_CMD_END, 0,false,false,false);
i2c->dev->int_ena.end_detect=1; //maybe? i2c->dev->int_ena.end_detect=1;
i2c->dev->int_clr.end_detect=1; //maybe? i2c->dev->int_clr.end_detect=1;
done = true; done = true;
} }
@ -389,7 +392,6 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
qp++; qp++;
if(qp < i2c->queueCount) { if(qp < i2c->queueCount) {
tdq = &i2c->dq[qp]; tdq = &i2c->dq[qp];
// log_e("inc to next queue=%d",qp);
} else { } else {
done = true; done = true;
} }
@ -397,7 +399,7 @@ static void IRAM_ATTR fillCmdQueue(i2c_t * i2c, bool INTS)
} }
}// while(!done) }// 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) { if(ena_rx) {
i2c->dev->int_ena.rx_fifo_full = 1; 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) 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. 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 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 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 // update debug buffer tx counts
cnt += intBuff[intPos[i2c->num]][1][i2c->num]>>16; cnt += intBuff[intPos[i2c->num]][1][i2c->num]>>16;
@ -489,8 +480,9 @@ 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
i2c->dev->int_ena.tx_fifo_empty=0; // (a >= i2c->queueCount) means no more data is available
i2c->dev->int_ena.tx_fifo_empty= 0;
} }
i2c->dev->int_clr.tx_fifo_empty=1; i2c->dev->int_clr.tx_fifo_empty=1;
@ -501,40 +493,46 @@ static void IRAM_ATTR fillTxFifo(i2c_t * i2c)
static void IRAM_ATTR emptyRxFifo(i2c_t * i2c) static void IRAM_ATTR emptyRxFifo(i2c_t * i2c)
{ {
uint32_t d, cnt=0, moveCnt; 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 moveCnt = i2c->dev->status_reg.rx_fifo_cnt;//no need to check the reg until this many are read
if(moveCnt > (tdq->length - tdq->position)) { //makesure they go in this dq 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 // part of these reads go into the next dq
moveCnt = (tdq->length - tdq->position); moveCnt = (tdq->length - tdq->position);
} }
} else {// error
if(tdq->ctrl.mode==1) { // read log_e("RxEmpty(%d) call on TxBuffer? dq=%d",moveCnt,i2c->queuePos);
while(moveCnt > 0) { return;
while(moveCnt > 0) { }
d = i2c->dev->fifo_data.val; while(moveCnt > 0) {
moveCnt--; d = i2c->dev->fifo_data.val;
cnt++; moveCnt--;
tdq->data[tdq->position++] = (d&0xFF); 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. // see if any more chars showed up while empting Fifo.
moveCnt = i2c->dev->status_reg.rx_fifo_cnt; moveCnt = i2c->dev->status_reg.rx_fifo_cnt;
if(moveCnt > (tdq->length - tdq->position)) { //makesure they go in this dq if(moveCnt > (tdq->length - tdq->position)) { //make sure they go in this dq
// part of these reads go into the next dq // part of these reads go into the next dq
moveCnt = (tdq->length - tdq->position); 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 // update Debug rxCount
cnt += (intBuff[intPos[i2c->num]][1][i2c->num])&&0xffFF; 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; intBuff[intPos[i2c->num]][1][i2c->num] = (intBuff[intPos[i2c->num]][1][i2c->num]&0xFFFF0000)|cnt;
#endif #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) static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal)
{ {
@ -559,19 +557,17 @@ static void IRAM_ATTR i2cIsrExit(i2c_t * i2c,const uint32_t eventCode,bool Fatal
i2c->error = I2C_ERROR; i2c->error = I2C_ERROR;
} }
uint32_t exitCode = EVENT_DONE | eventCode |(Fatal?EVENT_ERROR:0); uint32_t exitCode = EVENT_DONE | eventCode |(Fatal?EVENT_ERROR:0);
if((i2c->queuePos < i2c->queueCount) && (i2c->dq[i2c->queuePos].ctrl.mode == 1)) {
if(i2c->dq[i2c->queuePos].ctrl.mode == 1) {
emptyRxFifo(i2c); // grab last few characters emptyRxFifo(i2c); // grab last few characters
} }
i2c->dev->int_ena.val = 0; // shut down interrupts
i2c->dev->int_ena.val = 0; // shutdown interrupts i2c->dev->int_clr.val = 0x1FFF;
i2c->dev->int_clr.val = 0x1FFFF;
i2c->stage = I2C_DONE; i2c->stage = I2C_DONE;
i2c->exitCode = exitCode; //true eventcode i2c->exitCode = exitCode; //true eventcode
portBASE_TYPE HPTaskAwoken = pdFALSE,xResult; portBASE_TYPE HPTaskAwoken = pdFALSE,xResult;
// try to notify Dispatch we are done, // try to notify Dispatch we are done,
// else the 50ms timeout will recover the APP, just alittle slower // else the 50ms time out will recover the APP, just a little slower
HPTaskAwoken = pdFALSE; HPTaskAwoken = pdFALSE;
xResult = xEventGroupSetBitsFromISR(i2c->i2c_event, exitCode, &HPTaskAwoken); xResult = xEventGroupSetBitsFromISR(i2c->i2c_event, exitCode, &HPTaskAwoken);
if(xResult == pdPASS) { if(xResult == pdPASS) {
@ -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) static void IRAM_ATTR i2c_isr_handler_default(void* arg)
{ {
i2c_t* p_i2c = (i2c_t*) arg; // recover data 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, can't service, not configured
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
if(p_i2c->stage==I2C_DONE) { //get Out uint32_t raw = p_i2c->dev->int_raw.val;
log_e("eject int=%p, ena=%p",activeInt,p_i2c->dev->int_ena.val); #endif
p_i2c->dev->int_ena.val = 0; 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; 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 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)) { 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; intBuff[intPos[p_i2c->num]][0][p_i2c->num] = (((intBuff[intPos[p_i2c->num]][0][p_i2c->num]>>16)+1)<<16)|activeInt;
} else { } 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 intBuff[intPos[p_i2c->num]][2][p_i2c->num] = xTaskGetTickCountFromISR(); // when IRQ fired
#endif #endif
//uint32_t oldInt =activeInt;
if (activeInt & I2C_TRANS_START_INT_ST_M) { if (activeInt & I2C_TRANS_START_INT_ST_M) {
// p_i2c->byteCnt=0;
if(p_i2c->stage==I2C_STARTUP) { if(p_i2c->stage==I2C_STARTUP) {
p_i2c->stage=I2C_RUNNING; 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; 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 (activeInt & I2C_ACK_ERR_INT_ST_M) {//fatal error, abort i2c service
if (p_i2c->mode == I2C_MASTER) { if (p_i2c->mode == I2C_MASTER) {
// log_e("AcK Err byteCnt=%d, queuepos=%d",p_i2c->byteCnt,p_i2c->queuePos); i2c_update_error_byte_cnt(p_i2c); // calc which byte caused ack Error, check if address or data
if(p_i2c->byteCnt==1) { log_v("AcK Err errorByteCnt=%d, errorQueue=%d queuepos=%d",p_i2c->errorByteCnt,p_i2c->errorQueue, p_i2c->queuePos);
i2cIsrExit(p_i2c,EVENT_ERROR_NAK,true); if(p_i2c->errorByteCnt <= p_i2c->dq[p_i2c->errorQueue].ctrl.addrReq) { // address
} else if((p_i2c->byteCnt == 2) && (p_i2c->dq[p_i2c->queuePos].ctrl.addrReq == 2)) {
i2cIsrExit(p_i2c,EVENT_ERROR_NAK,true); i2cIsrExit(p_i2c,EVENT_ERROR_NAK,true);
} else { } else {
i2cIsrExit(p_i2c,EVENT_ERROR_DATA_NAK,true); i2cIsrExit(p_i2c,EVENT_ERROR_DATA_NAK,true); //data
} }
} }
return; 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 // the Statemachine only has a 13.1ms max timout, some Devices >500ms
p_i2c->dev->int_clr.time_out =1; p_i2c->dev->int_clr.time_out =1;
activeInt &=~I2C_TIME_OUT_INT_ST; 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) { if (activeInt & I2C_TRANS_COMPLETE_INT_ST_M) {
p_i2c->dev->int_clr.trans_complete = 1;
i2cIsrExit(p_i2c,EVENT_DONE,false); i2cIsrExit(p_i2c,EVENT_DONE,false);
return; // no more work to do 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) 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, // need to grab a MUTEX for exclusive Queue,
// what out if ISR is running? // what about if ISR is running?
if(i2c==NULL) { if(i2c==NULL) {
return I2C_ERROR_DEV; 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.mode = mode;
dqx.ctrl.stop= sendStop; dqx.ctrl.stop= sendStop;
dqx.ctrl.addrReq = ((i2cDeviceAddr&0xFC00)==0x7800)?2:1; // 10bit or 7bit address dqx.ctrl.addrReq = ((i2cDeviceAddr&0xFC00)==0x7800)?2:1; // 10bit or 7bit address
dqx.queueLength = dataLen + dqx.ctrl.addrReq;
dqx.queueEvent = event; dqx.queueEvent = event;
if(event) { // an eventGroup exist, so, initialize it 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. // readBit.
// this might cause an internal register pointer problem with 10bit // 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. // this is the Industry Standard specification.
if((i2cDeviceAddr &0xFC00)==0x7800) { // ten bit read 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 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++) { for(uint16_t i=0; i<INTBUFFMAX; i++) {
intBuff[i][0][i2c->num] = 0; intBuff[i][0][i2c->num] = 0;
intBuff[i][1][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_err_t reason = I2C_ERROR_OK;
i2c->mode = I2C_MASTER; i2c->mode = I2C_MASTER;
i2c->dev->ctr.trans_start=0; // Pause Machine i2c->dev->ctr.trans_start=0; // Pause Machine
i2c->dev->timeout.tout = 0xFFFFF; // max 13ms i2c->dev->timeout.tout = 0xFFFFF; // max 13ms
I2C_FIFO_CONF_t f; i2c->dev->int_clr.val = 0x1FFF; // kill them All!
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
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->dev->ctr.ms_mode = 1; // master!
i2c->queuePos=0; i2c->queuePos=0;
i2c->byteCnt=0; i2c->errorByteCnt=0;
i2c->errorQueue = 0;
uint32_t totalBytes=0; // total number of bytes to be Moved! uint32_t totalBytes=0; // total number of bytes to be Moved!
// convert address field to required I2C format // convert address field to required I2C format
while(i2c->queuePos < i2c->queueCount) { // need to push these address modes upstream, to AddQueue 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.mode;
} }
tdq->ctrl.addr = taddr; // all fixed with R/W bit 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; i2c->queuePos=0;
fillCmdQueue(i2c,false); // don't enable Tx/RX irq's fillCmdQueue(i2c,false); // don't enable Tx/RX irq's
// start adding command[], END irq will keep it full // start adding command[], END irq will keep it full
//Data Fifo will be filled after trans_start is issued //Data Fifo will be filled after trans_start is issued
i2c->exitCode=0; 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 i2c->stage = I2C_STARTUP; // everything configured, now start the I2C StateMachine, and
// As soon as interrupts are enabled, the ISR will start handling them. // As soon as interrupts are enabled, the ISR will start handling them.
// it should receive a TXFIFO_EMPTY immediately, even before it // it should receive a TXFIFO_EMPTY immediately, even before it
// receives the TRANS_START // receives the TRANS_START
i2c->dev->int_ena.val = i2c->dev->int_ena.val =
I2C_ACK_ERR_INT_ENA | // (BIT(10)) Causes Fatal Error Exit 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_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_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_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_ARBITRATION_LOST_INT_ENA | // (BIT(5)) cause fatal error exit
I2C_SLAVE_TRAN_COMP_INT_ENA | // (BIT(4)) unhandled I2C_SLAVE_TRAN_COMP_INT_ENA | // (BIT(4)) unhandled
I2C_END_DETECT_INT_ENA | // (BIT(3)) refills cmd[] list 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. ESP_INTR_FLAG_LOWMED; //< Low and medium prio interrupts. These can be handled in C.
if(i2c->num) { 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 { } 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) { 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. //hang until it completes.
// how many ticks should it take to transfer totalBytes thru the I2C hardware, // how many ticks should it take to transfer totalBytes through the I2C hardware,
// add user supplied timeOutMillis to Calc Value // add user supplied timeOutMillis to Calculated Value
portTickType ticksTimeOut = ((totalBytes*10*1000)/(i2cGetFrequency(i2c))+timeOutMillis)/portTICK_PERIOD_MS; 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 i2c->dev->ctr.trans_start=1; // go for it
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
portTickType tBefore=xTaskGetTickCount(); portTickType tBefore=xTaskGetTickCount();
#endif #endif
// wait for ISR to complete the transfer, or until timeOut in case of bus fault, hardware problem
uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut); uint32_t eBits = xEventGroupWaitBits(i2c->i2c_event,EVENT_DONE,pdFALSE,pdTRUE,ticksTimeOut);
//log_e("after WaitBits=%x @tick=%d",eBits,xTaskGetTickCount());
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR
portTickType tAfter=xTaskGetTickCount(); portTickType tAfter=xTaskGetTickCount();
#endif #endif
uint32_t b;
// if xEventGroupSetBitsFromISR() failed, the ISR could have succeeded but never been // if xEventGroupSetBitsFromISR() failed, the ISR could have succeeded but never been
// able to mark the success // 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); // log_e("EventGroup Failed:%p!=%p",eBits,i2c->exitCode);
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(!(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 #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO
i2cDumpI2c(i2c); i2cDumpI2c(i2c);
i2cDumpInts(i2c->num); i2cDumpInts(i2c->num);
#else
log_n("I2C exitCode=0x%x",eBits);
#endif #endif
} }
@ -1016,11 +1051,12 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
i2c->stage = I2C_DONE; i2c->stage = I2C_DONE;
i2c->dev->int_ena.val =0; i2c->dev->int_ena.val =0;
i2c->dev->int_clr.val = 0x1FFF; 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; reason = I2C_ERROR_BUSY;
eBits = eBits | EVENT_ERROR_BUS_BUSY|EVENT_ERROR|EVENT_DONE; eBits = eBits | EVENT_ERROR_BUS_BUSY|EVENT_ERROR|EVENT_DONE;
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
log_e(" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error); log_d(" Busy Timeout start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error);
i2cDumpI2c(i2c); i2cDumpI2c(i2c);
i2cDumpInts(i2c->num); i2cDumpInts(i2c->num);
#endif #endif
@ -1028,19 +1064,25 @@ i2c_err_t i2cProcQueue(i2c_t * i2c, uint32_t *readCount, uint16_t timeOutMillis)
reason = I2C_ERROR_TIMEOUT; reason = I2C_ERROR_TIMEOUT;
eBits = eBits | EVENT_ERROR_TIMEOUT|EVENT_ERROR|EVENT_DONE; eBits = eBits | EVENT_ERROR_TIMEOUT|EVENT_ERROR|EVENT_DONE;
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG
log_e(" Gross Timeout Dead start=0x%x, end=0x%x, =%d, max=%d error=%d",tBefore,tAfter,(tAfter-tBefore),ticksTimeOut,i2c->error); 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); i2cDumpI2c(i2c);
i2cDumpInts(i2c->num); i2cDumpInts(i2c->num);
#endif #endif
} }
} }
// offloading all EventGroups to dispatch, EventGroups in ISR is not always successful /* offloading all EventGroups to dispatch, EventGroups in ISR is not always successful
// 11/20/2017 11/20/2017
// if error, need to trigger all succeeding dataQueue events with the EVENT_ERROR_PREV if error, need to trigger all succeeding dataQueue events with the EVENT_ERROR_PREV
07/22/2018
b = 0; 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) { while(b < i2c->queueCount) {
if(i2c->dq[b].ctrl.mode==1 && readCount) { 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 // 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 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) { if(i2c_num > 1) {
return NULL; return NULL;
} }
@ -1326,12 +1369,23 @@ i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
if(i2c == NULL) { if(i2c == NULL) {
return I2C_ERROR_DEV; return I2C_ERROR_DEV;
} }
I2C_FIFO_CONF_t f;
uint32_t period = (APB_CLK_FREQ/clk_speed) / 2; uint32_t period = (APB_CLK_FREQ/clk_speed) / 2;
uint32_t halfPeriod = period/2; uint32_t halfPeriod = period/2;
uint32_t quarterPeriod = period/4; uint32_t quarterPeriod = period/4;
I2C_MUTEX_LOCK(); 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 //the clock num during SCL is low level
i2c->dev->scl_low_period.period = period; i2c->dev->scl_low_period.period = period;
//the clock num during SCL is high level //the clock num during SCL is high level
@ -1381,7 +1435,12 @@ void i2cDumpDqData(i2c_t * i2c)
I2C_DATA_QUEUE_t *tdq; I2C_DATA_QUEUE_t *tdq;
while(a<i2c->queueCount) { while(a<i2c->queueCount) {
tdq=&i2c->dq[a]; 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; uint16_t offset = 0;
while(offset<tdq->length) { while(offset<tdq->length) {
memset(buff,' ',140); memset(buff,' ',140);
@ -1403,8 +1462,6 @@ void i2cDumpDqData(i2c_t * i2c)
} }
a++; a++;
} }
#else
log_n("Enable Core Debug Level \"Error\"");
#endif #endif
} }
@ -1424,7 +1481,8 @@ void i2cDumpI2c(i2c_t * i2c)
log_e("dq=%p",i2c->dq); log_e("dq=%p",i2c->dq);
log_e("queueCount=%d",i2c->queueCount); log_e("queueCount=%d",i2c->queueCount);
log_e("queuePos=%d",i2c->queuePos); 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) { if(i2c->dq) {
i2cDumpDqData(i2c); i2cDumpDqData(i2c);
} }
@ -1432,7 +1490,8 @@ void i2cDumpI2c(i2c_t * i2c)
void i2cDumpInts(uint8_t num) 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; uint32_t b;
log_e("%u row count INTR TX RX",num); log_e("%u row count INTR TX RX",num);
for(uint32_t a=1; a<=INTBUFFMAX; a++) { for(uint32_t a=1; a<=INTBUFFMAX; a++) {
@ -1442,15 +1501,15 @@ void i2cDumpInts(uint8_t num)
} }
} }
#else #else
log_n("enable Core Debug Level \"Error\""); log_i("Debug Buffer not Enabled");
#endif #endif
} }
/* todo /* todo
24Nov17 22JUL18
Need to think about not usings I2C_MASTER_TRAN_COMP_INT_ST to adjust queuePos. This need to add multi-thread capability, use dq.queueEvent as the group marker. When multiple threads
INT triggers every byte. The only reason to know which byte is being transfered is transactions are present in the same queue, and an error occurs, abort all succeeding unserviced transactions
the status_reg.tx_fifo_cnt and a .txQueued to do this in the fillRxFifo(). The with the same dq.queueEvent value. Succeeding unserviced transactions with different dq.queueEvent values
same mechanism could work if an error occured in i2cErrorExit(). can be re-queued and processed independently.
*/ */

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

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

View File

@ -7,7 +7,6 @@
#define INT_BUFFER_SIZE 16 #define INT_BUFFER_SIZE 16
typedef enum { typedef enum {
OTA_IDLE, OTA_IDLE,
OTA_WAITAUTH, OTA_WAITAUTH,
@ -25,9 +24,9 @@ typedef enum {
class ArduinoOTAClass class ArduinoOTAClass
{ {
public: public:
typedef std::function<void(void)> THandlerFunction; typedef std::function<void(void)> THandlerFunction;
typedef std::function<void(ota_error_t)> THandlerFunction_Error; typedef std::function<void(ota_error_t)> THandlerFunction_Error;
typedef std::function<void(unsigned int, unsigned int)> THandlerFunction_Progress; typedef std::function<void(unsigned int, unsigned int)> THandlerFunction_Progress;
ArduinoOTAClass(); ArduinoOTAClass();
~ArduinoOTAClass(); ~ArduinoOTAClass();
@ -75,6 +74,8 @@ class ArduinoOTAClass
//Gets update command type after OTA has started. Either U_FLASH or U_SPIFFS //Gets update command type after OTA has started. Either U_FLASH or U_SPIFFS
int getCommand(); int getCommand();
void setTimeout(int timeoutInMillis);
private: private:
int _port; int _port;
String _password; String _password;
@ -88,6 +89,7 @@ class ArduinoOTAClass
int _size; int _size;
int _cmd; int _cmd;
int _ota_port; int _ota_port;
int _ota_timeout;
IPAddress _ota_ip; IPAddress _ota_ip;
String _md5; String _md5;
@ -106,4 +108,4 @@ class ArduinoOTAClass
extern ArduinoOTAClass ArduinoOTA; extern ArduinoOTAClass ArduinoOTA;
#endif #endif
#endif /* __ARDUINO_OTA_H */ #endif /* __ARDUINO_OTA_H */

View File

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

View File

@ -24,7 +24,6 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "Arduino.h"
#include "EEPROM.h" #include "EEPROM.h"
#include <esp_log.h> #include <esp_log.h>

View File

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

View File

@ -1,6 +1,11 @@
#include "FS.h" #include "FS.h"
#include "SPIFFS.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){ void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\r\n", dirname); Serial.printf("Listing directory: %s\r\n", dirname);
@ -151,7 +156,7 @@ void testFileIO(fs::FS &fs, const char * path){
void setup(){ void setup(){
Serial.begin(115200); Serial.begin(115200);
if(!SPIFFS.begin()){ if(!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)){
Serial.println("SPIFFS Mount Failed"); Serial.println("SPIFFS Mount Failed");
return; return;
} }

View File

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

View File

@ -54,6 +54,8 @@ WebServer::WebServer(IPAddress addr, int port)
, _lastHandler(nullptr) , _lastHandler(nullptr)
, _currentArgCount(0) , _currentArgCount(0)
, _currentArgs(nullptr) , _currentArgs(nullptr)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0) , _headerKeysCount(0)
, _currentHeaders(nullptr) , _currentHeaders(nullptr)
, _contentLength(0) , _contentLength(0)
@ -72,6 +74,8 @@ WebServer::WebServer(int port)
, _lastHandler(nullptr) , _lastHandler(nullptr)
, _currentArgCount(0) , _currentArgCount(0)
, _currentArgs(nullptr) , _currentArgs(nullptr)
, _postArgsLen(0)
, _postArgs(nullptr)
, _headerKeysCount(0) , _headerKeysCount(0)
, _currentHeaders(nullptr) , _currentHeaders(nullptr)
, _contentLength(0) , _contentLength(0)
@ -507,6 +511,10 @@ void WebServer::_streamFileCore(const size_t fileSize, const String & fileName,
String WebServer::arg(String name) { 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) { for (int i = 0; i < _currentArgCount; ++i) {
if ( _currentArgs[i].key == name ) if ( _currentArgs[i].key == name )
return _currentArgs[i].value; return _currentArgs[i].value;
@ -531,6 +539,10 @@ int WebServer::args() {
} }
bool WebServer::hasArg(String name) { 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) { for (int i = 0; i < _currentArgCount; ++i) {
if (_currentArgs[i].key == name) if (_currentArgs[i].key == name)
return true; return true;

View File

@ -147,7 +147,7 @@ protected:
bool _parseForm(WiFiClient& client, String boundary, uint32_t len); bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
bool _parseFormUploadAborted(); bool _parseFormUploadAborted();
void _uploadWriteByte(uint8_t b); 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); void _prepareHeader(String& response, int code, const char* content_type, size_t contentLength);
bool _collectHeader(const char* headerName, const char* headerValue); bool _collectHeader(const char* headerName, const char* headerValue);
@ -179,6 +179,9 @@ protected:
int _currentArgCount; int _currentArgCount;
RequestArgument* _currentArgs; RequestArgument* _currentArgs;
int _postArgsLen;
RequestArgument* _postArgs;
std::unique_ptr<HTTPUpload> _currentUpload; std::unique_ptr<HTTPUpload> _currentUpload;
int _headerKeysCount; 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

@ -438,9 +438,23 @@ uint8_t WiFiClient::connected()
if (_connected) { if (_connected) {
uint8_t dummy; uint8_t dummy;
int res = recv(fd(), &dummy, 0, MSG_DONTWAIT); int res = recv(fd(), &dummy, 0, MSG_DONTWAIT);
if (res <= 0 && errno != EWOULDBLOCK) { switch (errno) {
_connected = false; case EWOULDBLOCK:
log_i("Disconnected: RES: %d, ERR: %d", res, errno); 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;
} }
} }
return _connected; return _connected;

View File

@ -365,14 +365,17 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event)
} else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) { } else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
WiFiSTAClass::_setStatus(WL_CONNECTION_LOST); WiFiSTAClass::_setStatus(WL_CONNECTION_LOST);
} else if(reason == WIFI_REASON_AUTH_EXPIRE) { } else if(reason == WIFI_REASON_AUTH_EXPIRE) {
if(WiFi.getAutoReconnect()){
WiFi.begin();
}
} else { } else {
WiFiSTAClass::_setStatus(WL_DISCONNECTED); WiFiSTAClass::_setStatus(WL_DISCONNECTED);
} }
clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT); 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(); WiFi.begin();
} }
} else if(event->event_id == SYSTEM_EVENT_STA_GOT_IP) { } else if(event->event_id == SYSTEM_EVENT_STA_GOT_IP) {

View File

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

View File

@ -315,8 +315,8 @@ set -e
rm -f "$releasesJson" rm -f "$releasesJson"
echo " previous Release: $prev_release" echo " previous Release: $prev_release"
echo " previous (?Pre-)release: $prev_any_release"
echo " previous Pre-release: $prev_pre_release" echo " previous Pre-release: $prev_pre_release"
echo " previous (any)release: $prev_any_release"
# add generated items to JSON package-definition contents # add generated items to JSON package-definition contents
jq_arg=".packages[0].platforms[0].version = \"$ver\" | \ jq_arg=".packages[0].platforms[0].version = \"$ver\" | \

View File

@ -1,5 +1,11 @@
#!/bin/bash #!/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 set -e
#Cmdline options #Cmdline options
@ -70,33 +76,37 @@ shopt -u nocasematch
# #
# Prepare Markdown release notes: # Prepare Markdown release notes:
################################# #################################
# # - annotated tags only, lightweight tags just display message of referred commit
# - tag's description: # - tag's description conversion to relnotes:
# ignore first 3 lines - commiter, tagname, blank # first 3 lines (tagname, commiter, blank): ignored
# first line of message: heading # 4th line: relnotes heading
# other lines: converted to bullets # remaining lines: each converted to bullet-list item
# empty lines ignored # empty lines ignored
# if '* ' found as a first char pair, it's converted to '- ' to keep bulleting unified # if '* ' found as a first char pair, it's converted to '- ' to keep bulleting unified
echo
echo Preparing release notes echo Preparing release notes
echo ----------------------- echo -----------------------
echo "Tag's message:" echo "Tag's message:"
relNotesRaw=`git show -s --format=%b $varTagName` relNotesRaw=`git show -s --format=%b $varTagName`
readarray -t msgArray <<<"$relNotesRaw" readarray -t msgArray <<<"$relNotesRaw"
arrLen=${#msgArray[@]} arrLen=${#msgArray[@]}
if [ $arrLen > 3 ]; then
#process annotated tags only
if [ $arrLen > 3 ] && [ "${msgArray[0]:0:3}" == "tag" ]; then
ind=3 ind=3
while [ $ind -lt $arrLen ]; do while [ $ind -lt $arrLen ]; do
if [ $ind -eq 3 ]; then if [ $ind -eq 3 ]; then
releaseNotes="#### ${msgArray[ind]}\\n" releaseNotes="#### ${msgArray[ind]}"
releaseNotes+=$'\r\n'
else else
oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')" oneLine="$(echo -e "${msgArray[ind]}" | sed -e 's/^[[:space:]]*//')"
if [ ${#oneLine} -gt 0 ]; then if [ ${#oneLine} -gt 0 ]; then
if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi if [ "${oneLine:0:2}" == "* " ]; then oneLine=$(echo ${oneLine/\*/-}); fi
if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi if [ "${oneLine:0:2}" != "- " ]; then releaseNotes+="- "; fi
releaseNotes+="$oneLine\\n" releaseNotes+="$oneLine"
releaseNotes+=$'\r\n'
#debug output #debug output
echo " ${oneLine}" echo " ${oneLine}"
@ -104,21 +114,16 @@ if [ $arrLen > 3 ]; then
fi fi
let ind=$ind+1 let ind=$ind+1
done done
echo "<tag's message end>"
else
releaseNotes="#### Release of $varTagName\\n"
#debug output
echo " Release of $varTagName"
fi fi
echo "$releaseNotes"
# - list of commits (commits.txt must exit in the output dir) # - list of commits (commits.txt must exit in the output dir)
commitFile=$varAssetsDir/commits.txt commitFile=$varAssetsDir/commits.txt
if [ -e "$commitFile" ]; then if [ -s "$commitFile" ]; then
releaseNotes+="\\n##### Commits\\n" releaseNotes+=$'\r\n##### Commits\r\n'
#debug output
echo echo
echo "Commits:" echo "Commits:"
@ -126,48 +131,86 @@ if [ -e "$commitFile" ]; then
for next in `cat $commitFile` for next in `cat $commitFile`
do do
IFS=' ' read -r commitId commitMsg <<< "$next" 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"
#debug output releaseNotes+="$commitLine"
echo " - [$commitId](https://github.com/$varRepoSlug/commit/$commitId) $commitMsg" releaseNotes+=$'\r\n'
done done
rm -f $commitFile rm -f $commitFile
fi fi
releaseNotes=$(perl -pe 's/\r?\n/\\n/' <<< ${releaseNotes})
# Check possibly existing release for current tag # Check possibly existing release for current tag
echo "Checking for possible releases of current tag $varTagName..." echo
# (eg build invoked by Create New Release GHUI button -> GH default release pack created immediatelly including default assests) 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) 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_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')
HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') 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 the release exists, append/update recent files to its assets vector
if [ $HTTP_STATUS -eq 200 ]; then if [ $HTTP_STATUS -eq 200 ]; then
releaseId=$(echo $HTTP_BODY | jq -r '.id') releaseId=$(echo $HTTP_BODY | jq -r '.id')
echo " - $varTagName release found (id $releaseId)" echo " - $varTagName release found (id $releaseId)"
#merge release notes and overwrite pre-release flag. all other attributes remain unchanged #Merge release notes and overwrite pre-release flag. all other attributes remain unchanged:
releaseNotesGH=$(echo $HTTP_BODY | jq -r '.body')
releaseNotes="$releaseNotesGH\\n$releaseNotes"
echo " ... updating release notes and pre-release flag" # 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}" curlData="{\"body\": \"$releaseNotes\",\"prerelease\": $varPrerelease}"
curl --data "$curlData" https://api.github.com/repos/$varRepoSlug/releases/$releaseId?access_token=$varAccessToken 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 if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
echo " - $varTagName release record successfully updated"
#... or create a new release record #... or create a new release record
else 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}" 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'" #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') 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 if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
echo " - $varTagName release record successfully created (id $releaseId)"
fi fi
# Assets defined by dir contents # Assets defined by dir contents
@ -180,19 +223,19 @@ if [ ! -z $varAssetsDir ]; then
done done
fi fi
echo
echo varAssets: $varAssets
#Upload additional assets #Upload additional assets
if [ ! -z $varAssets ]; then if [ ! -z $varAssets ]; then
echo echo
echo "Uploading assets:" echo "Uploading assets:"
echo "-----------------" echo "-----------------"
echo " Files to upload:"
echo " $varAssets"
echo
curlAuth="Authorization: token $varAccessToken" curlAuth="Authorization: token $varAccessToken"
for filename in $(echo $varAssets | tr ";" "\n") for filename in $(echo $varAssets | tr ";" "\n")
do do
echo " - ${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) 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 if [ $? -ne 0 ]; then echo "FAILED: $? => aborting"; exit 1; fi
@ -203,8 +246,3 @@ if [ ! -z $varAssets ]; then
done done
fi 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 */

54
variants/d32/d32_core.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef _D32_CORE_H_
#define _D32_CORE_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 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 A0 = 36;
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 = 33;
static const uint8_t T9 = 32;
static const uint8_t DAC1 = 25;
static const uint8_t DAC2 = 26;
#endif

View File

@ -0,0 +1,11 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#include <d32_core.h>
static const uint8_t LED_BUILTIN = 5;
#define BUILTIN_LED LED_BUILTIN // backward compatibility
static const uint8_t _VBAT = 35; // battery voltage
#endif /* Pins_Arduino_h */

View File

@ -0,0 +1,19 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#include <../d32/d32_core.h>
static const uint8_t LED_BUILTIN = 5;
#define BUILTIN_LED LED_BUILTIN // backward compatibility
static const uint8_t _VBAT = 35; // battery voltage
static const uint8_t TF_CS = 4; // TF (Micro SD Card) CS pin
static const uint8_t TS_CS = 12; // Touch Screen CS pin
static const uint8_t TFT_CS = 14; // TFT CS pin
static const uint8_t TFT_LED = 32; // TFT backlight control pin
static const uint8_t TFT_RST = 33; // TFT reset pin
static const uint8_t TFT_DC = 27; // TFT DC pin
#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 */