diff options
Diffstat (limited to 'code')
-rw-r--r-- | code/fe310/eos/Makefile | 2 | ||||
-rw-r--r-- | code/fe310/eos/eve.c | 36 | ||||
-rw-r--r-- | code/fe310/eos/eve.h | 6 | ||||
-rw-r--r-- | code/fe310/eos/eve_text.c | 100 | ||||
-rw-r--r-- | code/fe310/eos/eve_text.h | 20 |
5 files changed, 150 insertions, 14 deletions
diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile index 36eefd7..133a36a 100644 --- a/code/fe310/eos/Makefile +++ b/code/fe310/eos/Makefile @@ -2,7 +2,7 @@ include ../common.mk CFLAGS += -I../include -I../drivers -obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o uart.o spi.o net.o wifi.o cell.o sock.o eve.o +obj = trap_entry.o eos.o msgq.o event.o interrupt.o timer.o i2s.o uart.o spi.o net.o wifi.o cell.o sock.o eve.o eve_text.o %.o: %.c %.h diff --git a/code/fe310/eos/eve.c b/code/fe310/eos/eve.c index 8c0a477..9d902b2 100644 --- a/code/fe310/eos/eve.c +++ b/code/fe310/eos/eve.c @@ -96,8 +96,8 @@ static void _dl_inc(uint16_t i) { dl_offset += i; } -void eos_eve_dl_start(void) { - dl_offset = 0; +void eos_eve_dl_start(uint16_t offset) { + dl_offset = offset; } void eos_eve_dl_write(uint32_t dl) { @@ -106,10 +106,14 @@ void eos_eve_dl_write(uint32_t dl) { _dl_inc(4); } -void eos_eve_dl_end(void) { +void eos_eve_dl_swap(void) { eos_eve_write8(REG_DLSWAP, EVE_DLSWAP_FRAME); } +uint16_t eos_eve_dl_offset(void) { + return dl_offset; +} + static void _cmd_inc(uint16_t i) { cmd_offset += i; cmd_offset &= 0x0fff; @@ -145,8 +149,7 @@ static void _cmd_string(const char *s, uint8_t flags) { p = 4 - p; /* 4, 3, 2 or 1 */ i += p; - while(p > 0) - { + while(p > 0) { eos_spi_xchg8(0, EOS_SPI_FLAG_BSWAP | flags); p--; } @@ -156,7 +159,8 @@ static void _cmd_string(const char *s, uint8_t flags) { void eos_eve_cmd(uint32_t cmd, const char *fmt, ...) { uint8_t flags = cmd_burst ? EOS_SPI_FLAG_TX : 0; va_list argv; - int i; + uint16_t *p; + int i = 0; va_start(argv, fmt); _cmd_begin(cmd); @@ -174,6 +178,12 @@ void eos_eve_cmd(uint32_t cmd, const char *fmt, ...) { eos_spi_xchg32(va_arg(argv, int), EOS_SPI_FLAG_BSWAP | flags); _cmd_inc(4); break; + case 'W': + p = va_arg(argv, uint16_t *); + *p = cmd_offset; + eos_spi_xchg32(0, EOS_SPI_FLAG_BSWAP | flags); + _cmd_inc(4); + break; case 's': _cmd_string(va_arg(argv, const char *), flags); break; @@ -184,6 +194,10 @@ void eos_eve_cmd(uint32_t cmd, const char *fmt, ...) { va_end(argv); } +uint32_t eos_eve_cmd_result(uint16_t offset) { + return eos_eve_read32(EVE_RAM_CMD + offset); +} + void eos_eve_cmd_dl(uint32_t dl) { _cmd_begin(dl); _cmd_end(); @@ -271,11 +285,11 @@ int eos_eve_init(void) { eos_eve_write16(REG_SOUND, 0x6000); /* set synthesizer to mute */ /* write a basic display-list to get things started */ - eos_eve_dl_start(); - eos_eve_dl_write(DL_CLEAR_RGB); - eos_eve_dl_write(DL_CLEAR | CLR_COL | CLR_STN | CLR_TAG); - eos_eve_dl_write(DL_DISPLAY); - eos_eve_dl_end(); + eos_eve_dl_start(0); + eos_eve_dl_write(CLEAR_COLOR_RGB(0,0,0)); + eos_eve_dl_write(CLEAR(1,1,1)); + eos_eve_dl_write(DISPLAY()); + eos_eve_dl_swap(); /* nothing is being displayed yet... the pixel clock is still 0x00 */ eos_eve_write8(REG_GPIO, 0x80); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIO_DIR by default */ diff --git a/code/fe310/eos/eve.h b/code/fe310/eos/eve.h index b3c7ec2..1c837f5 100644 --- a/code/fe310/eos/eve.h +++ b/code/fe310/eos/eve.h @@ -17,11 +17,13 @@ void eos_eve_sleep(void); void eos_eve_reset(void); void eos_eve_brightness(uint8_t b); -void eos_eve_dl_start(void); +void eos_eve_dl_start(uint16_t offset); void eos_eve_dl_write(uint32_t dl); -void eos_eve_dl_end(void); +void eos_eve_dl_swap(void); +uint16_t eos_eve_dl_offset(void); void eos_eve_cmd(uint32_t cmd, const char *fmt, ...); +uint32_t eos_eve_cmd_result(uint16_t offset); void eos_eve_cmd_dl(uint32_t dl); int eos_eve_cmd_done(void); int eos_eve_cmd_exec(int w); diff --git a/code/fe310/eos/eve_text.c b/code/fe310/eos/eve_text.c new file mode 100644 index 0000000..73fcb65 --- /dev/null +++ b/code/fe310/eos/eve_text.c @@ -0,0 +1,100 @@ +#include "eve.h" +#include "eve_text.h" + +static int _line_diff(EVETextBox *box, int line) { + if (line > box->line_idx) { + return line - box->line_idx; + } else { + return box->buf_line_h - box->line_idx + line; + } +} + +static void _line_scroll(EVETextBox *box) { + box->line_idx = (box->line_idx + 1) % box->buf_line_h; + eos_eve_cmd(CMD_MEMSET, "www", EVE_RAM_G + box->buf_addr + box->buf_idx, 0x0, box->w * 2); + eos_eve_cmd_exec(1); + eos_eve_dl_start(box->dl_offset); + eos_eve_text_update(box); + eos_eve_dl_swap(); +} + +void eos_eve_text_init(EVETextBox *box, uint16_t buf_addr, int buf_line_h, int w, int h, int x, int y, uint8_t bitmap_handle) { + box->buf_addr = buf_addr; + box->buf_line_h = buf_line_h; + box->w = w; + box->h = h; + box->x = x; + box->y = y; + box->buf_idx = 0; + box->line_idx = 0; + box->dl_offset = 0; + box->bitmap_handle = bitmap_handle; + + eos_eve_cmd(CMD_MEMSET, "www", EVE_RAM_G + buf_addr, 0x0, w * 2 * buf_line_h); + eos_eve_cmd_exec(1); +} + +void eos_eve_text_update(EVETextBox *box) { + int text_h1; + int text_h2; + + eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle)); + eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr + box->line_idx * box->w * 2)); + if (box->line_idx + box->h > box->buf_line_h) { + text_h1 = box->buf_line_h - box->line_idx; + text_h2 = box->h - text_h1; + } else { + text_h1 = box->h; + text_h2 = 0; + } + eos_eve_dl_write(BITMAP_LAYOUT(EVE_TEXTVGA, box->w * 2, text_h1)); + eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * 8, text_h1 * 16)); + + if (text_h2) { + eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle+1)); + eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr)); + eos_eve_dl_write(BITMAP_LAYOUT(EVE_TEXTVGA, box->w * 2, text_h2)); + eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * 8, text_h2 * 16)); + } else { + eos_eve_dl_write(NOP()); + eos_eve_dl_write(NOP()); + eos_eve_dl_write(NOP()); + eos_eve_dl_write(NOP()); + } + + eos_eve_dl_write(BEGIN(EVE_BITMAPS)); + eos_eve_dl_write(VERTEX2II(box->x, box->y, 0, 0)); + if (text_h2) { + eos_eve_dl_write(VERTEX2II(box->x, box->y + text_h1 * 16, 1, 0)); + } else { + eos_eve_dl_write(NOP()); + } + eos_eve_dl_write(END()); +} + +void eos_eve_text_draw(EVETextBox *box) { + box->dl_offset = eos_eve_dl_offset(); + eos_eve_text_update(box); +} + +void eos_eve_text_putc(EVETextBox *box, int c) { + int line_c, line_n; + + line_c = box->buf_idx / 2 / box->w; + + eos_eve_write16(EVE_RAM_G + box->buf_addr + box->buf_idx, 0x0A00 | (c & 0xff)); + box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2); + + line_n = box->buf_idx / 2 / box->w; + if ((line_c != line_n) && (_line_diff(box, line_n) == box->h)) { + _line_scroll(box); + } +} + +void eos_eve_text_newline(EVETextBox *box) { + int line = (box->buf_idx / 2 / box->w + 1) % box->buf_line_h; + box->buf_idx = line * box->w * 2; + if (_line_diff(box, line) == box->h) { + _line_scroll(box); + } +}
\ No newline at end of file diff --git a/code/fe310/eos/eve_text.h b/code/fe310/eos/eve_text.h new file mode 100644 index 0000000..e882195 --- /dev/null +++ b/code/fe310/eos/eve_text.h @@ -0,0 +1,20 @@ +#include <stdint.h> + +typedef struct EVETextBox { + uint16_t buf_addr; + int buf_line_h; + int w; + int h; + int x; + int y; + int buf_idx; + int line_idx; + uint16_t dl_offset; + uint8_t bitmap_handle; +} EVETextBox; + +void eos_eve_text_init(EVETextBox *box, uint16_t buf_addr, int buf_line_h, int w, int h, int x, int y, uint8_t bitmap_handle); +void eos_eve_text_update(EVETextBox *box); +void eos_eve_text_draw(EVETextBox *box); +void eos_eve_text_putc(EVETextBox *box, int c); +void eos_eve_text_newline(EVETextBox *box);
\ No newline at end of file |