rfdsatt: move LED and microvty to fibre/protothreads

This commit is contained in:
Harald Welte 2021-05-05 22:37:28 +02:00
parent abfceb45f5
commit cd97005150
3 changed files with 92 additions and 25 deletions

View File

@ -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 <librfn/fibre.h>
extern fibre_t microvty_fibre;
#endif

View File

@ -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 <librfn/fibre.h>
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 */

View File

@ -27,8 +27,11 @@
#include <libopencm3/cm3/systick.h>
#include <librfn/time.h>
#include <librfn/util.h>
#include <librfn/fibre.h>
#include <libcommon/iob.h>
#include <libcommon/utils.h>
#include <libcommon/microvty.h>
#include <stdio.h>
@ -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(&microvty_fibre);
fibre_scheduler_main_loop();
return 0;
}