Skip to content

Commit 038df43

Browse files
committed
stmhal: Implement selector for USB device mode; improve boot up.
Can now choose at boot up whether the USB device is CDC+MSC or CDC+HID. Choice is made by an option in boot.py, with default being CDC+MSC. HID+MSC is not currently supported, but should be easy to implement. Boot up now has ability to change the reset mode: hold down USR switch while booting and LEDs will count from 1 to 7 to indicate the boot mode. Release USR when correct mode is selected. Current modes are 1 (normal boot), 2 (safe mode), 3 (reset FS mode).
1 parent d40d8f1 commit 038df43

21 files changed

Lines changed: 3513 additions & 113 deletions

stmhal/Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ INC += -I$(PY_SRC)
2121
INC += -I$(CMSIS_DIR)/inc
2222
INC += -I$(CMSIS_DIR)/devinc
2323
INC += -I$(HAL_DIR)/inc
24-
INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc_msc/inc
24+
INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/cdc_msc_hid/inc
2525
#INC += -I$(USBHOST_DIR)
2626
INC += -I$(FATFS_DIR)/src
2727
#INC += -I$(CC3K_DIR)
@@ -135,10 +135,10 @@ SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\
135135
core/src/usbd_core.c \
136136
core/src/usbd_ctlreq.c \
137137
core/src/usbd_ioreq.c \
138-
class/cdc_msc/src/usbd_cdc_msc.c \
139-
class/cdc_msc/src/usbd_msc_bot.c \
140-
class/cdc_msc/src/usbd_msc_scsi.c \
141-
class/cdc_msc/src/usbd_msc_data.c \
138+
class/cdc_msc_hid/src/usbd_cdc_msc_hid.c \
139+
class/cdc_msc_hid/src/usbd_msc_bot.c \
140+
class/cdc_msc_hid/src/usbd_msc_scsi.c \
141+
class/cdc_msc_hid/src/usbd_msc_data.c \
142142
)
143143

144144
# class/cdc/src/usbd_cdc.c \

stmhal/led.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <stdio.h>
22
#include <stm32f4xx_hal.h>
3-
#include "usbd_cdc_msc.h"
3+
#include "usbd_cdc_msc_hid.h"
44
#include "usbd_cdc_interface.h"
55

66
#include "nlr.h"

stmhal/main.c

Lines changed: 91 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ void __fatal_error(const char *msg) {
7575

7676
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
7777
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
78+
STATIC mp_obj_t pyb_config_usb_mode = MP_OBJ_NULL;
7879

7980
STATIC mp_obj_t pyb_source_dir(mp_obj_t source_dir) {
8081
if (MP_OBJ_IS_STR(source_dir)) {
@@ -94,6 +95,15 @@ STATIC mp_obj_t pyb_main(mp_obj_t main) {
9495

9596
MP_DEFINE_CONST_FUN_OBJ_1(pyb_main_obj, pyb_main);
9697

98+
STATIC mp_obj_t pyb_usb_mode(mp_obj_t usb_mode) {
99+
if (MP_OBJ_IS_STR(usb_mode)) {
100+
pyb_config_usb_mode = usb_mode;
101+
}
102+
return mp_const_none;
103+
}
104+
105+
MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_mode_obj, pyb_usb_mode);
106+
97107
void fatality(void) {
98108
led_state(PYB_LED_R1, 1);
99109
led_state(PYB_LED_G1, 1);
@@ -109,12 +119,9 @@ static const char fresh_boot_py[] =
109119
"# can run arbitrary Python, but best to keep it minimal\n"
110120
"\n"
111121
"import pyb\n"
112-
"pyb.source_dir('/src')\n"
113-
"pyb.main('main.py')\n"
114-
"#pyb.usb_usr('VCP')\n"
115-
"#pyb.usb_msd(True, 'dual partition')\n"
116-
"#pyb.flush_cache(False)\n"
117-
"#pyb.error_log('error.txt')\n"
122+
"#pyb.source_dir('/src')\n"
123+
"#pyb.main('main.py')\n"
124+
"#pyb.usb_mode('CDC+MSC') # one of: 'CDC+MSC', 'CDC+HID'\n"
118125
;
119126

120127
static const char fresh_main_py[] =
@@ -171,23 +178,64 @@ int main(void) {
171178
// basic sub-system init
172179
pendsv_init();
173180
led_init();
181+
switch_init0();
174182

175-
// turn on LED to indicate bootup
176-
led_state(PYB_LED_GREEN, 1);
183+
int first_soft_reset = true;
184+
uint reset_mode;
185+
186+
soft_reset:
187+
188+
// check if user switch held to select the reset mode
189+
reset_mode = 1;
190+
led_state(1, 0);
191+
led_state(2, 1);
192+
led_state(3, 0);
193+
led_state(4, 0);
194+
195+
#if MICROPY_HW_HAS_SWITCH
196+
if (switch_get()) {
197+
for (uint i = 0; i < 3000; i++) {
198+
if (!switch_get()) {
199+
break;
200+
}
201+
HAL_Delay(20);
202+
if (i % 30 == 29) {
203+
reset_mode = (reset_mode + 1) & 7;
204+
led_state(2, reset_mode & 1);
205+
led_state(3, reset_mode & 2);
206+
led_state(4, reset_mode & 4);
207+
}
208+
}
209+
// flash the selected reset mode
210+
for (uint i = 0; i < 6; i++) {
211+
led_state(2, 0);
212+
led_state(3, 0);
213+
led_state(4, 0);
214+
HAL_Delay(50);
215+
led_state(2, reset_mode & 1);
216+
led_state(3, reset_mode & 2);
217+
led_state(4, reset_mode & 4);
218+
HAL_Delay(50);
219+
}
220+
HAL_Delay(400);
221+
}
222+
#endif
177223

178224
#if MICROPY_HW_ENABLE_RTC
179-
rtc_init();
225+
if (first_soft_reset) {
226+
rtc_init();
227+
}
180228
#endif
181229

182230
// more sub-system init
183231
#if MICROPY_HW_HAS_SDCARD
184-
sdcard_init();
232+
if (first_soft_reset) {
233+
sdcard_init();
234+
}
185235
#endif
186-
storage_init();
187-
188-
int first_soft_reset = true;
189-
190-
soft_reset:
236+
if (first_soft_reset) {
237+
storage_init();
238+
}
191239

192240
// GC init
193241
gc_init(&_heap_start, &_heap_end);
@@ -215,6 +263,7 @@ int main(void) {
215263
exti_init();
216264

217265
#if MICROPY_HW_HAS_SWITCH
266+
// must come after exti_init
218267
switch_init();
219268
#endif
220269

@@ -225,29 +274,12 @@ int main(void) {
225274

226275
pin_map_init();
227276

228-
// check if user switch held (initiates reset of filesystem)
229-
bool reset_filesystem = false;
230-
#if MICROPY_HW_HAS_SWITCH
231-
if (switch_get()) {
232-
reset_filesystem = true;
233-
for (int i = 0; i < 50; i++) {
234-
if (!switch_get()) {
235-
reset_filesystem = false;
236-
break;
237-
}
238-
HAL_Delay(10);
239-
}
240-
}
241-
#endif
242277
// local filesystem init
243278
{
244279
// try to mount the flash
245280
FRESULT res = f_mount(&fatfs0, "0:", 1);
246-
if (!reset_filesystem && res == FR_OK) {
247-
// mount sucessful
248-
} else if (reset_filesystem || res == FR_NO_FILESYSTEM) {
249-
// no filesystem, so create a fresh one
250-
// TODO doesn't seem to work correctly when reset_filesystem is true...
281+
if (reset_mode == 3 || res == FR_NO_FILESYSTEM) {
282+
// no filesystem, or asked to reset it, so create a fresh one
251283

252284
// LED on to indicate creation of LFS
253285
led_state(PYB_LED_R2, 1);
@@ -275,6 +307,8 @@ int main(void) {
275307
// keep LED on for at least 200ms
276308
sys_tick_wait_at_least(start_tick, 200);
277309
led_state(PYB_LED_R2, 0);
310+
} else if (res == FR_OK) {
311+
// mount sucessful
278312
} else {
279313
__fatal_error("could not access LFS");
280314
}
@@ -317,28 +351,32 @@ int main(void) {
317351
}
318352

319353
// run /boot.py
320-
if (!pyexec_file("0:/boot.py")) {
321-
flash_error(4);
354+
if (reset_mode == 1) {
355+
if (!pyexec_file("0:/boot.py")) {
356+
flash_error(4);
357+
}
322358
}
323359

324-
// turn boot-up LED off
325-
led_state(PYB_LED_GREEN, 0);
360+
// turn boot-up LEDs off
361+
led_state(2, 0);
362+
led_state(3, 0);
363+
led_state(4, 0);
326364

327365
#if defined(USE_DEVICE_MODE)
328-
usbd_storage_medium_kind_t usbd_medium_kind = USBD_STORAGE_MEDIUM_FLASH;
366+
usb_storage_medium_t usb_medium = USB_STORAGE_MEDIUM_FLASH;
329367
#endif
330368

331369
#if MICROPY_HW_HAS_SDCARD
332370
// if an SD card is present then mount it on 1:/
333-
if (sdcard_is_present()) {
371+
if (reset_mode == 1 && sdcard_is_present()) {
334372
FRESULT res = f_mount(&fatfs1, "1:", 1);
335373
if (res != FR_OK) {
336374
printf("[SD] could not mount SD card\n");
337375
} else {
338376
if (first_soft_reset) {
339377
// use SD card as medium for the USB MSD
340378
#if defined(USE_DEVICE_MODE)
341-
usbd_medium_kind = USBD_STORAGE_MEDIUM_SDCARD;
379+
usb_medium = USB_STORAGE_MEDIUM_SDCARD;
342380
#endif
343381
}
344382
}
@@ -353,7 +391,17 @@ int main(void) {
353391
pyb_usb_host_init();
354392
#elif defined(USE_DEVICE_MODE)
355393
// USB device
356-
pyb_usb_dev_init(USBD_DEVICE_CDC_MSC, usbd_medium_kind);
394+
if (reset_mode == 1) {
395+
usb_device_mode_t usb_mode = USB_DEVICE_MODE_CDC_MSC;
396+
if (pyb_config_usb_mode != MP_OBJ_NULL) {
397+
if (strcmp(mp_obj_str_get_str(pyb_config_usb_mode), "CDC+HID") == 0) {
398+
usb_mode = USB_DEVICE_MODE_CDC_HID;
399+
}
400+
}
401+
pyb_usb_dev_init(usb_mode, usb_medium);
402+
} else {
403+
pyb_usb_dev_init(USB_DEVICE_MODE_CDC_MSC, usb_medium);
404+
}
357405
#endif
358406

359407
#if MICROPY_HW_ENABLE_RNG
@@ -387,7 +435,7 @@ int main(void) {
387435
#endif
388436

389437
// run main script
390-
{
438+
if (reset_mode == 1) {
391439
vstr_t *vstr = vstr_new();
392440
vstr_add_str(vstr, "0:/");
393441
if (pyb_config_source_dir == MP_OBJ_NULL) {
@@ -408,41 +456,6 @@ int main(void) {
408456
}
409457

410458
#if 0
411-
#if MICROPY_HW_HAS_MMA7660
412-
// HID example
413-
if (0) {
414-
uint8_t data[4];
415-
data[0] = 0;
416-
data[1] = 1;
417-
data[2] = -2;
418-
data[3] = 0;
419-
for (;;) {
420-
#if MICROPY_HW_HAS_SWITCH
421-
if (switch_get()) {
422-
data[0] = 0x01; // 0x04 is middle, 0x02 is right
423-
} else {
424-
data[0] = 0x00;
425-
}
426-
#else
427-
data[0] = 0x00;
428-
#endif
429-
accel_start(0x4c /* ACCEL_ADDR */, 1);
430-
accel_send_byte(0);
431-
accel_restart(0x4c /* ACCEL_ADDR */, 0);
432-
for (int i = 0; i <= 1; i++) {
433-
int v = accel_read_ack() & 0x3f;
434-
if (v & 0x20) {
435-
v |= ~0x1f;
436-
}
437-
data[1 + i] = v;
438-
}
439-
accel_read_nack();
440-
usb_hid_send_report(data);
441-
HAL_Delay(15);
442-
}
443-
}
444-
#endif
445-
446459
#if MICROPY_HW_HAS_WLAN
447460
// wifi
448461
pyb_wlan_init();

stmhal/modpyb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_input_obj, pyb_input);
208208

209209
MP_DECLARE_CONST_FUN_OBJ(pyb_source_dir_obj); // defined in main.c
210210
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
211+
MP_DECLARE_CONST_FUN_OBJ(pyb_usb_mode_obj); // defined in main.c
211212

212213
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
213214
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
@@ -220,6 +221,7 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = {
220221
{ MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj },
221222
{ MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj },
222223
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
224+
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_mode), (mp_obj_t)&pyb_usb_mode_obj },
223225

224226
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
225227
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },

stmhal/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Q(stop)
1010
Q(standby)
1111
Q(source_dir)
1212
Q(main)
13+
Q(usb_mode)
1314
Q(sync)
1415
Q(gc)
1516
Q(repl_info)

stmhal/stm32f4xx_hal_msp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
/* Includes ------------------------------------------------------------------*/
4040
#include "stm32f4xx_hal.h"
41-
#include "usbd_cdc_msc.h"
41+
#include "usbd_cdc_msc_hid.h"
4242
#include "usbd_cdc_interface.h"
4343

4444
#include "misc.h"

stmhal/stm32f4xx_it.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
#include "stm32f4xx_it.h"
4444
#include "stm32f4xx_hal.h"
45-
#include "usbd_cdc_msc.h"
45+
#include "usbd_cdc_msc_hid.h"
4646
#include "usbd_cdc_interface.h"
4747

4848
#include "misc.h"

stmhal/usb.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include "usbd_core.h"
44
#include "usbd_desc.h"
5-
#include "usbd_cdc_msc.h"
5+
#include "usbd_cdc_msc_hid.h"
66
#include "usbd_cdc_interface.h"
77
#include "usbd_msc_storage.h"
88

@@ -19,28 +19,24 @@ USBD_HandleTypeDef hUSBDDevice;
1919
static int dev_is_enabled = 0;
2020
mp_obj_t mp_const_vcp_interrupt = MP_OBJ_NULL;
2121

22-
void pyb_usb_dev_init(usbd_device_kind_t device_kind, usbd_storage_medium_kind_t medium_kind) {
22+
void pyb_usb_dev_init(usb_device_mode_t mode, usb_storage_medium_t medium) {
2323
#ifdef USE_DEVICE_MODE
2424
if (!dev_is_enabled) {
2525
// only init USB once in the device's power-lifetime
26-
switch (device_kind) {
27-
case USBD_DEVICE_CDC_MSC:
28-
USBD_Init(&hUSBDDevice, &VCP_Desc, 0);
29-
USBD_RegisterClass(&hUSBDDevice, &USBD_CDC_MSC);
30-
USBD_CDC_RegisterInterface(&hUSBDDevice, (USBD_CDC_ItfTypeDef*)&USBD_CDC_fops);
31-
if (medium_kind == USBD_STORAGE_MEDIUM_FLASH) {
32-
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
33-
} else {
34-
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops);
35-
}
36-
USBD_Start(&hUSBDDevice);
37-
break;
38-
39-
case USBD_DEVICE_HID:
40-
//USBD_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_HID_cb, &USR_cb);
41-
// TODO
42-
break;
26+
if (mode == USB_DEVICE_MODE_CDC_MSC) {
27+
USBD_SelectMode(USBD_MODE_CDC_MSC);
28+
} else {
29+
USBD_SelectMode(USBD_MODE_CDC_HID);
4330
}
31+
USBD_Init(&hUSBDDevice, &VCP_Desc, 0);
32+
USBD_RegisterClass(&hUSBDDevice, &USBD_CDC_MSC_HID);
33+
USBD_CDC_RegisterInterface(&hUSBDDevice, (USBD_CDC_ItfTypeDef*)&USBD_CDC_fops);
34+
if (medium == USB_STORAGE_MEDIUM_FLASH) {
35+
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
36+
} else {
37+
USBD_MSC_RegisterStorage(&hUSBDDevice, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops);
38+
}
39+
USBD_Start(&hUSBDDevice);
4440
}
4541
dev_is_enabled = 1;
4642

0 commit comments

Comments
 (0)