summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--code/fe310/eos/Makefile2
-rw-r--r--code/fe310/eos/eve.c36
-rw-r--r--code/fe310/eos/eve.h6
-rw-r--r--code/fe310/eos/eve_text.c100
-rw-r--r--code/fe310/eos/eve_text.h20
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