Skip to content

Commit

Permalink
Refresh USB logic; callback for events; hotplug in STOP mode; STOP mo…
Browse files Browse the repository at this point in the history
…de in USB SUSPEND; bunch of race conditions in the USB/CDC code; avoid SOF interrupt; 500mA max power in descriptiors
  • Loading branch information
GrumpyOldPizza committed May 5, 2020
1 parent d85e756 commit bdd33df
Show file tree
Hide file tree
Showing 17 changed files with 802 additions and 584 deletions.
132 changes: 78 additions & 54 deletions cores/arduino/USBAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,41 @@ class USBDeviceClass
USBDeviceClass() {};

// USB Device API
void init();
bool begin();
void end();
bool attach();
bool detach();
void poll();
void wakeup();

bool configured();
bool attached();
bool connected();
bool configured();
bool suspended();

void onConnect(void(*callback)(void));
void onConnect(Callback callback);
void onDisconnect(void(*callback)(void));
void onDisconnect(Callback callback);
void onSuspend(void(*callback)(void));
void onSuspend(Callback callback);
void onResume(void(*callback)(void));
void onResume(Callback callback);

void enableWakeup();
void disableWakeup();

private:
bool _initialized;
bool _enabled;

Callback _connectCallback;
Callback _disconnectCallback;
Callback _suspendCallback;
Callback _resumeCallback;

static void connectCallback(void);
static void disconnectCallback(void);
static void suspendCallback(void);
static void resumeCallback(void);
};

extern USBDeviceClass USBDevice;
Expand Down Expand Up @@ -84,16 +108,16 @@ class CDC : public HardwareSerial
bool rts();

enum {
ONE_STOP_BIT = 0,
ONE_AND_HALF_STOP_BIT = 1,
TWO_STOP_BITS = 2,
ONE_STOP_BIT = 0,
ONE_AND_HALF_STOP_BIT = 1,
TWO_STOP_BITS = 2,
};
enum {
NO_PARITY = 0,
ODD_PARITY = 1,
EVEN_PARITY = 2,
MARK_PARITY = 3,
SPACE_PARITY = 4,
NO_PARITY = 0,
ODD_PARITY = 1,
EVEN_PARITY = 2,
MARK_PARITY = 3,
SPACE_PARITY = 4,
};

// STM32L0 EXTENSTION: enable/disable non-blocking writes
Expand Down Expand Up @@ -134,10 +158,10 @@ class MouseClass
void begin(void);
void end(void);
void click(uint8_t b = MOUSE_LEFT);
void move(signed char x, signed char y, signed char wheel = 0);
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
void move(signed char x, signed char y, signed char wheel = 0);
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default

private:
uint8_t _buttons;
Expand All @@ -146,44 +170,44 @@ class MouseClass

extern MouseClass Mouse;

#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87

#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
#define KEY_BACKSPACE 0xB2
#define KEY_TAB 0xB3
#define KEY_RETURN 0xB0
#define KEY_ESC 0xB1
#define KEY_INSERT 0xD1
#define KEY_DELETE 0xD4
#define KEY_PAGE_UP 0xD3
#define KEY_PAGE_DOWN 0xD6
#define KEY_HOME 0xD2
#define KEY_END 0xD5
#define KEY_CAPS_LOCK 0xC1
#define KEY_F1 0xC2
#define KEY_F2 0xC3
#define KEY_F3 0xC4
#define KEY_F4 0xC5
#define KEY_F5 0xC6
#define KEY_F6 0xC7
#define KEY_F7 0xC8
#define KEY_F8 0xC9
#define KEY_F9 xCA
#define KEY_F10 0xCB
#define KEY_F11 0xCC
#define KEY_F12 0xCD

// Low level key report: up to 6 keys and shift, ctrl etc at once
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87

#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
#define KEY_BACKSPACE 0xB2
#define KEY_TAB 0xB3
#define KEY_RETURN 0xB0
#define KEY_ESC 0xB1
#define KEY_INSERT 0xD1
#define KEY_DELETE 0xD4
#define KEY_PAGE_UP 0xD3
#define KEY_PAGE_DOWN 0xD6
#define KEY_HOME 0xD2
#define KEY_END 0xD5
#define KEY_CAPS_LOCK 0xC1
#define KEY_F1 0xC2
#define KEY_F2 0xC3
#define KEY_F3 0xC4
#define KEY_F4 0xC5
#define KEY_F5 0xC6
#define KEY_F6 0xC7
#define KEY_F7 0xC8
#define KEY_F8 0xC9
#define KEY_F9 xCA
#define KEY_F10 0xCB
#define KEY_F11 0xCC
#define KEY_F12 0xCD

// Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
{
uint8_t modifiers;
Expand Down
122 changes: 111 additions & 11 deletions cores/arduino/USBCore.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2018 Thomas Roell. All rights reserved.
* Copyright (c) 2016-2020 Thomas Roell. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
Expand Down Expand Up @@ -59,20 +59,37 @@
#endif
#endif

void USBDeviceClass::init()
bool USBDeviceClass::begin()
{
#if defined(USB_CLASS)
USBD_Initialize(USB_VID, USB_PID, (const uint8_t*)USB_MANUFACTURER, (const uint8_t*)USB_PRODUCT, USB_CLASS, STM32L0_CONFIG_PIN_VBUS, STM32L0_USB_IRQ_PRIORITY);
if (!_enabled) {
_enabled = USBD_Initialize(USB_VID, USB_PID, (const uint8_t*)USB_MANUFACTURER, (const uint8_t*)USB_PRODUCT, USB_CLASS,
STM32L0_CONFIG_PIN_VBUS, STM32L0_USB_IRQ_PRIORITY,
&USBDeviceClass::connectCallback, &USBDeviceClass::disconnectCallback, &USBDeviceClass::suspendCallback, &USBDeviceClass::resumeCallback);
}

return _enabled;
#endif
return false;
}

_initialized = true;
void USBDeviceClass::end()
{
#if defined(USB_CLASS)
if (_enabled)
{
USBD_Teardown();

_enabled = false;
}
#endif
}

bool USBDeviceClass::attach()
{
#if defined(USB_CLASS)
if (!_initialized) {
return false;
if (!_enabled) {
return false;
}

USBD_Attach();
Expand All @@ -86,8 +103,8 @@ bool USBDeviceClass::attach()
bool USBDeviceClass::detach()
{
#if defined(USB_CLASS)
if (!_initialized) {
return false;
if (!_enabled) {
return false;
}

USBD_Detach();
Expand All @@ -98,15 +115,24 @@ bool USBDeviceClass::detach()
#endif
}

void USBDeviceClass::poll()
void USBDeviceClass::wakeup()
{
#if defined(USB_CLASS)
if (_initialized) {
USBD_Poll();
if (_enabled) {
USBD_Wakeup();
}
#endif
}

bool USBDeviceClass::attached()
{
#if defined(USB_CLASS)
return USBD_Attached();
#else
return false;
#endif
}

bool USBDeviceClass::connected()
{
#if defined(USB_CLASS)
Expand Down Expand Up @@ -134,6 +160,80 @@ bool USBDeviceClass::suspended()
#endif
}

void USBDeviceClass::onConnect(void(*callback)(void))
{
_connectCallback = Callback(callback);
}

void USBDeviceClass::onConnect(Callback callback)
{
_connectCallback = callback;
}

void USBDeviceClass::onDisconnect(void(*callback)(void))
{
_disconnectCallback = Callback(callback);
}

void USBDeviceClass::onDisconnect(Callback callback)
{
_disconnectCallback = callback;
}

void USBDeviceClass::onSuspend(void(*callback)(void))
{
_suspendCallback = Callback(callback);
}

void USBDeviceClass::onSuspend(Callback callback)
{
_suspendCallback = callback;
}

void USBDeviceClass::onResume(void(*callback)(void))
{
_resumeCallback = Callback(callback);
}

void USBDeviceClass::onResume(Callback callback)
{
_resumeCallback = callback;
}

void USBDeviceClass::enableWakeup()
{
if (_enabled) {
USBD_SetupVBUS(false);
}
}

void USBDeviceClass::disableWakeup()
{
if (_enabled) {
USBD_SetupVBUS(true);
}
}

void USBDeviceClass::connectCallback(void)
{
USBDevice._connectCallback.queue();
}

void USBDeviceClass::disconnectCallback(void)
{
USBDevice._disconnectCallback.queue();
}

void USBDeviceClass::suspendCallback(void)
{
USBDevice._suspendCallback.queue();
}

void USBDeviceClass::resumeCallback(void)
{
USBDevice._resumeCallback.queue();
}

USBDeviceClass USBDevice;

#endif /* USBCON */
Expand Down
3 changes: 1 addition & 2 deletions cores/arduino/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ int main( void )

__libc_init_array();

delay(1);
#if defined(USBCON)
USBDevice.init();
USBDevice.begin();
USBDevice.attach();
#endif

Expand Down
10 changes: 8 additions & 2 deletions cores/arduino/wiring_private.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018 Thomas Roell. All rights reserved.
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
Expand Down Expand Up @@ -61,13 +61,19 @@ extern void USBD_CDC_MSC_Initialize(void *);
extern void USBD_CDC_HID_Initialize(void *);
extern void USBD_CDC_MSC_HID_Initialize(void *);

extern void USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, const uint8_t *product, void(*initialize)(void *), unsigned int pin_vbus, unsigned int priority);
extern bool USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, const uint8_t *product, void(*initialize)(void *),
unsigned int pin_vbus, unsigned int priority,
void(*connect_callback)(void), void(*disconnect_callback)(void), void(*suspend_callback)(void), void(*resume_callback)(void));
extern void USBD_Teardown(void);
extern void USBD_Attach(void);
extern void USBD_Detach(void);
extern void USBD_Wakeup(void);
extern void USBD_Poll(void);
extern bool USBD_Attached(void);
extern bool USBD_Connected(void);
extern bool USBD_Configured(void);
extern bool USBD_Suspended(void);
extern void USBD_SetupVBUS(bool park);

extern void CMWX1ZZABZ_Initialize(uint16_t pin_tcxo, uint16_t pin_stsafe);
extern void SX1272MB2DAS_Initialize(void);
Expand Down
4 changes: 3 additions & 1 deletion system/STM32L0xx/Include/armv6m_atomic.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2018 Thomas Roell. All rights reserved.
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
Expand Down Expand Up @@ -592,11 +592,13 @@ extern uint32_t armv6m_atomic_cas(volatile uint32_t *p_data, uint32_t data_expec

extern uint32_t armv6m_atomic_andh(volatile uint16_t *p_data, uint32_t data);
extern uint32_t armv6m_atomic_orh(volatile uint16_t *p_data, uint32_t data);
extern uint32_t armv6m_atomic_swaph(volatile uint16_t *p_data, uint32_t data);
extern uint32_t armv6m_atomic_cash(volatile uint16_t *p_data, uint32_t data_expected, uint32_t data);
extern uint32_t armv6m_atomic_andb(volatile uint8_t *p_data, uint32_t data);
extern uint32_t armv6m_atomic_orb(volatile uint8_t *p_data, uint32_t data);
extern uint32_t armv6m_atomic_decb(volatile uint8_t *p_data);
extern uint32_t armv6m_atomic_incb(volatile uint8_t *p_data);
extern uint32_t armv6m_atomic_swapb(volatile uint8_t *p_data, uint32_t data);
extern uint32_t armv6m_atomic_casb(volatile uint8_t *p_data, uint32_t data_expected, uint32_t data);

/* *p_data = (*p_data & ~mask) ^ data */
Expand Down
Loading

0 comments on commit bdd33df

Please sign in to comment.