diff --git a/ports/zephyr/Kconfig b/ports/zephyr/Kconfig index c12e4bc854f..87f4d0c8d0a 100644 --- a/ports/zephyr/Kconfig +++ b/ports/zephyr/Kconfig @@ -83,6 +83,37 @@ choice MICROPY_CONFIG_ROM_LEVEL endchoice +choice MICROPY_GETCHAR + prompt "Getchar driver to use for the console" + default MICROPY_GETCHAR_CONSOLE_DRIVER + + config MICROPY_GETCHAR_CONSOLE_DRIVER + bool "Use the console driver getchar" + depends on UART_CONSOLE + depends on UART_CONSOLE_DEBUG_SERVER_HOOKS + help + Use the uart_console driver API directly to access interrupts via a mix + of UART-like drivers and standard I/O. The console buffer is managed by + MicroPython. + + config MICROPY_GETCHAR_CONSOLE_SUBSYS + bool "Use the console subsys getchar" + depends on CONSOLE_SUBSYS + depends on CONSOLE_GETCHAR + help + Let Zephyr handle all the console management including the buffers via + the console subsystem. + +endchoice + +if MICROPY_GETCHAR_CONSOLE_DRIVER + +config MICROPY_GETCHAR_CONSOLE_DRIVER_BUF_SIZE + int "Size of the console driver getchar buffer" + default 1024 + +endif # MICROPY_GETCHAR_CONSOLE_DRIVER + endmenu # MicroPython Options source "Kconfig.zephyr" diff --git a/ports/zephyr/boards/ai_m61_32s_kit.conf b/ports/zephyr/boards/ai_m61_32s_kit.conf index 32ba172caaf..56cea1e31f4 100644 --- a/ports/zephyr/boards/ai_m61_32s_kit.conf +++ b/ports/zephyr/boards/ai_m61_32s_kit.conf @@ -2,10 +2,6 @@ CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_WATCHDOG=y -CONFIG_CONSOLE_SUBSYS=y -CONFIG_CONSOLE_GETCHAR=y -CONFIG_CONSOLE_GETCHAR_BUFSIZE=1024 -CONFIG_CONSOLE_PUTCHAR_BUFSIZE=1024 CONFIG_I2C=y CONFIG_I2C_TARGET=y CONFIG_SPI=y diff --git a/ports/zephyr/boards/ai_m62_12f_kit.conf b/ports/zephyr/boards/ai_m62_12f_kit.conf index b5eca34c974..2779fdb41c1 100644 --- a/ports/zephyr/boards/ai_m62_12f_kit.conf +++ b/ports/zephyr/boards/ai_m62_12f_kit.conf @@ -2,10 +2,6 @@ CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_WATCHDOG=y -CONFIG_CONSOLE_SUBSYS=y -CONFIG_CONSOLE_GETCHAR=y -CONFIG_CONSOLE_GETCHAR_BUFSIZE=1024 -CONFIG_CONSOLE_PUTCHAR_BUFSIZE=1024 CONFIG_I2C=y CONFIG_I2C_TARGET=y CONFIG_SPI=y diff --git a/ports/zephyr/boards/ai_m64p_32s_kit.conf b/ports/zephyr/boards/ai_m64p_32s_kit.conf index 3cec78a6d4b..d6ee27fc959 100644 --- a/ports/zephyr/boards/ai_m64p_32s_kit.conf +++ b/ports/zephyr/boards/ai_m64p_32s_kit.conf @@ -2,10 +2,6 @@ CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_WATCHDOG=y -CONFIG_CONSOLE_SUBSYS=y -CONFIG_CONSOLE_GETCHAR=y -CONFIG_CONSOLE_GETCHAR_BUFSIZE=1024 -CONFIG_CONSOLE_PUTCHAR_BUFSIZE=1024 CONFIG_I2C=y CONFIG_I2C_TARGET=y CONFIG_SPI=y diff --git a/ports/zephyr/boards/ai_wb2_12f_kit.conf b/ports/zephyr/boards/ai_wb2_12f_kit.conf index c240f115e7a..e83a5ead014 100644 --- a/ports/zephyr/boards/ai_wb2_12f_kit.conf +++ b/ports/zephyr/boards/ai_wb2_12f_kit.conf @@ -2,10 +2,6 @@ CONFIG_PINCTRL=y CONFIG_GPIO=y CONFIG_WATCHDOG=y -CONFIG_CONSOLE_SUBSYS=y -CONFIG_CONSOLE_GETCHAR=y -CONFIG_CONSOLE_GETCHAR_BUFSIZE=1024 -CONFIG_CONSOLE_PUTCHAR_BUFSIZE=1024 CONFIG_I2C=y CONFIG_I2C_TARGET=y CONFIG_SPI=y diff --git a/ports/zephyr/main.c b/ports/zephyr/main.c index 169ad625c01..62ba0e8725a 100644 --- a/ports/zephyr/main.c +++ b/ports/zephyr/main.c @@ -41,7 +41,7 @@ #include -#ifdef CONFIG_CONSOLE_SUBSYS +#ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_SUBSYS #include #if CONFIG_CONSOLE_GETCHAR_BUFSIZE < 512 @@ -129,13 +129,15 @@ void init_zephyr(void) { int main(void) { /* Initialize terminal device */ - #ifdef CONFIG_CONSOLE_SUBSYS + #ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_SUBSYS console_init(); /* Always immediately hand control back to micropython */ console_set_rx_timeout(K_NO_WAIT); console_set_tx_timeout(K_NO_WAIT); - #else + #elif CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER zephyr_getchar_init(); + #else + #error A getchar driver must be chosen #endif #if MICROPY_PY_THREAD diff --git a/ports/zephyr/src/zephyr_getchar.c b/ports/zephyr/src/zephyr_getchar.c index bf504a97c9b..f2ff635f291 100644 --- a/ports/zephyr/src/zephyr_getchar.c +++ b/ports/zephyr/src/zephyr_getchar.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER + #include #include #include @@ -24,12 +26,11 @@ extern int mp_interrupt_char; void mp_sched_keyboard_interrupt(void); void mp_hal_signal_event(void); -#define UART_BUFSIZE (512) -static uint8_t uart_ringbuf[UART_BUFSIZE]; -static uint16_t i_get, i_put; +static uint8_t uart_ringbuf[CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER_BUF_SIZE]; +static uint16_t i_get = 0, i_put = 0; static int console_irq_input_hook(uint8_t ch) { - int i_next = (i_put + 1) & (UART_BUFSIZE - 1); + int i_next = (i_put + 1) & (CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER_BUF_SIZE - 1); if (i_next == i_get) { printk("UART buffer overflow - char dropped\n"); return 1; @@ -54,7 +55,7 @@ int zephyr_getchar(void) { if (i_get != i_put) { unsigned int key = irq_lock(); int c = (int)uart_ringbuf[i_get++]; - i_get &= UART_BUFSIZE - 1; + i_get &= CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER_BUF_SIZE - 1; irq_unlock(key); return c; } @@ -66,3 +67,5 @@ void zephyr_getchar_init(void) { // All NULLs because we're interested only in the callback above uart_register_input(NULL, NULL, NULL); } + +#endif /* CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER */ diff --git a/ports/zephyr/src/zephyr_getchar.h b/ports/zephyr/src/zephyr_getchar.h index 3f31c4317fa..c4c50611916 100644 --- a/ports/zephyr/src/zephyr_getchar.h +++ b/ports/zephyr/src/zephyr_getchar.h @@ -14,8 +14,15 @@ * limitations under the License. */ -#include +#ifndef MICROPY_INCLUDED_ZEPHYR_SRC_ZEPHYR_GETCHAR_H +#define MICROPY_INCLUDED_ZEPHYR_SRC_ZEPHYR_GETCHAR_H + +#ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER void zephyr_getchar_init(void); int zephyr_getchar_check(void); int zephyr_getchar(void); + +#endif + +#endif /* MICROPY_INCLUDED_ZEPHYR_SRC_ZEPHYR_GETCHAR_H */ diff --git a/ports/zephyr/uart_core.c b/ports/zephyr/uart_core.c index 1effa65c106..4ecdf03d0b7 100644 --- a/ports/zephyr/uart_core.c +++ b/ports/zephyr/uart_core.c @@ -23,6 +23,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ + #include #include "py/mpconfig.h" #include "py/runtime.h" @@ -38,10 +39,14 @@ * Core UART functions to implement for a port */ +#ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_DRIVER +static const struct device *const uart_console_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); +#endif + uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { uintptr_t ret = 0; if (poll_flags & MP_STREAM_POLL_RD) { - #ifdef CONFIG_CONSOLE_SUBSYS + #ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_SUBSYS // It's not easy to test if tty is readable, so just unconditionally set it for now. ret |= MP_STREAM_POLL_RD; #else @@ -60,7 +65,7 @@ uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) { int mp_hal_stdin_rx_chr(void) { for (;;) { int _chr; - #ifdef CONFIG_CONSOLE_SUBSYS + #ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_SUBSYS _chr = console_getchar(); #else _chr = zephyr_getchar(); @@ -75,7 +80,7 @@ int mp_hal_stdin_rx_chr(void) { // Send string of given length mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { mp_uint_t ret = len; - #ifdef CONFIG_CONSOLE_SUBSYS + #ifdef CONFIG_MICROPY_GETCHAR_CONSOLE_SUBSYS while (len--) { char c = *str++; /* console_putchar returns -EAGAIN when no free tx is available */ @@ -84,9 +89,11 @@ mp_uint_t mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { } } #else - static const struct device *uart_console_dev = - DEVICE_DT_GET(DT_CHOSEN(zephyr_console)); - + /* Use poll out directly, because printk and other indirect uart_console access will append + * windows line returns to the output. + * This works for UART and UART-like serial drivers (CDC ACM) and is equivalent to the + * uart_console driver's output. + */ while (len--) { uart_poll_out(uart_console_dev, *str++); }