diff --git a/libcommon/include/libcommon/microvty.h b/libcommon/include/libcommon/microvty.h index c83250e..1475bbd 100644 --- a/libcommon/include/libcommon/microvty.h +++ b/libcommon/include/libcommon/microvty.h @@ -42,3 +42,8 @@ void microvty_print_prompt(void); /* to be provided by implementation: tell the code if UART Rx is non- * empty and hence if a subsequent getchar() would return something */ bool microvty_cb_uart_rx_not_empty(void); + +#ifndef CONFIG_NO_FIBRE +#include +extern fibre_t microvty_fibre; +#endif diff --git a/libcommon/src/microvty.c b/libcommon/src/microvty.c index cdf4e36..a0d2a87 100644 --- a/libcommon/src/microvty.c +++ b/libcommon/src/microvty.c @@ -88,6 +88,28 @@ void microvty_print_prompt(void) printf(g_cmds.prompt); } + +static bool microvty_process_char(int c) +{ + if (c == '\r' || c == '\n' || g_cmds.buf_idx >= sizeof(g_cmds.buf)-1) { + /* skip empty commands */ + if (g_cmds.buf_idx == 0) { + printf("\r\n"); + microvty_print_prompt(); + return true; + } + cmd_execute(); + cmd_buf_reset(); + microvty_print_prompt(); + return true; + } else { + /* print + append character */ + putchar(c); + cmd_buf_append(c); + } + return false; +} + /*! try to receive characters from the console, dispatching them */ void microvty_try_recv(void) { @@ -98,23 +120,8 @@ void microvty_try_recv(void) int c = getchar(); if (c < 0) return; - if (c == '\r' || c == '\n' || g_cmds.buf_idx >= sizeof(g_cmds.buf)-1) { - /* skip empty commands */ - if (g_cmds.buf_idx == 0) { - printf("\r\n"); - microvty_print_prompt(); - return; - } - cmd_execute(); - cmd_buf_reset(); - printf(g_cmds.prompt); + if (microvty_process_char(c)) return; - } else { - /* print + append character */ - putchar(c); - cmd_buf_append(c); - } - i++; } } @@ -125,3 +132,31 @@ void microvty_init(const char *prompt) g_cmds.prompt = prompt; microvty_register(&help_cmd); } + + + +#ifndef CONFIG_NO_FIBRE +#include + +static int microvty_fibre_fn(fibre_t *fibre) +{ + PT_BEGIN_FIBRE(fibre); + + while (true) { + /* we could use PT_WAIT_UNTIL() herre, but then we'd have to hack + * a fibre_run_atomic() call into the USART2 ISR, which is ugly and + * violates the separation of the stdio/bio layer and the microvty */ + if (!microvty_cb_uart_rx_not_empty()) + PT_YIELD(); + + int c = getchar(); + if (c >= 0) + microvty_process_char(c); + } + + PT_END(); +} + +fibre_t microvty_fibre = FIBRE_VAR_INIT(microvty_fibre_fn); + +#endif /* CONFIG_NO_FIBRE */ diff --git a/projects/rfdsatt/rfdsatt.c b/projects/rfdsatt/rfdsatt.c index bdd22ab..9e64d62 100644 --- a/projects/rfdsatt/rfdsatt.c +++ b/projects/rfdsatt/rfdsatt.c @@ -27,8 +27,11 @@ #include #include +#include +#include #include +#include #include #include @@ -213,6 +216,34 @@ static void print_banner(void) printf("======================================================================\r\n\r\n"); } +typedef struct { + uint32_t time; + fibre_t fibre; +} led_fibre_t; + +int led_fibre(fibre_t *fibre) +{ + led_fibre_t *led = containerof(fibre, led_fibre_t, fibre); + + PT_BEGIN_FIBRE(fibre); + + led->time = time_now(); + + while (true) { + led->time += 500000; + PT_WAIT_UNTIL(fibre_timeout(led->time)); + gpio_toggle(GPIOB, GPIO15); /* LED on/off */ + } + + PT_END(); +} + +led_fibre_t led = { + .fibre = FIBRE_VAR_INIT(led_fibre) +}; + +extern fibre_t microvty_fibre; + int main(void) { /* get, store and clear the cause of the last reset */ @@ -224,6 +255,7 @@ int main(void) usart_setup(); iob_init(USART2); i2c_setup(); + time_init(); attenuator_init(&board_att_cfg, board_att_st); microvty_init("rfdsat4ch> "); @@ -235,15 +267,10 @@ int main(void) print_banner(); microvty_print_prompt(); - /* Blink the LED (PB15) on the board with every transmitted byte. */ - while (1) { - int i; - gpio_toggle(GPIOB, GPIO15); /* LED on/off */ - //printf("Hello world\r\n"); - microvty_try_recv(); - for (i = 0; i < 800000; i++) /* Wait a bit. */ - __asm__("nop"); - } + fibre_run(&led.fibre); + fibre_run(µvty_fibre); + + fibre_scheduler_main_loop(); return 0; }