From 80f9f9aeec393ec29b343cee111528f2c026f8c4 Mon Sep 17 00:00:00 2001 From: chuck todd Date: Sun, 26 Jan 2020 15:20:19 -0700 Subject: [PATCH 01/13] fix removeApbChangeCallback() error in spiStopBus() (#3675) * fix removeApbChangeCallback() error in spiStopBus() spiStartBus() was using spiStopBus() to init the hardware, one of spiStopBus() functions is to unregister the runtime CPU clock speed change callback. But, spiStartBus() only wanted to init the hardware. This patch separates the hardware init into a standalone function spiInitBus() that both spiStartBus() and spiStopBus() call. * Update esp32-hal-spi.c capitalization problem --- cores/esp32/esp32-hal-spi.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index cf302cac..b3b703cc 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -384,12 +384,8 @@ static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb } } -void spiStopBus(spi_t * spi) +static void spiInitBus(spi_t * spi) { - if(!spi) { - return; - } - SPI_MUTEX_LOCK(); spi->dev->slave.trans_done = 0; spi->dev->slave.slave_mode = 0; spi->dev->pin.val = 0; @@ -399,8 +395,19 @@ void spiStopBus(spi_t * spi) spi->dev->ctrl1.val = 0; spi->dev->ctrl2.val = 0; spi->dev->clock.val = 0; - SPI_MUTEX_UNLOCK(); +} + +void spiStopBus(spi_t * spi) +{ + if(!spi) { + return; + } + removeApbChangeCallback(spi, _on_apb_change); + + SPI_MUTEX_LOCK(); + spiInitBus(spi); + SPI_MUTEX_UNLOCK(); } spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_t bitOrder) @@ -431,12 +438,8 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_1); } - spiStopBus(spi); - spiSetDataMode(spi, dataMode); - spiSetBitOrder(spi, bitOrder); - spiSetClockDiv(spi, clockDiv); - SPI_MUTEX_LOCK(); + spiInitBus(spi); spi->dev->user.usr_mosi = 1; spi->dev->user.usr_miso = 1; spi->dev->user.doutdin = 1; @@ -447,6 +450,10 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ } SPI_MUTEX_UNLOCK(); + spiSetDataMode(spi, dataMode); + spiSetBitOrder(spi, bitOrder); + spiSetClockDiv(spi, clockDiv); + addApbChangeCallback(spi, _on_apb_change); return spi; } From ed220bd0420236e9ff95888f7459f0eb9c97a570 Mon Sep 17 00:00:00 2001 From: hreintke Date: Sun, 26 Jan 2020 23:38:06 +0100 Subject: [PATCH 02/13] Minimize HardwareSerial Receive and Transmit delays (#3664) * Minimize HardwareSerial Receive and Transmit delays * Remove uartRxFifoToQueue from esp-hal-uart.h Co-authored-by: Me No Dev --- cores/esp32/esp32-hal-uart.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 90acf54f..8ec1fe6f 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -208,6 +208,11 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx uart->dev->conf0.stop_bit_num = ONE_STOP_BITS_CONF; uart->dev->rs485_conf.dl1_en = 1; } + + // tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate) + // Setting it to 0 prevents line idle time/delays when sending messages with small intervals + uart->dev->idle_conf.tx_idle_num = 0; // + UART_MUTEX_UNLOCK(); if(rxPin != -1) { @@ -265,7 +270,7 @@ uint32_t uartAvailable(uart_t* uart) if(uart == NULL || uart->queue == NULL) { return 0; } - return uxQueueMessagesWaiting(uart->queue); + return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ; } uint32_t uartAvailableForWrite(uart_t* uart) @@ -276,12 +281,27 @@ uint32_t uartAvailableForWrite(uart_t* uart) return 0x7f - uart->dev->status.txfifo_cnt; } +void uartRxFifoToQueue(uart_t* uart) +{ + uint8_t c; + UART_MUTEX_LOCK(); + while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { + c = uart->dev->fifo.rw_byte; + xQueueSend(uart->queue, &c, 0); + } + UART_MUTEX_UNLOCK(); +} + uint8_t uartRead(uart_t* uart) { if(uart == NULL || uart->queue == NULL) { return 0; } uint8_t c; + if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) + { + uartRxFifoToQueue(uart); + } if(xQueueReceive(uart->queue, &c, 0)) { return c; } @@ -294,6 +314,10 @@ uint8_t uartPeek(uart_t* uart) return 0; } uint8_t c; + if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) + { + uartRxFifoToQueue(uart); + } if(xQueuePeek(uart->queue, &c, 0)) { return c; } From b2c678877c04428f06ec5f1f59cc4d204bcd05ec Mon Sep 17 00:00:00 2001 From: chuck todd Date: Wed, 29 Jan 2020 03:18:54 -0700 Subject: [PATCH 03/13] std::shared_ptr Memory Leak (#3680) * std::shared_ptr Memory Leak clientSocketHande and _rxBuffer are std::shared_ptr, the stop() call was not correctly releasing them and the operator= had similar problems fix for #3679 * operator= second attempt * operator= third time --- libraries/WiFi/src/WiFiClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp index e422b636..3913208b 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/WiFi/src/WiFiClient.cpp @@ -196,8 +196,8 @@ WiFiClient & WiFiClient::operator=(const WiFiClient &other) void WiFiClient::stop() { - clientSocketHandle = NULL; - _rxBuffer = NULL; + clientSocketHandle.reset(); // clientSocketHandle = NULL; + _rxBuffer.reset(); // _rxBuffer = NULL; _connected = false; } From 109ba7a3b44cf0d89068aa0ec812271d3bc4acbc Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Wed, 29 Jan 2020 12:30:08 +0200 Subject: [PATCH 04/13] Revert "std::shared_ptr Memory Leak (#3680)" (#3682) This reverts commit b2c678877c04428f06ec5f1f59cc4d204bcd05ec. --- libraries/WiFi/src/WiFiClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp index 3913208b..e422b636 100644 --- a/libraries/WiFi/src/WiFiClient.cpp +++ b/libraries/WiFi/src/WiFiClient.cpp @@ -196,8 +196,8 @@ WiFiClient & WiFiClient::operator=(const WiFiClient &other) void WiFiClient::stop() { - clientSocketHandle.reset(); // clientSocketHandle = NULL; - _rxBuffer.reset(); // _rxBuffer = NULL; + clientSocketHandle = NULL; + _rxBuffer = NULL; _connected = false; } From 9b75c65fc76ea67b7b8420dbc2c8ccc917182765 Mon Sep 17 00:00:00 2001 From: Isaranu Janthong Date: Wed, 29 Jan 2020 22:08:14 +0700 Subject: [PATCH 05/13] Add Senses's WEIZEN board from Senses IoT platform (#3687) * Add Senses's WEIZEN board from Senses IoT platform * Add Senses's WEIZEN board (updated variant) --- boards.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/boards.txt b/boards.txt index fea38318..7ec85f10 100644 --- a/boards.txt +++ b/boards.txt @@ -4774,3 +4774,45 @@ metro_esp-32.menu.DebugLevel.verbose=Verbose metro_esp-32.menu.DebugLevel.verbose.build.code_debug=5 ############################################################## +sensesiot_weizen.name=Senses's WEIZEN + +sensesiot_weizen.upload.tool=esptool_py +sensesiot_weizen.upload.maximum_size=1310720 +sensesiot_weizen.upload.maximum_data_size=327680 +sensesiot_weizen.upload.wait_for_upload_port=true + +sensesiot_weizen.serial.disableDTR=true +sensesiot_weizen.serial.disableRTS=true + +sensesiot_weizen.build.mcu=esp32 +sensesiot_weizen.build.core=esp32 +sensesiot_weizen.build.variant=esp32 +sensesiot_weizen.build.board=sensesiot_weizen + +sensesiot_weizen.build.f_cpu=240000000L +sensesiot_weizen.build.flash_mode=dio +sensesiot_weizen.build.flash_size=4MB +sensesiot_weizen.build.boot=dio +sensesiot_weizen.build.partitions=default +sensesiot_weizen.build.defines= + +sensesiot_weizen.menu.FlashFreq.80=80MHz +sensesiot_weizen.menu.FlashFreq.80.build.flash_freq=80m +sensesiot_weizen.menu.FlashFreq.40=40MHz +sensesiot_weizen.menu.FlashFreq.40.build.flash_freq=40m + +sensesiot_weizen.menu.UploadSpeed.921600=921600 +sensesiot_weizen.menu.UploadSpeed.921600.upload.speed=921600 +sensesiot_weizen.menu.UploadSpeed.115200=115200 +sensesiot_weizen.menu.UploadSpeed.115200.upload.speed=115200 +sensesiot_weizen.menu.UploadSpeed.256000.windows=256000 +sensesiot_weizen.menu.UploadSpeed.256000.upload.speed=256000 +sensesiot_weizen.menu.UploadSpeed.230400.windows.upload.speed=256000 +sensesiot_weizen.menu.UploadSpeed.230400=230400 +sensesiot_weizen.menu.UploadSpeed.230400.upload.speed=230400 +sensesiot_weizen.menu.UploadSpeed.460800.linux=460800 +sensesiot_weizen.menu.UploadSpeed.460800.macosx=460800 +sensesiot_weizen.menu.UploadSpeed.460800.upload.speed=460800 +sensesiot_weizen.menu.UploadSpeed.512000.windows=512000 +sensesiot_weizen.menu.UploadSpeed.512000.upload.speed=512000 +############################################################## From 13e02063d63146096952fc6a6ef0bc3ced5b1203 Mon Sep 17 00:00:00 2001 From: Alexander Bergmann Date: Fri, 14 Feb 2020 10:03:38 +0100 Subject: [PATCH 06/13] Move _STREAM_BOUNDARY before _STREAM_PART (#3720) The boundary delimiter (_STREAM_BOUNDARY) needs to be send before the body part (_STREAM_PART) too follow RFC2046. This caused ffplay/ffmpeg to fail to open the MJPEG stream. --- .../ESP32/examples/Camera/CameraWebServer/app_httpd.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index 07d29ee7..5e33ec7c 100644 --- a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp +++ b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp @@ -403,6 +403,9 @@ static esp_err_t stream_handler(httpd_req_t *req){ } } } + if(res == ESP_OK){ + res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); + } if(res == ESP_OK){ size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len); res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); @@ -410,9 +413,6 @@ static esp_err_t stream_handler(httpd_req_t *req){ if(res == ESP_OK){ res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len); } - if(res == ESP_OK){ - res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); - } if(fb){ esp_camera_fb_return(fb); fb = NULL; From 0f772270fbb32099cad72053755d6b4c7e8e1f82 Mon Sep 17 00:00:00 2001 From: hznupeter Date: Thu, 12 Mar 2020 16:16:50 +0800 Subject: [PATCH 07/13] add new board Handbit (#3807) * add handbit * add handbit pins_arduino * Update boards.txt --- boards.txt | 109 ++++++++++++++++++++++++++++++++ variants/handbit/pins_arduino.h | 90 ++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 variants/handbit/pins_arduino.h diff --git a/boards.txt b/boards.txt index 7ec85f10..2a524dfc 100644 --- a/boards.txt +++ b/boards.txt @@ -4816,3 +4816,112 @@ sensesiot_weizen.menu.UploadSpeed.460800.upload.speed=460800 sensesiot_weizen.menu.UploadSpeed.512000.windows=512000 sensesiot_weizen.menu.UploadSpeed.512000.upload.speed=512000 ############################################################## +mPython.name=mPython + +mPython.upload.tool=esptool_py +mPython.upload.maximum_size=1310720 +mPython.upload.maximum_data_size=327680 +mPython.upload.wait_for_upload_port=true + +mPython.serial.disableDTR=true +mPython.serial.disableRTS=true + +mPython.build.mcu=esp32 +mPython.build.core=esp32 +mPython.build.variant=mpython +mPython.build.board=ESP32_DEV + +mPython.build.f_cpu=240000000L +mPython.build.flash_size=8MB +mPython.build.flash_freq=40m +mPython.build.flash_mode=dio +mPython.build.boot=dio +mPython.build.partitions=huge_app +mPython.build.defines= + +mPython.menu.PSRAM.disabled=Disabled +mPython.menu.PSRAM.disabled.build.defines= +mPython.menu.PSRAM.enabled=Enabled +mPython.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue + +mPython.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS) +mPython.menu.PartitionScheme.huge_app.build.partitions=huge_app +mPython.menu.PartitionScheme.huge_app.upload.maximum_size=3145728 +mPython.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS) +mPython.menu.PartitionScheme.default.build.partitions=default +mPython.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS) +mPython.menu.PartitionScheme.defaultffat.build.partitions=default_ffat +mPython.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS) +mPython.menu.PartitionScheme.minimal.build.partitions=minimal +mPython.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS) +mPython.menu.PartitionScheme.no_ota.build.partitions=no_ota +mPython.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +mPython.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS) +mPython.menu.PartitionScheme.noota_3g.build.partitions=noota_3g +mPython.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576 +mPython.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS) +mPython.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat +mPython.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152 +mPython.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS) +mPython.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat +mPython.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576 +mPython.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS) +mPython.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +mPython.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 +mPython.menu.PartitionScheme.fatflash=16M Flash (2MB APP/12.5MB FAT) +mPython.menu.PartitionScheme.fatflash.build.partitions=ffat + +mPython.menu.CPUFreq.240=240MHz (WiFi/BT) +mPython.menu.CPUFreq.240.build.f_cpu=240000000L + + +mPython.menu.FlashMode.qio=QIO +mPython.menu.FlashMode.qio.build.flash_mode=dio +mPython.menu.FlashMode.qio.build.boot=qio +mPython.menu.FlashMode.dio=DIO +mPython.menu.FlashMode.dio.build.flash_mode=dio +mPython.menu.FlashMode.dio.build.boot=dio +mPython.menu.FlashMode.qout=QOUT +mPython.menu.FlashMode.qout.build.flash_mode=dout +mPython.menu.FlashMode.qout.build.boot=qout +mPython.menu.FlashMode.dout=DOUT +mPython.menu.FlashMode.dout.build.flash_mode=dout +mPython.menu.FlashMode.dout.build.boot=dout + +mPython.menu.FlashFreq.80=80MHz +mPython.menu.FlashFreq.80.build.flash_freq=80m +mPython.menu.FlashFreq.40=40MHz +mPython.menu.FlashFreq.40.build.flash_freq=40m + +mPython.menu.FlashSize.8M=8MB (64Mb) +mPython.menu.FlashSize.8M.build.flash_size=8MB + + +mPython.menu.UploadSpeed.921600=921600 +mPython.menu.UploadSpeed.921600.upload.speed=921600 +mPython.menu.UploadSpeed.115200=115200 +mPython.menu.UploadSpeed.115200.upload.speed=115200 +mPython.menu.UploadSpeed.256000.windows=256000 +mPython.menu.UploadSpeed.256000.upload.speed=256000 +mPython.menu.UploadSpeed.230400.windows.upload.speed=256000 +mPython.menu.UploadSpeed.230400=230400 +mPython.menu.UploadSpeed.230400.upload.speed=230400 +mPython.menu.UploadSpeed.460800.linux=460800 +mPython.menu.UploadSpeed.460800.macosx=460800 +mPython.menu.UploadSpeed.460800.upload.speed=460800 +mPython.menu.UploadSpeed.512000.windows=512000 +mPython.menu.UploadSpeed.512000.upload.speed=512000 + +mPython.menu.DebugLevel.none=None +mPython.menu.DebugLevel.none.build.code_debug=0 +mPython.menu.DebugLevel.error=Error +mPython.menu.DebugLevel.error.build.code_debug=1 +mPython.menu.DebugLevel.warn=Warn +mPython.menu.DebugLevel.warn.build.code_debug=2 +mPython.menu.DebugLevel.info=Info +mPython.menu.DebugLevel.info.build.code_debug=3 +mPython.menu.DebugLevel.debug=Debug +mPython.menu.DebugLevel.debug.build.code_debug=4 +mPython.menu.DebugLevel.verbose=Verbose +mPython.menu.DebugLevel.verbose.build.code_debug=5 +############################################################## diff --git a/variants/handbit/pins_arduino.h b/variants/handbit/pins_arduino.h new file mode 100644 index 00000000..5ecb2a55 --- /dev/null +++ b/variants/handbit/pins_arduino.h @@ -0,0 +1,90 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#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 = 23; +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; + + +static const uint8_t P0 = 33; +static const uint8_t P1 = 32; +static const uint8_t P2 = 35; +static const uint8_t P3 = 34; +static const uint8_t P4 = 39; +static const uint8_t P5 = 0; +static const uint8_t P6 = 16; +static const uint8_t P7 = 17; +static const uint8_t P8 = 26; +static const uint8_t P9 = 25; +static const uint8_t P10 = 36; +static const uint8_t P11 = 2; +static const uint8_t P13 = 18; +static const uint8_t P14 = 19; +static const uint8_t P15 = 21; +static const uint8_t P16 = 5; +static const uint8_t P19 = 22; +static const uint8_t P20 = 23; + +static const uint8_t P = 27; +static const uint8_t Y = 14; +static const uint8_t T = 12; +static const uint8_t H = 13; +static const uint8_t O = 15; +static const uint8_t N = 4; + +static const uint8_t BTN_A = 0; +static const uint8_t BTN_B = 2; +static const uint8_t SOUND = 36; +static const uint8_t LIGHT = 39; +static const uint8_t BUZZER = 16; + + +#endif /* Pins_Arduino_h */ From 5508689ea3ac8309ea39b52a6c079cf76288092b Mon Sep 17 00:00:00 2001 From: Me No Dev Date: Mon, 13 Apr 2020 12:47:34 +0300 Subject: [PATCH 08/13] Update install-platformio-esp32.sh --- .github/scripts/install-platformio-esp32.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/install-platformio-esp32.sh b/.github/scripts/install-platformio-esp32.sh index ce6de4a2..65dc0c40 100755 --- a/.github/scripts/install-platformio-esp32.sh +++ b/.github/scripts/install-platformio-esp32.sh @@ -9,7 +9,7 @@ echo "Installing PlatformIO ..." pip install -U https://github.com/platformio/platformio/archive/develop.zip > /dev/null 2>&1 echo "Installing Platform ESP32 ..." -python -m platformio platform install https://github.com/platformio/platform-espressif32.git#feature/stage > /dev/null 2>&1 +python -m platformio platform install https://github.com/platformio/platform-espressif32.git > /dev/null 2>&1 echo "Replacing the framework version ..." if [[ "$OSTYPE" == "darwin"* ]]; then From 2c9b648502f1cfdbe2e9a1ef9c26582718633830 Mon Sep 17 00:00:00 2001 From: sweetymhaiske Date: Thu, 16 Apr 2020 02:07:55 +0530 Subject: [PATCH 09/13] Add support of unified provisioning to Arduino 1. WiFiProv.ino sketch is added that allows arduino users to do provisioning via SoftAP or BLE. WiFi.beginProvision( ) API is designed for provisioning in Arduino. 2. In WiFiProv.h provisioning class is defined. 3. WiFiProv.cpp contains implementation for provisioning class. 4. README.md file is added which contains detail information for working. --- CMakeLists.txt | 1 + libraries/WiFi/examples/WiFiProv/README.md | 135 +++++++++++++++ libraries/WiFi/examples/WiFiProv/WiFiProv.ino | 63 +++++++ libraries/WiFi/src/WiFi.h | 6 +- libraries/WiFi/src/WiFiGeneric.cpp | 72 ++++++-- libraries/WiFi/src/WiFiGeneric.h | 18 +- libraries/WiFi/src/WiFiProv.cpp | 157 ++++++++++++++++++ libraries/WiFi/src/WiFiProv.h | 55 ++++++ 8 files changed, 490 insertions(+), 17 deletions(-) create mode 100644 libraries/WiFi/examples/WiFiProv/README.md create mode 100644 libraries/WiFi/examples/WiFiProv/WiFiProv.ino create mode 100644 libraries/WiFi/src/WiFiProv.cpp create mode 100644 libraries/WiFi/src/WiFiProv.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cf8981f9..d38f9d43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,7 @@ set(LIBRARY_SRCS libraries/WiFi/src/WiFi.cpp libraries/WiFi/src/WiFiGeneric.cpp libraries/WiFi/src/WiFiMulti.cpp + libraries/WiFi/src/WiFiProv.cpp libraries/WiFi/src/WiFiScan.cpp libraries/WiFi/src/WiFiServer.cpp libraries/WiFi/src/WiFiSTA.cpp diff --git a/libraries/WiFi/examples/WiFiProv/README.md b/libraries/WiFi/examples/WiFiProv/README.md new file mode 100644 index 00000000..2816381f --- /dev/null +++ b/libraries/WiFi/examples/WiFiProv/README.md @@ -0,0 +1,135 @@ +# Provisioning for Arduino + +This sketch implements provisioning using various IDF components + +# Description + +This example allows Arduino user to choose either BLE or SOFTAP as a mode of transport, over which the provisioning related communication is to take place, between the device (to be provisioned) and the client (owner of the device). + +## API's introduced for provisioning + +## WiFi.onEvent() + +Using this API user can register to recieve WIFI Events and Provisioning Events + +#### Parameters passed + +A function with following signature +* void SysProvEvent(system_event_t * , wifi_prov_event_t * ); + +#### structure [ wifi_prov_event_t ] + +* wifi_prov_cb_event_t event; +* void * event_data; + +### WiFi.beginProvision() + +WiFi.beginProvision(scheme prov_scheme, wifi_prov_scheme_event_handler_t scheme_event_handler, wifi_prov_security_t security, char * pop, char * service_name, char * service_key, uint8_t * uuid); + +#### Parameters + +* prov_scheme : choose the mode of transfer + * WIFI_PROV_SCHEME_BLE - Using BLE + * WIFI_PROV_SCHEME_SOFTAP - Using SoftAP + +* security : choose security type + * WIFI_PROV_SECURITY_1 - It allows secure communication which consists of secure handshake using key exchange and proof of possession (pop) and encryption/decryption of messages. + + * WIFI_PROV_SECURITY_0 - It do not provide application level security, it involve simply plain text communication. + +* scheme_event_handler : specify the handlers according to the mode chosen + * BLE : + - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM - This scheme event handler is used when application doesn't need BT and BLE after provisioning is finised + - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE - This scheme event handler is used when application doesn't need BLE to be active after provisioning is finised + - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT - This scheme event handler is used when application doesn't need BT to be active after provisioning is finised + + * SoftAp : + - WIFI_PROV_EVENT_HANDLER_NONE + +* pop : It is the string that is used to provide the authentication while provisioning + +* service_name : Specify service name for the device while provisioning, if it is not specified then default chosen name via SoftAP is WIFI_XXX and for BLE service it is BLE_XXX where XXX is the last 3 bytes of the MAC address. + +* service_key : Specify service key while provisioning, if chosen mode of provisioning is BLE then service_key is always NULL + +* uuid : user can specify there own 128 bit UUID while provisioning using BLE, if not specified then default value taken is + - { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, + 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, } + +# NOTE + +* If none of the parameters are specified in beginProvision then default provisioning takes place using SoftAP with + * scheme = WIFI_PROV_SCHEME_SOFTAP + * scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE + * security = WIFI_PROV_SECURITY_1 + * pop = "abcd1234" + * service_name = "WiFi_XXX" + * service_key = NULL + * uuid = NULL + +# Log Output +* Enable debuger : [ Tools -> Core Debug Level -> Info ] + +# App required for provisioning + +##Gihub link + +* Android : (https://github.com/espressif/esp-idf-provisioning-android) +* iOS : (https://github.com/espressif/esp-idf-provisioning-ios) + +## These apps are available on playstore + +* For SoftAP : ESP SoftAP Prov +* For BLE : ESP BLE Prov + +# Example output + +## Provisioning using SoftAP + +``` +[I][WiFiProv.cpp:117] beginProvision(): Starting AP using SOFTAP + service_name : WIFI_XXX + password : 123456789 + pop : abcd1234 + +Provisioning started +Give Credentials of your access point using " Android app " + +Received Wi-Fi credentials + SSID : GIONEE M2 + Password : 123456789 + +Connected IP address : 192.168.43.120 +Provisioning Successful +Provisioning Ends + +``` + +## Provisioning using BLE + +``` +[I][WiFiProv.cpp:115] beginProvision(): Starting AP using BLE + service_name : BLE_XXX + pop : abcd1234 + +Provisioning started +Give Credentials of your access point using " Android app " + +Received Wi-Fi credentials + SSID : GIONEE M2 + Password : 123456789 + +Connected IP address : 192.168.43.120 +Provisioning Successful +Provisioning Ends + +``` + +## Credentials are available on device + +``` +[I][WiFiProv.cpp:125] beginProvision(): Aleardy Provisioned, starting Wi-Fi STA +[I][WiFiProv.cpp:126] beginProvision(): CONNECTING ACCESS POINT CREDENTIALS : +[I][WiFiProv.cpp:126] beginProvision(): SSID : GIONEE M2 + +``` diff --git a/libraries/WiFi/examples/WiFiProv/WiFiProv.ino b/libraries/WiFi/examples/WiFiProv/WiFiProv.ino new file mode 100644 index 00000000..92b141b4 --- /dev/null +++ b/libraries/WiFi/examples/WiFiProv/WiFiProv.ino @@ -0,0 +1,63 @@ +#include "WiFi.h" +void SysProvEvent(system_event_t *sys_event,wifi_prov_event_t *prov_event) +{ + if(sys_event) { + switch (sys_event->event_id) { + case SYSTEM_EVENT_STA_GOT_IP: + Serial.print("\nConnected IP address : "); + Serial.println(ip4addr_ntoa(&sys_event->event_info.got_ip.ip_info.ip)); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + Serial.println("\nDisconnected. Connecting to the AP again... "); + break; + default: + break; + } + } + + if(prov_event) { + switch (prov_event->event) { + case WIFI_PROV_START: + Serial.println("\nProvisioning started\nGive Credentials of your access point using \" Android app \""); + break; + case WIFI_PROV_CRED_RECV: { + Serial.println("\nReceived Wi-Fi credentials"); + wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)prov_event->event_data; + Serial.print("\tSSID : "); + Serial.println((const char *) wifi_sta_cfg->ssid); + Serial.print("\tPassword : "); + Serial.println((char const *) wifi_sta_cfg->password); + break; + } + case WIFI_PROV_CRED_FAIL: { + wifi_prov_sta_fail_reason_t *reason = (wifi_prov_sta_fail_reason_t *)prov_event->event_data; + Serial.println("\nProvisioning failed!\nPlease reset to factory and retry provisioning\n"); + if(*reason == WIFI_PROV_STA_AUTH_ERROR) + Serial.println("\nWi-Fi AP password incorrect"); + else + Serial.println("\nWi-Fi AP not found....Add API \" nvs_flash_erase() \" before beginProvision()"); + break; + } + case WIFI_PROV_CRED_SUCCESS: + Serial.println("\nProvisioning Successful"); + break; + case WIFI_PROV_END: + Serial.println("\nProvisioning Ends"); + break; + default: + break; + } + } +} + +void setup() { + Serial.begin(115200); + //Sample uuid that user can pass during provisioning using BLE + /* uint8_t uuid[16] = {0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, + 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02 };*/ + WiFi.onEvent(SysProvEvent); + WiFi.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, "abcd1234", "BLE_XXX", NULL, NULL); +} + +void loop() { +} diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h index ad6c3274..54bd1025 100644 --- a/libraries/WiFi/src/WiFi.h +++ b/libraries/WiFi/src/WiFi.h @@ -37,8 +37,9 @@ #include "WiFiClient.h" #include "WiFiServer.h" #include "WiFiUdp.h" +#include "WiFiProv.h" -class WiFiClass : public WiFiGenericClass, public WiFiSTAClass, public WiFiScanClass, public WiFiAPClass +class WiFiClass : public WiFiGenericClass, public WiFiSTAClass, public WiFiScanClass, public WiFiAPClass, public WiFiProvClass { public: using WiFiGenericClass::channel; @@ -54,8 +55,7 @@ public: using WiFiScanClass::BSSID; using WiFiScanClass::BSSIDstr; using WiFiScanClass::channel; - -public: +public: void printDiag(Print& dest); friend class WiFiClient; friend class WiFiServer; diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 50fb56f4..05458a26 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -42,7 +42,6 @@ extern "C" { #include "lwip/dns.h" #include "esp_ipc.h" - } //extern "C" #include "esp32-hal-log.h" @@ -53,20 +52,42 @@ static xQueueHandle _network_event_queue; static TaskHandle_t _network_event_task_handle = NULL; static EventGroupHandle_t _network_event_group = NULL; +esp_err_t postToSysQueue(system_prov_event_t *data) +{ + if (xQueueSend(_network_event_queue, &data, portMAX_DELAY) != pdPASS) { + log_w("Network Event Queue Send Failed!"); + return ESP_FAIL; + } + return ESP_OK; +} + static void _network_event_task(void * arg){ - system_event_t event; + system_prov_event_t *data; for (;;) { - if(xQueueReceive(_network_event_queue, &event, portMAX_DELAY) == pdTRUE){ - WiFiGenericClass::_eventCallback(arg, &event); - } + if(xQueueReceive(_network_event_queue, &data, portMAX_DELAY) == pdTRUE){ + if(data->prov_event != NULL){ + WiFiGenericClass::_eventCallback(arg, data->sys_event, data->prov_event); + free(data->sys_event); + free(data->prov_event); + } else { + WiFiGenericClass::_eventCallback(arg, data->sys_event, NULL); + } + free(data); + } } vTaskDelete(NULL); _network_event_task_handle = NULL; } -static esp_err_t _network_event_cb(void *arg, system_event_t *event){ - if (xQueueSend(_network_event_queue, event, portMAX_DELAY) != pdPASS) { - log_w("Network Event Queue Send Failed!"); +static esp_err_t _network_event_cb(void *arg, system_event_t *event){ + system_prov_event_t *sys_prov_data = (system_prov_event_t *)malloc(sizeof(system_prov_event_t)); + if(sys_prov_data == NULL) { + return ESP_FAIL; + } + sys_prov_data->sys_event = event; + sys_prov_data->prov_event = NULL; + if (postToSysQueue(sys_prov_data) != ESP_OK){ + free(sys_prov_data); return ESP_FAIL; } return ESP_OK; @@ -82,7 +103,7 @@ static bool _start_network_event_task(){ xEventGroupSetBits(_network_event_group, WIFI_DNS_IDLE_BIT); } if(!_network_event_queue){ - _network_event_queue = xQueueCreate(32, sizeof(system_event_t)); + _network_event_queue = xQueueCreate(32, sizeof(system_prov_event_t)); if(!_network_event_queue){ log_e("Network Event Queue Create Failed!"); return false; @@ -144,7 +165,7 @@ static bool espWiFiStart(){ _esp_wifi_started = true; system_event_t event; event.event_id = SYSTEM_EVENT_WIFI_READY; - WiFiGenericClass::_eventCallback(nullptr, &event); + WiFiGenericClass::_eventCallback(nullptr, &event, NULL); return true; } @@ -173,9 +194,10 @@ typedef struct WiFiEventCbList { WiFiEventCb cb; WiFiEventFuncCb fcb; WiFiEventSysCb scb; + WiFiProvEventCb provcb; system_event_id_t event; - WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), event(SYSTEM_EVENT_WIFI_READY) {} + WiFiEventCbList() : id(current_id++), cb(NULL), fcb(NULL), scb(NULL), provcb(NULL), event(SYSTEM_EVENT_WIFI_READY) {} } WiFiEventCbList_t; wifi_event_id_t WiFiEventCbList::current_id = 1; @@ -230,6 +252,20 @@ int WiFiGenericClass::waitStatusBits(int bits, uint32_t timeout_ms){ * @param cbEvent WiFiEventCb * @param event optional filter (WIFI_EVENT_MAX is all events) */ +wifi_event_id_t WiFiGenericClass::onEvent(WiFiProvEventCb cbEvent, system_event_id_t event) +{ + if(!cbEvent){ + return 0; + } + WiFiEventCbList_t newEventHandler; + newEventHandler.cb = NULL; + newEventHandler.fcb = NULL; + newEventHandler.scb = NULL; + newEventHandler.provcb = cbEvent; + newEventHandler.event = event; + cbEventList.push_back(newEventHandler); + return newEventHandler.id; +} wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t event) { if(!cbEvent) { @@ -239,6 +275,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventCb cbEvent, system_event_id_t newEventHandler.cb = cbEvent; newEventHandler.fcb = NULL; newEventHandler.scb = NULL; + newEventHandler.provcb = NULL; newEventHandler.event = event; cbEventList.push_back(newEventHandler); return newEventHandler.id; @@ -253,6 +290,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventFuncCb cbEvent, system_event_ newEventHandler.cb = NULL; newEventHandler.fcb = cbEvent; newEventHandler.scb = NULL; + newEventHandler.provcb = NULL; newEventHandler.event = event; cbEventList.push_back(newEventHandler); return newEventHandler.id; @@ -267,6 +305,7 @@ wifi_event_id_t WiFiGenericClass::onEvent(WiFiEventSysCb cbEvent, system_event_i newEventHandler.cb = NULL; newEventHandler.fcb = NULL; newEventHandler.scb = cbEvent; + newEventHandler.provcb = NULL; newEventHandler.event = event; cbEventList.push_back(newEventHandler); return newEventHandler.id; @@ -326,8 +365,11 @@ const char * system_event_names[] = { "WIFI_READY", "SCAN_DONE", "STA_START", "S const char * system_event_reasons[] = { "UNSPECIFIED", "AUTH_EXPIRE", "AUTH_LEAVE", "ASSOC_EXPIRE", "ASSOC_TOOMANY", "NOT_AUTHED", "NOT_ASSOCED", "ASSOC_LEAVE", "ASSOC_NOT_AUTHED", "DISASSOC_PWRCAP_BAD", "DISASSOC_SUPCHAN_BAD", "UNSPECIFIED", "IE_INVALID", "MIC_FAILURE", "4WAY_HANDSHAKE_TIMEOUT", "GROUP_KEY_UPDATE_TIMEOUT", "IE_IN_4WAY_DIFFERS", "GROUP_CIPHER_INVALID", "PAIRWISE_CIPHER_INVALID", "AKMP_INVALID", "UNSUPP_RSN_IE_VERSION", "INVALID_RSN_IE_CAP", "802_1X_AUTH_FAILED", "CIPHER_SUITE_REJECTED", "BEACON_TIMEOUT", "NO_AP_FOUND", "AUTH_FAIL", "ASSOC_FAIL", "HANDSHAKE_TIMEOUT", "CONNECTION_FAIL" }; #define reason2str(r) ((r>176)?system_event_reasons[r-176]:system_event_reasons[r-1]) #endif -esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event) +esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event, wifi_prov_event_t *prov_event) { + if(WiFi.isProvEnabled()) { + wifi_prov_mgr_event_handler(arg,event); + } if(event->event_id < 26) { log_d("Event: %d - %s", event->event_id, system_event_names[event->event_id]); } @@ -422,7 +464,7 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event) setStatusBits(ETH_CONNECTED_BIT | ETH_HAS_IP6_BIT); } } - + for(uint32_t i = 0; i < cbEventList.size(); i++) { WiFiEventCbList_t entry = cbEventList[i]; if(entry.cb || entry.fcb || entry.scb) { @@ -436,6 +478,10 @@ esp_err_t WiFiGenericClass::_eventCallback(void *arg, system_event_t *event) } } } + + if(entry.provcb) { + entry.provcb(event,prov_event); + } } return ESP_OK; } diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index 65f5d23b..364a685d 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -27,10 +27,25 @@ #include #include #include "WiFiType.h" +#include "IPAddress.h" +#include + +typedef struct +{ + wifi_prov_cb_event_t event; + void *event_data; +}wifi_prov_event_t; + +typedef struct +{ + wifi_prov_event_t *prov_event; + system_event_t *sys_event; +}system_prov_event_t; typedef void (*WiFiEventCb)(system_event_id_t event); typedef std::function WiFiEventFuncCb; typedef void (*WiFiEventSysCb)(system_event_t *event); +typedef void (*WiFiProvEventCb)(system_event_t *sys_event, wifi_prov_event_t *prov_event); typedef size_t wifi_event_id_t; @@ -73,6 +88,7 @@ class WiFiGenericClass wifi_event_id_t onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); + wifi_event_id_t onEvent(WiFiProvEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); void removeEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); void removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX); void removeEvent(wifi_event_id_t id); @@ -97,7 +113,7 @@ class WiFiGenericClass bool setTxPower(wifi_power_t power); wifi_power_t getTxPower(); - static esp_err_t _eventCallback(void *arg, system_event_t *event); + static esp_err_t _eventCallback(void *arg, system_event_t *event, wifi_prov_event_t *prov_event); protected: static bool _persistent; diff --git a/libraries/WiFi/src/WiFiProv.cpp b/libraries/WiFi/src/WiFiProv.cpp new file mode 100644 index 00000000..d7631785 --- /dev/null +++ b/libraries/WiFi/src/WiFiProv.cpp @@ -0,0 +1,157 @@ +/* + WiFiProv.cpp - WiFiProv class for provisioning + All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#undef IPADDR_NONE +#include "WiFi.h" + +extern esp_err_t postToSysQueue(system_prov_event_t *); +static const uint8_t custom_service_uuid[16] = { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, + 0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02, }; + +#define SERV_NAME_PREFIX_BLE "BLE_" +#define SERV_NAME_PREFIX_WIFI "WIFI_" + +bool WiFiProvClass::prov_enable = true; + +bool WiFiProvClass::isProvEnabled() +{ + return prov_enable; +} + +static void prov_event_handler(void *user_data, wifi_prov_cb_event_t event, void *event_data) +{ + if (!event) { + return; + } + + system_prov_event_t *sys_prov = (system_prov_event_t *)malloc(sizeof(system_prov_event_t)); + if(sys_prov == NULL) { + log_e("Malloc Failed"); + return; + } + + sys_prov->prov_event = (wifi_prov_event_t *)malloc(sizeof(wifi_prov_event_t)); + if(sys_prov->prov_event == NULL) { + log_e("Malloc Failed"); + free(sys_prov); + return; + } + + sys_prov->sys_event = (system_event_t *)malloc(sizeof(system_event_t)); + if(sys_prov->sys_event == NULL) { + log_e("Malloc Failed"); + free(sys_prov->prov_event); + free(sys_prov); + return; + } + + sys_prov->prov_event->event = event; + sys_prov->prov_event->event_data = event_data; + sys_prov->sys_event->event_id = SYSTEM_EVENT_MAX; + esp_err_t check = postToSysQueue(sys_prov); + if(check == ESP_FAIL) { + log_e("Provisioning event not send to queue"); + free(sys_prov->sys_event); + free(sys_prov->prov_event); + free(sys_prov); + } +} + +static void get_device_service_name(scheme prov_scheme, char *service_name, size_t max) +{ + uint8_t eth_mac[6]; + WiFi.macAddress(eth_mac); + if(prov_scheme == WIFI_PROV_SCHEME_BLE) { + snprintf(service_name, max, "%s%02X%02X%02X",SERV_NAME_PREFIX_BLE, eth_mac[3], eth_mac[4], eth_mac[5]); + } else { + snprintf(service_name, max, "%s%02X%02X%02X",SERV_NAME_PREFIX_WIFI, eth_mac[3], eth_mac[4], eth_mac[5]); + } +} + +void WiFiProvClass :: beginProvision(scheme prov_scheme, wifi_prov_event_handler_t scheme_event_handler, wifi_prov_security_t security, const char * pop, const char *service_name, const char *service_key, uint8_t * uuid) +{ + prov_enable = true; + bool provisioned = false; + wifi_prov_mgr_config_t config; + config.scheme_event_handler = scheme_event_handler; + config.app_event_handler = { + .event_cb = prov_event_handler, + .user_data = NULL + }; + + if(prov_scheme == WIFI_PROV_SCHEME_BLE) { + config.scheme = wifi_prov_scheme_ble; + } else { + config.scheme = wifi_prov_scheme_softap; + } + + wifi_prov_mgr_init(config); + WiFi.mode(WIFI_MODE_AP); + wifi_prov_mgr_is_provisioned(&provisioned); + if(provisioned == false) { + if(prov_scheme == WIFI_PROV_SCHEME_BLE) { + service_key = NULL; + if(uuid == NULL) { + uuid=(uint8_t *)custom_service_uuid; + } + wifi_prov_scheme_ble_set_service_uuid(uuid); + } + + if(service_name == NULL) { + char service_name_temp[12]; + get_device_service_name(prov_scheme,service_name_temp,sizeof(service_name_temp)); + service_name = (const char *)service_name_temp; + } + + if(prov_scheme == WIFI_PROV_SCHEME_BLE) { + log_i("Starting AP using BLE\n service_name : %s\n pop : %s",service_name,pop); + + } else { + if(service_key == NULL) { + log_i("Starting AP using SOFTAP\n service_name : %s\n pop : %s",service_name,pop); + } else { + log_i("Starting AP using SOFTAP\n service_name : %s\n password : %s\n pop : %s",service_name,service_key,pop); + } + } + + wifi_prov_mgr_start_provisioning(security,pop,service_name,service_key); + + } else { + wifi_prov_mgr_deinit(); + WiFi.mode(WIFI_MODE_STA); + log_i("Aleardy Provisioned, starting Wi-Fi STA"); + log_i("CONNECTING ACCESS POINT CREDENTIALS : "); + log_i("SSID : %s\n",WiFi.SSID().c_str()); + } +} + diff --git a/libraries/WiFi/src/WiFiProv.h b/libraries/WiFi/src/WiFiProv.h new file mode 100644 index 00000000..6492c4dd --- /dev/null +++ b/libraries/WiFi/src/WiFiProv.h @@ -0,0 +1,55 @@ +/* + WiFiProv.h - Base class for provisioning support + All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "wifi_provisioning/manager.h" +#include "wifi_provisioning/scheme_ble.h" +#include "esp_wifi.h" +#include "nvs_flash.h" +#include "SimpleBLE.h" +//Select the scheme using which you want to provision +enum scheme +{ + WIFI_PROV_SCHEME_BLE, + WIFI_PROV_SCHEME_SOFTAP, + WIFI_PROV_SCHEME_CONSOLE +}; +//Provisioning class +class WiFiProvClass +{ + protected: + static bool prov_enable; + + public: + WiFiProvClass() { + prov_enable = false; + } + + bool isProvEnabled(); + + void beginProvision(scheme prov_scheme = WIFI_PROV_SCHEME_SOFTAP, wifi_prov_event_handler_t scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE, wifi_prov_security_t security = WIFI_PROV_SECURITY_1, const char * pop = "abcd1234", const char * service_name = NULL, const char * service_key = NULL, uint8_t *uuid = NULL); +}; + +/* + Event Handler for BLE + - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM + - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE + - WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT +Event Handler for SOFTAP + - WIFI_PROV_EVENT_HANDLER_NONE +*/ From 4d118b36a29684e65425716632110b23c34ee85a Mon Sep 17 00:00:00 2001 From: sweetymhaiske Date: Tue, 21 Apr 2020 17:09:26 +0530 Subject: [PATCH 10/13] Minor modifications in provisioning (#3919) --- libraries/WiFi/examples/WiFiProv/README.md | 29 ++++++++-------------- libraries/WiFi/src/WiFiProv.cpp | 6 ++++- 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/libraries/WiFi/examples/WiFiProv/README.md b/libraries/WiFi/examples/WiFiProv/README.md index 2816381f..3c0c5dfe 100644 --- a/libraries/WiFi/examples/WiFiProv/README.md +++ b/libraries/WiFi/examples/WiFiProv/README.md @@ -6,11 +6,11 @@ This sketch implements provisioning using various IDF components This example allows Arduino user to choose either BLE or SOFTAP as a mode of transport, over which the provisioning related communication is to take place, between the device (to be provisioned) and the client (owner of the device). -## API's introduced for provisioning +# APIs introduced for provisioning ## WiFi.onEvent() -Using this API user can register to recieve WIFI Events and Provisioning Events +Using this API user can register to receive WiFi Events and Provisioning Events #### Parameters passed @@ -22,11 +22,11 @@ A function with following signature * wifi_prov_cb_event_t event; * void * event_data; -### WiFi.beginProvision() +## WiFi.beginProvision() WiFi.beginProvision(scheme prov_scheme, wifi_prov_scheme_event_handler_t scheme_event_handler, wifi_prov_security_t security, char * pop, char * service_name, char * service_key, uint8_t * uuid); -#### Parameters +#### Parameters passed * prov_scheme : choose the mode of transfer * WIFI_PROV_SCHEME_BLE - Using BLE @@ -46,11 +46,11 @@ WiFi.beginProvision(scheme prov_scheme, wifi_prov_scheme_event_handler_t scheme_ * SoftAp : - WIFI_PROV_EVENT_HANDLER_NONE -* pop : It is the string that is used to provide the authentication while provisioning +* pop : It is the string that is used to provide the authentication. -* service_name : Specify service name for the device while provisioning, if it is not specified then default chosen name via SoftAP is WIFI_XXX and for BLE service it is BLE_XXX where XXX is the last 3 bytes of the MAC address. +* service_name : Specify service name for the device, if it is not specified then default chosen name via SoftAP is WIFI_XXX and via BLE is BLE_XXX where XXX are the last 3 bytes of the MAC address. -* service_key : Specify service key while provisioning, if chosen mode of provisioning is BLE then service_key is always NULL +* service_key : Specify service key, if chosen mode of provisioning is BLE then service_key is always NULL * uuid : user can specify there own 128 bit UUID while provisioning using BLE, if not specified then default value taken is - { 0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf, @@ -63,24 +63,15 @@ WiFi.beginProvision(scheme prov_scheme, wifi_prov_scheme_event_handler_t scheme_ * scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE * security = WIFI_PROV_SECURITY_1 * pop = "abcd1234" - * service_name = "WiFi_XXX" + * service_name = "WiFi_XXX" * service_key = NULL * uuid = NULL # Log Output * Enable debuger : [ Tools -> Core Debug Level -> Info ] -# App required for provisioning - -##Gihub link - -* Android : (https://github.com/espressif/esp-idf-provisioning-android) -* iOS : (https://github.com/espressif/esp-idf-provisioning-ios) - -## These apps are available on playstore - -* For SoftAP : ESP SoftAP Prov -* For BLE : ESP BLE Prov +# Provisioning Tools +https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/provisioning/wifi_provisioning.html#provisioning-tools # Example output diff --git a/libraries/WiFi/src/WiFiProv.cpp b/libraries/WiFi/src/WiFiProv.cpp index d7631785..1296efe8 100644 --- a/libraries/WiFi/src/WiFiProv.cpp +++ b/libraries/WiFi/src/WiFiProv.cpp @@ -151,7 +151,11 @@ void WiFiProvClass :: beginProvision(scheme prov_scheme, wifi_prov_event_handler WiFi.mode(WIFI_MODE_STA); log_i("Aleardy Provisioned, starting Wi-Fi STA"); log_i("CONNECTING ACCESS POINT CREDENTIALS : "); - log_i("SSID : %s\n",WiFi.SSID().c_str()); +#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_INFO + wifi_config_t conf; + esp_wifi_get_config(WIFI_IF_STA,&conf); + log_i("SSID : %s\n",conf.sta.ssid); +#endif } } From c8215315aef8a11529743dd403f2e894350ad547 Mon Sep 17 00:00:00 2001 From: Gitshaoxiang <45260108+Gitshaoxiang@users.noreply.github.com> Date: Thu, 23 Apr 2020 06:39:31 -0400 Subject: [PATCH 11/13] Add M5Stack-ATOM Board (#3883) * Add M5Stack-ATOM Board * Add M5Stack-ATOM Board * Add M5Stack-ATOM Board Co-authored-by: Me No Dev --- boards.txt | 61 ++++++++++++++++++++++++++++ variants/m5stack_atom/pins_arduino.h | 45 ++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 variants/m5stack_atom/pins_arduino.h diff --git a/boards.txt b/boards.txt index 2a524dfc..d1c5dc6f 100644 --- a/boards.txt +++ b/boards.txt @@ -2491,6 +2491,67 @@ m5stick-c.menu.DebugLevel.debug.build.code_debug=4 m5stick-c.menu.DebugLevel.verbose=Verbose m5stick-c.menu.DebugLevel.verbose.build.code_debug=5 +############################################################## + +m5stack-atom.name=M5Stack-ATOM + +m5stack-atom.upload.tool=esptool_py +m5stack-atom.upload.maximum_size=1310720 +m5stack-atom.upload.maximum_data_size=327680 +m5stack-atom.upload.wait_for_upload_port=true + +m5stack-atom.serial.disableDTR=true +m5stack-atom.serial.disableRTS=true + +m5stack-atom.build.mcu=esp32 +m5stack-atom.build.core=esp32 +m5stack-atom.build.variant=m5stack_atom +m5stack-atom.build.board=M5Stack_ATOM + +m5stack-atom.build.f_cpu=240000000L +m5stack-atom.build.flash_size=4MB +m5stack-atom.build.flash_freq=80m +m5stack-atom.build.flash_mode=dio +m5stack-atom.build.boot=dio +m5stack-atom.build.partitions=default +m5stack-atom.build.defines= + +m5stack-atom.menu.PartitionScheme.default=Default +m5stack-atom.menu.PartitionScheme.default.build.partitions=default +m5stack-atom.menu.PartitionScheme.no_ota=No OTA (Large APP) +m5stack-atom.menu.PartitionScheme.no_ota.build.partitions=no_ota +m5stack-atom.menu.PartitionScheme.no_ota.upload.maximum_size=2097152 +m5stack-atom.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (Large APPS with OTA) +m5stack-atom.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs +m5stack-atom.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080 + + +m5stack-atom.menu.UploadSpeed.1500000=1500000 +m5stack-atom.menu.UploadSpeed.1500000.upload.speed=1500000 +m5stack-atom.menu.UploadSpeed.750000=750000 +m5stack-atom.menu.UploadSpeed.750000.upload.speed=750000 +m5stack-atom.menu.UploadSpeed.500000=500000 +m5stack-atom.menu.UploadSpeed.500000.upload.speed=500000 +m5stack-atom.menu.UploadSpeed.250000=250000 +m5stack-atom.menu.UploadSpeed.250000.upload.speed=250000 +m5stack-atom.menu.UploadSpeed.115200=115200 +m5stack-atom.menu.UploadSpeed.115200.upload.speed=115200 + + + +m5stack-atom.menu.DebugLevel.none=None +m5stack-atom.menu.DebugLevel.none.build.code_debug=0 +m5stack-atom.menu.DebugLevel.error=Error +m5stack-atom.menu.DebugLevel.error.build.code_debug=1 +m5stack-atom.menu.DebugLevel.warn=Warn +m5stack-atom.menu.DebugLevel.warn.build.code_debug=2 +m5stack-atom.menu.DebugLevel.info=Info +m5stack-atom.menu.DebugLevel.info.build.code_debug=3 +m5stack-atom.menu.DebugLevel.debug=Debug +m5stack-atom.menu.DebugLevel.debug.build.code_debug=4 +m5stack-atom.menu.DebugLevel.verbose=Verbose +m5stack-atom.menu.DebugLevel.verbose.build.code_debug=5 + ############################################################## diff --git a/variants/m5stack_atom/pins_arduino.h b/variants/m5stack_atom/pins_arduino.h new file mode 100644 index 00000000..30c52452 --- /dev/null +++ b/variants/m5stack_atom/pins_arduino.h @@ -0,0 +1,45 @@ +#ifndef Pins_Arduino_h +#define Pins_Arduino_h + +#include + +#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 = 26; +static const uint8_t SCL = 32; + + +static const uint8_t G12 = 12; +static const uint8_t G19 = 19; +static const uint8_t G22 = 21; +static const uint8_t G22 = 22; +static const uint8_t G23 = 23; +static const uint8_t G25 = 25; +static const uint8_t G26 = 26; +static const uint8_t G27 = 27; +static const uint8_t G32 = 32; +static const uint8_t G33 = 33; +static const uint8_t G39 = 39; + +static const uint8_t G9 = 9; +static const uint8_t G10 = 10; +static const uint8_t G37 = 37; +static const uint8_t G36 = 36; +static const uint8_t G0 = 0; + +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 */ From 5d9bb5cf5070f269cd72c22d253f3df7a9902b18 Mon Sep 17 00:00:00 2001 From: Valerii Koval Date: Mon, 4 May 2020 16:47:14 +0300 Subject: [PATCH 12/13] Allow using custom linker scripts (#3735) Co-authored-by: Ivan Kravets --- tools/platformio-build.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/platformio-build.py b/tools/platformio-build.py index 60e9402e..ec8d241a 100644 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -184,6 +184,9 @@ env.Append( ] ) +if not env.BoardConfig().get("build.ldscript", ""): + env.Replace(LDSCRIPT_PATH=env.BoardConfig().get("build.arduino.ldscript", "")) + # # Target: Build Core Library # From 49b76649f13acdb8abaf795015d2740bc5f6b340 Mon Sep 17 00:00:00 2001 From: hreintke Date: Tue, 5 May 2020 16:55:58 +0200 Subject: [PATCH 13/13] HardwareSerial bugfix & improvement (#3713) Co-authored-by: Me No Dev --- cores/esp32/esp32-hal-uart.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index 8ec1fe6f..26652846 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -85,7 +85,7 @@ static void IRAM_ATTR _uart_isr(void *arg) uart->dev->int_clr.rxfifo_tout = 1; while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { c = uart->dev->fifo.rw_byte; - if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) { + if(uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } } @@ -285,10 +285,18 @@ void uartRxFifoToQueue(uart_t* uart) { uint8_t c; UART_MUTEX_LOCK(); - while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { - c = uart->dev->fifo.rw_byte; - xQueueSend(uart->queue, &c, 0); - } + //disable interrupts + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; + while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { + c = uart->dev->fifo.rw_byte; + xQueueSend(uart->queue, &c, 0); + } + //enable interrupts + uart->dev->int_ena.rxfifo_full = 1; + uart->dev->int_ena.frm_err = 1; + uart->dev->int_ena.rxfifo_tout = 1; + uart->dev->int_clr.val = 0xffffffff; UART_MUTEX_UNLOCK(); }