mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
pkg/tinyusb: fix reset for STM32 boards without internal D+ pullup
If the STM32 MCU does not have an internal D+ pullup and there is no dedicated GPIO on the board to simulate a USB disconnect, the D+ GPIO has to be temporarily configured as an output and pushed down to simulate a disconnect/connect cycle to allow the host to recognize the device. This is done correctly in `cpu/stm32/periph/usbdev_fs.c` but not in tinyUSB STM32 hardware driver. That is, pressing the RESET button doesn't reset the USB connection. fixup! pkg/tinyusb: fix reset for STM32 boards without internal D+ pullup
This commit is contained in:
parent
045bb7c39c
commit
fc1600252f
@ -6,6 +6,7 @@
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include "log.h"
|
||||
#include "kernel_defines.h"
|
||||
#include "thread.h"
|
||||
|
||||
@ -27,9 +28,15 @@ static void *_tinyusb_thread_impl(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
if (tinyusb_hw_init() != 0) {
|
||||
LOG_ERROR("tinyUSB peripherals couldn't be initialized\n");
|
||||
assert(0);
|
||||
}
|
||||
DEBUG("tinyUSB peripherals initialized\n");
|
||||
|
||||
if (IS_USED(MODULE_TINYUSB_DEVICE)) {
|
||||
if (!tud_init(TINYUSB_TUD_RHPORT)) {
|
||||
DEBUG("tinyUSB device stack couldn't be initialized\n");
|
||||
LOG_ERROR("tinyUSB device stack couldn't be initialized\n");
|
||||
assert(0);
|
||||
}
|
||||
DEBUG("tinyUSB device stack initialized\n");
|
||||
@ -37,7 +44,7 @@ static void *_tinyusb_thread_impl(void *arg)
|
||||
|
||||
if (IS_USED(MODULE_TINYUSB_HOST)) {
|
||||
if (!tuh_init(TINYUSB_TUH_RHPORT)) {
|
||||
DEBUG("tinyUSB host stack couldn't be initialized\n");
|
||||
LOG_ERROR("tinyUSB host stack couldn't be initialized\n");
|
||||
assert(0);
|
||||
}
|
||||
DEBUG("tinyUSB host stack initialized\n");
|
||||
@ -65,18 +72,12 @@ int tinyusb_setup(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
if ((res = tinyusb_hw_init()) != 0) {
|
||||
DEBUG("tinyUSB peripherals couldn't be initialized\n");
|
||||
return res;
|
||||
}
|
||||
DEBUG("tinyUSB peripherals initialized\n");
|
||||
|
||||
if ((res = thread_create(_tinyusb_thread_stack,
|
||||
sizeof(_tinyusb_thread_stack),
|
||||
TINYUSB_PRIORITY,
|
||||
THREAD_CREATE_WOUT_YIELD | THREAD_CREATE_STACKTEST,
|
||||
_tinyusb_thread_impl, NULL, "tinyusb")) < 0) {
|
||||
DEBUG("tinyUSB thread couldn't be created, reason %d\n", res);
|
||||
LOG_ERROR("tinyUSB thread couldn't be created, reason %d\n", res);
|
||||
return res;
|
||||
}
|
||||
DEBUG("tinyUSB thread created\n");
|
||||
|
@ -51,6 +51,19 @@ static int tinyusb_hw_init_dev(const stm32_usbdev_fs_config_t *conf)
|
||||
CRS->CR |= (CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
|
||||
#endif
|
||||
|
||||
if (conf->af == GPIO_AF_UNDEF && conf->disconn == GPIO_UNDEF) {
|
||||
/* If the MCU does not have an internal D+ pullup and there is no
|
||||
* dedicated GPIO on the board to simulate a USB disconnect, the D+ GPIO
|
||||
* is temporarily configured as an output and pushed down to simulate
|
||||
* a disconnect/connect cycle to allow the host to recognize the device.
|
||||
* This requires an external pullup on D+ signal to work. */
|
||||
gpio_init(conf->dp, GPIO_OUT);
|
||||
gpio_clear(conf->dp);
|
||||
/* wait about a ms */
|
||||
ztimer_sleep(ZTIMER_MSEC, 1);
|
||||
gpio_init(conf->dp, GPIO_IN);
|
||||
}
|
||||
|
||||
if (conf->af != GPIO_AF_UNDEF) {
|
||||
/* Configure AF for the pins */
|
||||
gpio_init_af(conf->dp, conf->af);
|
||||
|
Loading…
Reference in New Issue
Block a user