diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-09-25 21:00:16 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-09-25 21:00:16 +0300 |
| commit | 6d0e7c5eba49efc171e63ff2631722a5c7f95460 (patch) | |
| tree | 9159d22c6ee1ee2949dcf8455998405b031cb351 /src/uart/simple_uart.c | |
| parent | fecb86f6093c1e8aed6ab05c29c5af9d0cb93157 (diff) | |
| download | gran-6d0e7c5eba49efc171e63ff2631722a5c7f95460.tar.gz gran-6d0e7c5eba49efc171e63ff2631722a5c7f95460.zip | |
technically speaking deadlock free, but starves
Diffstat (limited to 'src/uart/simple_uart.c')
| -rw-r--r-- | src/uart/simple_uart.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/uart/simple_uart.c b/src/uart/simple_uart.c new file mode 100644 index 0000000..e640ae1 --- /dev/null +++ b/src/uart/simple_uart.c @@ -0,0 +1,55 @@ +#include <stdio.h> +#include <gran/uart/simple_uart.h> + +struct simple_uart { + struct component component; + + struct component *send; + struct packet pkt; + bool busy; +}; + +static stat simple_uart_clock(struct simple_uart *uart) +{ + if (!uart->busy) + return OK; + + stat r = SEND(uart, uart->send, uart->pkt); + if (r == EBUSY) + return OK; + + uart->busy = false; + return OK; +} + +static stat simple_uart_receive(struct simple_uart *uart, struct component *from, struct packet pkt) +{ + if (uart->busy) + return EBUSY; + + uart->busy = true; + uart->send = from; + uart->pkt = response(pkt); + + size_t size = packet_convsize(&pkt); + if (size != 1) { + set_flags(&uart->pkt, PACKET_ERROR); + return OK; + } + + putchar(packet_convu8(&pkt)); + fflush(stdout); + set_flags(&uart->pkt, PACKET_DONE); + return OK; +} + +struct component *create_simple_uart() +{ + struct simple_uart *uart = calloc(1, sizeof(struct simple_uart)); + if (!uart) + return NULL; + + uart->component.receive = (receive_callback)simple_uart_receive; + uart->component.clock = (clock_callback)simple_uart_clock; + return (struct component *)uart; +} |
