From bb096153914ddadefc4e1a8b72ef61d0bef41921 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 20 Dec 2021 10:11:53 +0200 Subject: [PATCH 1/9] Fix Arduino Core config for ESP32-S2 Fixes: https://github.com/espressif/arduino-esp32/issues/6019 --- tools/sdk/esp32s2/include/config/sdkconfig.h | 12 ++++++------ tools/sdk/esp32s2/sdkconfig | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/sdk/esp32s2/include/config/sdkconfig.h b/tools/sdk/esp32s2/include/config/sdkconfig.h index e773df7572e..f5989cb267a 100644 --- a/tools/sdk/esp32s2/include/config/sdkconfig.h +++ b/tools/sdk/esp32s2/include/config/sdkconfig.h @@ -51,14 +51,14 @@ #define CONFIG_PARTITION_TABLE_MD5 1 #define CONFIG_ENABLE_ARDUINO_DEPENDS 1 #define CONFIG_AUTOSTART_ARDUINO 1 -#define CONFIG_ARDUINO_RUN_CORE1 1 -#define CONFIG_ARDUINO_RUNNING_CORE 1 +#define CONFIG_ARDUINO_RUN_CORE0 1 +#define CONFIG_ARDUINO_RUNNING_CORE 0 #define CONFIG_ARDUINO_LOOP_STACK_SIZE 8192 -#define CONFIG_ARDUINO_EVENT_RUN_CORE1 1 -#define CONFIG_ARDUINO_EVENT_RUNNING_CORE 1 -#define CONFIG_ARDUINO_UDP_RUN_CORE1 1 +#define CONFIG_ARDUINO_EVENT_RUN_CORE0 1 +#define CONFIG_ARDUINO_EVENT_RUNNING_CORE 0 +#define CONFIG_ARDUINO_UDP_RUN_CORE0 1 #define CONFIG_ARDUINO_UDP_TASK_PRIORITY 3 -#define CONFIG_ARDUINO_UDP_RUNNING_CORE 1 +#define CONFIG_ARDUINO_UDP_RUNNING_CORE 0 #define CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL_ERROR 1 #define CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL 1 #define CONFIG_ARDUHAL_ESP_LOG 1 diff --git a/tools/sdk/esp32s2/sdkconfig b/tools/sdk/esp32s2/sdkconfig index b7d50b9bd9d..3cb05e18822 100644 --- a/tools/sdk/esp32s2/sdkconfig +++ b/tools/sdk/esp32s2/sdkconfig @@ -143,20 +143,20 @@ CONFIG_PARTITION_TABLE_MD5=y # CONFIG_ENABLE_ARDUINO_DEPENDS=y CONFIG_AUTOSTART_ARDUINO=y -# CONFIG_ARDUINO_RUN_CORE0 is not set -CONFIG_ARDUINO_RUN_CORE1=y +CONFIG_ARDUINO_RUN_CORE0=y +# CONFIG_ARDUINO_RUN_CORE1 is not set # CONFIG_ARDUINO_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_RUNNING_CORE=1 +CONFIG_ARDUINO_RUNNING_CORE=0 CONFIG_ARDUINO_LOOP_STACK_SIZE=8192 -# CONFIG_ARDUINO_EVENT_RUN_CORE0 is not set -CONFIG_ARDUINO_EVENT_RUN_CORE1=y +CONFIG_ARDUINO_EVENT_RUN_CORE0=y +# CONFIG_ARDUINO_EVENT_RUN_CORE1 is not set # CONFIG_ARDUINO_EVENT_RUN_NO_AFFINITY is not set -CONFIG_ARDUINO_EVENT_RUNNING_CORE=1 -# CONFIG_ARDUINO_UDP_RUN_CORE0 is not set -CONFIG_ARDUINO_UDP_RUN_CORE1=y +CONFIG_ARDUINO_EVENT_RUNNING_CORE=0 +CONFIG_ARDUINO_UDP_RUN_CORE0=y +# CONFIG_ARDUINO_UDP_RUN_CORE1 is not set # CONFIG_ARDUINO_UDP_RUN_NO_AFFINITY is not set CONFIG_ARDUINO_UDP_TASK_PRIORITY=3 -CONFIG_ARDUINO_UDP_RUNNING_CORE=1 +CONFIG_ARDUINO_UDP_RUNNING_CORE=0 # CONFIG_ARDUINO_ISR_IRAM is not set # CONFIG_DISABLE_HAL_LOCKS is not set From 5940d89e671fa5ee5b065be46f5d959515feca6f Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Mon, 20 Dec 2021 10:17:25 +0200 Subject: [PATCH 2/9] Fix wrongly applied patch to WiFi STA Init --- libraries/WiFi/src/WiFiSTA.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index f6de6a13939..dd468823607 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -92,13 +92,13 @@ static void wifi_sta_config(wifi_config_t * wifi_config, const char * ssid=NULL, wifi_config->sta.pmf_cfg.required = pmf_required; wifi_config->sta.bssid_set = 0; memset(wifi_config->sta.bssid, 0, 6); - wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + wifi_config->sta.threshold.authmode = WIFI_AUTH_OPEN; wifi_config->sta.ssid[0] = 0; wifi_config->sta.password[0] = 0; if(ssid != NULL && ssid[0] != 0){ _wifi_strncpy((char*)wifi_config->sta.ssid, ssid, 32); if(password != NULL && password[0] != 0){ - wifi_config->sta.threshold.authmode = WIFI_AUTH_WEP; + wifi_config->sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; _wifi_strncpy((char*)wifi_config->sta.password, password, 64); } if(bssid != NULL){ From 82ec74a07275e79e92ee4e7eb973ee30c2c00cd3 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Mon, 20 Dec 2021 08:10:36 -0300 Subject: [PATCH 3/9] Adds support to change LoopTask Stack size (#6025) ## Summary Arduino ```setup()``` and ```loop()``` run under a Task with a fixed Stack size of 8KB. Users may want to change this size. This PR adds this possibility by just adding a line of code, as for example: ``` dart ESP_LOOP_TASK_STACK_SIZE(16384); void setup() { } void loop() { } ``` ## Impact None. It adds a new functionality to ESP32 Arduino. If ```ESP_LOOP_TASK_STACK_SIZE(newSize);``` is not declared/used, it will compile the sketch with the default stack size of 8KB. ## Related links fix #6010 https://github.com/espressif/arduino-esp32/issues/6010#issuecomment-992701658 Thanks @igrr for the suggestion! --- cores/esp32/Arduino.h | 3 ++ cores/esp32/main.cpp | 6 +++- .../ArduinoStackSize/ArduinoStackSize.ino | 36 +++++++++++++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 libraries/ESP32/examples/ArduinoStackSize/ArduinoStackSize.ino diff --git a/cores/esp32/Arduino.h b/cores/esp32/Arduino.h index 71ffe75197e..8014d3c8342 100644 --- a/cores/esp32/Arduino.h +++ b/cores/esp32/Arduino.h @@ -179,6 +179,9 @@ uint16_t makeWord(uint8_t h, uint8_t l); #define word(...) makeWord(__VA_ARGS__) +size_t getArduinoLoopTaskStackSize(void); +#define SET_LOOP_TASK_STACK_SIZE(sz) size_t getArduinoLoopTaskStackSize() { return sz;} + unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L); diff --git a/cores/esp32/main.cpp b/cores/esp32/main.cpp index 903e80f1748..f4e79844818 100644 --- a/cores/esp32/main.cpp +++ b/cores/esp32/main.cpp @@ -33,6 +33,10 @@ void yieldIfNecessary(void){ bool loopTaskWDTEnabled; +__attribute__((weak)) size_t getArduinoLoopTaskStackSize(void) { + return ARDUINO_LOOP_STACK_SIZE; +} + void loopTask(void *pvParameters) { setup(); @@ -64,7 +68,7 @@ extern "C" void app_main() #endif loopTaskWDTEnabled = false; initArduino(); - xTaskCreateUniversal(loopTask, "loopTask", ARDUINO_LOOP_STACK_SIZE, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE); + xTaskCreateUniversal(loopTask, "loopTask", getArduinoLoopTaskStackSize(), NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE); } #endif diff --git a/libraries/ESP32/examples/ArduinoStackSize/ArduinoStackSize.ino b/libraries/ESP32/examples/ArduinoStackSize/ArduinoStackSize.ino new file mode 100644 index 00000000000..73c42023591 --- /dev/null +++ b/libraries/ESP32/examples/ArduinoStackSize/ArduinoStackSize.ino @@ -0,0 +1,36 @@ +/* + ESP32 Arduino creates a task to run setup() and then to execute loop() continuously + This task can be found at https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/main.cpp + + By default "loopTask" will be created with a stack size of 8KB. + This should be plenty for most general sketches. + + There is a way to change the stack size of this task by using + SET_LOOP_TASK_STACK_SIZE(size); + It will bypass the default stack size of 8KB and allow the user to define a new size. + + It is recommend this value to be higher than 8KB, for instance 16KB. + This increasing may be necessary for the sketches that use deep recursion for instance. + + In this example, you can verify it by changing or just commenting out SET_LOOP_TASK_STACK_SIZE(); +*/ + + +// This sets Arduino Stack Size - comment this line to use default 8K stack size +SET_LOOP_TASK_STACK_SIZE(16*1024); // 16KB + +void setup() { + Serial.begin(115200); + + Serial.printf("Arduino Stack was set to %d bytes", getArduinoLoopTaskStackSize()); + + // Print unused stack for the task that is running setup() + Serial.printf("\nSetup() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL)); +} + +void loop() { + delay(1000); + + // Print unused stack for the task that is running loop() - the same as for setup() + Serial.printf("\nLoop() - Free Stack Space: %d", uxTaskGetStackHighWaterMark(NULL)); +} From 7b96374ea67222bac68452a7d37537e07608d1b2 Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Mon, 20 Dec 2021 11:11:22 +0000 Subject: [PATCH 4/9] [Fix] Added the Win32 not supported notice/warning (#6031) Related to: #6012 #5994 #5991 --- docs/source/installing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/source/installing.rst b/docs/source/installing.rst index 3913e5d9d9e..59028fcbf1b 100644 --- a/docs/source/installing.rst +++ b/docs/source/installing.rst @@ -61,6 +61,10 @@ To start the installation process using the Boards Managaer, follow these steps: Windows ------- +.. warning:: Arduino ESP32 core v2.x.x cannot be used on Windows 8.x x86 (32 bits), Windows 7 or earlier. The Windows 32 bits OS is no longer supported by this toolchain. + + The Arduino ESP32 v1.0.6 still works on WIN32. You might want to install python 3.8.x because it is the latest release supported by Windows 7. + Steps to install Arduino ESP32 support on Windows: **Step 1** From 063119ac876d0c4e92db5ca411a657b3c3fdceff Mon Sep 17 00:00:00 2001 From: Mondbaron <5863649+mondbaron@users.noreply.github.com> Date: Mon, 20 Dec 2021 12:21:53 +0100 Subject: [PATCH 5/9] fix variant wt32-eth01 (initializer not constant) (#6040) fix not constant definitions in variant wt32-eth01 (error: initializer element is not constant) --- variants/wt32-eth01/pins_arduino.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/variants/wt32-eth01/pins_arduino.h b/variants/wt32-eth01/pins_arduino.h index f92bfec8667..7ea22ab69c3 100644 --- a/variants/wt32-eth01/pins_arduino.h +++ b/variants/wt32-eth01/pins_arduino.h @@ -45,11 +45,11 @@ static const uint8_t IO36 = 36; static const uint8_t IO39 = 39; // UART interfaces -static const uint8_t TXD0 = IO1, TX0 = IO1; -static const uint8_t RXD0 = IO3, RX0 = IO3; -static const uint8_t TXD2 = IO17, TXD = IO17; -static const uint8_t RXD2 = IO5, RXD = IO5; -static const uint8_t TX = TX0; -static const uint8_t RX = TX0; - -#endif /* Pins_Arduino_h */ \ No newline at end of file +static const uint8_t TXD0 = 1, TX0 = 1; +static const uint8_t RXD0 = 3, RX0 = 3; +static const uint8_t TXD2 = 17, TXD = 17; +static const uint8_t RXD2 = 5, RXD = 5; +static const uint8_t TX = 1; +static const uint8_t RX = 3; + +#endif /* Pins_Arduino_h */ From 6b90627b21cb888c1bfa700385bee03f0ff8c6f9 Mon Sep 17 00:00:00 2001 From: discapacidad5 Date: Mon, 20 Dec 2021 12:22:58 +0100 Subject: [PATCH 6/9] HID_BRAILLE_DISPLAY (#6043) 23 Braille Display Page (0x41) Braille display allow visually impaired computer users to read out text using raised pins. The pins are electro-mechanically activated. These devices also have support for controls that help navigate the computer screen. Typically, braille displays interface with software known as a screen reader in order to perform this navigation. --- libraries/BLE/src/BLEHIDDevice.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/BLE/src/BLEHIDDevice.h b/libraries/BLE/src/BLEHIDDevice.h index fead92b730a..9770145f7e7 100644 --- a/libraries/BLE/src/BLEHIDDevice.h +++ b/libraries/BLE/src/BLEHIDDevice.h @@ -26,6 +26,7 @@ #define HID_CARD_READER 0x03C6 #define HID_DIGITAL_PEN 0x03C7 #define HID_BARCODE 0x03C8 +#define HID_BRAILLE_DISPLAY 0x03C9 class BLEHIDDevice { public: From d6934a528941f1ee545917c0a61e98d1c23fcc83 Mon Sep 17 00:00:00 2001 From: P-R-O-C-H-Y <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 20 Dec 2021 13:58:49 +0100 Subject: [PATCH 7/9] Implement LEDC based on ESP-IDF API (#6045) This PR is refactoring of LEDC HAL in order to use IDF instead of current Register manipulation approach. Fixing duty -> if all bits in resolution are set -> FULL ON --- cores/esp32/esp32-hal-ledc.c | 312 ++++++++++------------------------- 1 file changed, 87 insertions(+), 225 deletions(-) diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c index 4e20e7b8bd4..6274ed0708c 100644 --- a/cores/esp32/esp32-hal-ledc.c +++ b/cores/esp32/esp32-hal-ledc.c @@ -13,46 +13,25 @@ // limitations under the License. #include "esp32-hal.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "esp32-hal-matrix.h" #include "soc/soc_caps.h" -#include "soc/ledc_reg.h" -#include "soc/ledc_struct.h" -#include "driver/periph_ctrl.h" +#include "driver/ledc.h" -#include "esp_system.h" -#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+ -#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4 -#include "soc/dport_reg.h" -#include "esp32/rom/ets_sys.h" -#define LAST_CHAN (15) -#elif CONFIG_IDF_TARGET_ESP32S2 -#include "soc/dport_reg.h" -#include "esp32s2/rom/ets_sys.h" -#define LAST_CHAN (7) -#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V -#elif CONFIG_IDF_TARGET_ESP32C3 -#include "esp32c3/rom/ets_sys.h" -#define LAST_CHAN (7) -#define LEDC_DIV_NUM_HSTIMER0_V LEDC_CLK_DIV_LSTIMER0_V -#else -#error Target CONFIG_IDF_TARGET is not supported -#endif -#else // ESP32 Before IDF 4.0 -#include "rom/ets_sys.h" +#ifdef SOC_LEDC_SUPPORT_HS_MODE +#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM<<1) +#else +#define LEDC_CHANNELS (SOC_LEDC_CHANNEL_NUM) #endif -#if CONFIG_DISABLE_HAL_LOCKS -#define LEDC_MUTEX_LOCK() -#define LEDC_MUTEX_UNLOCK() +//Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz +//Need to be fixed in ESP-IDF +#ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK +#define LEDC_DEFAULT_CLK LEDC_USE_XTAL_CLK #else -#define LEDC_MUTEX_LOCK() do {} while (xSemaphoreTake(_ledc_sys_lock, portMAX_DELAY) != pdPASS) -#define LEDC_MUTEX_UNLOCK() xSemaphoreGive(_ledc_sys_lock) -xSemaphoreHandle _ledc_sys_lock = NULL; +#define LEDC_DEFAULT_CLK LEDC_AUTO_CLK #endif +#define LEDC_MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM + /* * LEDC Chan to Group/Channel/Timer Mapping ** ledc: 0 => Group: 0, Channel: 0, Timer: 0 @@ -72,203 +51,55 @@ xSemaphoreHandle _ledc_sys_lock = NULL; ** ledc: 14 => Group: 1, Channel: 6, Timer: 3 ** ledc: 15 => Group: 1, Channel: 7, Timer: 3 */ -#define LEDC_CHAN(g,c) LEDC.channel_group[(g)].channel[(c)] -#define LEDC_TIMER(g,t) LEDC.timer_group[(g)].timer[(t)] -static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ - if(ev_type == APB_AFTER_CHANGE && old_apb != new_apb){ - uint16_t iarg = *(uint16_t*)arg; - uint8_t chan = 0; - old_apb /= 1000000; - new_apb /= 1000000; - while(iarg){ // run though all active channels, adjusting timing configurations - if(iarg & 1) {// this channel is active - uint8_t group=(chan/8), timer=((chan/2)%4); - if(LEDC_TIMER(group, timer).conf.tick_sel){ - LEDC_MUTEX_LOCK(); - uint32_t old_div = LEDC_TIMER(group, timer).conf.clock_divider; - uint32_t div_num = (new_apb * old_div) / old_apb; - if(div_num > LEDC_DIV_NUM_HSTIMER0_V){ - div_num = ((REF_CLK_FREQ /1000000) * old_div) / old_apb; - if(div_num > LEDC_DIV_NUM_HSTIMER0_V) { - div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible - } - LEDC_TIMER(group, timer).conf.tick_sel = 0; - } else if(div_num < 256) { - div_num = 256;//highest clock possible - } - LEDC_TIMER(group, timer).conf.clock_divider = div_num; - LEDC_MUTEX_UNLOCK(); - } - else { - log_d("using REF_CLK chan=%d",chan); - } - } - iarg = iarg >> 1; - chan++; - } - } -} +uint8_t channels_resolution[LEDC_CHANNELS] = {0}; -//uint32_t frequency = (80MHz or 1MHz)/((div_num / 256.0)*(1 << bit_num)); -static void _ledcSetupTimer(uint8_t chan, uint32_t div_num, uint8_t bit_num, bool apb_clk) -{ - uint8_t group=(chan/8), timer=((chan/2)%4); - static bool tHasStarted = false; - static uint16_t _activeChannels = 0; -#if CONFIG_IDF_TARGET_ESP32S2 -// ESP32-S2 TRM v1.0 on Page 789 -> BIT LEDC_TICK_SEL_TIMERx is 0 for LEDC_PWM_CLK and 1 for REF_TICK - apb_clk = 0; -#endif - if(!tHasStarted) { - tHasStarted = true; - periph_module_enable(PERIPH_LEDC_MODULE); - LEDC.conf.apb_clk_sel = 1;//LS use apb clock - addApbChangeCallback((void*)&_activeChannels, _on_apb_change); - -#if !CONFIG_DISABLE_HAL_LOCKS - _ledc_sys_lock = xSemaphoreCreateMutex(); -#endif - } - LEDC_MUTEX_LOCK(); - LEDC_TIMER(group, timer).conf.clock_divider = div_num;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part. - LEDC_TIMER(group, timer).conf.duty_resolution = bit_num;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20. - LEDC_TIMER(group, timer).conf.tick_sel = apb_clk;//apb clock -#if CONFIG_IDF_TARGET_ESP32 - if(group) { -#endif - LEDC_TIMER(group, timer).conf.low_speed_update = 1;//This bit is only useful for low speed timer channels, reserved for high speed timers -#if CONFIG_IDF_TARGET_ESP32 - } -#endif - LEDC_TIMER(group, timer).conf.pause = 0; - LEDC_TIMER(group, timer).conf.rst = 1;//This bit is used to reset timer the counter will be 0 after reset. - LEDC_TIMER(group, timer).conf.rst = 0; - LEDC_MUTEX_UNLOCK(); - _activeChannels |= (1 << chan); // mark as active for APB callback -} - -//max div_num 0x3FFFF (262143) -//max bit_num 0x1F (31) -static double _ledcSetupTimerFreq(uint8_t chan, double freq, uint8_t bit_num) +double ledcSetup(uint8_t chan, double freq, uint8_t bit_num) { - uint64_t clk_freq = getApbFrequency(); - clk_freq <<= 8;//div_num is 8 bit decimal - uint32_t div_num = (clk_freq >> bit_num) / freq; - bool apb_clk = true; - if(div_num > LEDC_DIV_NUM_HSTIMER0_V) { - clk_freq /= 80; - div_num = (clk_freq >> bit_num) / freq; - if(div_num > LEDC_DIV_NUM_HSTIMER0_V) { - div_num = LEDC_DIV_NUM_HSTIMER0_V;//lowest clock possible - } - apb_clk = false; - } else if(div_num < 256) { - div_num = 256;//highest clock possible + if(chan >= LEDC_CHANNELS){ + log_e("No more LEDC channels available! You can have maximum %u", LEDC_CHANNELS); + return 0; } - _ledcSetupTimer(chan, div_num, bit_num, apb_clk); - //log_i("Fin: %f, Fclk: %uMhz, bits: %u, DIV: %u, Fout: %f", - // freq, apb_clk?80:1, bit_num, div_num, (clk_freq >> bit_num) / (double)div_num); - return (clk_freq >> bit_num) / (double)div_num; -} - -static double _ledcTimerRead(uint8_t chan) -{ - uint32_t div_num; - uint8_t bit_num; - bool apb_clk; uint8_t group=(chan/8), timer=((chan/2)%4); - LEDC_MUTEX_LOCK(); - div_num = LEDC_TIMER(group, timer).conf.clock_divider;//18 bit (10.8) This register is used to configure parameter for divider in timer the least significant eight bits represent the decimal part. - bit_num = LEDC_TIMER(group, timer).conf.duty_resolution;//5 bit This register controls the range of the counter in timer. the counter range is [0 2**bit_num] the max bit width for counter is 20. - apb_clk = LEDC_TIMER(group, timer).conf.tick_sel;//apb clock - LEDC_MUTEX_UNLOCK(); - uint64_t clk_freq = 1000000; - if(apb_clk) { - clk_freq = getApbFrequency(); - } - clk_freq <<= 8;//div_num is 8 bit decimal - return (clk_freq >> bit_num) / (double)div_num; -} -static void _ledcSetupChannel(uint8_t chan, uint8_t idle_level) -{ - uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4); - LEDC_MUTEX_LOCK(); - LEDC_CHAN(group, channel).conf0.timer_sel = timer;//2 bit Selects the timer to attach 0-3 - LEDC_CHAN(group, channel).conf0.idle_lv = idle_level;//1 bit This bit is used to control the output value when channel is off. - LEDC_CHAN(group, channel).hpoint.hpoint = 0;//20 bit The output value changes to high when timer selected by channel has reached hpoint - LEDC_CHAN(group, channel).conf1.duty_inc = 1;//1 bit This register is used to increase the duty of output signal or decrease the duty of output signal for high speed channel - LEDC_CHAN(group, channel).conf1.duty_num = 1;//10 bit This register is used to control the number of increased or decreased times for channel - LEDC_CHAN(group, channel).conf1.duty_cycle = 1;//10 bit This register is used to increase or decrease the duty every duty_cycle cycles for channel - LEDC_CHAN(group, channel).conf1.duty_scale = 0;//10 bit This register controls the increase or decrease step scale for channel. - LEDC_CHAN(group, channel).duty.duty = 0; - LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel - LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware. -#if CONFIG_IDF_TARGET_ESP32 - if(group) { -#endif - LEDC_CHAN(group, channel).conf0.low_speed_update = 1; -#if CONFIG_IDF_TARGET_ESP32 - } else { - LEDC_CHAN(group, channel).conf0.clk_en = 0; - } -#endif - LEDC_MUTEX_UNLOCK(); -} + ledc_timer_config_t ledc_timer = { + .speed_mode = group, + .timer_num = timer, + .duty_resolution = bit_num, + .freq_hz = freq, + .clk_cfg = LEDC_DEFAULT_CLK + }; + ledc_timer_config(&ledc_timer); + channels_resolution[chan] = bit_num; -double ledcSetup(uint8_t chan, double freq, uint8_t bit_num) -{ - if(chan > LAST_CHAN) { - return 0; - } - double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num); - _ledcSetupChannel(chan, LOW); - return res_freq; + return ledc_get_freq(group,timer); } void ledcWrite(uint8_t chan, uint32_t duty) { - if(chan > LAST_CHAN) { + if(chan >= LEDC_CHANNELS){ return; } uint8_t group=(chan/8), channel=(chan%8); - LEDC_MUTEX_LOCK(); - LEDC_CHAN(group, channel).duty.duty = duty << 4;//25 bit (21.4) - if(duty) { - LEDC_CHAN(group, channel).conf0.sig_out_en = 1;//This is the output enable control bit for channel - LEDC_CHAN(group, channel).conf1.duty_start = 1;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware. -#if CONFIG_IDF_TARGET_ESP32 - if(group) { -#endif - LEDC_CHAN(group, channel).conf0.low_speed_update = 1; -#if CONFIG_IDF_TARGET_ESP32 - } else { - LEDC_CHAN(group, channel).conf0.clk_en = 1; - } -#endif - } else { - LEDC_CHAN(group, channel).conf0.sig_out_en = 0;//This is the output enable control bit for channel - LEDC_CHAN(group, channel).conf1.duty_start = 0;//When duty_num duty_cycle and duty_scale has been configured. these register won't take effect until set duty_start. this bit is automatically cleared by hardware. -#if CONFIG_IDF_TARGET_ESP32 - if(group) { -#endif - LEDC_CHAN(group, channel).conf0.low_speed_update = 1; -#if CONFIG_IDF_TARGET_ESP32 - } else { - LEDC_CHAN(group, channel).conf0.clk_en = 0; - } -#endif + + //Fixing if all bits in resolution is set = LEDC FULL ON + uint32_t max_duty = (1 << channels_resolution[chan]) - 1; + + if(duty == max_duty){ + duty = max_duty + 1; } - LEDC_MUTEX_UNLOCK(); + + ledc_set_duty(group, channel, duty); + ledc_update_duty(group, channel); } uint32_t ledcRead(uint8_t chan) { - if(chan > LAST_CHAN) { + if(chan >= LEDC_CHANNELS){ return 0; } - return LEDC.channel_group[chan/8].channel[chan%8].duty.duty >> 4; + uint8_t group=(chan/8), channel=(chan%8); + return ledc_get_duty(group,channel); } double ledcReadFreq(uint8_t chan) @@ -276,19 +107,33 @@ double ledcReadFreq(uint8_t chan) if(!ledcRead(chan)){ return 0; } - return _ledcTimerRead(chan); + uint8_t group=(chan/8), timer=((chan/2)%4); + return ledc_get_freq(group,timer); } double ledcWriteTone(uint8_t chan, double freq) { - if(chan > LAST_CHAN) { + if(chan >= LEDC_CHANNELS){ return 0; } - if(!freq) { + if(!freq){ ledcWrite(chan, 0); return 0; } - double res_freq = _ledcSetupTimerFreq(chan, freq, 10); + + uint8_t group=(chan/8), timer=((chan/2)%4); + + ledc_timer_config_t ledc_timer = { + .speed_mode = group, + .timer_num = timer, + .duty_resolution = 10, + .freq_hz = freq, + .clk_cfg = LEDC_DEFAULT_CLK + }; + ledc_timer_config(&ledc_timer); + channels_resolution[chan] = 10; + + double res_freq = ledc_get_freq(group,timer); ledcWrite(chan, 0x1FF); return res_freq; } @@ -308,15 +153,21 @@ double ledcWriteNote(uint8_t chan, note_t note, uint8_t octave){ void ledcAttachPin(uint8_t pin, uint8_t chan) { - if(chan > LAST_CHAN) { + if(chan >= LEDC_CHANNELS){ return; } - pinMode(pin, OUTPUT); -#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3 - pinMatrixOutAttach(pin, LEDC_LS_SIG_OUT0_IDX + chan, false, false); -#else - pinMatrixOutAttach(pin, ((chan/8)?LEDC_LS_SIG_OUT0_IDX:LEDC_HS_SIG_OUT0_IDX) + (chan%8), false, false); -#endif + uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4); + + ledc_channel_config_t ledc_channel = { + .speed_mode = group, + .channel = channel, + .timer_sel = timer, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = pin, + .duty = 0, + .hpoint = 0 + }; + ledc_channel_config(&ledc_channel); } void ledcDetachPin(uint8_t pin) @@ -326,21 +177,32 @@ void ledcDetachPin(uint8_t pin) double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num) { - if (chan > 15) { + if(chan >= LEDC_CHANNELS){ return 0; } - double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num); - return res_freq; + uint8_t group=(chan/8), timer=((chan/2)%4); + + ledc_timer_config_t ledc_timer = { + .speed_mode = group, + .timer_num = timer, + .duty_resolution = bit_num, + .freq_hz = freq, + .clk_cfg = LEDC_DEFAULT_CLK + }; + ledc_timer_config(&ledc_timer); + channels_resolution[chan] = bit_num; + + return ledc_get_freq(group,timer); } static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 }; -static int cnt_channel = SOC_LEDC_CHANNEL_NUM; +static int cnt_channel = LEDC_CHANNELS; void analogWrite(uint8_t pin, int value) { // Use ledc hardware for internal pins if (pin < SOC_GPIO_PIN_COUNT) { if (pin_to_channel[pin] == 0) { if (!cnt_channel) { - log_e("No more analogWrite channels available! You can have maximum %u", SOC_LEDC_CHANNEL_NUM); + log_e("No more analogWrite channels available! You can have maximum %u", LEDC_CHANNELS); return; } pin_to_channel[pin] = cnt_channel--; From c3d41c9b54261265966717331960aabcf4848e23 Mon Sep 17 00:00:00 2001 From: Rodrigo Garcia Date: Tue, 21 Dec 2021 05:10:31 -0300 Subject: [PATCH 8/9] Fixes baudrate with CPU Freq < 80MHz (#6037) This PR fixes an issue with UART when CPUFreq is lower than 80MHz (APB Freq) --- cores/esp32/esp32-hal-uart.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-uart.c b/cores/esp32/esp32-hal-uart.c index b76d02f18f8..c34c54b1a25 100644 --- a/cores/esp32/esp32-hal-uart.c +++ b/cores/esp32/esp32-hal-uart.c @@ -69,6 +69,19 @@ static uart_t _uart_bus_array[] = { #endif +// solves issue https://github.com/espressif/arduino-esp32/issues/6032 +// baudrate must be multiplied when CPU Frequency is lower than APB 80MHz +uint32_t _get_effective_baudrate(uint32_t baudrate) +{ + uint32_t Freq = getApbFrequency()/1000000; + if (Freq < 80) { + return 80 / Freq * baudrate; + } + else { + return baudrate; + } +} + bool uartIsDriverInstalled(uart_t* uart) { if(uart == NULL) { @@ -121,7 +134,7 @@ uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rx UART_MUTEX_LOCK(); uart_config_t uart_config; - uart_config.baud_rate = baudrate; + uart_config.baud_rate = _get_effective_baudrate(baudrate); uart_config.data_bits = (config & 0xc) >> 2; uart_config.parity = (config & 0x3); uart_config.stop_bits = (config & 0x30) >> 4; @@ -307,7 +320,7 @@ void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) return; } UART_MUTEX_LOCK(); - uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), baud_rate); + uart_ll_set_baudrate(UART_LL_GET_HW(uart->num), _get_effective_baudrate(baud_rate)); UART_MUTEX_UNLOCK(); } From 7ba11cc1ae206f88d82b27eac9a0a6dec833dc6f Mon Sep 17 00:00:00 2001 From: Pedro Minatel Date: Tue, 21 Dec 2021 10:51:38 +0000 Subject: [PATCH 9/9] [Docs] Added USB documentation (#6036) Summary Added USB documentation. Closes: #5784 --- docs/source/api/usb.rst | 331 ++++++++++++++++++++++++++++++++++++ docs/source/api/usb_cdc.rst | 192 +++++++++++++++++++++ docs/source/api/usb_msc.rst | 114 +++++++++++++ docs/source/libraries.rst | 1 + 4 files changed, 638 insertions(+) create mode 100644 docs/source/api/usb.rst create mode 100644 docs/source/api/usb_cdc.rst create mode 100644 docs/source/api/usb_msc.rst diff --git a/docs/source/api/usb.rst b/docs/source/api/usb.rst new file mode 100644 index 00000000000..94261185f61 --- /dev/null +++ b/docs/source/api/usb.rst @@ -0,0 +1,331 @@ +####### +USB API +####### + +.. note:: This feature is only supported on ESP chips that have USB peripheral, like the ESP32-S2 and ESP32-S3. Some chips, like the ESP32-C3 include native CDC+JTAG peripheral that is not covered here. + +About +----- + +The **Universal Serial Bus** is a widely used peripheral to exchange data between devices. USB was introduced on the ESP32, supporting both device and host mode. + +To learn about the USB, see the `USB.org`_ for developers. + +USB as Device +************* + +In the device mode, the ESP32 acts as an USB device, like a mouse or keyboard to be connected to a host device, like your computer or smartphone. + +USB as Host +*********** + +The USB host mode, you can connect devices on the ESP32, like external modems, mouse and keyboards. + +.. note:: This mode is still under development for the ESP32. + +API Description +--------------- + +This is the common USB API description. + +For more supported USB classes implementation, see the following sections: + +.. toctree:: + :maxdepth: 1 + :caption: Classes: + + USB CDC + USB MSC + +USB Common +********** + +These are the common APIs for the USB driver. + +onEvent +^^^^^^^ + +Event handling function to set the callback. + +.. code-block:: arduino + + void onEvent(esp_event_handler_t callback); + +Event handling function for the specific event. + +.. code-block:: arduino + + void onEvent(arduino_usb_event_t event, esp_event_handler_t callback); + +Where ``event`` can be: + +* ARDUINO_USB_ANY_EVENT +* ARDUINO_USB_STARTED_EVENT +* ARDUINO_USB_STOPPED_EVENT +* ARDUINO_USB_SUSPEND_EVENT +* ARDUINO_USB_RESUME_EVENT +* ARDUINO_USB_MAX_EVENT + +VID +^^^ + +Set the Vendor ID. This 16 bits identification is used to identify the company that develops the product. + +.. note:: You can't define your own VID. If you need your own VID, you need to buy one. See https://www.usb.org/getting-vendor-id for more details. + +.. code-block:: arduino + + bool VID(uint16_t v); + + +Get the Vendor ID. + +.. code-block:: arduino + + uint16_t VID(void); + +Returns the Vendor ID. The default value for the VID is: ``0x303A``. + +PID +^^^ + +Set the Product ID. This 16 bits identification is used to identify the product. + +.. code-block:: arduino + + bool PID(uint16_t p); + +Get the Product ID. + +.. code-block:: arduino + + uint16_t PID(void); + +Returns the Product ID. The default PID is: ``0x0002``. + +firmwareVersion +^^^^^^^^^^^^^^^ + +Set the firmware version. This is a 16 bits unsigned value. + +.. code-block:: arduino + + bool firmwareVersion(uint16_t version); + +Get the firmware version. + +.. code-block:: arduino + + uint16_t firmwareVersion(void); + +Return the 16 bits unsigned value. The default value is: ``0x100``. + +usbVersion +^^^^^^^^^^ + +Set the USB version. + +.. code-block:: arduino + + bool usbVersion(uint16_t version); + +Get the USB version. + +.. code-block:: arduino + + uint16_t usbVersion(void); + +Return the USB version. The default value is: ``0x200`` (USB 2.0). + +usbPower +^^^^^^^^ + +Set the USB power as mA (current). + +.. note:: This configuration does not change the physical power output. This is only used for the USB device information. + +.. code-block:: arduino + + bool usbPower(uint16_t mA); + +Get the USB power configuration. + +.. code-block:: arduino + + uint16_t usbPower(void); + +Return the current in mA. The default value is: ``0x500`` (500mA). + +usbClass +^^^^^^^^ + +Set the USB class. + +.. code-block:: arduino + + bool usbClass(uint8_t _class); + +Get the USB class. + +.. code-block:: arduino + + uint8_t usbClass(void); + +Return the USB class. The default value is: ``TUSB_CLASS_MISC``. + +usbSubClass +^^^^^^^^^^^ + +Set the USB sub-class. + +.. code-block:: arduino + + bool usbSubClass(uint8_t subClass); + +Get the USB sub-class. + +.. code-block:: arduino + + uint8_t usbSubClass(void); + +Return the USB sub-class. The default value is: ``MISC_SUBCLASS_COMMON``. + +usbProtocol +^^^^^^^^^^^ + +Define the USB protocol. + +.. code-block:: arduino + + bool usbProtocol(uint8_t protocol); + +Get the USB protocol. + +.. code-block:: arduino + + uint8_t usbProtocol(void); + +Return the USB protocol. The default value is: ``MISC_PROTOCOL_IAD`` + +usbAttributes +^^^^^^^^^^^^^ + +Set the USB attributes. + +.. code-block:: arduino + + bool usbAttributes(uint8_t attr); + +Get the USB attributes. + +.. code-block:: arduino + + uint8_t usbAttributes(void); + +Return the USB attributes. The default value is: ``TUSB_DESC_CONFIG_ATT_SELF_POWERED`` + +webUSB +^^^^^^ + +This function is used to enable the ``webUSB`` functionality. + +.. code-block:: arduino + + bool webUSB(bool enabled); + +This function is used to get the ``webUSB`` setting. + +.. code-block:: arduino + + bool webUSB(void); + +Return the ``webUSB`` setting (`Enabled` or `Disabled`) + +productName +^^^^^^^^^^^ + +This function is used to define the product name. + +.. code-block:: arduino + + bool productName(const char * name); + +This function is used to get the product's name. + +.. code-block:: arduino + + const char * productName(void); + +manufacturerName +^^^^^^^^^^^^^^^^ + +This function is used to define the manufacturer name. + +.. code-block:: arduino + + bool manufacturerName(const char * name); + +This function is used to get the manufacturer's name. + +.. code-block:: arduino + + const char * manufacturerName(void); + +serialNumber +^^^^^^^^^^^^ + +This function is used to define the serial number. + +.. code-block:: arduino + + bool serialNumber(const char * name); + +This function is used to get the serial number. + +.. code-block:: arduino + + const char * serialNumber(void); + +The default serial number is: ``0``. + +webUSBURL +^^^^^^^^^ + +This function is used to define the ``webUSBURL``. + +.. code-block:: arduino + + bool webUSBURL(const char * name); + +This function is used to get the ``webUSBURL``. + +.. code-block:: arduino + + const char * webUSBURL(void); + +The default ``webUSBURL`` is: https://espressif.github.io/arduino-esp32/webusb.html + +enableDFU +^^^^^^^^^ + +This function is used to enable the DFU capability. + +.. code-block:: arduino + + bool enableDFU(); + +begin +^^^^^ + +This function is used to start the peripheral using the default configuration. + +.. code-block:: arduino + + bool begin(); + +Example Code +------------ + +There are a collection of USB device examples on the project GitHub, including Firmware MSC update, USB CDC, HID and composite device. + +.. _USB.org: https://www.usb.org/developers diff --git a/docs/source/api/usb_cdc.rst b/docs/source/api/usb_cdc.rst new file mode 100644 index 00000000000..1c0b04f2f3c --- /dev/null +++ b/docs/source/api/usb_cdc.rst @@ -0,0 +1,192 @@ +####### +USB CDC +####### + +About +----- + +USB Communications Device Class API. This class is used to enable communication between the host and the device. + +This class is often used to enable serial communication and can be used to flash the firmware on the ESP32 without the external USB to Serial chip. + +APIs +**** + +onEvent +^^^^^^^ + +Event handling functions. + +.. code-block:: arduino + + void onEvent(esp_event_handler_t callback); + +.. code-block:: arduino + + void onEvent(arduino_usb_cdc_event_t event, esp_event_handler_t callback); + +Where ``event`` can be: + +* ARDUINO_USB_CDC_ANY_EVENT +* ARDUINO_USB_CDC_CONNECTED_EVENT +* ARDUINO_USB_CDC_DISCONNECTED_EVENT +* ARDUINO_USB_CDC_LINE_STATE_EVENT +* ARDUINO_USB_CDC_LINE_CODING_EVENT +* ARDUINO_USB_CDC_RX_EVENT +* ARDUINO_USB_CDC_TX_EVENT +* ARDUINO_USB_CDC_MAX_EVENT + +setRxBufferSize +^^^^^^^^^^^^^^^ + +The ``setRxBufferSize`` function is used to set the size of the RX buffer. + +.. code-block:: arduino + + size_t setRxBufferSize(size_t size); + +setTxTimeoutMs +^^^^^^^^^^^^^^ + +This function is used to define the time to reach the timeout for the TX. + +.. code-block:: arduino + + void setTxTimeoutMs(uint32_t timeout); + +begin +^^^^^ + +This function is used to start the peripheral using the default CDC configuration. + +.. code-block:: arduino + + void begin(unsigned long baud); + +Where: + +* ``baud`` is the baud rate. + +end +^^^ + +This function will finish the peripheral as CDC and release all the allocated resources. After calling ``end`` you need to use ``begin`` again in order to initialize the USB CDC driver again. + +.. code-block:: arduino + + void end(); + +available +^^^^^^^^^ + +This function will return if there are messages in the queue. + +.. code-block:: arduino + + int available(void); + +The return is the number of bytes available to read. + +availableForWrite +^^^^^^^^^^^^^^^^^ + +This function will return if the hardware is available to write data. + +.. code-block:: arduino + + int availableForWrite(void); + +peek +^^^^ + +This function is used to ``peek`` messages from the queue. + +.. code-block:: arduino + + int peek(void); + +read +^^^^ + +This function is used to read the bytes available. + +.. code-block:: arduino + + size_t read(uint8_t *buffer, size_t size); + +Where: + +* ``buffer`` is the pointer to the buffer to be read. +* ``size`` is the number of bytes to be read. + +write +^^^^^ + +This function is used to write the message. + +.. code-block:: arduino + + size_t write(const uint8_t *buffer, size_t size); + +Where: + +* ``buffer`` is the pointer to the buffer to be written. +* ``size`` is the number of bytes to be written. + +flush +^^^^^ + +This function is used to flush the data. + +.. code-block:: arduino + + void flush(void); + +baudRate +^^^^^^^^ + +This function is used to get the ``baudRate``. + +.. code-block:: arduino + + uint32_t baudRate(); + +setDebugOutput +^^^^^^^^^^^^^^ + +This function will enable the debug output, usually from the `UART0`, to the USB CDC. + +.. code-block:: arduino + + void setDebugOutput(bool); + +enableReboot +^^^^^^^^^^^^ + +This function enables the device to reboot by the DTR as RTS signals. + +.. code-block:: arduino + + void enableReboot(bool enable); + +rebootEnabled +^^^^^^^^^^^^^ + +This function will return if the reboot is enabled. + +.. code-block:: arduino + + bool rebootEnabled(void); + +Example Code +------------ + +Here is an example of how to use the USB CDC. + +USBSerial +********* + +.. literalinclude:: ../../../libraries/USB/examples/USBSerial/USBSerial.ino + :language: arduino + +.. _USB.org: https://www.usb.org/developers diff --git a/docs/source/api/usb_msc.rst b/docs/source/api/usb_msc.rst new file mode 100644 index 00000000000..846e72e8db0 --- /dev/null +++ b/docs/source/api/usb_msc.rst @@ -0,0 +1,114 @@ +####### +USB MSC +####### + +About +----- + +USB Mass Storage Class API. This class makes the device accessible as a mass storage device and allows you to transfer data between the host and the device. + +One of the examples for this mode is to flash the device by dropping the firmware binary like a flash memory device when connecting the ESP32 to the host computer. + +APIs +**** + +begin +^^^^^ + +This function is used to start the peripheral using the default MSC configuration. + +.. code-block:: arduino + + bool begin(uint32_t block_count, uint16_t block_size); + +Where: + +* ``block_count`` set the disk sector count. +* ``block_size`` set the disk sector size. + +This function will return ``true`` if the configuration was successful. + +end +^^^ + +This function will finish the peripheral as MSC and release all the allocated resources. After calling ``end`` you need to use ``begin`` again in order to initialize the USB MSC driver again. + +.. code-block:: arduino + + void end(); + +vendorID +^^^^^^^^ + +This function is used to define the vendor ID. + +.. code-block:: arduino + + void vendorID(const char * vid);//max 8 chars + +productID +^^^^^^^^^ + +This function is used to define the product ID. + +.. code-block:: arduino + + void productID(const char * pid);//max 16 chars + +productRevision +^^^^^^^^^^^^^^^ + +This function is used to define the product revision. + +.. code-block:: arduino + + void productRevision(const char * ver);//max 4 chars + +mediaPresent +^^^^^^^^^^^^ + +Set the ``mediaPresent`` configuration. + +.. code-block:: arduino + + void mediaPresent(bool media_present); + +onStartStop +^^^^^^^^^^^ + +Set the ``onStartStop`` callback function. + +.. code-block:: arduino + + void onStartStop(msc_start_stop_cb cb); + +onRead +^^^^^^ + +Set the ``onRead`` callback function. + +.. code-block:: arduino + + void onRead(msc_read_cb cb); + +onWrite +^^^^^^^ + +Set the ``onWrite`` callback function. + +.. code-block:: arduino + + void onWrite(msc_write_cb cb); + +Example Code +------------ + +Here is an example of how to use the USB MSC. + +FirmwareMSC +*********** + +.. literalinclude:: ../../../libraries/USB/examples/FirmwareMSC/FirmwareMSC.ino + :language: arduino + +.. _USB.org: https://www.usb.org/developers diff --git a/docs/source/libraries.rst b/docs/source/libraries.rst index 6275e603f2a..12dd8cfd37f 100644 --- a/docs/source/libraries.rst +++ b/docs/source/libraries.rst @@ -86,4 +86,5 @@ The Arduino ESP32 offers some unique APIs, described in this section: I2C RainMaker Reset Reason + USB Wi-Fi