From 412a8f99928beff605805807b0f07f6bf8d0a965 Mon Sep 17 00:00:00 2001 From: Uros Majstorovic Date: Fri, 13 May 2022 12:45:53 +0200 Subject: code rename --- fw/fe310/eos/cam.c | 138 ------- fw/fe310/eos/cam.h | 88 ----- fw/fe310/eos/cell.c | 51 --- fw/fe310/eos/cell.h | 51 --- fw/fe310/eos/dev/Makefile | 16 + fw/fe310/eos/dev/bq25895.c | 43 ++ fw/fe310/eos/dev/bq25895.h | 5 + fw/fe310/eos/dev/cam.c | 138 +++++++ fw/fe310/eos/dev/cam.h | 88 +++++ fw/fe310/eos/dev/drv2605.h | 3 + fw/fe310/eos/dev/lcd.c | 546 ++++++++++++++++++++++++++ fw/fe310/eos/dev/lcd.h | 12 + fw/fe310/eos/dev/lsm9ds1.h | 4 + fw/fe310/eos/dev/ov2640.c | 861 +++++++++++++++++++++++++++++++++++++++++ fw/fe310/eos/dev/ov2640.h | 8 + fw/fe310/eos/dev/ov2640_regs.h | 245 ++++++++++++ fw/fe310/eos/dev/sdc_crypto.c | 51 +++ fw/fe310/eos/dev/sdc_crypto.h | 18 + fw/fe310/eos/dev/sdcard.c | 539 ++++++++++++++++++++++++++ fw/fe310/eos/dev/sdcard.h | 22 ++ fw/fe310/eos/i2c.c | 145 ------- fw/fe310/eos/i2c.h | 13 - fw/fe310/eos/i2c/Makefile | 16 - fw/fe310/eos/i2c/bq25895.c | 43 -- fw/fe310/eos/i2c/bq25895.h | 5 - fw/fe310/eos/i2c/drv2605.h | 3 - fw/fe310/eos/i2c/lsm9ds1.h | 4 - fw/fe310/eos/i2c/ov2640.c | 861 ----------------------------------------- fw/fe310/eos/i2c/ov2640.h | 8 - fw/fe310/eos/i2c/ov2640_regs.h | 245 ------------ fw/fe310/eos/i2s.c | 477 ----------------------- fw/fe310/eos/i2s.h | 38 -- fw/fe310/eos/i2s_def.h | 8 - fw/fe310/eos/i2s_priv.h | 8 - fw/fe310/eos/interrupt.c | 75 ---- fw/fe310/eos/interrupt.h | 13 - fw/fe310/eos/lcd.c | 546 -------------------------- fw/fe310/eos/lcd.h | 12 - fw/fe310/eos/net.c | 602 ---------------------------- fw/fe310/eos/net.h | 47 --- fw/fe310/eos/net/cell.c | 51 +++ fw/fe310/eos/net/cell.h | 51 +++ fw/fe310/eos/net/rng.c | 27 ++ fw/fe310/eos/net/rng.h | 5 + fw/fe310/eos/net/sock.c | 154 ++++++++ fw/fe310/eos/net/sock.h | 28 ++ fw/fe310/eos/net/wifi.c | 106 +++++ fw/fe310/eos/net/wifi.h | 18 + fw/fe310/eos/pwr.c | 133 ------- fw/fe310/eos/pwr.h | 25 -- fw/fe310/eos/rng.c | 27 -- fw/fe310/eos/rng.h | 5 - fw/fe310/eos/sdc_crypto.c | 51 --- fw/fe310/eos/sdc_crypto.h | 18 - fw/fe310/eos/sdcard.c | 539 -------------------------- fw/fe310/eos/sdcard.h | 22 -- fw/fe310/eos/soc/i2c.c | 145 +++++++ fw/fe310/eos/soc/i2c.h | 13 + fw/fe310/eos/soc/i2s.c | 477 +++++++++++++++++++++++ fw/fe310/eos/soc/i2s.h | 38 ++ fw/fe310/eos/soc/i2s_def.h | 8 + fw/fe310/eos/soc/i2s_priv.h | 8 + fw/fe310/eos/soc/interrupt.c | 75 ++++ fw/fe310/eos/soc/interrupt.h | 13 + fw/fe310/eos/soc/net.c | 602 ++++++++++++++++++++++++++++ fw/fe310/eos/soc/net.h | 47 +++ fw/fe310/eos/soc/pwr.c | 133 +++++++ fw/fe310/eos/soc/pwr.h | 25 ++ fw/fe310/eos/soc/spi.c | 350 +++++++++++++++++ fw/fe310/eos/soc/spi.h | 28 ++ fw/fe310/eos/soc/spi_cfg.h | 37 ++ fw/fe310/eos/soc/spi_dev.c | 97 +++++ fw/fe310/eos/soc/spi_dev.h | 19 + fw/fe310/eos/soc/spi_priv.h | 8 + fw/fe310/eos/soc/timer.c | 137 +++++++ fw/fe310/eos/soc/timer.h | 23 ++ fw/fe310/eos/soc/trap_entry.S | 554 ++++++++++++++++++++++++++ fw/fe310/eos/soc/uart.c | 114 ++++++ fw/fe310/eos/soc/uart.h | 24 ++ fw/fe310/eos/sock.c | 154 -------- fw/fe310/eos/sock.h | 28 -- fw/fe310/eos/spi.c | 350 ----------------- fw/fe310/eos/spi.h | 28 -- fw/fe310/eos/spi_cfg.h | 37 -- fw/fe310/eos/spi_dev.c | 97 ----- fw/fe310/eos/spi_dev.h | 19 - fw/fe310/eos/spi_priv.h | 8 - fw/fe310/eos/timer.c | 137 ------- fw/fe310/eos/timer.h | 23 -- fw/fe310/eos/trap_entry.S | 554 -------------------------- fw/fe310/eos/uart.c | 114 ------ fw/fe310/eos/uart.h | 24 -- fw/fe310/eos/wifi.c | 106 ----- fw/fe310/eos/wifi.h | 18 - 94 files changed, 6014 insertions(+), 6014 deletions(-) delete mode 100644 fw/fe310/eos/cam.c delete mode 100644 fw/fe310/eos/cam.h delete mode 100644 fw/fe310/eos/cell.c delete mode 100644 fw/fe310/eos/cell.h create mode 100644 fw/fe310/eos/dev/Makefile create mode 100644 fw/fe310/eos/dev/bq25895.c create mode 100644 fw/fe310/eos/dev/bq25895.h create mode 100644 fw/fe310/eos/dev/cam.c create mode 100644 fw/fe310/eos/dev/cam.h create mode 100644 fw/fe310/eos/dev/drv2605.h create mode 100644 fw/fe310/eos/dev/lcd.c create mode 100644 fw/fe310/eos/dev/lcd.h create mode 100644 fw/fe310/eos/dev/lsm9ds1.h create mode 100644 fw/fe310/eos/dev/ov2640.c create mode 100644 fw/fe310/eos/dev/ov2640.h create mode 100644 fw/fe310/eos/dev/ov2640_regs.h create mode 100644 fw/fe310/eos/dev/sdc_crypto.c create mode 100644 fw/fe310/eos/dev/sdc_crypto.h create mode 100644 fw/fe310/eos/dev/sdcard.c create mode 100644 fw/fe310/eos/dev/sdcard.h delete mode 100644 fw/fe310/eos/i2c.c delete mode 100644 fw/fe310/eos/i2c.h delete mode 100644 fw/fe310/eos/i2c/Makefile delete mode 100644 fw/fe310/eos/i2c/bq25895.c delete mode 100644 fw/fe310/eos/i2c/bq25895.h delete mode 100644 fw/fe310/eos/i2c/drv2605.h delete mode 100644 fw/fe310/eos/i2c/lsm9ds1.h delete mode 100644 fw/fe310/eos/i2c/ov2640.c delete mode 100644 fw/fe310/eos/i2c/ov2640.h delete mode 100644 fw/fe310/eos/i2c/ov2640_regs.h delete mode 100644 fw/fe310/eos/i2s.c delete mode 100644 fw/fe310/eos/i2s.h delete mode 100644 fw/fe310/eos/i2s_def.h delete mode 100644 fw/fe310/eos/i2s_priv.h delete mode 100644 fw/fe310/eos/interrupt.c delete mode 100644 fw/fe310/eos/interrupt.h delete mode 100644 fw/fe310/eos/lcd.c delete mode 100644 fw/fe310/eos/lcd.h delete mode 100644 fw/fe310/eos/net.c delete mode 100644 fw/fe310/eos/net.h create mode 100644 fw/fe310/eos/net/cell.c create mode 100644 fw/fe310/eos/net/cell.h create mode 100644 fw/fe310/eos/net/rng.c create mode 100644 fw/fe310/eos/net/rng.h create mode 100644 fw/fe310/eos/net/sock.c create mode 100644 fw/fe310/eos/net/sock.h create mode 100644 fw/fe310/eos/net/wifi.c create mode 100644 fw/fe310/eos/net/wifi.h delete mode 100644 fw/fe310/eos/pwr.c delete mode 100644 fw/fe310/eos/pwr.h delete mode 100644 fw/fe310/eos/rng.c delete mode 100644 fw/fe310/eos/rng.h delete mode 100644 fw/fe310/eos/sdc_crypto.c delete mode 100644 fw/fe310/eos/sdc_crypto.h delete mode 100644 fw/fe310/eos/sdcard.c delete mode 100644 fw/fe310/eos/sdcard.h create mode 100644 fw/fe310/eos/soc/i2c.c create mode 100644 fw/fe310/eos/soc/i2c.h create mode 100644 fw/fe310/eos/soc/i2s.c create mode 100644 fw/fe310/eos/soc/i2s.h create mode 100644 fw/fe310/eos/soc/i2s_def.h create mode 100644 fw/fe310/eos/soc/i2s_priv.h create mode 100644 fw/fe310/eos/soc/interrupt.c create mode 100644 fw/fe310/eos/soc/interrupt.h create mode 100644 fw/fe310/eos/soc/net.c create mode 100644 fw/fe310/eos/soc/net.h create mode 100644 fw/fe310/eos/soc/pwr.c create mode 100644 fw/fe310/eos/soc/pwr.h create mode 100644 fw/fe310/eos/soc/spi.c create mode 100644 fw/fe310/eos/soc/spi.h create mode 100644 fw/fe310/eos/soc/spi_cfg.h create mode 100644 fw/fe310/eos/soc/spi_dev.c create mode 100644 fw/fe310/eos/soc/spi_dev.h create mode 100644 fw/fe310/eos/soc/spi_priv.h create mode 100644 fw/fe310/eos/soc/timer.c create mode 100644 fw/fe310/eos/soc/timer.h create mode 100644 fw/fe310/eos/soc/trap_entry.S create mode 100644 fw/fe310/eos/soc/uart.c create mode 100644 fw/fe310/eos/soc/uart.h delete mode 100644 fw/fe310/eos/sock.c delete mode 100644 fw/fe310/eos/sock.h delete mode 100644 fw/fe310/eos/spi.c delete mode 100644 fw/fe310/eos/spi.h delete mode 100644 fw/fe310/eos/spi_cfg.h delete mode 100644 fw/fe310/eos/spi_dev.c delete mode 100644 fw/fe310/eos/spi_dev.h delete mode 100644 fw/fe310/eos/spi_priv.h delete mode 100644 fw/fe310/eos/timer.c delete mode 100644 fw/fe310/eos/timer.h delete mode 100644 fw/fe310/eos/trap_entry.S delete mode 100644 fw/fe310/eos/uart.c delete mode 100644 fw/fe310/eos/uart.h delete mode 100644 fw/fe310/eos/wifi.c delete mode 100644 fw/fe310/eos/wifi.h diff --git a/fw/fe310/eos/cam.c b/fw/fe310/eos/cam.c deleted file mode 100644 index 43293af..0000000 --- a/fw/fe310/eos/cam.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include - -#include "eos.h" -#include "spi.h" -#include "cam.h" - -const int _eos_cam_resolution[][2] = { - {0, 0 }, - // C/SIF Resolutions - {88, 72 }, /* QQCIF */ - {176, 144 }, /* QCIF */ - {352, 288 }, /* CIF */ - {88, 60 }, /* QQSIF */ - {176, 120 }, /* QSIF */ - {352, 240 }, /* SIF */ - // VGA Resolutions - {40, 30 }, /* QQQQVGA */ - {80, 60 }, /* QQQVGA */ - {160, 120 }, /* QQVGA */ - {320, 240 }, /* QVGA */ - {640, 480 }, /* VGA */ - {60, 40 }, /* HQQQVGA */ - {120, 80 }, /* HQQVGA */ - {240, 160 }, /* HQVGA */ - // FFT Resolutions - {64, 32 }, /* 64x32 */ - {64, 64 }, /* 64x64 */ - {128, 64 }, /* 128x64 */ - {128, 128 }, /* 128x128 */ - {320, 320 }, /* 128x128 */ - // Other - {128, 160 }, /* LCD */ - {128, 160 }, /* QQVGA2 */ - {720, 480 }, /* WVGA */ - {752, 480 }, /* WVGA2 */ - {800, 600 }, /* SVGA */ - {1024, 768 }, /* XGA */ - {1280, 1024}, /* SXGA */ - {1600, 1200}, /* UXGA */ - {1280, 720 }, /* HD */ - {1920, 1080}, /* FHD */ - {2560, 1440}, /* QHD */ - {2048, 1536}, /* QXGA */ - {2560, 1600}, /* WQXGA */ - {2592, 1944}, /* WQXGA2 */ -}; - -#define CAM_REG_CAPTURE_CTRL 0x01 -#define CAM_REG_FIFO_CTRL 0x04 - -#define CAM_REG_GPIO_DIR 0x05 -#define CAM_REG_GPIO_WR 0x06 -#define CAM_REG_GPIO_RD 0x45 - -#define CAM_REG_STATUS 0x41 - -#define CAM_REG_VER 0x40 - -#define CAM_REG_READ_BURST 0x3c -#define CAM_REG_READ_BYTE 0x3d - -#define CAM_REG_FIFO_SIZE1 0x42 -#define CAM_REG_FIFO_SIZE2 0x43 -#define CAM_REG_FIFO_SIZE3 0x44 - -#define CAM_VAL_FIFO_CTRL_CLEAR 0x01 -#define CAM_VAL_FIFO_CTRL_START 0x02 -#define CAM_VAL_FIFO_CTRL_RSTWR 0x10 -#define CAM_VAL_FIFO_CTRL_RSTRD 0x20 - -#define CAM_VAL_STATUS_VSYNC 0x01 -#define CAM_VAL_STATUS_SHUTTER 0x02 -#define CAM_VAL_STATUS_CPTDONE 0x08 - -#define CAM_VAL_GPIO_RST 0x01 -#define CAM_VAL_GPIO_PWRDN 0x02 -#define CAM_VAL_GPIO_PWREN 0x04 - -static uint8_t reg_read(uint8_t addr) { - uint8_t ret; - - eos_spi_cs_set(); - eos_spi_xchg8(addr, 0); - ret = eos_spi_xchg8(0, 0); - eos_spi_cs_clear(); - - return ret; -} - -static void reg_write(uint8_t addr, uint8_t val) { - eos_spi_cs_set(); - eos_spi_xchg8(addr | 0x80, 0); - eos_spi_xchg8(val, 0); - eos_spi_cs_clear(); -} - -void eos_cam_capture(void) { - reg_write(CAM_REG_FIFO_CTRL, CAM_VAL_FIFO_CTRL_START); -} - -int eos_cam_capture_done(void) { - return !!(reg_read(CAM_REG_STATUS) & CAM_VAL_STATUS_CPTDONE); -} - -void eos_cam_capture_wait(void) { - int done = 0; - - while (!done) { - done = eos_cam_capture_done(); - } -} - -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; - return ret; -} - -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); - - for (i=0; i - -typedef enum { - PIXFORMAT_INVALID = 0, - PIXFORMAT_BINARY, // 1BPP/BINARY - PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE - PIXFORMAT_RGB565, // 2BPP/RGB565 - PIXFORMAT_YUV422, // 2BPP/YUV422 - PIXFORMAT_BAYER, // 1BPP/RAW - PIXFORMAT_JPEG, // JPEG/COMPRESSED -} pixformat_t; - -typedef enum { - FRAMESIZE_INVALID = 0, - // C/SIF Resolutions - FRAMESIZE_QQCIF, // 88x72 - FRAMESIZE_QCIF, // 176x144 - FRAMESIZE_CIF, // 352x288 - FRAMESIZE_QQSIF, // 88x60 - FRAMESIZE_QSIF, // 176x120 - FRAMESIZE_SIF, // 352x240 - // VGA Resolutions - FRAMESIZE_QQQQVGA, // 40x30 - FRAMESIZE_QQQVGA, // 80x60 - FRAMESIZE_QQVGA, // 160x120 - FRAMESIZE_QVGA, // 320x240 - FRAMESIZE_VGA, // 640x480 - FRAMESIZE_HQQQVGA, // 60x40 - FRAMESIZE_HQQVGA, // 120x80 - FRAMESIZE_HQVGA, // 240x160 - // FFT Resolutions - FRAMESIZE_64X32, // 64x32 - FRAMESIZE_64X64, // 64x64 - FRAMESIZE_128X64, // 128x64 - FRAMESIZE_128X128, // 128x128 - FRAMESIZE_320X320, // 320x320 - // Other - FRAMESIZE_LCD, // 128x160 - FRAMESIZE_QQVGA2, // 128x160 - FRAMESIZE_WVGA, // 720x480 - FRAMESIZE_WVGA2, // 752x480 - FRAMESIZE_SVGA, // 800x600 - FRAMESIZE_XGA, // 1024x768 - FRAMESIZE_SXGA, // 1280x1024 - FRAMESIZE_UXGA, // 1600x1200 - FRAMESIZE_HD, // 1280x720 - FRAMESIZE_FHD, // 1920x1080 - FRAMESIZE_QHD, // 2560x1440 - FRAMESIZE_QXGA, // 2048x1536 - FRAMESIZE_WQXGA, // 2560x1600 - FRAMESIZE_WQXGA2, // 2592x1944 -} framesize_t; - -typedef enum { - GAINCEILING_2X, - GAINCEILING_4X, - GAINCEILING_8X, - GAINCEILING_16X, - GAINCEILING_32X, - GAINCEILING_64X, - GAINCEILING_128X, -} gainceiling_t; - -typedef enum { - SDE_NORMAL, - SDE_NEGATIVE, -} sde_t; - -extern const int _eos_cam_resolution[][2]; - -#define IM_LOG2_2(x) (((x) & 0x2ULL) ? ( 2 ) : 1) // NO ({ ... }) ! -#define IM_LOG2_4(x) (((x) & 0xCULL) ? ( 2 + IM_LOG2_2((x) >> 2)) : IM_LOG2_2(x)) // NO ({ ... }) ! -#define IM_LOG2_8(x) (((x) & 0xF0ULL) ? ( 4 + IM_LOG2_4((x) >> 4)) : IM_LOG2_4(x)) // NO ({ ... }) ! -#define IM_LOG2_16(x) (((x) & 0xFF00ULL) ? ( 8 + IM_LOG2_8((x) >> 8)) : IM_LOG2_8(x)) // NO ({ ... }) ! -#define IM_LOG2_32(x) (((x) & 0xFFFF0000ULL) ? (16 + IM_LOG2_16((x) >> 16)) : IM_LOG2_16(x)) // NO ({ ... }) ! -#define IM_LOG2(x) (((x) & 0xFFFFFFFF00000000ULL) ? (32 + IM_LOG2_32((x) >> 32)) : IM_LOG2_32(x)) // NO ({ ... }) ! - -#define IM_MAX(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; }) -#define IM_MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) -#define IM_DIV(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; }) -#define IM_MOD(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; }) - -void eos_cam_capture(void); -int eos_cam_capture_done(void); -void eos_cam_capture_wait(void); -uint32_t eos_cam_fbuf_size(void); -void eos_cam_fbuf_read(uint8_t *buffer, uint16_t sz, int first); -void eos_cam_fbuf_done(void); diff --git a/fw/fe310/eos/cell.c b/fw/fe310/eos/cell.c deleted file mode 100644 index 20a9f42..0000000 --- a/fw/fe310/eos/cell.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "event.h" -#include "net.h" - -#include "cell.h" - -static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE]; - -static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char mtype; - unsigned char idx; - - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - mtype = buffer[0]; - idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; - if ((idx < EOS_CELL_MAX_MTYPE) && evt_handler[idx]) { - evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, len); - } else { - eos_net_bad_handler(type, buffer, len); - } -} - -void eos_cell_netinit(void) { - int i; - - for (i=0; i> 4; - - if (idx < EOS_CELL_MAX_MTYPE) evt_handler[idx] = handler; -} - -eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) { - unsigned char idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; - - if (idx < EOS_CELL_MAX_MTYPE) return evt_handler[idx]; - return NULL; -} diff --git a/fw/fe310/eos/cell.h b/fw/fe310/eos/cell.h deleted file mode 100644 index b01d4cf..0000000 --- a/fw/fe310/eos/cell.h +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include "event.h" - -#define EOS_CELL_MTYPE_DEV 0x10 -#define EOS_CELL_MTYPE_VOICE 0x20 -#define EOS_CELL_MTYPE_SMS 0x30 -#define EOS_CELL_MTYPE_CBS 0x40 -#define EOS_CELL_MTYPE_USSD 0x50 -#define EOS_CELL_MTYPE_PDP 0x60 - -#define EOS_CELL_MTYPE_MASK 0xf0 -#define EOS_CELL_MAX_MTYPE 8 - -/* EOS_CELL_MTYPE_DEV subtypes */ -#define EOS_CELL_MTYPE_READY 1 -#define EOS_CELL_MTYPE_UART_DATA 2 -#define EOS_CELL_MTYPE_UART_TAKE 3 -#define EOS_CELL_MTYPE_UART_GIVE 4 -#define EOS_CELL_MTYPE_RESET 5 - -#define EOS_CELL_MTYPE_VOICE_PCM 1 -#define EOS_CELL_MTYPE_VOICE_DIAL 2 -#define EOS_CELL_MTYPE_VOICE_RING 3 -#define EOS_CELL_MTYPE_VOICE_ANSWER 4 -#define EOS_CELL_MTYPE_VOICE_HANGUP 5 -#define EOS_CELL_MTYPE_VOICE_BEGIN 6 -#define EOS_CELL_MTYPE_VOICE_END 7 -#define EOS_CELL_MTYPE_VOICE_MISS 8 -#define EOS_CELL_MTYPE_VOICE_BUSY 9 -#define EOS_CELL_MTYPE_VOICE_ERR 10 - -#define EOS_CELL_MTYPE_SMS_LIST 1 -#define EOS_CELL_MTYPE_SMS_SEND 2 -#define EOS_CELL_MTYPE_SMS_MSG_NEW 3 -#define EOS_CELL_MTYPE_SMS_MSG_ITEM 4 - -#define EOS_CELL_MTYPE_USSD_REQUEST 1 -#define EOS_CELL_MTYPE_USSD_REPLY 2 -#define EOS_CELL_MTYPE_USSD_CANCEL 3 - -#define EOS_CELL_MTYPE_PDP_CONFIG 1 -#define EOS_CELL_MTYPE_PDP_CONNECT 2 -#define EOS_CELL_MTYPE_PDP_DISCONNECT 3 - -#define EOS_CELL_SMS_ADDRTYPE_INTL 1 -#define EOS_CELL_SMS_ADDRTYPE_ALPHA 2 -#define EOS_CELL_SMS_ADDRTYPE_OTHER 3 - -void eos_cell_netinit(void); -void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler); -eos_evt_handler_t eos_cell_get_handler(unsigned char mtype); \ No newline at end of file diff --git a/fw/fe310/eos/dev/Makefile b/fw/fe310/eos/dev/Makefile new file mode 100644 index 0000000..83cb1f5 --- /dev/null +++ b/fw/fe310/eos/dev/Makefile @@ -0,0 +1,16 @@ +include ../../common.mk +CFLAGS += -I$(bsp_dir)/include + +obj = bq25895.o ov2640.o gt911.o + + +%.o: %.c %.h + $(CC) $(CFLAGS) -c $< + +%.o: %.S + $(CC) $(CFLAGS) -c $< + +all: $(obj) + +clean: + rm -f *.o diff --git a/fw/fe310/eos/dev/bq25895.c b/fw/fe310/eos/dev/bq25895.c new file mode 100644 index 0000000..b290926 --- /dev/null +++ b/fw/fe310/eos/dev/bq25895.c @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "eos.h" +#include "pwr.h" +#include "i2c.h" +#include "bq25895.h" + +static int reg_read(uint8_t reg, uint8_t *data) { + return eos_i2c_read8(BQ25895_ADDR, reg, data, 1); +} + +static int reg_write(uint8_t reg, uint8_t data) { + return eos_i2c_write8(BQ25895_ADDR, reg, &data, 1); +} + +int eos_bq25895_init(uint8_t wakeup_cause) { + int rst = (wakeup_cause == EOS_PWR_WAKE_RST); + int i, rv = EOS_OK; + uint8_t data = 0; + + if (rst) { + rv = reg_write(0x14, 0x80); // reset + if (rv) printf("I2C ERROR 0x14\n"); + rv = reg_write(0x14, 0x00); // disable watchdog + if (rv) printf("I2C ERROR 0x14\n"); + rv = reg_write(0x07, 0x8d); // disable watchdog + if (rv) printf("I2C ERROR 0x07\n"); + rv = reg_write(0x00, 0x28); // 2.1A input current + if (rv) printf("I2C ERROR 0x00\n"); + rv = reg_write(0x02, 0x30); // enable ICO, disaable MaxCharge and D+/D- + if (rv) printf("I2C ERROR 0x02\n"); + } + + printf("BQ25895:\n"); + for (i=0; i<0x15; i++) { + rv = reg_read(i, &data); + if (!rv) printf("REG%02x: %02x\n", i, data); + } + + return EOS_OK; +} diff --git a/fw/fe310/eos/dev/bq25895.h b/fw/fe310/eos/dev/bq25895.h new file mode 100644 index 0000000..cbef36e --- /dev/null +++ b/fw/fe310/eos/dev/bq25895.h @@ -0,0 +1,5 @@ +#include + +#define BQ25895_ADDR 0x6A + +int eos_bq25895_init(uint8_t wakeup_cause); diff --git a/fw/fe310/eos/dev/cam.c b/fw/fe310/eos/dev/cam.c new file mode 100644 index 0000000..43293af --- /dev/null +++ b/fw/fe310/eos/dev/cam.c @@ -0,0 +1,138 @@ +#include +#include + +#include "eos.h" +#include "spi.h" +#include "cam.h" + +const int _eos_cam_resolution[][2] = { + {0, 0 }, + // C/SIF Resolutions + {88, 72 }, /* QQCIF */ + {176, 144 }, /* QCIF */ + {352, 288 }, /* CIF */ + {88, 60 }, /* QQSIF */ + {176, 120 }, /* QSIF */ + {352, 240 }, /* SIF */ + // VGA Resolutions + {40, 30 }, /* QQQQVGA */ + {80, 60 }, /* QQQVGA */ + {160, 120 }, /* QQVGA */ + {320, 240 }, /* QVGA */ + {640, 480 }, /* VGA */ + {60, 40 }, /* HQQQVGA */ + {120, 80 }, /* HQQVGA */ + {240, 160 }, /* HQVGA */ + // FFT Resolutions + {64, 32 }, /* 64x32 */ + {64, 64 }, /* 64x64 */ + {128, 64 }, /* 128x64 */ + {128, 128 }, /* 128x128 */ + {320, 320 }, /* 128x128 */ + // Other + {128, 160 }, /* LCD */ + {128, 160 }, /* QQVGA2 */ + {720, 480 }, /* WVGA */ + {752, 480 }, /* WVGA2 */ + {800, 600 }, /* SVGA */ + {1024, 768 }, /* XGA */ + {1280, 1024}, /* SXGA */ + {1600, 1200}, /* UXGA */ + {1280, 720 }, /* HD */ + {1920, 1080}, /* FHD */ + {2560, 1440}, /* QHD */ + {2048, 1536}, /* QXGA */ + {2560, 1600}, /* WQXGA */ + {2592, 1944}, /* WQXGA2 */ +}; + +#define CAM_REG_CAPTURE_CTRL 0x01 +#define CAM_REG_FIFO_CTRL 0x04 + +#define CAM_REG_GPIO_DIR 0x05 +#define CAM_REG_GPIO_WR 0x06 +#define CAM_REG_GPIO_RD 0x45 + +#define CAM_REG_STATUS 0x41 + +#define CAM_REG_VER 0x40 + +#define CAM_REG_READ_BURST 0x3c +#define CAM_REG_READ_BYTE 0x3d + +#define CAM_REG_FIFO_SIZE1 0x42 +#define CAM_REG_FIFO_SIZE2 0x43 +#define CAM_REG_FIFO_SIZE3 0x44 + +#define CAM_VAL_FIFO_CTRL_CLEAR 0x01 +#define CAM_VAL_FIFO_CTRL_START 0x02 +#define CAM_VAL_FIFO_CTRL_RSTWR 0x10 +#define CAM_VAL_FIFO_CTRL_RSTRD 0x20 + +#define CAM_VAL_STATUS_VSYNC 0x01 +#define CAM_VAL_STATUS_SHUTTER 0x02 +#define CAM_VAL_STATUS_CPTDONE 0x08 + +#define CAM_VAL_GPIO_RST 0x01 +#define CAM_VAL_GPIO_PWRDN 0x02 +#define CAM_VAL_GPIO_PWREN 0x04 + +static uint8_t reg_read(uint8_t addr) { + uint8_t ret; + + eos_spi_cs_set(); + eos_spi_xchg8(addr, 0); + ret = eos_spi_xchg8(0, 0); + eos_spi_cs_clear(); + + return ret; +} + +static void reg_write(uint8_t addr, uint8_t val) { + eos_spi_cs_set(); + eos_spi_xchg8(addr | 0x80, 0); + eos_spi_xchg8(val, 0); + eos_spi_cs_clear(); +} + +void eos_cam_capture(void) { + reg_write(CAM_REG_FIFO_CTRL, CAM_VAL_FIFO_CTRL_START); +} + +int eos_cam_capture_done(void) { + return !!(reg_read(CAM_REG_STATUS) & CAM_VAL_STATUS_CPTDONE); +} + +void eos_cam_capture_wait(void) { + int done = 0; + + while (!done) { + done = eos_cam_capture_done(); + } +} + +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; + return ret; +} + +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); + + for (i=0; i + +typedef enum { + PIXFORMAT_INVALID = 0, + PIXFORMAT_BINARY, // 1BPP/BINARY + PIXFORMAT_GRAYSCALE, // 1BPP/GRAYSCALE + PIXFORMAT_RGB565, // 2BPP/RGB565 + PIXFORMAT_YUV422, // 2BPP/YUV422 + PIXFORMAT_BAYER, // 1BPP/RAW + PIXFORMAT_JPEG, // JPEG/COMPRESSED +} pixformat_t; + +typedef enum { + FRAMESIZE_INVALID = 0, + // C/SIF Resolutions + FRAMESIZE_QQCIF, // 88x72 + FRAMESIZE_QCIF, // 176x144 + FRAMESIZE_CIF, // 352x288 + FRAMESIZE_QQSIF, // 88x60 + FRAMESIZE_QSIF, // 176x120 + FRAMESIZE_SIF, // 352x240 + // VGA Resolutions + FRAMESIZE_QQQQVGA, // 40x30 + FRAMESIZE_QQQVGA, // 80x60 + FRAMESIZE_QQVGA, // 160x120 + FRAMESIZE_QVGA, // 320x240 + FRAMESIZE_VGA, // 640x480 + FRAMESIZE_HQQQVGA, // 60x40 + FRAMESIZE_HQQVGA, // 120x80 + FRAMESIZE_HQVGA, // 240x160 + // FFT Resolutions + FRAMESIZE_64X32, // 64x32 + FRAMESIZE_64X64, // 64x64 + FRAMESIZE_128X64, // 128x64 + FRAMESIZE_128X128, // 128x128 + FRAMESIZE_320X320, // 320x320 + // Other + FRAMESIZE_LCD, // 128x160 + FRAMESIZE_QQVGA2, // 128x160 + FRAMESIZE_WVGA, // 720x480 + FRAMESIZE_WVGA2, // 752x480 + FRAMESIZE_SVGA, // 800x600 + FRAMESIZE_XGA, // 1024x768 + FRAMESIZE_SXGA, // 1280x1024 + FRAMESIZE_UXGA, // 1600x1200 + FRAMESIZE_HD, // 1280x720 + FRAMESIZE_FHD, // 1920x1080 + FRAMESIZE_QHD, // 2560x1440 + FRAMESIZE_QXGA, // 2048x1536 + FRAMESIZE_WQXGA, // 2560x1600 + FRAMESIZE_WQXGA2, // 2592x1944 +} framesize_t; + +typedef enum { + GAINCEILING_2X, + GAINCEILING_4X, + GAINCEILING_8X, + GAINCEILING_16X, + GAINCEILING_32X, + GAINCEILING_64X, + GAINCEILING_128X, +} gainceiling_t; + +typedef enum { + SDE_NORMAL, + SDE_NEGATIVE, +} sde_t; + +extern const int _eos_cam_resolution[][2]; + +#define IM_LOG2_2(x) (((x) & 0x2ULL) ? ( 2 ) : 1) // NO ({ ... }) ! +#define IM_LOG2_4(x) (((x) & 0xCULL) ? ( 2 + IM_LOG2_2((x) >> 2)) : IM_LOG2_2(x)) // NO ({ ... }) ! +#define IM_LOG2_8(x) (((x) & 0xF0ULL) ? ( 4 + IM_LOG2_4((x) >> 4)) : IM_LOG2_4(x)) // NO ({ ... }) ! +#define IM_LOG2_16(x) (((x) & 0xFF00ULL) ? ( 8 + IM_LOG2_8((x) >> 8)) : IM_LOG2_8(x)) // NO ({ ... }) ! +#define IM_LOG2_32(x) (((x) & 0xFFFF0000ULL) ? (16 + IM_LOG2_16((x) >> 16)) : IM_LOG2_16(x)) // NO ({ ... }) ! +#define IM_LOG2(x) (((x) & 0xFFFFFFFF00000000ULL) ? (32 + IM_LOG2_32((x) >> 32)) : IM_LOG2_32(x)) // NO ({ ... }) ! + +#define IM_MAX(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; }) +#define IM_MIN(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; }) +#define IM_DIV(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; }) +#define IM_MOD(a,b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; }) + +void eos_cam_capture(void); +int eos_cam_capture_done(void); +void eos_cam_capture_wait(void); +uint32_t eos_cam_fbuf_size(void); +void eos_cam_fbuf_read(uint8_t *buffer, uint16_t sz, int first); +void eos_cam_fbuf_done(void); diff --git a/fw/fe310/eos/dev/drv2605.h b/fw/fe310/eos/dev/drv2605.h new file mode 100644 index 0000000..fe90a9b --- /dev/null +++ b/fw/fe310/eos/dev/drv2605.h @@ -0,0 +1,3 @@ +#include + +#define DRV2605_ADDR 0x5A diff --git a/fw/fe310/eos/dev/lcd.c b/fw/fe310/eos/dev/lcd.c new file mode 100644 index 0000000..3080a13 --- /dev/null +++ b/fw/fe310/eos/dev/lcd.c @@ -0,0 +1,546 @@ +#include +#include +#include +#include + +#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 new file mode 100644 index 0000000..1bcb2cd --- /dev/null +++ b/fw/fe310/eos/dev/lcd.h @@ -0,0 +1,12 @@ +#include + +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/lsm9ds1.h b/fw/fe310/eos/dev/lsm9ds1.h new file mode 100644 index 0000000..92220e7 --- /dev/null +++ b/fw/fe310/eos/dev/lsm9ds1.h @@ -0,0 +1,4 @@ +#include + +#define LSM9DS1_ADDR_AG 0x1E +#define LSM9DS1_ADDR_M 0x6B diff --git a/fw/fe310/eos/dev/ov2640.c b/fw/fe310/eos/dev/ov2640.c new file mode 100644 index 0000000..6e54f10 --- /dev/null +++ b/fw/fe310/eos/dev/ov2640.c @@ -0,0 +1,861 @@ +#include +#include +#include + +#include "eos.h" +#include "timer.h" +#include "cam.h" + +#include "i2c.h" +#include "ov2640_regs.h" +#include "ov2640.h" + +#define XCLK_FREQ 24000000 +//#define XCLK_FREQ 12000000 + +#define CIF_WIDTH (400) +#define CIF_HEIGHT (296) + +#define SVGA_WIDTH (800) +#define SVGA_HEIGHT (600) + +#define UXGA_WIDTH (1600) +#define UXGA_HEIGHT (1200) + +static const uint8_t default_regs[][2] = { + +// From Linux Driver. + + {BANK_SEL, BANK_SEL_DSP}, + {0x2c, 0xff}, + {0x2e, 0xdf}, + {BANK_SEL, BANK_SEL_SENSOR}, + {0x3c, 0x32}, +// {CLKRC, CLKRC_DOUBLE | 0x02}, + {CLKRC, 0x01}, + {COM2, COM2_OUT_DRIVE_3x}, + {REG04, REG04_SET(REG04_HFLIP_IMG | REG04_VFLIP_IMG | REG04_VREF_EN | REG04_HREF_EN)}, + {COM8, COM8_SET(COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN)}, + {COM9, COM9_AGC_SET(COM9_AGC_GAIN_8x)}, + {0x2c, 0x0c}, + {0x33, 0x78}, + {0x3a, 0x33}, + {0x3b, 0xfb}, + {0x3e, 0x00}, + {0x43, 0x11}, + {0x16, 0x10}, + {0x39, 0x02}, + {0x35, 0x88}, + {0x22, 0x0a}, + {0x37, 0x40}, + {0x23, 0x00}, + {ARCOM2, 0xa0}, + {0x06, 0x02}, + {0x06, 0x88}, + {0x07, 0xc0}, + {0x0d, 0xb7}, + {0x0e, 0x01}, + {0x4c, 0x00}, + {0x4a, 0x81}, + {0x21, 0x99}, + {AEW, 0x40}, + {AEB, 0x38}, + {VV, VV_AGC_TH_SET(0x08, 0x02)}, + {0x5c, 0x00}, + {0x63, 0x00}, + {FLL, 0x22}, + {COM3, COM3_BAND_SET(COM3_BAND_AUTO)}, + {REG5D, 0x55}, + {REG5E, 0x7d}, + {REG5F, 0x7d}, + {REG60, 0x55}, + {HISTO_LOW, 0x70}, + {HISTO_HIGH, 0x80}, + {0x7c, 0x05}, + {0x20, 0x80}, + {0x28, 0x30}, + {0x6c, 0x00}, + {0x6d, 0x80}, + {0x6e, 0x00}, + {0x70, 0x02}, + {0x71, 0x94}, + {0x73, 0xc1}, + {0x3d, 0x34}, + {COM7, COM7_RES_UXGA | COM7_ZOOM_EN}, + {0x5a, 0x57}, + {COM25, 0x00}, + {BD50, 0xbb}, + {BD60, 0x9c}, + {BANK_SEL, BANK_SEL_DSP}, + {0xe5, 0x7f}, + {MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL}, + {0x41, 0x24}, + {RESET, RESET_JPEG | RESET_DVP}, + {0x76, 0xff}, + {0x33, 0xa0}, + {0x42, 0x20}, + {0x43, 0x18}, + {0x4c, 0x00}, + {CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10}, + {0x88, 0x3f}, + {0xd7, 0x03}, + {0xd9, 0x10}, + {R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x2}, + {0xc8, 0x08}, + {0xc9, 0x80}, + {BPADDR, 0x00}, + {BPDATA, 0x00}, + {BPADDR, 0x03}, + {BPDATA, 0x48}, + {BPDATA, 0x48}, + {BPADDR, 0x08}, + {BPDATA, 0x20}, + {BPDATA, 0x10}, + {BPDATA, 0x0e}, + {0x90, 0x00}, + {0x91, 0x0e}, + {0x91, 0x1a}, + {0x91, 0x31}, + {0x91, 0x5a}, + {0x91, 0x69}, + {0x91, 0x75}, + {0x91, 0x7e}, + {0x91, 0x88}, + {0x91, 0x8f}, + {0x91, 0x96}, + {0x91, 0xa3}, + {0x91, 0xaf}, + {0x91, 0xc4}, + {0x91, 0xd7}, + {0x91, 0xe8}, + {0x91, 0x20}, + {0x92, 0x00}, + {0x93, 0x06}, + {0x93, 0xe3}, + {0x93, 0x03}, + {0x93, 0x03}, + {0x93, 0x00}, + {0x93, 0x02}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x93, 0x00}, + {0x96, 0x00}, + {0x97, 0x08}, + {0x97, 0x19}, + {0x97, 0x02}, + {0x97, 0x0c}, + {0x97, 0x24}, + {0x97, 0x30}, + {0x97, 0x28}, + {0x97, 0x26}, + {0x97, 0x02}, + {0x97, 0x98}, + {0x97, 0x80}, + {0x97, 0x00}, + {0x97, 0x00}, + {0xa4, 0x00}, + {0xa8, 0x00}, + {0xc5, 0x11}, + {0xc6, 0x51}, + {0xbf, 0x80}, + {0xc7, 0x10}, /* simple AWB */ + {0xb6, 0x66}, + {0xb8, 0xA5}, + {0xb7, 0x64}, + {0xb9, 0x7C}, + {0xb3, 0xaf}, + {0xb4, 0x97}, + {0xb5, 0xFF}, + {0xb0, 0xC5}, + {0xb1, 0x94}, + {0xb2, 0x0f}, + {0xc4, 0x5c}, + {0xa6, 0x00}, + {0xa7, 0x20}, + {0xa7, 0xd8}, + {0xa7, 0x1b}, + {0xa7, 0x31}, + {0xa7, 0x00}, + {0xa7, 0x18}, + {0xa7, 0x20}, + {0xa7, 0xd8}, + {0xa7, 0x19}, + {0xa7, 0x31}, + {0xa7, 0x00}, + {0xa7, 0x18}, + {0xa7, 0x20}, + {0xa7, 0xd8}, + {0xa7, 0x19}, + {0xa7, 0x31}, + {0xa7, 0x00}, + {0xa7, 0x18}, + {0x7f, 0x00}, + {0xe5, 0x1f}, + {0xe1, 0x77}, + {0xdd, 0x7f}, + {CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN}, + +// OpenMV Custom. + + {BANK_SEL, BANK_SEL_SENSOR}, + {0x0f, 0x4b}, + {COM1, 0x8f}, + +// End. + + {0xff, 0xff}, +}; + +// Looks really bad. +//static const uint8_t cif_regs[][2] = { +// {BANK_SEL, BANK_SEL_SENSOR}, +// {COM7, COM7_RES_CIF}, +// {COM1, 0x06 | 0x80}, +// {HSTART, 0x11}, +// {HSTOP, 0x43}, +// {VSTART, 0x01}, // 0x01 fixes issue with garbage pixels in the image... +// {VSTOP, 0x97}, +// {REG32, 0x09}, +// {BANK_SEL, BANK_SEL_DSP}, +// {RESET, RESET_DVP}, +// {SIZEL, SIZEL_HSIZE8_11_SET(CIF_WIDTH) | SIZEL_HSIZE8_SET(CIF_WIDTH) | SIZEL_VSIZE8_SET(CIF_HEIGHT)}, +// {HSIZE8, HSIZE8_SET(CIF_WIDTH)}, +// {VSIZE8, VSIZE8_SET(CIF_HEIGHT)}, +// {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, +// {0, 0}, +//}; + +static const uint8_t svga_regs[][2] = { + {BANK_SEL, BANK_SEL_SENSOR}, + {COM7, COM7_RES_SVGA}, + {COM1, 0x0A | 0x80}, + {HSTART, 0x11}, + {HSTOP, 0x43}, + {VSTART, 0x01}, // 0x01 fixes issue with garbage pixels in the image... + {VSTOP, 0x97}, + {REG32, 0x09}, + {BANK_SEL, BANK_SEL_DSP}, + {RESET, RESET_DVP}, + {SIZEL, SIZEL_HSIZE8_11_SET(SVGA_WIDTH) | SIZEL_HSIZE8_SET(SVGA_WIDTH) | SIZEL_VSIZE8_SET(SVGA_HEIGHT)}, + {HSIZE8, HSIZE8_SET(SVGA_WIDTH)}, + {VSIZE8, VSIZE8_SET(SVGA_HEIGHT)}, + {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, + {0xff, 0xff}, +}; + +static const uint8_t uxga_regs[][2] = { + {BANK_SEL, BANK_SEL_SENSOR}, + {COM7, COM7_RES_UXGA}, + {COM1, 0x0F | 0x80}, + {HSTART, 0x11}, + {HSTOP, 0x75}, + {VSTART, 0x01}, + {VSTOP, 0x97}, + {REG32, 0x36}, + {BANK_SEL, BANK_SEL_DSP}, + {RESET, RESET_DVP}, + {SIZEL, SIZEL_HSIZE8_11_SET(UXGA_WIDTH) | SIZEL_HSIZE8_SET(UXGA_WIDTH) | SIZEL_VSIZE8_SET(UXGA_HEIGHT)}, + {HSIZE8, HSIZE8_SET(UXGA_WIDTH)}, + {VSIZE8, VSIZE8_SET(UXGA_HEIGHT)}, + {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, + {0xff, 0xff}, +}; + +static const uint8_t yuv422_regs[][2] = { + {BANK_SEL, BANK_SEL_DSP}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {IMAGE_MODE, IMAGE_MODE_YUV422}, + {0xd7, 0x03}, + {0x33, 0xa0}, + {0xe5, 0x1f}, + {0xe1, 0x67}, + {RESET, 0x00}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {0xff, 0xff}, +}; + +static const uint8_t rgb565_regs[][2] = { + {BANK_SEL, BANK_SEL_DSP}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {IMAGE_MODE, IMAGE_MODE_RGB565}, + {0xd7, 0x03}, + {RESET, 0x00}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {0xff, 0xff}, +}; + +static const uint8_t bayer_regs[][2] = { + {BANK_SEL, BANK_SEL_DSP}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {IMAGE_MODE, IMAGE_MODE_RAW10}, + {0xd7, 0x03}, + {RESET, 0x00}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {0xff, 0xff}, +}; + +static const uint8_t jpeg_regs[][2] = { + {BANK_SEL, BANK_SEL_DSP}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {IMAGE_MODE, IMAGE_MODE_JPEG_EN}, + {0xd7, 0x03}, + {RESET, 0x00}, + {R_BYPASS, R_BYPASS_DSP_EN}, + {0xff, 0xff}, +}; + +#define NUM_BRIGHTNESS_LEVELS (5) +static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = { + {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA}, + {0x00, 0x04, 0x09, 0x00, 0x00}, /* -2 */ + {0x00, 0x04, 0x09, 0x10, 0x00}, /* -1 */ + {0x00, 0x04, 0x09, 0x20, 0x00}, /* 0 */ + {0x00, 0x04, 0x09, 0x30, 0x00}, /* +1 */ + {0x00, 0x04, 0x09, 0x40, 0x00}, /* +2 */ +}; + +#define NUM_CONTRAST_LEVELS (5) +static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = { + {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA}, + {0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06}, /* -2 */ + {0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06}, /* -1 */ + {0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06}, /* 0 */ + {0x00, 0x04, 0x07, 0x20, 0x24, 0x16, 0x06}, /* +1 */ + {0x00, 0x04, 0x07, 0x20, 0x28, 0x0c, 0x06}, /* +2 */ +}; + +#define NUM_SATURATION_LEVELS (5) +static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = { + {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA}, + {0x00, 0x02, 0x03, 0x28, 0x28}, /* -2 */ + {0x00, 0x02, 0x03, 0x38, 0x38}, /* -1 */ + {0x00, 0x02, 0x03, 0x48, 0x48}, /* 0 */ + {0x00, 0x02, 0x03, 0x58, 0x58}, /* +1 */ + {0x00, 0x02, 0x03, 0x68, 0x68}, /* +2 */ +}; + +static int reg_read(int8_t reg, uint8_t *data) { + return eos_i2c_read8(OV2640_ADDR, reg, data, 1); +} + +static int reg_write(uint8_t reg, uint8_t data) { + return eos_i2c_write8(OV2640_ADDR, reg, &data, 1); +} + +static int regarr_write(const uint8_t (*regs)[2]) { + int i, rv; + + i = 0; + rv = EOS_OK; + + while ((regs[i][0] != 0xff) || (regs[i][1] != 0xff)) { + if (!rv) rv = reg_write(regs[i][0], regs[i][1]); + i++; + } + + return rv; +} + +int eos_ov2640_init(void) { + int rv; + + // Reset all registers + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_write(COM7, COM7_SRST); + if (rv) return rv; + + // Delay 5 ms + eos_time_sleep(5); + + // Write default regsiters + rv = regarr_write(default_regs); + if (rv) return rv; + + // Delay 300 ms + eos_time_sleep(300); + + return EOS_OK; +} + +int eos_ov2640_sleep(int enable) { + uint8_t reg; + int rv; + + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_read(COM2, ®); + if (rv) return rv; + + if (enable) { + reg |= COM2_STDBY; + } else { + reg &= ~COM2_STDBY; + } + + // Write back register + return reg_write(COM2, reg); +} + +int eos_ov2640_set_pixfmt(pixformat_t fmt) { + const uint8_t (*regs)[2]; + + switch (fmt) { + case PIXFORMAT_RGB565: + regs = rgb565_regs; + break; + case PIXFORMAT_YUV422: + case PIXFORMAT_GRAYSCALE: + regs = yuv422_regs; + break; + case PIXFORMAT_BAYER: + regs = bayer_regs; + break; + case PIXFORMAT_JPEG: + regs = jpeg_regs; + break; + default: + return EOS_ERR; + } + + return regarr_write(regs); +} + +int eos_ov2640_set_framesize(framesize_t framesize) { + const uint8_t (*regs)[2]; + uint16_t sensor_w = 0; + uint16_t sensor_h = 0; + uint16_t w = _eos_cam_resolution[framesize][0]; + uint16_t h = _eos_cam_resolution[framesize][1]; + int rv; + + if ((w % 4) || (h % 4) || (w > UXGA_WIDTH) || (h > UXGA_HEIGHT)) { // w/h must be divisble by 4 + return EOS_ERR; + } + + // Looks really bad. + /* if ((w <= CIF_WIDTH) && (h <= CIF_HEIGHT)) { + regs = cif_regs; + sensor_w = CIF_WIDTH; + sensor_h = CIF_HEIGHT; + } else */ if ((w <= SVGA_WIDTH) && (h <= SVGA_HEIGHT)) { + regs = svga_regs; + sensor_w = SVGA_WIDTH; + sensor_h = SVGA_HEIGHT; + } else { + regs = uxga_regs; + sensor_w = UXGA_WIDTH; + sensor_h = UXGA_HEIGHT; + } + + // Write setup regsiters + rv = regarr_write(regs); + if (rv) return rv; + + uint64_t tmp_div = IM_MIN(sensor_w / w, sensor_h / h); + uint16_t log_div = IM_MIN(IM_LOG2(tmp_div) - 1, 3); + uint16_t div = 1 << log_div; + uint16_t w_mul = w * div; + uint16_t h_mul = h * div; + uint16_t x_off = (sensor_w - w_mul) / 2; + uint16_t y_off = (sensor_h - h_mul) / 2; + + rv = EOS_OK; + if (!rv) rv = reg_write(CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(log_div) | CTRLI_H_DIV_SET(log_div)); + if (!rv) rv = reg_write(HSIZE, HSIZE_SET(w_mul)); + if (!rv) rv = reg_write(VSIZE, VSIZE_SET(h_mul)); + if (!rv) rv = reg_write(XOFFL, XOFFL_SET(x_off)); + if (!rv) rv = reg_write(YOFFL, YOFFL_SET(y_off)); + if (!rv) rv = reg_write(VHYX, VHYX_HSIZE_SET(w_mul) | VHYX_VSIZE_SET(h_mul) | VHYX_XOFF_SET(x_off) | VHYX_YOFF_SET(y_off)); + if (!rv) rv = reg_write(TEST, TEST_HSIZE_SET(w_mul)); + if (!rv) rv = reg_write(ZMOW, ZMOW_OUTW_SET(w)); + if (!rv) rv = reg_write(ZMOH, ZMOH_OUTH_SET(h)); + if (!rv) rv = reg_write(ZMHH, ZMHH_OUTW_SET(w) | ZMHH_OUTH_SET(h)); + if (!rv) rv = reg_write(R_DVP_SP, div); + if (!rv) rv = reg_write(RESET, 0x00); + + return rv; +} + +int eos_ov2640_set_contrast(int level) { + int rv = EOS_OK; + + level += (NUM_CONTRAST_LEVELS / 2) + 1; + if (level <= 0 || level > NUM_CONTRAST_LEVELS) { + return EOS_ERR; + } + + /* Switch to DSP register bank */ + rv = reg_write(BANK_SEL, BANK_SEL_DSP); + + /* Write contrast registers */ + for (int i=0; i NUM_BRIGHTNESS_LEVELS) { + return EOS_ERR; + } + + /* Switch to DSP register bank */ + rv = reg_write(BANK_SEL, BANK_SEL_DSP); + + /* Write brightness registers */ + for (int i=0; i NUM_SATURATION_LEVELS) { + return EOS_ERR; + } + + /* Switch to DSP register bank */ + rv = reg_write(BANK_SEL, BANK_SEL_DSP); + + /* Write saturation registers */ + for (int i=0; i> (4 - gain_temp); + int gain_lo = IM_MIN(roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15); + + if (!rv) rv = reg_write(GAIN, (gain_hi << 4) | (gain_lo << 0)); + } + + return rv; +} + +int eos_ov2640_get_gain_db(float *gain_db) { + int rv = EOS_OK; + uint8_t reg, gain; + + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_read(COM8, ®); + if (rv) return rv; + + // DISABLED + // if (reg & COM8_AGC_EN) { + // rv = reg_write(COM8, reg & (~COM8_AGC_EN)); + // if (rv) return rv; + // } + // DISABLED + + rv = reg_read(GAIN, &gain); + if (rv) return rv; + + // DISABLED + // if (reg & COM8_AGC_EN) { + // rv = reg_write(COM8, reg | COM8_AGC_EN); + // if (rv) return rv; + // } + // DISABLED + + int hi_gain = 1 << (((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1)); + float lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0); + *gain_db = 20.0 * (logf(hi_gain * lo_gain) / logf(10.0)); + + return EOS_OK; +} + +int eos_ov2640_set_auto_exposure(int enable, int exposure_us) { + int rv = EOS_OK; + uint8_t reg; + + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_read(COM8, ®); + if (rv) return rv; + + rv = reg_write(COM8, COM8_SET_AEC(reg, (enable != 0))); + if (rv) return rv; + + if (!enable && (exposure_us >= 0)) { + rv = reg_read(COM7, ®); + if (rv) return rv; + + int t_line = 0; + + if (COM7_GET_RES(reg) == COM7_RES_UXGA) t_line = 1600 + 322; + if (COM7_GET_RES(reg) == COM7_RES_SVGA) t_line = 800 + 390; + if (COM7_GET_RES(reg) == COM7_RES_CIF) t_line = 400 + 195; + + rv = reg_read(CLKRC, ®); + if (rv) return rv; + + int pll_mult = ((reg & CLKRC_DOUBLE) ? 2 : 1) * 3; + int clk_rc = (reg & CLKRC_DIVIDER_MASK) + 2; + + rv = reg_write(BANK_SEL, BANK_SEL_DSP); + if (rv) return rv; + + rv = reg_read(IMAGE_MODE, ®); + if (rv) return rv; + + int t_pclk = 0; + + if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_YUV422) t_pclk = 2; + if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RAW10) t_pclk = 1; + if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RGB565) t_pclk = 2; + + int exposure = IM_MAX(IM_MIN(((exposure_us*(((XCLK_FREQ/clk_rc)*pll_mult)/1000000))/t_pclk)/t_line,0xFFFF),0x0000); + + if (!rv) rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + + if (!rv) rv = reg_read(REG04, ®); + if (!rv) rv = reg_write(REG04, (reg & 0xFC) | ((exposure >> 0) & 0x3)); + + if (!rv) rv = reg_read(AEC, ®); + if (!rv) rv = reg_write(AEC, (reg & 0x00) | ((exposure >> 2) & 0xFF)); + + if (!rv) rv = reg_read(REG45, ®); + if (!rv) rv = reg_write(REG45, (reg & 0xC0) | ((exposure >> 10) & 0x3F)); + } + + return rv; +} + +int eos_ov2640_get_exposure_us(int *exposure_us) { + int rv = EOS_OK; + uint8_t reg, aec_10, aec_92, aec_1510; + + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_read(COM8, ®); + if (rv) return rv; + + // DISABLED + // if (reg & COM8_AEC_EN) { + // rv = reg_write(COM8, reg & (~COM8_AEC_EN)); + // if (rv) return rv; + // } + // DISABLED + + rv = reg_read(REG04, &aec_10); + if (rv) return rv; + + rv = reg_read(AEC, &aec_92); + if (rv) return rv; + + rv = reg_read(REG45, &aec_1510); + if (rv) return rv; + + // DISABLED + // if (reg & COM8_AEC_EN) { + // rv = reg_write(COM8, reg | COM8_AEC_EN); + // if (rv) return rv; + // } + // DISABLED + + rv = reg_read(COM7, ®); + if (rv) return rv; + + int t_line = 0; + + if (COM7_GET_RES(reg) == COM7_RES_UXGA) t_line = 1600 + 322; + if (COM7_GET_RES(reg) == COM7_RES_SVGA) t_line = 800 + 390; + if (COM7_GET_RES(reg) == COM7_RES_CIF) t_line = 400 + 195; + + rv = reg_read(CLKRC, ®); + if (rv) return rv; + + int pll_mult = ((reg & CLKRC_DOUBLE) ? 2 : 1) * 3; + int clk_rc = (reg & CLKRC_DIVIDER_MASK) + 2; + + rv = reg_write(BANK_SEL, BANK_SEL_DSP); + if (rv) return rv; + + rv = reg_read(IMAGE_MODE, ®); + if (rv) return rv; + + int t_pclk = 0; + + if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_YUV422) t_pclk = 2; + if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RAW10) t_pclk = 1; + if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RGB565) t_pclk = 2; + + uint16_t exposure = ((aec_1510 & 0x3F) << 10) + ((aec_92 & 0xFF) << 2) + ((aec_10 & 0x3) << 0); + *exposure_us = (exposure*t_line*t_pclk)/(((XCLK_FREQ/clk_rc)*pll_mult)/1000000); + + return EOS_OK; +} + +int eos_ov2640_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db) { + int rv = EOS_OK; + uint8_t reg; + + rv = reg_write(BANK_SEL, BANK_SEL_DSP); + if (rv) return rv; + + rv = reg_read(CTRL1, ®); + if (rv) return rv; + + rv = reg_write(CTRL1, (reg & (~CTRL1_AWB)) | (enable ? CTRL1_AWB : 0)); + if (rv) return rv; + + if (!enable && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db)) + && (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) { + } + + return rv; +} + +int eos_ov2640_set_hmirror(int enable) { + int rv = EOS_OK; + uint8_t reg; + + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_read(REG04, ®); + if (rv) return rv; + + if (!enable) { // Already mirrored. + reg |= REG04_HFLIP_IMG; + } else { + reg &= ~REG04_HFLIP_IMG; + } + + return reg_write(REG04, reg); +} + +int eos_ov2640_set_vflip(int enable) { + int rv = EOS_OK; + uint8_t reg; + + rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); + if (rv) return rv; + + rv = reg_read(REG04, ®); + if (rv) return rv; + + if (!enable) { // Already flipped. + reg |= REG04_VFLIP_IMG | REG04_VREF_EN; + } else { + reg &= ~(REG04_VFLIP_IMG | REG04_VREF_EN); + } + + return reg_write(REG04, reg); +} + +int eos_ov2640_set_effect(sde_t sde) { + int rv = EOS_OK; + + switch (sde) { + case SDE_NEGATIVE: + if (!rv) rv = reg_write(BANK_SEL, BANK_SEL_DSP); + if (!rv) rv = reg_write(BPADDR, 0x00); + if (!rv) rv = reg_write(BPDATA, 0x40); + if (!rv) rv = reg_write(BPADDR, 0x05); + if (!rv) rv = reg_write(BPDATA, 0x80); + if (!rv) rv = reg_write(BPDATA, 0x80); + break; + case SDE_NORMAL: + if (!rv) rv = reg_write(BANK_SEL, BANK_SEL_DSP); + if (!rv) rv = reg_write(BPADDR, 0x00); + if (!rv) rv = reg_write(BPDATA, 0x00); + if (!rv) rv = reg_write(BPADDR, 0x05); + if (!rv) rv = reg_write(BPDATA, 0x80); + if (!rv) rv = reg_write(BPDATA, 0x80); + break; + default: + return EOS_ERR; + } + + return rv; +} diff --git a/fw/fe310/eos/dev/ov2640.h b/fw/fe310/eos/dev/ov2640.h new file mode 100644 index 0000000..3d08c2a --- /dev/null +++ b/fw/fe310/eos/dev/ov2640.h @@ -0,0 +1,8 @@ +#include + +#define OV2640_ADDR 0x30 + +int eos_ov2640_init(void); +int eos_ov2640_sleep(int enable); +int eos_ov2640_set_pixfmt(pixformat_t fmt); +int eos_ov2640_set_framesize(framesize_t framesize); diff --git a/fw/fe310/eos/dev/ov2640_regs.h b/fw/fe310/eos/dev/ov2640_regs.h new file mode 100644 index 0000000..deb7521 --- /dev/null +++ b/fw/fe310/eos/dev/ov2640_regs.h @@ -0,0 +1,245 @@ +/* + * This file is part of the OpenMV project. + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * Copyright (c) 2013-2021 Kwabena W. Agyeman + * + * This work is licensed under the MIT license, see the file LICENSE for details. + * + * OV2640 register definitions. + */ +#ifndef __REG_REGS_H__ +#define __REG_REGS_H__ + +/* DSP register bank FF=0x00*/ + +#define QS 0x44 +#define HSIZE 0x51 +#define VSIZE 0x52 +#define XOFFL 0x53 +#define YOFFL 0x54 +#define VHYX 0x55 +#define DPRP 0x56 +#define TEST 0x57 +#define ZMOW 0x5A +#define ZMOH 0x5B +#define ZMHH 0x5C +#define BPADDR 0x7C +#define BPDATA 0x7D +#define SIZEL 0x8C +#define HSIZE8 0xC0 +#define VSIZE8 0xC1 +#define CTRL1 0xC3 +#define MS_SP 0xF0 +#define SS_ID 0xF7 +#define SS_CTRL 0xF7 +#define MC_AL 0xFA +#define MC_AH 0xFB +#define MC_D 0xFC +#define P_CMD 0xFD +#define P_STATUS 0xFE + +#define CTRLI 0x50 +#define CTRLI_LP_DP 0x80 +#define CTRLI_ROUND 0x40 + +#define CTRL0 0xC2 +#define CTRL0_AEC_EN 0x80 +#define CTRL0_AEC_SEL 0x40 +#define CTRL0_STAT_SEL 0x20 +#define CTRL0_VFIRST 0x10 +#define CTRL0_YUV422 0x08 +#define CTRL0_YUV_EN 0x04 +#define CTRL0_RGB_EN 0x02 +#define CTRL0_RAW_EN 0x01 + +#define CTRL2 0x86 +#define CTRL2_DCW_EN 0x20 +#define CTRL2_SDE_EN 0x10 +#define CTRL2_UV_ADJ_EN 0x08 +#define CTRL2_UV_AVG_EN 0x04 +#define CTRL2_CMX_EN 0x01 + +#define CTRL3 0x87 +#define CTRL3_BPC_EN 0x80 +#define CTRL3_WPC_EN 0x40 +#define R_DVP_SP 0xD3 +#define R_DVP_SP_AUTO_MODE 0x80 + +#define R_BYPASS 0x05 +#define R_BYPASS_DSP_EN 0x00 +#define R_BYPASS_DSP_BYPAS 0x01 + +#define IMAGE_MODE 0xDA +#define IMAGE_MODE_Y8_DVP_EN 0x40 +#define IMAGE_MODE_JPEG_EN 0x10 +#define IMAGE_MODE_YUV422 0x00 +#define IMAGE_MODE_RAW10 0x04 +#define IMAGE_MODE_RGB565 0x09 +#define IMAGE_MODE_HREF_VSYNC 0x02 +#define IMAGE_MODE_LBYTE_FIRST 0x01 +#define IMAGE_MODE_GET_FMT(x) ((x)&0xC) + +#define RESET 0xE0 +#define RESET_MICROC 0x40 +#define RESET_SCCB 0x20 +#define RESET_JPEG 0x10 +#define RESET_DVP 0x04 +#define RESET_IPU 0x02 +#define RESET_CIF 0x01 + +#define MC_BIST 0xF9 +#define MC_BIST_RESET 0x80 +#define MC_BIST_BOOT_ROM_SEL 0x40 +#define MC_BIST_12KB_SEL 0x20 +#define MC_BIST_12KB_MASK 0x30 +#define MC_BIST_512KB_SEL 0x08 +#define MC_BIST_512KB_MASK 0x0C +#define MC_BIST_BUSY_BIT_R 0x02 +#define MC_BIST_MC_RES_ONE_SH_W 0x02 +#define MC_BIST_LAUNCH 0x01 + +#define BANK_SEL 0xFF +#define BANK_SEL_DSP 0x00 +#define BANK_SEL_SENSOR 0x01 + +/* Sensor register bank FF=0x01*/ + +#define GAIN 0x00 +#define COM1 0x03 +#define REG_PID 0x0A +#define REG_VER 0x0B +#define COM4 0x0D +#define AEC 0x10 + +#define CLKRC 0x11 +#define CLKRC_DOUBLE 0x80 +#define CLKRC_DIVIDER_MASK 0x3F + +#define COM10 0x15 +#define HSTART 0x17 +#define HSTOP 0x18 +#define VSTART 0x19 +#define VSTOP 0x1A +#define MIDH 0x1C +#define MIDL 0x1D +#define AEW 0x24 +#define AEB 0x25 +#define REG2A 0x2A +#define FRARL 0x2B +#define ADDVSL 0x2D +#define ADDVSH 0x2E +#define YAVG 0x2F +#define HSDY 0x30 +#define HEDY 0x31 +#define ARCOM2 0x34 +#define REG45 0x45 +#define FLL 0x46 +#define FLH 0x47 +#define COM19 0x48 +#define ZOOMS 0x49 +#define COM22 0x4B +#define COM25 0x4E +#define BD50 0x4F +#define BD60 0x50 +#define REG5D 0x5D +#define REG5E 0x5E +#define REG5F 0x5F +#define REG60 0x60 +#define HISTO_LOW 0x61 +#define HISTO_HIGH 0x62 + +#define REG04 0x04 +#define REG04_DEFAULT 0x28 +#define REG04_HFLIP_IMG 0x80 +#define REG04_VFLIP_IMG 0x40 +#define REG04_VREF_EN 0x10 +#define REG04_HREF_EN 0x08 +#define REG04_SET(x) (REG04_DEFAULT|x) + +#define REG08 0x08 +#define COM2 0x09 +#define COM2_STDBY 0x10 +#define COM2_OUT_DRIVE_1x 0x00 +#define COM2_OUT_DRIVE_2x 0x01 +#define COM2_OUT_DRIVE_3x 0x02 +#define COM2_OUT_DRIVE_4x 0x03 + +#define COM3 0x0C +#define COM3_DEFAULT 0x38 +#define COM3_BAND_50Hz 0x04 +#define COM3_BAND_60Hz 0x00 +#define COM3_BAND_AUTO 0x02 +#define COM3_BAND_SET(x) (COM3_DEFAULT|x) + +#define COM7 0x12 +#define COM7_SRST 0x80 +#define COM7_RES_UXGA 0x00 /* UXGA */ +#define COM7_RES_SVGA 0x40 /* SVGA */ +#define COM7_RES_CIF 0x20 /* CIF */ +#define COM7_ZOOM_EN 0x04 /* Enable Zoom */ +#define COM7_COLOR_BAR 0x02 /* Enable Color Bar Test */ +#define COM7_GET_RES(x) ((x)&0x70) + +#define COM8 0x13 +#define COM8_DEFAULT 0xC0 +#define COM8_BNDF_EN 0x20 /* Enable Banding filter */ +#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ +#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ +#define COM8_SET(x) (COM8_DEFAULT|x) +#define COM8_SET_AEC(r,x) (((r)&0xFE)|((x)&1)) + +#define COM9 0x14 /* AGC gain ceiling */ +#define COM9_DEFAULT 0x08 +#define COM9_AGC_GAIN_2x 0x00 /* AGC: 2x */ +#define COM9_AGC_GAIN_4x 0x01 /* AGC: 4x */ +#define COM9_AGC_GAIN_8x 0x02 /* AGC: 8x */ +#define COM9_AGC_GAIN_16x 0x03 /* AGC: 16x */ +#define COM9_AGC_GAIN_32x 0x04 /* AGC: 32x */ +#define COM9_AGC_GAIN_64x 0x05 /* AGC: 64x */ +#define COM9_AGC_GAIN_128x 0x06 /* AGC: 128x */ +#define COM9_AGC_SET(x) (COM9_DEFAULT|(x<<5)) + +#define CTRL1_AWB 0x08 /* Enable AWB */ + +#define VV 0x26 +#define VV_AGC_TH_SET(h,l) ((h<<4)|(l&0x0F)) + +#define REG32 0x32 +#define REG32_UXGA 0x36 +#define REG32_SVGA 0x09 +#define REG32_CIF 0x00 + +#define VAL_SET(x, mask, rshift, lshift) ((((x) >> rshift) & mask) << lshift) + +#define CTRLI_V_DIV_SET(x) VAL_SET(x, 0x3, 0, 3) +#define CTRLI_H_DIV_SET(x) VAL_SET(x, 0x3, 0, 0) + +#define SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6) +#define SIZEL_HSIZE8_SET(x) VAL_SET(x, 0x7, 0, 3) +#define SIZEL_VSIZE8_SET(x) VAL_SET(x, 0x7, 0, 0) + +#define HSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) +#define VSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) + +#define HSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) +#define VSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) + +#define XOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) +#define YOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) + +#define VHYX_VSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 7) +#define VHYX_HSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 3) +#define VHYX_YOFF_SET(x) VAL_SET(x, 0x3, 8, 4) +#define VHYX_XOFF_SET(x) VAL_SET(x, 0x3, 8, 0) + +#define TEST_HSIZE_SET(x) VAL_SET(x, 0x1, (9+2), 7) + +#define ZMOW_OUTW_SET(x) VAL_SET(x, 0xFF, 2, 0) +#define ZMOH_OUTH_SET(x) VAL_SET(x, 0xFF, 2, 0) + +#define ZMHH_ZSPEED_SET(x) VAL_SET(x, 0x0F, 0, 4) +#define ZMHH_OUTH_SET(x) VAL_SET(x, 0x1, (8+2), 2) +#define ZMHH_OUTW_SET(x) VAL_SET(x, 0x3, (8+2), 0) + +#endif //__REG_REGS_H__ diff --git a/fw/fe310/eos/dev/sdc_crypto.c b/fw/fe310/eos/dev/sdc_crypto.c new file mode 100644 index 0000000..f0e935d --- /dev/null +++ b/fw/fe310/eos/dev/sdc_crypto.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#include "sha/sha1.h" +#include "sdc_crypto.h" + +#define SDC_CRYPTO_KEY_SIZE 16 +#define SDC_CRYPTO_BLK_SIZE 16 +#define SDC_CRYPTO_HASH_SIZE 20 + +EOSSDCCrypto *sdc_crypto; + +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) { + char key_essiv[SDC_CRYPTO_HASH_SIZE]; + + sdc_crypto = crypto; + + memset(key_essiv, 0, SDC_CRYPTO_HASH_SIZE); + init(ctx, key); + sdc_crypto->ctx = ctx; + sdc_crypto->enc = enc; + sdc_crypto->dec = dec; + + SHA1(key_essiv, key, SDC_CRYPTO_KEY_SIZE); + init_essiv(ctx_essiv, key_essiv); + sdc_crypto->ctx_essiv = ctx_essiv; + sdc_crypto->enc_essiv = enc_essiv; +} + +void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer) { + uint8_t iv[SDC_CRYPTO_BLK_SIZE]; + + if (sdc_crypto == NULL) return; + + memset(iv, 0, SDC_CRYPTO_BLK_SIZE); + memcpy(iv, §, sizeof(sect)); + sdc_crypto->enc_essiv(sdc_crypto->ctx_essiv, iv); + sdc_crypto->enc(sdc_crypto->ctx, iv, buffer, 512); +} + +void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer) { + uint8_t iv[SDC_CRYPTO_BLK_SIZE]; + + if (sdc_crypto == NULL) return; + + memset(iv, 0, SDC_CRYPTO_BLK_SIZE); + memcpy(iv, §, sizeof(sect)); + sdc_crypto->enc_essiv(sdc_crypto->ctx_essiv, iv); + sdc_crypto->dec(sdc_crypto->ctx, iv, buffer, 512); +} diff --git a/fw/fe310/eos/dev/sdc_crypto.h b/fw/fe310/eos/dev/sdc_crypto.h new file mode 100644 index 0000000..015bf8a --- /dev/null +++ b/fw/fe310/eos/dev/sdc_crypto.h @@ -0,0 +1,18 @@ +#include +#include + +typedef void (*eve_sdcc_init_t) (void *, uint8_t *); +typedef void (*eve_sdcc_crypt_t) (void *, uint8_t *, uint8_t *, size_t); +typedef void (*eve_sdcc_essiv_t) (void *, uint8_t *); + +typedef struct EOSSDCCrypto { + void *ctx; + eve_sdcc_crypt_t enc; + eve_sdcc_crypt_t dec; + void *ctx_essiv; + eve_sdcc_essiv_t enc_essiv; +} 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 diff --git a/fw/fe310/eos/dev/sdcard.c b/fw/fe310/eos/dev/sdcard.c new file mode 100644 index 0000000..d081388 --- /dev/null +++ b/fw/fe310/eos/dev/sdcard.c @@ -0,0 +1,539 @@ +#include +#include +#include + +#include "eos.h" +#include "timer.h" + +#include "spi.h" +#include "spi_dev.h" + +#include "sdc_crypto.h" +#include "sdcard.h" + +#define SDC_TIMEOUT_CMD 500 +#define SDC_TIMEOUT_READ 200 +#define SDC_TIMEOUT_WRITE 500 + +#define SDC_POLY_CRC7 0x09 +#define SDC_POLY_CRC16 0x1021 + +#define SDC_CMD_FLAG_CRC 0x01 +#define SDC_CMD_FLAG_NOCS 0x02 +#define SDC_CMD_FLAG_NOWAIT 0x04 +#define SDC_CMD_FLAG_RSTUFF 0x08 + +#define SDC_TOKEN_START_BLK 0xfe +#define SDC_TOKEN_START_BLKM 0xfc +#define SDC_TOKEN_STOP_TRAN 0xfd + +#define SDC_DRESP_MASK 0x1f +#define SDC_DRESP_ACCEPT 0x05 +#define SDC_DRESP_ERR_CRC 0x0b +#define SDC_DRESP_ERR_WRITE 0x0d + +#define SDC_R1_READY 0x00 + +#define SDC_R1_IDLE_STATE 0x01 +#define SDC_R1_ERASE_RESET 0x02 +#define SDC_R1_ILLEGAL_CMD 0x04 +#define SDC_R1_ERR_CMD_CRC 0x08 +#define SDC_R1_ERR_ERASE_SEQ 0x10 +#define SDC_R1_ERR_ADDR 0x20 +#define SDC_R1_ERR_PARAM 0x40 + +#define SDC_NCR 10 + +#define SDC_ERR(rv) ((rv < 0) ? rv : EOS_ERR) + +/* CMD */ +#define GO_IDLE_STATE 0 +#define SEND_OP_COND 1 +#define SEND_IF_COND 8 +#define SEND_CSD 9 +#define STOP_TRANSMISSION 12 +#define SET_BLOCKLEN 16 +#define READ_SINGLE_BLOCK 17 +#define READ_MULTIPLE_BLOCK 18 +#define WRITE_BLOCK 24 +#define WRITE_MULTIPLE_BLOCK 25 +#define ERASE_WR_BLK_START 32 +#define ERASE_WR_BLK_END 33 +#define ERASE 38 +#define APP_CMD 55 +#define READ_OCR 58 + +/* ACMD */ +#define SD_STATUS 13 +#define SET_WR_BLK_ERASE_COUNT 23 +#define SD_APP_OP_COND 41 + +static uint8_t sdc_type = 0; + +static uint8_t sdc_crc7(uint8_t crc, uint8_t b) { + int i; + + for (i=8; i--; b<<=1) { + crc <<= 1; + if ((b ^ crc) & 0x80) crc ^= SDC_POLY_CRC7; + } + return crc & 0x7f; +} + +static uint16_t sdc_crc16(uint16_t crc, uint8_t b) { + int i; + + crc = crc ^ ((uint16_t)b << 8); + for (i=8; i--;) { + if (crc & 0x8000) { + crc = (crc << 1) ^ SDC_POLY_CRC16; + } else { + crc <<= 1; + } + } + return crc; +} + +static uint32_t sdc_nto(uint32_t start, uint32_t timeout) { + uint32_t d = eos_time_delta_ms(start); + return (d > timeout) ? 0 : timeout - d; +} + +static uint8_t sdc_xchg8(uint8_t data) { + return eos_spi_xchg8(data, 0); +} + +static uint16_t sdc_xchg16(uint16_t data) { + return eos_spi_xchg16(data, 0); +} + +static uint32_t sdc_xchg32(uint32_t data) { + return eos_spi_xchg32(data, 0); +} + +static void sdc_buf_send(unsigned char *buffer, uint16_t len) { + int i; + + for (i=0; i> 24); + crc = sdc_crc7(crc, arg >> 16); + crc = sdc_crc7(crc, arg >> 8); + crc = sdc_crc7(crc, arg); + } + crc = (crc << 1) | 0x01; + sdc_xchg8(cmd); + sdc_xchg32(arg); + sdc_xchg8(crc); + if (flags & SDC_CMD_FLAG_RSTUFF) sdc_xchg8(0xff); + + i = SDC_NCR; + do { + ret = sdc_xchg8(0xff); + } while ((ret & 0x80) && --i); + if (ret & 0x80) return EOS_ERR_BUSY; + + return ret; +} + +static int sdc_ready(uint32_t timeout) { + uint8_t d = 0; + uint32_t start; + + if (timeout == 0) return EOS_ERR_BUSY; + start = eos_time_get_tick(); + do { + if (eos_time_delta_ms(start) > timeout) break; + d = sdc_xchg8(0xff); + } while (d != 0xff); + if (d != 0xff) return EOS_ERR_BUSY; + + return EOS_OK; +} + +static int sdc_block_read(uint8_t *buffer, uint16_t len, uint32_t timeout) { + uint8_t token = 0xff; + uint32_t start; + + if (timeout == 0) return EOS_ERR_BUSY; + start = eos_time_get_tick(); + do { + if (eos_time_delta_ms(start) > timeout) break; + token = sdc_xchg8(0xff); + } while (token == 0xff); + if (token == 0xff) return EOS_ERR_BUSY; + if (token != SDC_TOKEN_START_BLK) return EOS_ERR; + + sdc_buf_recv(buffer, len); + sdc_xchg16(0xffff); /* dummy CRC */ + + return EOS_OK; +} + +static int sdc_block_write(uint8_t token, uint8_t *buffer, uint16_t len, uint32_t timeout) { + uint8_t d; + int rv; + + rv = sdc_ready(timeout); + if (rv) return rv; + + sdc_xchg8(token); + if (buffer && len) { + sdc_buf_send(buffer, len); + sdc_xchg16(0xffff); /* dummy CRC */ + + d = sdc_xchg8(0xff); /* Response */ + if ((d & SDC_DRESP_MASK) != SDC_DRESP_ACCEPT) return EOS_ERR; + } + + return EOS_OK; +} + +static int sdc_cmd(uint8_t cmd, uint32_t arg, uint8_t flags, uint32_t timeout) { + int do_cs = !(flags & SDC_CMD_FLAG_NOCS); + int do_wait = !(flags & SDC_CMD_FLAG_NOWAIT); + int rv = EOS_OK; + + if (do_cs) sdc_select(); + if (do_wait) rv = sdc_ready(timeout); + if (rv) { + if (do_cs) sdc_deselect(); + return rv; + } + rv = sdc_xchg_cmd(cmd, arg, flags); + if (do_cs) sdc_deselect(); + return rv; +} + +static int sdc_acmd(uint8_t cmd, uint32_t arg, uint8_t flags, uint32_t timeout) { + int rv; + uint32_t start; + + start = eos_time_get_tick(); + rv = sdc_cmd(APP_CMD, 0, flags, timeout); + if (rv & ~SDC_R1_IDLE_STATE) return rv; + + if (flags & SDC_CMD_FLAG_NOCS) { + sdc_deselect(); + sdc_select(); + } + return sdc_cmd(cmd, arg, flags, sdc_nto(start, timeout)); +} + +static int sdc_init(uint32_t timeout) { + int rv, i; + uint8_t _type; + uint8_t ocr[4]; + uint32_t start; + start = eos_time_get_tick(); + + eos_time_sleep(100); + for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */ + + rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD); + if (rv != SDC_R1_IDLE_STATE) return SDC_ERR(rv); + + sdc_select(); + rv = sdc_cmd(SEND_IF_COND, 0x1aa, SDC_CMD_FLAG_CRC | SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); + switch (rv) { + case SDC_R1_IDLE_STATE: + for (i=0; i<4; i++) { /* R7 response */ + ocr[i] = sdc_xchg8(0xff); + } + sdc_deselect(); + if (ocr[2] == 0x01 && ocr[3] == 0xaa) { /* Check voltage range: 2.7-3.6V */ + do { + rv = sdc_acmd(SD_APP_OP_COND, 0x40000000, 0, sdc_nto(start, timeout)); + } while (rv == SDC_R1_IDLE_STATE); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + + sdc_select(); + rv = sdc_cmd(READ_OCR, 0, SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); + if (rv == SDC_R1_READY) { + for (i=0; i<4; i++) { /* R7 response */ + ocr[i] = sdc_xchg8(0xff); + } + sdc_deselect(); + } else { + sdc_deselect(); + return SDC_ERR(rv); + } + + _type = EOS_SDC_TYPE_SDC2; + if (ocr[0] & 0xc0) _type |= EOS_SDC_CAP_BLK; + } + break; + + case SDC_R1_IDLE_STATE | SDC_R1_ILLEGAL_CMD: + sdc_deselect(); + rv = sdc_acmd(SD_APP_OP_COND, 0, 0, sdc_nto(start, timeout)); + switch (rv) { + case SDC_R1_IDLE_STATE: + do { + rv = sdc_acmd(SD_APP_OP_COND, 0, 0, sdc_nto(start, timeout)); + } while (rv == SDC_R1_IDLE_STATE); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + case SDC_R1_READY: + _type = EOS_SDC_TYPE_SDC1; + break; + + default: + do { + rv = sdc_cmd(SEND_OP_COND, 0, 0, sdc_nto(start, timeout)); + } while (rv == SDC_R1_IDLE_STATE); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + _type = EOS_SDC_TYPE_MMC; + break; + + } + break; + + default: + sdc_deselect(); + return SDC_ERR(rv); + } + + if (!(_type & EOS_SDC_CAP_BLK)) { + rv = sdc_cmd(SET_BLOCKLEN, 512, 0, sdc_nto(start, timeout)); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + } + + if (_type & EOS_SDC_TYPE_SDC) { + uint8_t csd[16]; + + sdc_select(); + rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); + if (rv == SDC_R1_READY) { + rv = sdc_block_read(csd, 16, sdc_nto(start, timeout)); + } else { + rv = SDC_ERR(rv); + } + sdc_deselect(); + if (rv) return rv; + + for (i=0; i<16; i++) { + printf("%.2x ", csd[i]); + } + printf("\n"); + if (csd[10] & 0x40) _type |= EOS_SDC_CAP_ERASE_EN; + } + + eos_spi_set_div(EOS_SPI_DEV_SDC, 5); + sdc_type = _type; + return EOS_OK; +} + +int eos_sdc_init(uint8_t wakeup_cause) { + int rv; + + eos_spi_select(EOS_SPI_DEV_SDC); + rv = sdc_init(5000); + if (rv) { + printf("SDC ERROR\n"); + } else { + printf("SDC OK:%x\n", sdc_type); + } + eos_spi_deselect(); + + return EOS_OK; +} + +uint8_t eos_sdc_type(void) { + return sdc_type & EOS_SDC_TYPE_MASK; +} + +uint8_t eos_sdc_cap(void) { + return sdc_type & EOS_SDC_CAP_MASK; +} + +int eos_sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { + int rv; + uint8_t csd[16]; + uint32_t start = eos_time_get_tick(); + + sdc_select(); + rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, timeout); + if (rv == SDC_R1_READY) { + rv = sdc_block_read(csd, 16, sdc_nto(start, timeout)); + } else { + rv = SDC_ERR(rv); + } + sdc_deselect(); + if (rv) return rv; + + if ((csd[0] >> 6) == 1) { /* SDCv2 */ + *sectors = (csd[9] + (csd[8] << 8) + ((csd[7] & 0x3f) << 16) + 1) << 10; + } else { /* SDCv1 or MMC*/ + uint8_t n = (csd[5] & 0x0f) + (csd[10] >> 7) + ((csd[9] & 0x03) << 1) + 2; + *sectors = (csd[8] >> 6) + (csd[7] << 2) + ((csd[6] & 0x03) << 10) + 1; + *sectors = *sectors << (n - 9); + } + + return EOS_OK; +} + +int eos_sdc_get_blk_size(uint32_t timeout, uint32_t *size) { + int rv; + uint8_t rbl[64]; /* SD Status or CSD register */ + uint32_t start = eos_time_get_tick(); + + sdc_select(); + if (sdc_type & EOS_SDC_TYPE_SDC2) { + rv = sdc_acmd(SD_STATUS, 0, SDC_CMD_FLAG_NOCS, timeout); + sdc_xchg8(0xff); /* R2 response */ + } else { + rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, timeout); + } + if (rv == SDC_R1_READY) { + rv = sdc_block_read(rbl, (sdc_type & EOS_SDC_TYPE_SDC2) ? 64 : 16, sdc_nto(start, timeout)); + } else { + rv = SDC_ERR(rv); + } + sdc_deselect(); + if (rv) return rv; + + if (sdc_type & EOS_SDC_TYPE_SDC2) { + *size = 16UL << (rbl[10] >> 4); + } else if (sdc_type & EOS_SDC_TYPE_SDC1) { + *size = (((rbl[10] & 0x3f) << 1) + (rbl[11] >> 7) + 1) << ((rbl[13] >> 6) - 1); + } else { + *size = (((rbl[10] & 0x7c) >> 2) + 1) * (((rbl[11] & 0x03) << 3) + (rbl[11] >> 5) + 1); + } + + return EOS_OK; +} + +int eos_sdc_sync(uint32_t timeout) { + int rv; + + sdc_select(); + rv = sdc_ready(timeout); + sdc_deselect(); + + return rv; +} + +int eos_sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout) { + int rv; + uint32_t start; + + if (!(sdc_type & EOS_SDC_TYPE_SDC)) return EOS_ERR; + if (!(sdc_type & EOS_SDC_CAP_ERASE_EN)) return EOS_ERR; + if (!(sdc_type & EOS_SDC_CAP_BLK)) { + blk_start *= 512; + blk_end *= 512; + } + + start = eos_time_get_tick(); + rv = sdc_cmd(ERASE_WR_BLK_START, blk_start, 0, timeout); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + + rv = sdc_cmd(ERASE_WR_BLK_END, blk_end, 0, sdc_nto(start, timeout)); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + + rv = sdc_cmd(ERASE, 0, 0, sdc_nto(start, timeout)); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + + return eos_sdc_sync(sdc_nto(start, timeout)); +} + +int eos_sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer) { + int rv; + uint8_t cmd = ((count == 1) ? READ_SINGLE_BLOCK : READ_MULTIPLE_BLOCK); + + if (!(sdc_type & EOS_SDC_CAP_BLK)) sect *= 512; + + sdc_select(); + rv = sdc_cmd(cmd, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); + if (rv == SDC_R1_READY) { + int _rv = SDC_R1_READY; + + while (count) { + rv = sdc_block_read(buffer, 512, SDC_TIMEOUT_READ); + if (rv) break; + eos_sdcc_decrypt(sect, buffer); + buffer += 512; + count--; + } + if (cmd == READ_MULTIPLE_BLOCK) _rv = sdc_cmd(STOP_TRANSMISSION, 0, SDC_CMD_FLAG_NOCS | SDC_CMD_FLAG_NOWAIT | SDC_CMD_FLAG_RSTUFF, 0); + if (!rv && (_rv != SDC_R1_READY)) rv = SDC_ERR(_rv); + } else { + rv = SDC_ERR(rv); + } + sdc_deselect(); + + return rv; +} + +int eos_sdc_sect_write(uint32_t sect, unsigned int count, uint8_t *buffer) { + int rv; + + if (!(sdc_type & EOS_SDC_CAP_BLK)) sect *= 512; + + if (count == 1) { + sdc_select(); + rv = sdc_cmd(WRITE_BLOCK, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); + if (rv == SDC_R1_READY) { + eos_sdcc_encrypt(sect, buffer); + rv = sdc_block_write(SDC_TOKEN_START_BLK, buffer, 512, SDC_TIMEOUT_WRITE); + } else { + rv = SDC_ERR(rv); + } + sdc_deselect(); + } else { + if (sdc_type & EOS_SDC_TYPE_SDC) { + rv = sdc_acmd(SET_WR_BLK_ERASE_COUNT, count, 0, SDC_TIMEOUT_CMD); + if (rv != SDC_R1_READY) return SDC_ERR(rv); + } + + sdc_select(); + rv = sdc_cmd(WRITE_MULTIPLE_BLOCK, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); + if (rv == SDC_R1_READY) { + int _rv; + + while (count) { + eos_sdcc_encrypt(sect, buffer); + rv = sdc_block_write(SDC_TOKEN_START_BLKM, buffer, 512, SDC_TIMEOUT_WRITE); + if (rv) break; + buffer += 512; + count--; + } + _rv = sdc_block_write(SDC_TOKEN_STOP_TRAN, NULL, 0, SDC_TIMEOUT_WRITE); + if (!rv && (_rv != SDC_R1_READY)) rv = SDC_ERR(_rv); + } else { + rv = SDC_ERR(rv); + } + sdc_deselect(); + } + + return rv; +} diff --git a/fw/fe310/eos/dev/sdcard.h b/fw/fe310/eos/dev/sdcard.h new file mode 100644 index 0000000..910a6e0 --- /dev/null +++ b/fw/fe310/eos/dev/sdcard.h @@ -0,0 +1,22 @@ +#include + +#define EOS_SDC_TYPE_MMC 0x01 + +#define EOS_SDC_TYPE_SDC1 0x04 +#define EOS_SDC_TYPE_SDC2 0x08 +#define EOS_SDC_TYPE_SDC 0x0c +#define EOS_SDC_TYPE_MASK 0x0f + +#define EOS_SDC_CAP_BLK 0x10 +#define EOS_SDC_CAP_ERASE_EN 0x20 +#define EOS_SDC_CAP_MASK 0xf0 + +int eos_sdc_init(uint8_t wakeup_cause); +uint8_t eos_sdc_type(void); +uint8_t eos_sdc_cap(void); +int eos_sdc_get_sect_count(uint32_t timeout, uint32_t *sectors); +int eos_sdc_get_blk_size(uint32_t timeout, uint32_t *size); +int eos_sdc_sync(uint32_t timeout); +int eos_sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout); +int eos_sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer); +int eos_sdc_sect_write(uint32_t sect, unsigned int count, uint8_t *buffer); diff --git a/fw/fe310/eos/i2c.c b/fw/fe310/eos/i2c.c deleted file mode 100644 index a507af1..0000000 --- a/fw/fe310/eos/i2c.c +++ /dev/null @@ -1,145 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" -#include "prci_driver.h" - -#include "eos.h" -#include "i2s.h" -#include "i2c.h" - -int eos_i2c_init(uint8_t wakeup_cause) { - eos_i2c_speed(EOS_I2C_SPEED); - // eos_i2c_start(); - - return EOS_OK; -} - -void eos_i2c_start(void) { - I2C0_REGB(I2C_CONTROL) |= I2C_CONTROL_EN; - GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_I2C0_MASK; - GPIO_REG(GPIO_IOF_EN) |= IOF0_I2C0_MASK; -} - -void eos_i2c_stop(void) { - GPIO_REG(GPIO_IOF_EN) &= ~IOF0_I2C0_MASK; - I2C0_REGB(I2C_CONTROL) &= ~I2C_CONTROL_EN; -} - -void eos_i2c_speed(uint32_t baud_rate) { - unsigned long clock_rate = PRCI_get_cpu_freq(); - uint16_t prescaler = (clock_rate / (baud_rate * 5)) - 1; - - I2C0_REGB(I2C_PRESCALE_LOW) = prescaler & 0xFF; - I2C0_REGB(I2C_PRESCALE_HIGH) = (prescaler >> 8) & 0xFF; -} - - -static int i2c_read(uint8_t cmd) { - I2C0_REGB(I2C_COMMAND) = I2C_CMD_READ | cmd; - while (I2C0_REGB(I2C_STATUS) & I2C_STATUS_TIP); - - return I2C0_REGB(I2C_RECEIVE); -} - -static int i2c_write(uint8_t cmd, uint8_t b) { - I2C0_REGB(I2C_TRANSMIT) = b; - I2C0_REGB(I2C_COMMAND) = I2C_CMD_WRITE | cmd; - while (I2C0_REGB(I2C_STATUS) & I2C_STATUS_TIP); - - if (I2C0_REGB(I2C_STATUS) & I2C_STATUS_RXACK) return EOS_ERR; - return EOS_OK; -} - -static int i2c_addr(uint8_t addr, uint8_t rw_flag) { - return i2c_write(I2C_CMD_START, ((addr & 0x7F) << 1) | (rw_flag & 0x1)); -} - -int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t len) { - int rv; - int i; - - rv = i2c_addr(addr, I2C_WRITE); - if (rv) return rv; - - rv = i2c_write(0, reg); - if (rv) return rv; - - rv = i2c_addr(addr, I2C_READ); - if (rv) return rv; - - for (i=0; i> 8); - if (rv) return rv; - - rv = i2c_write(0, reg & 0xff); - if (rv) return rv; - - rv = i2c_addr(addr, I2C_READ); - if (rv) return rv; - - for (i=0; i> 8); - if (rv) return rv; - - rv = i2c_write(0, reg & 0xff); - if (rv) return rv; - - for (i=0; i - -#define EOS_I2C_SPEED 100000 - -int eos_i2c_init(uint8_t wakeup_cause); -int eos_i2c_run(uint8_t wakeup_cause); -void eos_i2c_start(void); -void eos_i2c_stop(void); -void eos_i2c_speed(uint32_t baud_rate); -int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t len); -int eos_i2c_read16(uint8_t addr, uint16_t reg, uint8_t *buffer, uint16_t len); -int eos_i2c_write8(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t len); -int eos_i2c_write16(uint8_t addr, uint16_t reg, uint8_t *buffer, uint16_t len); diff --git a/fw/fe310/eos/i2c/Makefile b/fw/fe310/eos/i2c/Makefile deleted file mode 100644 index 83cb1f5..0000000 --- a/fw/fe310/eos/i2c/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -include ../../common.mk -CFLAGS += -I$(bsp_dir)/include - -obj = bq25895.o ov2640.o gt911.o - - -%.o: %.c %.h - $(CC) $(CFLAGS) -c $< - -%.o: %.S - $(CC) $(CFLAGS) -c $< - -all: $(obj) - -clean: - rm -f *.o diff --git a/fw/fe310/eos/i2c/bq25895.c b/fw/fe310/eos/i2c/bq25895.c deleted file mode 100644 index b290926..0000000 --- a/fw/fe310/eos/i2c/bq25895.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "pwr.h" -#include "i2c.h" -#include "bq25895.h" - -static int reg_read(uint8_t reg, uint8_t *data) { - return eos_i2c_read8(BQ25895_ADDR, reg, data, 1); -} - -static int reg_write(uint8_t reg, uint8_t data) { - return eos_i2c_write8(BQ25895_ADDR, reg, &data, 1); -} - -int eos_bq25895_init(uint8_t wakeup_cause) { - int rst = (wakeup_cause == EOS_PWR_WAKE_RST); - int i, rv = EOS_OK; - uint8_t data = 0; - - if (rst) { - rv = reg_write(0x14, 0x80); // reset - if (rv) printf("I2C ERROR 0x14\n"); - rv = reg_write(0x14, 0x00); // disable watchdog - if (rv) printf("I2C ERROR 0x14\n"); - rv = reg_write(0x07, 0x8d); // disable watchdog - if (rv) printf("I2C ERROR 0x07\n"); - rv = reg_write(0x00, 0x28); // 2.1A input current - if (rv) printf("I2C ERROR 0x00\n"); - rv = reg_write(0x02, 0x30); // enable ICO, disaable MaxCharge and D+/D- - if (rv) printf("I2C ERROR 0x02\n"); - } - - printf("BQ25895:\n"); - for (i=0; i<0x15; i++) { - rv = reg_read(i, &data); - if (!rv) printf("REG%02x: %02x\n", i, data); - } - - return EOS_OK; -} diff --git a/fw/fe310/eos/i2c/bq25895.h b/fw/fe310/eos/i2c/bq25895.h deleted file mode 100644 index cbef36e..0000000 --- a/fw/fe310/eos/i2c/bq25895.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -#define BQ25895_ADDR 0x6A - -int eos_bq25895_init(uint8_t wakeup_cause); diff --git a/fw/fe310/eos/i2c/drv2605.h b/fw/fe310/eos/i2c/drv2605.h deleted file mode 100644 index fe90a9b..0000000 --- a/fw/fe310/eos/i2c/drv2605.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -#define DRV2605_ADDR 0x5A diff --git a/fw/fe310/eos/i2c/lsm9ds1.h b/fw/fe310/eos/i2c/lsm9ds1.h deleted file mode 100644 index 92220e7..0000000 --- a/fw/fe310/eos/i2c/lsm9ds1.h +++ /dev/null @@ -1,4 +0,0 @@ -#include - -#define LSM9DS1_ADDR_AG 0x1E -#define LSM9DS1_ADDR_M 0x6B diff --git a/fw/fe310/eos/i2c/ov2640.c b/fw/fe310/eos/i2c/ov2640.c deleted file mode 100644 index 6e54f10..0000000 --- a/fw/fe310/eos/i2c/ov2640.c +++ /dev/null @@ -1,861 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "timer.h" -#include "cam.h" - -#include "i2c.h" -#include "ov2640_regs.h" -#include "ov2640.h" - -#define XCLK_FREQ 24000000 -//#define XCLK_FREQ 12000000 - -#define CIF_WIDTH (400) -#define CIF_HEIGHT (296) - -#define SVGA_WIDTH (800) -#define SVGA_HEIGHT (600) - -#define UXGA_WIDTH (1600) -#define UXGA_HEIGHT (1200) - -static const uint8_t default_regs[][2] = { - -// From Linux Driver. - - {BANK_SEL, BANK_SEL_DSP}, - {0x2c, 0xff}, - {0x2e, 0xdf}, - {BANK_SEL, BANK_SEL_SENSOR}, - {0x3c, 0x32}, -// {CLKRC, CLKRC_DOUBLE | 0x02}, - {CLKRC, 0x01}, - {COM2, COM2_OUT_DRIVE_3x}, - {REG04, REG04_SET(REG04_HFLIP_IMG | REG04_VFLIP_IMG | REG04_VREF_EN | REG04_HREF_EN)}, - {COM8, COM8_SET(COM8_BNDF_EN | COM8_AGC_EN | COM8_AEC_EN)}, - {COM9, COM9_AGC_SET(COM9_AGC_GAIN_8x)}, - {0x2c, 0x0c}, - {0x33, 0x78}, - {0x3a, 0x33}, - {0x3b, 0xfb}, - {0x3e, 0x00}, - {0x43, 0x11}, - {0x16, 0x10}, - {0x39, 0x02}, - {0x35, 0x88}, - {0x22, 0x0a}, - {0x37, 0x40}, - {0x23, 0x00}, - {ARCOM2, 0xa0}, - {0x06, 0x02}, - {0x06, 0x88}, - {0x07, 0xc0}, - {0x0d, 0xb7}, - {0x0e, 0x01}, - {0x4c, 0x00}, - {0x4a, 0x81}, - {0x21, 0x99}, - {AEW, 0x40}, - {AEB, 0x38}, - {VV, VV_AGC_TH_SET(0x08, 0x02)}, - {0x5c, 0x00}, - {0x63, 0x00}, - {FLL, 0x22}, - {COM3, COM3_BAND_SET(COM3_BAND_AUTO)}, - {REG5D, 0x55}, - {REG5E, 0x7d}, - {REG5F, 0x7d}, - {REG60, 0x55}, - {HISTO_LOW, 0x70}, - {HISTO_HIGH, 0x80}, - {0x7c, 0x05}, - {0x20, 0x80}, - {0x28, 0x30}, - {0x6c, 0x00}, - {0x6d, 0x80}, - {0x6e, 0x00}, - {0x70, 0x02}, - {0x71, 0x94}, - {0x73, 0xc1}, - {0x3d, 0x34}, - {COM7, COM7_RES_UXGA | COM7_ZOOM_EN}, - {0x5a, 0x57}, - {COM25, 0x00}, - {BD50, 0xbb}, - {BD60, 0x9c}, - {BANK_SEL, BANK_SEL_DSP}, - {0xe5, 0x7f}, - {MC_BIST, MC_BIST_RESET | MC_BIST_BOOT_ROM_SEL}, - {0x41, 0x24}, - {RESET, RESET_JPEG | RESET_DVP}, - {0x76, 0xff}, - {0x33, 0xa0}, - {0x42, 0x20}, - {0x43, 0x18}, - {0x4c, 0x00}, - {CTRL3, CTRL3_BPC_EN | CTRL3_WPC_EN | 0x10}, - {0x88, 0x3f}, - {0xd7, 0x03}, - {0xd9, 0x10}, - {R_DVP_SP, R_DVP_SP_AUTO_MODE | 0x2}, - {0xc8, 0x08}, - {0xc9, 0x80}, - {BPADDR, 0x00}, - {BPDATA, 0x00}, - {BPADDR, 0x03}, - {BPDATA, 0x48}, - {BPDATA, 0x48}, - {BPADDR, 0x08}, - {BPDATA, 0x20}, - {BPDATA, 0x10}, - {BPDATA, 0x0e}, - {0x90, 0x00}, - {0x91, 0x0e}, - {0x91, 0x1a}, - {0x91, 0x31}, - {0x91, 0x5a}, - {0x91, 0x69}, - {0x91, 0x75}, - {0x91, 0x7e}, - {0x91, 0x88}, - {0x91, 0x8f}, - {0x91, 0x96}, - {0x91, 0xa3}, - {0x91, 0xaf}, - {0x91, 0xc4}, - {0x91, 0xd7}, - {0x91, 0xe8}, - {0x91, 0x20}, - {0x92, 0x00}, - {0x93, 0x06}, - {0x93, 0xe3}, - {0x93, 0x03}, - {0x93, 0x03}, - {0x93, 0x00}, - {0x93, 0x02}, - {0x93, 0x00}, - {0x93, 0x00}, - {0x93, 0x00}, - {0x93, 0x00}, - {0x93, 0x00}, - {0x93, 0x00}, - {0x93, 0x00}, - {0x96, 0x00}, - {0x97, 0x08}, - {0x97, 0x19}, - {0x97, 0x02}, - {0x97, 0x0c}, - {0x97, 0x24}, - {0x97, 0x30}, - {0x97, 0x28}, - {0x97, 0x26}, - {0x97, 0x02}, - {0x97, 0x98}, - {0x97, 0x80}, - {0x97, 0x00}, - {0x97, 0x00}, - {0xa4, 0x00}, - {0xa8, 0x00}, - {0xc5, 0x11}, - {0xc6, 0x51}, - {0xbf, 0x80}, - {0xc7, 0x10}, /* simple AWB */ - {0xb6, 0x66}, - {0xb8, 0xA5}, - {0xb7, 0x64}, - {0xb9, 0x7C}, - {0xb3, 0xaf}, - {0xb4, 0x97}, - {0xb5, 0xFF}, - {0xb0, 0xC5}, - {0xb1, 0x94}, - {0xb2, 0x0f}, - {0xc4, 0x5c}, - {0xa6, 0x00}, - {0xa7, 0x20}, - {0xa7, 0xd8}, - {0xa7, 0x1b}, - {0xa7, 0x31}, - {0xa7, 0x00}, - {0xa7, 0x18}, - {0xa7, 0x20}, - {0xa7, 0xd8}, - {0xa7, 0x19}, - {0xa7, 0x31}, - {0xa7, 0x00}, - {0xa7, 0x18}, - {0xa7, 0x20}, - {0xa7, 0xd8}, - {0xa7, 0x19}, - {0xa7, 0x31}, - {0xa7, 0x00}, - {0xa7, 0x18}, - {0x7f, 0x00}, - {0xe5, 0x1f}, - {0xe1, 0x77}, - {0xdd, 0x7f}, - {CTRL0, CTRL0_YUV422 | CTRL0_YUV_EN | CTRL0_RGB_EN}, - -// OpenMV Custom. - - {BANK_SEL, BANK_SEL_SENSOR}, - {0x0f, 0x4b}, - {COM1, 0x8f}, - -// End. - - {0xff, 0xff}, -}; - -// Looks really bad. -//static const uint8_t cif_regs[][2] = { -// {BANK_SEL, BANK_SEL_SENSOR}, -// {COM7, COM7_RES_CIF}, -// {COM1, 0x06 | 0x80}, -// {HSTART, 0x11}, -// {HSTOP, 0x43}, -// {VSTART, 0x01}, // 0x01 fixes issue with garbage pixels in the image... -// {VSTOP, 0x97}, -// {REG32, 0x09}, -// {BANK_SEL, BANK_SEL_DSP}, -// {RESET, RESET_DVP}, -// {SIZEL, SIZEL_HSIZE8_11_SET(CIF_WIDTH) | SIZEL_HSIZE8_SET(CIF_WIDTH) | SIZEL_VSIZE8_SET(CIF_HEIGHT)}, -// {HSIZE8, HSIZE8_SET(CIF_WIDTH)}, -// {VSIZE8, VSIZE8_SET(CIF_HEIGHT)}, -// {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, -// {0, 0}, -//}; - -static const uint8_t svga_regs[][2] = { - {BANK_SEL, BANK_SEL_SENSOR}, - {COM7, COM7_RES_SVGA}, - {COM1, 0x0A | 0x80}, - {HSTART, 0x11}, - {HSTOP, 0x43}, - {VSTART, 0x01}, // 0x01 fixes issue with garbage pixels in the image... - {VSTOP, 0x97}, - {REG32, 0x09}, - {BANK_SEL, BANK_SEL_DSP}, - {RESET, RESET_DVP}, - {SIZEL, SIZEL_HSIZE8_11_SET(SVGA_WIDTH) | SIZEL_HSIZE8_SET(SVGA_WIDTH) | SIZEL_VSIZE8_SET(SVGA_HEIGHT)}, - {HSIZE8, HSIZE8_SET(SVGA_WIDTH)}, - {VSIZE8, VSIZE8_SET(SVGA_HEIGHT)}, - {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, - {0xff, 0xff}, -}; - -static const uint8_t uxga_regs[][2] = { - {BANK_SEL, BANK_SEL_SENSOR}, - {COM7, COM7_RES_UXGA}, - {COM1, 0x0F | 0x80}, - {HSTART, 0x11}, - {HSTOP, 0x75}, - {VSTART, 0x01}, - {VSTOP, 0x97}, - {REG32, 0x36}, - {BANK_SEL, BANK_SEL_DSP}, - {RESET, RESET_DVP}, - {SIZEL, SIZEL_HSIZE8_11_SET(UXGA_WIDTH) | SIZEL_HSIZE8_SET(UXGA_WIDTH) | SIZEL_VSIZE8_SET(UXGA_HEIGHT)}, - {HSIZE8, HSIZE8_SET(UXGA_WIDTH)}, - {VSIZE8, VSIZE8_SET(UXGA_HEIGHT)}, - {CTRL2, CTRL2_DCW_EN | CTRL2_SDE_EN | CTRL2_UV_AVG_EN | CTRL2_CMX_EN | CTRL2_UV_ADJ_EN}, - {0xff, 0xff}, -}; - -static const uint8_t yuv422_regs[][2] = { - {BANK_SEL, BANK_SEL_DSP}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {IMAGE_MODE, IMAGE_MODE_YUV422}, - {0xd7, 0x03}, - {0x33, 0xa0}, - {0xe5, 0x1f}, - {0xe1, 0x67}, - {RESET, 0x00}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {0xff, 0xff}, -}; - -static const uint8_t rgb565_regs[][2] = { - {BANK_SEL, BANK_SEL_DSP}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {IMAGE_MODE, IMAGE_MODE_RGB565}, - {0xd7, 0x03}, - {RESET, 0x00}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {0xff, 0xff}, -}; - -static const uint8_t bayer_regs[][2] = { - {BANK_SEL, BANK_SEL_DSP}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {IMAGE_MODE, IMAGE_MODE_RAW10}, - {0xd7, 0x03}, - {RESET, 0x00}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {0xff, 0xff}, -}; - -static const uint8_t jpeg_regs[][2] = { - {BANK_SEL, BANK_SEL_DSP}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {IMAGE_MODE, IMAGE_MODE_JPEG_EN}, - {0xd7, 0x03}, - {RESET, 0x00}, - {R_BYPASS, R_BYPASS_DSP_EN}, - {0xff, 0xff}, -}; - -#define NUM_BRIGHTNESS_LEVELS (5) -static const uint8_t brightness_regs[NUM_BRIGHTNESS_LEVELS + 1][5] = { - {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA}, - {0x00, 0x04, 0x09, 0x00, 0x00}, /* -2 */ - {0x00, 0x04, 0x09, 0x10, 0x00}, /* -1 */ - {0x00, 0x04, 0x09, 0x20, 0x00}, /* 0 */ - {0x00, 0x04, 0x09, 0x30, 0x00}, /* +1 */ - {0x00, 0x04, 0x09, 0x40, 0x00}, /* +2 */ -}; - -#define NUM_CONTRAST_LEVELS (5) -static const uint8_t contrast_regs[NUM_CONTRAST_LEVELS + 1][7] = { - {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA, BPDATA, BPDATA}, - {0x00, 0x04, 0x07, 0x20, 0x18, 0x34, 0x06}, /* -2 */ - {0x00, 0x04, 0x07, 0x20, 0x1c, 0x2a, 0x06}, /* -1 */ - {0x00, 0x04, 0x07, 0x20, 0x20, 0x20, 0x06}, /* 0 */ - {0x00, 0x04, 0x07, 0x20, 0x24, 0x16, 0x06}, /* +1 */ - {0x00, 0x04, 0x07, 0x20, 0x28, 0x0c, 0x06}, /* +2 */ -}; - -#define NUM_SATURATION_LEVELS (5) -static const uint8_t saturation_regs[NUM_SATURATION_LEVELS + 1][5] = { - {BPADDR, BPDATA, BPADDR, BPDATA, BPDATA}, - {0x00, 0x02, 0x03, 0x28, 0x28}, /* -2 */ - {0x00, 0x02, 0x03, 0x38, 0x38}, /* -1 */ - {0x00, 0x02, 0x03, 0x48, 0x48}, /* 0 */ - {0x00, 0x02, 0x03, 0x58, 0x58}, /* +1 */ - {0x00, 0x02, 0x03, 0x68, 0x68}, /* +2 */ -}; - -static int reg_read(int8_t reg, uint8_t *data) { - return eos_i2c_read8(OV2640_ADDR, reg, data, 1); -} - -static int reg_write(uint8_t reg, uint8_t data) { - return eos_i2c_write8(OV2640_ADDR, reg, &data, 1); -} - -static int regarr_write(const uint8_t (*regs)[2]) { - int i, rv; - - i = 0; - rv = EOS_OK; - - while ((regs[i][0] != 0xff) || (regs[i][1] != 0xff)) { - if (!rv) rv = reg_write(regs[i][0], regs[i][1]); - i++; - } - - return rv; -} - -int eos_ov2640_init(void) { - int rv; - - // Reset all registers - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_write(COM7, COM7_SRST); - if (rv) return rv; - - // Delay 5 ms - eos_time_sleep(5); - - // Write default regsiters - rv = regarr_write(default_regs); - if (rv) return rv; - - // Delay 300 ms - eos_time_sleep(300); - - return EOS_OK; -} - -int eos_ov2640_sleep(int enable) { - uint8_t reg; - int rv; - - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_read(COM2, ®); - if (rv) return rv; - - if (enable) { - reg |= COM2_STDBY; - } else { - reg &= ~COM2_STDBY; - } - - // Write back register - return reg_write(COM2, reg); -} - -int eos_ov2640_set_pixfmt(pixformat_t fmt) { - const uint8_t (*regs)[2]; - - switch (fmt) { - case PIXFORMAT_RGB565: - regs = rgb565_regs; - break; - case PIXFORMAT_YUV422: - case PIXFORMAT_GRAYSCALE: - regs = yuv422_regs; - break; - case PIXFORMAT_BAYER: - regs = bayer_regs; - break; - case PIXFORMAT_JPEG: - regs = jpeg_regs; - break; - default: - return EOS_ERR; - } - - return regarr_write(regs); -} - -int eos_ov2640_set_framesize(framesize_t framesize) { - const uint8_t (*regs)[2]; - uint16_t sensor_w = 0; - uint16_t sensor_h = 0; - uint16_t w = _eos_cam_resolution[framesize][0]; - uint16_t h = _eos_cam_resolution[framesize][1]; - int rv; - - if ((w % 4) || (h % 4) || (w > UXGA_WIDTH) || (h > UXGA_HEIGHT)) { // w/h must be divisble by 4 - return EOS_ERR; - } - - // Looks really bad. - /* if ((w <= CIF_WIDTH) && (h <= CIF_HEIGHT)) { - regs = cif_regs; - sensor_w = CIF_WIDTH; - sensor_h = CIF_HEIGHT; - } else */ if ((w <= SVGA_WIDTH) && (h <= SVGA_HEIGHT)) { - regs = svga_regs; - sensor_w = SVGA_WIDTH; - sensor_h = SVGA_HEIGHT; - } else { - regs = uxga_regs; - sensor_w = UXGA_WIDTH; - sensor_h = UXGA_HEIGHT; - } - - // Write setup regsiters - rv = regarr_write(regs); - if (rv) return rv; - - uint64_t tmp_div = IM_MIN(sensor_w / w, sensor_h / h); - uint16_t log_div = IM_MIN(IM_LOG2(tmp_div) - 1, 3); - uint16_t div = 1 << log_div; - uint16_t w_mul = w * div; - uint16_t h_mul = h * div; - uint16_t x_off = (sensor_w - w_mul) / 2; - uint16_t y_off = (sensor_h - h_mul) / 2; - - rv = EOS_OK; - if (!rv) rv = reg_write(CTRLI, CTRLI_LP_DP | CTRLI_V_DIV_SET(log_div) | CTRLI_H_DIV_SET(log_div)); - if (!rv) rv = reg_write(HSIZE, HSIZE_SET(w_mul)); - if (!rv) rv = reg_write(VSIZE, VSIZE_SET(h_mul)); - if (!rv) rv = reg_write(XOFFL, XOFFL_SET(x_off)); - if (!rv) rv = reg_write(YOFFL, YOFFL_SET(y_off)); - if (!rv) rv = reg_write(VHYX, VHYX_HSIZE_SET(w_mul) | VHYX_VSIZE_SET(h_mul) | VHYX_XOFF_SET(x_off) | VHYX_YOFF_SET(y_off)); - if (!rv) rv = reg_write(TEST, TEST_HSIZE_SET(w_mul)); - if (!rv) rv = reg_write(ZMOW, ZMOW_OUTW_SET(w)); - if (!rv) rv = reg_write(ZMOH, ZMOH_OUTH_SET(h)); - if (!rv) rv = reg_write(ZMHH, ZMHH_OUTW_SET(w) | ZMHH_OUTH_SET(h)); - if (!rv) rv = reg_write(R_DVP_SP, div); - if (!rv) rv = reg_write(RESET, 0x00); - - return rv; -} - -int eos_ov2640_set_contrast(int level) { - int rv = EOS_OK; - - level += (NUM_CONTRAST_LEVELS / 2) + 1; - if (level <= 0 || level > NUM_CONTRAST_LEVELS) { - return EOS_ERR; - } - - /* Switch to DSP register bank */ - rv = reg_write(BANK_SEL, BANK_SEL_DSP); - - /* Write contrast registers */ - for (int i=0; i NUM_BRIGHTNESS_LEVELS) { - return EOS_ERR; - } - - /* Switch to DSP register bank */ - rv = reg_write(BANK_SEL, BANK_SEL_DSP); - - /* Write brightness registers */ - for (int i=0; i NUM_SATURATION_LEVELS) { - return EOS_ERR; - } - - /* Switch to DSP register bank */ - rv = reg_write(BANK_SEL, BANK_SEL_DSP); - - /* Write saturation registers */ - for (int i=0; i> (4 - gain_temp); - int gain_lo = IM_MIN(roundf(((gain / (1 << gain_temp)) - 1.0) * 16.0), 15); - - if (!rv) rv = reg_write(GAIN, (gain_hi << 4) | (gain_lo << 0)); - } - - return rv; -} - -int eos_ov2640_get_gain_db(float *gain_db) { - int rv = EOS_OK; - uint8_t reg, gain; - - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_read(COM8, ®); - if (rv) return rv; - - // DISABLED - // if (reg & COM8_AGC_EN) { - // rv = reg_write(COM8, reg & (~COM8_AGC_EN)); - // if (rv) return rv; - // } - // DISABLED - - rv = reg_read(GAIN, &gain); - if (rv) return rv; - - // DISABLED - // if (reg & COM8_AGC_EN) { - // rv = reg_write(COM8, reg | COM8_AGC_EN); - // if (rv) return rv; - // } - // DISABLED - - int hi_gain = 1 << (((gain >> 7) & 1) + ((gain >> 6) & 1) + ((gain >> 5) & 1) + ((gain >> 4) & 1)); - float lo_gain = 1.0 + (((gain >> 0) & 0xF) / 16.0); - *gain_db = 20.0 * (logf(hi_gain * lo_gain) / logf(10.0)); - - return EOS_OK; -} - -int eos_ov2640_set_auto_exposure(int enable, int exposure_us) { - int rv = EOS_OK; - uint8_t reg; - - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_read(COM8, ®); - if (rv) return rv; - - rv = reg_write(COM8, COM8_SET_AEC(reg, (enable != 0))); - if (rv) return rv; - - if (!enable && (exposure_us >= 0)) { - rv = reg_read(COM7, ®); - if (rv) return rv; - - int t_line = 0; - - if (COM7_GET_RES(reg) == COM7_RES_UXGA) t_line = 1600 + 322; - if (COM7_GET_RES(reg) == COM7_RES_SVGA) t_line = 800 + 390; - if (COM7_GET_RES(reg) == COM7_RES_CIF) t_line = 400 + 195; - - rv = reg_read(CLKRC, ®); - if (rv) return rv; - - int pll_mult = ((reg & CLKRC_DOUBLE) ? 2 : 1) * 3; - int clk_rc = (reg & CLKRC_DIVIDER_MASK) + 2; - - rv = reg_write(BANK_SEL, BANK_SEL_DSP); - if (rv) return rv; - - rv = reg_read(IMAGE_MODE, ®); - if (rv) return rv; - - int t_pclk = 0; - - if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_YUV422) t_pclk = 2; - if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RAW10) t_pclk = 1; - if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RGB565) t_pclk = 2; - - int exposure = IM_MAX(IM_MIN(((exposure_us*(((XCLK_FREQ/clk_rc)*pll_mult)/1000000))/t_pclk)/t_line,0xFFFF),0x0000); - - if (!rv) rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - - if (!rv) rv = reg_read(REG04, ®); - if (!rv) rv = reg_write(REG04, (reg & 0xFC) | ((exposure >> 0) & 0x3)); - - if (!rv) rv = reg_read(AEC, ®); - if (!rv) rv = reg_write(AEC, (reg & 0x00) | ((exposure >> 2) & 0xFF)); - - if (!rv) rv = reg_read(REG45, ®); - if (!rv) rv = reg_write(REG45, (reg & 0xC0) | ((exposure >> 10) & 0x3F)); - } - - return rv; -} - -int eos_ov2640_get_exposure_us(int *exposure_us) { - int rv = EOS_OK; - uint8_t reg, aec_10, aec_92, aec_1510; - - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_read(COM8, ®); - if (rv) return rv; - - // DISABLED - // if (reg & COM8_AEC_EN) { - // rv = reg_write(COM8, reg & (~COM8_AEC_EN)); - // if (rv) return rv; - // } - // DISABLED - - rv = reg_read(REG04, &aec_10); - if (rv) return rv; - - rv = reg_read(AEC, &aec_92); - if (rv) return rv; - - rv = reg_read(REG45, &aec_1510); - if (rv) return rv; - - // DISABLED - // if (reg & COM8_AEC_EN) { - // rv = reg_write(COM8, reg | COM8_AEC_EN); - // if (rv) return rv; - // } - // DISABLED - - rv = reg_read(COM7, ®); - if (rv) return rv; - - int t_line = 0; - - if (COM7_GET_RES(reg) == COM7_RES_UXGA) t_line = 1600 + 322; - if (COM7_GET_RES(reg) == COM7_RES_SVGA) t_line = 800 + 390; - if (COM7_GET_RES(reg) == COM7_RES_CIF) t_line = 400 + 195; - - rv = reg_read(CLKRC, ®); - if (rv) return rv; - - int pll_mult = ((reg & CLKRC_DOUBLE) ? 2 : 1) * 3; - int clk_rc = (reg & CLKRC_DIVIDER_MASK) + 2; - - rv = reg_write(BANK_SEL, BANK_SEL_DSP); - if (rv) return rv; - - rv = reg_read(IMAGE_MODE, ®); - if (rv) return rv; - - int t_pclk = 0; - - if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_YUV422) t_pclk = 2; - if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RAW10) t_pclk = 1; - if (IMAGE_MODE_GET_FMT(reg) == IMAGE_MODE_RGB565) t_pclk = 2; - - uint16_t exposure = ((aec_1510 & 0x3F) << 10) + ((aec_92 & 0xFF) << 2) + ((aec_10 & 0x3) << 0); - *exposure_us = (exposure*t_line*t_pclk)/(((XCLK_FREQ/clk_rc)*pll_mult)/1000000); - - return EOS_OK; -} - -int eos_ov2640_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db) { - int rv = EOS_OK; - uint8_t reg; - - rv = reg_write(BANK_SEL, BANK_SEL_DSP); - if (rv) return rv; - - rv = reg_read(CTRL1, ®); - if (rv) return rv; - - rv = reg_write(CTRL1, (reg & (~CTRL1_AWB)) | (enable ? CTRL1_AWB : 0)); - if (rv) return rv; - - if (!enable && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db)) - && (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) { - } - - return rv; -} - -int eos_ov2640_set_hmirror(int enable) { - int rv = EOS_OK; - uint8_t reg; - - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_read(REG04, ®); - if (rv) return rv; - - if (!enable) { // Already mirrored. - reg |= REG04_HFLIP_IMG; - } else { - reg &= ~REG04_HFLIP_IMG; - } - - return reg_write(REG04, reg); -} - -int eos_ov2640_set_vflip(int enable) { - int rv = EOS_OK; - uint8_t reg; - - rv = reg_write(BANK_SEL, BANK_SEL_SENSOR); - if (rv) return rv; - - rv = reg_read(REG04, ®); - if (rv) return rv; - - if (!enable) { // Already flipped. - reg |= REG04_VFLIP_IMG | REG04_VREF_EN; - } else { - reg &= ~(REG04_VFLIP_IMG | REG04_VREF_EN); - } - - return reg_write(REG04, reg); -} - -int eos_ov2640_set_effect(sde_t sde) { - int rv = EOS_OK; - - switch (sde) { - case SDE_NEGATIVE: - if (!rv) rv = reg_write(BANK_SEL, BANK_SEL_DSP); - if (!rv) rv = reg_write(BPADDR, 0x00); - if (!rv) rv = reg_write(BPDATA, 0x40); - if (!rv) rv = reg_write(BPADDR, 0x05); - if (!rv) rv = reg_write(BPDATA, 0x80); - if (!rv) rv = reg_write(BPDATA, 0x80); - break; - case SDE_NORMAL: - if (!rv) rv = reg_write(BANK_SEL, BANK_SEL_DSP); - if (!rv) rv = reg_write(BPADDR, 0x00); - if (!rv) rv = reg_write(BPDATA, 0x00); - if (!rv) rv = reg_write(BPADDR, 0x05); - if (!rv) rv = reg_write(BPDATA, 0x80); - if (!rv) rv = reg_write(BPDATA, 0x80); - break; - default: - return EOS_ERR; - } - - return rv; -} diff --git a/fw/fe310/eos/i2c/ov2640.h b/fw/fe310/eos/i2c/ov2640.h deleted file mode 100644 index 3d08c2a..0000000 --- a/fw/fe310/eos/i2c/ov2640.h +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#define OV2640_ADDR 0x30 - -int eos_ov2640_init(void); -int eos_ov2640_sleep(int enable); -int eos_ov2640_set_pixfmt(pixformat_t fmt); -int eos_ov2640_set_framesize(framesize_t framesize); diff --git a/fw/fe310/eos/i2c/ov2640_regs.h b/fw/fe310/eos/i2c/ov2640_regs.h deleted file mode 100644 index deb7521..0000000 --- a/fw/fe310/eos/i2c/ov2640_regs.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * This file is part of the OpenMV project. - * - * Copyright (c) 2013-2021 Ibrahim Abdelkader - * Copyright (c) 2013-2021 Kwabena W. Agyeman - * - * This work is licensed under the MIT license, see the file LICENSE for details. - * - * OV2640 register definitions. - */ -#ifndef __REG_REGS_H__ -#define __REG_REGS_H__ - -/* DSP register bank FF=0x00*/ - -#define QS 0x44 -#define HSIZE 0x51 -#define VSIZE 0x52 -#define XOFFL 0x53 -#define YOFFL 0x54 -#define VHYX 0x55 -#define DPRP 0x56 -#define TEST 0x57 -#define ZMOW 0x5A -#define ZMOH 0x5B -#define ZMHH 0x5C -#define BPADDR 0x7C -#define BPDATA 0x7D -#define SIZEL 0x8C -#define HSIZE8 0xC0 -#define VSIZE8 0xC1 -#define CTRL1 0xC3 -#define MS_SP 0xF0 -#define SS_ID 0xF7 -#define SS_CTRL 0xF7 -#define MC_AL 0xFA -#define MC_AH 0xFB -#define MC_D 0xFC -#define P_CMD 0xFD -#define P_STATUS 0xFE - -#define CTRLI 0x50 -#define CTRLI_LP_DP 0x80 -#define CTRLI_ROUND 0x40 - -#define CTRL0 0xC2 -#define CTRL0_AEC_EN 0x80 -#define CTRL0_AEC_SEL 0x40 -#define CTRL0_STAT_SEL 0x20 -#define CTRL0_VFIRST 0x10 -#define CTRL0_YUV422 0x08 -#define CTRL0_YUV_EN 0x04 -#define CTRL0_RGB_EN 0x02 -#define CTRL0_RAW_EN 0x01 - -#define CTRL2 0x86 -#define CTRL2_DCW_EN 0x20 -#define CTRL2_SDE_EN 0x10 -#define CTRL2_UV_ADJ_EN 0x08 -#define CTRL2_UV_AVG_EN 0x04 -#define CTRL2_CMX_EN 0x01 - -#define CTRL3 0x87 -#define CTRL3_BPC_EN 0x80 -#define CTRL3_WPC_EN 0x40 -#define R_DVP_SP 0xD3 -#define R_DVP_SP_AUTO_MODE 0x80 - -#define R_BYPASS 0x05 -#define R_BYPASS_DSP_EN 0x00 -#define R_BYPASS_DSP_BYPAS 0x01 - -#define IMAGE_MODE 0xDA -#define IMAGE_MODE_Y8_DVP_EN 0x40 -#define IMAGE_MODE_JPEG_EN 0x10 -#define IMAGE_MODE_YUV422 0x00 -#define IMAGE_MODE_RAW10 0x04 -#define IMAGE_MODE_RGB565 0x09 -#define IMAGE_MODE_HREF_VSYNC 0x02 -#define IMAGE_MODE_LBYTE_FIRST 0x01 -#define IMAGE_MODE_GET_FMT(x) ((x)&0xC) - -#define RESET 0xE0 -#define RESET_MICROC 0x40 -#define RESET_SCCB 0x20 -#define RESET_JPEG 0x10 -#define RESET_DVP 0x04 -#define RESET_IPU 0x02 -#define RESET_CIF 0x01 - -#define MC_BIST 0xF9 -#define MC_BIST_RESET 0x80 -#define MC_BIST_BOOT_ROM_SEL 0x40 -#define MC_BIST_12KB_SEL 0x20 -#define MC_BIST_12KB_MASK 0x30 -#define MC_BIST_512KB_SEL 0x08 -#define MC_BIST_512KB_MASK 0x0C -#define MC_BIST_BUSY_BIT_R 0x02 -#define MC_BIST_MC_RES_ONE_SH_W 0x02 -#define MC_BIST_LAUNCH 0x01 - -#define BANK_SEL 0xFF -#define BANK_SEL_DSP 0x00 -#define BANK_SEL_SENSOR 0x01 - -/* Sensor register bank FF=0x01*/ - -#define GAIN 0x00 -#define COM1 0x03 -#define REG_PID 0x0A -#define REG_VER 0x0B -#define COM4 0x0D -#define AEC 0x10 - -#define CLKRC 0x11 -#define CLKRC_DOUBLE 0x80 -#define CLKRC_DIVIDER_MASK 0x3F - -#define COM10 0x15 -#define HSTART 0x17 -#define HSTOP 0x18 -#define VSTART 0x19 -#define VSTOP 0x1A -#define MIDH 0x1C -#define MIDL 0x1D -#define AEW 0x24 -#define AEB 0x25 -#define REG2A 0x2A -#define FRARL 0x2B -#define ADDVSL 0x2D -#define ADDVSH 0x2E -#define YAVG 0x2F -#define HSDY 0x30 -#define HEDY 0x31 -#define ARCOM2 0x34 -#define REG45 0x45 -#define FLL 0x46 -#define FLH 0x47 -#define COM19 0x48 -#define ZOOMS 0x49 -#define COM22 0x4B -#define COM25 0x4E -#define BD50 0x4F -#define BD60 0x50 -#define REG5D 0x5D -#define REG5E 0x5E -#define REG5F 0x5F -#define REG60 0x60 -#define HISTO_LOW 0x61 -#define HISTO_HIGH 0x62 - -#define REG04 0x04 -#define REG04_DEFAULT 0x28 -#define REG04_HFLIP_IMG 0x80 -#define REG04_VFLIP_IMG 0x40 -#define REG04_VREF_EN 0x10 -#define REG04_HREF_EN 0x08 -#define REG04_SET(x) (REG04_DEFAULT|x) - -#define REG08 0x08 -#define COM2 0x09 -#define COM2_STDBY 0x10 -#define COM2_OUT_DRIVE_1x 0x00 -#define COM2_OUT_DRIVE_2x 0x01 -#define COM2_OUT_DRIVE_3x 0x02 -#define COM2_OUT_DRIVE_4x 0x03 - -#define COM3 0x0C -#define COM3_DEFAULT 0x38 -#define COM3_BAND_50Hz 0x04 -#define COM3_BAND_60Hz 0x00 -#define COM3_BAND_AUTO 0x02 -#define COM3_BAND_SET(x) (COM3_DEFAULT|x) - -#define COM7 0x12 -#define COM7_SRST 0x80 -#define COM7_RES_UXGA 0x00 /* UXGA */ -#define COM7_RES_SVGA 0x40 /* SVGA */ -#define COM7_RES_CIF 0x20 /* CIF */ -#define COM7_ZOOM_EN 0x04 /* Enable Zoom */ -#define COM7_COLOR_BAR 0x02 /* Enable Color Bar Test */ -#define COM7_GET_RES(x) ((x)&0x70) - -#define COM8 0x13 -#define COM8_DEFAULT 0xC0 -#define COM8_BNDF_EN 0x20 /* Enable Banding filter */ -#define COM8_AGC_EN 0x04 /* AGC Auto/Manual control selection */ -#define COM8_AEC_EN 0x01 /* Auto/Manual Exposure control */ -#define COM8_SET(x) (COM8_DEFAULT|x) -#define COM8_SET_AEC(r,x) (((r)&0xFE)|((x)&1)) - -#define COM9 0x14 /* AGC gain ceiling */ -#define COM9_DEFAULT 0x08 -#define COM9_AGC_GAIN_2x 0x00 /* AGC: 2x */ -#define COM9_AGC_GAIN_4x 0x01 /* AGC: 4x */ -#define COM9_AGC_GAIN_8x 0x02 /* AGC: 8x */ -#define COM9_AGC_GAIN_16x 0x03 /* AGC: 16x */ -#define COM9_AGC_GAIN_32x 0x04 /* AGC: 32x */ -#define COM9_AGC_GAIN_64x 0x05 /* AGC: 64x */ -#define COM9_AGC_GAIN_128x 0x06 /* AGC: 128x */ -#define COM9_AGC_SET(x) (COM9_DEFAULT|(x<<5)) - -#define CTRL1_AWB 0x08 /* Enable AWB */ - -#define VV 0x26 -#define VV_AGC_TH_SET(h,l) ((h<<4)|(l&0x0F)) - -#define REG32 0x32 -#define REG32_UXGA 0x36 -#define REG32_SVGA 0x09 -#define REG32_CIF 0x00 - -#define VAL_SET(x, mask, rshift, lshift) ((((x) >> rshift) & mask) << lshift) - -#define CTRLI_V_DIV_SET(x) VAL_SET(x, 0x3, 0, 3) -#define CTRLI_H_DIV_SET(x) VAL_SET(x, 0x3, 0, 0) - -#define SIZEL_HSIZE8_11_SET(x) VAL_SET(x, 0x1, 11, 6) -#define SIZEL_HSIZE8_SET(x) VAL_SET(x, 0x7, 0, 3) -#define SIZEL_VSIZE8_SET(x) VAL_SET(x, 0x7, 0, 0) - -#define HSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) -#define VSIZE8_SET(x) VAL_SET(x, 0xFF, 3, 0) - -#define HSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) -#define VSIZE_SET(x) VAL_SET(x, 0xFF, 2, 0) - -#define XOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) -#define YOFFL_SET(x) VAL_SET(x, 0xFF, 0, 0) - -#define VHYX_VSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 7) -#define VHYX_HSIZE_SET(x) VAL_SET(x, 0x1, (8+2), 3) -#define VHYX_YOFF_SET(x) VAL_SET(x, 0x3, 8, 4) -#define VHYX_XOFF_SET(x) VAL_SET(x, 0x3, 8, 0) - -#define TEST_HSIZE_SET(x) VAL_SET(x, 0x1, (9+2), 7) - -#define ZMOW_OUTW_SET(x) VAL_SET(x, 0xFF, 2, 0) -#define ZMOH_OUTH_SET(x) VAL_SET(x, 0xFF, 2, 0) - -#define ZMHH_ZSPEED_SET(x) VAL_SET(x, 0x0F, 0, 4) -#define ZMHH_OUTH_SET(x) VAL_SET(x, 0x1, (8+2), 2) -#define ZMHH_OUTW_SET(x) VAL_SET(x, 0x3, (8+2), 0) - -#endif //__REG_REGS_H__ diff --git a/fw/fe310/eos/i2s.c b/fw/fe310/eos/i2s.c deleted file mode 100644 index 9cc9d9c..0000000 --- a/fw/fe310/eos/i2s.c +++ /dev/null @@ -1,477 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" -#include "prci_driver.h" - -#include "eos.h" -#include "interrupt.h" -#include "event.h" - -#include "board.h" - -#include "i2s.h" -#include "i2s_priv.h" - -#define I2S_REG_CK(o) _REG32(I2S_CTRL_ADDR_CK, o) -#define I2S_REG_WS_MIC(o) _REG32(I2S_CTRL_ADDR_WS_MIC, o) -#define I2S_REG_WS_SPK(o) _REG32(I2S_CTRL_ADDR_WS_SPK, o) - -#define I2S_PIN_PWM ((1 << I2S_PIN_CK) | (1 << I2S_PIN_CK_SW) | (1 << I2S_PIN_WS_MIC) | (1 << I2S_PIN_WS_SPK)) - -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) - -#define EOS_ABUF_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) - -EOSABuf i2s_mic_buf; -EOSABuf i2s_spk_buf; - -static eos_i2s_handler_t i2s_mic_handler = NULL; -static eos_i2s_handler_t i2s_spk_handler = NULL; -static uint32_t i2s_clk_period; -static uint8_t i2s_mic_volume = 0; /* 0 - 8 */ -static uint8_t i2s_spk_volume = 16; /* 0 - 16 */ - -uint32_t _eos_i2s_drvr[] = { - 0, /* I2S_MIC_BUF */ - 0, /* I2S_SPK_BUF */ - EOS_I2S_FMT_PCM16, /* I2S_FMT */ - EOS_I2S_MODE_STEREO, /* I2S_MODE */ - 0, /* I2S_MIC_WM */ - 0, /* I2S_SPK_WM */ - 0, /* I2S_MIC_EVT */ - 0, /* I2S_SPK_EVT */ - 0, /* I2S_MIC_CMP2 */ - 0, /* I2S_MIC_CMP3 */ - 0, /* I2S_SAMPLE */ -}; - -#define I2S_MIC_BUF 0 -#define I2S_SPK_BUF 1 -#define I2S_FMT 2 -#define I2S_MODE 3 -#define I2S_MIC_WM 4 -#define I2S_SPK_WM 5 -#define I2S_MIC_EVT 6 -#define I2S_SPK_EVT 7 -#define I2S_MIC_CMP2 8 -#define I2S_MIC_CMP3 9 -#define I2S_SAMPLE 10 - -static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { - buf->idx_r = 0; - buf->idx_w = 0; - buf->size = size; - buf->array = array; -} - -static int _abuf_push8(EOSABuf *buf, uint8_t sample) { - if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL; - - buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample; - buf->idx_w++; - return EOS_OK; -} - -static int _abuf_push16(EOSABuf *buf, uint16_t sample) { - if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL; - - buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample >> 8; - buf->array[EOS_ABUF_IDX_MASK(buf->idx_w + 1, buf->size)] = sample & 0xFF; - buf->idx_w += 2; - return EOS_OK; -} - -static int _abuf_pop8(EOSABuf *buf, uint8_t *sample) { - if (buf->idx_r == buf->idx_w) { - return EOS_ERR_EMPTY; - } else { - *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)]; - buf->idx_r++; - return EOS_OK; - } -} - -static int _abuf_pop16(EOSABuf *buf, uint16_t *sample) { - if (buf->idx_r == buf->idx_w) { - return EOS_ERR_EMPTY; - } else { - *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)] << 8; - *sample |= buf->array[EOS_ABUF_IDX_MASK(buf->idx_r + 1, buf->size)]; - buf->idx_r += 2; - return EOS_OK; - } -} - -static void _abuf_flush(EOSABuf *buf) { - buf->idx_r = 0; - buf->idx_w = 0; -} - -static uint16_t _abuf_len(EOSABuf *buf) { - return buf->idx_w - buf->idx_r; -} - -static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - switch(type & ~EOS_EVT_MASK) { - case EOS_I2S_ETYPE_MIC: - if (i2s_mic_handler) { - i2s_mic_handler(type); - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_MIC_EVT] = 1; - set_csr(mstatus, MSTATUS_MIE); - } - break; - - case EOS_I2S_ETYPE_SPK: - if (i2s_spk_handler) { - i2s_spk_handler(type); - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_SPK_EVT] = 1; - set_csr(mstatus, MSTATUS_MIE); - } - break; - - default: - eos_evtq_bad_handler(type, buffer, len); - break; - } -} - -#define PLIC_PRIORITY 0x0C000000 - -static void i2s_cmp_set(void) { - int c = 7; /* interrupt will trigger c i2s clocks before spk ws */ - int spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; - volatile uint32_t *p = (uint32_t *)PLIC_PRIORITY+I2S_IRQ_SD_ID; - - /* interrupt trigger - will start with left channel */ - if (spk_ws_offset - c < 0) { - I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (64 + spk_ws_offset - c); - } else { - I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (spk_ws_offset - c); - } - - /* disable interrupt for this cycle */ - *p = 0; - - /* empty buffers */ - // i2s_mic_buf.idx_r = i2s_mic_buf.idx_w; - // i2s_spk_buf.idx_w = i2s_spk_buf.idx_r; - - /* adjust spk ws relative to mic ws */ - if (spk_ws_offset <= 0) { - spk_ws_offset += 32; - GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); - } else { - GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << I2S_PIN_WS_SPK); - } - I2S_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * spk_ws_offset; - I2S_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (32 + spk_ws_offset); - - /* mic cmp2 relative to interrupt trigger */ - _eos_i2s_drvr[I2S_MIC_CMP2] = (17 + c - i2s_spk_volume) * i2s_clk_period; /* (17 + c - i2s_spk_volume) == (1 + i2s_mic_volume) - (spk_ws_offset - c) */ - _eos_i2s_drvr[I2S_MIC_CMP3] = 16 * i2s_clk_period; -} - -extern void _eos_i2s_start_pwm(void); - -int eos_i2s_init(uint8_t wakeup_cause) { - eos_evtq_set_handler(EOS_EVT_I2S, i2s_handle_evt); - - I2S_REG_CK(PWM_CFG) = 0; - I2S_REG_WS_MIC(PWM_CFG) = 0; - I2S_REG_WS_SPK(PWM_CFG) = 0; - - eos_i2s_init_mux(); - - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SW); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_CK_SR); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK_SW); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK_SW); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK_SR); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK_SR); - - return EOS_OK; -} - -void eos_i2s_init_mux(void) { - GPIO_REG(GPIO_OUTPUT_VAL) &= ~((1 << I2S_PIN_CK) | (1 << I2S_PIN_WS_MIC) | (1 << I2S_PIN_WS_SPK)); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_SPK); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_SPK); - - GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_IN); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); -} - -void eos_i2s_start(uint32_t sample_rate) { - i2s_clk_period = ((PRCI_get_cpu_freq() / (sample_rate * 64)) & ~I2S_PWM_SCALE_CK_MASK) + 1; - - GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_IN); - - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); - GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); - - I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> I2S_PWM_SCALE_CK; - I2S_REG_CK(PWM_CMP1) = I2S_REG_CK(PWM_CMP0) / 2; - I2S_REG_CK(PWM_CMP2) = 0; - I2S_REG_CK(PWM_CMP3) = 0; - - I2S_REG_WS_MIC(PWM_CMP0) = i2s_clk_period * 64 - 1; - I2S_REG_WS_MIC(PWM_CMP1) = i2s_clk_period * 32; - - I2S_REG_WS_SPK(PWM_CMP0) = i2s_clk_period * 64 - 1; - i2s_cmp_set(); - - I2S_REG_CK(PWM_COUNT) = 0; - I2S_REG_WS_MIC(PWM_COUNT) = 0; - I2S_REG_WS_SPK(PWM_COUNT) = i2s_clk_period / 2; - - if (i2s_mic_buf.array && i2s_mic_buf.size) { - _eos_i2s_drvr[I2S_MIC_BUF] = (uint32_t)&i2s_mic_buf; - if (_eos_i2s_drvr[I2S_MIC_WM] == 0) { - _eos_i2s_drvr[I2S_MIC_WM] = i2s_mic_buf.size / 2; - } - } - if (i2s_spk_buf.array && i2s_spk_buf.size) { - _eos_i2s_drvr[I2S_SPK_BUF] = (uint32_t)&i2s_spk_buf; - if (_eos_i2s_drvr[I2S_SPK_WM] == 0) { - _eos_i2s_drvr[I2S_SPK_WM] = i2s_spk_buf.size / 2; - } - } - if (i2s_mic_handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1; - if (i2s_spk_handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1; - - eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD); - eos_intr_set_priority(I2S_IRQ_WS_ID, IRQ_PRIORITY_I2S_WS); - eos_intr_enable(I2S_IRQ_SD_ID); - eos_intr_enable(I2S_IRQ_WS_ID); - - _eos_i2s_start_pwm(); - /* - I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK; - I2S_REG_WS_MIC(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG; - I2S_REG_WS_SPK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG; - */ - - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_MIC); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC); - - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SR); - GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; - GPIO_REG(GPIO_IOF_EN) |= I2S_PIN_PWM; -} - -void eos_i2s_stop(void) { - I2S_REG_CK(PWM_CFG) = 0; - I2S_REG_WS_MIC(PWM_CFG) = 0; - I2S_REG_WS_SPK(PWM_CFG) = 0; - I2S_REG_CK(PWM_COUNT) = 0; - I2S_REG_WS_MIC(PWM_COUNT) = 0; - I2S_REG_WS_SPK(PWM_COUNT) = 0; - - _eos_i2s_drvr[I2S_MIC_BUF] = 0; - _eos_i2s_drvr[I2S_MIC_EVT] = 0; - _eos_i2s_drvr[I2S_MIC_WM] = 0; - - _eos_i2s_drvr[I2S_SPK_BUF] = 0; - _eos_i2s_drvr[I2S_SPK_EVT] = 0; - _eos_i2s_drvr[I2S_SPK_WM] = 0; - - eos_intr_disable(I2S_IRQ_WS_ID); - eos_intr_disable(I2S_IRQ_SD_ID); - - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SW); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_CK_SR); - - GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); - GPIO_REG(GPIO_IOF_EN) &= ~I2S_PIN_PWM; - - eos_i2s_mic_set_wm(0); - eos_i2s_spk_set_wm(0); -} - -int eos_i2s_running(void) { - return !!(GPIO_REG(GPIO_IOF_EN) & (1 << I2S_PIN_CK)); -} - -void eos_i2s_set_fmt(unsigned char fmt) { - _eos_i2s_drvr[I2S_FMT] = fmt; -} - -void eos_i2s_set_mode(unsigned char mode) { - _eos_i2s_drvr[I2S_MODE] = mode; -} - -void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { - clear_csr(mstatus, MSTATUS_MIE); - _abuf_init(&i2s_mic_buf, mic_arr, mic_arr_size); - set_csr(mstatus, MSTATUS_MIE); -} - -void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler) { - clear_csr(mstatus, MSTATUS_MIE); - i2s_mic_handler = wm_handler; - set_csr(mstatus, MSTATUS_MIE); -} - -void eos_i2s_mic_set_wm(uint16_t wm) { - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_MIC_WM] = wm; - set_csr(mstatus, MSTATUS_MIE); - -} - -uint16_t eos_i2s_mic_len(void) { - clear_csr(mstatus, MSTATUS_MIE); - uint16_t ret = _abuf_len(&i2s_mic_buf); - set_csr(mstatus, MSTATUS_MIE); - return ret; -} - -uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { - uint16_t i; - uint16_t _ssize = 0; - - clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, _abuf_len(&i2s_mic_buf)); - set_csr(mstatus, MSTATUS_MIE); - - for (i=0; i<_ssize; i++) { - sample[i] = i2s_mic_buf.array[EOS_ABUF_IDX_MASK(i2s_mic_buf.idx_r + i, i2s_mic_buf.size)]; - } - - clear_csr(mstatus, MSTATUS_MIE); - i2s_mic_buf.idx_r += _ssize; - set_csr(mstatus, MSTATUS_MIE); - - return _ssize; -} - -int eos_i2s_mic_pop8(uint8_t *sample) { - int ret; - - clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop8(&i2s_mic_buf, sample); - set_csr(mstatus, MSTATUS_MIE); - - return ret; -} - -int eos_i2s_mic_pop16(uint16_t *sample) { - int ret; - - clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop16(&i2s_mic_buf, sample); - set_csr(mstatus, MSTATUS_MIE); - - return ret; -} - -int eos_i2s_mic_vol_get(void) { - return i2s_mic_volume; -} - -void eos_i2s_mic_vol_set(int vol) { - if ((vol < 0) || (vol > 8)) return; - - i2s_mic_volume = vol; - - clear_csr(mstatus, MSTATUS_MIE); - i2s_cmp_set(); - set_csr(mstatus, MSTATUS_MIE); -} - -void eos_i2s_spk_init(uint8_t *spk_arr, uint16_t spk_arr_size) { - clear_csr(mstatus, MSTATUS_MIE); - _abuf_init(&i2s_spk_buf, spk_arr, spk_arr_size); - set_csr(mstatus, MSTATUS_MIE); -} - -void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler) { - clear_csr(mstatus, MSTATUS_MIE); - i2s_spk_handler = wm_handler; - set_csr(mstatus, MSTATUS_MIE); -} - -void eos_i2s_spk_set_wm(uint16_t wm) { - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_drvr[I2S_SPK_WM] = wm; - set_csr(mstatus, MSTATUS_MIE); -} - -uint16_t eos_i2s_spk_len(void) { - clear_csr(mstatus, MSTATUS_MIE); - uint16_t ret = _abuf_len(&i2s_spk_buf); - set_csr(mstatus, MSTATUS_MIE); - return ret; -} - -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { - uint16_t i; - uint16_t _ssize = 0; - - clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, i2s_spk_buf.size - _abuf_len(&i2s_spk_buf)); - set_csr(mstatus, MSTATUS_MIE); - - for (i=0; i<_ssize; i++) { - i2s_spk_buf.array[EOS_ABUF_IDX_MASK(i2s_spk_buf.idx_w + i, i2s_spk_buf.size)] = sample[i]; - } - - clear_csr(mstatus, MSTATUS_MIE); - i2s_spk_buf.idx_w += _ssize; - set_csr(mstatus, MSTATUS_MIE); - - return _ssize; -} - -int eos_i2s_spk_push8(uint8_t sample) { - int ret; - - clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push8(&i2s_spk_buf, sample); - set_csr(mstatus, MSTATUS_MIE); - - return ret; -} - -int eos_i2s_spk_push16(uint16_t sample) { - int ret; - - clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push16(&i2s_spk_buf, sample); - set_csr(mstatus, MSTATUS_MIE); - - return ret; -} - -int eos_i2s_spk_vol_get(void) { - return i2s_spk_volume; -} - -void eos_i2s_spk_vol_set(int vol) { - if ((vol < 0) || (vol > 16)) return; - - i2s_spk_volume = vol; - - clear_csr(mstatus, MSTATUS_MIE); - i2s_cmp_set(); - set_csr(mstatus, MSTATUS_MIE); -} diff --git a/fw/fe310/eos/i2s.h b/fw/fe310/eos/i2s.h deleted file mode 100644 index 81b4ade..0000000 --- a/fw/fe310/eos/i2s.h +++ /dev/null @@ -1,38 +0,0 @@ -#include - -#include "i2s_def.h" - -typedef struct EOSABuf { - uint16_t idx_r; - uint16_t idx_w; - uint16_t size; - uint8_t *array; -} EOSABuf; - -typedef void (*eos_i2s_handler_t) (unsigned char); - -int eos_i2s_init(uint8_t wakeup_cause); -void eos_i2s_init_mux(void); -void eos_i2s_start(uint32_t sample_rate); -void eos_i2s_stop(void); -int eos_i2s_running(void); -void eos_i2s_set_fmt(unsigned char fmt); -void eos_i2s_set_mode(unsigned char mode); -void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size); -void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler); -void eos_i2s_mic_set_wm(uint16_t wm); -uint16_t eos_i2s_mic_len(void); -uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize); -int eos_i2s_mic_pop8(uint8_t *sample); -int eos_i2s_mic_pop16(uint16_t *sample); -int eos_i2s_mic_vol_get(void); -void eos_i2s_mic_vol_set(int vol); -void eos_i2s_spk_init(uint8_t *mic_arr, uint16_t mic_arr_size); -void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler); -void eos_i2s_spk_set_wm(uint16_t wm); -uint16_t eos_i2s_spk_len(void); -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize); -int eos_i2s_spk_push8(uint8_t sample); -int eos_i2s_spk_push16(uint16_t sample); -int eos_i2s_spk_vol_get(void); -void eos_i2s_spk_vol_set(int vol); diff --git a/fw/fe310/eos/i2s_def.h b/fw/fe310/eos/i2s_def.h deleted file mode 100644 index 3529be1..0000000 --- a/fw/fe310/eos/i2s_def.h +++ /dev/null @@ -1,8 +0,0 @@ -#define EOS_I2S_FMT_PCM16 0 -#define EOS_I2S_FMT_ALAW 1 - -#define EOS_I2S_MODE_STEREO 0 -#define EOS_I2S_MODE_MONO 1 - -#define EOS_I2S_ETYPE_MIC 1 -#define EOS_I2S_ETYPE_SPK 2 diff --git a/fw/fe310/eos/i2s_priv.h b/fw/fe310/eos/i2s_priv.h deleted file mode 100644 index 25237c3..0000000 --- a/fw/fe310/eos/i2s_priv.h +++ /dev/null @@ -1,8 +0,0 @@ -#define I2S_PWM_SCALE_CK 2 -#define I2S_PWM_SCALE_CK_MASK 0x0003 - -/* asm */ -#define I2S_ABUF_OFF_IDXR 0 -#define I2S_ABUF_OFF_IDXW 2 -#define I2S_ABUF_OFF_SIZE 4 -#define I2S_ABUF_OFF_ARRAY 8 diff --git a/fw/fe310/eos/interrupt.c b/fw/fe310/eos/interrupt.c deleted file mode 100644 index dab6fab..0000000 --- a/fw/fe310/eos/interrupt.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include - -#include "encoding.h" -#include "platform.h" -#include "plic_driver.h" - -#include "eos.h" -#include "interrupt.h" - -// Global Instance data for the PLIC -// for use by the PLIC Driver. -static plic_instance_t plic; - -static eos_intr_handler_t ext_interrupt_handler[PLIC_NUM_INTERRUPTS]; - -uintptr_t eos_intr_handle(uintptr_t int_num) { - if ((int_num >=1) && (int_num <= PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num-1])) { - ext_interrupt_handler[int_num-1](); - } else { - printf("INTR ERROR:%d\n", int_num); - exit(int_num); - } - return int_num; -} - -int eos_intr_init(uint8_t wakeup_cause) { - for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){ - ext_interrupt_handler[i] = NULL; - } - - /************************************************************************** - * Set up the PLIC - **************************************************************************/ - PLIC_init(&plic, - PLIC_CTRL_ADDR, - PLIC_NUM_INTERRUPTS, - PLIC_NUM_PRIORITIES); - - // Enable Global (PLIC) interrupts. - set_csr(mie, MIP_MEIP); - - // Enable all interrupts - set_csr(mstatus, MSTATUS_MIE); - - return EOS_OK; -} - -void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_handler_t handler) { - ext_interrupt_handler[int_num-1] = handler; - PLIC_set_priority(&plic, int_num, priority); - PLIC_enable_interrupt(&plic, int_num); -} - -void eos_intr_set_handler(uint8_t int_num, eos_intr_handler_t handler) { - ext_interrupt_handler[int_num-1] = handler; -} - -void eos_intr_set_priority(uint8_t int_num, uint8_t priority) { - PLIC_set_priority(&plic, int_num, priority); -} - -void eos_intr_enable(uint8_t int_num) { - PLIC_enable_interrupt(&plic, int_num); -} - -void eos_intr_disable(uint8_t int_num) { - PLIC_disable_interrupt(&plic, int_num); -} - -void eos_intr_mask(uint8_t priority) { - PLIC_set_threshold(&plic, priority); -} diff --git a/fw/fe310/eos/interrupt.h b/fw/fe310/eos/interrupt.h deleted file mode 100644 index a239934..0000000 --- a/fw/fe310/eos/interrupt.h +++ /dev/null @@ -1,13 +0,0 @@ -#include - -#include "irq_def.h" - -typedef void (*eos_intr_handler_t) (void); - -int eos_intr_init(uint8_t wakeup_cause); -void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_handler_t handler); -void eos_intr_set_handler(uint8_t int_num, eos_intr_handler_t handler); -void eos_intr_set_priority(uint8_t int_num, uint8_t priority); -void eos_intr_enable(uint8_t int_num); -void eos_intr_disable(uint8_t int_num); -void eos_intr_mask(uint8_t priority); \ No newline at end of file diff --git a/fw/fe310/eos/lcd.c b/fw/fe310/eos/lcd.c deleted file mode 100644 index 3080a13..0000000 --- a/fw/fe310/eos/lcd.c +++ /dev/null @@ -1,546 +0,0 @@ -#include -#include -#include -#include - -#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/lcd.h b/fw/fe310/eos/lcd.h deleted file mode 100644 index 1bcb2cd..0000000 --- a/fw/fe310/eos/lcd.h +++ /dev/null @@ -1,12 +0,0 @@ -#include - -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/net.c b/fw/fe310/eos/net.c deleted file mode 100644 index 33b71c2..0000000 --- a/fw/fe310/eos/net.c +++ /dev/null @@ -1,602 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" - -#include "eos.h" -#include "msgq.h" -#include "interrupt.h" -#include "event.h" -#include "timer.h" -#include "pwr.h" - -#include "board.h" - -#include "spi.h" -#include "spi_priv.h" -#include "spi_dev.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_intr_set_handler(INT_SPI1_BASE, net_handle_xchg); - SPI1_REG(SPI_REG_SCKDIV) = eos_spi_div(EOS_SPI_DEV_NET); - SPI1_REG(SPI_REG_CSID) = eos_spi_csid(EOS_SPI_DEV_NET); -} - -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 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/net.h b/fw/fe310/eos/net.h deleted file mode 100644 index 79caf4b..0000000 --- a/fw/fe310/eos/net.h +++ /dev/null @@ -1,47 +0,0 @@ -#include -#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/net/cell.c b/fw/fe310/eos/net/cell.c new file mode 100644 index 0000000..20a9f42 --- /dev/null +++ b/fw/fe310/eos/net/cell.c @@ -0,0 +1,51 @@ +#include +#include +#include + +#include "eos.h" +#include "event.h" +#include "net.h" + +#include "cell.h" + +static eos_evt_handler_t evt_handler[EOS_CELL_MAX_MTYPE]; + +static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char mtype; + unsigned char idx; + + if ((buffer == NULL) || (len < 1)) { + eos_net_bad_handler(type, buffer, len); + return; + } + + mtype = buffer[0]; + idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; + if ((idx < EOS_CELL_MAX_MTYPE) && evt_handler[idx]) { + evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, len); + } else { + eos_net_bad_handler(type, buffer, len); + } +} + +void eos_cell_netinit(void) { + int i; + + for (i=0; i> 4; + + if (idx < EOS_CELL_MAX_MTYPE) evt_handler[idx] = handler; +} + +eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) { + unsigned char idx = (mtype & EOS_CELL_MTYPE_MASK) >> 4; + + if (idx < EOS_CELL_MAX_MTYPE) return evt_handler[idx]; + return NULL; +} diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h new file mode 100644 index 0000000..b01d4cf --- /dev/null +++ b/fw/fe310/eos/net/cell.h @@ -0,0 +1,51 @@ +#include +#include "event.h" + +#define EOS_CELL_MTYPE_DEV 0x10 +#define EOS_CELL_MTYPE_VOICE 0x20 +#define EOS_CELL_MTYPE_SMS 0x30 +#define EOS_CELL_MTYPE_CBS 0x40 +#define EOS_CELL_MTYPE_USSD 0x50 +#define EOS_CELL_MTYPE_PDP 0x60 + +#define EOS_CELL_MTYPE_MASK 0xf0 +#define EOS_CELL_MAX_MTYPE 8 + +/* EOS_CELL_MTYPE_DEV subtypes */ +#define EOS_CELL_MTYPE_READY 1 +#define EOS_CELL_MTYPE_UART_DATA 2 +#define EOS_CELL_MTYPE_UART_TAKE 3 +#define EOS_CELL_MTYPE_UART_GIVE 4 +#define EOS_CELL_MTYPE_RESET 5 + +#define EOS_CELL_MTYPE_VOICE_PCM 1 +#define EOS_CELL_MTYPE_VOICE_DIAL 2 +#define EOS_CELL_MTYPE_VOICE_RING 3 +#define EOS_CELL_MTYPE_VOICE_ANSWER 4 +#define EOS_CELL_MTYPE_VOICE_HANGUP 5 +#define EOS_CELL_MTYPE_VOICE_BEGIN 6 +#define EOS_CELL_MTYPE_VOICE_END 7 +#define EOS_CELL_MTYPE_VOICE_MISS 8 +#define EOS_CELL_MTYPE_VOICE_BUSY 9 +#define EOS_CELL_MTYPE_VOICE_ERR 10 + +#define EOS_CELL_MTYPE_SMS_LIST 1 +#define EOS_CELL_MTYPE_SMS_SEND 2 +#define EOS_CELL_MTYPE_SMS_MSG_NEW 3 +#define EOS_CELL_MTYPE_SMS_MSG_ITEM 4 + +#define EOS_CELL_MTYPE_USSD_REQUEST 1 +#define EOS_CELL_MTYPE_USSD_REPLY 2 +#define EOS_CELL_MTYPE_USSD_CANCEL 3 + +#define EOS_CELL_MTYPE_PDP_CONFIG 1 +#define EOS_CELL_MTYPE_PDP_CONNECT 2 +#define EOS_CELL_MTYPE_PDP_DISCONNECT 3 + +#define EOS_CELL_SMS_ADDRTYPE_INTL 1 +#define EOS_CELL_SMS_ADDRTYPE_ALPHA 2 +#define EOS_CELL_SMS_ADDRTYPE_OTHER 3 + +void eos_cell_netinit(void); +void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler); +eos_evt_handler_t eos_cell_get_handler(unsigned char mtype); \ No newline at end of file diff --git a/fw/fe310/eos/net/rng.c b/fw/fe310/eos/net/rng.c new file mode 100644 index 0000000..317941d --- /dev/null +++ b/fw/fe310/eos/net/rng.c @@ -0,0 +1,27 @@ +#include +#include +#include + +#include "net.h" + +int getentropy(unsigned char *b, size_t sz) { + unsigned char type; + unsigned char *buffer; + uint16_t len; + int rv; + + buffer = eos_net_alloc(); + + type = EOS_NET_MTYPE_RNG; + len = sizeof(uint16_t); + buffer[0] = sz >> 8; + buffer[1] = sz; + + rv = eos_net_xchg(&type, buffer, &len); + if (rv || (len != sz)) rv = -1; + + if (!rv) memcpy(b, buffer, sz); + eos_net_free(buffer, 1); + + return rv; +} diff --git a/fw/fe310/eos/net/rng.h b/fw/fe310/eos/net/rng.h new file mode 100644 index 0000000..27bbf74 --- /dev/null +++ b/fw/fe310/eos/net/rng.h @@ -0,0 +1,5 @@ +#include + +int getentropy(unsigned char *b, size_t sz); +int arc4random_alloc(void **rsp, size_t rsp_size, void **rsxp, size_t rsxp_size); +void arc4random_close(void **rsp, void **rsxp); \ No newline at end of file diff --git a/fw/fe310/eos/net/sock.c b/fw/fe310/eos/net/sock.c new file mode 100644 index 0000000..7365c97 --- /dev/null +++ b/fw/fe310/eos/net/sock.c @@ -0,0 +1,154 @@ +#include +#include +#include + +#include "eos.h" +#include "event.h" +#include "net.h" + +#include "sock.h" + +static eos_evt_handler_t evt_handler[EOS_SOCK_MAX_SOCK]; + +static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char sock; + + if ((buffer == NULL) || (len < 2)) { + eos_net_bad_handler(type, buffer, len); + return; + } + + sock = buffer[1]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, buffer, len); + return; + } + + switch(buffer[0]) { + case EOS_SOCK_MTYPE_PKT: + evt_handler[sock - 1](type, buffer, len); + break; + default: + eos_net_bad_handler(type, buffer, len); + break; + } +} + +void eos_sock_netinit(void) { + int i; + + for (i=0; ihost, sizeof(addr->host)); + buffer += sizeof(addr->host); + buffer[0] = addr->port >> 8; + buffer[1] = addr->port; + buffer += sizeof(addr->port); + if (msg) { + if (msg_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_MTU) return EOS_ERR_SIZE; + memcpy(buffer, msg, msg_len); + } + + return EOS_OK; +} + +int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer) { + int rv; + + rv = sock_send(sock, msg, msg_len, addr, buffer); + if (rv) return rv; + + return eos_net_send(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR); +} + +int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more) { + int rv; + + rv = sock_send(sock, msg, msg_len, addr, buffer); + if (rv) return rv; + + return eos_net_send_async(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR, more); +} + +int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr) { + if (len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + + if (buffer[0] != EOS_SOCK_MTYPE_PKT) return EOS_ERR_NET; + + buffer += 2; + memcpy(addr->host, buffer, sizeof(addr->host)); + buffer += sizeof(addr->host); + addr->port = (uint16_t)buffer[0] << 8; + addr->port |= (uint16_t)buffer[1]; + buffer += sizeof(addr->port); + if (msg) { + if (msg_size < len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + memcpy(msg, buffer, len - EOS_SOCK_SIZE_UDP_HDR); + } + + return EOS_OK; +} diff --git a/fw/fe310/eos/net/sock.h b/fw/fe310/eos/net/sock.h new file mode 100644 index 0000000..5ef42e3 --- /dev/null +++ b/fw/fe310/eos/net/sock.h @@ -0,0 +1,28 @@ +#include +#include "event.h" + +#define EOS_SOCK_MTYPE_PKT 0 +#define EOS_SOCK_MTYPE_OPEN_DGRAM 1 +#define EOS_SOCK_MTYPE_CLOSE 127 + +#define EOS_SOCK_MAX_SOCK 2 + +#define EOS_SOCK_SIZE_UDP_HDR 8 + +#define EOS_IPv4_ADDR_SIZE 4 + +typedef struct EOSNetAddr { + unsigned char host[EOS_IPv4_ADDR_SIZE]; + uint16_t port; +} EOSNetAddr; + +void eos_sock_netinit(void); +void eos_sock_set_handler(unsigned char sock, eos_evt_handler_t handler); +eos_evt_handler_t eos_sock_get_handler(unsigned char sock); + +int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer); +void eos_sock_close(unsigned char sock, unsigned char *buffer); + +int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer); +int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more); +int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr); diff --git a/fw/fe310/eos/net/wifi.c b/fw/fe310/eos/net/wifi.c new file mode 100644 index 0000000..0663582 --- /dev/null +++ b/fw/fe310/eos/net/wifi.c @@ -0,0 +1,106 @@ +#include +#include +#include + +#include "eos.h" +#include "event.h" +#include "net.h" + +#include "wifi.h" + +static eos_evt_handler_t evt_handler[EOS_WIFI_MAX_MTYPE]; + +static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char mtype; + + if ((buffer == NULL) || (len < 1)) { + eos_net_bad_handler(type, buffer, len); + return; + } + + mtype = buffer[0]; + if ((mtype < EOS_WIFI_MAX_MTYPE) && evt_handler[mtype]) { + evt_handler[mtype](mtype, buffer, len); + } else { + eos_net_bad_handler(type, buffer, len); + } +} + +void eos_wifi_netinit(void) { + int i; + + for (i=0; i EOS_NET_MTU) return EOS_ERR_SIZE; + + buf = buffer; + buf[0] = EOS_WIFI_MTYPE_AUTH; + buf++; + strcpy(buf, ssid); + buf += ssid_len; + strcpy(buf, pass); + buf += pass_len; + + return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1 + ssid_len + pass_len, async, 1); +} + +int eos_wifi_connect(unsigned char *buffer) { + int async; + + async = 0; + if (buffer == NULL) { + buffer = eos_net_alloc(); + async = 1; + } + buffer[0] = EOS_WIFI_MTYPE_CONNECT; + return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); +} + +int eos_wifi_disconnect(unsigned char *buffer) { + int async; + + async = 0; + if (buffer == NULL) { + buffer = eos_net_alloc(); + async = 1; + } + buffer[0] = EOS_WIFI_MTYPE_DISCONNECT; + return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); +} diff --git a/fw/fe310/eos/net/wifi.h b/fw/fe310/eos/net/wifi.h new file mode 100644 index 0000000..4a49518 --- /dev/null +++ b/fw/fe310/eos/net/wifi.h @@ -0,0 +1,18 @@ +#include +#include "event.h" + +#define EOS_WIFI_MTYPE_SCAN 1 +#define EOS_WIFI_MTYPE_AUTH 2 +#define EOS_WIFI_MTYPE_CONNECT 3 +#define EOS_WIFI_MTYPE_DISCONNECT 4 + +#define EOS_WIFI_MAX_MTYPE 5 + +void eos_wifi_netinit(void); +void eos_wifi_set_handler(unsigned char mtype, eos_evt_handler_t handler); +eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype); + +int eos_wifi_scan(unsigned char *buffer); +int eos_wifi_auth(const char *ssid, const char *pass, unsigned char *buffer); +int eos_wifi_connect(unsigned char *buffer); +int eos_wifi_disconnect(unsigned char *buffer); diff --git a/fw/fe310/eos/pwr.c b/fw/fe310/eos/pwr.c deleted file mode 100644 index 802e593..0000000 --- a/fw/fe310/eos/pwr.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" - -#include "eos.h" -#include "event.h" -#include "timer.h" -#include "spi.h" -#include "spi_dev.h" -#include "net.h" -#include "lcd.h" -#include "eve/eve.h" - -#include "pwr.h" - -#define PWR_RTC_SCALE 15 -#define PWR_RTC_SFREQ (EOS_TIMER_RTC_FREQ >> PWR_RTC_SCALE) - -static eos_evt_handler_t evt_handler[EOS_PWR_MAX_MTYPE]; -static unsigned char power_btn_down; - -int eos_pwr_init(uint8_t wakeup_cause) { - AON_REG(AON_PMUKEY) = 0x51F15E; - AON_REG(AON_PMUIE) = 0x5; - - AON_REG(AON_RTCCMP) = 0xFFFFFFFF; - AON_REG(AON_RTCCFG) = PWR_RTC_SCALE; - AON_REG(AON_RTCHI) = 0; - AON_REG(AON_RTCLO) = 0; - - return EOS_OK; -} - -uint8_t eos_pwr_wakeup_cause(void) { - return AON_REG(AON_PMUCAUSE) & 0xff; -} - -uint8_t eos_pwr_reset_cause(void) { - return (AON_REG(AON_PMUCAUSE) >> 8) & 0xff; -} - -int eos_pwr_sleep(void) { - int rv; - - rv = eos_lcd_sleep(); - if (rv) return rv; - - eos_spi_select(EOS_SPI_DEV_EVE); - eve_pwr_sleep(); - eos_spi_deselect(); - - rv = eos_net_sleep(1000); - if (rv) return rv; - - AON_REG(AON_PMUKEY) = 0x51F15E; - AON_REG(AON_PMUSLEEP) = 1; - - return EOS_OK; -} - -void eos_pwr_wake_at(uint32_t msec) { - uint32_t pmuie; - - AON_REG(AON_RTCCFG) |= AON_RTCCFG_ENALWAYS; - AON_REG(AON_RTCCMP) = msec * PWR_RTC_SFREQ / 1000; - - pmuie = AON_REG(AON_PMUIE) | 0x2; - AON_REG(AON_PMUKEY) = 0x51F15E; - AON_REG(AON_PMUIE) = pmuie; -} - -void eos_pwr_wake_disable(void) { - uint32_t pmuie; - - AON_REG(AON_RTCCMP) = 0xFFFFFFFF; - AON_REG(AON_RTCCFG) &= ~AON_RTCCFG_ENALWAYS; - AON_REG(AON_RTCHI) = 0; - AON_REG(AON_RTCLO) = 0; - - pmuie = AON_REG(AON_PMUIE) & ~0x2; - AON_REG(AON_PMUKEY) = 0x51F15E; - AON_REG(AON_PMUIE) = pmuie; -} - -static void pwr_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char mtype; - - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - mtype = buffer[0]; - if ((mtype < EOS_PWR_MAX_MTYPE) && evt_handler[mtype]) { - evt_handler[mtype](mtype, buffer, len); - } else { - eos_net_bad_handler(type, buffer, len); - } -} - -static void pwr_handle_btn(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char level = buffer[1]; - - eos_net_free(buffer, 0); - if (!level) { - power_btn_down = 1; - return; - } - if (!power_btn_down) return; - - eos_pwr_sleep(); -} - -void eos_pwr_netinit(void) { - int i; - - for (i=0; i -#include "event.h" - -#define EOS_PWR_MTYPE_BUTTON 1 - -#define EOS_PWR_MAX_MTYPE 2 - -#define EOS_PWR_WAKE_RST 0 -#define EOS_PWR_WAKE_RTC 1 -#define EOS_PWR_WAKE_BTN 2 - -#define EOS_PWR_RST_PWRON 0 -#define EOS_PWR_RST_EXT 1 -#define EOS_PWR_RST_WDOG 2 - -int eos_pwr_init(uint8_t wakeup_cause); -uint8_t eos_pwr_wakeup_cause(void); -uint8_t eos_pwr_reset_cause(void); -int eos_pwr_sleep(void); -void eos_pwr_wake_at(uint32_t msec); -void eos_pwr_wake_disable(void); - -void eos_pwr_netinit(void); -void eos_pwr_set_handler(unsigned char mtype, eos_evt_handler_t handler); -eos_evt_handler_t eos_pwr_get_handler(unsigned char mtype); \ No newline at end of file diff --git a/fw/fe310/eos/rng.c b/fw/fe310/eos/rng.c deleted file mode 100644 index 317941d..0000000 --- a/fw/fe310/eos/rng.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include -#include - -#include "net.h" - -int getentropy(unsigned char *b, size_t sz) { - unsigned char type; - unsigned char *buffer; - uint16_t len; - int rv; - - buffer = eos_net_alloc(); - - type = EOS_NET_MTYPE_RNG; - len = sizeof(uint16_t); - buffer[0] = sz >> 8; - buffer[1] = sz; - - rv = eos_net_xchg(&type, buffer, &len); - if (rv || (len != sz)) rv = -1; - - if (!rv) memcpy(b, buffer, sz); - eos_net_free(buffer, 1); - - return rv; -} diff --git a/fw/fe310/eos/rng.h b/fw/fe310/eos/rng.h deleted file mode 100644 index 27bbf74..0000000 --- a/fw/fe310/eos/rng.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -int getentropy(unsigned char *b, size_t sz); -int arc4random_alloc(void **rsp, size_t rsp_size, void **rsxp, size_t rsxp_size); -void arc4random_close(void **rsp, void **rsxp); \ No newline at end of file diff --git a/fw/fe310/eos/sdc_crypto.c b/fw/fe310/eos/sdc_crypto.c deleted file mode 100644 index f0e935d..0000000 --- a/fw/fe310/eos/sdc_crypto.c +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -#include - -#include "sha/sha1.h" -#include "sdc_crypto.h" - -#define SDC_CRYPTO_KEY_SIZE 16 -#define SDC_CRYPTO_BLK_SIZE 16 -#define SDC_CRYPTO_HASH_SIZE 20 - -EOSSDCCrypto *sdc_crypto; - -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) { - char key_essiv[SDC_CRYPTO_HASH_SIZE]; - - sdc_crypto = crypto; - - memset(key_essiv, 0, SDC_CRYPTO_HASH_SIZE); - init(ctx, key); - sdc_crypto->ctx = ctx; - sdc_crypto->enc = enc; - sdc_crypto->dec = dec; - - SHA1(key_essiv, key, SDC_CRYPTO_KEY_SIZE); - init_essiv(ctx_essiv, key_essiv); - sdc_crypto->ctx_essiv = ctx_essiv; - sdc_crypto->enc_essiv = enc_essiv; -} - -void eos_sdcc_encrypt(uint32_t sect, uint8_t *buffer) { - uint8_t iv[SDC_CRYPTO_BLK_SIZE]; - - if (sdc_crypto == NULL) return; - - memset(iv, 0, SDC_CRYPTO_BLK_SIZE); - memcpy(iv, §, sizeof(sect)); - sdc_crypto->enc_essiv(sdc_crypto->ctx_essiv, iv); - sdc_crypto->enc(sdc_crypto->ctx, iv, buffer, 512); -} - -void eos_sdcc_decrypt(uint32_t sect, uint8_t *buffer) { - uint8_t iv[SDC_CRYPTO_BLK_SIZE]; - - if (sdc_crypto == NULL) return; - - memset(iv, 0, SDC_CRYPTO_BLK_SIZE); - memcpy(iv, §, sizeof(sect)); - sdc_crypto->enc_essiv(sdc_crypto->ctx_essiv, iv); - sdc_crypto->dec(sdc_crypto->ctx, iv, buffer, 512); -} diff --git a/fw/fe310/eos/sdc_crypto.h b/fw/fe310/eos/sdc_crypto.h deleted file mode 100644 index 015bf8a..0000000 --- a/fw/fe310/eos/sdc_crypto.h +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include - -typedef void (*eve_sdcc_init_t) (void *, uint8_t *); -typedef void (*eve_sdcc_crypt_t) (void *, uint8_t *, uint8_t *, size_t); -typedef void (*eve_sdcc_essiv_t) (void *, uint8_t *); - -typedef struct EOSSDCCrypto { - void *ctx; - eve_sdcc_crypt_t enc; - eve_sdcc_crypt_t dec; - void *ctx_essiv; - eve_sdcc_essiv_t enc_essiv; -} 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 diff --git a/fw/fe310/eos/sdcard.c b/fw/fe310/eos/sdcard.c deleted file mode 100644 index d081388..0000000 --- a/fw/fe310/eos/sdcard.c +++ /dev/null @@ -1,539 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "timer.h" - -#include "spi.h" -#include "spi_dev.h" - -#include "sdc_crypto.h" -#include "sdcard.h" - -#define SDC_TIMEOUT_CMD 500 -#define SDC_TIMEOUT_READ 200 -#define SDC_TIMEOUT_WRITE 500 - -#define SDC_POLY_CRC7 0x09 -#define SDC_POLY_CRC16 0x1021 - -#define SDC_CMD_FLAG_CRC 0x01 -#define SDC_CMD_FLAG_NOCS 0x02 -#define SDC_CMD_FLAG_NOWAIT 0x04 -#define SDC_CMD_FLAG_RSTUFF 0x08 - -#define SDC_TOKEN_START_BLK 0xfe -#define SDC_TOKEN_START_BLKM 0xfc -#define SDC_TOKEN_STOP_TRAN 0xfd - -#define SDC_DRESP_MASK 0x1f -#define SDC_DRESP_ACCEPT 0x05 -#define SDC_DRESP_ERR_CRC 0x0b -#define SDC_DRESP_ERR_WRITE 0x0d - -#define SDC_R1_READY 0x00 - -#define SDC_R1_IDLE_STATE 0x01 -#define SDC_R1_ERASE_RESET 0x02 -#define SDC_R1_ILLEGAL_CMD 0x04 -#define SDC_R1_ERR_CMD_CRC 0x08 -#define SDC_R1_ERR_ERASE_SEQ 0x10 -#define SDC_R1_ERR_ADDR 0x20 -#define SDC_R1_ERR_PARAM 0x40 - -#define SDC_NCR 10 - -#define SDC_ERR(rv) ((rv < 0) ? rv : EOS_ERR) - -/* CMD */ -#define GO_IDLE_STATE 0 -#define SEND_OP_COND 1 -#define SEND_IF_COND 8 -#define SEND_CSD 9 -#define STOP_TRANSMISSION 12 -#define SET_BLOCKLEN 16 -#define READ_SINGLE_BLOCK 17 -#define READ_MULTIPLE_BLOCK 18 -#define WRITE_BLOCK 24 -#define WRITE_MULTIPLE_BLOCK 25 -#define ERASE_WR_BLK_START 32 -#define ERASE_WR_BLK_END 33 -#define ERASE 38 -#define APP_CMD 55 -#define READ_OCR 58 - -/* ACMD */ -#define SD_STATUS 13 -#define SET_WR_BLK_ERASE_COUNT 23 -#define SD_APP_OP_COND 41 - -static uint8_t sdc_type = 0; - -static uint8_t sdc_crc7(uint8_t crc, uint8_t b) { - int i; - - for (i=8; i--; b<<=1) { - crc <<= 1; - if ((b ^ crc) & 0x80) crc ^= SDC_POLY_CRC7; - } - return crc & 0x7f; -} - -static uint16_t sdc_crc16(uint16_t crc, uint8_t b) { - int i; - - crc = crc ^ ((uint16_t)b << 8); - for (i=8; i--;) { - if (crc & 0x8000) { - crc = (crc << 1) ^ SDC_POLY_CRC16; - } else { - crc <<= 1; - } - } - return crc; -} - -static uint32_t sdc_nto(uint32_t start, uint32_t timeout) { - uint32_t d = eos_time_delta_ms(start); - return (d > timeout) ? 0 : timeout - d; -} - -static uint8_t sdc_xchg8(uint8_t data) { - return eos_spi_xchg8(data, 0); -} - -static uint16_t sdc_xchg16(uint16_t data) { - return eos_spi_xchg16(data, 0); -} - -static uint32_t sdc_xchg32(uint32_t data) { - return eos_spi_xchg32(data, 0); -} - -static void sdc_buf_send(unsigned char *buffer, uint16_t len) { - int i; - - for (i=0; i> 24); - crc = sdc_crc7(crc, arg >> 16); - crc = sdc_crc7(crc, arg >> 8); - crc = sdc_crc7(crc, arg); - } - crc = (crc << 1) | 0x01; - sdc_xchg8(cmd); - sdc_xchg32(arg); - sdc_xchg8(crc); - if (flags & SDC_CMD_FLAG_RSTUFF) sdc_xchg8(0xff); - - i = SDC_NCR; - do { - ret = sdc_xchg8(0xff); - } while ((ret & 0x80) && --i); - if (ret & 0x80) return EOS_ERR_BUSY; - - return ret; -} - -static int sdc_ready(uint32_t timeout) { - uint8_t d = 0; - uint32_t start; - - if (timeout == 0) return EOS_ERR_BUSY; - start = eos_time_get_tick(); - do { - if (eos_time_delta_ms(start) > timeout) break; - d = sdc_xchg8(0xff); - } while (d != 0xff); - if (d != 0xff) return EOS_ERR_BUSY; - - return EOS_OK; -} - -static int sdc_block_read(uint8_t *buffer, uint16_t len, uint32_t timeout) { - uint8_t token = 0xff; - uint32_t start; - - if (timeout == 0) return EOS_ERR_BUSY; - start = eos_time_get_tick(); - do { - if (eos_time_delta_ms(start) > timeout) break; - token = sdc_xchg8(0xff); - } while (token == 0xff); - if (token == 0xff) return EOS_ERR_BUSY; - if (token != SDC_TOKEN_START_BLK) return EOS_ERR; - - sdc_buf_recv(buffer, len); - sdc_xchg16(0xffff); /* dummy CRC */ - - return EOS_OK; -} - -static int sdc_block_write(uint8_t token, uint8_t *buffer, uint16_t len, uint32_t timeout) { - uint8_t d; - int rv; - - rv = sdc_ready(timeout); - if (rv) return rv; - - sdc_xchg8(token); - if (buffer && len) { - sdc_buf_send(buffer, len); - sdc_xchg16(0xffff); /* dummy CRC */ - - d = sdc_xchg8(0xff); /* Response */ - if ((d & SDC_DRESP_MASK) != SDC_DRESP_ACCEPT) return EOS_ERR; - } - - return EOS_OK; -} - -static int sdc_cmd(uint8_t cmd, uint32_t arg, uint8_t flags, uint32_t timeout) { - int do_cs = !(flags & SDC_CMD_FLAG_NOCS); - int do_wait = !(flags & SDC_CMD_FLAG_NOWAIT); - int rv = EOS_OK; - - if (do_cs) sdc_select(); - if (do_wait) rv = sdc_ready(timeout); - if (rv) { - if (do_cs) sdc_deselect(); - return rv; - } - rv = sdc_xchg_cmd(cmd, arg, flags); - if (do_cs) sdc_deselect(); - return rv; -} - -static int sdc_acmd(uint8_t cmd, uint32_t arg, uint8_t flags, uint32_t timeout) { - int rv; - uint32_t start; - - start = eos_time_get_tick(); - rv = sdc_cmd(APP_CMD, 0, flags, timeout); - if (rv & ~SDC_R1_IDLE_STATE) return rv; - - if (flags & SDC_CMD_FLAG_NOCS) { - sdc_deselect(); - sdc_select(); - } - return sdc_cmd(cmd, arg, flags, sdc_nto(start, timeout)); -} - -static int sdc_init(uint32_t timeout) { - int rv, i; - uint8_t _type; - uint8_t ocr[4]; - uint32_t start; - start = eos_time_get_tick(); - - eos_time_sleep(100); - for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */ - - rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD); - if (rv != SDC_R1_IDLE_STATE) return SDC_ERR(rv); - - sdc_select(); - rv = sdc_cmd(SEND_IF_COND, 0x1aa, SDC_CMD_FLAG_CRC | SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); - switch (rv) { - case SDC_R1_IDLE_STATE: - for (i=0; i<4; i++) { /* R7 response */ - ocr[i] = sdc_xchg8(0xff); - } - sdc_deselect(); - if (ocr[2] == 0x01 && ocr[3] == 0xaa) { /* Check voltage range: 2.7-3.6V */ - do { - rv = sdc_acmd(SD_APP_OP_COND, 0x40000000, 0, sdc_nto(start, timeout)); - } while (rv == SDC_R1_IDLE_STATE); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - sdc_select(); - rv = sdc_cmd(READ_OCR, 0, SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); - if (rv == SDC_R1_READY) { - for (i=0; i<4; i++) { /* R7 response */ - ocr[i] = sdc_xchg8(0xff); - } - sdc_deselect(); - } else { - sdc_deselect(); - return SDC_ERR(rv); - } - - _type = EOS_SDC_TYPE_SDC2; - if (ocr[0] & 0xc0) _type |= EOS_SDC_CAP_BLK; - } - break; - - case SDC_R1_IDLE_STATE | SDC_R1_ILLEGAL_CMD: - sdc_deselect(); - rv = sdc_acmd(SD_APP_OP_COND, 0, 0, sdc_nto(start, timeout)); - switch (rv) { - case SDC_R1_IDLE_STATE: - do { - rv = sdc_acmd(SD_APP_OP_COND, 0, 0, sdc_nto(start, timeout)); - } while (rv == SDC_R1_IDLE_STATE); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - case SDC_R1_READY: - _type = EOS_SDC_TYPE_SDC1; - break; - - default: - do { - rv = sdc_cmd(SEND_OP_COND, 0, 0, sdc_nto(start, timeout)); - } while (rv == SDC_R1_IDLE_STATE); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - _type = EOS_SDC_TYPE_MMC; - break; - - } - break; - - default: - sdc_deselect(); - return SDC_ERR(rv); - } - - if (!(_type & EOS_SDC_CAP_BLK)) { - rv = sdc_cmd(SET_BLOCKLEN, 512, 0, sdc_nto(start, timeout)); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - } - - if (_type & EOS_SDC_TYPE_SDC) { - uint8_t csd[16]; - - sdc_select(); - rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); - if (rv == SDC_R1_READY) { - rv = sdc_block_read(csd, 16, sdc_nto(start, timeout)); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - if (rv) return rv; - - for (i=0; i<16; i++) { - printf("%.2x ", csd[i]); - } - printf("\n"); - if (csd[10] & 0x40) _type |= EOS_SDC_CAP_ERASE_EN; - } - - eos_spi_set_div(EOS_SPI_DEV_SDC, 5); - sdc_type = _type; - return EOS_OK; -} - -int eos_sdc_init(uint8_t wakeup_cause) { - int rv; - - eos_spi_select(EOS_SPI_DEV_SDC); - rv = sdc_init(5000); - if (rv) { - printf("SDC ERROR\n"); - } else { - printf("SDC OK:%x\n", sdc_type); - } - eos_spi_deselect(); - - return EOS_OK; -} - -uint8_t eos_sdc_type(void) { - return sdc_type & EOS_SDC_TYPE_MASK; -} - -uint8_t eos_sdc_cap(void) { - return sdc_type & EOS_SDC_CAP_MASK; -} - -int eos_sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { - int rv; - uint8_t csd[16]; - uint32_t start = eos_time_get_tick(); - - sdc_select(); - rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, timeout); - if (rv == SDC_R1_READY) { - rv = sdc_block_read(csd, 16, sdc_nto(start, timeout)); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - if (rv) return rv; - - if ((csd[0] >> 6) == 1) { /* SDCv2 */ - *sectors = (csd[9] + (csd[8] << 8) + ((csd[7] & 0x3f) << 16) + 1) << 10; - } else { /* SDCv1 or MMC*/ - uint8_t n = (csd[5] & 0x0f) + (csd[10] >> 7) + ((csd[9] & 0x03) << 1) + 2; - *sectors = (csd[8] >> 6) + (csd[7] << 2) + ((csd[6] & 0x03) << 10) + 1; - *sectors = *sectors << (n - 9); - } - - return EOS_OK; -} - -int eos_sdc_get_blk_size(uint32_t timeout, uint32_t *size) { - int rv; - uint8_t rbl[64]; /* SD Status or CSD register */ - uint32_t start = eos_time_get_tick(); - - sdc_select(); - if (sdc_type & EOS_SDC_TYPE_SDC2) { - rv = sdc_acmd(SD_STATUS, 0, SDC_CMD_FLAG_NOCS, timeout); - sdc_xchg8(0xff); /* R2 response */ - } else { - rv = sdc_cmd(SEND_CSD, 0, SDC_CMD_FLAG_NOCS, timeout); - } - if (rv == SDC_R1_READY) { - rv = sdc_block_read(rbl, (sdc_type & EOS_SDC_TYPE_SDC2) ? 64 : 16, sdc_nto(start, timeout)); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - if (rv) return rv; - - if (sdc_type & EOS_SDC_TYPE_SDC2) { - *size = 16UL << (rbl[10] >> 4); - } else if (sdc_type & EOS_SDC_TYPE_SDC1) { - *size = (((rbl[10] & 0x3f) << 1) + (rbl[11] >> 7) + 1) << ((rbl[13] >> 6) - 1); - } else { - *size = (((rbl[10] & 0x7c) >> 2) + 1) * (((rbl[11] & 0x03) << 3) + (rbl[11] >> 5) + 1); - } - - return EOS_OK; -} - -int eos_sdc_sync(uint32_t timeout) { - int rv; - - sdc_select(); - rv = sdc_ready(timeout); - sdc_deselect(); - - return rv; -} - -int eos_sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout) { - int rv; - uint32_t start; - - if (!(sdc_type & EOS_SDC_TYPE_SDC)) return EOS_ERR; - if (!(sdc_type & EOS_SDC_CAP_ERASE_EN)) return EOS_ERR; - if (!(sdc_type & EOS_SDC_CAP_BLK)) { - blk_start *= 512; - blk_end *= 512; - } - - start = eos_time_get_tick(); - rv = sdc_cmd(ERASE_WR_BLK_START, blk_start, 0, timeout); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - rv = sdc_cmd(ERASE_WR_BLK_END, blk_end, 0, sdc_nto(start, timeout)); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - rv = sdc_cmd(ERASE, 0, 0, sdc_nto(start, timeout)); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - - return eos_sdc_sync(sdc_nto(start, timeout)); -} - -int eos_sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer) { - int rv; - uint8_t cmd = ((count == 1) ? READ_SINGLE_BLOCK : READ_MULTIPLE_BLOCK); - - if (!(sdc_type & EOS_SDC_CAP_BLK)) sect *= 512; - - sdc_select(); - rv = sdc_cmd(cmd, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); - if (rv == SDC_R1_READY) { - int _rv = SDC_R1_READY; - - while (count) { - rv = sdc_block_read(buffer, 512, SDC_TIMEOUT_READ); - if (rv) break; - eos_sdcc_decrypt(sect, buffer); - buffer += 512; - count--; - } - if (cmd == READ_MULTIPLE_BLOCK) _rv = sdc_cmd(STOP_TRANSMISSION, 0, SDC_CMD_FLAG_NOCS | SDC_CMD_FLAG_NOWAIT | SDC_CMD_FLAG_RSTUFF, 0); - if (!rv && (_rv != SDC_R1_READY)) rv = SDC_ERR(_rv); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - - return rv; -} - -int eos_sdc_sect_write(uint32_t sect, unsigned int count, uint8_t *buffer) { - int rv; - - if (!(sdc_type & EOS_SDC_CAP_BLK)) sect *= 512; - - if (count == 1) { - sdc_select(); - rv = sdc_cmd(WRITE_BLOCK, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); - if (rv == SDC_R1_READY) { - eos_sdcc_encrypt(sect, buffer); - rv = sdc_block_write(SDC_TOKEN_START_BLK, buffer, 512, SDC_TIMEOUT_WRITE); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - } else { - if (sdc_type & EOS_SDC_TYPE_SDC) { - rv = sdc_acmd(SET_WR_BLK_ERASE_COUNT, count, 0, SDC_TIMEOUT_CMD); - if (rv != SDC_R1_READY) return SDC_ERR(rv); - } - - sdc_select(); - rv = sdc_cmd(WRITE_MULTIPLE_BLOCK, sect, SDC_CMD_FLAG_NOCS, SDC_TIMEOUT_CMD); - if (rv == SDC_R1_READY) { - int _rv; - - while (count) { - eos_sdcc_encrypt(sect, buffer); - rv = sdc_block_write(SDC_TOKEN_START_BLKM, buffer, 512, SDC_TIMEOUT_WRITE); - if (rv) break; - buffer += 512; - count--; - } - _rv = sdc_block_write(SDC_TOKEN_STOP_TRAN, NULL, 0, SDC_TIMEOUT_WRITE); - if (!rv && (_rv != SDC_R1_READY)) rv = SDC_ERR(_rv); - } else { - rv = SDC_ERR(rv); - } - sdc_deselect(); - } - - return rv; -} diff --git a/fw/fe310/eos/sdcard.h b/fw/fe310/eos/sdcard.h deleted file mode 100644 index 910a6e0..0000000 --- a/fw/fe310/eos/sdcard.h +++ /dev/null @@ -1,22 +0,0 @@ -#include - -#define EOS_SDC_TYPE_MMC 0x01 - -#define EOS_SDC_TYPE_SDC1 0x04 -#define EOS_SDC_TYPE_SDC2 0x08 -#define EOS_SDC_TYPE_SDC 0x0c -#define EOS_SDC_TYPE_MASK 0x0f - -#define EOS_SDC_CAP_BLK 0x10 -#define EOS_SDC_CAP_ERASE_EN 0x20 -#define EOS_SDC_CAP_MASK 0xf0 - -int eos_sdc_init(uint8_t wakeup_cause); -uint8_t eos_sdc_type(void); -uint8_t eos_sdc_cap(void); -int eos_sdc_get_sect_count(uint32_t timeout, uint32_t *sectors); -int eos_sdc_get_blk_size(uint32_t timeout, uint32_t *size); -int eos_sdc_sync(uint32_t timeout); -int eos_sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout); -int eos_sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer); -int eos_sdc_sect_write(uint32_t sect, unsigned int count, uint8_t *buffer); diff --git a/fw/fe310/eos/soc/i2c.c b/fw/fe310/eos/soc/i2c.c new file mode 100644 index 0000000..a507af1 --- /dev/null +++ b/fw/fe310/eos/soc/i2c.c @@ -0,0 +1,145 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" +#include "prci_driver.h" + +#include "eos.h" +#include "i2s.h" +#include "i2c.h" + +int eos_i2c_init(uint8_t wakeup_cause) { + eos_i2c_speed(EOS_I2C_SPEED); + // eos_i2c_start(); + + return EOS_OK; +} + +void eos_i2c_start(void) { + I2C0_REGB(I2C_CONTROL) |= I2C_CONTROL_EN; + GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_I2C0_MASK; + GPIO_REG(GPIO_IOF_EN) |= IOF0_I2C0_MASK; +} + +void eos_i2c_stop(void) { + GPIO_REG(GPIO_IOF_EN) &= ~IOF0_I2C0_MASK; + I2C0_REGB(I2C_CONTROL) &= ~I2C_CONTROL_EN; +} + +void eos_i2c_speed(uint32_t baud_rate) { + unsigned long clock_rate = PRCI_get_cpu_freq(); + uint16_t prescaler = (clock_rate / (baud_rate * 5)) - 1; + + I2C0_REGB(I2C_PRESCALE_LOW) = prescaler & 0xFF; + I2C0_REGB(I2C_PRESCALE_HIGH) = (prescaler >> 8) & 0xFF; +} + + +static int i2c_read(uint8_t cmd) { + I2C0_REGB(I2C_COMMAND) = I2C_CMD_READ | cmd; + while (I2C0_REGB(I2C_STATUS) & I2C_STATUS_TIP); + + return I2C0_REGB(I2C_RECEIVE); +} + +static int i2c_write(uint8_t cmd, uint8_t b) { + I2C0_REGB(I2C_TRANSMIT) = b; + I2C0_REGB(I2C_COMMAND) = I2C_CMD_WRITE | cmd; + while (I2C0_REGB(I2C_STATUS) & I2C_STATUS_TIP); + + if (I2C0_REGB(I2C_STATUS) & I2C_STATUS_RXACK) return EOS_ERR; + return EOS_OK; +} + +static int i2c_addr(uint8_t addr, uint8_t rw_flag) { + return i2c_write(I2C_CMD_START, ((addr & 0x7F) << 1) | (rw_flag & 0x1)); +} + +int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t len) { + int rv; + int i; + + rv = i2c_addr(addr, I2C_WRITE); + if (rv) return rv; + + rv = i2c_write(0, reg); + if (rv) return rv; + + rv = i2c_addr(addr, I2C_READ); + if (rv) return rv; + + for (i=0; i> 8); + if (rv) return rv; + + rv = i2c_write(0, reg & 0xff); + if (rv) return rv; + + rv = i2c_addr(addr, I2C_READ); + if (rv) return rv; + + for (i=0; i> 8); + if (rv) return rv; + + rv = i2c_write(0, reg & 0xff); + if (rv) return rv; + + for (i=0; i + +#define EOS_I2C_SPEED 100000 + +int eos_i2c_init(uint8_t wakeup_cause); +int eos_i2c_run(uint8_t wakeup_cause); +void eos_i2c_start(void); +void eos_i2c_stop(void); +void eos_i2c_speed(uint32_t baud_rate); +int eos_i2c_read8(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t len); +int eos_i2c_read16(uint8_t addr, uint16_t reg, uint8_t *buffer, uint16_t len); +int eos_i2c_write8(uint8_t addr, uint8_t reg, uint8_t *buffer, uint16_t len); +int eos_i2c_write16(uint8_t addr, uint16_t reg, uint8_t *buffer, uint16_t len); diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c new file mode 100644 index 0000000..9cc9d9c --- /dev/null +++ b/fw/fe310/eos/soc/i2s.c @@ -0,0 +1,477 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" +#include "prci_driver.h" + +#include "eos.h" +#include "interrupt.h" +#include "event.h" + +#include "board.h" + +#include "i2s.h" +#include "i2s_priv.h" + +#define I2S_REG_CK(o) _REG32(I2S_CTRL_ADDR_CK, o) +#define I2S_REG_WS_MIC(o) _REG32(I2S_CTRL_ADDR_WS_MIC, o) +#define I2S_REG_WS_SPK(o) _REG32(I2S_CTRL_ADDR_WS_SPK, o) + +#define I2S_PIN_PWM ((1 << I2S_PIN_CK) | (1 << I2S_PIN_CK_SW) | (1 << I2S_PIN_WS_MIC) | (1 << I2S_PIN_WS_SPK)) + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) + +#define EOS_ABUF_IDX_MASK(IDX, SIZE) ((IDX) & ((SIZE) - 1)) + +EOSABuf i2s_mic_buf; +EOSABuf i2s_spk_buf; + +static eos_i2s_handler_t i2s_mic_handler = NULL; +static eos_i2s_handler_t i2s_spk_handler = NULL; +static uint32_t i2s_clk_period; +static uint8_t i2s_mic_volume = 0; /* 0 - 8 */ +static uint8_t i2s_spk_volume = 16; /* 0 - 16 */ + +uint32_t _eos_i2s_drvr[] = { + 0, /* I2S_MIC_BUF */ + 0, /* I2S_SPK_BUF */ + EOS_I2S_FMT_PCM16, /* I2S_FMT */ + EOS_I2S_MODE_STEREO, /* I2S_MODE */ + 0, /* I2S_MIC_WM */ + 0, /* I2S_SPK_WM */ + 0, /* I2S_MIC_EVT */ + 0, /* I2S_SPK_EVT */ + 0, /* I2S_MIC_CMP2 */ + 0, /* I2S_MIC_CMP3 */ + 0, /* I2S_SAMPLE */ +}; + +#define I2S_MIC_BUF 0 +#define I2S_SPK_BUF 1 +#define I2S_FMT 2 +#define I2S_MODE 3 +#define I2S_MIC_WM 4 +#define I2S_SPK_WM 5 +#define I2S_MIC_EVT 6 +#define I2S_SPK_EVT 7 +#define I2S_MIC_CMP2 8 +#define I2S_MIC_CMP3 9 +#define I2S_SAMPLE 10 + +static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { + buf->idx_r = 0; + buf->idx_w = 0; + buf->size = size; + buf->array = array; +} + +static int _abuf_push8(EOSABuf *buf, uint8_t sample) { + if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL; + + buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample; + buf->idx_w++; + return EOS_OK; +} + +static int _abuf_push16(EOSABuf *buf, uint16_t sample) { + if ((uint16_t)(buf->idx_w - buf->idx_r) == buf->size) return EOS_ERR_FULL; + + buf->array[EOS_ABUF_IDX_MASK(buf->idx_w, buf->size)] = sample >> 8; + buf->array[EOS_ABUF_IDX_MASK(buf->idx_w + 1, buf->size)] = sample & 0xFF; + buf->idx_w += 2; + return EOS_OK; +} + +static int _abuf_pop8(EOSABuf *buf, uint8_t *sample) { + if (buf->idx_r == buf->idx_w) { + return EOS_ERR_EMPTY; + } else { + *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)]; + buf->idx_r++; + return EOS_OK; + } +} + +static int _abuf_pop16(EOSABuf *buf, uint16_t *sample) { + if (buf->idx_r == buf->idx_w) { + return EOS_ERR_EMPTY; + } else { + *sample = buf->array[EOS_ABUF_IDX_MASK(buf->idx_r, buf->size)] << 8; + *sample |= buf->array[EOS_ABUF_IDX_MASK(buf->idx_r + 1, buf->size)]; + buf->idx_r += 2; + return EOS_OK; + } +} + +static void _abuf_flush(EOSABuf *buf) { + buf->idx_r = 0; + buf->idx_w = 0; +} + +static uint16_t _abuf_len(EOSABuf *buf) { + return buf->idx_w - buf->idx_r; +} + +static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + switch(type & ~EOS_EVT_MASK) { + case EOS_I2S_ETYPE_MIC: + if (i2s_mic_handler) { + i2s_mic_handler(type); + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_drvr[I2S_MIC_EVT] = 1; + set_csr(mstatus, MSTATUS_MIE); + } + break; + + case EOS_I2S_ETYPE_SPK: + if (i2s_spk_handler) { + i2s_spk_handler(type); + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_drvr[I2S_SPK_EVT] = 1; + set_csr(mstatus, MSTATUS_MIE); + } + break; + + default: + eos_evtq_bad_handler(type, buffer, len); + break; + } +} + +#define PLIC_PRIORITY 0x0C000000 + +static void i2s_cmp_set(void) { + int c = 7; /* interrupt will trigger c i2s clocks before spk ws */ + int spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; + volatile uint32_t *p = (uint32_t *)PLIC_PRIORITY+I2S_IRQ_SD_ID; + + /* interrupt trigger - will start with left channel */ + if (spk_ws_offset - c < 0) { + I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (64 + spk_ws_offset - c); + } else { + I2S_REG_WS_SPK(PWM_CMP3) = i2s_clk_period * (spk_ws_offset - c); + } + + /* disable interrupt for this cycle */ + *p = 0; + + /* empty buffers */ + // i2s_mic_buf.idx_r = i2s_mic_buf.idx_w; + // i2s_spk_buf.idx_w = i2s_spk_buf.idx_r; + + /* adjust spk ws relative to mic ws */ + if (spk_ws_offset <= 0) { + spk_ws_offset += 32; + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); + } else { + GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << I2S_PIN_WS_SPK); + } + I2S_REG_WS_SPK(PWM_CMP1) = i2s_clk_period * spk_ws_offset; + I2S_REG_WS_SPK(PWM_CMP2) = i2s_clk_period * (32 + spk_ws_offset); + + /* mic cmp2 relative to interrupt trigger */ + _eos_i2s_drvr[I2S_MIC_CMP2] = (17 + c - i2s_spk_volume) * i2s_clk_period; /* (17 + c - i2s_spk_volume) == (1 + i2s_mic_volume) - (spk_ws_offset - c) */ + _eos_i2s_drvr[I2S_MIC_CMP3] = 16 * i2s_clk_period; +} + +extern void _eos_i2s_start_pwm(void); + +int eos_i2s_init(uint8_t wakeup_cause) { + eos_evtq_set_handler(EOS_EVT_I2S, i2s_handle_evt); + + I2S_REG_CK(PWM_CFG) = 0; + I2S_REG_WS_MIC(PWM_CFG) = 0; + I2S_REG_WS_SPK(PWM_CFG) = 0; + + eos_i2s_init_mux(); + + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_CK_SR); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK_SW); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK_SR); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK_SR); + + return EOS_OK; +} + +void eos_i2s_init_mux(void) { + GPIO_REG(GPIO_OUTPUT_VAL) &= ~((1 << I2S_PIN_CK) | (1 << I2S_PIN_WS_MIC) | (1 << I2S_PIN_WS_SPK)); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_CK); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_CK); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_SPK); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_SPK); + + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_IN); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); +} + +void eos_i2s_start(uint32_t sample_rate) { + i2s_clk_period = ((PRCI_get_cpu_freq() / (sample_rate * 64)) & ~I2S_PWM_SCALE_CK_MASK) + 1; + + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_IN); + + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << I2S_PIN_SD_OUT); + + I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> I2S_PWM_SCALE_CK; + I2S_REG_CK(PWM_CMP1) = I2S_REG_CK(PWM_CMP0) / 2; + I2S_REG_CK(PWM_CMP2) = 0; + I2S_REG_CK(PWM_CMP3) = 0; + + I2S_REG_WS_MIC(PWM_CMP0) = i2s_clk_period * 64 - 1; + I2S_REG_WS_MIC(PWM_CMP1) = i2s_clk_period * 32; + + I2S_REG_WS_SPK(PWM_CMP0) = i2s_clk_period * 64 - 1; + i2s_cmp_set(); + + I2S_REG_CK(PWM_COUNT) = 0; + I2S_REG_WS_MIC(PWM_COUNT) = 0; + I2S_REG_WS_SPK(PWM_COUNT) = i2s_clk_period / 2; + + if (i2s_mic_buf.array && i2s_mic_buf.size) { + _eos_i2s_drvr[I2S_MIC_BUF] = (uint32_t)&i2s_mic_buf; + if (_eos_i2s_drvr[I2S_MIC_WM] == 0) { + _eos_i2s_drvr[I2S_MIC_WM] = i2s_mic_buf.size / 2; + } + } + if (i2s_spk_buf.array && i2s_spk_buf.size) { + _eos_i2s_drvr[I2S_SPK_BUF] = (uint32_t)&i2s_spk_buf; + if (_eos_i2s_drvr[I2S_SPK_WM] == 0) { + _eos_i2s_drvr[I2S_SPK_WM] = i2s_spk_buf.size / 2; + } + } + if (i2s_mic_handler) _eos_i2s_drvr[I2S_MIC_EVT] = 1; + if (i2s_spk_handler) _eos_i2s_drvr[I2S_SPK_EVT] = 1; + + eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD); + eos_intr_set_priority(I2S_IRQ_WS_ID, IRQ_PRIORITY_I2S_WS); + eos_intr_enable(I2S_IRQ_SD_ID); + eos_intr_enable(I2S_IRQ_WS_ID); + + _eos_i2s_start_pwm(); + /* + I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK; + I2S_REG_WS_MIC(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG; + I2S_REG_WS_SPK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG; + */ + + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_WS_MIC); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_WS_MIC); + + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SR); + GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; + GPIO_REG(GPIO_IOF_EN) |= I2S_PIN_PWM; +} + +void eos_i2s_stop(void) { + I2S_REG_CK(PWM_CFG) = 0; + I2S_REG_WS_MIC(PWM_CFG) = 0; + I2S_REG_WS_SPK(PWM_CFG) = 0; + I2S_REG_CK(PWM_COUNT) = 0; + I2S_REG_WS_MIC(PWM_COUNT) = 0; + I2S_REG_WS_SPK(PWM_COUNT) = 0; + + _eos_i2s_drvr[I2S_MIC_BUF] = 0; + _eos_i2s_drvr[I2S_MIC_EVT] = 0; + _eos_i2s_drvr[I2S_MIC_WM] = 0; + + _eos_i2s_drvr[I2S_SPK_BUF] = 0; + _eos_i2s_drvr[I2S_SPK_EVT] = 0; + _eos_i2s_drvr[I2S_SPK_WM] = 0; + + eos_intr_disable(I2S_IRQ_WS_ID); + eos_intr_disable(I2S_IRQ_SD_ID); + + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_CK_SW); + GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_CK_SR); + + GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); + GPIO_REG(GPIO_IOF_EN) &= ~I2S_PIN_PWM; + + eos_i2s_mic_set_wm(0); + eos_i2s_spk_set_wm(0); +} + +int eos_i2s_running(void) { + return !!(GPIO_REG(GPIO_IOF_EN) & (1 << I2S_PIN_CK)); +} + +void eos_i2s_set_fmt(unsigned char fmt) { + _eos_i2s_drvr[I2S_FMT] = fmt; +} + +void eos_i2s_set_mode(unsigned char mode) { + _eos_i2s_drvr[I2S_MODE] = mode; +} + +void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size) { + clear_csr(mstatus, MSTATUS_MIE); + _abuf_init(&i2s_mic_buf, mic_arr, mic_arr_size); + set_csr(mstatus, MSTATUS_MIE); +} + +void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler) { + clear_csr(mstatus, MSTATUS_MIE); + i2s_mic_handler = wm_handler; + set_csr(mstatus, MSTATUS_MIE); +} + +void eos_i2s_mic_set_wm(uint16_t wm) { + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_drvr[I2S_MIC_WM] = wm; + set_csr(mstatus, MSTATUS_MIE); + +} + +uint16_t eos_i2s_mic_len(void) { + clear_csr(mstatus, MSTATUS_MIE); + uint16_t ret = _abuf_len(&i2s_mic_buf); + set_csr(mstatus, MSTATUS_MIE); + return ret; +} + +uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { + uint16_t i; + uint16_t _ssize = 0; + + clear_csr(mstatus, MSTATUS_MIE); + _ssize = MIN(ssize, _abuf_len(&i2s_mic_buf)); + set_csr(mstatus, MSTATUS_MIE); + + for (i=0; i<_ssize; i++) { + sample[i] = i2s_mic_buf.array[EOS_ABUF_IDX_MASK(i2s_mic_buf.idx_r + i, i2s_mic_buf.size)]; + } + + clear_csr(mstatus, MSTATUS_MIE); + i2s_mic_buf.idx_r += _ssize; + set_csr(mstatus, MSTATUS_MIE); + + return _ssize; +} + +int eos_i2s_mic_pop8(uint8_t *sample) { + int ret; + + clear_csr(mstatus, MSTATUS_MIE); + ret = _abuf_pop8(&i2s_mic_buf, sample); + set_csr(mstatus, MSTATUS_MIE); + + return ret; +} + +int eos_i2s_mic_pop16(uint16_t *sample) { + int ret; + + clear_csr(mstatus, MSTATUS_MIE); + ret = _abuf_pop16(&i2s_mic_buf, sample); + set_csr(mstatus, MSTATUS_MIE); + + return ret; +} + +int eos_i2s_mic_vol_get(void) { + return i2s_mic_volume; +} + +void eos_i2s_mic_vol_set(int vol) { + if ((vol < 0) || (vol > 8)) return; + + i2s_mic_volume = vol; + + clear_csr(mstatus, MSTATUS_MIE); + i2s_cmp_set(); + set_csr(mstatus, MSTATUS_MIE); +} + +void eos_i2s_spk_init(uint8_t *spk_arr, uint16_t spk_arr_size) { + clear_csr(mstatus, MSTATUS_MIE); + _abuf_init(&i2s_spk_buf, spk_arr, spk_arr_size); + set_csr(mstatus, MSTATUS_MIE); +} + +void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler) { + clear_csr(mstatus, MSTATUS_MIE); + i2s_spk_handler = wm_handler; + set_csr(mstatus, MSTATUS_MIE); +} + +void eos_i2s_spk_set_wm(uint16_t wm) { + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_drvr[I2S_SPK_WM] = wm; + set_csr(mstatus, MSTATUS_MIE); +} + +uint16_t eos_i2s_spk_len(void) { + clear_csr(mstatus, MSTATUS_MIE); + uint16_t ret = _abuf_len(&i2s_spk_buf); + set_csr(mstatus, MSTATUS_MIE); + return ret; +} + +uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize) { + uint16_t i; + uint16_t _ssize = 0; + + clear_csr(mstatus, MSTATUS_MIE); + _ssize = MIN(ssize, i2s_spk_buf.size - _abuf_len(&i2s_spk_buf)); + set_csr(mstatus, MSTATUS_MIE); + + for (i=0; i<_ssize; i++) { + i2s_spk_buf.array[EOS_ABUF_IDX_MASK(i2s_spk_buf.idx_w + i, i2s_spk_buf.size)] = sample[i]; + } + + clear_csr(mstatus, MSTATUS_MIE); + i2s_spk_buf.idx_w += _ssize; + set_csr(mstatus, MSTATUS_MIE); + + return _ssize; +} + +int eos_i2s_spk_push8(uint8_t sample) { + int ret; + + clear_csr(mstatus, MSTATUS_MIE); + ret = _abuf_push8(&i2s_spk_buf, sample); + set_csr(mstatus, MSTATUS_MIE); + + return ret; +} + +int eos_i2s_spk_push16(uint16_t sample) { + int ret; + + clear_csr(mstatus, MSTATUS_MIE); + ret = _abuf_push16(&i2s_spk_buf, sample); + set_csr(mstatus, MSTATUS_MIE); + + return ret; +} + +int eos_i2s_spk_vol_get(void) { + return i2s_spk_volume; +} + +void eos_i2s_spk_vol_set(int vol) { + if ((vol < 0) || (vol > 16)) return; + + i2s_spk_volume = vol; + + clear_csr(mstatus, MSTATUS_MIE); + i2s_cmp_set(); + set_csr(mstatus, MSTATUS_MIE); +} diff --git a/fw/fe310/eos/soc/i2s.h b/fw/fe310/eos/soc/i2s.h new file mode 100644 index 0000000..81b4ade --- /dev/null +++ b/fw/fe310/eos/soc/i2s.h @@ -0,0 +1,38 @@ +#include + +#include "i2s_def.h" + +typedef struct EOSABuf { + uint16_t idx_r; + uint16_t idx_w; + uint16_t size; + uint8_t *array; +} EOSABuf; + +typedef void (*eos_i2s_handler_t) (unsigned char); + +int eos_i2s_init(uint8_t wakeup_cause); +void eos_i2s_init_mux(void); +void eos_i2s_start(uint32_t sample_rate); +void eos_i2s_stop(void); +int eos_i2s_running(void); +void eos_i2s_set_fmt(unsigned char fmt); +void eos_i2s_set_mode(unsigned char mode); +void eos_i2s_mic_init(uint8_t *mic_arr, uint16_t mic_arr_size); +void eos_i2s_mic_set_handler(eos_i2s_handler_t wm_handler); +void eos_i2s_mic_set_wm(uint16_t wm); +uint16_t eos_i2s_mic_len(void); +uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize); +int eos_i2s_mic_pop8(uint8_t *sample); +int eos_i2s_mic_pop16(uint16_t *sample); +int eos_i2s_mic_vol_get(void); +void eos_i2s_mic_vol_set(int vol); +void eos_i2s_spk_init(uint8_t *mic_arr, uint16_t mic_arr_size); +void eos_i2s_spk_set_handler(eos_i2s_handler_t wm_handler); +void eos_i2s_spk_set_wm(uint16_t wm); +uint16_t eos_i2s_spk_len(void); +uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize); +int eos_i2s_spk_push8(uint8_t sample); +int eos_i2s_spk_push16(uint16_t sample); +int eos_i2s_spk_vol_get(void); +void eos_i2s_spk_vol_set(int vol); diff --git a/fw/fe310/eos/soc/i2s_def.h b/fw/fe310/eos/soc/i2s_def.h new file mode 100644 index 0000000..3529be1 --- /dev/null +++ b/fw/fe310/eos/soc/i2s_def.h @@ -0,0 +1,8 @@ +#define EOS_I2S_FMT_PCM16 0 +#define EOS_I2S_FMT_ALAW 1 + +#define EOS_I2S_MODE_STEREO 0 +#define EOS_I2S_MODE_MONO 1 + +#define EOS_I2S_ETYPE_MIC 1 +#define EOS_I2S_ETYPE_SPK 2 diff --git a/fw/fe310/eos/soc/i2s_priv.h b/fw/fe310/eos/soc/i2s_priv.h new file mode 100644 index 0000000..25237c3 --- /dev/null +++ b/fw/fe310/eos/soc/i2s_priv.h @@ -0,0 +1,8 @@ +#define I2S_PWM_SCALE_CK 2 +#define I2S_PWM_SCALE_CK_MASK 0x0003 + +/* asm */ +#define I2S_ABUF_OFF_IDXR 0 +#define I2S_ABUF_OFF_IDXW 2 +#define I2S_ABUF_OFF_SIZE 4 +#define I2S_ABUF_OFF_ARRAY 8 diff --git a/fw/fe310/eos/soc/interrupt.c b/fw/fe310/eos/soc/interrupt.c new file mode 100644 index 0000000..dab6fab --- /dev/null +++ b/fw/fe310/eos/soc/interrupt.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +#include "encoding.h" +#include "platform.h" +#include "plic_driver.h" + +#include "eos.h" +#include "interrupt.h" + +// Global Instance data for the PLIC +// for use by the PLIC Driver. +static plic_instance_t plic; + +static eos_intr_handler_t ext_interrupt_handler[PLIC_NUM_INTERRUPTS]; + +uintptr_t eos_intr_handle(uintptr_t int_num) { + if ((int_num >=1) && (int_num <= PLIC_NUM_INTERRUPTS) && (ext_interrupt_handler[int_num-1])) { + ext_interrupt_handler[int_num-1](); + } else { + printf("INTR ERROR:%d\n", int_num); + exit(int_num); + } + return int_num; +} + +int eos_intr_init(uint8_t wakeup_cause) { + for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){ + ext_interrupt_handler[i] = NULL; + } + + /************************************************************************** + * Set up the PLIC + **************************************************************************/ + PLIC_init(&plic, + PLIC_CTRL_ADDR, + PLIC_NUM_INTERRUPTS, + PLIC_NUM_PRIORITIES); + + // Enable Global (PLIC) interrupts. + set_csr(mie, MIP_MEIP); + + // Enable all interrupts + set_csr(mstatus, MSTATUS_MIE); + + return EOS_OK; +} + +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_handler_t handler) { + ext_interrupt_handler[int_num-1] = handler; + PLIC_set_priority(&plic, int_num, priority); + PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_set_handler(uint8_t int_num, eos_intr_handler_t handler) { + ext_interrupt_handler[int_num-1] = handler; +} + +void eos_intr_set_priority(uint8_t int_num, uint8_t priority) { + PLIC_set_priority(&plic, int_num, priority); +} + +void eos_intr_enable(uint8_t int_num) { + PLIC_enable_interrupt(&plic, int_num); +} + +void eos_intr_disable(uint8_t int_num) { + PLIC_disable_interrupt(&plic, int_num); +} + +void eos_intr_mask(uint8_t priority) { + PLIC_set_threshold(&plic, priority); +} diff --git a/fw/fe310/eos/soc/interrupt.h b/fw/fe310/eos/soc/interrupt.h new file mode 100644 index 0000000..a239934 --- /dev/null +++ b/fw/fe310/eos/soc/interrupt.h @@ -0,0 +1,13 @@ +#include + +#include "irq_def.h" + +typedef void (*eos_intr_handler_t) (void); + +int eos_intr_init(uint8_t wakeup_cause); +void eos_intr_set(uint8_t int_num, uint8_t priority, eos_intr_handler_t handler); +void eos_intr_set_handler(uint8_t int_num, eos_intr_handler_t handler); +void eos_intr_set_priority(uint8_t int_num, uint8_t priority); +void eos_intr_enable(uint8_t int_num); +void eos_intr_disable(uint8_t int_num); +void eos_intr_mask(uint8_t priority); \ No newline at end of file diff --git a/fw/fe310/eos/soc/net.c b/fw/fe310/eos/soc/net.c new file mode 100644 index 0000000..33b71c2 --- /dev/null +++ b/fw/fe310/eos/soc/net.c @@ -0,0 +1,602 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "msgq.h" +#include "interrupt.h" +#include "event.h" +#include "timer.h" +#include "pwr.h" + +#include "board.h" + +#include "spi.h" +#include "spi_priv.h" +#include "spi_dev.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_intr_set_handler(INT_SPI1_BASE, net_handle_xchg); + SPI1_REG(SPI_REG_SCKDIV) = eos_spi_div(EOS_SPI_DEV_NET); + SPI1_REG(SPI_REG_CSID) = eos_spi_csid(EOS_SPI_DEV_NET); +} + +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 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/soc/net.h b/fw/fe310/eos/soc/net.h new file mode 100644 index 0000000..79caf4b --- /dev/null +++ b/fw/fe310/eos/soc/net.h @@ -0,0 +1,47 @@ +#include +#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/soc/pwr.c b/fw/fe310/eos/soc/pwr.c new file mode 100644 index 0000000..802e593 --- /dev/null +++ b/fw/fe310/eos/soc/pwr.c @@ -0,0 +1,133 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "event.h" +#include "timer.h" +#include "spi.h" +#include "spi_dev.h" +#include "net.h" +#include "lcd.h" +#include "eve/eve.h" + +#include "pwr.h" + +#define PWR_RTC_SCALE 15 +#define PWR_RTC_SFREQ (EOS_TIMER_RTC_FREQ >> PWR_RTC_SCALE) + +static eos_evt_handler_t evt_handler[EOS_PWR_MAX_MTYPE]; +static unsigned char power_btn_down; + +int eos_pwr_init(uint8_t wakeup_cause) { + AON_REG(AON_PMUKEY) = 0x51F15E; + AON_REG(AON_PMUIE) = 0x5; + + AON_REG(AON_RTCCMP) = 0xFFFFFFFF; + AON_REG(AON_RTCCFG) = PWR_RTC_SCALE; + AON_REG(AON_RTCHI) = 0; + AON_REG(AON_RTCLO) = 0; + + return EOS_OK; +} + +uint8_t eos_pwr_wakeup_cause(void) { + return AON_REG(AON_PMUCAUSE) & 0xff; +} + +uint8_t eos_pwr_reset_cause(void) { + return (AON_REG(AON_PMUCAUSE) >> 8) & 0xff; +} + +int eos_pwr_sleep(void) { + int rv; + + rv = eos_lcd_sleep(); + if (rv) return rv; + + eos_spi_select(EOS_SPI_DEV_EVE); + eve_pwr_sleep(); + eos_spi_deselect(); + + rv = eos_net_sleep(1000); + if (rv) return rv; + + AON_REG(AON_PMUKEY) = 0x51F15E; + AON_REG(AON_PMUSLEEP) = 1; + + return EOS_OK; +} + +void eos_pwr_wake_at(uint32_t msec) { + uint32_t pmuie; + + AON_REG(AON_RTCCFG) |= AON_RTCCFG_ENALWAYS; + AON_REG(AON_RTCCMP) = msec * PWR_RTC_SFREQ / 1000; + + pmuie = AON_REG(AON_PMUIE) | 0x2; + AON_REG(AON_PMUKEY) = 0x51F15E; + AON_REG(AON_PMUIE) = pmuie; +} + +void eos_pwr_wake_disable(void) { + uint32_t pmuie; + + AON_REG(AON_RTCCMP) = 0xFFFFFFFF; + AON_REG(AON_RTCCFG) &= ~AON_RTCCFG_ENALWAYS; + AON_REG(AON_RTCHI) = 0; + AON_REG(AON_RTCLO) = 0; + + pmuie = AON_REG(AON_PMUIE) & ~0x2; + AON_REG(AON_PMUKEY) = 0x51F15E; + AON_REG(AON_PMUIE) = pmuie; +} + +static void pwr_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char mtype; + + if ((buffer == NULL) || (len < 1)) { + eos_net_bad_handler(type, buffer, len); + return; + } + + mtype = buffer[0]; + if ((mtype < EOS_PWR_MAX_MTYPE) && evt_handler[mtype]) { + evt_handler[mtype](mtype, buffer, len); + } else { + eos_net_bad_handler(type, buffer, len); + } +} + +static void pwr_handle_btn(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char level = buffer[1]; + + eos_net_free(buffer, 0); + if (!level) { + power_btn_down = 1; + return; + } + if (!power_btn_down) return; + + eos_pwr_sleep(); +} + +void eos_pwr_netinit(void) { + int i; + + for (i=0; i +#include "event.h" + +#define EOS_PWR_MTYPE_BUTTON 1 + +#define EOS_PWR_MAX_MTYPE 2 + +#define EOS_PWR_WAKE_RST 0 +#define EOS_PWR_WAKE_RTC 1 +#define EOS_PWR_WAKE_BTN 2 + +#define EOS_PWR_RST_PWRON 0 +#define EOS_PWR_RST_EXT 1 +#define EOS_PWR_RST_WDOG 2 + +int eos_pwr_init(uint8_t wakeup_cause); +uint8_t eos_pwr_wakeup_cause(void); +uint8_t eos_pwr_reset_cause(void); +int eos_pwr_sleep(void); +void eos_pwr_wake_at(uint32_t msec); +void eos_pwr_wake_disable(void); + +void eos_pwr_netinit(void); +void eos_pwr_set_handler(unsigned char mtype, eos_evt_handler_t handler); +eos_evt_handler_t eos_pwr_get_handler(unsigned char mtype); \ No newline at end of file diff --git a/fw/fe310/eos/soc/spi.c b/fw/fe310/eos/soc/spi.c new file mode 100644 index 0000000..05c9448 --- /dev/null +++ b/fw/fe310/eos/soc/spi.c @@ -0,0 +1,350 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "msgq.h" +#include "interrupt.h" +#include "event.h" + +#include "board.h" + +#include "spi.h" +#include "spi_priv.h" + +#define SPI_MODE0 0x00 +#define SPI_MODE1 0x01 +#define SPI_MODE2 0x02 +#define SPI_MODE3 0x03 + +#define SPI_FLAG_XCHG 0x10 + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) + +static uint8_t spi_cspin; +static volatile uint8_t spi_state_flags; +static unsigned char spi_evt; +static unsigned char spi_in_xchg; + +static uint32_t spi_state_len = 0; +static uint32_t spi_state_idx_tx = 0; +static uint32_t spi_state_idx_rx = 0; +static unsigned char *spi_state_buf = NULL; + +static eos_evt_handler_t evt_handler[EOS_SPI_MAX_EVT]; + +static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char idx = (type & ~EOS_EVT_MASK) - 1; + if (idx < EOS_SPI_MAX_EVT) { + evt_handler[idx](type, buffer, len); + } else { + eos_evtq_bad_handler(type, buffer, len); + } +} + +int eos_spi_init(uint8_t wakeup_cause) { + int i; + + for (i=0; i> 8; + } else { + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0xFF00) >> 8; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF); + } + + if (rx) { + if (flags & EOS_SPI_FLAG_BSWAP) { + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF); + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 8; + } else { + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 8; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF); + } + } + + return r; +} + +uint32_t eos_spi_xchg24(uint32_t data, uint8_t flags) { + volatile uint32_t x = 0; + uint8_t rx = !(flags & EOS_SPI_FLAG_TX); + uint32_t r = 0; + + spi_state_flags &= 0xF0; + spi_state_flags |= flags; + + if (flags & EOS_SPI_FLAG_BSWAP) { + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; + } else { + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); + } + + if (rx) { + if (flags & EOS_SPI_FLAG_BSWAP) { + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF); + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 8; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 16; + } else { + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 16; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 8; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF); + } + } + + return r; +} + +uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags) { + volatile uint32_t x = 0; + uint8_t rx = !(flags & EOS_SPI_FLAG_TX); + uint32_t r = 0; + + spi_state_flags &= 0xF0; + spi_state_flags |= flags; + + if (flags & EOS_SPI_FLAG_BSWAP) { + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0xFF000000) >> 24; + } else { + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0xFF000000) >> 24; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; + while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); + SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); + } + + if (rx) { + if (flags & EOS_SPI_FLAG_BSWAP) { + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF); + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 8; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 16; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 24; + } else { + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 24; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 16; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF) << 8; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + r |= (x & 0xFF); + } + } + + return r; +} + +void eos_spi_flush(void) { + volatile uint32_t x = 0; + + if (spi_in_xchg) spi_xchg_finish(); + + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); + while (!x) { + if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) x = SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY; + } +} diff --git a/fw/fe310/eos/soc/spi.h b/fw/fe310/eos/soc/spi.h new file mode 100644 index 0000000..a23a235 --- /dev/null +++ b/fw/fe310/eos/soc/spi.h @@ -0,0 +1,28 @@ +#include +#include "event.h" + +#define EOS_SPI_FLAG_TX 0x01 +#define EOS_SPI_FLAG_MORE 0x02 +#define EOS_SPI_FLAG_BSWAP 0x04 + +#define EOS_SPI_EVT_SDC 1 +#define EOS_SPI_EVT_CAM 2 + +#define EOS_SPI_MAX_EVT 2 + +int eos_spi_init(uint8_t wakeup_cause); +void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt); +void eos_spi_stop(void); +void eos_spi_set_handler(unsigned char evt, eos_evt_handler_t handler); + +void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags); +void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags); +void eos_spi_handle_xchg(void); + +void eos_spi_cs_set(void); +void eos_spi_cs_clear(void); +uint8_t eos_spi_xchg8(uint8_t data, uint8_t flags); +uint16_t eos_spi_xchg16(uint16_t data, uint8_t flags); +uint32_t eos_spi_xchg24(uint32_t data, uint8_t flags); +uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags); +void eos_spi_flush(void); diff --git a/fw/fe310/eos/soc/spi_cfg.h b/fw/fe310/eos/soc/spi_cfg.h new file mode 100644 index 0000000..84ab8bb --- /dev/null +++ b/fw/fe310/eos/soc/spi_cfg.h @@ -0,0 +1,37 @@ +#include + +#define EOS_SPI_MAX_DEV 4 + +typedef struct { + uint16_t div; + uint8_t csid; + uint8_t cspin; + unsigned char evt; +} SPIConfig; + +static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { + { // DEV_NET + .div = SPI_DIV_NET, + .csid = SPI_CSID_NET, + .cspin = SPI_CSPIN_NET, + .evt = 0, // Not SPI event + }, + { // DEV_EVE + .div = SPI_DIV_EVE, + .csid = SPI_CSID_EVE, + .cspin = SPI_CSPIN_EVE, + .evt = 0, + }, + { // DEV_SDC + .div = SPI_DIV_SDC, + .csid = SPI_CSID_SDC, + .cspin = SPI_CSPIN_SDC, + .evt = EOS_SPI_EVT_SDC, + }, + { // DEV_CAM + .div = SPI_DIV_CAM, + .csid = SPI_CSID_CAM, + .cspin = SPI_CSPIN_CAM, + .evt = EOS_SPI_EVT_CAM, + }, +}; diff --git a/fw/fe310/eos/soc/spi_dev.c b/fw/fe310/eos/soc/spi_dev.c new file mode 100644 index 0000000..c0c21b0 --- /dev/null +++ b/fw/fe310/eos/soc/spi_dev.c @@ -0,0 +1,97 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "msgq.h" +#include "interrupt.h" +#include "event.h" + +#include "board.h" + +#include "net.h" +#include "spi.h" +#include "spi_priv.h" +#include "spi_cfg.h" +#include "spi_dev.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 + +#define EOS_SPI_DEV_NET 0 +#define EOS_SPI_DEV_EVE 1 +#define EOS_SPI_DEV_SDC 2 +#define EOS_SPI_DEV_CAM 3 + +int eos_spi_dev_init(uint8_t wakeup_cause); +int eos_spi_select(unsigned char dev); +int eos_spi_deselect(void); + +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/soc/spi_priv.h b/fw/fe310/eos/soc/spi_priv.h new file mode 100644 index 0000000..72c2dae --- /dev/null +++ b/fw/fe310/eos/soc/spi_priv.h @@ -0,0 +1,8 @@ +#include + +#define SPI_CSID_NONE 1 +#define SPI_CSPIN_NONE 0xff + +/* DO NOT TOUCH THEESE */ +#define SPI_SIZE_CHUNK 4 +#define SPI_SIZE_WM 2 diff --git a/fw/fe310/eos/soc/timer.c b/fw/fe310/eos/soc/timer.c new file mode 100644 index 0000000..91861a3 --- /dev/null +++ b/fw/fe310/eos/soc/timer.c @@ -0,0 +1,137 @@ +#include +#include + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "msgq.h" +#include "event.h" +#include "timer.h" + +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) + +static eos_timer_handler_t timer_handler[EOS_TIMER_MAX_ETYPE + 1]; +static uint64_t timer_next[EOS_TIMER_MAX_ETYPE + 1]; + +static void timer_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char idx = (type & ~EOS_EVT_MASK); + + if (idx && (idx <= EOS_TIMER_MAX_ETYPE) && timer_handler[idx]) { + timer_handler[idx](type); + } else { + eos_evtq_bad_handler(type, buffer, len); + } +} + +void _eos_timer_handle(void) { + int i; + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t now = *mtime; + uint64_t next = 0; + + for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { + if (timer_next[i] && (timer_next[i] <= now)) { + timer_next[i] = 0; + if (i == 0) { + timer_handler[0](0); + } else { + eos_evtq_push_isr(EOS_EVT_TIMER | i, NULL, 0); + } + } + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); + } + *mtimecmp = next; + if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); +} + +int eos_timer_init(uint8_t wakeup_cause) { + int i; + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + + clear_csr(mie, MIP_MTIP); + *mtimecmp = 0; + for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { + timer_next[i] = 0; + timer_handler[i] = NULL; + } + eos_evtq_set_handler(EOS_EVT_TIMER, timer_handle_evt); + + return EOS_OK; +} + +void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler) { + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + + if (!evt && (*mtimecmp != 0)) clear_csr(mie, MIP_MTIP); + timer_handler[evt] = handler; + if (!evt && (*mtimecmp != 0)) set_csr(mie, MIP_MTIP); +} + +uint32_t eos_timer_get(unsigned char evt) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t now; + uint32_t ret; + + if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); + now = *mtime; + if (timer_next[evt]) { + ret = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0; + } else { + ret = EOS_TIMER_NONE; + } + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); + + return ret; +} + +void eos_timer_set(unsigned char evt, uint32_t msec) { + int i; + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t tick = *mtime + msec * (uint64_t)EOS_TIMER_RTC_FREQ / 1000; + uint64_t next = 0; + + if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); + timer_next[evt] = tick; + for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); + } + *mtimecmp = next; + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); +} + +void eos_timer_clear(unsigned char evt) { + int i; + uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); + uint64_t next = 0; + + if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); + if (timer_next[evt]) { + timer_next[evt] = 0; + for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { + next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); + } + *mtimecmp = next; + } + if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); +} + +void eos_time_sleep(uint32_t msec) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + uint64_t mtime0 = *mtime; + + while ((*mtime - mtime0) < (msec * EOS_TIMER_RTC_FREQ / 1000 + 1)); +} + +uint64_t eos_time_get_tick(void) { + volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); + return *mtime; +} + +uint32_t eos_time_delta_ms(uint32_t tick) { + return ((uint32_t)eos_time_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; +} diff --git a/fw/fe310/eos/soc/timer.h b/fw/fe310/eos/soc/timer.h new file mode 100644 index 0000000..0309454 --- /dev/null +++ b/fw/fe310/eos/soc/timer.h @@ -0,0 +1,23 @@ +#include + +#define EOS_TIMER_ETYPE_UI 1 +#define EOS_TIMER_ETYPE_ECP 2 +#define EOS_TIMER_ETYPE_USER 4 + +#define EOS_TIMER_MAX_ETYPE 4 + +#define EOS_TIMER_NONE -1 +#define EOS_TIMER_RTC_FREQ 32768 + +typedef void (*eos_timer_handler_t) (unsigned char); + +int eos_timer_init(uint8_t wakeup_cause); +void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler); + +uint32_t eos_timer_get(unsigned char evt); +void eos_timer_set(unsigned char evt, uint32_t msec); +void eos_timer_clear(unsigned char evt); + +void eos_time_sleep(uint32_t msec); +uint64_t eos_time_get_tick(void); +uint32_t eos_time_delta_ms(uint32_t tick); diff --git a/fw/fe310/eos/soc/trap_entry.S b/fw/fe310/eos/soc/trap_entry.S new file mode 100644 index 0000000..fb2b121 --- /dev/null +++ b/fw/fe310/eos/soc/trap_entry.S @@ -0,0 +1,554 @@ +#include "encoding.h" +#include "sifive/bits.h" + +#define MCAUSE_INT 0x80000000 +#define MCAUSE_EXT (MCAUSE_INT | IRQ_M_EXT) +#define MCAUSE_TIMER (MCAUSE_INT | IRQ_M_TIMER) + +#define PLIC_PRIORITY 0x0C000000 +#define PLIC_THRESHOLD 0x0C200000 +#define PLIC_CLAIM 0x0C200004 + +#define PWM0_CTRL_ADDR 0x10015000 +#define PWM1_CTRL_ADDR 0x10025000 +#define PWM2_CTRL_ADDR 0x10035000 +#include "sifive/devices/pwm.h" + +#define GPIO_CTRL_ADDR 0x10012000 +#include "sifive/devices/gpio.h" + +#define SPI0_CTRL_ADDR 0x10014000 +#define SPI1_CTRL_ADDR 0x10024000 +#include "sifive/devices/spi.h" + +#define INT_PWM0_BASE 40 +#define INT_PWM1_BASE 44 +#define INT_PWM2_BASE 48 + +#define I2S_MIC_BUF (0*4) +#define I2S_SPK_BUF (1*4) +#define I2S_FMT (2*4) +#define I2S_MODE (3*4) +#define I2S_MIC_WM (4*4) +#define I2S_SPK_WM (5*4) +#define I2S_MIC_EVT (6*4) +#define I2S_SPK_EVT (7*4) +#define I2S_MIC_CMP2 (8*4) +#define I2S_MIC_CMP3 (9*4) +#define I2S_SAMPLE (10*4) + +#include "board.h" +#include "irq_def.h" +#include "evt_def.h" +#include "i2s_def.h" +#include "i2s_priv.h" +#include "msgq_priv.h" + + .section .data.entry + .align 4 + +.global eos_trap_entry +eos_trap_entry: + addi sp, sp, -12*REGBYTES + STORE x8, 0*REGBYTES(sp) + STORE x9, 1*REGBYTES(sp) + STORE x18, 2*REGBYTES(sp) + STORE x19, 3*REGBYTES(sp) + STORE x20, 4*REGBYTES(sp) + STORE x21, 5*REGBYTES(sp) + STORE x22, 6*REGBYTES(sp) + STORE x23, 7*REGBYTES(sp) + STORE x24, 8*REGBYTES(sp) # format: 0 - PCM16; 1 - ALAW + STORE x25, 9*REGBYTES(sp) # mode: 0 - stereo; 1 - mono + STORE x26, 10*REGBYTES(sp) # channel: 0 - left; 1 - right + STORE x27, 11*REGBYTES(sp) # _eos_event_q addr + + csrr x8, mcause + li x18, MCAUSE_EXT + bne x8, x18, handle_intr + li x18, PLIC_CLAIM + lw x9, 0(x18) + li x18, I2S_IRQ_WS_ID + beq x9, x18, i2s_handle_ws + li x18, I2S_IRQ_SD_ID + beq x9, x18, i2s_handle_sd + j handle_intr + +evtq_push: + la x9, _eos_event_q + lbu x18, MSGQ_OFF_IDXR(x9) + lbu x19, MSGQ_OFF_IDXW(x9) + lbu x20, MSGQ_OFF_SIZE(x9) + + sub x18, x19, x18 + andi x18, x18, 0xff + beq x18, x20, 0f + + addi x20, x20, -1 + and x20, x20, x19 + li x18, MSGQ_ITEM_SIZE + mul x20, x20, x18 + lw x21, MSGQ_OFF_ARRAY(x9) + add x21, x21, x20 + + addi x19, x19, 1 + sb x19, MSGQ_OFF_IDXW(x9) + jalr x0, x22 + +0: + mv x20, x0 + jalr x0, x21 + +i2s_handle_sd: + li x8, I2S_CTRL_ADDR_WS_SPK + lw x18, PWM_COUNT(x8) + lw x19, PWM_CMP3(x8) + + # exit if too early + bltu x18, x19, i2s_sd_exit + + la x27, _eos_i2s_drvr + + # move CMPs for next channel and store channel bit to x26 + lw x20, I2S_MIC_CMP2(x27) + lw x21, I2S_MIC_CMP3(x27) # 16-bit period + + add x23, x19, x20 + add x24, x23, x21 + slli x20, x21, 1 # 32-bit period + slli x21, x20, 1 # 64-bit period + bltu x24, x21, 0f + neg x21, x21 + add x23, x23, x21 + add x24, x24, x21 +0: + li x26, 0 + bltu x23, x20, 0f + li x26, 1 +0: + bltu x19, x20, 0f + neg x20, x20 + li x18, PLIC_PRIORITY + sw x0, 4*I2S_IRQ_SD_ID(x18) +0: + add x19, x19, x20 + + li x9, I2S_CTRL_ADDR_WS_MIC + sw x19, PWM_CMP3(x8) + sw x23, PWM_CMP2(x9) + sw x24, PWM_CMP3(x9) + + lw x24, I2S_FMT(x27) + lw x25, I2S_MODE(x27) + +i2s_abuf_pop: + and x8, x25, x26 + beqz x8, 0f + + lw x8, I2S_SAMPLE(x27) + j i2s_sd_xchg +0: + # pop from spk buf -> x8 + lw x9, I2S_SPK_BUF(x27) + beqz x9, i2s_sd_xchg + lhu x18, I2S_ABUF_OFF_IDXR(x9) + lhu x19, I2S_ABUF_OFF_IDXW(x9) + lhu x20, I2S_ABUF_OFF_SIZE(x9) + + beq x18, x19, 2f + + addi x20, x20, -1 + and x20, x20, x18 + lw x21, I2S_ABUF_OFF_ARRAY(x9) + add x21, x21, x20 + beqz x24, 0f + lbu x8, 0(x21) + addi x18, x18, 1 + j 1f +0: + lb x8, 0(x21) + lbu x20, 1(x21) + slli x8, x8, 8 + or x8, x8, x20 + addi x18, x18, 2 +1: + sh x18, I2S_ABUF_OFF_IDXR(x9) + +2: + li x21, 0xffff + sub x18, x19, x18 + and x18, x18, x21 + + # check for push to event queue + lw x9, I2S_SPK_WM(x27) + bgtu x18, x9, i2s_decode + + lw x9, I2S_SPK_EVT(x27) + beqz x9, i2s_decode + sw x0, I2S_SPK_EVT(x27) + + # push to event queue + jal x22, evtq_push + beqz x21, i2s_decode + li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_SPK) + sb x18, MSGQ_ITEM_OFF_TYPE(x21) + +i2s_decode: + beqz x24, 3f + # aLaw decode -> x8 + xori x8, x8, 0x55 + andi x9, x8, 0x80 + beqz x9, 0f + li x9, 1 + slli x9, x9, 7 + not x9, x9 + and x8, x8, x9 + li x9, -1 +0: + andi x18, x8, 0xf0 + srli x18, x18, 4 + addi x18, x18, 4 + + li x19, 4 + beq x18, x19, 1f + + andi x8, x8, 0x0f + addi x19, x18, -4 + sll x8, x8, x19 + + li x19, 1 + sll x19, x19, x18 + or x8, x8, x19 + + li x19, 1 + addi x18, x18, -5 + sll x19, x19, x18 + or x8, x8, x19 + j 2f +1: + slli x8, x8, 1 + ori x8, x8, 1 +2: + beqz x9, 3f + mul x8, x8, x9 +3: + beqz x25, i2s_sd_xchg + sw x8, I2S_SAMPLE(x27) + +i2s_sd_xchg: + # read/write shift reg: x8 -> sr -> x8 + li x18, GPIO_CTRL_ADDR + li x19, (0x1 << I2S_PIN_SD_IN) + li x20, (0x1 << I2S_PIN_SD_OUT) + li x21, (0x1 << I2S_PIN_CK_SR) + lw x22, GPIO_OUTPUT_VAL(x18) + + lw x9, GPIO_OUTPUT_EN(x18) + or x9, x9, x20 + sw x9, GPIO_OUTPUT_EN(x18) + + not x20, x20 + xor x22, x22, x21 + + li x23, 16 +0: + # write bit + li x9, 1 + slli x9, x9, 15 + and x9, x8, x9 + slli x8, x8, 1 +#if I2S_PIN_SD_OUT > 15 + slli x9, x9, (I2S_PIN_SD_OUT - 15) +#else + srli x9, x9, (15 - I2S_PIN_SD_OUT) +#endif + and x22, x22, x20 + or x22, x22, x9 + + # read bit + lw x9, GPIO_INPUT_VAL(x18) + and x9, x9, x19 + srli x9, x9, I2S_PIN_SD_IN + or x8, x8, x9 + + # 74HC595 ck low (I2S_PIN_CK_SR high) + xor x22, x22, x21 + sw x22, GPIO_OUTPUT_VAL(x18) + + # idle + li x9, I2S_IDLE_CYCLES +1: + addi x9, x9, -1 + bnez x9, 1b + + # 74HC595 ck high (I2S_PIN_CK_SR low) + xor x22, x22, x21 + sw x22, GPIO_OUTPUT_VAL(x18) + + addi x23, x23, -1 + bnez x23, 0b + + # idle + li x9, I2S_IDLE_CYCLES +1: + addi x9, x9, -1 + bnez x9, 1b + + # 74HC595 ck low (I2S_PIN_CK_SR high) + xor x22, x22, x21 + sw x22, GPIO_OUTPUT_VAL(x18) + + lw x9, GPIO_OUTPUT_EN(x18) + and x9, x9, x20 + sw x9, GPIO_OUTPUT_EN(x18) + + slli x8, x8, 16 + srai x8, x8, 16 + +i2s_encode: + beqz x24, i2s_abuf_push + # aLaw encode -> x8 + li x18, 0x800 + li x19, 7 + bgez x8, 0f + neg x8, x8 + lui x9, 0x80000 + or x8, x8, x9 +0: + and x9, x8, x18 + beq x9, x18, 1f + beqz x19, 1f + srli x18, x18, 1 + addi x19, x19, -1 + j 0b +1: + mv x9, x19 + bnez x9, 2f + addi x9, x9, 1 +2: + sra x8, x8, x9 + li x9, 0x8000000f + and x8, x8, x9 + slli x19, x19, 4 + or x8, x8, x19 + bgez x8, 3f + ori x8, x8, 0x80 +3: + xori x8, x8, 0x55 + andi x8, x8, 0xff + +i2s_abuf_push: + # check channel + # bnez x26, i2s_sd_exit + + # push to mic buf + lw x9, I2S_MIC_BUF(x27) + beqz x9, i2s_sd_exit + lhu x18, I2S_ABUF_OFF_IDXR(x9) + lhu x19, I2S_ABUF_OFF_IDXW(x9) + lhu x20, I2S_ABUF_OFF_SIZE(x9) + li x21, 0xffff + + sub x18, x19, x18 + and x18, x18, x21 + beq x18, x20, 2f + + addi x20, x20, -1 + and x20, x20, x19 + lw x21, I2S_ABUF_OFF_ARRAY(x9) + add x21, x21, x20 + beqz x24, 0f + sb x8, 0(x21) + addi x19, x19, 1 + addi x18, x18, 1 + j 1f +0: + sb x8, 1(x21) + srli x8, x8, 8 + sb x8, 0(x21) + addi x19, x19, 2 + addi x18, x18, 2 +1: + sh x19, I2S_ABUF_OFF_IDXW(x9) + +2: + # check for push to event queue + lw x9, I2S_MIC_WM(x27) + bltu x18, x9, i2s_sd_exit + + lw x9, I2S_MIC_EVT(x27) + beqz x9, i2s_sd_exit + sw x0, I2S_MIC_EVT(x27) + + # push to event queue + jal x22, evtq_push + beqz x21, i2s_sd_exit + li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_MIC) + sb x18, MSGQ_ITEM_OFF_TYPE(x21) + +i2s_sd_exit: + # complete + li x18, I2S_IRQ_SD_ID + li x19, PLIC_CLAIM + sw x18, 0(x19) + + # exit + j trap_exit_data + +i2s_handle_ws: + # enable sd irq + li x18, PLIC_PRIORITY + li x19, IRQ_PRIORITY_I2S_SD + sw x19, 4*I2S_IRQ_SD_ID(x18) + + # complete + li x18, I2S_IRQ_WS_ID + li x19, PLIC_CLAIM + sw x18, 0(x19) + + # exit + j trap_exit_data + +.global _eos_i2s_start_pwm +_eos_i2s_start_pwm: + addi sp, sp, -8*REGBYTES + STORE x8, 0*REGBYTES(sp) + STORE x9, 1*REGBYTES(sp) + STORE x18, 2*REGBYTES(sp) + STORE x19, 3*REGBYTES(sp) + STORE x20, 4*REGBYTES(sp) + STORE x21, 5*REGBYTES(sp) + STORE x22, 6*REGBYTES(sp) + STORE x23, 7*REGBYTES(sp) + + li x18, I2S_CTRL_ADDR_CK + li x19, I2S_CTRL_ADDR_WS_MIC + li x20, I2S_CTRL_ADDR_WS_SPK + li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK + li x22, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG + li x23, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG + sw x21, PWM_CFG(x18) + sw x22, PWM_CFG(x19) + sw x23, PWM_CFG(x20) + + LOAD x8, 0*REGBYTES(sp) + LOAD x9, 1*REGBYTES(sp) + LOAD x18, 2*REGBYTES(sp) + LOAD x19, 3*REGBYTES(sp) + LOAD x20, 4*REGBYTES(sp) + LOAD x21, 5*REGBYTES(sp) + LOAD x22, 6*REGBYTES(sp) + LOAD x23, 7*REGBYTES(sp) + addi sp, sp, 8*REGBYTES + + ret + +trap_exit_data: + # Remain in M-mode after mret + li x18, MSTATUS_MPP + csrs mstatus, x18 + + LOAD x8, 0*REGBYTES(sp) + LOAD x9, 1*REGBYTES(sp) + LOAD x18, 2*REGBYTES(sp) + LOAD x19, 3*REGBYTES(sp) + LOAD x20, 4*REGBYTES(sp) + LOAD x21, 5*REGBYTES(sp) + LOAD x22, 6*REGBYTES(sp) + LOAD x23, 7*REGBYTES(sp) + LOAD x24, 8*REGBYTES(sp) + LOAD x25, 9*REGBYTES(sp) + LOAD x26, 10*REGBYTES(sp) + LOAD x27, 11*REGBYTES(sp) + addi sp, sp, 12*REGBYTES + + mret + +handle_intr: + lui x18, %hi(trap_entry_text) + addi x18, x18, %lo(trap_entry_text) + jalr x0, x18 + + .section .text.entry + .align 4 + +trap_entry_text: + addi sp, sp, -20*REGBYTES + + STORE x1, 0*REGBYTES(sp) + STORE x2, 1*REGBYTES(sp) + STORE x3, 2*REGBYTES(sp) + STORE x4, 3*REGBYTES(sp) + STORE x5, 4*REGBYTES(sp) + STORE x6, 5*REGBYTES(sp) + STORE x7, 6*REGBYTES(sp) + STORE x10, 7*REGBYTES(sp) + STORE x11, 8*REGBYTES(sp) + STORE x12, 9*REGBYTES(sp) + STORE x13, 10*REGBYTES(sp) + STORE x14, 11*REGBYTES(sp) + STORE x15, 12*REGBYTES(sp) + STORE x16, 13*REGBYTES(sp) + STORE x17, 14*REGBYTES(sp) + STORE x28, 15*REGBYTES(sp) + STORE x29, 16*REGBYTES(sp) + STORE x30, 17*REGBYTES(sp) + STORE x31, 18*REGBYTES(sp) + + li x18, MCAUSE_TIMER + beq x8, x18, handle_timer + li x18, MCAUSE_EXT + beq x8, x18, handle_ext + mv a0, x8 + call _exit + +handle_timer: + call _eos_timer_handle + j trap_exit_text + +handle_ext: + mv a0, x9 + call eos_intr_handle + li x18, PLIC_CLAIM + sw a0, 0(x18) + +trap_exit_text: + # Remain in M-mode after mret + li t0, MSTATUS_MPP + csrs mstatus, t0 + + LOAD x1, 0*REGBYTES(sp) + LOAD x2, 1*REGBYTES(sp) + LOAD x3, 2*REGBYTES(sp) + LOAD x4, 3*REGBYTES(sp) + LOAD x5, 4*REGBYTES(sp) + LOAD x6, 5*REGBYTES(sp) + LOAD x7, 6*REGBYTES(sp) + LOAD x10, 7*REGBYTES(sp) + LOAD x11, 8*REGBYTES(sp) + LOAD x12, 9*REGBYTES(sp) + LOAD x13, 10*REGBYTES(sp) + LOAD x14, 11*REGBYTES(sp) + LOAD x15, 12*REGBYTES(sp) + LOAD x16, 13*REGBYTES(sp) + LOAD x17, 14*REGBYTES(sp) + LOAD x28, 15*REGBYTES(sp) + LOAD x29, 16*REGBYTES(sp) + LOAD x30, 17*REGBYTES(sp) + LOAD x31, 18*REGBYTES(sp) + + LOAD x8, 20*REGBYTES(sp) + LOAD x9, 21*REGBYTES(sp) + LOAD x18, 22*REGBYTES(sp) + LOAD x19, 23*REGBYTES(sp) + LOAD x20, 24*REGBYTES(sp) + LOAD x21, 25*REGBYTES(sp) + LOAD x22, 26*REGBYTES(sp) + LOAD x23, 27*REGBYTES(sp) + LOAD x24, 28*REGBYTES(sp) + LOAD x25, 29*REGBYTES(sp) + LOAD x26, 30*REGBYTES(sp) + LOAD x27, 31*REGBYTES(sp) + + addi sp, sp, 32*REGBYTES + mret diff --git a/fw/fe310/eos/soc/uart.c b/fw/fe310/eos/soc/uart.c new file mode 100644 index 0000000..30f76d9 --- /dev/null +++ b/fw/fe310/eos/soc/uart.c @@ -0,0 +1,114 @@ +#include +#include +#include + +#include "encoding.h" +#include "platform.h" +#include "prci_driver.h" + +#include "eos.h" +#include "interrupt.h" +#include "event.h" + +#include "uart.h" + +static eos_uart_handler_t uart_handler[EOS_UART_MAX_ETYPE]; + +static void uart_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + unsigned char idx = (type & ~EOS_EVT_MASK) - 1; + + if ((idx < EOS_UART_MAX_ETYPE) && uart_handler[idx]) { + uart_handler[idx](type); + } else { + eos_evtq_bad_handler(type, buffer, len); + } +} + +static void uart_handle_intr(void) { + if (UART0_REG(UART_REG_IP) & UART_IP_TXWM) { + UART0_REG(UART_REG_IE) &= ~UART_IP_TXWM; + eos_evtq_push_isr(EOS_EVT_UART | EOS_UART_ETYPE_TX, NULL, 0); + } + if (UART0_REG(UART_REG_IP) & UART_IP_RXWM) { + UART0_REG(UART_REG_IE) &= ~UART_IP_RXWM; + eos_evtq_push_isr(EOS_EVT_UART | EOS_UART_ETYPE_RX, NULL, 0); + } +} + +int eos_uart_init(uint8_t wakeup_cause) { + int i; + + for (i=0; i + +#define EOS_UART_ETYPE_TX 1 +#define EOS_UART_ETYPE_RX 2 + +#define EOS_UART_MAX_ETYPE 2 + +#define EOS_UART_SPEED 115200 + +typedef void (*eos_uart_handler_t) (unsigned char); + +int eos_uart_init(uint8_t wakeup_cause); +void eos_uart_start(void); +void eos_uart_stop(void); +void eos_uart_speed(uint32_t baud_rate); + +void eos_uart_set_handler(unsigned char type, eos_uart_handler_t handler); + +void eos_uart_txwm_set(uint8_t wm); +void eos_uart_txwm_clear(void); +void eos_uart_rxwm_set(uint8_t wm); +void eos_uart_rxwm_clear(void); +int eos_uart_putc(int c, char b); +int eos_uart_getc(char b); \ No newline at end of file diff --git a/fw/fe310/eos/sock.c b/fw/fe310/eos/sock.c deleted file mode 100644 index 7365c97..0000000 --- a/fw/fe310/eos/sock.c +++ /dev/null @@ -1,154 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "event.h" -#include "net.h" - -#include "sock.h" - -static eos_evt_handler_t evt_handler[EOS_SOCK_MAX_SOCK]; - -static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char sock; - - if ((buffer == NULL) || (len < 2)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - sock = buffer[1]; - if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - switch(buffer[0]) { - case EOS_SOCK_MTYPE_PKT: - evt_handler[sock - 1](type, buffer, len); - break; - default: - eos_net_bad_handler(type, buffer, len); - break; - } -} - -void eos_sock_netinit(void) { - int i; - - for (i=0; ihost, sizeof(addr->host)); - buffer += sizeof(addr->host); - buffer[0] = addr->port >> 8; - buffer[1] = addr->port; - buffer += sizeof(addr->port); - if (msg) { - if (msg_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_MTU) return EOS_ERR_SIZE; - memcpy(buffer, msg, msg_len); - } - - return EOS_OK; -} - -int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer) { - int rv; - - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; - - return eos_net_send(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR); -} - -int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more) { - int rv; - - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; - - return eos_net_send_async(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR, more); -} - -int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr) { - if (len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; - - if (buffer[0] != EOS_SOCK_MTYPE_PKT) return EOS_ERR_NET; - - buffer += 2; - memcpy(addr->host, buffer, sizeof(addr->host)); - buffer += sizeof(addr->host); - addr->port = (uint16_t)buffer[0] << 8; - addr->port |= (uint16_t)buffer[1]; - buffer += sizeof(addr->port); - if (msg) { - if (msg_size < len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; - memcpy(msg, buffer, len - EOS_SOCK_SIZE_UDP_HDR); - } - - return EOS_OK; -} diff --git a/fw/fe310/eos/sock.h b/fw/fe310/eos/sock.h deleted file mode 100644 index 5ef42e3..0000000 --- a/fw/fe310/eos/sock.h +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include "event.h" - -#define EOS_SOCK_MTYPE_PKT 0 -#define EOS_SOCK_MTYPE_OPEN_DGRAM 1 -#define EOS_SOCK_MTYPE_CLOSE 127 - -#define EOS_SOCK_MAX_SOCK 2 - -#define EOS_SOCK_SIZE_UDP_HDR 8 - -#define EOS_IPv4_ADDR_SIZE 4 - -typedef struct EOSNetAddr { - unsigned char host[EOS_IPv4_ADDR_SIZE]; - uint16_t port; -} EOSNetAddr; - -void eos_sock_netinit(void); -void eos_sock_set_handler(unsigned char sock, eos_evt_handler_t handler); -eos_evt_handler_t eos_sock_get_handler(unsigned char sock); - -int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer); -void eos_sock_close(unsigned char sock, unsigned char *buffer); - -int eos_sock_sendto(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer); -int eos_sock_sendto_async(unsigned char sock, unsigned char *msg, size_t msg_len, EOSNetAddr *addr, unsigned char *buffer, unsigned char more); -int eos_sock_recvfrom(unsigned char *buffer, uint16_t len, unsigned char *msg, size_t msg_size, EOSNetAddr *addr); diff --git a/fw/fe310/eos/spi.c b/fw/fe310/eos/spi.c deleted file mode 100644 index 05c9448..0000000 --- a/fw/fe310/eos/spi.c +++ /dev/null @@ -1,350 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" - -#include "eos.h" -#include "msgq.h" -#include "interrupt.h" -#include "event.h" - -#include "board.h" - -#include "spi.h" -#include "spi_priv.h" - -#define SPI_MODE0 0x00 -#define SPI_MODE1 0x01 -#define SPI_MODE2 0x02 -#define SPI_MODE3 0x03 - -#define SPI_FLAG_XCHG 0x10 - -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) - -static uint8_t spi_cspin; -static volatile uint8_t spi_state_flags; -static unsigned char spi_evt; -static unsigned char spi_in_xchg; - -static uint32_t spi_state_len = 0; -static uint32_t spi_state_idx_tx = 0; -static uint32_t spi_state_idx_rx = 0; -static unsigned char *spi_state_buf = NULL; - -static eos_evt_handler_t evt_handler[EOS_SPI_MAX_EVT]; - -static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK) - 1; - if (idx < EOS_SPI_MAX_EVT) { - evt_handler[idx](type, buffer, len); - } else { - eos_evtq_bad_handler(type, buffer, len); - } -} - -int eos_spi_init(uint8_t wakeup_cause) { - int i; - - for (i=0; i> 8; - } else { - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0xFF00) >> 8; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF); - } - - if (rx) { - if (flags & EOS_SPI_FLAG_BSWAP) { - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF); - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 8; - } else { - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 8; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF); - } - } - - return r; -} - -uint32_t eos_spi_xchg24(uint32_t data, uint8_t flags) { - volatile uint32_t x = 0; - uint8_t rx = !(flags & EOS_SPI_FLAG_TX); - uint32_t r = 0; - - spi_state_flags &= 0xF0; - spi_state_flags |= flags; - - if (flags & EOS_SPI_FLAG_BSWAP) { - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; - } else { - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); - } - - if (rx) { - if (flags & EOS_SPI_FLAG_BSWAP) { - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF); - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 8; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 16; - } else { - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 16; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 8; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF); - } - } - - return r; -} - -uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags) { - volatile uint32_t x = 0; - uint8_t rx = !(flags & EOS_SPI_FLAG_TX); - uint32_t r = 0; - - spi_state_flags &= 0xF0; - spi_state_flags |= flags; - - if (flags & EOS_SPI_FLAG_BSWAP) { - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0xFF000000) >> 24; - } else { - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0xFF000000) >> 24; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x00FF0000) >> 16; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x0000FF00) >> 8; - while (SPI1_REG(SPI_REG_TXFIFO) & SPI_TXFIFO_FULL); - SPI1_REG(SPI_REG_TXFIFO) = (data & 0x000000FF); - } - - if (rx) { - if (flags & EOS_SPI_FLAG_BSWAP) { - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF); - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 8; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 16; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 24; - } else { - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 24; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 16; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF) << 8; - while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); - r |= (x & 0xFF); - } - } - - return r; -} - -void eos_spi_flush(void) { - volatile uint32_t x = 0; - - if (spi_in_xchg) spi_xchg_finish(); - - SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); - while (!x) { - if (SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM) x = SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY; - } -} diff --git a/fw/fe310/eos/spi.h b/fw/fe310/eos/spi.h deleted file mode 100644 index a23a235..0000000 --- a/fw/fe310/eos/spi.h +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include "event.h" - -#define EOS_SPI_FLAG_TX 0x01 -#define EOS_SPI_FLAG_MORE 0x02 -#define EOS_SPI_FLAG_BSWAP 0x04 - -#define EOS_SPI_EVT_SDC 1 -#define EOS_SPI_EVT_CAM 2 - -#define EOS_SPI_MAX_EVT 2 - -int eos_spi_init(uint8_t wakeup_cause); -void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt); -void eos_spi_stop(void); -void eos_spi_set_handler(unsigned char evt, eos_evt_handler_t handler); - -void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags); -void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags); -void eos_spi_handle_xchg(void); - -void eos_spi_cs_set(void); -void eos_spi_cs_clear(void); -uint8_t eos_spi_xchg8(uint8_t data, uint8_t flags); -uint16_t eos_spi_xchg16(uint16_t data, uint8_t flags); -uint32_t eos_spi_xchg24(uint32_t data, uint8_t flags); -uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags); -void eos_spi_flush(void); diff --git a/fw/fe310/eos/spi_cfg.h b/fw/fe310/eos/spi_cfg.h deleted file mode 100644 index 84ab8bb..0000000 --- a/fw/fe310/eos/spi_cfg.h +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#define EOS_SPI_MAX_DEV 4 - -typedef struct { - uint16_t div; - uint8_t csid; - uint8_t cspin; - unsigned char evt; -} SPIConfig; - -static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { - { // DEV_NET - .div = SPI_DIV_NET, - .csid = SPI_CSID_NET, - .cspin = SPI_CSPIN_NET, - .evt = 0, // Not SPI event - }, - { // DEV_EVE - .div = SPI_DIV_EVE, - .csid = SPI_CSID_EVE, - .cspin = SPI_CSPIN_EVE, - .evt = 0, - }, - { // DEV_SDC - .div = SPI_DIV_SDC, - .csid = SPI_CSID_SDC, - .cspin = SPI_CSPIN_SDC, - .evt = EOS_SPI_EVT_SDC, - }, - { // DEV_CAM - .div = SPI_DIV_CAM, - .csid = SPI_CSID_CAM, - .cspin = SPI_CSPIN_CAM, - .evt = EOS_SPI_EVT_CAM, - }, -}; diff --git a/fw/fe310/eos/spi_dev.c b/fw/fe310/eos/spi_dev.c deleted file mode 100644 index c0c21b0..0000000 --- a/fw/fe310/eos/spi_dev.c +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" - -#include "eos.h" -#include "msgq.h" -#include "interrupt.h" -#include "event.h" - -#include "board.h" - -#include "net.h" -#include "spi.h" -#include "spi_priv.h" -#include "spi_cfg.h" -#include "spi_dev.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 - -#define EOS_SPI_DEV_NET 0 -#define EOS_SPI_DEV_EVE 1 -#define EOS_SPI_DEV_SDC 2 -#define EOS_SPI_DEV_CAM 3 - -int eos_spi_dev_init(uint8_t wakeup_cause); -int eos_spi_select(unsigned char dev); -int eos_spi_deselect(void); - -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/spi_priv.h b/fw/fe310/eos/spi_priv.h deleted file mode 100644 index 72c2dae..0000000 --- a/fw/fe310/eos/spi_priv.h +++ /dev/null @@ -1,8 +0,0 @@ -#include - -#define SPI_CSID_NONE 1 -#define SPI_CSPIN_NONE 0xff - -/* DO NOT TOUCH THEESE */ -#define SPI_SIZE_CHUNK 4 -#define SPI_SIZE_WM 2 diff --git a/fw/fe310/eos/timer.c b/fw/fe310/eos/timer.c deleted file mode 100644 index 91861a3..0000000 --- a/fw/fe310/eos/timer.c +++ /dev/null @@ -1,137 +0,0 @@ -#include -#include - -#include "encoding.h" -#include "platform.h" - -#include "eos.h" -#include "msgq.h" -#include "event.h" -#include "timer.h" - -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) - -static eos_timer_handler_t timer_handler[EOS_TIMER_MAX_ETYPE + 1]; -static uint64_t timer_next[EOS_TIMER_MAX_ETYPE + 1]; - -static void timer_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK); - - if (idx && (idx <= EOS_TIMER_MAX_ETYPE) && timer_handler[idx]) { - timer_handler[idx](type); - } else { - eos_evtq_bad_handler(type, buffer, len); - } -} - -void _eos_timer_handle(void) { - int i; - volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - uint64_t now = *mtime; - uint64_t next = 0; - - for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { - if (timer_next[i] && (timer_next[i] <= now)) { - timer_next[i] = 0; - if (i == 0) { - timer_handler[0](0); - } else { - eos_evtq_push_isr(EOS_EVT_TIMER | i, NULL, 0); - } - } - next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); - } - *mtimecmp = next; - if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); -} - -int eos_timer_init(uint8_t wakeup_cause) { - int i; - uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - - clear_csr(mie, MIP_MTIP); - *mtimecmp = 0; - for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { - timer_next[i] = 0; - timer_handler[i] = NULL; - } - eos_evtq_set_handler(EOS_EVT_TIMER, timer_handle_evt); - - return EOS_OK; -} - -void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler) { - uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - - if (!evt && (*mtimecmp != 0)) clear_csr(mie, MIP_MTIP); - timer_handler[evt] = handler; - if (!evt && (*mtimecmp != 0)) set_csr(mie, MIP_MTIP); -} - -uint32_t eos_timer_get(unsigned char evt) { - volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - uint64_t now; - uint32_t ret; - - if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); - now = *mtime; - if (timer_next[evt]) { - ret = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0; - } else { - ret = EOS_TIMER_NONE; - } - if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); - - return ret; -} - -void eos_timer_set(unsigned char evt, uint32_t msec) { - int i; - volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - uint64_t tick = *mtime + msec * (uint64_t)EOS_TIMER_RTC_FREQ / 1000; - uint64_t next = 0; - - if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); - timer_next[evt] = tick; - for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { - next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); - } - *mtimecmp = next; - if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); -} - -void eos_timer_clear(unsigned char evt) { - int i; - uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - uint64_t next = 0; - - if (*mtimecmp != 0) clear_csr(mie, MIP_MTIP); - if (timer_next[evt]) { - timer_next[evt] = 0; - for (i=0; i<=EOS_TIMER_MAX_ETYPE; i++) { - next = next && timer_next[i] ? MIN(next, timer_next[i]) : (next ? next : timer_next[i]); - } - *mtimecmp = next; - } - if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); -} - -void eos_time_sleep(uint32_t msec) { - volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - uint64_t mtime0 = *mtime; - - while ((*mtime - mtime0) < (msec * EOS_TIMER_RTC_FREQ / 1000 + 1)); -} - -uint64_t eos_time_get_tick(void) { - volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); - return *mtime; -} - -uint32_t eos_time_delta_ms(uint32_t tick) { - return ((uint32_t)eos_time_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; -} diff --git a/fw/fe310/eos/timer.h b/fw/fe310/eos/timer.h deleted file mode 100644 index 0309454..0000000 --- a/fw/fe310/eos/timer.h +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#define EOS_TIMER_ETYPE_UI 1 -#define EOS_TIMER_ETYPE_ECP 2 -#define EOS_TIMER_ETYPE_USER 4 - -#define EOS_TIMER_MAX_ETYPE 4 - -#define EOS_TIMER_NONE -1 -#define EOS_TIMER_RTC_FREQ 32768 - -typedef void (*eos_timer_handler_t) (unsigned char); - -int eos_timer_init(uint8_t wakeup_cause); -void eos_timer_set_handler(unsigned char evt, eos_timer_handler_t handler); - -uint32_t eos_timer_get(unsigned char evt); -void eos_timer_set(unsigned char evt, uint32_t msec); -void eos_timer_clear(unsigned char evt); - -void eos_time_sleep(uint32_t msec); -uint64_t eos_time_get_tick(void); -uint32_t eos_time_delta_ms(uint32_t tick); diff --git a/fw/fe310/eos/trap_entry.S b/fw/fe310/eos/trap_entry.S deleted file mode 100644 index fb2b121..0000000 --- a/fw/fe310/eos/trap_entry.S +++ /dev/null @@ -1,554 +0,0 @@ -#include "encoding.h" -#include "sifive/bits.h" - -#define MCAUSE_INT 0x80000000 -#define MCAUSE_EXT (MCAUSE_INT | IRQ_M_EXT) -#define MCAUSE_TIMER (MCAUSE_INT | IRQ_M_TIMER) - -#define PLIC_PRIORITY 0x0C000000 -#define PLIC_THRESHOLD 0x0C200000 -#define PLIC_CLAIM 0x0C200004 - -#define PWM0_CTRL_ADDR 0x10015000 -#define PWM1_CTRL_ADDR 0x10025000 -#define PWM2_CTRL_ADDR 0x10035000 -#include "sifive/devices/pwm.h" - -#define GPIO_CTRL_ADDR 0x10012000 -#include "sifive/devices/gpio.h" - -#define SPI0_CTRL_ADDR 0x10014000 -#define SPI1_CTRL_ADDR 0x10024000 -#include "sifive/devices/spi.h" - -#define INT_PWM0_BASE 40 -#define INT_PWM1_BASE 44 -#define INT_PWM2_BASE 48 - -#define I2S_MIC_BUF (0*4) -#define I2S_SPK_BUF (1*4) -#define I2S_FMT (2*4) -#define I2S_MODE (3*4) -#define I2S_MIC_WM (4*4) -#define I2S_SPK_WM (5*4) -#define I2S_MIC_EVT (6*4) -#define I2S_SPK_EVT (7*4) -#define I2S_MIC_CMP2 (8*4) -#define I2S_MIC_CMP3 (9*4) -#define I2S_SAMPLE (10*4) - -#include "board.h" -#include "irq_def.h" -#include "evt_def.h" -#include "i2s_def.h" -#include "i2s_priv.h" -#include "msgq_priv.h" - - .section .data.entry - .align 4 - -.global eos_trap_entry -eos_trap_entry: - addi sp, sp, -12*REGBYTES - STORE x8, 0*REGBYTES(sp) - STORE x9, 1*REGBYTES(sp) - STORE x18, 2*REGBYTES(sp) - STORE x19, 3*REGBYTES(sp) - STORE x20, 4*REGBYTES(sp) - STORE x21, 5*REGBYTES(sp) - STORE x22, 6*REGBYTES(sp) - STORE x23, 7*REGBYTES(sp) - STORE x24, 8*REGBYTES(sp) # format: 0 - PCM16; 1 - ALAW - STORE x25, 9*REGBYTES(sp) # mode: 0 - stereo; 1 - mono - STORE x26, 10*REGBYTES(sp) # channel: 0 - left; 1 - right - STORE x27, 11*REGBYTES(sp) # _eos_event_q addr - - csrr x8, mcause - li x18, MCAUSE_EXT - bne x8, x18, handle_intr - li x18, PLIC_CLAIM - lw x9, 0(x18) - li x18, I2S_IRQ_WS_ID - beq x9, x18, i2s_handle_ws - li x18, I2S_IRQ_SD_ID - beq x9, x18, i2s_handle_sd - j handle_intr - -evtq_push: - la x9, _eos_event_q - lbu x18, MSGQ_OFF_IDXR(x9) - lbu x19, MSGQ_OFF_IDXW(x9) - lbu x20, MSGQ_OFF_SIZE(x9) - - sub x18, x19, x18 - andi x18, x18, 0xff - beq x18, x20, 0f - - addi x20, x20, -1 - and x20, x20, x19 - li x18, MSGQ_ITEM_SIZE - mul x20, x20, x18 - lw x21, MSGQ_OFF_ARRAY(x9) - add x21, x21, x20 - - addi x19, x19, 1 - sb x19, MSGQ_OFF_IDXW(x9) - jalr x0, x22 - -0: - mv x20, x0 - jalr x0, x21 - -i2s_handle_sd: - li x8, I2S_CTRL_ADDR_WS_SPK - lw x18, PWM_COUNT(x8) - lw x19, PWM_CMP3(x8) - - # exit if too early - bltu x18, x19, i2s_sd_exit - - la x27, _eos_i2s_drvr - - # move CMPs for next channel and store channel bit to x26 - lw x20, I2S_MIC_CMP2(x27) - lw x21, I2S_MIC_CMP3(x27) # 16-bit period - - add x23, x19, x20 - add x24, x23, x21 - slli x20, x21, 1 # 32-bit period - slli x21, x20, 1 # 64-bit period - bltu x24, x21, 0f - neg x21, x21 - add x23, x23, x21 - add x24, x24, x21 -0: - li x26, 0 - bltu x23, x20, 0f - li x26, 1 -0: - bltu x19, x20, 0f - neg x20, x20 - li x18, PLIC_PRIORITY - sw x0, 4*I2S_IRQ_SD_ID(x18) -0: - add x19, x19, x20 - - li x9, I2S_CTRL_ADDR_WS_MIC - sw x19, PWM_CMP3(x8) - sw x23, PWM_CMP2(x9) - sw x24, PWM_CMP3(x9) - - lw x24, I2S_FMT(x27) - lw x25, I2S_MODE(x27) - -i2s_abuf_pop: - and x8, x25, x26 - beqz x8, 0f - - lw x8, I2S_SAMPLE(x27) - j i2s_sd_xchg -0: - # pop from spk buf -> x8 - lw x9, I2S_SPK_BUF(x27) - beqz x9, i2s_sd_xchg - lhu x18, I2S_ABUF_OFF_IDXR(x9) - lhu x19, I2S_ABUF_OFF_IDXW(x9) - lhu x20, I2S_ABUF_OFF_SIZE(x9) - - beq x18, x19, 2f - - addi x20, x20, -1 - and x20, x20, x18 - lw x21, I2S_ABUF_OFF_ARRAY(x9) - add x21, x21, x20 - beqz x24, 0f - lbu x8, 0(x21) - addi x18, x18, 1 - j 1f -0: - lb x8, 0(x21) - lbu x20, 1(x21) - slli x8, x8, 8 - or x8, x8, x20 - addi x18, x18, 2 -1: - sh x18, I2S_ABUF_OFF_IDXR(x9) - -2: - li x21, 0xffff - sub x18, x19, x18 - and x18, x18, x21 - - # check for push to event queue - lw x9, I2S_SPK_WM(x27) - bgtu x18, x9, i2s_decode - - lw x9, I2S_SPK_EVT(x27) - beqz x9, i2s_decode - sw x0, I2S_SPK_EVT(x27) - - # push to event queue - jal x22, evtq_push - beqz x21, i2s_decode - li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_SPK) - sb x18, MSGQ_ITEM_OFF_TYPE(x21) - -i2s_decode: - beqz x24, 3f - # aLaw decode -> x8 - xori x8, x8, 0x55 - andi x9, x8, 0x80 - beqz x9, 0f - li x9, 1 - slli x9, x9, 7 - not x9, x9 - and x8, x8, x9 - li x9, -1 -0: - andi x18, x8, 0xf0 - srli x18, x18, 4 - addi x18, x18, 4 - - li x19, 4 - beq x18, x19, 1f - - andi x8, x8, 0x0f - addi x19, x18, -4 - sll x8, x8, x19 - - li x19, 1 - sll x19, x19, x18 - or x8, x8, x19 - - li x19, 1 - addi x18, x18, -5 - sll x19, x19, x18 - or x8, x8, x19 - j 2f -1: - slli x8, x8, 1 - ori x8, x8, 1 -2: - beqz x9, 3f - mul x8, x8, x9 -3: - beqz x25, i2s_sd_xchg - sw x8, I2S_SAMPLE(x27) - -i2s_sd_xchg: - # read/write shift reg: x8 -> sr -> x8 - li x18, GPIO_CTRL_ADDR - li x19, (0x1 << I2S_PIN_SD_IN) - li x20, (0x1 << I2S_PIN_SD_OUT) - li x21, (0x1 << I2S_PIN_CK_SR) - lw x22, GPIO_OUTPUT_VAL(x18) - - lw x9, GPIO_OUTPUT_EN(x18) - or x9, x9, x20 - sw x9, GPIO_OUTPUT_EN(x18) - - not x20, x20 - xor x22, x22, x21 - - li x23, 16 -0: - # write bit - li x9, 1 - slli x9, x9, 15 - and x9, x8, x9 - slli x8, x8, 1 -#if I2S_PIN_SD_OUT > 15 - slli x9, x9, (I2S_PIN_SD_OUT - 15) -#else - srli x9, x9, (15 - I2S_PIN_SD_OUT) -#endif - and x22, x22, x20 - or x22, x22, x9 - - # read bit - lw x9, GPIO_INPUT_VAL(x18) - and x9, x9, x19 - srli x9, x9, I2S_PIN_SD_IN - or x8, x8, x9 - - # 74HC595 ck low (I2S_PIN_CK_SR high) - xor x22, x22, x21 - sw x22, GPIO_OUTPUT_VAL(x18) - - # idle - li x9, I2S_IDLE_CYCLES -1: - addi x9, x9, -1 - bnez x9, 1b - - # 74HC595 ck high (I2S_PIN_CK_SR low) - xor x22, x22, x21 - sw x22, GPIO_OUTPUT_VAL(x18) - - addi x23, x23, -1 - bnez x23, 0b - - # idle - li x9, I2S_IDLE_CYCLES -1: - addi x9, x9, -1 - bnez x9, 1b - - # 74HC595 ck low (I2S_PIN_CK_SR high) - xor x22, x22, x21 - sw x22, GPIO_OUTPUT_VAL(x18) - - lw x9, GPIO_OUTPUT_EN(x18) - and x9, x9, x20 - sw x9, GPIO_OUTPUT_EN(x18) - - slli x8, x8, 16 - srai x8, x8, 16 - -i2s_encode: - beqz x24, i2s_abuf_push - # aLaw encode -> x8 - li x18, 0x800 - li x19, 7 - bgez x8, 0f - neg x8, x8 - lui x9, 0x80000 - or x8, x8, x9 -0: - and x9, x8, x18 - beq x9, x18, 1f - beqz x19, 1f - srli x18, x18, 1 - addi x19, x19, -1 - j 0b -1: - mv x9, x19 - bnez x9, 2f - addi x9, x9, 1 -2: - sra x8, x8, x9 - li x9, 0x8000000f - and x8, x8, x9 - slli x19, x19, 4 - or x8, x8, x19 - bgez x8, 3f - ori x8, x8, 0x80 -3: - xori x8, x8, 0x55 - andi x8, x8, 0xff - -i2s_abuf_push: - # check channel - # bnez x26, i2s_sd_exit - - # push to mic buf - lw x9, I2S_MIC_BUF(x27) - beqz x9, i2s_sd_exit - lhu x18, I2S_ABUF_OFF_IDXR(x9) - lhu x19, I2S_ABUF_OFF_IDXW(x9) - lhu x20, I2S_ABUF_OFF_SIZE(x9) - li x21, 0xffff - - sub x18, x19, x18 - and x18, x18, x21 - beq x18, x20, 2f - - addi x20, x20, -1 - and x20, x20, x19 - lw x21, I2S_ABUF_OFF_ARRAY(x9) - add x21, x21, x20 - beqz x24, 0f - sb x8, 0(x21) - addi x19, x19, 1 - addi x18, x18, 1 - j 1f -0: - sb x8, 1(x21) - srli x8, x8, 8 - sb x8, 0(x21) - addi x19, x19, 2 - addi x18, x18, 2 -1: - sh x19, I2S_ABUF_OFF_IDXW(x9) - -2: - # check for push to event queue - lw x9, I2S_MIC_WM(x27) - bltu x18, x9, i2s_sd_exit - - lw x9, I2S_MIC_EVT(x27) - beqz x9, i2s_sd_exit - sw x0, I2S_MIC_EVT(x27) - - # push to event queue - jal x22, evtq_push - beqz x21, i2s_sd_exit - li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_MIC) - sb x18, MSGQ_ITEM_OFF_TYPE(x21) - -i2s_sd_exit: - # complete - li x18, I2S_IRQ_SD_ID - li x19, PLIC_CLAIM - sw x18, 0(x19) - - # exit - j trap_exit_data - -i2s_handle_ws: - # enable sd irq - li x18, PLIC_PRIORITY - li x19, IRQ_PRIORITY_I2S_SD - sw x19, 4*I2S_IRQ_SD_ID(x18) - - # complete - li x18, I2S_IRQ_WS_ID - li x19, PLIC_CLAIM - sw x18, 0(x19) - - # exit - j trap_exit_data - -.global _eos_i2s_start_pwm -_eos_i2s_start_pwm: - addi sp, sp, -8*REGBYTES - STORE x8, 0*REGBYTES(sp) - STORE x9, 1*REGBYTES(sp) - STORE x18, 2*REGBYTES(sp) - STORE x19, 3*REGBYTES(sp) - STORE x20, 4*REGBYTES(sp) - STORE x21, 5*REGBYTES(sp) - STORE x22, 6*REGBYTES(sp) - STORE x23, 7*REGBYTES(sp) - - li x18, I2S_CTRL_ADDR_CK - li x19, I2S_CTRL_ADDR_WS_MIC - li x20, I2S_CTRL_ADDR_WS_SPK - li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK - li x22, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG - li x23, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG - sw x21, PWM_CFG(x18) - sw x22, PWM_CFG(x19) - sw x23, PWM_CFG(x20) - - LOAD x8, 0*REGBYTES(sp) - LOAD x9, 1*REGBYTES(sp) - LOAD x18, 2*REGBYTES(sp) - LOAD x19, 3*REGBYTES(sp) - LOAD x20, 4*REGBYTES(sp) - LOAD x21, 5*REGBYTES(sp) - LOAD x22, 6*REGBYTES(sp) - LOAD x23, 7*REGBYTES(sp) - addi sp, sp, 8*REGBYTES - - ret - -trap_exit_data: - # Remain in M-mode after mret - li x18, MSTATUS_MPP - csrs mstatus, x18 - - LOAD x8, 0*REGBYTES(sp) - LOAD x9, 1*REGBYTES(sp) - LOAD x18, 2*REGBYTES(sp) - LOAD x19, 3*REGBYTES(sp) - LOAD x20, 4*REGBYTES(sp) - LOAD x21, 5*REGBYTES(sp) - LOAD x22, 6*REGBYTES(sp) - LOAD x23, 7*REGBYTES(sp) - LOAD x24, 8*REGBYTES(sp) - LOAD x25, 9*REGBYTES(sp) - LOAD x26, 10*REGBYTES(sp) - LOAD x27, 11*REGBYTES(sp) - addi sp, sp, 12*REGBYTES - - mret - -handle_intr: - lui x18, %hi(trap_entry_text) - addi x18, x18, %lo(trap_entry_text) - jalr x0, x18 - - .section .text.entry - .align 4 - -trap_entry_text: - addi sp, sp, -20*REGBYTES - - STORE x1, 0*REGBYTES(sp) - STORE x2, 1*REGBYTES(sp) - STORE x3, 2*REGBYTES(sp) - STORE x4, 3*REGBYTES(sp) - STORE x5, 4*REGBYTES(sp) - STORE x6, 5*REGBYTES(sp) - STORE x7, 6*REGBYTES(sp) - STORE x10, 7*REGBYTES(sp) - STORE x11, 8*REGBYTES(sp) - STORE x12, 9*REGBYTES(sp) - STORE x13, 10*REGBYTES(sp) - STORE x14, 11*REGBYTES(sp) - STORE x15, 12*REGBYTES(sp) - STORE x16, 13*REGBYTES(sp) - STORE x17, 14*REGBYTES(sp) - STORE x28, 15*REGBYTES(sp) - STORE x29, 16*REGBYTES(sp) - STORE x30, 17*REGBYTES(sp) - STORE x31, 18*REGBYTES(sp) - - li x18, MCAUSE_TIMER - beq x8, x18, handle_timer - li x18, MCAUSE_EXT - beq x8, x18, handle_ext - mv a0, x8 - call _exit - -handle_timer: - call _eos_timer_handle - j trap_exit_text - -handle_ext: - mv a0, x9 - call eos_intr_handle - li x18, PLIC_CLAIM - sw a0, 0(x18) - -trap_exit_text: - # Remain in M-mode after mret - li t0, MSTATUS_MPP - csrs mstatus, t0 - - LOAD x1, 0*REGBYTES(sp) - LOAD x2, 1*REGBYTES(sp) - LOAD x3, 2*REGBYTES(sp) - LOAD x4, 3*REGBYTES(sp) - LOAD x5, 4*REGBYTES(sp) - LOAD x6, 5*REGBYTES(sp) - LOAD x7, 6*REGBYTES(sp) - LOAD x10, 7*REGBYTES(sp) - LOAD x11, 8*REGBYTES(sp) - LOAD x12, 9*REGBYTES(sp) - LOAD x13, 10*REGBYTES(sp) - LOAD x14, 11*REGBYTES(sp) - LOAD x15, 12*REGBYTES(sp) - LOAD x16, 13*REGBYTES(sp) - LOAD x17, 14*REGBYTES(sp) - LOAD x28, 15*REGBYTES(sp) - LOAD x29, 16*REGBYTES(sp) - LOAD x30, 17*REGBYTES(sp) - LOAD x31, 18*REGBYTES(sp) - - LOAD x8, 20*REGBYTES(sp) - LOAD x9, 21*REGBYTES(sp) - LOAD x18, 22*REGBYTES(sp) - LOAD x19, 23*REGBYTES(sp) - LOAD x20, 24*REGBYTES(sp) - LOAD x21, 25*REGBYTES(sp) - LOAD x22, 26*REGBYTES(sp) - LOAD x23, 27*REGBYTES(sp) - LOAD x24, 28*REGBYTES(sp) - LOAD x25, 29*REGBYTES(sp) - LOAD x26, 30*REGBYTES(sp) - LOAD x27, 31*REGBYTES(sp) - - addi sp, sp, 32*REGBYTES - mret diff --git a/fw/fe310/eos/uart.c b/fw/fe310/eos/uart.c deleted file mode 100644 index 30f76d9..0000000 --- a/fw/fe310/eos/uart.c +++ /dev/null @@ -1,114 +0,0 @@ -#include -#include -#include - -#include "encoding.h" -#include "platform.h" -#include "prci_driver.h" - -#include "eos.h" -#include "interrupt.h" -#include "event.h" - -#include "uart.h" - -static eos_uart_handler_t uart_handler[EOS_UART_MAX_ETYPE]; - -static void uart_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char idx = (type & ~EOS_EVT_MASK) - 1; - - if ((idx < EOS_UART_MAX_ETYPE) && uart_handler[idx]) { - uart_handler[idx](type); - } else { - eos_evtq_bad_handler(type, buffer, len); - } -} - -static void uart_handle_intr(void) { - if (UART0_REG(UART_REG_IP) & UART_IP_TXWM) { - UART0_REG(UART_REG_IE) &= ~UART_IP_TXWM; - eos_evtq_push_isr(EOS_EVT_UART | EOS_UART_ETYPE_TX, NULL, 0); - } - if (UART0_REG(UART_REG_IP) & UART_IP_RXWM) { - UART0_REG(UART_REG_IE) &= ~UART_IP_RXWM; - eos_evtq_push_isr(EOS_EVT_UART | EOS_UART_ETYPE_RX, NULL, 0); - } -} - -int eos_uart_init(uint8_t wakeup_cause) { - int i; - - for (i=0; i - -#define EOS_UART_ETYPE_TX 1 -#define EOS_UART_ETYPE_RX 2 - -#define EOS_UART_MAX_ETYPE 2 - -#define EOS_UART_SPEED 115200 - -typedef void (*eos_uart_handler_t) (unsigned char); - -int eos_uart_init(uint8_t wakeup_cause); -void eos_uart_start(void); -void eos_uart_stop(void); -void eos_uart_speed(uint32_t baud_rate); - -void eos_uart_set_handler(unsigned char type, eos_uart_handler_t handler); - -void eos_uart_txwm_set(uint8_t wm); -void eos_uart_txwm_clear(void); -void eos_uart_rxwm_set(uint8_t wm); -void eos_uart_rxwm_clear(void); -int eos_uart_putc(int c, char b); -int eos_uart_getc(char b); \ No newline at end of file diff --git a/fw/fe310/eos/wifi.c b/fw/fe310/eos/wifi.c deleted file mode 100644 index 0663582..0000000 --- a/fw/fe310/eos/wifi.c +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include - -#include "eos.h" -#include "event.h" -#include "net.h" - -#include "wifi.h" - -static eos_evt_handler_t evt_handler[EOS_WIFI_MAX_MTYPE]; - -static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t len) { - unsigned char mtype; - - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); - return; - } - - mtype = buffer[0]; - if ((mtype < EOS_WIFI_MAX_MTYPE) && evt_handler[mtype]) { - evt_handler[mtype](mtype, buffer, len); - } else { - eos_net_bad_handler(type, buffer, len); - } -} - -void eos_wifi_netinit(void) { - int i; - - for (i=0; i EOS_NET_MTU) return EOS_ERR_SIZE; - - buf = buffer; - buf[0] = EOS_WIFI_MTYPE_AUTH; - buf++; - strcpy(buf, ssid); - buf += ssid_len; - strcpy(buf, pass); - buf += pass_len; - - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1 + ssid_len + pass_len, async, 1); -} - -int eos_wifi_connect(unsigned char *buffer) { - int async; - - async = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } - buffer[0] = EOS_WIFI_MTYPE_CONNECT; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); -} - -int eos_wifi_disconnect(unsigned char *buffer) { - int async; - - async = 0; - if (buffer == NULL) { - buffer = eos_net_alloc(); - async = 1; - } - buffer[0] = EOS_WIFI_MTYPE_DISCONNECT; - return _eos_net_send(EOS_NET_MTYPE_WIFI, buffer, 1, async, 1); -} diff --git a/fw/fe310/eos/wifi.h b/fw/fe310/eos/wifi.h deleted file mode 100644 index 4a49518..0000000 --- a/fw/fe310/eos/wifi.h +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "event.h" - -#define EOS_WIFI_MTYPE_SCAN 1 -#define EOS_WIFI_MTYPE_AUTH 2 -#define EOS_WIFI_MTYPE_CONNECT 3 -#define EOS_WIFI_MTYPE_DISCONNECT 4 - -#define EOS_WIFI_MAX_MTYPE 5 - -void eos_wifi_netinit(void); -void eos_wifi_set_handler(unsigned char mtype, eos_evt_handler_t handler); -eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype); - -int eos_wifi_scan(unsigned char *buffer); -int eos_wifi_auth(const char *ssid, const char *pass, unsigned char *buffer); -int eos_wifi_connect(unsigned char *buffer); -int eos_wifi_disconnect(unsigned char *buffer); -- cgit v1.2.3