Skip to content

Commit

Permalink
ESP32-S2 Support
Browse files Browse the repository at this point in the history
  • Loading branch information
tobozo committed Aug 9, 2022
1 parent 2ab4ab0 commit edc5281
Show file tree
Hide file tree
Showing 8 changed files with 574 additions and 145 deletions.
22 changes: 15 additions & 7 deletions examples/USB_Test/USB_Test.ino
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

#define DEBUG_ALL
#include <ESP32-USBSoftHost.hpp>
#include "usbkbd.h" // KeyboardReportParser

Expand Down Expand Up @@ -56,11 +56,23 @@
#define DM_P0 8
#define DP_P1 -1
#define DM_P1 -1
#define DP_P2 -1
#define DM_P2 -1
#define DP_P3 -1
#define DM_P3 -1
#elif CONFIG_IDF_TARGET_ESP32S2 || defined CONFIG_IDF_TARGET_ESP32S2
#define LOAD_TINYUSB
#define PROFILE_NAME "ESP32 S2 Dev module"
// [OK] 20/19 (USB RS/TS)
#define DP_P0 20 // ok
#define DM_P0 19 // ok
#define DP_P1 -1
#define DM_P1 -1
#define DP_P2 -1
#define DM_P2 -1
#define DP_P3 -1
#define DM_P3 -1

#else
// default pins tested on ESP32-Wroom
#define PROFILE_NAME "Default Wroom"
Expand All @@ -75,7 +87,6 @@
#endif



static void my_USB_DetectCB( uint8_t usbNum, void * dev )
{
sDevDesc *device = (sDevDesc*)dev;
Expand Down Expand Up @@ -119,14 +130,11 @@ usb_pins_config_t USB_Pins_Config =

void setup()
{

Serial.begin(115200);
delay(200);
delay(5000);
Serial.printf("USB Soft Host Test for %s\n", PROFILE_NAME );
delay(1000);

Serial.printf("TIMER_BASE_CLK: %d, TIMER_DIVIDER:%d, TIMER_SCALE: %d\n", TIMER_BASE_CLK, TIMER_DIVIDER, TIMER_SCALE );
USH.init( USB_Pins_Config, my_USB_DetectCB, my_USB_PrintCB );

}

void loop()
Expand Down
6 changes: 3 additions & 3 deletions examples/USB_Test/usbkbd.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ class KeyboardReportParser
{
switch(key) {
case UHS_HID_BOOT_KEY_NUM_LOCK:
bmNumLock = ~bmNumLock;
bmNumLock = !bmNumLock;
break;
case UHS_HID_BOOT_KEY_CAPS_LOCK:
bmCapsLock = ~bmCapsLock;
bmCapsLock = !bmCapsLock;
break;
case UHS_HID_BOOT_KEY_SCROLL_LOCK:
bmScrollLock = ~bmScrollLock;
bmScrollLock = !bmScrollLock;
break;
}
return 0;
Expand Down
5 changes: 3 additions & 2 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name=ESP32-USB-Soft-Host
version=0.1.1
version=0.1.2
author=tobozo <[email protected]>
maintainer=tobozo <[email protected]>
sentence="An Arduino wrapper to @sdima1357's usb_soft_host esp-idf example"
paragraph="ESP32-USB-Soft-Host is a pure software USB host through general IO pins. It can connect up to 4 USB-LS HID (keyboard mouse joystick) devices simultaneously."
category=Data Processing
category=Device Control
includes=ESP32-USB-Soft-Host.h
url=https://github.com/tobozo/ESP32-USB-Soft-Host/
architectures=esp32
12 changes: 12 additions & 0 deletions src/ESP32-USB-Soft-Host.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#ifdef __cplusplus

#include "ESP32-USBSoftHost.hpp"

#else

#error ESP32-USB-Soft-Host requires a C++ compiler, please change file extension to .cc or .cpp

#endif

112 changes: 101 additions & 11 deletions src/ESP32-USBSoftHost.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#ifndef BLINK_GPIO
#if CONFIG_IDF_TARGET_ESP32C3 || defined ESP32C3
#define BLINK_GPIO 18
#elif CONFIG_IDF_TARGET_ESP32S2 || defined ESP32S2
#define BLINK_GPIO 2 //19 // 9 // 2
#else
#define BLINK_GPIO 22
#endif
Expand All @@ -15,6 +17,7 @@ extern "C" {
#include "usb_host.h"
}


static xQueueHandle usb_msg_queue = NULL;

struct USBMessage
Expand Down Expand Up @@ -81,6 +84,54 @@ static void Default_USB_DataCB(uint8_t usbNum, uint8_t byte_depth, uint8_t* data
}


#if !defined USE_NATIVE_GROUP_TIMERS

typedef struct
{
int type; // the type of timer's event
int timer_group;
int timer_idx;
uint64_t timer_counter_value;
} timer_event_t;
static xQueueHandle timer_queue = NULL;

void IRAM_ATTR timer_group0_isr(void *para)
{
// this is mainly a group-timer layer for esp-idf 3.x
// most of this is handled by the SDK since esp-idf 4.x
int timer_idx = (int) para;
uint32_t intr_status = TIMERG0.int_st_timers.val;// Retrieve the interrupt status and the counter value from the timer that reported the interrupt
TIMERG0.hw_timer[timer_idx].update = 1;
uint64_t timer_counter_value = ((uint64_t) TIMERG0.hw_timer[timer_idx].cnt_high) << 32 | TIMERG0.hw_timer[timer_idx].cnt_low;
timer_event_t evt; // Prepare basic event data that will be then sent back to the main program task
evt.timer_group = 0;
evt.timer_idx = timer_idx;
evt.timer_counter_value = timer_counter_value;
usb_process();// process USB signal
if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) { // Clear the interrupt and update the alarm time for the timer with without reload
evt.type = 1; // no reload
TIMERG0.int_clr_timers.t0 = 1;
timer_counter_value += (uint64_t) (TIMER_INTERVAL0_SEC * TIMER_SCALE);
TIMERG0.hw_timer[timer_idx].alarm_high = (uint32_t) (timer_counter_value >> 32);
TIMERG0.hw_timer[timer_idx].alarm_low = (uint32_t) timer_counter_value;
}
TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN; // After the alarm has been triggered we need enable it again, so it is triggered the next time
xQueueSendFromISR(timer_queue, &evt, NULL); // Now just send the event data back to the main program task

}

#else

void IRAM_ATTR timer_group0_isr(void *para)
{
timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
//taskENTER_CRITICAL();
usb_process();
//taskEXIT_CRITICAL();
timer_group_enable_alarm_in_isr(TIMER_GROUP_0, TIMER_0);
}

#endif


class USB_SOFT_HOST
Expand Down Expand Up @@ -116,14 +167,19 @@ class USB_SOFT_HOST

bool USB_SOFT_HOST::init( usb_pins_config_t pconf, ondetectcb_t onDetectCB, printcb_t onDataCB, ontick_t onTickCB )
{
Serial.println("Attaching onDetectCB");
setOndetectCb( onDetectCB );
Serial.println("Attaching onDataCB");
setPrintCb( onDataCB );
Serial.println("Attaching onUSBMessageDecode");
setUSBMessageCb( onUSBMessageDecode );
//setMessageReceiver(
Serial.println("Attaching onTickCB");
USB_SOFT_HOST::setTaskTicker( onTickCB );
if( _init( pconf ) ) {
Serial.println("Attaching Timer Task");
xTaskCreatePinnedToCore(USB_SOFT_HOST::TimerTask, "USB Soft Host Timer Task", 8192, NULL, priority, NULL, core);
log_w("USB Soft Host Group timer task is now running on core #%d with priority %d", core, priority);
//xTaskCreate(USB_SOFT_HOST::TimerTask, "USB Soft Host Timer Task", 8192, NULL, priority, NULL);
Serial.printf("USB Soft Host Group timer task is now running on core #%d with priority %d\n", core, priority);
return true;
}
return false;
Expand All @@ -135,36 +191,70 @@ bool USB_SOFT_HOST::_init( usb_pins_config_t pconf )
{
if( inited ) return false;

timer_config_t config;
config.divider = TIMER_DIVIDER;
config.counter_dir = TIMER_COUNT_UP;
config.counter_en = TIMER_PAUSE;
config.alarm_en = TIMER_ALARM_EN;
config.auto_reload = (timer_autoreload_t) 1; // fix for ¬invalid conversion from 'int' to 'timer_autoreload_t'¬ thanks rudi ;-)

#if !defined USE_NATIVE_GROUP_TIMERS
Serial.println("Using custom group timer");
timer_queue = xQueueCreate( 10, sizeof(timer_event_t) );
#endif

setDelay(4);
Serial.println("Creating message queue");

usb_msg_queue = xQueueCreate( 10, sizeof(struct USBMessage) );

Serial.println("Setting USB Delay");

setDelay(4);

Serial.println("Setting up pins");

initStates(
(gpio_num_t)pconf.dp0, (gpio_num_t)pconf.dm0,
(gpio_num_t)pconf.dp1, (gpio_num_t)pconf.dm1,
(gpio_num_t)pconf.dp2, (gpio_num_t)pconf.dm2,
(gpio_num_t)pconf.dp3, (gpio_num_t)pconf.dm3
);

Serial.printf("Seleting SCL (blink) Pin #%d\n", BLINK_GPIO);

gpio_pad_select_gpio((gpio_num_t)BLINK_GPIO);
//gpio_set_direction((gpio_num_t)BLINK_GPIO, GPIO_MODE_OUTPUT);
gpio_set_direction((gpio_num_t)BLINK_GPIO, GPIO_MODE_OUTPUT);

Serial.println("Creating timer config");

#if defined ESP32 || defined ESP32S2
timer_config_t config;
config.divider = TIMER_DIVIDER;
config.counter_dir = TIMER_COUNT_UP;
config.counter_en = TIMER_PAUSE;
config.alarm_en = TIMER_ALARM_EN;
config.intr_type = TIMER_INTR_MAX;
config.auto_reload = (timer_autoreload_t) 1; // fix for ¬invalid conversion from 'int' to 'timer_autoreload_t'¬ thanks rudi ;-)
#elif defined ESP32C3
timer_config_t config =
{
.clk_src = TIMER_SRC_CLK_XTAL, // TIMER_SRC_CLK_DEFAULT ?
.alarm_en = TIMER_ALARM_EN,//enable timer alarm
.counter_en = TIMER_PAUSE,//starts counting counter once timer_init called
.intr_type = TIMER_INTR_MAX,
.counter_dir = TIMER_COUNT_UP,//counts from 0 to counter value
.auto_reload = TIMER_AUTORELOAD_EN,// reloads counter automatically
.divider = TIMER_DIVIDER
};
//#elif defined ESP32S2
#else
#error "Invalid board"
#endif



Serial.println("Init timer");
timer_init(TIMER_GROUP_0, TIMER_0, &config);
timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0x00000000ULL);
timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, (double)TIMER_INTERVAL0_SEC * TIMER_SCALE);
Serial.println("Enable interrupt");
timer_enable_intr(TIMER_GROUP_0, TIMER_0);
Serial.println("Register ISR");
timer_isr_register(TIMER_GROUP_0, TIMER_0, timer_group0_isr, (void *) TIMER_0, ESP_INTR_FLAG_IRAM, NULL);
Serial.println("Start timer");
timer_start(TIMER_GROUP_0, TIMER_0);

inited = true;
Expand Down
Loading

0 comments on commit edc5281

Please sign in to comment.