diff options
Diffstat (limited to 'display_sim.c')
-rw-r--r-- | display_sim.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/display_sim.c b/display_sim.c new file mode 100644 index 0000000..b17979f --- /dev/null +++ b/display_sim.c @@ -0,0 +1,118 @@ +#include <stdio.h> +#include <avr/io.h> + +#define BAUD 57600 +#include <util/setbaud.h> + +#include "display.h" + +/* WIDTH+1 for string terminator */ +static char display[LCD_HEIGHT][LCD_WIDTH+1]; +static int cursor_x; +static int cursor_y; + +/* Slightly icky hack to use first avaialable USART */ +#ifdef UDR0 +# define UBRRx UBRR0 +# define UCSRxA UCSR0A +# define UCSRxB UCSR0B +# define UCSRxC UCSR0C +# define UCSZx0 UCSZ00 +# define UCSZx1 UCSZ01 +# define RXENx RXEN0 +# define TXENx TXEN0 +# define UDREx UDRE0 +# define UDRx UDR0 +# define U2Xx U2X0 +#else +# define UBRRx UBRR1 +# define UCSRxA UCSR1A +# define UCSRxB UCSR1B +# define UCSRxC UCSR1C +# define UCSZx0 UCSZ10 +# define UCSZx1 UCSZ11 +# define RXENx RXEN1 +# define TXENx TXEN1 +# define UDREx UDRE1 +# define UDRx UDR1 +# define U2Xx U2X1 +#endif + +static void uart_init(void) +{ + UBRRx = UBRR_VALUE; +#if USE_2X + UCSRxA |= (1 << U2Xx); +#else + UCSRxA &= ~(1 << U2Xx); +#endif + UCSRxB = _BV(RXENx) | _BV(TXENx); + UCSRxC = _BV(UCSZx1) | _BV(UCSZx0); +} + +static int uart_putc(char c, FILE *unused) +{ + UDRx = c; + loop_until_bit_is_set(UCSRxA, UDREx); + return 1; +} + +/* uart_out is plopped on stdout so that prints go to it by default */ +static FILE uart_out = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE); + +/* internal function to dump the display contents to stdout, since there + * is no background thread for doing this constantly */ +void display_display(void) +{ + int x = 0; + int y = 0; + printf("\033[6A"); // hack: raw ANSI escape sequence to move up 6 + printf(",--------------------.\n"); + for (y = 0; y < LCD_HEIGHT; y++) { + printf("|%s|\n", display[y]); + } + printf("`--------------------'\n"); +} + +void display_clear(void) +{ + int x = 0; + int y = 0; + for (y = 0; y < LCD_HEIGHT; y++) { + for (x = 0; x < LCD_WIDTH; x++) { + display[y][x] = ' '; + } + display[y][x] = '\0'; + } + + display_display(); +} + +void display_init(void) +{ + uart_init(); + /* FIXME hack: stdout not guaranteed to be assignable */ + stdout = &uart_out; + display_clear(); + cursor_x = cursor_y = 0; +} + +void display_write(const char *text) +{ + size_t text_x = 0; + char c = '\0'; + while (cursor_x < LCD_WIDTH && *text) { + c = *(text++); + /* 0-7 are custom chars in CGRAM on real LCD */ + if (c < 8) + c = '_'; + display[cursor_y][cursor_x++] = c; + } + display_display(); +} + +void display_set_cursor(int x, int y) +{ + cursor_x = x; + cursor_y = y; +} |