Commit f31c6b48 authored by Damien George's avatar Damien George

mimxrt: Fix USB CDC handling so it works reliably.

On i.MX the SysTick IRQ cannot wake the CPU from a WFI so the CPU was
blocked on WFI waiting for USB data in mp_hal_stdin_rx_chr() even though it
had already arrived (because it may arrive just after calling the check
tud_cdc_available()).  This commit fixes this problem by using SEV/WFE to
indicate that there has been a USB event.

The mp_hal_stdout_tx_strn() function is also fixed so that it doesn't
overflow the USB buffers.
Signed-off-by: default avatarDamien George <damien@micropython.org>
parent c9260dda
...@@ -92,9 +92,11 @@ void SysTick_Handler(void) { ...@@ -92,9 +92,11 @@ void SysTick_Handler(void) {
void USB_OTG1_IRQHandler(void) { void USB_OTG1_IRQHandler(void) {
tud_int_handler(0); tud_int_handler(0);
tud_task(); tud_task();
__SEV();
} }
void USB_OTG2_IRQHandler(void) { void USB_OTG2_IRQHandler(void) {
tud_int_handler(1); tud_int_handler(1);
tud_task(); tud_task();
__SEV();
} }
...@@ -94,7 +94,7 @@ extern const struct _mp_obj_module_t mp_module_utime; ...@@ -94,7 +94,7 @@ extern const struct _mp_obj_module_t mp_module_utime;
do { \ do { \
extern void mp_handle_pending(bool); \ extern void mp_handle_pending(bool); \
mp_handle_pending(true); \ mp_handle_pending(true); \
__WFI(); \ __WFE(); \
} while (0); } while (0);
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1)) #define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))
......
...@@ -75,7 +75,7 @@ int mp_hal_stdin_rx_chr(void) { ...@@ -75,7 +75,7 @@ int mp_hal_stdin_rx_chr(void) {
return buf[0]; return buf[0];
} }
} }
__WFI(); MICROPY_EVENT_POLL_HOOK
} }
} }
...@@ -83,17 +83,16 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { ...@@ -83,17 +83,16 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
if (tud_cdc_connected()) { if (tud_cdc_connected()) {
for (size_t i = 0; i < len;) { for (size_t i = 0; i < len;) {
uint32_t n = len - i; uint32_t n = len - i;
uint32_t n2 = tud_cdc_write(str + i, n); if (n > CFG_TUD_CDC_EP_BUFSIZE) {
if (n2 < n) { n = CFG_TUD_CDC_EP_BUFSIZE;
while (!tud_cdc_write_flush()) {
__WFI();
}
} }
while (n > tud_cdc_write_available()) {
__WFE();
}
uint32_t n2 = tud_cdc_write(str + i, n);
tud_cdc_write_flush();
i += n2; i += n2;
} }
while (!tud_cdc_write_flush()) {
__WFI();
}
} }
// TODO // TODO
// while (len--) { // while (len--) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment