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 diff --git a/CMakeLists.txt b/CMakeLists.txt index 2665c37c..67791157 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/boards.txt b/boards.txt index c35b1407..9cd9182f 100644 --- a/boards.txt +++ b/boards.txt @@ -2625,6 +2625,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 + ############################################################## @@ -4908,3 +4969,154 @@ 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 +############################################################## +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/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index 1f890598..ef2b025a 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -540,12 +540,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; #if CONFIG_IDF_TARGET_ESP32S2 @@ -559,8 +555,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) @@ -604,12 +611,8 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ } #endif - 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; @@ -620,6 +623,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; } diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index c3eea548..5def9b20 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -118,7 +118,7 @@ static void IRAM_ATTR _uart_isr(void *arg) while(uart->dev->status.rxfifo_cnt) { c = uart->dev->ahb_fifo.rw_byte; #endif - if(uart->queue != NULL && !xQueueIsQueueFullFromISR(uart->queue)) { + if(uart->queue != NULL) { xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); } } @@ -247,6 +247,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) { @@ -304,7 +309,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) @@ -315,12 +320,35 @@ uint32_t uartAvailableForWrite(uart_t* uart) return 0x7f - uart->dev->status.txfifo_cnt; } +void uartRxFifoToQueue(uart_t* uart) +{ + uint8_t c; + UART_MUTEX_LOCK(); + //disable interrupts + uart->dev->int_ena.val = 0; + uart->dev->int_clr.val = 0xffffffff; + 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(); +} + 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; } @@ -333,6 +361,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; } diff --git a/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp b/libraries/ESP32/examples/Camera/CameraWebServer/app_httpd.cpp index 9c4f11c9..a624c81f 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; diff --git a/libraries/WiFi/examples/WiFiProv/README.md b/libraries/WiFi/examples/WiFiProv/README.md new file mode 100644 index 00000000..3c0c5dfe --- /dev/null +++ b/libraries/WiFi/examples/WiFiProv/README.md @@ -0,0 +1,126 @@ +# 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). + +# APIs introduced for provisioning + +## WiFi.onEvent() + +Using this API user can register to receive 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 passed + +* 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. + +* 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, 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 ] + +# Provisioning Tools +https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/provisioning/wifi_provisioning.html#provisioning-tools + +# 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 05496050..a77bb11d 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,29 +52,47 @@ 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 void _network_event_cb(void* arg, esp_event_base_t base, int32_t id, void* data) { - if (xQueueSend(_network_event_queue, (system_event_t *)data, portMAX_DELAY) != pdPASS) { - log_w("Network Event Queue Send Failed!"); + system_event_t *event = (system_event_t *)data; + system_prov_event_t *sys_prov_data = (system_prov_event_t *)malloc(sizeof(system_prov_event_t)); + if(sys_prov_data == NULL) { + return; + } + sys_prov_data->sys_event = event; + sys_prov_data->prov_event = NULL; + if (postToSysQueue(sys_prov_data) != ESP_OK){ + free(sys_prov_data); + return; } } -// 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!"); -// return ESP_FAIL; -// } -// return ESP_OK; -// } + ESP_EVENT_DEFINE_BASE(SYSTEM_EVENT); static bool _start_network_event_task(){ @@ -88,7 +105,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; @@ -164,7 +181,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; } @@ -193,9 +210,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; @@ -250,6 +268,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) { @@ -259,6 +291,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; @@ -273,6 +306,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; @@ -287,6 +321,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; @@ -346,8 +381,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]); } @@ -442,7 +480,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) { @@ -456,6 +494,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 b4fc1c47..152c0351 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..1296efe8 --- /dev/null +++ b/libraries/WiFi/src/WiFiProv.cpp @@ -0,0 +1,161 @@ +/* + 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 : "); +#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 + } +} + 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 +*/ 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 */ 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 */