From 2d9f22e056b61917979db67da49fc0655b0af3a4 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Tue, 7 Jan 2020 00:54:54 +0100 Subject: touch event hanlder: added tracking/dragging; text box: added drag/scroll capability; added keyboard --- code/fe310/eos/Makefile | 2 +- code/fe310/eos/eve.c | 291 +++++++++++++++++++++++++++------------------- code/fe310/eos/eve.h | 23 +++- code/fe310/eos/eve_kbd.c | 115 ++++++++++++++++++ code/fe310/eos/eve_kbd.h | 18 +++ code/fe310/eos/eve_text.c | 160 ++++++++++++++++++------- code/fe310/eos/eve_text.h | 25 ++-- code/fe310/eos/msgq.c | 1 - 8 files changed, 458 insertions(+), 177 deletions(-) create mode 100644 code/fe310/eos/eve_kbd.c create mode 100644 code/fe310/eos/eve_kbd.h diff --git a/code/fe310/eos/Makefile b/code/fe310/eos/Makefile index 133a36a..95e0da5 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 eve_text.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_kbd.o eve_text.o %.o: %.c %.h diff --git a/code/fe310/eos/eve.c b/code/fe310/eos/eve.c index bd94be2..98a729d 100644 --- a/code/fe310/eos/eve.c +++ b/code/fe310/eos/eve.c @@ -13,9 +13,12 @@ #include "eve.h" #include "irq_def.h" -#define MEM_WRITE 0x800000 +#define MEM_WRITE 0x800000 -#define EVE_PIN_INT 0 +#define EVE_PIN_INT 0 +#define EVE_MAX_TOUCH 5 + +#define EVE_ETYPE_INT 1 static char eve_cmd_burst; static uint16_t eve_cmd_offset; @@ -24,9 +27,33 @@ static uint32_t eve_dl_addr; static int eve_int_mask = EVE_INT_TAG | EVE_INT_TOUCH; static int eve_multitouch = 0; static uint8_t eve_tag0; -EVETag eve_tag[5]; +static EOSTouch eve_touch[5]; +static uint8_t eve_touch_evt[256]; static eos_eve_fptr_t eve_renderer; +static const uint32_t _reg_touch[] = { + REG_CTOUCH_TOUCH0_XY, + REG_CTOUCH_TOUCH1_XY, + REG_CTOUCH_TOUCH2_XY, + REG_CTOUCH_TOUCH3_XY +}; + +static const uint32_t _reg_tag[] = { + REG_TOUCH_TAG, + REG_TOUCH_TAG1, + REG_TOUCH_TAG2, + REG_TOUCH_TAG3, + REG_TOUCH_TAG4 +}; + +static const uint32_t _reg_track[] = { + REG_TRACKER, + REG_TRACKER_1, + REG_TRACKER_2, + REG_TRACKER_3, + REG_TRACKER_4 +}; + void eos_eve_command(uint8_t command, uint8_t parameter) { eos_spi_cs_set(); eos_spi_xchg24(((uint32_t)command << 16) | ((uint32_t)parameter << 8), 0); @@ -263,147 +290,148 @@ void eos_eve_cmd_burst_end(void) { static void eve_handler_int(void) { GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); - eos_evtq_push_isr(EOS_EVT_UI, NULL, 0); + eos_evtq_push_isr(EOS_EVT_UI | EVE_ETYPE_INT, NULL, 0); return; } static void eve_handler_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - char render = 0; - int touch_tag_idx = -1; - uint8_t flags = eos_eve_read8(REG_INT_FLAGS) & eve_int_mask; + uint8_t flags; uint8_t touch_tag; uint32_t touch_xy; - EVETag *tag; - + uint32_t touch_track; + uint8_t tag0 = eve_tag0; + uint8_t touch_idx = 0; + int touch_idx_max = -1; + int i; + EOSTouch *touch; + + eos_spi_dev_start(EOS_SPI_DEV_DISP); + flags = eos_eve_read8(REG_INT_FLAGS) & eve_int_mask; if (!eve_multitouch) { - if (flags & EVE_INT_TAG) { - touch_tag = eos_eve_read8(REG_TOUCH_TAG); - eve_tag[0].value_prev = eve_tag[0].value; - eve_tag[0].value = touch_tag; - touch_tag_idx = 0; - if (touch_tag) eve_tag0 = touch_tag; - } + touch = &eve_touch[0]; + + tag0 = eve_tag0; + touch->evt &= (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH0_XY); if (touch_xy == 0x80008000) { - eve_tag[0].t = 0; + touch_tag = 0; + eve_tag0 = 0; + touch->t = 0; + touch->evt &= ~(EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); + if (eve_int_mask & EVE_INT_CONVCOMPLETE) { + eve_int_mask &= ~EVE_INT_CONVCOMPLETE; + eos_eve_write8(REG_INT_MASK, eve_int_mask); + } } else { - eve_tag[0].t = 1; - eve_tag[0].x = touch_xy >> 16; - eve_tag[0].y = touch_xy & 0xffff; + touch->t = 1; + touch->x = touch_xy >> 16; + touch->y = touch_xy & 0xffff; + if ((flags & EVE_INT_TAG) && !(touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK))) { + touch_tag = eos_eve_read8(REG_TOUCH_TAG); + } else { + touch_tag = touch->tag; + } + if (touch->evt & EOS_TOUCH_ETYPE_TRACK) { + touch_track = eos_eve_read32(REG_TRACKER); + touch->tracker.tag = touch_track & 0xffff; + touch->tracker.val = touch_track >> 16; + } + if (touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK)) { + touch_idx = 1; + touch_idx_max = 1; + } if (flags & EVE_INT_TOUCH) { eve_multitouch = 1; - eve_int_mask |= EVE_INT_CONVCOMPLETE; - eos_eve_write8(REG_INT_MASK, eve_int_mask); + if (!(eve_int_mask & EVE_INT_CONVCOMPLETE)) { + eve_int_mask |= EVE_INT_CONVCOMPLETE; + eos_eve_write8(REG_INT_MASK, eve_int_mask); + } } } - } else if (flags & EVE_INT_CONVCOMPLETE) { - tag = &eve_tag[0]; - touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH0_XY); - if (touch_xy == 0x80008000) { - touch_tag = 0; - tag->t = 0; - } else { - touch_tag = eos_eve_read8(REG_TOUCH_TAG); - tag->t = 1; - tag->x = touch_xy >> 16; - tag->y = touch_xy & 0xffff; - } - if (touch_tag != tag->value) { - tag->value_prev = tag->value; - tag->value = touch_tag; - touch_tag_idx = 0; - } - - tag = &eve_tag[1]; - touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH1_XY); - if (touch_xy == 0x80008000) { - touch_tag = 0; - tag->t = 0; - } else { - touch_tag = eos_eve_read8(REG_TOUCH_TAG1); - tag->t = 1; - tag->x = touch_xy >> 16; - tag->y = touch_xy & 0xffff; - } - if (touch_tag != tag->value) { - tag->value_prev = tag->value; - tag->value = touch_tag; - touch_tag_idx = 1; - } - - tag = &eve_tag[2]; - touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH2_XY); - if (touch_xy == 0x80008000) { - touch_tag = 0; - tag->t = 0; - } else { - touch_tag = eos_eve_read8(REG_TOUCH_TAG2); - tag->t = 1; - tag->x = touch_xy >> 16; - tag->y = touch_xy & 0xffff; - } - if (touch_tag != tag->value) { - tag->value_prev = tag->value; - tag->value = touch_tag; - touch_tag_idx = 2; - } - - tag = &eve_tag[3]; - touch_xy = eos_eve_read32(REG_CTOUCH_TOUCH3_XY); - if (touch_xy == 0x80008000) { - touch_tag = 0; - tag->t = 0; - } else { - touch_tag = eos_eve_read8(REG_TOUCH_TAG3); - tag->t = 1; - tag->x = touch_xy >> 16; - tag->y = touch_xy & 0xffff; - } - if (touch_tag != tag->value) { - tag->value_prev = tag->value; - tag->value = touch_tag; - touch_tag_idx = 3; - } - - tag = &eve_tag[4]; - touch_xy = ((uint32_t)eos_eve_read16(REG_CTOUCH_TOUCH4_X) << 16) | eos_eve_read16(REG_CTOUCH_TOUCH4_Y); - if (touch_xy == 0x80008000) { - touch_tag = 0; - tag->t = 0; - } else { - touch_tag = eos_eve_read8(REG_TOUCH_TAG4); - tag->t = 1; - tag->x = touch_xy >> 16; - tag->y = touch_xy & 0xffff; + if ((touch_tag != touch->tag) && !(touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK))) { + touch->tag_prev = touch->tag; + touch->tag = touch_tag; + touch_idx = 1; + touch_idx_max = 1; + if (touch->tag) touch->evt |= EOS_TOUCH_ETYPE_DOWN; + if (touch->tag_prev) touch->evt |= EOS_TOUCH_ETYPE_UP; + if (touch_tag && !eve_tag0) { + eve_tag0 = touch_tag; + tag0 = touch_tag; + if (eve_touch_evt[touch_tag]) { + touch->evt |= eve_touch_evt[touch_tag]; + touch->tracker.tag = 0; + if (!(eve_int_mask & EVE_INT_CONVCOMPLETE)) { + eve_int_mask |= EVE_INT_CONVCOMPLETE; + eos_eve_write8(REG_INT_MASK, eve_int_mask); + } + } + } } - if (touch_tag != tag->value) { - tag->value_prev = tag->value; - tag->value = touch_tag; - touch_tag_idx = 4; + } else if (flags & EVE_INT_CONVCOMPLETE) { + int touched = 0; + + for (i=0; ievt &= (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); + touch_xy = i < 4 ? eos_eve_read32(_reg_touch[i]) : (((uint32_t)eos_eve_read16(REG_CTOUCH_TOUCH4_X) << 16) | eos_eve_read16(REG_CTOUCH_TOUCH4_Y)); + if (touch_xy == 0x80008000) { + touch_tag = 0; + touch->t = 0; + touch->evt &= ~(EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK); + } else { + touch->t = 1; + touch->x = touch_xy >> 16; + touch->y = touch_xy & 0xffff; + if (!(touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK))) { + touch_tag = eos_eve_read8(_reg_tag[i]); + } else { + touch_tag = touch->tag; + } + if (touch->evt & EOS_TOUCH_ETYPE_TRACK) { + touch_track = eos_eve_read32(_reg_track[i]); + touch->tracker.tag = touch_track & 0xffff; + touch->tracker.val = touch_track >> 16; + } + if (touch->evt & (EOS_TOUCH_ETYPE_DRAG | EOS_TOUCH_ETYPE_TRACK)) { + touch_idx |= (1 << i); + touch_idx_max = i + 1; + } + touched = 1; + } + if (touch_tag != touch->tag) { + touch->tag_prev = touch->tag; + touch->tag = touch_tag; + touch_idx |= (1 << i); + touch_idx_max = i + 1; + if (touch->tag) touch->evt |= EOS_TOUCH_ETYPE_DOWN; + if (touch->tag_prev) touch->evt |= EOS_TOUCH_ETYPE_UP; + if (eve_touch_evt[touch_tag]) { + touch->evt |= eve_touch_evt[touch_tag]; + touch->tracker.tag = 0; + } + } } - if (!eve_tag[1].t && !eve_tag[2].t && !eve_tag[3].t && !eve_tag[4].t) { + if (!touched) { + eve_tag0 = 0; eve_multitouch = 0; eve_int_mask &= ~EVE_INT_CONVCOMPLETE; eos_eve_write8(REG_INT_MASK, eve_int_mask); } } - if (touch_tag_idx != -1) render = 1; - if (render) eve_renderer(eve_tag0, touch_tag_idx); - - /* - uint32_t track = eos_eve_read32(REG_TRACKER); - printf("F:%x TAG:%x %x %x %x %x %x\n", flags, eve_tag0, eve_tag[0].value, eve_tag[1].value, eve_tag[2].value, eve_tag[3].value, eve_tag[4].value); - if (flags & 0x04) { - track_tag = track & 0xffff; - track_val = track >> 16; + if (touch_idx_max != -1) { + for (i=0; i> 1; + } } - */ GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INT); GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); - return; + eos_spi_dev_stop(); } int eos_eve_init(void) { @@ -514,10 +542,33 @@ int eos_eve_init(void) { return EOS_OK; } -void eos_eve_set_renderer(eos_eve_fptr_t renderer) { +void eos_eve_set_renderer(eos_eve_fptr_t renderer, uint8_t flags) { eve_renderer = renderer; + eos_evtq_set_flags(EOS_EVT_UI | EVE_ETYPE_INT, flags); +} + +EOSTouch *eos_touch_evt(uint8_t tag0, int touch_idx, uint8_t tag_min, uint8_t tag_max, uint8_t *evt) { + uint8_t tag; + EOSTouch *ret = NULL; + + *evt = 0; + if ((touch_idx < 0) || (touch_idx > 4)) return ret; + + ret = &eve_touch[touch_idx]; + if ((tag0 < tag_min) || (tag0 > tag_max)) return ret; + + tag = eve_touch[touch_idx].tag; + if ((tag >= tag_min) && (tag <= tag_max)) *evt |= (eve_touch[touch_idx].evt & (EOS_TOUCH_ETYPE_DOWN | EOS_TOUCH_ETYPE_DRAG)); + + tag = eve_touch[touch_idx].tag_prev; + if ((tag >= tag_min) && (tag <= tag_max)) *evt |= (eve_touch[touch_idx].evt & EOS_TOUCH_ETYPE_UP); + + tag = eve_touch[touch_idx].tracker.tag; + if ((tag >= tag_min) && (tag <= tag_max)) *evt |= (eve_touch[touch_idx].evt & EOS_TOUCH_ETYPE_TRACK); + + return ret; } -EVETag *eos_eve_tag(void) { - return eve_tag; +void eos_touch_set_evt(uint8_t tag, uint8_t evt) { + eve_touch_evt[tag] = evt; } diff --git a/code/fe310/eos/eve.h b/code/fe310/eos/eve.h index bf6c4e8..dc22f80 100644 --- a/code/fe310/eos/eve.h +++ b/code/fe310/eos/eve.h @@ -2,13 +2,23 @@ #include "eve_def.h" -typedef struct EVETag { +#define EOS_TOUCH_ETYPE_DOWN 0x01 +#define EOS_TOUCH_ETYPE_UP 0x02 +#define EOS_TOUCH_ETYPE_DRAG 0x04 +#define EOS_TOUCH_ETYPE_TRACK 0x08 + +typedef struct EOSTouch { uint16_t x; uint16_t y; - uint8_t value; - uint8_t value_prev; + uint8_t tag; + uint8_t tag_prev; + uint8_t evt; char t; -} EVETag; + struct { + uint16_t tag; + uint16_t val; + } tracker; +} EOSTouch; typedef void (*eos_eve_fptr_t) (uint8_t, int); @@ -38,5 +48,6 @@ void eos_eve_cmd_burst_start(void); void eos_eve_cmd_burst_end(void); int eos_eve_init(void); -void eos_eve_set_renderer(eos_eve_fptr_t renderer); -EVETag *eos_eve_tag(void); \ No newline at end of file +void eos_eve_set_renderer(eos_eve_fptr_t renderer, uint8_t flags); +EOSTouch *eos_touch_evt(uint8_t tag0, int touch_idx, uint8_t tag_min, uint8_t tag_max, uint8_t *evt); +void eos_touch_set_evt(uint8_t tag, uint8_t evt); diff --git a/code/fe310/eos/eve_kbd.c b/code/fe310/eos/eve_kbd.c new file mode 100644 index 0000000..00d5328 --- /dev/null +++ b/code/fe310/eos/eve_kbd.c @@ -0,0 +1,115 @@ +#include "eve.h" +#include "eve_kbd.h" + +#define FLAG_SHIFT 0x01 +#define FLAG_CTRL 0x02 +#define FLAG_FN 0x04 + +#define KEY_SHIFT 0x11 +#define KEY_CTRL 0x12 +#define KEY_FN 0x13 + +#define KEY_DEL 0x08 +#define KEY_RET 0x0a + +#define KEYS_Y 575 +#define KEYS_FSIZE 29 +#define KEYS_HEIGHT 40 +#define KEYS_RSIZE 45 + +void eos_kbd_init(EOSKbd *kbd, eos_kbd_fptr_t key_down_f, uint32_t mem_addr, uint32_t *mem_next) { + eos_eve_write16(REG_CMD_DL, 0); + eos_kbd_update(kbd); + eos_eve_cmd_exec(1); + kbd->mem_addr = mem_addr; + kbd->mem_size = eos_eve_read16(REG_CMD_DL); + kbd->key_modifier = 0; + kbd->key_count = 0; + kbd->key_down = 0; + kbd->key_down_f = key_down_f; + eos_eve_cmd(CMD_MEMCPY, "www", kbd->mem_addr, EVE_RAM_DL, kbd->mem_size); + eos_eve_cmd_exec(1); + *mem_next = kbd->mem_addr + kbd->mem_size; +} + +void eos_kbd_draw(EOSKbd *kbd, uint8_t tag0, int touch_idx) { + uint8_t evt; + EOSTouch *t = eos_touch_evt(tag0, touch_idx, 1, 127, &evt); + + if (t && evt) { + if (evt & EOS_TOUCH_ETYPE_DOWN) { + uint8_t _tag = t->tag; + + if (_tag >= KEY_SHIFT && _tag <= KEY_FN) { + if (touch_idx == 0) { + uint8_t f = (1 << (_tag - KEY_SHIFT)); + + kbd->key_modifier = f; + kbd->key_modifier_sticky &= f; + kbd->key_modifier_lock &= f; + if (kbd->key_modifier_lock & f) { + kbd->key_modifier_lock &= ~f; + } else if (kbd->key_modifier_sticky & f) { + kbd->key_modifier_sticky &= ~f; + kbd->key_modifier_lock |= f; + } else { + kbd->key_modifier_sticky |= f; + } + } + } else { + kbd->key_count++; + kbd->key_down = _tag; + if (kbd->key_down_f) { + int c = _tag; + + if ((kbd->key_modifier & FLAG_CTRL) && (_tag >= '?') && (_tag <= '_')) c = (_tag - '@') & 0x7f; + kbd->key_down_f(c); + } + } + } + if (evt & EOS_TOUCH_ETYPE_UP) { + uint8_t _tag = t->tag_prev; + + if (_tag >= KEY_SHIFT && _tag <= KEY_FN) { + if (touch_idx == 0) { + uint8_t f = (1 << (_tag - KEY_SHIFT)); + + if (!((kbd->key_modifier_lock | kbd->key_modifier_sticky) & f)) { + kbd->key_modifier &= ~f; + } + } + } else { + if (kbd->key_count) kbd->key_count--; + if (!kbd->key_count) kbd->key_down = 0; + if (kbd->key_modifier_sticky) { + if (touch_idx == 0) kbd->key_modifier &= ~kbd->key_modifier_sticky; + kbd->key_modifier_sticky = 0; + } + } + } + eos_kbd_update(kbd); + } else { + eos_eve_cmd(CMD_APPEND, "ww", kbd->mem_addr, kbd->mem_size); + } +} + +void eos_kbd_update(EOSKbd *kbd) { + eos_eve_cmd_dl(SAVE_CONTEXT()); + eos_eve_cmd(CMD_KEYS, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 0, 480, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & (FLAG_FN | FLAG_SHIFT) ? "!@#$%^&*()" : (kbd->key_modifier & FLAG_CTRL ? " @[\\]^_? " : "1234567890")); + eos_eve_cmd(CMD_KEYS, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 1, 480, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & FLAG_FN ? "-_=+[]{}\\|" : kbd->key_modifier & (FLAG_SHIFT | FLAG_CTRL) ? "QWERTYUIOP" : "qwertyuiop"); + eos_eve_cmd(CMD_KEYS, "hhhhhhs", 24, KEYS_Y + KEYS_RSIZE * 2, 432, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & FLAG_FN ? "`~ ;:'\"" : kbd->key_modifier & (FLAG_SHIFT | FLAG_CTRL) ? "ASDFGHJKL" : "asdfghjkl"); + eos_eve_cmd(CMD_KEYS, "hhhhhhs", 72, KEYS_Y + KEYS_RSIZE * 3, 335, KEYS_HEIGHT, KEYS_FSIZE, kbd->key_down, kbd->key_modifier & FLAG_FN ? " ,.<>/?" : kbd->key_modifier & (FLAG_SHIFT | FLAG_CTRL) ? "ZXCVBNM" : "zxcvbnm"); + eos_eve_cmd_dl(TAG(KEY_SHIFT)); + eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 3, 69, KEYS_HEIGHT, 21, kbd->key_modifier & FLAG_SHIFT ? EVE_OPT_FLAT : 0, "shift"); + eos_eve_cmd_dl(TAG(KEY_DEL)); + eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 410, KEYS_Y + KEYS_RSIZE * 3, 70, KEYS_HEIGHT, 21, kbd->key_down == KEY_DEL ? EVE_OPT_FLAT : 0, "del"); + eos_eve_cmd_dl(TAG(KEY_FN)); + eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 0, KEYS_Y + KEYS_RSIZE * 4, 69, KEYS_HEIGHT, 21, kbd->key_modifier & FLAG_FN ? EVE_OPT_FLAT : 0, "fn"); + eos_eve_cmd_dl(TAG(KEY_CTRL)); + eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 72, KEYS_Y + KEYS_RSIZE * 4, 69, KEYS_HEIGHT, 21, kbd->key_modifier & FLAG_CTRL ? EVE_OPT_FLAT : 0, "ctrl"); + eos_eve_cmd_dl(TAG(' ')); + eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 144, KEYS_Y + KEYS_RSIZE * 4, 263, KEYS_HEIGHT, 21, kbd->key_down == ' ' ? EVE_OPT_FLAT : 0, ""); + eos_eve_cmd_dl(TAG(KEY_RET)); + eos_eve_cmd(CMD_BUTTON, "hhhhhhs", 410, KEYS_Y + KEYS_RSIZE * 4, 69, KEYS_HEIGHT, 21, kbd->key_down == KEY_RET ? EVE_OPT_FLAT : 0, "ret"); + eos_eve_cmd_dl(RESTORE_CONTEXT()); +} \ No newline at end of file diff --git a/code/fe310/eos/eve_kbd.h b/code/fe310/eos/eve_kbd.h new file mode 100644 index 0000000..60a2ff2 --- /dev/null +++ b/code/fe310/eos/eve_kbd.h @@ -0,0 +1,18 @@ +#include + +typedef void (*eos_kbd_fptr_t) (int); + +typedef struct EOSKbd { + uint32_t mem_addr; + uint16_t mem_size; + uint8_t key_count; + uint8_t key_down; + uint8_t key_modifier; + uint8_t key_modifier_sticky; + uint8_t key_modifier_lock; + eos_kbd_fptr_t key_down_f; +} EOSKbd; + +void eos_kbd_init(EOSKbd *kbd, eos_kbd_fptr_t key_down_f, uint32_t mem_addr, uint32_t *mem_next); +void eos_kbd_draw(EOSKbd *kbd, uint8_t tag0, int touch_idx); +void eos_kbd_update(EOSKbd *kbd); \ No newline at end of file diff --git a/code/fe310/eos/eve_text.c b/code/fe310/eos/eve_text.c index 4e343a0..93e628c 100644 --- a/code/fe310/eos/eve_text.c +++ b/code/fe310/eos/eve_text.c @@ -1,100 +1,180 @@ #include "eve.h" #include "eve_text.h" -static int _line_diff(EVEText *box, int line) { - if (line > box->line_idx) { - return line - box->line_idx; - } else { - return box->buf_line_h - box->line_idx + line; - } -} +#define TEXT_ATTR 0x0A +#define TEXT_CRSR 0x02DB + +#define LINE_IDX_ADD(l1,l2,s) (((((l1) + (l2)) % (s)) + (s)) % (s)) +#define LINE_IDX_SUB(l1,l2,s) (((((l1) - (l2)) % (s)) + (s)) % (s)) -static void _line_scroll(EVEText *box) { +#define LINE_IDX_LTE(l1,l2,s,h) (LINE_IDX_SUB(l2,l1,s) <= (s) - (h)) +#define LINE_IDX_DIFF(l1,l2,s) ((l1) > (l2) ? (l1) - (l2) : (s) - (l2) + (l1)) + +static void scroll1(EOSText *box) { box->line_idx = (box->line_idx + 1) % box->buf_line_h; eos_eve_cmd(CMD_MEMSET, "www", box->buf_addr + box->buf_idx, 0x0, box->w * 2); eos_eve_cmd_exec(1); - eos_eve_text_update(box); + box->dirty = 1; } -void eos_eve_text_init(EVEText *box, int x, int y, int w, int h, uint8_t bitmap_handle, uint32_t mem_addr, int buf_line_h, uint32_t *mem_next) { +void eos_text_init(EOSText *box, int x, int y, int w, int h, double scale_x, double scale_y, uint8_t tag, int buf_line_h, uint32_t mem_addr, uint32_t *mem_next) { box->x = x; box->y = y; box->w = w; box->h = h; - box->bitmap_handle = bitmap_handle; + box->tag = tag; + box->transform_a = 256/scale_x; + box->transform_e = 256/scale_y; + box->ch_w = scale_x * 8; + box->ch_h = scale_y * 16; + box->dl_size = 17; box->buf_addr = mem_addr; box->buf_line_h = buf_line_h; box->buf_idx = 0; box->line_idx = 0; + if (box->transform_a != 256) { + box->dl_size += 1; + } + if (box->transform_e != 256) { + box->dl_size += 1; + } + + eos_touch_set_evt(tag, EOS_TOUCH_ETYPE_DRAG); eos_eve_cmd(CMD_MEMSET, "www", mem_addr, 0x0, w * 2 * buf_line_h); eos_eve_cmd_exec(1); - eos_eve_text_update(box); - *mem_next = box->buf_addr + box->w * 2 * box->buf_line_h + 12 * 4; + eos_text_update(box, -1); + *mem_next = box->buf_addr + box->w * 2 * box->buf_line_h + box->dl_size * 4; } -void eos_eve_text_draw(EVEText *box) { - eos_eve_cmd(CMD_APPEND, "ww", box->buf_addr + box->w * 2 * box->buf_line_h, 12 * 4); +void eos_text_draw(EOSText *box, uint8_t tag0, int touch_idx) { + static int y0; + static int line_idx = -1; + static int line_idx_last; + uint8_t evt; + EOSTouch *t = eos_touch_evt(tag0, touch_idx, box->tag, box->tag, &evt); + + if (t && evt) { + if (evt & EOS_TOUCH_ETYPE_DOWN) { + y0 = t->y; + if (line_idx < 0) { + line_idx = box->line_idx; + line_idx_last = line_idx; + } + } + if (evt & EOS_TOUCH_ETYPE_UP) { + line_idx = line_idx_last; + } + if (evt & EOS_TOUCH_ETYPE_DRAG) { + int _line_idx = LINE_IDX_ADD(line_idx, (y0 - t->y) / box->ch_h, box->buf_line_h); + if (LINE_IDX_LTE(_line_idx, box->line_idx, box->buf_line_h, box->h)) { + eos_text_update(box, _line_idx); + line_idx_last = _line_idx; + } + } + } else if (line_idx >= 0) { + line_idx = -1; + box->dirty = 1; + } + + if (box->dirty) { + eos_text_update(box, -1); + box->dirty = 0; + } + eos_eve_cmd(CMD_APPEND, "ww", box->buf_addr + box->w * 2 * box->buf_line_h, box->dl_size * 4); } -void eos_eve_text_update(EVEText *box) { +void eos_text_update(EOSText *box, int line_idx) { int text_h1; int text_h2; - if (box->line_idx + box->h > box->buf_line_h) { - text_h1 = box->buf_line_h - box->line_idx; + if (line_idx < 0) line_idx = box->line_idx; + + if (line_idx + box->h > box->buf_line_h) { + text_h1 = box->buf_line_h - line_idx; text_h2 = box->h - text_h1; } else { text_h1 = box->h; text_h2 = 0; } eos_eve_dl_start(box->buf_addr + box->w * 2 * box->buf_line_h); - eos_eve_dl_write(BITMAP_HANDLE(box->bitmap_handle)); - eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr + box->line_idx * box->w * 2)); + + eos_eve_dl_write(SAVE_CONTEXT()); + eos_eve_dl_write(BEGIN(EVE_BITMAPS)); + eos_eve_dl_write(TAG(box->tag)); + eos_eve_dl_write(VERTEX_FORMAT(0)); + eos_eve_dl_write(BITMAP_HANDLE(15)); + if (box->transform_a != 256) { + eos_eve_dl_write(BITMAP_TRANSFORM_A(box->transform_a)); + } + if (box->transform_e != 256) { + eos_eve_dl_write(BITMAP_TRANSFORM_E(box->transform_e)); + } + eos_eve_dl_write(BITMAP_SOURCE(box->buf_addr + line_idx * box->w * 2)); 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)); + eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * box->ch_w, text_h1 * box->ch_h)); + eos_eve_dl_write(BITMAP_SIZE_H(box->w * box->ch_w, text_h1 * box->ch_h)); + eos_eve_dl_write(VERTEX2F(box->x, box->y)); 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)); + eos_eve_dl_write(BITMAP_SIZE(EVE_NEAREST, EVE_BORDER, EVE_BORDER, box->w * box->ch_w, text_h2 * box->ch_h)); + eos_eve_dl_write(BITMAP_SIZE_H(box->w * box->ch_w, text_h2 * box->ch_h)); + eos_eve_dl_write(VERTEX2F(box->x, box->y + text_h1 * box->ch_h)); } 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()); + eos_eve_dl_write(RESTORE_CONTEXT()); } -void eos_eve_text_putc(EVEText *box, int c) { +void eos_text_putc(EOSText *box, int c) { int line_c, line_n; - line_c = box->buf_idx / 2 / box->w; + switch (c) { + case '\b': + eos_text_backspace(box); + break; + case '\r': + case '\n': + eos_text_newline(box); + break; + default: + line_c = box->buf_idx / 2 / box->w; - eos_eve_write16(box->buf_addr + box->buf_idx, 0x0A00 | (c & 0xff)); - box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2); + eos_eve_write16(box->buf_addr + box->buf_idx, 0x0200 | (c & 0xff)); + box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2); + eos_eve_write16(box->buf_addr + box->buf_idx, TEXT_CRSR); - line_n = box->buf_idx / 2 / box->w; - if ((line_c != line_n) && (_line_diff(box, line_n) == box->h)) { - _line_scroll(box); + line_n = box->buf_idx / 2 / box->w; + if ((line_c != line_n) && (LINE_IDX_DIFF(line_n, box->line_idx, box->buf_line_h) == box->h)) scroll1(box); + break; } } -void eos_eve_text_newline(EVEText *box) { +void eos_text_newline(EOSText *box) { int line = (box->buf_idx / 2 / box->w + 1) % box->buf_line_h; + + eos_eve_write16(box->buf_addr + box->buf_idx, 0); box->buf_idx = line * box->w * 2; - if (_line_diff(box, line) == box->h) { - _line_scroll(box); + if (LINE_IDX_DIFF(line, box->line_idx, box->buf_line_h) == box->h) scroll1(box); + eos_eve_write16(box->buf_addr + box->buf_idx, TEXT_CRSR); +} + +void eos_text_backspace(EOSText *box) { + uint16_t c; + + eos_eve_write16(box->buf_addr + box->buf_idx, 0); + box->buf_idx = (box->buf_idx - 2) % (box->buf_line_h * box->w * 2); + if (eos_eve_read16(box->buf_addr + box->buf_idx) == 0) { + box->buf_idx = (box->buf_idx + 2) % (box->buf_line_h * box->w * 2); } + eos_eve_write16(box->buf_addr + box->buf_idx, TEXT_CRSR); } \ No newline at end of file diff --git a/code/fe310/eos/eve_text.h b/code/fe310/eos/eve_text.h index 350be45..794f430 100644 --- a/code/fe310/eos/eve_text.h +++ b/code/fe310/eos/eve_text.h @@ -1,19 +1,26 @@ #include -typedef struct EVEText { +typedef struct EOSText { int x; int y; int w; int h; - uint32_t buf_addr; int buf_line_h; int buf_idx; int line_idx; - uint8_t bitmap_handle; -} EVEText; + uint32_t buf_addr; + uint16_t transform_a; + uint16_t transform_e; + uint8_t tag; + uint8_t ch_h; + uint8_t ch_w; + uint8_t dl_size; + char dirty; +} EOSText; -void eos_eve_text_init(EVEText *box, int x, int y, int w, int h, uint8_t bitmap_handle, uint32_t mem_addr, int buf_line_h, uint32_t *mem_next); -void eos_eve_text_draw(EVEText *box); -void eos_eve_text_update(EVEText *box); -void eos_eve_text_putc(EVEText *box, int c); -void eos_eve_text_newline(EVEText *box); +void eos_text_init(EOSText *box, int x, int y, int w, int h, double scale_x, double scale_y, uint8_t tag, int buf_line_h, uint32_t mem_addr, uint32_t *mem_next); +void eos_text_draw(EOSText *box, uint8_t tag0, int touch_idx); +void eos_text_update(EOSText *box, int line_idx); +void eos_text_putc(EOSText *box, int c); +void eos_text_newline(EOSText *box); +void eos_text_backspace(EOSText *box); diff --git a/code/fe310/eos/msgq.c b/code/fe310/eos/msgq.c index 2b20f31..07ea70f 100644 --- a/code/fe310/eos/msgq.c +++ b/code/fe310/eos/msgq.c @@ -10,7 +10,6 @@ #define IDX_LT(a,b) ((uint8_t)((uint8_t)(a) - (uint8_t)(b)) > IDX_HALF) #define IDX_LTE(a,b) ((uint8_t)((uint8_t)(b) - (uint8_t)(a)) < IDX_HALF) - void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->idx_r = 0; msgq->idx_w = 0; -- cgit v1.2.3