Skip to content

Commit bdd33df

Browse files
Refresh USB logic; callback for events; hotplug in STOP mode; STOP mode in USB SUSPEND; bunch of race conditions in the USB/CDC code; avoid SOF interrupt; 500mA max power in descriptiors
1 parent d85e756 commit bdd33df

17 files changed

+802
-584
lines changed

cores/arduino/USBAPI.h

Lines changed: 78 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,41 @@ class USBDeviceClass
3636
USBDeviceClass() {};
3737

3838
// USB Device API
39-
void init();
39+
bool begin();
40+
void end();
4041
bool attach();
4142
bool detach();
42-
void poll();
43+
void wakeup();
4344

44-
bool configured();
45+
bool attached();
4546
bool connected();
47+
bool configured();
4648
bool suspended();
4749

50+
void onConnect(void(*callback)(void));
51+
void onConnect(Callback callback);
52+
void onDisconnect(void(*callback)(void));
53+
void onDisconnect(Callback callback);
54+
void onSuspend(void(*callback)(void));
55+
void onSuspend(Callback callback);
56+
void onResume(void(*callback)(void));
57+
void onResume(Callback callback);
58+
59+
void enableWakeup();
60+
void disableWakeup();
61+
4862
private:
49-
bool _initialized;
63+
bool _enabled;
64+
65+
Callback _connectCallback;
66+
Callback _disconnectCallback;
67+
Callback _suspendCallback;
68+
Callback _resumeCallback;
69+
70+
static void connectCallback(void);
71+
static void disconnectCallback(void);
72+
static void suspendCallback(void);
73+
static void resumeCallback(void);
5074
};
5175

5276
extern USBDeviceClass USBDevice;
@@ -84,16 +108,16 @@ class CDC : public HardwareSerial
84108
bool rts();
85109

86110
enum {
87-
ONE_STOP_BIT = 0,
88-
ONE_AND_HALF_STOP_BIT = 1,
89-
TWO_STOP_BITS = 2,
111+
ONE_STOP_BIT = 0,
112+
ONE_AND_HALF_STOP_BIT = 1,
113+
TWO_STOP_BITS = 2,
90114
};
91115
enum {
92-
NO_PARITY = 0,
93-
ODD_PARITY = 1,
94-
EVEN_PARITY = 2,
95-
MARK_PARITY = 3,
96-
SPACE_PARITY = 4,
116+
NO_PARITY = 0,
117+
ODD_PARITY = 1,
118+
EVEN_PARITY = 2,
119+
MARK_PARITY = 3,
120+
SPACE_PARITY = 4,
97121
};
98122

99123
// STM32L0 EXTENSTION: enable/disable non-blocking writes
@@ -134,10 +158,10 @@ class MouseClass
134158
void begin(void);
135159
void end(void);
136160
void click(uint8_t b = MOUSE_LEFT);
137-
void move(signed char x, signed char y, signed char wheel = 0);
138-
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
139-
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
140-
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
161+
void move(signed char x, signed char y, signed char wheel = 0);
162+
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
163+
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
164+
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
141165

142166
private:
143167
uint8_t _buttons;
@@ -146,44 +170,44 @@ class MouseClass
146170

147171
extern MouseClass Mouse;
148172

149-
#define KEY_LEFT_CTRL 0x80
150-
#define KEY_LEFT_SHIFT 0x81
151-
#define KEY_LEFT_ALT 0x82
152-
#define KEY_LEFT_GUI 0x83
153-
#define KEY_RIGHT_CTRL 0x84
154-
#define KEY_RIGHT_SHIFT 0x85
155-
#define KEY_RIGHT_ALT 0x86
156-
#define KEY_RIGHT_GUI 0x87
157-
158-
#define KEY_UP_ARROW 0xDA
159-
#define KEY_DOWN_ARROW 0xD9
160-
#define KEY_LEFT_ARROW 0xD8
161-
#define KEY_RIGHT_ARROW 0xD7
162-
#define KEY_BACKSPACE 0xB2
163-
#define KEY_TAB 0xB3
164-
#define KEY_RETURN 0xB0
165-
#define KEY_ESC 0xB1
166-
#define KEY_INSERT 0xD1
167-
#define KEY_DELETE 0xD4
168-
#define KEY_PAGE_UP 0xD3
169-
#define KEY_PAGE_DOWN 0xD6
170-
#define KEY_HOME 0xD2
171-
#define KEY_END 0xD5
172-
#define KEY_CAPS_LOCK 0xC1
173-
#define KEY_F1 0xC2
174-
#define KEY_F2 0xC3
175-
#define KEY_F3 0xC4
176-
#define KEY_F4 0xC5
177-
#define KEY_F5 0xC6
178-
#define KEY_F6 0xC7
179-
#define KEY_F7 0xC8
180-
#define KEY_F8 0xC9
181-
#define KEY_F9 xCA
182-
#define KEY_F10 0xCB
183-
#define KEY_F11 0xCC
184-
#define KEY_F12 0xCD
185-
186-
// Low level key report: up to 6 keys and shift, ctrl etc at once
173+
#define KEY_LEFT_CTRL 0x80
174+
#define KEY_LEFT_SHIFT 0x81
175+
#define KEY_LEFT_ALT 0x82
176+
#define KEY_LEFT_GUI 0x83
177+
#define KEY_RIGHT_CTRL 0x84
178+
#define KEY_RIGHT_SHIFT 0x85
179+
#define KEY_RIGHT_ALT 0x86
180+
#define KEY_RIGHT_GUI 0x87
181+
182+
#define KEY_UP_ARROW 0xDA
183+
#define KEY_DOWN_ARROW 0xD9
184+
#define KEY_LEFT_ARROW 0xD8
185+
#define KEY_RIGHT_ARROW 0xD7
186+
#define KEY_BACKSPACE 0xB2
187+
#define KEY_TAB 0xB3
188+
#define KEY_RETURN 0xB0
189+
#define KEY_ESC 0xB1
190+
#define KEY_INSERT 0xD1
191+
#define KEY_DELETE 0xD4
192+
#define KEY_PAGE_UP 0xD3
193+
#define KEY_PAGE_DOWN 0xD6
194+
#define KEY_HOME 0xD2
195+
#define KEY_END 0xD5
196+
#define KEY_CAPS_LOCK 0xC1
197+
#define KEY_F1 0xC2
198+
#define KEY_F2 0xC3
199+
#define KEY_F3 0xC4
200+
#define KEY_F4 0xC5
201+
#define KEY_F5 0xC6
202+
#define KEY_F6 0xC7
203+
#define KEY_F7 0xC8
204+
#define KEY_F8 0xC9
205+
#define KEY_F9 xCA
206+
#define KEY_F10 0xCB
207+
#define KEY_F11 0xCC
208+
#define KEY_F12 0xCD
209+
210+
// Low level key report: up to 6 keys and shift, ctrl etc at once
187211
typedef struct
188212
{
189213
uint8_t modifiers;

cores/arduino/USBCore.cpp

Lines changed: 111 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016-2018 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2016-2020 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -59,20 +59,37 @@
5959
#endif
6060
#endif
6161

62-
void USBDeviceClass::init()
62+
bool USBDeviceClass::begin()
6363
{
6464
#if defined(USB_CLASS)
65-
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);
65+
if (!_enabled) {
66+
_enabled = USBD_Initialize(USB_VID, USB_PID, (const uint8_t*)USB_MANUFACTURER, (const uint8_t*)USB_PRODUCT, USB_CLASS,
67+
STM32L0_CONFIG_PIN_VBUS, STM32L0_USB_IRQ_PRIORITY,
68+
&USBDeviceClass::connectCallback, &USBDeviceClass::disconnectCallback, &USBDeviceClass::suspendCallback, &USBDeviceClass::resumeCallback);
69+
}
70+
71+
return _enabled;
6672
#endif
73+
return false;
74+
}
6775

68-
_initialized = true;
76+
void USBDeviceClass::end()
77+
{
78+
#if defined(USB_CLASS)
79+
if (_enabled)
80+
{
81+
USBD_Teardown();
82+
83+
_enabled = false;
84+
}
85+
#endif
6986
}
7087

7188
bool USBDeviceClass::attach()
7289
{
7390
#if defined(USB_CLASS)
74-
if (!_initialized) {
75-
return false;
91+
if (!_enabled) {
92+
return false;
7693
}
7794

7895
USBD_Attach();
@@ -86,8 +103,8 @@ bool USBDeviceClass::attach()
86103
bool USBDeviceClass::detach()
87104
{
88105
#if defined(USB_CLASS)
89-
if (!_initialized) {
90-
return false;
106+
if (!_enabled) {
107+
return false;
91108
}
92109

93110
USBD_Detach();
@@ -98,15 +115,24 @@ bool USBDeviceClass::detach()
98115
#endif
99116
}
100117

101-
void USBDeviceClass::poll()
118+
void USBDeviceClass::wakeup()
102119
{
103120
#if defined(USB_CLASS)
104-
if (_initialized) {
105-
USBD_Poll();
121+
if (_enabled) {
122+
USBD_Wakeup();
106123
}
107124
#endif
108125
}
109126

127+
bool USBDeviceClass::attached()
128+
{
129+
#if defined(USB_CLASS)
130+
return USBD_Attached();
131+
#else
132+
return false;
133+
#endif
134+
}
135+
110136
bool USBDeviceClass::connected()
111137
{
112138
#if defined(USB_CLASS)
@@ -134,6 +160,80 @@ bool USBDeviceClass::suspended()
134160
#endif
135161
}
136162

163+
void USBDeviceClass::onConnect(void(*callback)(void))
164+
{
165+
_connectCallback = Callback(callback);
166+
}
167+
168+
void USBDeviceClass::onConnect(Callback callback)
169+
{
170+
_connectCallback = callback;
171+
}
172+
173+
void USBDeviceClass::onDisconnect(void(*callback)(void))
174+
{
175+
_disconnectCallback = Callback(callback);
176+
}
177+
178+
void USBDeviceClass::onDisconnect(Callback callback)
179+
{
180+
_disconnectCallback = callback;
181+
}
182+
183+
void USBDeviceClass::onSuspend(void(*callback)(void))
184+
{
185+
_suspendCallback = Callback(callback);
186+
}
187+
188+
void USBDeviceClass::onSuspend(Callback callback)
189+
{
190+
_suspendCallback = callback;
191+
}
192+
193+
void USBDeviceClass::onResume(void(*callback)(void))
194+
{
195+
_resumeCallback = Callback(callback);
196+
}
197+
198+
void USBDeviceClass::onResume(Callback callback)
199+
{
200+
_resumeCallback = callback;
201+
}
202+
203+
void USBDeviceClass::enableWakeup()
204+
{
205+
if (_enabled) {
206+
USBD_SetupVBUS(false);
207+
}
208+
}
209+
210+
void USBDeviceClass::disableWakeup()
211+
{
212+
if (_enabled) {
213+
USBD_SetupVBUS(true);
214+
}
215+
}
216+
217+
void USBDeviceClass::connectCallback(void)
218+
{
219+
USBDevice._connectCallback.queue();
220+
}
221+
222+
void USBDeviceClass::disconnectCallback(void)
223+
{
224+
USBDevice._disconnectCallback.queue();
225+
}
226+
227+
void USBDeviceClass::suspendCallback(void)
228+
{
229+
USBDevice._suspendCallback.queue();
230+
}
231+
232+
void USBDeviceClass::resumeCallback(void)
233+
{
234+
USBDevice._resumeCallback.queue();
235+
}
236+
137237
USBDeviceClass USBDevice;
138238

139239
#endif /* USBCON */

cores/arduino/main.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ int main( void )
5050

5151
__libc_init_array();
5252

53-
delay(1);
5453
#if defined(USBCON)
55-
USBDevice.init();
54+
USBDevice.begin();
5655
USBDevice.attach();
5756
#endif
5857

cores/arduino/wiring_private.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2018 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -61,13 +61,19 @@ extern void USBD_CDC_MSC_Initialize(void *);
6161
extern void USBD_CDC_HID_Initialize(void *);
6262
extern void USBD_CDC_MSC_HID_Initialize(void *);
6363

64-
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);
64+
extern bool USBD_Initialize(uint16_t vid, uint16_t pid, const uint8_t *manufacturer, const uint8_t *product, void(*initialize)(void *),
65+
unsigned int pin_vbus, unsigned int priority,
66+
void(*connect_callback)(void), void(*disconnect_callback)(void), void(*suspend_callback)(void), void(*resume_callback)(void));
67+
extern void USBD_Teardown(void);
6568
extern void USBD_Attach(void);
6669
extern void USBD_Detach(void);
70+
extern void USBD_Wakeup(void);
6771
extern void USBD_Poll(void);
72+
extern bool USBD_Attached(void);
6873
extern bool USBD_Connected(void);
6974
extern bool USBD_Configured(void);
7075
extern bool USBD_Suspended(void);
76+
extern void USBD_SetupVBUS(bool park);
7177

7278
extern void CMWX1ZZABZ_Initialize(uint16_t pin_tcxo, uint16_t pin_stsafe);
7379
extern void SX1272MB2DAS_Initialize(void);

system/STM32L0xx/Include/armv6m_atomic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017-2018 Thomas Roell. All rights reserved.
2+
* Copyright (c) 2017-2020 Thomas Roell. All rights reserved.
33
*
44
* Permission is hereby granted, free of charge, to any person obtaining a copy
55
* of this software and associated documentation files (the "Software"), to
@@ -592,11 +592,13 @@ extern uint32_t armv6m_atomic_cas(volatile uint32_t *p_data, uint32_t data_expec
592592

593593
extern uint32_t armv6m_atomic_andh(volatile uint16_t *p_data, uint32_t data);
594594
extern uint32_t armv6m_atomic_orh(volatile uint16_t *p_data, uint32_t data);
595+
extern uint32_t armv6m_atomic_swaph(volatile uint16_t *p_data, uint32_t data);
595596
extern uint32_t armv6m_atomic_cash(volatile uint16_t *p_data, uint32_t data_expected, uint32_t data);
596597
extern uint32_t armv6m_atomic_andb(volatile uint8_t *p_data, uint32_t data);
597598
extern uint32_t armv6m_atomic_orb(volatile uint8_t *p_data, uint32_t data);
598599
extern uint32_t armv6m_atomic_decb(volatile uint8_t *p_data);
599600
extern uint32_t armv6m_atomic_incb(volatile uint8_t *p_data);
601+
extern uint32_t armv6m_atomic_swapb(volatile uint8_t *p_data, uint32_t data);
600602
extern uint32_t armv6m_atomic_casb(volatile uint8_t *p_data, uint32_t data_expected, uint32_t data);
601603

602604
/* *p_data = (*p_data & ~mask) ^ data */

0 commit comments

Comments
 (0)