summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/dev
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/dev')
-rw-r--r--fw/fe310/eos/dev/Makefile12
-rw-r--r--fw/fe310/eos/dev/bq25895.c5
-rw-r--r--fw/fe310/eos/dev/cam.c10
-rw-r--r--fw/fe310/eos/dev/eve.c152
-rw-r--r--fw/fe310/eos/dev/eve.h9
-rw-r--r--fw/fe310/eos/dev/lcd.c546
-rw-r--r--fw/fe310/eos/dev/lcd.h12
-rw-r--r--fw/fe310/eos/dev/net.c598
-rw-r--r--fw/fe310/eos/dev/net.h47
-rw-r--r--fw/fe310/eos/dev/ov2640.c6
-rw-r--r--fw/fe310/eos/dev/sdc_crypto.h2
-rw-r--r--fw/fe310/eos/dev/sdcard.c4
-rw-r--r--fw/fe310/eos/dev/spi.c113
-rw-r--r--fw/fe310/eos/dev/spi.h21
-rw-r--r--fw/fe310/eos/dev/spi_cfg.h52
15 files changed, 1015 insertions, 574 deletions
diff --git a/fw/fe310/eos/dev/Makefile b/fw/fe310/eos/dev/Makefile
index 83cb1f5..7407212 100644
--- a/fw/fe310/eos/dev/Makefile
+++ b/fw/fe310/eos/dev/Makefile
@@ -1,7 +1,8 @@
include ../../common.mk
-CFLAGS += -I$(bsp_dir)/include
+CFLAGS += -I$(bsp_dir)/include -I$(ext_dir)/crypto
-obj = bq25895.o ov2640.o gt911.o
+obj = spi.o net.o bq25895.o sdcard.o sdc_crypto.o eve.o ov2640.o cam.o
+lib = ../../libeos-dev.a
%.o: %.c %.h
@@ -10,7 +11,10 @@ obj = bq25895.o ov2640.o gt911.o
%.o: %.S
$(CC) $(CFLAGS) -c $<
-all: $(obj)
+all: $(lib)
+
+$(lib): $(obj)
+ $(AR) rcs $@ $(obj)
clean:
- rm -f *.o
+ rm -f *.o $(lib)
diff --git a/fw/fe310/eos/dev/bq25895.c b/fw/fe310/eos/dev/bq25895.c
index b290926..11323c7 100644
--- a/fw/fe310/eos/dev/bq25895.c
+++ b/fw/fe310/eos/dev/bq25895.c
@@ -3,8 +3,9 @@
#include <stdio.h>
#include "eos.h"
-#include "pwr.h"
-#include "i2c.h"
+#include "soc/pwr.h"
+#include "soc/i2c.h"
+
#include "bq25895.h"
static int reg_read(uint8_t reg, uint8_t *data) {
diff --git a/fw/fe310/eos/dev/cam.c b/fw/fe310/eos/dev/cam.c
index 43293af..50a0bdd 100644
--- a/fw/fe310/eos/dev/cam.c
+++ b/fw/fe310/eos/dev/cam.c
@@ -2,7 +2,9 @@
#include <stdint.h>
#include "eos.h"
-#include "spi.h"
+
+#include "soc/spi.h"
+
#include "cam.h"
const int _eos_cam_resolution[][2] = {
@@ -105,7 +107,7 @@ int eos_cam_capture_done(void) {
void eos_cam_capture_wait(void) {
int done = 0;
-
+
while (!done) {
done = eos_cam_capture_done();
}
@@ -113,7 +115,7 @@ void eos_cam_capture_wait(void) {
uint32_t eos_cam_fbuf_size(void) {
uint32_t ret;
-
+
ret = reg_read(CAM_REG_FIFO_SIZE1);
ret |= reg_read(CAM_REG_FIFO_SIZE2) << 8;
ret |= (reg_read(CAM_REG_FIFO_SIZE3) & 0x7f) << 16;
@@ -122,7 +124,7 @@ uint32_t eos_cam_fbuf_size(void) {
void eos_cam_fbuf_read(uint8_t *buffer, uint16_t sz, int first) {
int i;
-
+
eos_spi_cs_set();
eos_spi_xchg8(CAM_REG_READ_BURST, 0);
if (first) eos_spi_xchg8(0, 0);
diff --git a/fw/fe310/eos/dev/eve.c b/fw/fe310/eos/dev/eve.c
new file mode 100644
index 0000000..0f98fed
--- /dev/null
+++ b/fw/fe310/eos/dev/eve.c
@@ -0,0 +1,152 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "platform.h"
+
+#include "eos.h"
+#include "event.h"
+
+#include "board.h"
+
+#include "soc/interrupt.h"
+#include "soc/pwr.h"
+#include "soc/i2s.h"
+
+#include "eve/eve.h"
+#include "eve/eve_touch_engine.h"
+
+#include "eve.h"
+
+static void handle_time(unsigned char type) {
+ if (!eos_eve_running()) return;
+
+ eve_spi_start();
+ eve_handle_time();
+ eve_spi_stop();
+}
+
+static void handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
+ if (!eos_eve_running()) return;
+
+ eve_spi_start();
+ eve_handle_intr();
+ eve_spi_stop();
+
+ GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INTR);
+}
+
+static void handle_intr(void) {
+ GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INTR);
+ GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INTR);
+ eos_evtq_push_isr(EOS_EVT_EVE | EVE_ETYPE_INTR, NULL, 0);
+}
+
+static void _start(void) {
+ eve_touch_start();
+ eve_start();
+
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << EVE_PIN_INTR);
+ GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INTR);
+
+ eos_intr_enable(INT_GPIO_BASE + EVE_PIN_INTR);
+}
+
+static void _stop(void) {
+ eos_intr_disable(INT_GPIO_BASE + EVE_PIN_INTR);
+
+ GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INTR);
+ GPIO_REG(GPIO_INPUT_EN) &= ~(1 << EVE_PIN_INTR);
+
+ eve_touch_stop();
+ eve_stop();
+}
+
+int eos_eve_init(uint8_t wakeup_cause) {
+ int rst = (wakeup_cause == EOS_PWR_WAKE_RST);
+ int rv = EVE_OK;
+
+ eve_spi_start();
+ if (rst) {
+ rv = eve_init();
+ if (!rv) {
+ eve_gpio_set_dir(EVE_GPIO_DIR);
+ eve_touch_init_engine();
+ }
+ } else {
+ eve_activate();
+ }
+ eve_spi_stop();
+
+ if (rv) return EOS_ERR;
+
+ eve_touch_init();
+
+ eos_evtq_set_handler(EOS_EVT_EVE, handle_evt);
+ eos_timer_set_handler(EOS_TIMER_ETYPE_UI, handle_time);
+ eos_intr_set_handler(INT_GPIO_BASE + EVE_PIN_INTR, handle_intr);
+ eos_intr_set_priority(INT_GPIO_BASE + EVE_PIN_INTR, IRQ_PRIORITY_EVE);
+
+ return EOS_OK;
+}
+
+void eos_eve_calibrate(void) {
+ uint32_t matrix[6];
+ int r;
+
+ eve_spi_start();
+
+ eve_brightness(0x40);
+ eve_touch_set_extended(0);
+
+ eve_cmd(CMD_TEXT, "hhhhs", EVE_HSIZE/2, EVE_VSIZE/2, 27, EVE_OPT_CENTER, "Please tap on the dot.");
+ eve_cmd(CMD_CALIBRATE, "w", 0);
+ eve_cmd_exec(0);
+
+ do {
+ r = eve_cmd_done();
+ if (r < 0) break;
+ eve_spi_stop();
+ eos_evtq_exec();
+ eve_spi_start();
+ } while (!r);
+
+ eve_touch_set_extended(1);
+ eve_brightness(0);
+
+ eve_touch_get_matrix(matrix);
+ eve_spi_stop();
+
+ printf("TOUCH MATRIX:\n");
+ printf("uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+}
+
+void eos_eve_set_touch_matrix(const uint32_t *matrix) {
+ eve_spi_start();
+ eve_touch_set_matrix(matrix);
+ eve_spi_stop();
+}
+
+int eos_eve_run(uint8_t wakeup_cause) {
+ eve_spi_start();
+ _start();
+ eve_start_clk();
+ eve_spi_stop();
+
+ return EOS_OK;
+}
+
+void eos_eve_start(void) {
+ eve_spi_start();
+ _start();
+ eve_spi_stop();
+}
+
+void eos_eve_stop(void) {
+ eve_spi_start();
+ _stop();
+ eve_spi_stop();
+}
+
+int eos_eve_running(void) {
+ return !!(GPIO_REG(GPIO_INPUT_EN) & (1 << EVE_PIN_INTR));
+}
diff --git a/fw/fe310/eos/dev/eve.h b/fw/fe310/eos/dev/eve.h
new file mode 100644
index 0000000..8eb982f
--- /dev/null
+++ b/fw/fe310/eos/dev/eve.h
@@ -0,0 +1,9 @@
+#include <stdint.h>
+
+int eos_eve_init(uint8_t wakeup_cause);
+void eos_eve_calibrate(void);
+void eos_eve_set_touch_matrix(const uint32_t *matrix);
+int eos_eve_run(uint8_t wakeup_cause);
+void eos_eve_start(void);
+void eos_eve_stop(void);
+int eos_eve_running(void);
diff --git a/fw/fe310/eos/dev/lcd.c b/fw/fe310/eos/dev/lcd.c
deleted file mode 100644
index 3080a13..0000000
--- a/fw/fe310/eos/dev/lcd.c
+++ /dev/null
@@ -1,546 +0,0 @@
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "encoding.h"
-#include "platform.h"
-
-#include "eos.h"
-#include "timer.h"
-#include "i2s.h"
-#include "net.h"
-#include "spi_dev.h"
-#include "eve/eve.h"
-
-#include "board.h"
-
-#include "lcd.h"
-
-#define BIT_PUT(b, pin) if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << (pin)); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << (pin));
-#define BIT_GET(pin) ((GPIO_REG(GPIO_INPUT_VAL) & (1 << (pin))) >> (pin))
-
-#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--;
-}
-
-int eos_lcd_select(void) {
- if (eos_i2s_running()) return EOS_ERR_BUSY;
- if (eos_spi_dev() != EOS_SPI_DEV_NET) return EOS_ERR_BUSY;
-
- eos_net_stop();
-
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << LCD_PIN_CS);
-
- GPIO_REG(GPIO_INPUT_EN) &= ~(1 << LCD_PIN_CS);
- GPIO_REG(GPIO_OUTPUT_EN) |= (1 << LCD_PIN_CS);
-
- GPIO_REG(GPIO_IOF_EN) &= ~SPI_IOF_MASK;
-
- return EOS_OK;
-}
-
-void eos_lcd_deselect(void) {
- GPIO_REG(GPIO_IOF_EN) |= SPI_IOF_MASK;
- eos_net_start();
-}
-
-void eos_lcd_cs_set(void) {
- GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << LCD_PIN_CS);
-}
-
-void eos_lcd_cs_clear(void) {
- GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << LCD_PIN_CS);
-}
-
-/* sck frequency for r/w operations is 0.8Mhz */
-void eos_lcd_write(uint8_t dc, uint8_t data) {
- int i;
-
- BIT_PUT(dc, IOF_SPI1_MOSI);
- _sleep(10);
- SCK_UP;
- for (i=0; i<8; i++) {
- _sleep(10);
- SCK_DN;
- BIT_PUT(data & 0x80, IOF_SPI1_MOSI);
- _sleep(10);
- SCK_UP;
- data = data << 1;
- }
- _sleep(10);
- SCK_DN;
-}
-
-void eos_lcd_read(uint8_t *data) {
- int i;
-
- *data = 0;
- for (i=0; i<8; i++) {
- _sleep(10);
- *data = *data << 1;
- *data |= BIT_GET(IOF_SPI1_MISO);
- SCK_UP;
- _sleep(10);
- SCK_DN;
- }
-}
-
-static int _init(void) {
- int rv;
- uint8_t chip_id[3];
-
- rv = eos_lcd_select();
- if (rv) return rv;
- eos_lcd_cs_set();
-
- /* LCD Setting */
- eos_lcd_write(0, 0xFF); // change to Page 1 CMD
- eos_lcd_write(1, 0xFF);
- eos_lcd_write(1, 0x98);
- eos_lcd_write(1, 0x06);
- eos_lcd_write(1, 0x04);
- eos_lcd_write(1, 0x01);
-
- // eos_lcd_write(0, 0x08); // Output SDA
- // eos_lcd_write(1, 0x10);
-
- eos_lcd_write(0, 0xFE); // enable read
- eos_lcd_write(1, 0x81);
-
- eos_lcd_write(0, 0x00); // RDID4
- eos_lcd_read(&chip_id[0]);
-
- eos_lcd_write(0, 0x01);
- eos_lcd_read(&chip_id[1]);
-
- eos_lcd_write(0, 0x02);
- eos_lcd_read(&chip_id[2]);
-
- printf("LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]);
-
- eos_lcd_write(0, 0xFE); // disable read
- eos_lcd_write(1, 0x00);
-
- if (memcmp(chip_id, "\x98\x06\x04", sizeof(chip_id))) {
- return EOS_ERR_ABSENT;
- }
-
- eos_lcd_write(0, 0x20); // set DE/VSYNC mode
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x21); // DE = 1 Active
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x30); // resolution setting 480 X 854
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x31); // inversion setting 2-dot
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x40); // BT AVDD,AVDD
- eos_lcd_write(1, 0x16);
-
- eos_lcd_write(0, 0x41);
- eos_lcd_write(1, 0x33); // 22
-
- eos_lcd_write(0, 0x42);
- eos_lcd_write(1, 0x03); // VGL=DDVDH+VCIP-DDVDL, VGH=2DDVDL-VCIP
-
- eos_lcd_write(0, 0x43);
- eos_lcd_write(1, 0x09); // set VGH clamp level
-
- eos_lcd_write(0, 0x44);
- eos_lcd_write(1, 0x06); // set VGL clamp level
-
- eos_lcd_write(0, 0x50); // VREG1
- eos_lcd_write(1, 0x88);
-
- eos_lcd_write(0, 0x51); // VREG2
- eos_lcd_write(1, 0x88);
-
- eos_lcd_write(0, 0x52); // flicker MSB
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x53); // flicker LSB
- eos_lcd_write(1, 0x49); // VCOM
-
- eos_lcd_write(0, 0x55); // flicker
- eos_lcd_write(1, 0x49);
-
- eos_lcd_write(0, 0x60);
- eos_lcd_write(1, 0x07);
-
- eos_lcd_write(0, 0x61);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x62);
- eos_lcd_write(1, 0x07);
-
- eos_lcd_write(0, 0x63);
- eos_lcd_write(1, 0x00);
-
- /* Gamma Setting */
- eos_lcd_write(0, 0xA0); // positive Gamma
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0xA1);
- eos_lcd_write(1, 0x09);
-
- eos_lcd_write(0, 0xA2);
- eos_lcd_write(1, 0x11);
-
- eos_lcd_write(0, 0xA3);
- eos_lcd_write(1, 0x0B);
-
- eos_lcd_write(0, 0xA4);
- eos_lcd_write(1, 0x05);
-
- eos_lcd_write(0, 0xA5);
- eos_lcd_write(1, 0x08);
-
- eos_lcd_write(0, 0xA6);
- eos_lcd_write(1, 0x06);
-
- eos_lcd_write(0, 0xA7);
- eos_lcd_write(1, 0x04);
-
- eos_lcd_write(0, 0xA8);
- eos_lcd_write(1, 0x09);
-
- eos_lcd_write(0, 0xA9);
- eos_lcd_write(1, 0x0C);
-
- eos_lcd_write(0, 0xAA);
- eos_lcd_write(1, 0x15);
-
- eos_lcd_write(0, 0xAB);
- eos_lcd_write(1, 0x08);
-
- eos_lcd_write(0, 0xAC);
- eos_lcd_write(1, 0x0F);
-
- eos_lcd_write(0, 0xAD);
- eos_lcd_write(1, 0x12);
-
- eos_lcd_write(0, 0xAE);
- eos_lcd_write(1, 0x09);
-
- eos_lcd_write(0, 0xAF);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0xC0); // negative Gamma
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0xC1);
- eos_lcd_write(1, 0x09);
-
- eos_lcd_write(0, 0xC2);
- eos_lcd_write(1, 0x10);
-
- eos_lcd_write(0, 0xC3);
- eos_lcd_write(1, 0x0C);
-
- eos_lcd_write(0, 0xC4);
- eos_lcd_write(1, 0x05);
-
- eos_lcd_write(0, 0xC5);
- eos_lcd_write(1, 0x08);
-
- eos_lcd_write(0, 0xC6);
- eos_lcd_write(1, 0x06);
-
- eos_lcd_write(0, 0xC7);
- eos_lcd_write(1, 0x04);
-
- eos_lcd_write(0, 0xC8);
- eos_lcd_write(1, 0x08);
-
- eos_lcd_write(0, 0xC9);
- eos_lcd_write(1, 0x0C);
-
- eos_lcd_write(0, 0xCA);
- eos_lcd_write(1, 0x14);
-
- eos_lcd_write(0, 0xCB);
- eos_lcd_write(1, 0x08);
-
- eos_lcd_write(0, 0xCC);
- eos_lcd_write(1, 0x0F);
-
- eos_lcd_write(0, 0xCD);
- eos_lcd_write(1, 0x11);
-
- eos_lcd_write(0, 0xCE);
- eos_lcd_write(1, 0x09);
-
- eos_lcd_write(0, 0xCF);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0xFF); // change to Page 6 CMD for GIP timing
- eos_lcd_write(1, 0xFF);
- eos_lcd_write(1, 0x98);
- eos_lcd_write(1, 0x06);
- eos_lcd_write(1, 0x04);
- eos_lcd_write(1, 0x06);
-
- eos_lcd_write(0, 0x00);
- eos_lcd_write(1, 0x20);
-
- eos_lcd_write(0, 0x01);
- eos_lcd_write(1, 0x0A);
-
- eos_lcd_write(0, 0x02);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x03);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x04);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x05);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x06);
- eos_lcd_write(1, 0x98);
-
- eos_lcd_write(0, 0x07);
- eos_lcd_write(1, 0x06);
-
- eos_lcd_write(0, 0x08);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x09);
- eos_lcd_write(1, 0x80);
-
- eos_lcd_write(0, 0x0A);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x0B);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x0C);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x0D);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x0E);
- eos_lcd_write(1, 0x05);
-
- eos_lcd_write(0, 0x0F);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x10);
- eos_lcd_write(1, 0xF0);
-
- eos_lcd_write(0, 0x11);
- eos_lcd_write(1, 0xF4);
-
- eos_lcd_write(0, 0x12);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x13);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x14);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x15);
- eos_lcd_write(1, 0xC0);
-
- eos_lcd_write(0, 0x16);
- eos_lcd_write(1, 0x08);
-
- eos_lcd_write(0, 0x17);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x18);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x19);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x1A);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x1B);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x1C);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x1D);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x20);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x21);
- eos_lcd_write(1, 0x23);
-
- eos_lcd_write(0, 0x22);
- eos_lcd_write(1, 0x45);
-
- eos_lcd_write(0, 0x23);
- eos_lcd_write(1, 0x67);
-
- eos_lcd_write(0, 0x24);
- eos_lcd_write(1, 0x01);
-
- eos_lcd_write(0, 0x25);
- eos_lcd_write(1, 0x23);
-
- eos_lcd_write(0, 0x26);
- eos_lcd_write(1, 0x45);
-
- eos_lcd_write(0, 0x27);
- eos_lcd_write(1, 0x67);
-
- eos_lcd_write(0, 0x30);
- eos_lcd_write(1, 0x11);
-
- eos_lcd_write(0, 0x31);
- eos_lcd_write(1, 0x11);
-
- eos_lcd_write(0, 0x32);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x33);
- eos_lcd_write(1, 0xEE);
-
- eos_lcd_write(0, 0x34);
- eos_lcd_write(1, 0xFF);
-
- eos_lcd_write(0, 0x35);
- eos_lcd_write(1, 0xBB);
-
- eos_lcd_write(0, 0x36);
- eos_lcd_write(1, 0xAA);
-
- eos_lcd_write(0, 0x37);
- eos_lcd_write(1, 0xDD);
-
- eos_lcd_write(0, 0x38);
- eos_lcd_write(1, 0xCC);
-
- eos_lcd_write(0, 0x39);
- eos_lcd_write(1, 0x66);
-
- eos_lcd_write(0, 0x3A);
- eos_lcd_write(1, 0x77);
-
- eos_lcd_write(0, 0x3B);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0x3C);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0x3D);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0x3E);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0x3F);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0x40);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0xFF); // change to Page 7 CMD for GIP timing
- eos_lcd_write(1, 0xFF);
- eos_lcd_write(1, 0x98);
- eos_lcd_write(1, 0x06);
- eos_lcd_write(1, 0x04);
- eos_lcd_write(1, 0x07);
-
- eos_lcd_write(0, 0x17);
- eos_lcd_write(1, 0x22);
-
- eos_lcd_write(0, 0x02);
- eos_lcd_write(1, 0x77);
-
- eos_lcd_write(0, 0x26);
- eos_lcd_write(1, 0xB2);
-
- eos_lcd_write(0, 0xFF); // change to Page 0 CMD for normal command
- eos_lcd_write(1, 0xFF);
- eos_lcd_write(1, 0x98);
- eos_lcd_write(1, 0x06);
- eos_lcd_write(1, 0x04);
- eos_lcd_write(1, 0x00);
-
- eos_lcd_write(0, 0x3A);
- eos_lcd_write(1, 0x70); // 24BIT
-
- eos_lcd_write(0, 0x11);
- eos_time_sleep(120);
- eos_lcd_write(0, 0x29);
- eos_time_sleep(25);
-
- eos_lcd_cs_clear();
- eos_lcd_deselect();
-
- return EOS_OK;
-}
-
-int eos_lcd_init(uint8_t wakeup_cause) {
- eos_spi_select(EOS_SPI_DEV_EVE);
- eve_gpio_set(EVE_GPIO_LCD_EN, 1);
- eos_spi_deselect();
- eos_time_sleep(200);
-
- return _init();
-}
-
-int eos_lcd_sleep(void) {
- int rv;
-
- rv = eos_lcd_select();
- if (rv) return rv;
-
- eos_lcd_cs_set();
-
- eos_lcd_write(0, 0x28);
- eos_time_sleep(10);
- eos_lcd_write(0, 0x10);
-
- eos_lcd_cs_clear();
- eos_lcd_deselect();
-
- eos_spi_select(EOS_SPI_DEV_EVE);
- eve_gpio_set(EVE_GPIO_LCD_EN, 0);
- eos_spi_deselect();
-
- return EOS_OK;
-}
-
-int eos_lcd_wake(void) {
- int rv;
-
- eos_spi_select(EOS_SPI_DEV_EVE);
- eve_gpio_set(EVE_GPIO_LCD_EN, 1);
- eos_spi_deselect();
- eos_time_sleep(200);
-
- rv = eos_lcd_select();
- if (rv) return rv;
-
- eos_lcd_cs_set();
-
- eos_lcd_write(0, 0x11);
- eos_time_sleep(120);
- eos_lcd_write(0, 0x29);
-
- eos_lcd_cs_clear();
- eos_lcd_deselect();
-
- return EOS_OK;
-}
diff --git a/fw/fe310/eos/dev/lcd.h b/fw/fe310/eos/dev/lcd.h
deleted file mode 100644
index 1bcb2cd..0000000
--- a/fw/fe310/eos/dev/lcd.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <stdint.h>
-
-int eos_lcd_init(uint8_t wakeup_cause);
-int eos_lcd_select(void);
-void eos_lcd_deselect(void);
-void eos_lcd_cs_set(void);
-void eos_lcd_cs_clear(void);
-void eos_lcd_write(uint8_t dc, uint8_t data);
-void eos_lcd_read(uint8_t *data);
-
-int eos_lcd_sleep(void);
-int eos_lcd_wake(void); \ No newline at end of file
diff --git a/fw/fe310/eos/dev/net.c b/fw/fe310/eos/dev/net.c
new file mode 100644
index 0000000..d287e5a
--- /dev/null
+++ b/fw/fe310/eos/dev/net.c
@@ -0,0 +1,598 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "eos.h"
+#include "msgq.h"
+#include "event.h"
+
+#include "board.h"
+
+#include "soc/interrupt.h"
+#include "soc/timer.h"
+#include "soc/pwr.h"
+#include "soc/spi.h"
+#include "soc/spi_priv.h"
+
+#include "spi.h"
+
+#include "net.h"
+
+#define NET_SIZE_HDR 3
+#define NET_STATE_FLAG_RUN 0x01
+#define NET_STATE_FLAG_INIT 0x02
+#define NET_STATE_FLAG_XCHG 0x04
+#define NET_STATE_FLAG_ONEW 0x10
+#define NET_STATE_FLAG_SYNC 0x20
+#define NET_STATE_FLAG_RTS 0x40
+#define NET_STATE_FLAG_CTS 0x80
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
+
+static EOSBufQ net_buf_q;
+static unsigned char *net_bufq_array[EOS_NET_SIZE_BUFQ];
+static unsigned char net_bufq_buffer[EOS_NET_SIZE_BUFQ][EOS_NET_SIZE_BUF];
+
+static EOSMsgQ net_send_q;
+static EOSMsgItem net_sndq_array[EOS_NET_SIZE_BUFQ];
+
+static volatile uint8_t net_state_flags = 0;
+static unsigned char net_state_type = 0;
+static uint32_t net_state_len_tx = 0;
+static uint32_t net_state_len_rx = 0;
+unsigned char *net_state_buf = NULL;
+
+static uint8_t net_state_next_cnt = 0;
+static unsigned char *net_state_next_buf = NULL;
+
+static eos_evt_handler_t net_handler[EOS_NET_MAX_MTYPE];
+static uint16_t net_wrapper_acq[EOS_EVT_MAX_EVT];
+static uint16_t net_flags_acq[EOS_EVT_MAX_EVT];
+
+static int net_xchg_sleep(void) {
+ int i;
+ int rv = EOS_OK;
+ volatile uint32_t x = 0;
+ net_state_flags &= ~NET_STATE_FLAG_CTS;
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
+
+ SPI1_REG(SPI_REG_TXFIFO) = 0xFF;
+ while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+ if (x & 0xFF) rv = EOS_ERR_BUSY;
+
+ for (i=0; i<7; i++) {
+ while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
+ SPI1_REG(SPI_REG_TXFIFO) = 0;
+ while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+ }
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
+
+ return rv;
+}
+
+static void net_xchg_wake(void) {
+ int i;
+ volatile uint32_t x = 0;
+ net_state_flags &= ~NET_STATE_FLAG_CTS;
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
+
+ for (i=0; i<8; i++) {
+ while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL);
+ SPI1_REG(SPI_REG_TXFIFO) = 0;
+ while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+ }
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
+}
+
+static void net_xchg_reset(void) {
+ volatile uint32_t x = 0;
+ net_state_flags &= ~NET_STATE_FLAG_CTS;
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
+
+ SPI1_REG(SPI_REG_TXFIFO) = 0;
+ while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY);
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
+}
+
+static void net_xchg_start(unsigned char type, unsigned char *buffer, uint16_t len) {
+ net_state_flags &= ~NET_STATE_FLAG_CTS;
+ net_state_flags |= (NET_STATE_FLAG_INIT | NET_STATE_FLAG_XCHG);
+
+ if (net_state_next_cnt && (net_state_next_buf == NULL)) type |= EOS_NET_MTYPE_FLAG_ONEW;
+ if (type & EOS_NET_MTYPE_FLAG_ONEW) net_state_flags |= NET_STATE_FLAG_ONEW;
+
+ net_state_type = type;
+ net_state_len_tx = len;
+ net_state_len_rx = 0;
+ net_state_buf = buffer;
+
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD;
+ SPI1_REG(SPI_REG_TXFIFO) = type;
+ SPI1_REG(SPI_REG_TXFIFO) = (len >> 8) & 0xFF;
+ SPI1_REG(SPI_REG_TXFIFO) = (len & 0xFF);
+ SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(2);
+ SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM;
+}
+
+static int net_xchg_next(unsigned char *_buffer) {
+ unsigned char type;
+ unsigned char *buffer = NULL;
+ uint16_t len;
+ int ret = _buffer ? 1 : 0;
+
+ eos_msgq_pop(&net_send_q, &type, &buffer, &len);
+ if (type) {
+ net_xchg_start(type, buffer, len);
+ } else if (net_state_flags & NET_STATE_FLAG_RTS) {
+ if (_buffer) {
+ buffer = _buffer;
+ ret = 0;
+ } else {
+ buffer = eos_bufq_pop(&net_buf_q);
+ }
+ if (buffer) net_xchg_start(0, buffer, 0);
+ }
+
+ return ret;
+}
+
+static void net_handle_xchg(void) {
+ volatile uint32_t r1, r2, r3;
+ uint32_t len;
+
+ if (net_state_flags & NET_STATE_FLAG_INIT) {
+ net_state_flags &= ~NET_STATE_FLAG_INIT;
+
+ r1 = SPI1_REG(SPI_REG_RXFIFO);
+ r2 = SPI1_REG(SPI_REG_RXFIFO);
+ r3 = SPI1_REG(SPI_REG_RXFIFO);
+
+ if (net_state_flags & NET_STATE_FLAG_ONEW) {
+ r1 = 0;
+ r2 = 0;
+ r3 = 0;
+ }
+
+ net_state_type = (r1 & 0xFF);
+ net_state_len_rx = (r2 & 0xFF) << 8;
+ net_state_len_rx |= (r3 & 0xFF);
+ len = MAX(net_state_len_tx, net_state_len_rx);
+
+ if (len > EOS_NET_MTU) {
+ net_state_flags &= ~NET_STATE_FLAG_XCHG;
+ SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO;
+ SPI1_REG(SPI_REG_IE) = 0x0;
+ return;
+ }
+
+ // esp32 dma workaraund
+ if (len < 8 - NET_SIZE_HDR) {
+ len = 8 - NET_SIZE_HDR;
+ } else if ((len + NET_SIZE_HDR) % 4 != 0) {
+ len = ((len + NET_SIZE_HDR)/4 + 1) * 4 - NET_SIZE_HDR;
+ }
+
+ _eos_spi_xchg_init(net_state_buf, len, 0);
+ SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM);
+ SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM;
+ return;
+ }
+
+ eos_spi_handle_xchg();
+ if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_AUTO) { // exchange done
+ if (!(net_state_flags & NET_STATE_FLAG_SYNC)) {
+ if (net_state_type) {
+ int r = eos_evtq_push_isr(EOS_EVT_NET | net_state_type, net_state_buf, net_state_len_rx);
+ if (r) eos_bufq_push(&net_buf_q, net_state_buf);
+ } else if (((net_state_flags & NET_STATE_FLAG_ONEW) || net_state_next_cnt) && (net_state_next_buf == NULL)) {
+ net_state_next_buf = net_state_buf;
+ } else {
+ eos_bufq_push(&net_buf_q, net_state_buf);
+ }
+ }
+ net_state_flags &= ~(NET_STATE_FLAG_ONEW | NET_STATE_FLAG_XCHG);
+ }
+}
+
+static void net_handle_cts(void) {
+ GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
+ net_state_flags |= NET_STATE_FLAG_CTS;
+
+ if (net_state_flags & NET_STATE_FLAG_RUN) {
+ net_xchg_next(NULL);
+ }
+}
+
+static void net_handle_rts(void) {
+ uint32_t rts_offset = (1 << NET_PIN_RTS);
+
+ if (GPIO_REG(GPIO_RISE_IP) & rts_offset) {
+ GPIO_REG(GPIO_RISE_IP) = rts_offset;
+ net_state_flags |= NET_STATE_FLAG_RTS;
+ if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) {
+ net_xchg_reset();
+ }
+ } else if (GPIO_REG(GPIO_FALL_IP) & rts_offset) {
+ GPIO_REG(GPIO_FALL_IP) = rts_offset;
+ net_state_flags &= ~NET_STATE_FLAG_RTS;
+ }
+}
+
+static void net_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) {
+ unsigned char idx = (type & ~EOS_EVT_MASK) - 1;
+
+ if (idx < EOS_NET_MAX_MTYPE) {
+ net_handler[idx](type, buffer, len);
+ } else {
+ eos_net_bad_handler(type, buffer, len);
+ }
+}
+
+static int net_acquire(unsigned char reserved) {
+ int ret = 0;
+
+ if (reserved) {
+ while (!ret) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (net_state_next_buf) {
+ ret = 1;
+ net_state_next_cnt--;
+ } else {
+ asm volatile ("wfi");
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ } else {
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (net_state_next_buf == NULL) net_state_next_buf = eos_bufq_pop(&net_buf_q);
+ ret = (net_state_next_buf != NULL);
+ if (!ret) net_state_next_cnt++;
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ return ret;
+}
+
+static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char idx, uint16_t flag) {
+ int ok;
+
+ ok = net_acquire(net_wrapper_acq[idx] & flag);
+ if (ok) {
+ eos_evtq_get_handler(type)(type, buffer, len);
+ eos_net_release();
+ net_wrapper_acq[idx] &= ~flag;
+ } else {
+ net_wrapper_acq[idx] |= flag;
+ eos_evtq_push(type, buffer, len);
+ }
+}
+
+static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
+ unsigned char idx = (type & EOS_EVT_MASK) >> 4;
+
+ if (idx && (idx <= EOS_EVT_MAX_EVT)) {
+ uint16_t flag = (uint16_t)1 << (type & ~EOS_EVT_MASK);
+
+ idx--;
+ if (flag & net_flags_acq[idx]) {
+ evt_handler_wrapper(type, buffer, len, idx, flag);
+ } else {
+ eos_evtq_get_handler(type)(type, buffer, len);
+ }
+ } else {
+ eos_evtq_bad_handler(type, buffer, len);
+ }
+}
+
+static void net_pause(void) {
+ net_state_flags &= ~NET_STATE_FLAG_RUN;
+}
+
+static void net_resume(void) {
+ net_state_flags |= NET_STATE_FLAG_RUN;
+ if (net_state_flags & NET_STATE_FLAG_CTS) {
+ net_xchg_next(NULL);
+ }
+}
+
+static void net_start(void) {
+ eos_spi_dev_configure(EOS_SPI_DEV_NET);
+ eos_intr_set_handler(INT_SPI1_BASE, net_handle_xchg);
+}
+
+static void net_stop(void) {
+ eos_intr_set_handler(INT_SPI1_BASE, NULL);
+}
+
+int eos_net_init(uint8_t wakeup_cause) {
+ int i;
+
+ eos_msgq_init(&net_send_q, net_sndq_array, EOS_NET_SIZE_BUFQ);
+ eos_bufq_init(&net_buf_q, net_bufq_array, EOS_NET_SIZE_BUFQ);
+ for (i=0; i<EOS_NET_SIZE_BUFQ; i++) {
+ eos_bufq_push(&net_buf_q, net_bufq_buffer[i]);
+ }
+
+ for (i=0; i<EOS_NET_MAX_MTYPE; i++) {
+ net_handler[i] = eos_net_bad_handler;
+ }
+ eos_evtq_set_handler(0, evt_handler);
+ eos_evtq_set_handler(EOS_EVT_NET, net_handle_evt);
+
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_CTS);
+ GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_CTS);
+ eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, IRQ_PRIORITY_NET_CTS, net_handle_cts);
+
+ GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_RTS);
+ GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_RTS);
+ GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_RTS);
+ eos_intr_set(INT_GPIO_BASE + NET_PIN_RTS, IRQ_PRIORITY_NET_RTS, net_handle_rts);
+
+ /* set initial state */
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) net_state_flags |= NET_STATE_FLAG_CTS;
+ if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS)) net_state_flags |= NET_STATE_FLAG_RTS;
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return EOS_OK;
+}
+
+int eos_net_run(uint8_t wakeup_cause) {
+ net_start();
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (wakeup_cause != EOS_PWR_WAKE_RST) {
+ if (wakeup_cause != EOS_PWR_WAKE_BTN) {
+ net_xchg_wake();
+ }
+ if (!(net_state_flags & NET_STATE_FLAG_CTS)) {
+ while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) {
+ asm volatile ("wfi");
+ }
+ GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
+ }
+ net_xchg_reset();
+ }
+ net_resume();
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return EOS_OK;
+}
+
+void eos_net_start(void) {
+ net_start();
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ net_resume();
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+void eos_net_stop(void) {
+ uint8_t done = 0;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (net_state_flags & NET_STATE_FLAG_RUN) {
+ net_state_flags &= ~NET_STATE_FLAG_RUN;
+ done = !(net_state_flags & NET_STATE_FLAG_XCHG);
+ } else {
+ done = 1;
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+
+ while (!done) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ done = !(net_state_flags & NET_STATE_FLAG_XCHG);
+ if (!done) asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ net_stop();
+}
+
+int eos_net_sleep(uint32_t timeout) {
+ volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME);
+ uint64_t then_ms = timeout + *mtime * 1000 / EOS_TIMER_RTC_FREQ;
+ uint8_t done = 0;
+ int rv = EOS_OK;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (!(net_state_flags & NET_STATE_FLAG_RUN)) rv = EOS_ERR;
+ set_csr(mstatus, MSTATUS_MIE);
+
+ if (rv) return rv;
+
+ do {
+ if (*mtime * 1000 / EOS_TIMER_RTC_FREQ > then_ms) return EOS_ERR_TIMEOUT;
+ clear_csr(mstatus, MSTATUS_MIE);
+ eos_evtq_flush_isr();
+ done = (eos_msgq_len(&net_send_q) == 0);
+ done = done && (!(net_state_flags & NET_STATE_FLAG_RTS) && (net_state_flags & NET_STATE_FLAG_CTS));
+ if (done) done = (net_xchg_sleep() == EOS_OK);
+ if (!done) {
+ asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+ } while (!done);
+
+ while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) {
+ if (*mtime * 1000 / EOS_TIMER_RTC_FREQ > then_ms) {
+ rv = EOS_ERR_TIMEOUT;
+ break;
+ }
+ asm volatile ("wfi");
+ }
+
+ if (!rv) {
+ GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS);
+ net_state_flags &= ~NET_STATE_FLAG_RUN;
+ }
+
+ set_csr(mstatus, MSTATUS_MIE);
+
+ return rv;
+}
+
+void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) {
+ eos_evtq_bad_handler(type, buffer, len);
+ if (buffer) eos_net_free(buffer, 0);
+}
+
+void eos_net_set_handler(unsigned char mtype, eos_evt_handler_t handler) {
+ if (handler == NULL) handler = eos_net_bad_handler;
+ if (mtype && (mtype <= EOS_NET_MAX_MTYPE)) net_handler[mtype - 1] = handler;
+}
+
+void eos_net_acquire_for_evt(unsigned char type, char acq) {
+ unsigned char idx = (type & EOS_EVT_MASK) >> 4;
+ uint16_t flag = type & ~EOS_EVT_MASK ? (uint16_t)1 << (type & ~EOS_EVT_MASK) : 0xFFFF;
+
+ if (idx && (idx <= EOS_EVT_MAX_EVT)) {
+ idx--;
+ net_flags_acq[idx] &= ~flag;
+ if (acq) net_flags_acq[idx] |= flag;
+ }
+}
+
+void eos_net_acquire(void) {
+ unsigned char acq = net_acquire(0);
+ if (!acq) net_acquire(1);
+}
+
+void eos_net_release(void) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (!net_state_next_cnt && net_state_next_buf) {
+ eos_bufq_push(&net_buf_q, net_state_next_buf);
+ net_state_next_buf = NULL;
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+unsigned char *eos_net_alloc(void) {
+ unsigned char *ret = NULL;
+
+ while (!ret) {
+ clear_csr(mstatus, MSTATUS_MIE);
+ if (net_state_next_buf) {
+ ret = net_state_next_buf;
+ net_state_next_buf = NULL;
+ } else {
+ asm volatile ("wfi");
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+ }
+
+ return ret;
+}
+
+void eos_net_free(unsigned char *buffer, unsigned char more) {
+ uint8_t do_release = 1;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if ((more || net_state_next_cnt) && (net_state_next_buf == NULL)) {
+ net_state_next_buf = buffer;
+ } else {
+ if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) {
+ do_release = net_xchg_next(buffer);
+ }
+ if (do_release) {
+ eos_bufq_push(&net_buf_q, buffer);
+ }
+ }
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
+static int net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len, unsigned char flags) {
+ int rv = EOS_OK;
+ int _sync = 0;
+ unsigned char _type = *type;
+ uint16_t _len = *len;
+ uint8_t spi_dev = EOS_SPI_DEV_NET;
+
+ if (flags & EOS_NET_FLAG_ONEW) _type |= EOS_NET_MTYPE_FLAG_ONEW;
+ if (flags & EOS_NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL;
+ if (flags & EOS_NET_FLAG_SYNC) _sync = 1;
+
+ clear_csr(mstatus, MSTATUS_MIE);
+ if ((flags & EOS_NET_FLAG_ONEW) && !(net_state_flags & NET_STATE_FLAG_RUN)) _sync = 1;
+
+ if (_sync && !(net_state_flags & NET_STATE_FLAG_RUN)) {
+ int _rv;
+
+ set_csr(mstatus, MSTATUS_MIE);
+ spi_dev = eos_spi_dev();
+ _rv = eos_spi_deselect();
+ if (_rv) return _rv;
+ clear_csr(mstatus, MSTATUS_MIE);
+ }
+
+ if (_sync) {
+ net_pause();
+ while (!(net_state_flags & NET_STATE_FLAG_CTS)) {
+ asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MIE);
+ }
+ if (flags & EOS_NET_FLAG_SYNC) {
+ net_state_flags |= NET_STATE_FLAG_SYNC;
+ }
+ net_xchg_start(_type, buffer, _len);
+ if (flags & EOS_NET_FLAG_SYNC) {
+ if (flags & EOS_NET_FLAG_REPL) {
+ while (!(net_state_flags & NET_STATE_FLAG_CTS)) {
+ asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MIE);
+ }
+ net_xchg_start(0, buffer, 0);
+ }
+ while (net_state_flags & NET_STATE_FLAG_XCHG) {
+ asm volatile ("wfi");
+ set_csr(mstatus, MSTATUS_MIE);
+ clear_csr(mstatus, MSTATUS_MIE);
+ }
+ net_state_flags &= ~NET_STATE_FLAG_SYNC;
+ *type = net_state_type;
+ *len = net_state_len_rx;
+ }
+ net_resume();
+ } else {
+ if ((net_state_flags & NET_STATE_FLAG_RUN) && (net_state_flags & NET_STATE_FLAG_CTS)) {
+ net_xchg_start(_type, buffer, _len);
+ } else {
+ rv = eos_msgq_push(&net_send_q, _type, buffer, _len);
+ if (rv) eos_bufq_push(&net_buf_q, buffer);
+ }
+ }
+
+ set_csr(mstatus, MSTATUS_MIE);
+ if (spi_dev != EOS_SPI_DEV_NET) eos_spi_select(spi_dev);
+
+ return rv;
+}
+
+int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) {
+ return net_xchg(type, buffer, len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC | EOS_NET_FLAG_REPL));
+}
+
+int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len) {
+ return net_xchg(&type, buffer, &len, (EOS_NET_FLAG_ONEW | EOS_NET_FLAG_SYNC));
+}
+
+int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) {
+ return net_xchg(&type, buffer, &len, more ? EOS_NET_FLAG_ONEW : 0);
+}
+
+int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more) {
+ if (async) {
+ eos_net_send_async(type, buffer, len, more);
+ } else {
+ eos_net_send(type, buffer, len);
+ }
+}
diff --git a/fw/fe310/eos/dev/net.h b/fw/fe310/eos/dev/net.h
new file mode 100644
index 0000000..2482a32
--- /dev/null
+++ b/fw/fe310/eos/dev/net.h
@@ -0,0 +1,47 @@
+#include <stdint.h>
+#include "../event.h"
+
+/* common */
+#define EOS_NET_MTU 1500
+#define EOS_NET_SIZE_BUF EOS_NET_MTU
+
+#define EOS_NET_MTYPE_SOCK 1
+#define EOS_NET_MTYPE_RNG 3
+#define EOS_NET_MTYPE_POWER 4
+
+#define EOS_NET_MTYPE_WIFI 5
+#define EOS_NET_MTYPE_CELL 6
+#define EOS_NET_MTYPE_SIP 7
+#define EOS_NET_MTYPE_APP 8
+
+#define EOS_NET_MAX_MTYPE 8
+
+#define EOS_NET_MTYPE_FLAG_ONEW 0x40
+#define EOS_NET_MTYPE_FLAG_REPL 0x80
+#define EOS_NET_MTYPE_FLAG_MASK 0xc0
+
+/* fe310 specific */
+#define EOS_NET_SIZE_BUFQ 2
+
+#define EOS_NET_FLAG_ONEW 0x1
+#define EOS_NET_FLAG_SYNC 0x2
+#define EOS_NET_FLAG_REPL 0x4
+
+int eos_net_init(uint8_t wakeup_cause);
+int eos_net_run(uint8_t wakeup_cause);
+void eos_net_start(void);
+void eos_net_stop(void);
+int eos_net_sleep(uint32_t timeout);
+
+void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len);
+void eos_net_set_handler(unsigned char type, eos_evt_handler_t handler);
+void eos_net_acquire_for_evt(unsigned char type, char acq);
+
+void eos_net_acquire(void);
+void eos_net_release(void);
+unsigned char *eos_net_alloc(void);
+void eos_net_free(unsigned char *buffer, unsigned char more);
+int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len);
+int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len);
+int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more);
+int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more);
diff --git a/fw/fe310/eos/dev/ov2640.c b/fw/fe310/eos/dev/ov2640.c
index 6e54f10..e84a59b 100644
--- a/fw/fe310/eos/dev/ov2640.c
+++ b/fw/fe310/eos/dev/ov2640.c
@@ -3,10 +3,10 @@
#include <math.h>
#include "eos.h"
-#include "timer.h"
-#include "cam.h"
+#include "soc/timer.h"
+#include "soc/i2c.h"
-#include "i2c.h"
+#include "cam.h"
#include "ov2640_regs.h"
#include "ov2640.h"
diff --git a/fw/fe310/eos/dev/sdc_crypto.h b/fw/fe310/eos/dev/sdc_crypto.h
index 015bf8a..6442547 100644
--- a/fw/fe310/eos/dev/sdc_crypto.h
+++ b/fw/fe310/eos/dev/sdc_crypto.h
@@ -15,4 +15,4 @@ typedef struct EOSSDCCrypto {
void eos_sdcc_init(EOSSDCCrypto *crypto, uint8_t *key, void *ctx, eve_sdcc_init_t init, eve_sdcc_crypt_t enc, eve_sdcc_crypt_t dec, void *ctx_essiv, eve_sdcc_init_t init_essiv, eve_sdcc_essiv_t enc_essiv);
void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer);
-void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer); \ No newline at end of file
+void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer);
diff --git a/fw/fe310/eos/dev/sdcard.c b/fw/fe310/eos/dev/sdcard.c
index d081388..fa316c7 100644
--- a/fw/fe310/eos/dev/sdcard.c
+++ b/fw/fe310/eos/dev/sdcard.c
@@ -3,10 +3,10 @@
#include <stdio.h>
#include "eos.h"
-#include "timer.h"
+#include "soc/timer.h"
+#include "soc/spi.h"
#include "spi.h"
-#include "spi_dev.h"
#include "sdc_crypto.h"
#include "sdcard.h"
diff --git a/fw/fe310/eos/dev/spi.c b/fw/fe310/eos/dev/spi.c
new file mode 100644
index 0000000..12549fc
--- /dev/null
+++ b/fw/fe310/eos/dev/spi.c
@@ -0,0 +1,113 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "eos.h"
+#include "msgq.h"
+#include "event.h"
+
+#include "board.h"
+
+#include "soc/interrupt.h"
+#include "soc/spi.h"
+
+#include "net.h"
+
+#include "spi.h"
+#include "spi_cfg.h"
+
+static uint8_t spi_dev;
+static uint8_t spi_lock;
+static uint16_t spi_div[EOS_SPI_MAX_DEV];
+
+int eos_spi_dev_init(uint8_t wakeup_cause) {
+ int i;
+
+ for (i=0; i<EOS_SPI_MAX_DEV; i++) {
+ spi_div[i] = spi_cfg[i].div;
+ if (!(spi_cfg[i].flags & SPI_DEV_FLAG_CSFLOAT) && (spi_cfg[i].cspin != -1)) {
+ GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cfg[i].cspin);
+ GPIO_REG(GPIO_OUTPUT_EN) |= (1 << spi_cfg[i].cspin);
+ }
+ }
+
+ return EOS_OK;
+}
+
+int eos_spi_select(unsigned char dev) {
+ if (spi_lock) return EOS_ERR_BUSY;
+
+ if (spi_cfg[spi_dev].flags & SPI_DEV_FLAG_9BIT) {
+ eos_spi_enable();
+ } else {
+ if (spi_dev == EOS_SPI_DEV_NET) {
+ eos_net_stop();
+ } else {
+ eos_spi_stop();
+ }
+ }
+
+ spi_dev = dev;
+ if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) {
+ eos_spi_configure(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt);
+ eos_spi_disable();
+ } else {
+ if (dev == EOS_SPI_DEV_NET) {
+ eos_net_start();
+ } else {
+ eos_spi_start(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt);
+ }
+ }
+
+ return EOS_OK;
+}
+
+int eos_spi_deselect(void) {
+ if (spi_lock) return EOS_ERR_BUSY;
+ if (spi_dev == EOS_SPI_DEV_NET) return EOS_ERR;
+
+ if (spi_cfg[spi_dev].flags & SPI_DEV_FLAG_9BIT) {
+ eos_spi_enable();
+ } else {
+ eos_spi_stop();
+ }
+
+ spi_dev = EOS_SPI_DEV_NET;
+ eos_net_start();
+
+ return EOS_OK;
+}
+
+void eos_spi_dev_configure(unsigned char dev) {
+ eos_spi_configure(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt);
+}
+
+uint8_t eos_spi_dev(void) {
+ return spi_dev;
+}
+
+uint16_t eos_spi_div(unsigned char dev) {
+ return spi_div[dev];
+}
+
+uint8_t eos_spi_csid(unsigned char dev) {
+ return spi_cfg[dev].csid;
+}
+
+uint8_t eos_spi_cspin(unsigned char dev) {
+ return spi_cfg[dev].cspin;
+}
+
+void eos_spi_lock(void) {
+ spi_lock = 1;
+}
+
+void eos_spi_unlock(void) {
+ spi_lock = 0;
+}
+
+void eos_spi_set_div(unsigned char dev, uint16_t div) {
+ spi_div[dev] = div;
+}
diff --git a/fw/fe310/eos/dev/spi.h b/fw/fe310/eos/dev/spi.h
new file mode 100644
index 0000000..c899e83
--- /dev/null
+++ b/fw/fe310/eos/dev/spi.h
@@ -0,0 +1,21 @@
+#include <stdint.h>
+
+#define EOS_SPI_DEV_NET 0
+#define EOS_SPI_DEV_EVE 1
+#define EOS_SPI_DEV_SDC 2
+#define EOS_SPI_DEV_CAM 3
+#define EOS_SPI_DEV_LCD 4
+
+int eos_spi_dev_init(uint8_t wakeup_cause);
+int eos_spi_select(unsigned char dev);
+int eos_spi_deselect(void);
+void eos_spi_dev_configure(unsigned char dev);
+
+uint8_t eos_spi_dev(void);
+uint16_t eos_spi_div(unsigned char dev);
+uint8_t eos_spi_csid(unsigned char dev);
+uint8_t eos_spi_cspin(unsigned char dev);
+
+void eos_spi_lock(void);
+void eos_spi_unlock(void);
+void eos_spi_set_div(unsigned char dev, uint16_t div);
diff --git a/fw/fe310/eos/dev/spi_cfg.h b/fw/fe310/eos/dev/spi_cfg.h
new file mode 100644
index 0000000..6a5d7b4
--- /dev/null
+++ b/fw/fe310/eos/dev/spi_cfg.h
@@ -0,0 +1,52 @@
+#include <stdint.h>
+
+#define EOS_SPI_MAX_DEV 5
+
+typedef struct {
+ uint16_t div;
+ int8_t csid;
+ int8_t cspin;
+ uint8_t flags;
+ unsigned char evt;
+} SPIConfig;
+
+#define SPI_DEV_FLAG_9BIT 0x1
+#define SPI_DEV_FLAG_CSFLOAT 0x2
+
+static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = {
+ { // DEV_NET
+ .div = SPI_DIV_NET,
+ .csid = SPI_CSID_NET,
+ .cspin = SPI_CSPIN_NET,
+ .flags = 0,
+ .evt = 0, // Not SPI event
+ },
+ { // DEV_EVE
+ .div = SPI_DIV_EVE,
+ .csid = SPI_CSID_EVE,
+ .cspin = SPI_CSPIN_EVE,
+ .flags = 0,
+ .evt = 0,
+ },
+ { // DEV_SDC
+ .div = SPI_DIV_SDC,
+ .csid = SPI_CSID_SDC,
+ .cspin = SPI_CSPIN_SDC,
+ .flags = 0,
+ .evt = EOS_SPI_EVT_SDC,
+ },
+ { // DEV_CAM
+ .div = SPI_DIV_CAM,
+ .csid = SPI_CSID_CAM,
+ .cspin = SPI_CSPIN_CAM,
+ .flags = 0,
+ .evt = EOS_SPI_EVT_CAM,
+ },
+ { // DEV_LCD 9bit spi
+ .div = 0,
+ .csid = -1,
+ .cspin = SPI_CSPIN_LCD,
+ .flags = SPI_DEV_FLAG_9BIT | SPI_DEV_FLAG_CSFLOAT,
+ .evt = 0,
+ },
+};