Compare commits

..

7 Commits

Author SHA1 Message Date
44c11981d2 Added UM FeatherS2 Neo to boards.txt and added appropriate variants. (#5615) 2021-08-31 09:28:56 +03:00
9eea85f9ff Check if m_pServerCallbacks is not null before calling method. (#5603)
Fixes: https://github.com/espressif/arduino-esp32/issues/5573

To reproduce:
1. Run any sample code that starts a BLE server, and does not call `setCallbacks`.
2. Connect to the device using the "LightBlue" app on iOS.
3. Observe crash shown in the issue linked above.
2021-08-31 09:20:02 +03:00
24b76cbb14 Add string constructor and concat routines taking explicit length args (#5586)
## Summary
Applies the upstream changes here: https://github.com/arduino/ArduinoCore-API/compare/3b88acac8%5E...0d83f1afc3367037dbde5323c2abd0ae1bd2c583

## Impact
Adds new String convenience methods that are now available in the mainline Arduino implementation, simplifying interoperability with C code that uses pointer+length strings rather than 0-termination. Also includes a change to avoid mutating the source string when taking a substring.
2021-08-31 09:12:27 +03:00
4a55ff970d Add support for the hardware CDC in ESP32-C3 (#5614)
* Add support for the hardware CDC in ESP32-C3
2021-08-31 08:47:55 +03:00
a62979d8a0 Add missing upload.flags (#5589) 2021-08-25 10:40:13 +03:00
1f59c5abec Adds HardwareSerial::setRxBufferSize() (#5583)
* Adds rxBufferSize parameter to begin()

* Adds HardwareSerial::setRXBufferSize()
2021-08-24 08:21:20 +03:00
0730e0ec93 Include nvs_commit() on three methods (#5309)
* Include nvs_commit() on three methods

In [Preferences.cpp](https://github.com/espressif/arduino-esp32/blob/master/libraries/Preferences/src/Preferences.cpp),  the functions:
```
Preferences::clear()
Preferences::remove()
Preferences::end()
```
should be revised to include a call to 
`nvs_commit()`
as required per 
[Non-volatile storage library](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_flash.html)
when using 
```
nvs_erase_all()
nvs_erase_key()
nvs_close()
```
2021-08-23 21:23:42 +03:00
12 changed files with 657 additions and 19 deletions

View File

@ -32,6 +32,7 @@ set(CORE_SRCS
cores/esp32/stdlib_noniso.c
cores/esp32/Stream.cpp
cores/esp32/StreamString.cpp
cores/esp32/HWCDC.cpp
cores/esp32/USB.cpp
cores/esp32/USBCDC.cpp
cores/esp32/USBMSC.cpp

View File

@ -21,12 +21,16 @@ menu.EventsCore=Events Run On
##############################################################
esp32c3.name=ESP32C3 Dev Module
esp32c3.vid.0=0x303a
esp32c3.pid.0=0x1001
esp32c3.upload.tool=esptool_py
esp32c3.upload.maximum_size=1310720
esp32c3.upload.maximum_data_size=327680
esp32c3.upload.flags=
esp32c3.upload.extra_flags=
esp32c3.upload.use_1200bps_touch=false
esp32c3.upload.wait_for_upload_port=false
esp32c3.serial.disableDTR=false
esp32c3.serial.disableRTS=false
@ -48,6 +52,18 @@ esp32c3.build.boot=qio
esp32c3.build.partitions=default
esp32c3.build.defines=
esp32c3.menu.CDCOnBoot.default=Disabled
esp32c3.menu.CDCOnBoot.default.build.cdc_on_boot=0
esp32c3.menu.CDCOnBoot.cdc=Enabled
esp32c3.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
esp32c3.menu.UploadMode.default=UART0
esp32c3.menu.UploadMode.default.upload.use_1200bps_touch=false
esp32c3.menu.UploadMode.default.upload.wait_for_upload_port=false
esp32c3.menu.UploadMode.cdc=Internal USB
esp32c3.menu.UploadMode.cdc.upload.use_1200bps_touch=true
esp32c3.menu.UploadMode.cdc.upload.wait_for_upload_port=true
esp32c3.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
esp32c3.menu.PartitionScheme.default.build.partitions=default
esp32c3.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
@ -977,7 +993,7 @@ feathers2.build.variant=um_feathers2
feathers2.build.board=FEATHERS2
feathers2.build.cdc_on_boot=1
feathers2.build.msc_on_boot=1
feathers2.build.msc_on_boot=0
feathers2.build.dfu_on_boot=0
feathers2.build.f_cpu=240000000L
feathers2.build.flash_size=16MB
@ -992,10 +1008,10 @@ feathers2.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
feathers2.menu.CDCOnBoot.default=Disabled
feathers2.menu.CDCOnBoot.default.build.cdc_on_boot=0
feathers2.menu.MSCOnBoot.msc=Enabled
feathers2.menu.MSCOnBoot.msc.build.msc_on_boot=1
feathers2.menu.MSCOnBoot.default=Disabled
feathers2.menu.MSCOnBoot.default.build.msc_on_boot=0
feathers2.menu.MSCOnBoot.msc=Enabled
feathers2.menu.MSCOnBoot.msc.build.msc_on_boot=1
feathers2.menu.DFUOnBoot.default=Disabled
feathers2.menu.DFUOnBoot.default.build.dfu_on_boot=0
@ -1092,7 +1108,131 @@ feathers2.menu.DebugLevel.verbose=Verbose
feathers2.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
feathers2neo.name=UM FeatherS2 Neo
feathers2neo.vid.0=0x303a
feathers2neo.pid.0=0x80B4
feathers2neo.upload.tool=esptool_py
feathers2neo.upload.maximum_size=1310720
feathers2neo.upload.maximum_data_size=327680
feathers2neo.upload.flags=
feathers2neo.upload.extra_flags=
feathers2neo.upload.use_1200bps_touch=true
feathers2neo.upload.wait_for_upload_port=true
feathers2neo.serial.disableDTR=false
feathers2neo.serial.disableRTS=false
feathers2neo.build.tarch=xtensa
feathers2neo.build.bootloader_addr=0x1000
feathers2neo.build.target=esp32s2
feathers2neo.build.mcu=esp32s2
feathers2neo.build.core=esp32
feathers2neo.build.variant=um_feathers2neo
feathers2neo.build.board=FEATHERS2NEO
feathers2neo.build.cdc_on_boot=1
feathers2neo.build.msc_on_boot=0
feathers2neo.build.dfu_on_boot=0
feathers2neo.build.f_cpu=240000000L
feathers2neo.build.flash_size=4MB
feathers2neo.build.flash_freq=80m
feathers2neo.build.flash_mode=dio
feathers2neo.build.boot=qio
feathers2neo.build.partitions=default
feathers2neo.build.defines=
feathers2neo.menu.CDCOnBoot.cdc=Enabled
feathers2neo.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
feathers2neo.menu.CDCOnBoot.default=Disabled
feathers2neo.menu.CDCOnBoot.default.build.cdc_on_boot=0
feathers2neo.menu.MSCOnBoot.default=Disabled
feathers2neo.menu.MSCOnBoot.default.build.msc_on_boot=0
feathers2neo.menu.MSCOnBoot.msc=Enabled
feathers2neo.menu.MSCOnBoot.msc.build.msc_on_boot=1
feathers2neo.menu.DFUOnBoot.default=Disabled
feathers2neo.menu.DFUOnBoot.default.build.dfu_on_boot=0
feathers2neo.menu.DFUOnBoot.dfu=Enabled
feathers2neo.menu.DFUOnBoot.dfu.build.dfu_on_boot=1
feathers2neo.menu.PSRAM.enabled=Enabled
feathers2neo.menu.PSRAM.enabled.build.defines=-DBOARD_HAS_PSRAM
feathers2neo.menu.PSRAM.disabled=Disabled
feathers2neo.menu.PSRAM.disabled.build.defines=
feathers2neo.menu.PartitionScheme.default=Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)
feathers2neo.menu.PartitionScheme.default.build.partitions=default
feathers2neo.menu.PartitionScheme.defaultffat=Default 4MB with ffat (1.2MB APP/1.5MB FATFS)
feathers2neo.menu.PartitionScheme.defaultffat.build.partitions=default_ffat
feathers2neo.menu.PartitionScheme.minimal=Minimal (1.3MB APP/700KB SPIFFS)
feathers2neo.menu.PartitionScheme.minimal.build.partitions=minimal
feathers2neo.menu.PartitionScheme.no_ota=No OTA (2MB APP/2MB SPIFFS)
feathers2neo.menu.PartitionScheme.no_ota.build.partitions=no_ota
feathers2neo.menu.PartitionScheme.no_ota.upload.maximum_size=2097152
feathers2neo.menu.PartitionScheme.noota_3g=No OTA (1MB APP/3MB SPIFFS)
feathers2neo.menu.PartitionScheme.noota_3g.build.partitions=noota_3g
feathers2neo.menu.PartitionScheme.noota_3g.upload.maximum_size=1048576
feathers2neo.menu.PartitionScheme.noota_ffat=No OTA (2MB APP/2MB FATFS)
feathers2neo.menu.PartitionScheme.noota_ffat.build.partitions=noota_ffat
feathers2neo.menu.PartitionScheme.noota_ffat.upload.maximum_size=2097152
feathers2neo.menu.PartitionScheme.noota_3gffat=No OTA (1MB APP/3MB FATFS)
feathers2neo.menu.PartitionScheme.noota_3gffat.build.partitions=noota_3gffat
feathers2neo.menu.PartitionScheme.noota_3gffat.upload.maximum_size=1048576
feathers2neo.menu.PartitionScheme.huge_app=Huge APP (3MB No OTA/1MB SPIFFS)
feathers2neo.menu.PartitionScheme.huge_app.build.partitions=huge_app
feathers2neo.menu.PartitionScheme.huge_app.upload.maximum_size=3145728
feathers2neo.menu.PartitionScheme.min_spiffs=Minimal SPIFFS (1.9MB APP with OTA/190KB SPIFFS)
feathers2neo.menu.PartitionScheme.min_spiffs.build.partitions=min_spiffs
feathers2neo.menu.PartitionScheme.min_spiffs.upload.maximum_size=1966080
feathers2neo.menu.CPUFreq.240=240MHz (WiFi)
feathers2neo.menu.CPUFreq.240.build.f_cpu=240000000L
feathers2neo.menu.CPUFreq.160=160MHz (WiFi)
feathers2neo.menu.CPUFreq.160.build.f_cpu=160000000L
feathers2neo.menu.CPUFreq.80=80MHz (WiFi)
feathers2neo.menu.CPUFreq.80.build.f_cpu=80000000L
feathers2neo.menu.CPUFreq.40=40MHz
feathers2neo.menu.CPUFreq.40.build.f_cpu=40000000L
feathers2neo.menu.CPUFreq.20=20MHz
feathers2neo.menu.CPUFreq.20.build.f_cpu=20000000L
feathers2neo.menu.CPUFreq.10=10MHz
feathers2neo.menu.CPUFreq.10.build.f_cpu=10000000L
feathers2neo.menu.FlashSize.4M=4MB (32Mb)
feathers2neo.menu.FlashSize.4M.build.flash_size=4MB
feathers2neo.menu.FlashSize.2M=2MB (16Mb)
feathers2neo.menu.FlashSize.2M.build.flash_size=2MB
feathers2neo.menu.FlashSize.2M.build.partitions=minimal
feathers2neo.menu.UploadSpeed.921600=921600
feathers2neo.menu.UploadSpeed.921600.upload.speed=921600
feathers2neo.menu.UploadSpeed.115200=115200
feathers2neo.menu.UploadSpeed.115200.upload.speed=115200
feathers2neo.menu.UploadSpeed.256000.windows=256000
feathers2neo.menu.UploadSpeed.256000.upload.speed=256000
feathers2neo.menu.UploadSpeed.230400.windows.upload.speed=256000
feathers2neo.menu.UploadSpeed.230400=230400
feathers2neo.menu.UploadSpeed.230400.upload.speed=230400
feathers2neo.menu.UploadSpeed.460800.linux=460800
feathers2neo.menu.UploadSpeed.460800.macosx=460800
feathers2neo.menu.UploadSpeed.460800.upload.speed=460800
feathers2neo.menu.DebugLevel.none=None
feathers2neo.menu.DebugLevel.none.build.code_debug=0
feathers2neo.menu.DebugLevel.error=Error
feathers2neo.menu.DebugLevel.error.build.code_debug=1
feathers2neo.menu.DebugLevel.warn=Warn
feathers2neo.menu.DebugLevel.warn.build.code_debug=2
feathers2neo.menu.DebugLevel.info=Info
feathers2neo.menu.DebugLevel.info.build.code_debug=3
feathers2neo.menu.DebugLevel.debug=Debug
feathers2neo.menu.DebugLevel.debug.build.code_debug=4
feathers2neo.menu.DebugLevel.verbose=Verbose
feathers2neo.menu.DebugLevel.verbose.build.code_debug=5
##############################################################
tinys2.name=UM TinyS2
tinys2.vid.0=0x303a
tinys2.pid.0=0x8001
@ -1117,7 +1257,7 @@ tinys2.build.variant=um_tinys2
tinys2.build.board=TINYS2
tinys2.build.cdc_on_boot=1
tinys2.build.msc_on_boot=1
tinys2.build.msc_on_boot=0
tinys2.build.dfu_on_boot=0
tinys2.build.f_cpu=240000000L
tinys2.build.flash_size=4MB
@ -1132,10 +1272,10 @@ tinys2.menu.CDCOnBoot.cdc.build.cdc_on_boot=1
tinys2.menu.CDCOnBoot.default=Disabled
tinys2.menu.CDCOnBoot.default.build.cdc_on_boot=0
tinys2.menu.MSCOnBoot.msc=Enabled
tinys2.menu.MSCOnBoot.msc.build.msc_on_boot=1
tinys2.menu.MSCOnBoot.default=Disabled
tinys2.menu.MSCOnBoot.default.build.msc_on_boot=0
tinys2.menu.MSCOnBoot.msc=Enabled
tinys2.menu.MSCOnBoot.msc.build.msc_on_boot=1
tinys2.menu.DFUOnBoot.default=Disabled
tinys2.menu.DFUOnBoot.default.build.dfu_on_boot=0
@ -1204,7 +1344,6 @@ tinys2.menu.UploadSpeed.460800.linux=460800
tinys2.menu.UploadSpeed.460800.macosx=460800
tinys2.menu.UploadSpeed.460800.upload.speed=460800
tinys2.menu.DebugLevel.none=None
tinys2.menu.DebugLevel.none.build.code_debug=0
tinys2.menu.DebugLevel.error=Error
@ -1225,6 +1364,7 @@ S_ODI_Ultra.upload.tool=esptool_py
S_ODI_Ultra.upload.maximum_size=1310720
S_ODI_Ultra.upload.maximum_data_size=327680
S_ODI_Ultra.upload.wait_for_upload_port=true
S_ODI_Ultra.upload.flags=
S_ODI_Ultra.upload.extra_flags=
S_ODI_Ultra.serial.disableDTR=true
@ -2087,6 +2227,7 @@ esp32thing_plus.upload.tool=esptool_py
esp32thing_plus.upload.maximum_size=1310720
esp32thing_plus.upload.maximum_data_size=327680
esp32thing_plus.upload.wait_for_upload_port=true
esp32thing_plus.upload.flags=
esp32thing_plus.upload.extra_flags=
esp32thing_plus.serial.disableDTR=true
@ -2315,6 +2456,8 @@ esp32micromod.upload.tool=esptool_py
esp32micromod.upload.maximum_size=1310720
esp32micromod.upload.maximum_data_size=327680
esp32micromod.upload.wait_for_upload_port=true
esp32micromod.upload.flags=
esp32micromod.upload.extra_flags=
esp32micromod.serial.disableDTR=true
esp32micromod.serial.disableRTS=true
@ -2952,6 +3095,7 @@ lolin32-lite.upload.tool=esptool_py
lolin32-lite.upload.maximum_size=1310720
lolin32-lite.upload.maximum_data_size=327680
lolin32-lite.upload.wait_for_upload_port=true
lolin32-lite.upload.flags=
lolin32-lite.upload.extra_flags=
lolin32-lite.serial.disableDTR=true
@ -4567,6 +4711,7 @@ esp32doit-espduino.upload.tool=esptool
esp32doit-espduino.upload.maximum_size=1310720
esp32doit-espduino.upload.maximum_data_size=327680
esp32doit-espduino.upload.wait_for_upload_port=true
esp32doit-espduino.upload.flags=
esp32doit-espduino.upload.extra_flags=
esp32doit-espduino.serial.disableDTR=true
@ -5332,6 +5477,7 @@ m5stack-timer-cam.upload.tool=esptool_py
m5stack-timer-cam.upload.maximum_size=1310720
m5stack-timer-cam.upload.maximum_data_size=327680
m5stack-timer-cam.upload.wait_for_upload_port=true
m5stack-timer-cam.upload.flags=
m5stack-timer-cam.upload.extra_flags=
m5stack-timer-cam.serial.disableDTR=true
@ -5958,6 +6104,7 @@ heltec_wireless_stick_lite.upload.tool=esptool_py
heltec_wireless_stick_lite.upload.maximum_size=1310720
heltec_wireless_stick_lite.upload.maximum_data_size=327680
heltec_wireless_stick_lite.upload.wait_for_upload_port=true
heltec_wireless_stick_lite.upload.flags=
heltec_wireless_stick_lite.upload.extra_flags=
heltec_wireless_stick_lite.serial.disableDTR=true
@ -7926,6 +8073,7 @@ kits-edu.upload.tool=esptool_py
kits-edu.upload.maximum_size=1310720
kits-edu.upload.maximum_data_size=327680
kits-edu.upload.wait_for_upload_port=true
kits-edu.upload.flags=
kits-edu.upload.extra_flags=
kits-edu.serial.disableDTR=true
@ -8108,6 +8256,7 @@ OpenKB.upload.tool=esptool_py
OpenKB.upload.maximum_size=1310720
OpenKB.upload.maximum_data_size=327680
OpenKB.upload.wait_for_upload_port=true
OpenKB.upload.flags=
OpenKB.upload.extra_flags=
OpenKB.serial.disableDTR=true
@ -8156,6 +8305,7 @@ wifiduino32.upload.tool=esptool_py
wifiduino32.upload.maximum_size=1310720
wifiduino32.upload.maximum_data_size=327680
wifiduino32.upload.wait_for_upload_port=true
wifiduino32.upload.flags=
wifiduino32.upload.extra_flags=
wifiduino32.serial.disableDTR=true
@ -8342,6 +8492,7 @@ imbrios-logsens-v1p1.upload.tool=esptool_py
imbrios-logsens-v1p1.upload.maximum_size=1310720
imbrios-logsens-v1p1.upload.maximum_data_size=327680
imbrios-logsens-v1p1.upload.wait_for_upload_port=true
imbrios-logsens-v1p1.upload.flags=
imbrios-logsens-v1p1.upload.extra_flags=
imbrios-logsens-v1p1.serial.disableDTR=true
@ -8416,6 +8567,7 @@ healthypi4.upload.tool=esptool_py
healthypi4.upload.maximum_size=1310720
healthypi4.upload.maximum_data_size=327680
healthypi4.upload.wait_for_upload_port=true
healthypi4.upload.flags=
healthypi4.upload.extra_flags=
healthypi4.serial.disableDTR=true
@ -8487,6 +8639,7 @@ ET-Board.upload.tool=esptool_py
ET-Board.upload.maximum_size=1310720
ET-Board.upload.maximum_data_size=327680
ET-Board.upload.wait_for_upload_port=true
ET-Board.upload.flags=
ET-Board.upload.extra_flags=
ET-Board.serial.disableDTR=true
@ -8841,6 +8994,8 @@ kb32.upload.tool=esptool_py
kb32.upload.maximum_size=1310720
kb32.upload.maximum_data_size=327680
kb32.upload.wait_for_upload_port=true
kb32.upload.flags=
kb32.upload.extra_flags=
kb32.serial.disableDTR=true
kb32.serial.disableRTS=true
@ -8981,6 +9136,8 @@ deneyapkart.upload.tool=esptool_py
deneyapkart.upload.maximum_size=1310720
deneyapkart.upload.maximum_data_size=327680
deneyapkart.upload.wait_for_upload_port=true
deneyapkart.upload.flags=
deneyapkart.upload.extra_flags=
deneyapkart.serial.disableDTR=true
deneyapkart.serial.disableRTS=true

283
cores/esp32/HWCDC.cpp Normal file
View File

@ -0,0 +1,283 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "USB.h"
#if CONFIG_IDF_TARGET_ESP32C3
#include "esp32-hal.h"
#include "HWCDC.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/ringbuf.h"
#include "esp_intr_alloc.h"
#include "soc/periph_defs.h"
#include "hal/usb_serial_jtag_ll.h"
static RingbufHandle_t tx_ring_buf = NULL;
static xQueueHandle rx_queue = NULL;
static uint8_t rx_data_buf[64];
static intr_handle_t intr_handle = NULL;
static volatile bool initial_empty = false;
static void hw_cdc_isr_handler(void *arg) {
portBASE_TYPE xTaskWoken = 0;
uint32_t usbjtag_intr_status = 0;
usbjtag_intr_status = usb_serial_jtag_ll_get_intsts_mask();
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY) {
// Interrupt tells us the host picked up the data we sent.
if (usb_serial_jtag_ll_txfifo_writable() == 1) {
// We disable the interrupt here so that the interrupt won't be triggered if there is no data to send.
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
if(!initial_empty){
initial_empty = true;
//send event?
//ets_printf("CONNECTED\n");
}
size_t queued_size;
uint8_t *queued_buff = (uint8_t *)xRingbufferReceiveUpToFromISR(tx_ring_buf, &queued_size, 64);
// If the hardware fifo is avaliable, write in it. Otherwise, do nothing.
if (queued_buff != NULL) { //Although tx_queued_bytes may be larger than 0. We may have interrupt before xRingbufferSend() was called.
//Copy the queued buffer into the TX FIFO
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
usb_serial_jtag_ll_write_txfifo(queued_buff, queued_size);
usb_serial_jtag_ll_txfifo_flush();
vRingbufferReturnItemFromISR(tx_ring_buf, queued_buff, &xTaskWoken);
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
//send event?
//ets_printf("TX:%u\n", queued_size);
}
} else {
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
}
}
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT) {
// read rx buffer(max length is 64), and send avaliable data to ringbuffer.
// Ensure the rx buffer size is larger than RX_MAX_SIZE.
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT);
uint32_t rx_fifo_len = usb_serial_jtag_ll_read_rxfifo(rx_data_buf, 64);
uint32_t i=0;
for(i=0; i<rx_fifo_len; i++){
if(rx_queue == NULL || !xQueueSendFromISR(rx_queue, rx_data_buf+i, &xTaskWoken)){
break;
}
}
//send event?
//ets_printf("RX:%u/%u\n", i, rx_fifo_len);
}
if (usbjtag_intr_status & USB_SERIAL_JTAG_INTR_BUS_RESET) {
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_BUS_RESET);
initial_empty = false;
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
//ets_printf("BUS_RESET\n");
}
if (xTaskWoken == pdTRUE) {
portYIELD_FROM_ISR();
}
}
static void ARDUINO_ISR_ATTR cdc0_write_char(char c) {
if(xPortInIsrContext()){
xRingbufferSendFromISR(tx_ring_buf, (void*) (&c), 1, NULL);
} else {
xRingbufferSend(tx_ring_buf, (void*) (&c), 1, 0);
}
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
}
HWCDC::HWCDC() {
}
HWCDC::~HWCDC(){
end();
}
HWCDC::operator bool() const
{
return initial_empty;
}
void HWCDC::begin(unsigned long baud)
{
setRxBufferSize(256);//default if not preset
setTxBufferSize(256);//default if not preset
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
if(!intr_handle && esp_intr_alloc(ETS_USB_INTR_SOURCE/*ETS_USB_SERIAL_JTAG_INTR_SOURCE*/, 0, hw_cdc_isr_handler, NULL, &intr_handle) != ESP_OK){
isr_log_e("HW USB CDC failed to init interrupts");
end();
}
}
void HWCDC::end()
{
//Disable tx/rx interrupt.
usb_serial_jtag_ll_disable_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY | USB_SERIAL_JTAG_INTR_SERIAL_OUT_RECV_PKT | USB_SERIAL_JTAG_INTR_BUS_RESET);
esp_intr_free(intr_handle);
intr_handle = NULL;
setRxBufferSize(0);
setTxBufferSize(0);
}
/*
* WRITING
*/
size_t HWCDC::setTxBufferSize(size_t tx_queue_len){
if(tx_ring_buf){
if(!tx_queue_len){
vRingbufferDelete(tx_ring_buf);
tx_ring_buf = NULL;
}
return 0;
}
tx_ring_buf = xRingbufferCreate(tx_queue_len, RINGBUF_TYPE_BYTEBUF);
if(!tx_ring_buf){
return 0;
}
return tx_queue_len;
}
int HWCDC::availableForWrite(void)
{
if(tx_ring_buf == NULL){
return -1;
}
return xRingbufferGetCurFreeSize(tx_ring_buf);
}
size_t HWCDC::write(const uint8_t *buffer, size_t size)
{
// Blocking method, Sending data to ringbuffer, and handle the data in ISR.
if(xRingbufferSend(tx_ring_buf, (void*) (buffer), size, 200 / portTICK_PERIOD_MS) != pdTRUE){
log_e("Write Failed");
return 0;
}
// Now trigger the ISR to read data from the ring buffer.
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SERIAL_IN_EMPTY);
return size;
}
size_t HWCDC::write(uint8_t c)
{
return write(&c, 1);
}
void HWCDC::flush(void)
{
if(tx_ring_buf == NULL){
return;
}
UBaseType_t uxItemsWaiting = 0;
vRingbufferGetInfo(tx_ring_buf, NULL, NULL, NULL, NULL, &uxItemsWaiting);
while(uxItemsWaiting){
delay(5);
vRingbufferGetInfo(tx_ring_buf, NULL, NULL, NULL, NULL, &uxItemsWaiting);
}
}
/*
* READING
*/
size_t HWCDC::setRxBufferSize(size_t rx_queue_len){
if(rx_queue){
if(!rx_queue_len){
vQueueDelete(rx_queue);
rx_queue = NULL;
}
return 0;
}
rx_queue = xQueueCreate(rx_queue_len, sizeof(uint8_t));
if(!rx_queue){
return 0;
}
if(!tx_ring_buf){
tx_ring_buf = xRingbufferCreate(rx_queue_len, RINGBUF_TYPE_BYTEBUF);
}
return rx_queue_len;
}
int HWCDC::available(void)
{
if(rx_queue == NULL){
return -1;
}
return uxQueueMessagesWaiting(rx_queue);
}
int HWCDC::peek(void)
{
if(rx_queue == NULL){
return -1;
}
uint8_t c;
if(xQueuePeek(rx_queue, &c, 0)) {
return c;
}
return -1;
}
int HWCDC::read(void)
{
if(rx_queue == NULL){
return -1;
}
uint8_t c = 0;
if(xQueueReceive(rx_queue, &c, 0)) {
return c;
}
return -1;
}
size_t HWCDC::read(uint8_t *buffer, size_t size)
{
if(rx_queue == NULL){
return -1;
}
uint8_t c = 0;
size_t count = 0;
while(count < size && xQueueReceive(rx_queue, &c, 0)){
buffer[count++] = c;
}
return count;
}
/*
* DEBUG
*/
void HWCDC::setDebugOutput(bool en)
{
if(en) {
uartSetDebug(NULL);
ets_install_putc1((void (*)(char)) &cdc0_write_char);
} else {
ets_install_putc1(NULL);
}
}
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
HWCDC Serial;
#else
HWCDC USBSerial;
#endif
#endif /* CONFIG_TINYUSB_CDC_ENABLED */

82
cores/esp32/HWCDC.h Normal file
View File

@ -0,0 +1,82 @@
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "sdkconfig.h"
#if CONFIG_IDF_TARGET_ESP32C3
#include <inttypes.h>
#include "Stream.h"
class HWCDC: public Stream
{
public:
HWCDC();
~HWCDC();
size_t setRxBufferSize(size_t);
size_t setTxBufferSize(size_t);
void begin(unsigned long baud=0);
void end();
int available(void);
int availableForWrite(void);
int peek(void);
int read(void);
size_t read(uint8_t *buffer, size_t size);
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);
void flush(void);
inline size_t read(char * buffer, size_t size)
{
return read((uint8_t*) buffer, size);
}
inline size_t write(const char * buffer, size_t size)
{
return write((uint8_t*) buffer, size);
}
inline size_t write(const char * s)
{
return write((uint8_t*) s, strlen(s));
}
inline size_t write(unsigned long n)
{
return write((uint8_t) n);
}
inline size_t write(long n)
{
return write((uint8_t) n);
}
inline size_t write(unsigned int n)
{
return write((uint8_t) n);
}
inline size_t write(int n)
{
return write((uint8_t) n);
}
operator bool() const;
void setDebugOutput(bool);
uint32_t baudRate(){return 115200;}
};
#if ARDUINO_HW_CDC_ON_BOOT //Serial used for USB CDC
extern HWCDC Serial;
#else
extern HWCDC USBSerial;
#endif
#endif /* CONFIG_IDF_TARGET_ESP32C3 */

View File

@ -76,6 +76,8 @@ void serialEvent2(void) {}
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
HardwareSerial Serial0(0);
#elif ARDUINO_HW_CDC_ON_BOOT
HardwareSerial Serial0(0);
#else
HardwareSerial Serial(0);
#endif
@ -91,6 +93,8 @@ void serialEventRun(void)
{
#if ARDUINO_USB_CDC_ON_BOOT //Serial used for USB CDC
if(Serial0.available()) serialEvent();
#elif ARDUINO_HW_CDC_ON_BOOT
if(Serial0.available()) serialEvent();
#else
if(Serial.available()) serialEvent();
#endif
@ -103,7 +107,7 @@ void serialEventRun(void)
}
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL) {}
HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _uart(NULL), _rxBufferSize(256) {}
void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, int8_t txPin, bool invert, unsigned long timeout_ms, uint8_t rxfifo_full_thrhd)
{
@ -133,7 +137,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
}
#endif
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, 256, invert, rxfifo_full_thrhd);
_uart = uartBegin(_uart_nr, baud ? baud : 9600, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd);
if (!baud) {
// using baud rate as zero, forces it to try to detect the current baud rate in place
uartStartDetectBaudrate(_uart);
@ -147,7 +151,7 @@ void HardwareSerial::begin(unsigned long baud, uint32_t config, int8_t rxPin, in
if(detectedBaudRate) {
delay(100); // Give some time...
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, 256, invert, rxfifo_full_thrhd);
_uart = uartBegin(_uart_nr, detectedBaudRate, config, rxPin, txPin, _rxBufferSize, invert, rxfifo_full_thrhd);
} else {
log_e("Could not detect baudrate. Serial data at the port must be present within the timeout for detection to be possible");
_uart = NULL;
@ -268,3 +272,18 @@ void HardwareSerial::setPins(uint8_t rxPin, uint8_t txPin)
uartSetPins(_uart, rxPin, txPin);
}
size_t HardwareSerial::setRxBufferSize(size_t new_size) {
if (_uart) {
log_e("RX Buffer can't be resized when Serial is already running.\n");
return 0;
}
if (new_size <= SOC_UART_FIFO_LEN) {
log_e("RX Buffer must be higher than %d.\n", SOC_UART_FIFO_LEN);
return 0;
}
_rxBufferSize = new_size;
return _rxBufferSize;
}

View File

@ -50,6 +50,7 @@
#include "Stream.h"
#include "esp32-hal.h"
#include "soc/soc_caps.h"
#include "HWCDC.h"
class HardwareSerial: public Stream
{
@ -103,10 +104,12 @@ public:
void setRxInvert(bool);
void setPins(uint8_t rxPin, uint8_t txPin);
size_t setRxBufferSize(size_t new_size);
protected:
int _uart_nr;
uart_t* _uart;
size_t _rxBufferSize;
};
extern void serialEventRun(void) __attribute__((weak));
@ -119,6 +122,8 @@ extern void serialEventRun(void) __attribute__((weak));
#include "USB.h"
#include "USBCDC.h"
extern HardwareSerial Serial0;
#elif ARDUINO_HW_CDC_ON_BOOT
extern HardwareSerial Serial0;
#else
extern HardwareSerial Serial;
#endif

View File

@ -35,6 +35,12 @@ String::String(const char *cstr) {
copy(cstr, strlen(cstr));
}
String::String(const char *cstr, unsigned int length) {
init();
if (cstr)
copy(cstr, length);
}
String::String(const String &value) {
init();
*this = value;
@ -705,10 +711,7 @@ String String::substring(unsigned int left, unsigned int right) const {
return out;
if(right > len())
right = len();
char temp = buffer()[right]; // save the replaced character
wbuffer()[right] = '\0';
out = wbuffer() + left; // pointer arithmetic
wbuffer()[right] = temp; //restore character
out.copy(buffer() + left, right - left);
return out;
}

View File

@ -55,6 +55,10 @@ class String {
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const char *cstr, unsigned int length);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(const uint8_t *cstr, unsigned int length) : String((const char*)cstr, length) {}
#endif
String(const String &str);
String(const __FlashStringHelper *str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
@ -108,6 +112,8 @@ class String {
// concatenation is considered unsuccessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(const char *cstr, unsigned int length);
unsigned char concat(const uint8_t *cstr, unsigned int length) {return concat((const char*)cstr, length);}
unsigned char concat(char c);
unsigned char concat(unsigned char c);
unsigned char concat(int num);
@ -326,7 +332,6 @@ class String {
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
unsigned char concat(const char *cstr, unsigned int length);
// copy and move
String & copy(const char *cstr, unsigned int length);

View File

@ -157,7 +157,9 @@ void BLEServer::handleGATTServerEvent(esp_gatts_cb_event_t event, esp_gatt_if_t
case ESP_GATTS_MTU_EVT:
updatePeerMTU(param->mtu.conn_id, param->mtu.mtu);
m_pServerCallbacks->onMtuChanged(this, param);
if (m_pServerCallbacks != nullptr) {
m_pServerCallbacks->onMtuChanged(this, param);
}
break;
// ESP_GATTS_CONNECT_EVT

View File

@ -1,8 +1,9 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
@ -43,7 +44,7 @@ bool Preferences::begin(const char * name, bool readOnly, const char* partition_
}
err = nvs_open_from_partition(partition_label, name, readOnly ? NVS_READONLY : NVS_READWRITE, &_handle);
} else {
err = nvs_open(name, readOnly?NVS_READONLY:NVS_READWRITE, &_handle);
err = nvs_open(name, readOnly ? NVS_READONLY : NVS_READWRITE, &_handle);
}
if(err){
log_e("nvs_open failed: %s", nvs_error(err));
@ -74,6 +75,11 @@ bool Preferences::clear(){
log_e("nvs_erase_all fail: %s", nvs_error(err));
return false;
}
err = nvs_commit(_handle);
if(err){
log_e("nvs_commit fail: %s", nvs_error(err));
return false;
}
return true;
}
@ -90,6 +96,11 @@ bool Preferences::remove(const char * key){
log_e("nvs_erase_key fail: %s %s", key, nvs_error(err));
return false;
}
err = nvs_commit(_handle);
if(err){
log_e("nvs_commit fail: %s %s", key, nvs_error(err));
return false;
}
return true;
}

View File

@ -60,7 +60,7 @@ compiler.cpp.flags.esp32c3=-march=rv32imc -ffunction-sections -fdata-sections -W
compiler.S.flags.esp32c3=-ffunction-sections -fdata-sections -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -ggdb -Wno-error=format= -nostartfiles -Wno-format -Og -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -fno-jump-tables -fno-tree-switch-conversion -x assembler-with-cpp -MMD -c
compiler.c.elf.flags.esp32c3=-T memory.ld -T sections.ld -T esp32c3.rom.ld -T esp32c3.rom.api.ld -T esp32c3.rom.libgcc.ld -T esp32c3.rom.newlib.ld -T esp32c3.rom.version.ld -T esp32c3.peripherals.ld -nostartfiles -march=rv32imc --specs=nosys.specs -Wl,--cref -Wl,--gc-sections -fno-rtti -fno-lto -u _Z5setupv -u _Z4loopv -Wl,--wrap=mbedtls_mpi_exp_mod -u esp_app_desc -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -u start_app -u __ubsan_include -u __assert_func -u vfs_include_syscalls_impl -Wl,--undefined=uxTopUsedPriority -u app_main -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -Wl,--wrap=_Unwind_SetEnableExceptionFdeSorting -Wl,--wrap=__register_frame_info_bases -Wl,--wrap=__register_frame_info -Wl,--wrap=__register_frame -Wl,--wrap=__register_frame_info_table_bases -Wl,--wrap=__register_frame_info_table -Wl,--wrap=__register_frame_table -Wl,--wrap=__deregister_frame_info_bases -Wl,--wrap=__deregister_frame_info -Wl,--wrap=_Unwind_Find_FDE -Wl,--wrap=_Unwind_GetGR -Wl,--wrap=_Unwind_GetCFA -Wl,--wrap=_Unwind_GetIP -Wl,--wrap=_Unwind_GetIPInfo -Wl,--wrap=_Unwind_GetRegionStart -Wl,--wrap=_Unwind_GetDataRelBase -Wl,--wrap=_Unwind_GetTextRelBase -Wl,--wrap=_Unwind_SetIP -Wl,--wrap=_Unwind_SetGR -Wl,--wrap=_Unwind_GetLanguageSpecificData -Wl,--wrap=_Unwind_FindEnclosingFunction -Wl,--wrap=_Unwind_Resume -Wl,--wrap=_Unwind_RaiseException -Wl,--wrap=_Unwind_DeleteException -Wl,--wrap=_Unwind_ForcedUnwind -Wl,--wrap=_Unwind_Resume_or_Rethrow -Wl,--wrap=_Unwind_Backtrace -Wl,--wrap=__cxa_call_unexpected -Wl,--wrap=__gxx_personality_v0 -u __cxa_guard_dummy -u __cxx_fatal_exception
compiler.ar.flags.esp32c3=cr
build.extra_flags.esp32c3=-DARDUINO_USB_CDC_ON_BOOT=0
build.extra_flags.esp32c3=-DARDUINO_HW_CDC_ON_BOOT={build.cdc_on_boot}
#
# ESP32C3 Support End
#

View File

@ -0,0 +1,70 @@
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <stdint.h>
#define USB_VID 0x239A
#define USB_PID 0x80B4
#define USB_MANUFACTURER "Unexpected Maker"
#define USB_PRODUCT "FeatherS2 Neo"
#define USB_SERIAL ""
#define EXTERNAL_NUM_INTERRUPTS 46
#define NUM_DIGITAL_PINS 22
#define NUM_ANALOG_INPUTS 11
#define analogInputToDigitalPin(p) (((p)<20)?(esp32_adc2gpio[(p)]):-1)
#define digitalPinToInterrupt(p) (((p)<48)?(p):-1)
#define digitalPinHasPWM(p) (p < 46)
static const uint8_t TX = 43;
static const uint8_t RX = 44;
static const uint8_t SDA = 8;
static const uint8_t SCL = 9;
static const uint8_t SS = 34;
static const uint8_t MOSI = 35;
static const uint8_t MISO = 37;
static const uint8_t SDO = 35;
static const uint8_t SDI = 37;
static const uint8_t SCK = 36;
static const uint8_t A0 = 17;
static const uint8_t A1 = 18;
static const uint8_t A2 = 14;
static const uint8_t A3 = 12;
static const uint8_t A4 = 6;
static const uint8_t A5 = 5;
static const uint8_t A6 = 1;
static const uint8_t A7 = 3;
static const uint8_t A8 = 7;
static const uint8_t A9 = 10;
static const uint8_t A10 = 11;
static const uint8_t T1 = 1;
static const uint8_t T3 = 3;
static const uint8_t T5 = 5;
static const uint8_t T6 = 6;
static const uint8_t T7 = 7;
static const uint8_t T8 = 8;
static const uint8_t T9 = 9;
static const uint8_t T10 = 10;
static const uint8_t T11 = 11;
static const uint8_t T12 = 12;
static const uint8_t T14 = 14;
static const uint8_t DAC1 = 17;
static const uint8_t DAC2 = 18;
static const uint8_t NEOPIXEL_MATRIX_DATA = 21;
static const uint8_t NEOPIXEL_MATRIX_PWR = 4;
static const uint8_t NEOPIXEL_DATA = 40;
static const uint8_t NEOPIXEL_PWR = 39;
static const uint8_t VBAT_SENSE = 2;
static const uint8_t VBUS_SENSE = 34;
#endif /* Pins_Arduino_h */