diff --git a/ports/zephyr/mphalport.c b/ports/zephyr/mphalport.c index 4f00cbd26c..fa64c4afc9 100644 --- a/ports/zephyr/mphalport.c +++ b/ports/zephyr/mphalport.c @@ -51,12 +51,15 @@ void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms) { k_poll_event_init(&wait_events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, sem); } for (;;) { + mp_handle_pending(true); + MP_THREAD_GIL_EXIT(); k_timeout_t wait; if (timeout_ms == (uint32_t)-1) { wait = K_FOREVER; } else { uint32_t dt = mp_hal_ticks_ms() - t0; if (dt >= timeout_ms) { + MP_THREAD_GIL_ENTER(); return; } wait = K_MSEC(timeout_ms - dt); @@ -65,9 +68,9 @@ void mp_hal_wait_sem(struct k_sem *sem, uint32_t timeout_ms) { if (wait_events[0].state == K_POLL_STATE_SIGNALED) { wait_events[0].signal->signaled = 0; wait_events[0].state = K_POLL_STATE_NOT_READY; - mp_handle_pending(true); } else if (sem && wait_events[1].state == K_POLL_STATE_SEM_AVAILABLE) { wait_events[1].state = K_POLL_STATE_NOT_READY; + MP_THREAD_GIL_ENTER(); return; } } diff --git a/ports/zephyr/mpthreadport.c b/ports/zephyr/mpthreadport.c index 0edfdee1ed..0b304cfd50 100644 --- a/ports/zephyr/mpthreadport.c +++ b/ports/zephyr/mpthreadport.c @@ -269,6 +269,7 @@ int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait) { void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) { k_sem_give(&mutex->handle); + k_yield(); } void mp_thread_deinit(void) { diff --git a/ports/zephyr/src/zephyr_getchar.c b/ports/zephyr/src/zephyr_getchar.c index 5bbf1a9f68..0dc8a15bdd 100644 --- a/ports/zephyr/src/zephyr_getchar.c +++ b/ports/zephyr/src/zephyr_getchar.c @@ -50,14 +50,16 @@ static int console_irq_input_hook(uint8_t ch) { return 1; } -uint8_t zephyr_getchar(void) { - mp_hal_wait_sem(&uart_sem, -1); - k_sem_take(&uart_sem, K_FOREVER); - unsigned int key = irq_lock(); - uint8_t c = uart_ringbuf[i_get++]; - i_get &= UART_BUFSIZE - 1; - irq_unlock(key); - return c; +int zephyr_getchar(void) { + mp_hal_wait_sem(&uart_sem, 0); + if (k_sem_take(&uart_sem, K_MSEC(0)) == 0) { + unsigned int key = irq_lock(); + int c = (int)uart_ringbuf[i_get++]; + i_get &= UART_BUFSIZE - 1; + irq_unlock(key); + return c; + } + return -1; } void zephyr_getchar_init(void) { diff --git a/ports/zephyr/src/zephyr_getchar.h b/ports/zephyr/src/zephyr_getchar.h index fb5f19a7b4..fee899e1b4 100644 --- a/ports/zephyr/src/zephyr_getchar.h +++ b/ports/zephyr/src/zephyr_getchar.h @@ -17,4 +17,4 @@ #include void zephyr_getchar_init(void); -uint8_t zephyr_getchar(void); +int zephyr_getchar(void); diff --git a/ports/zephyr/src/zephyr_start.c b/ports/zephyr/src/zephyr_start.c index bcd68f92ce..3b00bac121 100644 --- a/ports/zephyr/src/zephyr_start.c +++ b/ports/zephyr/src/zephyr_start.c @@ -24,14 +24,14 @@ * THE SOFTWARE. */ #include -#include #include "zephyr_getchar.h" int real_main(void); +int mp_console_init(void); void main(void) { #ifdef CONFIG_CONSOLE_SUBSYS - console_init(); + mp_console_init(); #else zephyr_getchar_init(); #endif diff --git a/ports/zephyr/uart_core.c b/ports/zephyr/uart_core.c index 3f70cc0a17..7e2db3653b 100644 --- a/ports/zephyr/uart_core.c +++ b/ports/zephyr/uart_core.c @@ -25,10 +25,28 @@ */ #include #include "py/mpconfig.h" +#include "py/runtime.h" #include "src/zephyr_getchar.h" // Zephyr headers -#include +#include +#include #include +#include +#include + + +#ifdef CONFIG_CONSOLE_SUBSYS + +static int mp_console_putchar(char c); +static int mp_console_getchar(void); + + +static struct tty_serial mp_console_serial; + +static uint8_t mp_console_rxbuf[CONFIG_CONSOLE_GETCHAR_BUFSIZE]; +static uint8_t mp_console_txbuf[CONFIG_CONSOLE_PUTCHAR_BUFSIZE]; + +#endif // CONFIG_CONSOLE_SUBSYS /* * Core UART functions to implement for a port @@ -36,11 +54,18 @@ // Receive single character int mp_hal_stdin_rx_chr(void) { - #ifdef CONFIG_CONSOLE_SUBSYS - return console_getchar(); - #else - return zephyr_getchar(); - #endif + for (;;) { + int _chr; + #ifdef CONFIG_CONSOLE_SUBSYS + _chr = mp_console_getchar(); + #else + _chr = zephyr_getchar(); + #endif + if (_chr >= 0) { + return _chr; + } + MICROPY_EVENT_POLL_HOOK + } } // Send string of given length @@ -49,8 +74,8 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { #ifdef CONFIG_CONSOLE_SUBSYS while (len--) { char c = *str++; - while (console_putchar(c) == -1) { - k_msleep(1); + while (mp_console_putchar(c) == -1) { + MICROPY_EVENT_POLL_HOOK } } #else @@ -63,3 +88,58 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { #endif return ret; } + + +#ifdef CONFIG_CONSOLE_SUBSYS + +int mp_console_init(void) { + + const struct device *uart_dev; + int ret; + + uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); + if (!device_is_ready(uart_dev)) { + return -ENODEV; + } + + ret = tty_init(&mp_console_serial, uart_dev); + + if (ret) { + return ret; + } + + /* Checks device driver supports for interrupt driven data transfers. */ + if (CONFIG_CONSOLE_GETCHAR_BUFSIZE + CONFIG_CONSOLE_PUTCHAR_BUFSIZE) { + const struct uart_driver_api *api = + (const struct uart_driver_api *)uart_dev->api; + if (!api->irq_callback_set) { + return -ENOTSUP; + } + } + + tty_set_tx_buf(&mp_console_serial, mp_console_txbuf, sizeof(mp_console_txbuf)); + tty_set_rx_buf(&mp_console_serial, mp_console_rxbuf, sizeof(mp_console_rxbuf)); + + tty_set_rx_timeout(&mp_console_serial, 0); + tty_set_tx_timeout(&mp_console_serial, 1); + + return 0; +} + +static int mp_console_putchar(char c) { + return tty_write(&mp_console_serial, &c, 1); +} + +static int mp_console_getchar(void) { + uint8_t c; + int res; + + res = tty_read(&mp_console_serial, &c, 1); + if (res < 0) { + return res; + } + + return c; +} + +#endif // CONFIG_CONSOLE_SUBSYS