summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fw/fe310/eos/dev/Makefile2
-rw-r--r--fw/fe310/eos/dev/gt911.c278
-rw-r--r--fw/fe310/eos/dev/gt911.h24
-rw-r--r--fw/fe310/eos/dev/ili9806e.c431
-rw-r--r--fw/fe310/eos/dev/ili9806e.h3
-rw-r--r--fw/fe310/eos/soc/Makefile2
-rw-r--r--fw/fe310/eos/soc/spi9bit.c57
-rw-r--r--fw/fe310/eos/soc/spi9bit.h4
8 files changed, 799 insertions, 2 deletions
diff --git a/fw/fe310/eos/dev/Makefile b/fw/fe310/eos/dev/Makefile
index 7407212..a5d3f77 100644
--- a/fw/fe310/eos/dev/Makefile
+++ b/fw/fe310/eos/dev/Makefile
@@ -1,7 +1,7 @@
include ../../common.mk
CFLAGS += -I$(bsp_dir)/include -I$(ext_dir)/crypto
-obj = spi.o net.o bq25895.o sdcard.o sdc_crypto.o eve.o ov2640.o cam.o
+obj = spi.o net.o bq25895.o sdcard.o sdc_crypto.o lcd.o gt911.o ili9806e.o eve.o ov2640.o cam.o
lib = ../../libeos-dev.a
diff --git a/fw/fe310/eos/dev/gt911.c b/fw/fe310/eos/dev/gt911.c
new file mode 100644
index 0000000..6fc2e1f
--- /dev/null
+++ b/fw/fe310/eos/dev/gt911.c
@@ -0,0 +1,278 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "platform.h"
+#include "board.h"
+
+#include "eos.h"
+#include "event.h"
+
+#include "soc/interrupt.h"
+#include "soc/timer.h"
+#include "soc/i2c.h"
+#include "soc/i2s.h"
+
+#include "dev/eve.h"
+
+#include "eve/eve.h"
+#include "eve/eve_touch_engine.h"
+
+#include "gt911.h"
+
+#define CMD_SLEEP 0x05
+
+#define REG_CMD 0x8040
+#define REG_CMD2 0x8046
+
+#define REG_STATUS 0x814E
+#define REG_POINTS 0x814F
+
+#define REG_CFG 0x8047
+#define REG_CHKSUM 0x80FF
+
+#define REG_X_THR 0x8057
+#define REG_Y_THR 0x8058
+
+#define REG_PRODID 0x8140
+
+#define SIZE_POINT_BUF 8
+#define MAX_POINTS 5
+
+static int clear_tag0 = 0;
+
+static void handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
+ uint8_t status;
+ uint8_t points[SIZE_POINT_BUF * MAX_POINTS];
+ int i, num_points;
+ int rv;
+
+ if (!eos_gt911_intr_enabled()) return;
+
+ rv = eos_i2c_read16(GT911_ADDR, REG_STATUS, &status, 1);
+ if (rv) goto handle_evt_fin1;
+
+ if (!(status & 0x80)) goto handle_evt_fin1;
+
+ num_points = status & 0xf;
+ if (num_points > 5) goto handle_evt_fin1;
+
+ rv = eos_spi_select(EOS_SPI_DEV_EVE);
+ if (rv) goto handle_evt_fin0;
+ while (!eve_touch_ehost_ready());
+
+ if (num_points) {
+ if (clear_tag0) {
+ eve_touch_clear_tag0();
+ clear_tag0 = 0;
+ }
+ rv = eos_i2c_read16(GT911_ADDR, REG_POINTS, points, SIZE_POINT_BUF * num_points);
+ if (rv) goto handle_evt_fin0;
+
+ for (i=0; i<num_points; i++) {
+ uint8_t *point_buf;
+ uint8_t point_id;
+ uint16_t point_x;
+ uint16_t point_y;
+
+ point_buf = points + SIZE_POINT_BUF * i;
+ point_id = point_buf[0];
+ point_x = point_buf[1] | (point_buf[2] << 8);
+ point_y = point_buf[3] | (point_buf[4] << 8);
+ eve_touch_ehost_enter(point_id, point_x, point_y);
+ }
+ } else {
+ eve_touch_ehost_enter(0, 0x8000, 0x8000);
+ clear_tag0 = 1;
+ }
+
+ eve_touch_ehost_end();
+ eos_spi_deselect();
+
+ if (!eos_eve_intr_enabled()) {
+ eos_eve_poll();
+ }
+
+handle_evt_fin0:
+ status = 0;
+ rv = eos_i2c_write16(GT911_ADDR, REG_STATUS, &status, 1);
+
+handle_evt_fin1:
+ GPIO_REG(GPIO_RISE_IE) |= (1 << CTP_PIN_INT);
+}
+
+static void handle_intr(void) {
+ GPIO_REG(GPIO_RISE_IE) &= ~(1 << CTP_PIN_INT);
+ GPIO_REG(GPIO_RISE_IP) = (1 << CTP_PIN_INT);
+ eos_evtq_push_isr(EOS_EVT_CTP | CTP_ETYPE_INTR, NULL, 0);
+}
+
+int g911_command(uint8_t command) {
+ int rv;
+
+ if (command > 0x07) {
+ rv = eos_i2c_write16(GT911_ADDR, REG_CMD2, &command, 1);
+ if (rv) return rv;
+ }
+
+ rv = eos_i2c_write16(GT911_ADDR, REG_CMD, &command, 1);
+ if (rv) return rv;
+
+ return EOS_OK;
+}
+
+static uint8_t gt911_chksum(uint8_t *buf, uint8_t len) {
+ int i;
+ uint8_t csum = 0;
+
+ for(i=0; i<len; i++) {
+ csum += buf[i];
+ }
+
+ //csum %= 256;
+ csum = (~csum) + 1;
+
+ return csum;
+}
+
+static int gt911_chip_id(char *buf) {
+ int rv;
+
+ rv = eos_i2c_read16(GT911_ADDR, REG_PRODID, buf, 4);
+ return rv;
+}
+
+void eos_gt911_init(void) {
+ eos_intr_set_handler(INT_GPIO_BASE + CTP_PIN_INT, handle_intr);
+ eos_intr_set_priority(INT_GPIO_BASE + CTP_PIN_INT, IRQ_PRIORITY_CTP);
+ eos_evtq_set_handler(EOS_EVT_CTP, handle_evt);
+}
+
+void eos_gt911_intr_enable(void) {
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << CTP_PIN_INT);
+ GPIO_REG(GPIO_RISE_IE) |= (1 << CTP_PIN_INT);
+ eos_intr_enable(INT_GPIO_BASE + CTP_PIN_INT);
+}
+
+void eos_gt911_intr_disable(void) {
+ eos_intr_disable(INT_GPIO_BASE + CTP_PIN_INT);
+ GPIO_REG(GPIO_RISE_IE) &= ~(1 << CTP_PIN_INT);
+ GPIO_REG(GPIO_INPUT_EN) &= ~(1 << CTP_PIN_INT);
+}
+
+int eos_gt911_intr_enabled(void) {
+ return !!(GPIO_REG(GPIO_INPUT_EN) & (1 << CTP_PIN_INT));
+}
+
+void eos_gt911_reset(void) {
+ eos_gt911_intr_disable();
+
+ /* INT and RST output and low */
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~((1 << CTP_PIN_INT) | (1 << CTP_PIN_RST));
+ GPIO_REG(GPIO_OUTPUT_EN) |= ((1 << CTP_PIN_INT) | (1 << CTP_PIN_RST));
+
+ /* T2: > 10ms */
+ eos_time_sleep(12);
+
+ /* high: 0x28/0x29 (0x14 7bit), low: 0xBA/0xBB (0x5D 7bit) */
+ if (GT911_ADDR == 0x14) {
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << CTP_PIN_INT);
+ }
+
+ /* T3: > 100us */
+ eos_time_sleep(1);
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << CTP_PIN_RST);
+
+ /* T4: > 5ms */
+ eos_time_sleep(6);
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << CTP_PIN_INT);
+ /* end select I2C slave addr */
+
+ /* T5: > 50ms */
+ eos_time_sleep(51);
+
+ /* set INT as input */
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << CTP_PIN_INT);
+ eos_gt911_intr_enable();
+}
+
+void eos_gt911_sleep(void) {
+ eos_gt911_intr_disable();
+
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << CTP_PIN_INT);
+ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << CTP_PIN_INT);
+
+ g911_command(CMD_SLEEP);
+}
+
+void eos_gt911_wake(void) {
+ /* in case of wake from mcu sleep */
+ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << CTP_PIN_INT);
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << CTP_PIN_INT);
+
+ eos_time_sleep(5);
+ GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << CTP_PIN_INT);
+ GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << CTP_PIN_INT);
+
+ eos_gt911_intr_enable();
+}
+
+int eos_gt911_cfg_read(uint8_t *cfg_buf) {
+ int rv;
+
+ rv = eos_i2c_read16(GT911_ADDR, REG_CFG, cfg_buf, GT911_SIZE_CFG);
+ return rv;
+}
+
+int eos_gt911_cfg_write(uint8_t *cfg_buf) {
+ int rv;
+
+ cfg_buf[GT911_SIZE_CFG - 2] = gt911_chksum(cfg_buf, GT911_SIZE_CFG - 2);
+ cfg_buf[GT911_SIZE_CFG - 1] = 1;
+
+ rv = eos_i2c_write16(GT911_ADDR, REG_CFG, cfg_buf, GT911_SIZE_CFG);
+ return rv;
+}
+
+int eos_gt911_cfg_print(void) {
+ int i, rv;
+ uint8_t cfg_buf[GT911_SIZE_CFG];
+
+ rv = eos_gt911_cfg_read(cfg_buf);
+ if (rv) return rv;
+
+ printf("GT911 CFG:\n");
+ for (i=0; i<GT911_SIZE_CFG-2; i++) {
+ printf("%.2X", cfg_buf[i]);
+ if (i % 8 == 7) {
+ printf("\n");
+ } else {
+ printf(" ");
+ }
+ }
+
+ return EOS_OK;
+}
+
+void eos_gt911_set_reg(uint8_t *cfg_buf, uint16_t reg, uint8_t val) {
+ cfg_buf[reg - REG_CFG] = val;
+}
+
+uint8_t eos_gt911_get_reg(uint8_t *cfg_buf, uint16_t reg) {
+ return cfg_buf[reg - REG_CFG];
+}
+
+int eos_gt911_set_threshold(void) {
+ int rv;
+ uint8_t cfg_buf[GT911_SIZE_CFG];
+
+ rv = eos_gt911_cfg_read(cfg_buf);
+ if (rv) return rv;
+
+ eos_gt911_set_reg(cfg_buf, REG_X_THR, 1);
+ eos_gt911_set_reg(cfg_buf, REG_Y_THR, 1);
+
+ rv = eos_gt911_cfg_write(cfg_buf);
+ return rv;
+}
diff --git a/fw/fe310/eos/dev/gt911.h b/fw/fe310/eos/dev/gt911.h
new file mode 100644
index 0000000..179652b
--- /dev/null
+++ b/fw/fe310/eos/dev/gt911.h
@@ -0,0 +1,24 @@
+#include <stdint.h>
+
+#define CTP_ETYPE_INTR 1
+
+#define GT911_SIZE_CFG 186
+
+#define GT911_ADDR 0x5d
+
+void eos_gt911_init(void);
+void eos_gt911_intr_enable(void);
+void eos_gt911_intr_disable(void);
+int eos_gt911_intr_enabled(void);
+
+void eos_gt911_reset(void);
+void eos_gt911_sleep(void);
+void eos_gt911_wake(void);
+
+int eos_gt911_cfg_read(uint8_t *cfg_buf);
+int eos_gt911_cfg_write(uint8_t *cfg_buf);
+int eos_gt911_cfg_print(void);
+
+void eos_gt911_set_reg(uint8_t *cfg_buf, uint16_t reg, uint8_t val);
+uint8_t eos_gt911_get_reg(uint8_t *cfg_buf, uint16_t reg);
+int eos_gt911_set_threshold(void); \ No newline at end of file
diff --git a/fw/fe310/eos/dev/ili9806e.c b/fw/fe310/eos/dev/ili9806e.c
new file mode 100644
index 0000000..b8bc67f
--- /dev/null
+++ b/fw/fe310/eos/dev/ili9806e.c
@@ -0,0 +1,431 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "eos.h"
+
+#include "soc/spi.h"
+#include "soc/spi9bit.h"
+#include "soc/timer.h"
+
+#include "ili9806e.h"
+
+int eos_ili9806e_init(void) {
+ int rv;
+ uint8_t chip_id[3];
+
+ eos_spi_cs_set();
+
+ /* LCD Setting */
+ eos_spi9bit_write(0, 0xFF); // change to Page 1 CMD
+ eos_spi9bit_write(1, 0xFF);
+ eos_spi9bit_write(1, 0x98);
+ eos_spi9bit_write(1, 0x06);
+ eos_spi9bit_write(1, 0x04);
+ eos_spi9bit_write(1, 0x01);
+
+ // eos_spi9bit_write(0, 0x08); // Output SDA
+ // eos_spi9bit_write(1, 0x10);
+
+ eos_spi9bit_write(0, 0xFE); // enable read
+ eos_spi9bit_write(1, 0x81);
+
+ eos_spi9bit_write(0, 0x00); // RDID4
+ eos_spi9bit_read(&chip_id[0]);
+
+ eos_spi9bit_write(0, 0x01);
+ eos_spi9bit_read(&chip_id[1]);
+
+ eos_spi9bit_write(0, 0x02);
+ eos_spi9bit_read(&chip_id[2]);
+
+ printf("LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]);
+
+ eos_spi9bit_write(0, 0xFE); // disable read
+ eos_spi9bit_write(1, 0x00);
+
+ if (memcmp(chip_id, "\x98\x06\x04", sizeof(chip_id))) {
+ eos_spi_cs_clear();
+ return EOS_ERR_ABSENT;
+ }
+
+ eos_spi9bit_write(0, 0x20); // set DE/VSYNC mode
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x21); // DE = 1 Active
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x30); // resolution setting 480 X 854
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x31); // inversion setting 2-dot
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x40); // BT AVDD,AVDD
+ eos_spi9bit_write(1, 0x16);
+
+ eos_spi9bit_write(0, 0x41);
+ eos_spi9bit_write(1, 0x33); // 22
+
+ eos_spi9bit_write(0, 0x42);
+ eos_spi9bit_write(1, 0x03); // VGL=DDVDH+VCIP-DDVDL, VGH=2DDVDL-VCIP
+
+ eos_spi9bit_write(0, 0x43);
+ eos_spi9bit_write(1, 0x09); // set VGH clamp level
+
+ eos_spi9bit_write(0, 0x44);
+ eos_spi9bit_write(1, 0x06); // set VGL clamp level
+
+ eos_spi9bit_write(0, 0x50); // VREG1
+ eos_spi9bit_write(1, 0x88);
+
+ eos_spi9bit_write(0, 0x51); // VREG2
+ eos_spi9bit_write(1, 0x88);
+
+ eos_spi9bit_write(0, 0x52); // flicker MSB
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x53); // flicker LSB
+ eos_spi9bit_write(1, 0x49); // VCOM
+
+ eos_spi9bit_write(0, 0x55); // flicker
+ eos_spi9bit_write(1, 0x49);
+
+ eos_spi9bit_write(0, 0x60);
+ eos_spi9bit_write(1, 0x07);
+
+ eos_spi9bit_write(0, 0x61);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x62);
+ eos_spi9bit_write(1, 0x07);
+
+ eos_spi9bit_write(0, 0x63);
+ eos_spi9bit_write(1, 0x00);
+
+ /* Gamma Setting */
+ eos_spi9bit_write(0, 0xA0); // positive Gamma
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0xA1);
+ eos_spi9bit_write(1, 0x09);
+
+ eos_spi9bit_write(0, 0xA2);
+ eos_spi9bit_write(1, 0x11);
+
+ eos_spi9bit_write(0, 0xA3);
+ eos_spi9bit_write(1, 0x0B);
+
+ eos_spi9bit_write(0, 0xA4);
+ eos_spi9bit_write(1, 0x05);
+
+ eos_spi9bit_write(0, 0xA5);
+ eos_spi9bit_write(1, 0x08);
+
+ eos_spi9bit_write(0, 0xA6);
+ eos_spi9bit_write(1, 0x06);
+
+ eos_spi9bit_write(0, 0xA7);
+ eos_spi9bit_write(1, 0x04);
+
+ eos_spi9bit_write(0, 0xA8);
+ eos_spi9bit_write(1, 0x09);
+
+ eos_spi9bit_write(0, 0xA9);
+ eos_spi9bit_write(1, 0x0C);
+
+ eos_spi9bit_write(0, 0xAA);
+ eos_spi9bit_write(1, 0x15);
+
+ eos_spi9bit_write(0, 0xAB);
+ eos_spi9bit_write(1, 0x08);
+
+ eos_spi9bit_write(0, 0xAC);
+ eos_spi9bit_write(1, 0x0F);
+
+ eos_spi9bit_write(0, 0xAD);
+ eos_spi9bit_write(1, 0x12);
+
+ eos_spi9bit_write(0, 0xAE);
+ eos_spi9bit_write(1, 0x09);
+
+ eos_spi9bit_write(0, 0xAF);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0xC0); // negative Gamma
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0xC1);
+ eos_spi9bit_write(1, 0x09);
+
+ eos_spi9bit_write(0, 0xC2);
+ eos_spi9bit_write(1, 0x10);
+
+ eos_spi9bit_write(0, 0xC3);
+ eos_spi9bit_write(1, 0x0C);
+
+ eos_spi9bit_write(0, 0xC4);
+ eos_spi9bit_write(1, 0x05);
+
+ eos_spi9bit_write(0, 0xC5);
+ eos_spi9bit_write(1, 0x08);
+
+ eos_spi9bit_write(0, 0xC6);
+ eos_spi9bit_write(1, 0x06);
+
+ eos_spi9bit_write(0, 0xC7);
+ eos_spi9bit_write(1, 0x04);
+
+ eos_spi9bit_write(0, 0xC8);
+ eos_spi9bit_write(1, 0x08);
+
+ eos_spi9bit_write(0, 0xC9);
+ eos_spi9bit_write(1, 0x0C);
+
+ eos_spi9bit_write(0, 0xCA);
+ eos_spi9bit_write(1, 0x14);
+
+ eos_spi9bit_write(0, 0xCB);
+ eos_spi9bit_write(1, 0x08);
+
+ eos_spi9bit_write(0, 0xCC);
+ eos_spi9bit_write(1, 0x0F);
+
+ eos_spi9bit_write(0, 0xCD);
+ eos_spi9bit_write(1, 0x11);
+
+ eos_spi9bit_write(0, 0xCE);
+ eos_spi9bit_write(1, 0x09);
+
+ eos_spi9bit_write(0, 0xCF);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0xFF); // change to Page 6 CMD for GIP timing
+ eos_spi9bit_write(1, 0xFF);
+ eos_spi9bit_write(1, 0x98);
+ eos_spi9bit_write(1, 0x06);
+ eos_spi9bit_write(1, 0x04);
+ eos_spi9bit_write(1, 0x06);
+
+ eos_spi9bit_write(0, 0x00);
+ eos_spi9bit_write(1, 0x20);
+
+ eos_spi9bit_write(0, 0x01);
+ eos_spi9bit_write(1, 0x0A);
+
+ eos_spi9bit_write(0, 0x02);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x03);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x04);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x05);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x06);
+ eos_spi9bit_write(1, 0x98);
+
+ eos_spi9bit_write(0, 0x07);
+ eos_spi9bit_write(1, 0x06);
+
+ eos_spi9bit_write(0, 0x08);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x09);
+ eos_spi9bit_write(1, 0x80);
+
+ eos_spi9bit_write(0, 0x0A);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x0B);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x0C);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x0D);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x0E);
+ eos_spi9bit_write(1, 0x05);
+
+ eos_spi9bit_write(0, 0x0F);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x10);
+ eos_spi9bit_write(1, 0xF0);
+
+ eos_spi9bit_write(0, 0x11);
+ eos_spi9bit_write(1, 0xF4);
+
+ eos_spi9bit_write(0, 0x12);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x13);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x14);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x15);
+ eos_spi9bit_write(1, 0xC0);
+
+ eos_spi9bit_write(0, 0x16);
+ eos_spi9bit_write(1, 0x08);
+
+ eos_spi9bit_write(0, 0x17);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x18);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x19);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x1A);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x1B);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x1C);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x1D);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x20);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x21);
+ eos_spi9bit_write(1, 0x23);
+
+ eos_spi9bit_write(0, 0x22);
+ eos_spi9bit_write(1, 0x45);
+
+ eos_spi9bit_write(0, 0x23);
+ eos_spi9bit_write(1, 0x67);
+
+ eos_spi9bit_write(0, 0x24);
+ eos_spi9bit_write(1, 0x01);
+
+ eos_spi9bit_write(0, 0x25);
+ eos_spi9bit_write(1, 0x23);
+
+ eos_spi9bit_write(0, 0x26);
+ eos_spi9bit_write(1, 0x45);
+
+ eos_spi9bit_write(0, 0x27);
+ eos_spi9bit_write(1, 0x67);
+
+ eos_spi9bit_write(0, 0x30);
+ eos_spi9bit_write(1, 0x11);
+
+ eos_spi9bit_write(0, 0x31);
+ eos_spi9bit_write(1, 0x11);
+
+ eos_spi9bit_write(0, 0x32);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x33);
+ eos_spi9bit_write(1, 0xEE);
+
+ eos_spi9bit_write(0, 0x34);
+ eos_spi9bit_write(1, 0xFF);
+
+ eos_spi9bit_write(0, 0x35);
+ eos_spi9bit_write(1, 0xBB);
+
+ eos_spi9bit_write(0, 0x36);
+ eos_spi9bit_write(1, 0xAA);
+
+ eos_spi9bit_write(0, 0x37);
+ eos_spi9bit_write(1, 0xDD);
+
+ eos_spi9bit_write(0, 0x38);
+ eos_spi9bit_write(1, 0xCC);
+
+ eos_spi9bit_write(0, 0x39);
+ eos_spi9bit_write(1, 0x66);
+
+ eos_spi9bit_write(0, 0x3A);
+ eos_spi9bit_write(1, 0x77);
+
+ eos_spi9bit_write(0, 0x3B);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0x3C);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0x3D);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0x3E);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0x3F);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0x40);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0xFF); // change to Page 7 CMD for GIP timing
+ eos_spi9bit_write(1, 0xFF);
+ eos_spi9bit_write(1, 0x98);
+ eos_spi9bit_write(1, 0x06);
+ eos_spi9bit_write(1, 0x04);
+ eos_spi9bit_write(1, 0x07);
+
+ eos_spi9bit_write(0, 0x17);
+ eos_spi9bit_write(1, 0x22);
+
+ eos_spi9bit_write(0, 0x02);
+ eos_spi9bit_write(1, 0x77);
+
+ eos_spi9bit_write(0, 0x26);
+ eos_spi9bit_write(1, 0xB2);
+
+ eos_spi9bit_write(0, 0xFF); // change to Page 0 CMD for normal command
+ eos_spi9bit_write(1, 0xFF);
+ eos_spi9bit_write(1, 0x98);
+ eos_spi9bit_write(1, 0x06);
+ eos_spi9bit_write(1, 0x04);
+ eos_spi9bit_write(1, 0x00);
+
+ eos_spi9bit_write(0, 0x3A);
+ eos_spi9bit_write(1, 0x70); // 24BIT
+
+ eos_spi9bit_write(0, 0x11);
+ eos_time_sleep(120);
+ eos_spi9bit_write(0, 0x29);
+ eos_time_sleep(25);
+
+ eos_spi_cs_clear();
+
+ return EOS_OK;
+}
+
+void eos_ili9806e_sleep(void) {
+ eos_spi_cs_set();
+
+ eos_spi9bit_write(0, 0x28);
+ eos_time_sleep(10);
+ eos_spi9bit_write(0, 0x10);
+
+ eos_spi_cs_clear();
+
+}
+
+void eos_ili9806e_wake(void) {
+ eos_spi_cs_set();
+
+ eos_spi9bit_write(0, 0x11);
+ eos_time_sleep(120);
+ eos_spi9bit_write(0, 0x29);
+
+ eos_spi_cs_clear();
+}
diff --git a/fw/fe310/eos/dev/ili9806e.h b/fw/fe310/eos/dev/ili9806e.h
new file mode 100644
index 0000000..5e14c54
--- /dev/null
+++ b/fw/fe310/eos/dev/ili9806e.h
@@ -0,0 +1,3 @@
+int eos_ili9806e_init(void);
+void eos_ili9806e_sleep(void);
+void eos_ili9806e_wake(void);
diff --git a/fw/fe310/eos/soc/Makefile b/fw/fe310/eos/soc/Makefile
index 1404c81..f5f072a 100644
--- a/fw/fe310/eos/soc/Makefile
+++ b/fw/fe310/eos/soc/Makefile
@@ -1,7 +1,7 @@
include ../../common.mk
CFLAGS += -I$(bsp_dir)/include -I$(bsp_dir)/drivers
-obj = trap_entry.o interrupt.o timer.o pwr.o i2s.o i2c.o uart.o spi.o
+obj = trap_entry.o interrupt.o timer.o pwr.o i2s.o i2c.o uart.o spi.o spi9bit.o
lib = ../../libeos-soc.a
diff --git a/fw/fe310/eos/soc/spi9bit.c b/fw/fe310/eos/soc/spi9bit.c
new file mode 100644
index 0000000..712dc81
--- /dev/null
+++ b/fw/fe310/eos/soc/spi9bit.c
@@ -0,0 +1,57 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "eos.h"
+
+#include "spi9bit.h"
+
+#define BIT_GET ((GPIO_REG(GPIO_INPUT_VAL) & (1 << IOF_SPI1_MISO)) >> IOF_SPI1_MISO)
+#define BIT_PUT(b) { if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); }
+
+#define SCK_UP { GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_SCK); }
+#define SCK_DN { GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); }
+
+static inline void _sleep(int n) {
+ volatile int x = n;
+
+ while(x) x--;
+}
+
+/* sck frequency for r/w operations is 0.8Mhz */
+void eos_spi9bit_read(uint8_t *data) {
+ int i;
+
+ *data = 0;
+ for (i=0; i<8; i++) {
+ _sleep(10);
+ *data = *data << 1;
+ *data |= BIT_GET;
+ SCK_UP;
+ _sleep(10);
+ SCK_DN;
+ }
+}
+
+void eos_spi9bit_write(uint8_t dc, uint8_t data) {
+ int i;
+
+ BIT_PUT(dc);
+ _sleep(10);
+ SCK_UP;
+ for (i=0; i<8; i++) {
+ _sleep(10);
+ SCK_DN;
+ BIT_PUT(data & 0x80);
+ _sleep(10);
+ SCK_UP;
+ data = data << 1;
+ }
+ _sleep(10);
+ SCK_DN;
+ BIT_PUT(0);
+}
diff --git a/fw/fe310/eos/soc/spi9bit.h b/fw/fe310/eos/soc/spi9bit.h
new file mode 100644
index 0000000..dd3c254
--- /dev/null
+++ b/fw/fe310/eos/soc/spi9bit.h
@@ -0,0 +1,4 @@
+#include <stdint.h>
+
+void eos_spi9bit_read(uint8_t *data);
+void eos_spi9bit_write(uint8_t dc, uint8_t data);