diff options
119 files changed, 2858 insertions, 2197 deletions
diff --git a/fw/fe310/eos/board.h b/fw/fe310/eos/board.h index 21732dc..7836bd7 100644 --- a/fw/fe310/eos/board.h +++ b/fw/fe310/eos/board.h @@ -1,24 +1,30 @@ -#define SPI_DIV_NET 16 -#define SPI_DIV_EVE 4 -#define SPI_DIV_SDC 1024 +#define SPI_DIV_NET 16 /* 60 MHz max */ +#define SPI_DIV_EVE 5 /* 30 MHz max */ +#define SPI_DIV_SDC 5 #define SPI_DIV_CAM 24 +#define SPI_DIV_LCD 0 /* spi 9bit */ +#define SPI_DIV_HPAMP 1024 #define SPI_CSID_NET 0 #define SPI_CSID_EVE 2 -#define SPI_CSID_SDC -1 +#define SPI_CSID_SDC SPI_CSID_NONE #define SPI_CSID_CAM 3 +#define SPI_CSID_LCD SPI_CSID_NONE +#define SPI_CSID_HPAMP SPI_CSID_NONE -#define SPI_IOF_MASK ((1 << IOF_SPI1_SCK) | (1 << IOF_SPI1_MOSI) | (1 << IOF_SPI1_MISO) | (1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS2) | (1 << IOF_SPI1_SS3)) - -#define SPI_CSPIN_NET -1 -#define SPI_CSPIN_EVE -1 +#define SPI_CSPIN_NET 2 +#define SPI_CSPIN_EVE 9 #define SPI_CSPIN_SDC 0 -#define SPI_CSPIN_CAM -1 -/* only when i2s is off */ -#define SPI_CSPIN_LCD 21 +#define SPI_CSPIN_CAM 10 +#define SPI_CSPIN_LCD 21 /* only when i2s is off */ +#define SPI_CSPIN_HPAMP (SPI_CSFLAG_EGPIO | EGPIO_PIN_HPAMP_CS) -#define NET_PIN_RTS 20 -#define NET_PIN_CTS 22 +#define SPI_IOF_MASK ((1 << IOF_SPI1_SCK) | (1 << IOF_SPI1_MOSI) | (1 << IOF_SPI1_MISO) | (1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS2) | (1 << IOF_SPI1_SS3)) +// #define SPI_IOF_CSXOR ((1 << IOF_SPI1_SS0) | (1 << IOF_SPI1_SS3)) +#define SPI_IOF_CSXOR 0 + +#define NET_PIN_RTS 22 +#define NET_PIN_CTS 20 #define EGPIO_PIN_INT 23 @@ -32,6 +38,8 @@ #define I2S_PIN_INT 16 /* only when i2s is off */ -#define EVE_PIN_INTR 1 /* only when EGPIO_PIN_CTP_SEL is off */ -#define CTP_PIN_INT 1 /* only when EGPIO_PIN_CTP_SEL is on */ -#define CTP_PIN_RST 19 +#define CTP_PIN_INT 1 /* EGPIO_PIN_CTP_SEL is on: CTP int; EGPIO_PIN_CTP_SEL is off: EVE int */ +#define CTP_PIN_RST 19 /* only when EGPIO_PIN_CTP_SEL is on */ + +/* EVE gpio in dev/eve_priv.h */ +/* FXL6408 gpio in dev/egpio.h */
\ No newline at end of file diff --git a/fw/fe310/eos/dev/aon.c b/fw/fe310/eos/dev/aon.c index 3d8aaf6..7e4f5ec 100644 --- a/fw/fe310/eos/dev/aon.c +++ b/fw/fe310/eos/dev/aon.c @@ -6,13 +6,12 @@ #include "aon.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - #define AON_EVE_REG 0 #define AON_EVE_MASK 0x03 +#define AON_NET_REG 0 +#define AON_NET_MASK 0x04 + void eos_aon_save4eve(uint8_t power_state) { uint32_t reg; @@ -21,9 +20,23 @@ void eos_aon_save4eve(uint8_t power_state) { reg &= ~AON_EVE_MASK; reg |= power_state; - eos_aon_set_reg(0, power_state); + eos_aon_set_reg(AON_EVE_REG, reg); } uint8_t eos_aon_load4eve(void) { return (eos_aon_get_reg(AON_EVE_REG) & AON_EVE_MASK); } + +void eos_aon_save4net(int absent) { + uint32_t reg; + + reg = eos_aon_get_reg(AON_NET_REG); + reg &= ~AON_NET_MASK; + if (absent) reg |= AON_NET_MASK; + + eos_aon_set_reg(AON_NET_REG, reg); +} + +int eos_aon_load4net(void) { + return !!(eos_aon_get_reg(AON_NET_REG) & AON_NET_MASK); +}
\ No newline at end of file diff --git a/fw/fe310/eos/dev/aon.h b/fw/fe310/eos/dev/aon.h index 22ba84a..4551cc0 100644 --- a/fw/fe310/eos/dev/aon.h +++ b/fw/fe310/eos/dev/aon.h @@ -1,4 +1,7 @@ #include <stdint.h> void eos_aon_save4eve(uint8_t power_state); -uint8_t eos_aon_load4eve(void);
\ No newline at end of file +uint8_t eos_aon_load4eve(void); + +void eos_aon_save4net(int absent); +int eos_aon_load4net(void);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/app.c b/fw/fe310/eos/dev/app.c index 3c215f4..ce2cf05 100644 --- a/fw/fe310/eos/dev/app.c +++ b/fw/fe310/eos/dev/app.c @@ -2,23 +2,18 @@ #include <stdint.h> #include "eos.h" +#include "log.h" #include "hpamp.h" #include "app.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - void eos_app_hp_change(int hp_det) { if (hp_det) { int rv; rv = eos_hpamp_init(); if (rv) { -#ifdef EOS_DEBUG - printf("I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv); -#endif + EOS_LOG(EOS_LOG_ERR, "I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv); return; } } diff --git a/fw/fe310/eos/dev/batt.c b/fw/fe310/eos/dev/batt.c index 6f1eb97..45e6af0 100644 --- a/fw/fe310/eos/dev/batt.c +++ b/fw/fe310/eos/dev/batt.c @@ -2,14 +2,12 @@ #include <stdint.h> #include "eos.h" +#include "log.h" + #include "soc/pwr.h" #include "drv/bq25895.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - int eos_batt_init(void) { uint8_t wakeup_cause; int rst, rv; @@ -31,10 +29,10 @@ int eos_batt_init(void) { if (rv) return rv; #ifdef EOS_DEBUG - printf("BQ25895:\n"); + EOS_LOG(EOS_LOG_INFO, "BQ25895:\n"); for (i=0; i<0x15; i++) { rv = bq25895_reg_read(i, &data); - if (!rv) printf(" REG%.2X: %.2X\n", i, data); + if (!rv) EOS_LOG(EOS_LOG_INFO, " REG%.2X: %.2X\n", i, data); } #endif diff --git a/fw/fe310/eos/dev/cam.h b/fw/fe310/eos/dev/cam.h index 5153464..b0e1368 100644 --- a/fw/fe310/eos/dev/cam.h +++ b/fw/fe310/eos/dev/cam.h @@ -2,6 +2,9 @@ #include "drv/ov2640.h" #include "drv/arducam.h" +#include "egpio.h" +#include "egpio_priv.h" + #define eos_cam_init ov2640_init #define eos_cam_set_pixfmt ov2640_set_pixfmt #define eos_cam_set_framesize ov2640_set_pixfmt @@ -12,3 +15,6 @@ #define eos_cam_fbuf_size arducam_fbuf_size #define eos_cam_fbuf_read arducam_fbuf_read #define eos_cam_fbuf_done arducam_fbuf_done + +#define eos_cam_en() eos_egpio_set_val(EGPIO_PIN_CAM_EN, 1) +#define eos_cam_dis() eos_egpio_set_val(EGPIO_PIN_CAM_EN, 0) diff --git a/fw/fe310/eos/dev/ctp.c b/fw/fe310/eos/dev/ctp.c index fcc3c68..b6459b4 100644 --- a/fw/fe310/eos/dev/ctp.c +++ b/fw/fe310/eos/dev/ctp.c @@ -10,17 +10,13 @@ #include "eve/eve_touch_engine.h" #include "egpio.h" +#include "egpio_priv.h" #include "eve.h" -#include "pwr.h" #include "drv/fxl6408.h" #include "drv/gt911.h" #include "ctp.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - int eos_ctp_init(void) { uint8_t wakeup_cause; int rv, rst; @@ -37,6 +33,7 @@ int eos_ctp_init(void) { } int eos_ctp_reset(void) { + uint8_t status = 0; int rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; @@ -56,6 +53,7 @@ int eos_ctp_sleep(void) { int rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + if (!gt911_running()) return EOS_ERR; rv = eos_egpio_intr_disable(); if (rv) return rv; @@ -73,6 +71,7 @@ int eos_ctp_wake(void) { int rv; if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL) || !eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR_BUSY; + if (gt911_running()) return EOS_ERR; rv = eos_egpio_fxl_set_pin(EGPIO_PIN_CTP_INT, FXL6408_REG_PULL_DIR, 1); if (rv) return rv; @@ -94,10 +93,10 @@ int eos_ctp_give(void) { rv = eos_egpio_intr_disable(); if (rv) return rv; - rv = eve_select(); + rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); if (rv) return rv; - rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); + rv = eve_select(); if (rv) return rv; eve_touch_set_engine(EVE_TOUCH_ENGINE_GOODIX); @@ -138,7 +137,6 @@ int eos_ctp_take(void) { int eos_ctp_handle_intr(void) { uint8_t status; uint8_t points[GT911_SIZE_PBUF * GT911_MAX_POINTS]; - static int clear_tag0 = 0; int i, num_points; int rv; uint32_t start; @@ -150,11 +148,11 @@ int eos_ctp_handle_intr(void) { num_points = status & 0xf; if (num_points > 5) { rv = EOS_ERR; - goto handle_intr_fin; + goto handle_intr_fin1; } rv = eve_select(); - if (rv) goto handle_intr_fin; + if (rv) goto handle_intr_fin1; start = eos_get_tick(); while (!eve_touch_ehost_ready()) { @@ -163,20 +161,14 @@ int eos_ctp_handle_intr(void) { if (eos_tdelta_ms(start) > EVE_CMD_EXEC_TO) { rv = EOS_ERR_TIMEOUT; - eve_deselect(); - goto handle_intr_fin; + goto handle_intr_fin0; } if (num_points) { - if (clear_tag0) { - eve_touch_clear_tag0(); - clear_tag0 = 0; - } rv = gt911_get_points(num_points, points); if (rv) { rv = EOS_ERR; - eve_deselect(); - goto handle_intr_fin; + goto handle_intr_fin0; } for (i=0; i<num_points; i++) { @@ -193,20 +185,14 @@ int eos_ctp_handle_intr(void) { } } else { eve_touch_ehost_enter(0, 0x8000, 0x8000); - clear_tag0 = 1; } eve_touch_ehost_end(); +handle_intr_fin0: eve_deselect(); - -handle_intr_fin: +handle_intr_fin1: gt911_set_status(0); - if (rv) { -#ifdef EOS_DEBUG - printf("CTP HANDLE INTR ERR:%d\n", rv); -#endif - return rv; - } + if (rv) return rv; - return 1; + return status; } diff --git a/fw/fe310/eos/dev/drv/arducam.c b/fw/fe310/eos/dev/drv/arducam.c index a50830a..8ac3823 100644 --- a/fw/fe310/eos/dev/drv/arducam.c +++ b/fw/fe310/eos/dev/drv/arducam.c @@ -36,21 +36,21 @@ #define ARDUCAM_VAL_GPIO_PWREN 0x04 static uint8_t reg_read(uint8_t addr) { - uint8_t ret; + uint8_t rv; - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(addr, 0); - ret = drv_spi_xchg8(0, 0); - drv_spi_cs_clear(); + rv = drv_spi_xchg8(0, 0); + drv_spi_clear_cs(); - return ret; + return rv; } static void reg_write(uint8_t addr, uint8_t val) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(addr | 0x80, 0); drv_spi_xchg8(val, 0); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } void arducam_capture(void) { @@ -70,25 +70,25 @@ void arducam_capture_wait(void) { } uint32_t arducam_fbuf_size(void) { - uint32_t ret; + uint32_t rv; - ret = reg_read(ARDUCAM_REG_FIFO_SIZE1); - ret |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8; - ret |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16; - return ret; + rv = reg_read(ARDUCAM_REG_FIFO_SIZE1); + rv |= reg_read(ARDUCAM_REG_FIFO_SIZE2) << 8; + rv |= (reg_read(ARDUCAM_REG_FIFO_SIZE3) & 0x7f) << 16; + return rv; } void arducam_fbuf_read(uint8_t *buffer, uint16_t sz, int first) { int i; - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(ARDUCAM_REG_READ_BURST, 0); if (first) drv_spi_xchg8(0, 0); for (i=0; i<sz; i++) { buffer[i] = drv_spi_xchg8(0, 0); } - drv_spi_cs_clear(); + drv_spi_clear_cs(); } void arducam_fbuf_done(void) { diff --git a/fw/fe310/eos/dev/drv/gt911.c b/fw/fe310/eos/dev/drv/gt911.c index cd71d9a..8eb4358 100644 --- a/fw/fe310/eos/dev/drv/gt911.c +++ b/fw/fe310/eos/dev/drv/gt911.c @@ -124,6 +124,10 @@ void gt911_wake(void) { drv_gpio_set(GPIO_INPUT_EN, GT911_PIN_INT); } +int gt911_running(void) { + return drv_gpio_get(GPIO_INPUT_EN, GT911_PIN_INT); +} + int gt911_cfg_read(uint8_t *cfg_buf) { int rv; @@ -148,20 +152,20 @@ int gt911_cfg_print(void) { rv = gt911_cfg_read(cfg_buf); if (rv) return rv; - printf("GT911 CFG:\n"); + DRV_LOG(DRV_LOG_INFO, "GT911 CFG:\n"); for (i=0; i<GT911_SIZE_CFG-2; i++) { - printf("%.2X", cfg_buf[i]); + DRV_LOG(DRV_LOG_INFO, "%.2X", cfg_buf[i]); if (i % 8 == 7) { - printf("\n"); + DRV_LOG(DRV_LOG_INFO, "\n"); } else { - printf(" "); + DRV_LOG(DRV_LOG_INFO, " "); } } rv = gt911_fw_ver(cfg_buf); if (rv) return rv; - printf("GT911 FW VER:%.2X%.2X\n", cfg_buf[1], cfg_buf[0]); + DRV_LOG(DRV_LOG_INFO, "GT911 FW VER:%.2X%.2X\n", cfg_buf[1], cfg_buf[0]); return DRV_OK; } diff --git a/fw/fe310/eos/dev/drv/gt911.h b/fw/fe310/eos/dev/drv/gt911.h index 9db6981..61a6593 100644 --- a/fw/fe310/eos/dev/drv/gt911.h +++ b/fw/fe310/eos/dev/drv/gt911.h @@ -10,6 +10,7 @@ void gt911_reset(void); int gt911_sleep(void); void gt911_wake(void); +int gt911_running(void); int gt911_cfg_read(uint8_t *cfg_buf); int gt911_cfg_write(uint8_t *cfg_buf); diff --git a/fw/fe310/eos/dev/drv/ili9806e.c b/fw/fe310/eos/dev/drv/ili9806e.c index 45aabb7..b57a14c 100644 --- a/fw/fe310/eos/dev/drv/ili9806e.c +++ b/fw/fe310/eos/dev/drv/ili9806e.c @@ -5,15 +5,11 @@ #include "platform.h" #include "ili9806e.h" -#ifdef DRV_DEBUG -#include <stdio.h> -#endif - int ili9806e_init(void) { int rv; uint8_t chip_id[3]; - drv_spi_cs_set(); + drv_spi_set_cs(); /* LCD Setting */ drv_spi9bit_write(0, 0xFF); // change to Page 1 CMD @@ -38,15 +34,13 @@ int ili9806e_init(void) { drv_spi9bit_write(0, 0x02); drv_spi9bit_read(&chip_id[2]); -#ifdef DRV_DEBUG - printf("LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]); -#endif + DRV_LOG(DRV_LOG_INFO, "LCD CHIP ID: %.2x%.2x%.2x\n", chip_id[0], chip_id[1], chip_id[2]); drv_spi9bit_write(0, 0xFE); // disable read drv_spi9bit_write(1, 0x00); if (memcmp(chip_id, "\x98\x06\x04", sizeof(chip_id))) { - drv_spi_cs_clear(); + drv_spi_clear_cs(); return DRV_ERR_NOTFOUND; } @@ -404,28 +398,28 @@ int ili9806e_init(void) { drv_spi9bit_write(0, 0x29); drv_sleep(25); - drv_spi_cs_clear(); + drv_spi_clear_cs(); return DRV_OK; } void ili9806e_sleep(void) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi9bit_write(0, 0x28); drv_sleep(10); drv_spi9bit_write(0, 0x10); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } void ili9806e_wake(void) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi9bit_write(0, 0x11); drv_sleep(120); drv_spi9bit_write(0, 0x29); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } diff --git a/fw/fe310/eos/dev/drv/pcm1770.c b/fw/fe310/eos/dev/drv/pcm1770.c index c617ae9..eec7bd0 100644 --- a/fw/fe310/eos/dev/drv/pcm1770.c +++ b/fw/fe310/eos/dev/drv/pcm1770.c @@ -5,8 +5,8 @@ #include "pcm1770.h" void pcm1770_reg_write(uint8_t addr, uint8_t val) { - drv_spi_cs_set(); + drv_spi_set_cs(); drv_spi_xchg8(addr, 0); drv_spi_xchg8(val, 0); - drv_spi_cs_clear(); + drv_spi_clear_cs(); } diff --git a/fw/fe310/eos/dev/drv/platform.h b/fw/fe310/eos/dev/drv/platform.h index d1f7248..a2405d5 100644 --- a/fw/fe310/eos/dev/drv/platform.h +++ b/fw/fe310/eos/dev/drv/platform.h @@ -1,6 +1,7 @@ #include "board.h" #include "eos.h" +#include "log.h" #include "soc/timer.h" #include "soc/i2c.h" #include "soc/spi.h" @@ -16,17 +17,18 @@ #define DRV_ERR EOS_ERR #define DRV_ERR_NOTFOUND EOS_ERR_NOTFOUND -/* should define theese for non-EOS platforms: -#define GPIO_INPUT_EN -#define GPIO_OUTPUT_EN -#define GPIO_OUTPUT_VAL -*/ +#define DRV_LOG_DEBUG EOS_LOG_DEBUG +#define DRV_LOG_INFO EOS_LOG_INFO +#define DRV_LOG_ERR EOS_LOG_ERR +#define DRV_LOG_NONE EOS_LOG_NONE +#define DRV_LOG_LEVEL EOS_LOG_LEVEL +#define DRV_LOG(l, ...) EOS_LOG(l, __VA_ARGS__) #define GT911_PIN_INT CTP_PIN_INT #define GT911_PIN_RST CTP_PIN_RST -#define drv_spi_cs_set eos_spi_cs_set -#define drv_spi_cs_clear eos_spi_cs_clear +#define drv_spi_set_cs eos_spi_set_cs +#define drv_spi_clear_cs eos_spi_clear_cs #define drv_spi_xchg8 eos_spi_xchg8 #define drv_spi9bit_read eos_spi9bit_read #define drv_spi9bit_write eos_spi9bit_write @@ -38,5 +40,12 @@ #define drv_sleep eos_sleep +/* should define theese for non-EOS platforms: +#define GPIO_INPUT_EN +#define GPIO_OUTPUT_EN +#define GPIO_OUTPUT_VAL +*/ + +#define drv_gpio_get eos_gpio_get #define drv_gpio_set eos_gpio_set #define drv_gpio_clear eos_gpio_clear diff --git a/fw/fe310/eos/dev/drv/sdc_platform.h b/fw/fe310/eos/dev/drv/sdc_platform.h index 5d562c2..daf2670 100644 --- a/fw/fe310/eos/dev/drv/sdc_platform.h +++ b/fw/fe310/eos/dev/drv/sdc_platform.h @@ -1,19 +1,31 @@ /* included from sdcard.h - needs relative includes */ #include "../../eos.h" +#include "../../log.h" #include "../../soc/timer.h" #include "../../soc/spi.h" #include "../sdc_crypto.h" +#ifdef EOS_DEBUG +#define SDC_DEBUG +#endif + #define SDC_OK EOS_OK #define SDC_ERR EOS_ERR #define SDC_ERR_BUSY EOS_ERR_BUSY +#define SDC_LOG_DEBUG EOS_LOG_DEBUG +#define SDC_LOG_INFO EOS_LOG_INFO +#define SDC_LOG_ERR EOS_LOG_ERR +#define SDC_LOG_NONE EOS_LOG_NONE +#define SDC_LOG_LEVEL EOS_LOG_LEVEL +#define SDC_LOG(l, ...) EOS_LOG(l, __VA_ARGS__) + #define sdc_spi_xchg8 eos_spi_xchg8 #define sdc_spi_xchg16 eos_spi_xchg16 #define sdc_spi_xchg32 eos_spi_xchg32 -#define sdc_spi_cs_set eos_spi_cs_set -#define sdc_spi_cs_clear eos_spi_cs_clear +#define sdc_spi_set_cs eos_spi_set_cs +#define sdc_spi_clear_cs eos_spi_clear_cs #define sdc_sleep eos_sleep #define sdc_get_tick eos_get_tick #define sdc_tdelta_ms eos_tdelta_ms diff --git a/fw/fe310/eos/dev/drv/sdcard.c b/fw/fe310/eos/dev/drv/sdcard.c index 96b01ae..7d21b3d 100644 --- a/fw/fe310/eos/dev/drv/sdcard.c +++ b/fw/fe310/eos/dev/drv/sdcard.c @@ -126,18 +126,18 @@ static void sdc_buf_recv(unsigned char *buffer, uint16_t len) { } static void sdc_select(void) { - sdc_spi_cs_set(); + sdc_spi_set_cs(); sdc_spi_xchg8(0xff, 0); } static void sdc_deselect(void) { - sdc_spi_cs_clear(); + sdc_spi_clear_cs(); sdc_spi_xchg8(0xff, 0); } static int sdc_xchg_cmd(uint8_t cmd, uint32_t arg, uint8_t flags) { int i; - uint8_t ret; + uint8_t rv; uint8_t crc = 0x7f; cmd |= 0x40; @@ -156,11 +156,11 @@ static int sdc_xchg_cmd(uint8_t cmd, uint32_t arg, uint8_t flags) { i = SDC_NCR; do { - ret = sdc_xchg8(0xff); - } while ((ret & 0x80) && --i); - if (ret & 0x80) return SDC_ERR_BUSY; + rv = sdc_xchg8(0xff); + } while ((rv & 0x80) && --i); + if (rv & 0x80) return SDC_ERR_BUSY; - return ret; + return rv; } static int sdc_ready(uint32_t timeout) { @@ -256,11 +256,12 @@ int sdc_init(uint32_t timeout) { uint32_t start; start = sdc_get_tick(); - sdc_sleep(5); - for (i=10; i--;) sdc_xchg8(0xff); /* 80 dummy cycles */ + do { + if (sdc_tdelta_ms(start) > timeout) return SDC_ERR_BUSY; + 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_RV2ERR(rv); + rv = sdc_cmd(GO_IDLE_STATE, 0, SDC_CMD_FLAG_CRC, SDC_TIMEOUT_CMD); + } while (rv != SDC_R1_IDLE_STATE); sdc_select(); rv = sdc_cmd(SEND_IF_COND, 0x1aa, SDC_CMD_FLAG_CRC | SDC_CMD_FLAG_NOCS, sdc_nto(start, timeout)); @@ -341,11 +342,11 @@ int sdc_init(uint32_t timeout) { if (rv) return rv; #ifdef SDC_DEBUG - printf("SDCARD CSD: "); + SDC_LOG(SDC_LOG_INFO, "SDCARD CSD: "); for (i=0; i<16; i++) { - printf("%.2x ", csd[i]); + SDC_LOG(SDC_LOG_INFO, "%.2x ", csd[i]); } - printf("\n"); + SDC_LOG(SDC_LOG_INFO, "\n"); #endif if (csd[10] & 0x40) _type |= SDC_CAP_ERASE_EN; } @@ -366,7 +367,7 @@ void sdc_clear(void) { sdc_type = SDC_TYPE_NONE; } -int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { +int sdc_get_sect_count(uint32_t *sectors, uint32_t timeout) { int rv; uint8_t csd[16]; uint32_t start; @@ -393,7 +394,7 @@ int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors) { return SDC_OK; } -int sdc_get_blk_size(uint32_t timeout, uint32_t *size) { +int sdc_get_blk_size(uint32_t *size, uint32_t timeout) { int rv; uint8_t rbl[64]; /* SD Status or CSD register */ uint32_t start; diff --git a/fw/fe310/eos/dev/drv/sdcard.h b/fw/fe310/eos/dev/drv/sdcard.h index 39891bb..b4da896 100644 --- a/fw/fe310/eos/dev/drv/sdcard.h +++ b/fw/fe310/eos/dev/drv/sdcard.h @@ -20,8 +20,8 @@ uint8_t sdc_get_type(void); uint8_t sdc_get_cap(void); void sdc_clear(void); -int sdc_get_sect_count(uint32_t timeout, uint32_t *sectors); -int sdc_get_blk_size(uint32_t timeout, uint32_t *size); +int sdc_get_sect_count(uint32_t *sectors, uint32_t timeout); +int sdc_get_blk_size(uint32_t *size, uint32_t timeout); int sdc_sync(uint32_t timeout); int sdc_erase(uint32_t blk_start, uint32_t blk_end, uint32_t timeout); int sdc_sect_read(uint32_t sect, unsigned int count, uint8_t *buffer); diff --git a/fw/fe310/eos/dev/egpio.c b/fw/fe310/eos/dev/egpio.c index 7358082..cfcd0f3 100644 --- a/fw/fe310/eos/dev/egpio.c +++ b/fw/fe310/eos/dev/egpio.c @@ -6,6 +6,8 @@ #include "board.h" #include "eos.h" +#include "log.h" + #include "event.h" #include "soc/interrupt.h" @@ -18,24 +20,31 @@ #include "sdcard.h" #include "ctp.h" #include "eve.h" + #include "app.h" #include "drv/fxl6408.h" #include "egpio.h" +#include "egpio_priv.h" /* FXL chip only */ -static const uint8_t egpio_switch[2] = { - EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE, +static const uint8_t egpio_switch[EGPIO_MAX_FXL_CHIP] = { + EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE, EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET, }; static uint8_t egpio_pinval[EGPIO_MAX_CHIP]; +static uint8_t egpio_intmask[EGPIO_MAX_FXL_CHIP]; static uint8_t egpio_alt_pin; static uint32_t wake_start; static eos_egpio_intr_handler_t egpio_intr_handler; static eos_egpio_ext_handler_t egpio_ext_handler; +static int egpio_fxl_set_mask(uint8_t chip_id, uint8_t mask); +static int egpio_set_val(uint8_t pin, int val); +static int egpio_get_val(uint8_t pin); + #define EGPIO_ALT_EVEAUDIO_DIS 0x01 #define EGPIO_ALT_LSGAIN_SEL 0x02 #define EGPIO_ALT_AUDIO_SEL 0x04 @@ -43,8 +52,8 @@ static eos_egpio_ext_handler_t egpio_ext_handler; #define BITSET(var, bit, val) { var = (val) ? (var | (bit)) : (var & ~(bit)); } #define PINSWITCH(STPIN, SETPIN) { \ int rv; \ - BITSET(egpio_alt_pin, pin2alt_bit(STPIN), _eos_egpio_get_val(STPIN)); \ - rv = _eos_egpio_set_val(SETPIN, !!(egpio_alt_pin & pin2alt_bit(SETPIN))); \ + BITSET(egpio_alt_pin, pin2alt_bit(STPIN), egpio_get_val(STPIN)); \ + rv = egpio_set_val(SETPIN, !!(egpio_alt_pin & pin2alt_bit(SETPIN))); \ if (rv) return rv; \ } @@ -65,20 +74,22 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { int rv; switch (chip_id) { - case 0: { + case EGPIO_CHIP_FXL0: { if (intr & EGPIO_BIT_BAT_INT) { uint8_t fault0, fault1; rv = eos_batt_read_fault(&fault0, &fault1); if (rv) return rv; - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_BAT, fault1, fault0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_BAT, fault1, fault0); } if (intr & EGPIO_BIT_CTP_INT) { - eos_ctp_handle_intr(); + rv = eos_ctp_handle_intr(); + if (rv < 0) return rv; } if (intr & EGPIO_BIT_EVE_INT) { - eos_eve_handle_intr(); + rv = eos_eve_handle_intr(); + if (rv < 0) return rv; } if (intr & EGPIO_BIT_BTN_WAKE) { int btn_wake, tdelta; @@ -89,27 +100,29 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { } else { tdelta = eos_tdelta_ms(wake_start); } - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_WAKE, btn_wake, btn_wake ? tdelta : 0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_WAKE, btn_wake, btn_wake ? tdelta : 0); } - if (intr & EGPIO_BIT_SDCARD_DET) { - int sdc_det = eos_egpio_get_val(EGPIO_PIN_SDCARD_DET); + if (intr & EGPIO_BIT_SDCARD_NDET) { + int sdc_det; - eos_sdc_insert(sdc_det); - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_SDCARD, sdc_det, 0); + sdc_det = !eos_egpio_get_val(EGPIO_PIN_SDCARD_NDET); + rv = eos_sdc_insert(sdc_det, 0); + if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INSERT ERR:%d\n", rv); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_SDCARD, sdc_det, rv); } break; } - case 1: { + case EGPIO_CHIP_FXL1: { if (intr & EGPIO_BIT_MIC_MUTE) { - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_MUTE, eos_egpio_get_val(EGPIO_PIN_MIC_MUTE), 0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_MUTE, eos_egpio_get_val(EGPIO_PIN_MIC_MUTE), 0); } if (intr & EGPIO_BIT_HP_NDET) { int hp_det, i2s_running, app_audio; hp_det = !eos_egpio_get_val(EGPIO_PIN_HP_NDET); i2s_running = eos_i2s_running(); - app_audio = !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL); + app_audio = !egpio_get_val(EGPIO_PIN_AUDIO_SEL); if (i2s_running || app_audio) { if (i2s_running) { eos_i2s_hp_change(hp_det); @@ -125,7 +138,7 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { PINSWITCH(EGPIO_PIN_EVEAUDIO_DIS, EGPIO_PIN_LSGAIN_SEL); } } - if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_HP, hp_det, 0); + if (egpio_intr_handler) egpio_intr_handler(EOS_EGPIO_INT_TYPE_HP, hp_det, 0); } break; } @@ -135,14 +148,18 @@ static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { } static int handle_egpio_evt(uint8_t chip_id) { - uint8_t intr_reg, def_reg; + uint8_t intr_reg, mask_reg; int rv; rv = fxl6408_reg_read(chip_id, FXL6408_REG_INT_STATE, &intr_reg); - if (rv) return rv;; - if (!intr_reg) return 0; + if (rv) return rv; + + intr_reg &= ~egpio_intmask[chip_id]; + if (!intr_reg) return EOS_OK; if (intr_reg & egpio_switch[chip_id]) { + uint8_t def_reg; + rv = fxl6408_reg_read(chip_id, FXL6408_REG_I_DEFAULT, &def_reg); if (rv) return rv; @@ -157,47 +174,47 @@ static int handle_egpio_evt(uint8_t chip_id) { rv = handle_egpio_intr(chip_id, intr_reg); if (rv) return rv; - return 1; + return EOS_OK; } static void handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + int rv; + type &= ~EOS_EVT_MASK; switch (type) { - case EGPIO_ETYPE_INT: { - int rv; - - rv = handle_egpio_evt(0); - if (rv < 0) goto handle_evt_fin; + case EOS_EGPIO_ETYPE_INT: { + rv = handle_egpio_evt(EGPIO_CHIP_FXL0); + if (rv) goto handle_evt_fin; if (GPIO_REG(GPIO_INPUT_VAL) & (1 << EGPIO_PIN_INT)) goto handle_evt_fin; - rv = handle_egpio_evt(1); - if (rv < 0) goto handle_evt_fin; + rv = handle_egpio_evt(EGPIO_CHIP_FXL1); + if (rv) goto handle_evt_fin; if (GPIO_REG(GPIO_INPUT_VAL) & (1 << EGPIO_PIN_INT)) goto handle_evt_fin; if (egpio_ext_handler) rv = egpio_ext_handler(); handle_evt_fin: - clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_LOW_IP) = (1 << EGPIO_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); set_csr(mstatus, MSTATUS_MIE); + if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO HANDLE INTR ERR:%d\n", rv); break; } - case EGPIO_ETYPE_INT_CTP: - case EGPIO_ETYPE_INT_EVE: { + case EOS_EGPIO_ETYPE_INT_CTP: { if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { - eos_ctp_handle_intr(); + rv = eos_ctp_handle_intr(); } else { - eos_eve_handle_intr(); + rv = eos_eve_handle_intr(); } -handle_evt_eve_fin: + GPIO_REG(GPIO_LOW_IP) = (1 << CTP_PIN_INT); clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INT); - GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) |= (1 << CTP_PIN_INT); set_csr(mstatus, MSTATUS_MIE); + if (rv < 0) EOS_LOG(EOS_LOG_ERR, "CTP/EVE HANDLE INTR ERR:%d\n", rv); break; } } @@ -205,16 +222,12 @@ handle_evt_eve_fin: static void handle_intr(void) { GPIO_REG(GPIO_LOW_IE) &= ~(1 << EGPIO_PIN_INT); - eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT, NULL, 0); + eos_evtq_push_isr(EOS_EVT_EGPIO | EOS_EGPIO_ETYPE_INT, NULL, 0); } -static void handle_intr_eve(void) { - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); - if (egpio_pinval[EGPIO_CHIP_FXL0] & EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL)) { - eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT_CTP, NULL, 0); - } else { - eos_evtq_push_isr(EOS_EVT_EGPIO | EGPIO_ETYPE_INT_EVE, NULL, 0); - } +static void handle_intr_ctp(void) { + GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT); + eos_evtq_push_isr(EOS_EVT_EGPIO | EOS_EGPIO_ETYPE_INT_CTP, NULL, 0); } int eos_egpio_init(void) { @@ -224,83 +237,98 @@ int eos_egpio_init(void) { wakeup_cause = eos_pwr_wakeup_cause(); rst = (wakeup_cause == EOS_PWR_WAKE_RST); if (rst) { - rv = fxl6408_reg_read(0, FXL6408_REG_ID_CTRL, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_ID_CTRL, &data); + if (rv) return rv; + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_ID_CTRL, &data); if (rv) return rv; - rv = fxl6408_reg_read(1, FXL6408_REG_ID_CTRL, &data); + + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, 0xff); + if (rv) return rv; + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL1, 0xff); if (rv) return rv; - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, 0xff); + /* clear interrupts */ + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_INT_STATE, &data); if (rv) return rv; - rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, 0xff); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_INT_STATE, &data); if (rv) return rv; /* 1st chip */ data = EGPIO_BIT_CTP_SEL | EGPIO_BIT_EXP_IO0 | EGPIO_BIT_EXP_IO1; - rv = fxl6408_reg_write(0, FXL6408_REG_IO_DIR, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_IO_DIR, data); if (rv) return rv; data = EGPIO_BIT_CTP_SEL; - rv = fxl6408_reg_write(0, FXL6408_REG_O_STATE, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_O_STATE, data); if (rv) return rv; data = EGPIO_BIT_EXP_IO0 | EGPIO_BIT_EXP_IO1; - rv = fxl6408_reg_write(0, FXL6408_REG_O_HIZ, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_O_HIZ, data); if (rv) return rv; - data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; - rv = fxl6408_reg_write(0, FXL6408_REG_PULL_ENA, data); + data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_PULL_ENA, data); if (rv) return rv; - data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; - rv = fxl6408_reg_write(0, FXL6408_REG_PULL_DIR, data); + data = EGPIO_BIT_EVE_INT | EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_PULL_DIR, data); if (rv) return rv; /* 2nd chip */ data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL | EGPIO_BIT_USR0 | EGPIO_BIT_USR1 | EGPIO_BIT_USR2 | EGPIO_BIT_USR3; - rv = fxl6408_reg_write(1, FXL6408_REG_IO_DIR, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_IO_DIR, data); if (rv) return rv; data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL; - rv = fxl6408_reg_write(1, FXL6408_REG_O_STATE, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_O_STATE, data); if (rv) return rv; data = EGPIO_BIT_USR0 | EGPIO_BIT_USR1 | EGPIO_BIT_USR2 | EGPIO_BIT_USR3; - rv = fxl6408_reg_write(1, FXL6408_REG_O_HIZ, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_O_HIZ, data); if (rv) return rv; data = 0; - rv = fxl6408_reg_write(1, FXL6408_REG_PULL_ENA, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_PULL_ENA, data); if (rv) return rv; data = 0; - rv = fxl6408_reg_write(1, FXL6408_REG_PULL_DIR, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_PULL_DIR, data); + if (rv) return rv; + } else { + /* read interrupt mask */ + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_INT_MASK, &data); + if (rv) return rv; + egpio_intmask[EGPIO_CHIP_FXL0] = data; + + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_INT_MASK, &data); if (rv) return rv; + egpio_intmask[EGPIO_CHIP_FXL1] = data; } - rv = fxl6408_reg_read(0, FXL6408_REG_I_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_I_STATE, &data); if (rv) return rv; - data &= egpio_switch[0]; + data &= egpio_switch[EGPIO_CHIP_FXL0]; egpio_pinval[EGPIO_CHIP_FXL0] = data; data |= EGPIO_BIT_EVE_INT | EGPIO_BIT_BAT_INT | EGPIO_BIT_CTP_INT; - rv = fxl6408_reg_write(0, FXL6408_REG_I_DEFAULT, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL0, FXL6408_REG_I_DEFAULT, data); if (rv) return rv; - rv = fxl6408_reg_read(0, FXL6408_REG_IO_DIR, &data_dir); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_IO_DIR, &data_dir); if (rv) return rv; - rv = fxl6408_reg_read(0, FXL6408_REG_O_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL0, FXL6408_REG_O_STATE, &data); if (rv) return rv; egpio_pinval[EGPIO_CHIP_FXL0] |= (data & data_dir); - rv = fxl6408_reg_read(1, FXL6408_REG_I_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_I_STATE, &data); if (rv) return rv; - data &= egpio_switch[1]; + data &= egpio_switch[EGPIO_CHIP_FXL1]; egpio_pinval[EGPIO_CHIP_FXL1] = data; - rv = fxl6408_reg_write(1, FXL6408_REG_I_DEFAULT, data); + rv = fxl6408_reg_write(EGPIO_CHIP_FXL1, FXL6408_REG_I_DEFAULT, data); if (rv) return rv; - rv = fxl6408_reg_read(1, FXL6408_REG_IO_DIR, &data_dir); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_IO_DIR, &data_dir); if (rv) return rv; - rv = fxl6408_reg_read(1, FXL6408_REG_O_STATE, &data); + rv = fxl6408_reg_read(EGPIO_CHIP_FXL1, FXL6408_REG_O_STATE, &data); if (rv) return rv; egpio_pinval[EGPIO_CHIP_FXL1] |= (data & data_dir); @@ -313,31 +341,31 @@ int eos_egpio_run(void) { eos_evtq_set_handler(EOS_EVT_EGPIO, handle_evt); - GPIO_REG(GPIO_INPUT_EN) |= (1 << EGPIO_PIN_INT); - clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); - set_csr(mstatus, MSTATUS_MIE); - eos_intr_set(INT_GPIO_BASE + EGPIO_PIN_INT, IRQ_PRIORITY_EGPIO, handle_intr); - - /* EVE_PIN_INT will be set in intr_set() below */ - eos_intr_set(INT_GPIO_BASE + EVE_PIN_INT, IRQ_PRIORITY_EVE, handle_intr_eve); - wakeup_cause = eos_pwr_wakeup_cause(); rst = (wakeup_cause == EOS_PWR_WAKE_RST); if (rst) { - /* turn on interrupts when all is configured */ - data = ~(EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT); - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + /* enable interrupts when all is configured */ + data = ~(EGPIO_BIT_SDCARD_NDET | EGPIO_BIT_BTN_WAKE | EGPIO_BIT_BAT_INT); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, data); if (rv) return rv; data = ~(EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET); - rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL1, data); if (rv) return rv; } rv = eos_egpio_intr_set(); if (rv) return rv; + /* CTP_PIN_INT is configured in intr_set() above */ + eos_intr_set(INT_GPIO_BASE + CTP_PIN_INT, IRQ_PRIORITY_CTP, handle_intr_ctp); + + GPIO_REG(GPIO_INPUT_EN) |= (1 << EGPIO_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); + set_csr(mstatus, MSTATUS_MIE); + eos_intr_set(INT_GPIO_BASE + EGPIO_PIN_INT, IRQ_PRIORITY_EGPIO, handle_intr); + return EOS_OK; } @@ -346,33 +374,32 @@ void eos_egpio_eve_set(uint16_t gpio_reg) { if (gpio_reg & (1 << EVE_GPIO_DISP)) egpio_pinval[EGPIO_CHIP_EVE] |= EGPIO_PIN2BIT(EGPIO_PIN_DISP_SEL); } -int _eos_egpio_intr_set(int i2s_running, int app_disp) { - uint8_t data; +static int egpio_intr_set(int i2s_running, int app_disp) { + uint8_t mask; int rv; - rv = fxl6408_reg_read(0, FXL6408_REG_INT_MASK, &data); - if (rv) return rv; + mask = egpio_intmask[EGPIO_CHIP_FXL0]; + mask |= EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT; - data &= ~(EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); - if (app_disp) { - data |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); - } else if (!i2s_running) { - if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { - data |= EGPIO_BIT_CTP_INT; + if (!app_disp) { + if (i2s_running) { + mask &= ~(EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); + } else if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { + mask &= ~EGPIO_BIT_EVE_INT; } else { - data |= EGPIO_BIT_EVE_INT; + mask &= ~EGPIO_BIT_CTP_INT; } } - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, mask); if (rv) return rv; - GPIO_REG(GPIO_INPUT_EN) |= (1 << EVE_PIN_INT); + GPIO_REG(GPIO_INPUT_EN) |= (1 << CTP_PIN_INT); clear_csr(mstatus, MSTATUS_MIE); if (app_disp || i2s_running) { - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT); } else { - GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) |= (1 << CTP_PIN_INT); } set_csr(mstatus, MSTATUS_MIE); @@ -380,25 +407,23 @@ int _eos_egpio_intr_set(int i2s_running, int app_disp) { } int eos_egpio_intr_set(void) { - return _eos_egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); + return egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); } int eos_egpio_intr_disable(void) { - uint8_t data; + uint8_t mask; int rv; - rv = fxl6408_reg_read(0, FXL6408_REG_INT_MASK, &data); - if (rv) return rv; - - data |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); + mask = egpio_intmask[EGPIO_CHIP_FXL0]; + mask |= (EGPIO_BIT_EVE_INT | EGPIO_BIT_CTP_INT); - rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + rv = egpio_fxl_set_mask(EGPIO_CHIP_FXL0, mask); if (rv) return rv; clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) &= ~(1 << CTP_PIN_INT); set_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << EVE_PIN_INT); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << CTP_PIN_INT); return EOS_OK; } @@ -435,7 +460,17 @@ int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val) { return EOS_OK; } -int _eos_egpio_get_val(uint8_t pin) { +static int egpio_fxl_set_mask(uint8_t chip_id, uint8_t mask) { + int rv; + + rv = fxl6408_reg_write(chip_id, FXL6408_REG_INT_MASK, mask); + if (rv) return rv; + + egpio_intmask[chip_id] = mask; + return EOS_OK; +} + +static int egpio_get_val(uint8_t pin) { uint8_t chip_id; chip_id = EGPIO_PIN2CHIP(pin); @@ -443,7 +478,7 @@ int _eos_egpio_get_val(uint8_t pin) { return !!(egpio_pinval[chip_id] & EGPIO_PIN2BIT(pin)); } -int _eos_egpio_set_val(uint8_t pin, int val) { +static int egpio_set_val(uint8_t pin, int val) { uint8_t chip_id; int rv; @@ -485,7 +520,7 @@ int eos_egpio_get_val(uint8_t pin) { case EGPIO_PIN_EVEAUDIO_DIS: case EGPIO_PIN_LSGAIN_SEL: { - int lspk_on = (eos_i2s_running() || !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); + int lspk_on = (eos_i2s_running() || !egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) { return !!(egpio_alt_pin & pin2alt_bit(pin)); @@ -498,7 +533,7 @@ int eos_egpio_get_val(uint8_t pin) { } } - return _eos_egpio_get_val(pin); + return egpio_get_val(pin); } int eos_egpio_set_val(uint8_t pin, int val) { @@ -520,7 +555,7 @@ int eos_egpio_set_val(uint8_t pin, int val) { return EOS_OK; } - if ((val != _eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { + if ((val != egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { if (val) { /* store LSGAIN_SEL pin and set EVEAUDIO_DIS pin */ PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS); @@ -534,7 +569,7 @@ int eos_egpio_set_val(uint8_t pin, int val) { case EGPIO_PIN_EVEAUDIO_DIS: case EGPIO_PIN_LSGAIN_SEL: { - int lspk_on = (eos_i2s_running() || !_eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); + int lspk_on = (eos_i2s_running() || !egpio_get_val(EGPIO_PIN_AUDIO_SEL)) && eos_egpio_get_val(EGPIO_PIN_HP_NDET); if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) { BITSET(egpio_alt_pin, pin2alt_bit(pin), val); @@ -549,7 +584,7 @@ int eos_egpio_set_val(uint8_t pin, int val) { } } - rv = _eos_egpio_set_val(pin, val); + rv = egpio_set_val(pin, val); if (rv) return rv; return EOS_OK; @@ -559,13 +594,13 @@ int eos_egpio_i2s_start(void) { uint8_t data; int rv, audio_sel; - rv = _eos_egpio_intr_set(1, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); + rv = egpio_intr_set(1, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); if (rv) return rv; - audio_sel = _eos_egpio_get_val(EGPIO_PIN_AUDIO_SEL); + audio_sel = egpio_get_val(EGPIO_PIN_AUDIO_SEL); BITSET(egpio_alt_pin, pin2alt_bit(EGPIO_PIN_AUDIO_SEL), audio_sel); - rv = _eos_egpio_set_val(EGPIO_PIN_AUDIO_SEL, 1); + rv = egpio_set_val(EGPIO_PIN_AUDIO_SEL, 1); if (rv) return rv; if (!audio_sel && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { @@ -579,7 +614,7 @@ int eos_egpio_i2s_start(void) { int eos_egpio_i2s_stop(void) { int rv, audio_sel; - rv = _eos_egpio_intr_set(0, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); + rv = egpio_intr_set(0, !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); if (rv) return rv; audio_sel = (egpio_alt_pin & pin2alt_bit(EGPIO_PIN_AUDIO_SEL)); @@ -588,7 +623,7 @@ int eos_egpio_i2s_stop(void) { PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS); } - rv = _eos_egpio_set_val(EGPIO_PIN_AUDIO_SEL, audio_sel); + rv = egpio_set_val(EGPIO_PIN_AUDIO_SEL, audio_sel); if (rv) return rv; return EOS_OK; diff --git a/fw/fe310/eos/dev/egpio.h b/fw/fe310/eos/dev/egpio.h index 7d20443..a916ed5 100644 --- a/fw/fe310/eos/dev/egpio.h +++ b/fw/fe310/eos/dev/egpio.h @@ -1,93 +1,13 @@ #include <stdint.h> -#define EGPIO_ETYPE_INT 1 -#define EGPIO_ETYPE_INT_CTP 2 -#define EGPIO_ETYPE_INT_EVE 3 +#define EOS_EGPIO_ETYPE_INT 1 +#define EOS_EGPIO_ETYPE_INT_CTP 2 /* EGPIO_PIN_CTP_SEL is on: CTP int; EGPIO_PIN_CTP_SEL is off: EVE int */ -#define EGPIO_INT_TYPE_BAT 1 -#define EGPIO_INT_TYPE_WAKE 2 -#define EGPIO_INT_TYPE_SDCARD 3 -#define EGPIO_INT_TYPE_MUTE 4 -#define EGPIO_INT_TYPE_HP 5 - -#define EGPIO_CHIP_FXL0 0x00 -#define EGPIO_CHIP_FXL1 0x01 -#define EGPIO_CHIP_EVE 0x02 - -#define EGPIO_MAX_CHIP 3 - -#define EGPIO_PIN_MASK 0x07 -#define EGPIO_PIN_MASK_CHIP 0x30 - -#define EGPIO_PIN2BIT(X) (1 << ((X) & EGPIO_PIN_MASK)) -#define EGPIO_PIN2CHIP(X) (((X) & EGPIO_PIN_MASK_CHIP) >> 4) -#define EGPIO_PIN(C,P) (((C) << 4) | (P)) - -#define EGPIO0_PIN_EVE_INT 0x00 /* EVE interrrupt */ -#define EGPIO0_PIN_SDCARD_DET 0x01 /* SD Card detect */ -#define EGPIO0_PIN_EXP_IO0 0x02 /* expansion io 0 */ -#define EGPIO0_PIN_EXP_IO1 0x03 /* expansion io 1 */ -#define EGPIO0_PIN_BTN_WAKE 0x04 /* wake button */ -#define EGPIO0_PIN_BAT_INT 0x05 /* battery charger IC inetrrupt */ -#define EGPIO0_PIN_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:X and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */ -#define EGPIO0_PIN_CTP_INT 0x07 /* CTP interrupt */ - -#define EGPIO1_PIN_MIC_MUTE 0x00 /* microphone disable */ -#define EGPIO1_PIN_HPAMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */ -#define EGPIO1_PIN_AUDIO_SEL 0x02 /* switch audio connection: 0 - connected to app module, 1 - connected to fe310 chip (only when i2s is off) */ -#define EGPIO1_PIN_HP_NDET 0x03 /* headphone detect: 0 - inserted, 1 - not inserted */ -#define EGPIO1_PIN_USR0 0x04 /* user IO */ -#define EGPIO1_PIN_USR1 0x05 -#define EGPIO1_PIN_USR2 0x06 -#define EGPIO1_PIN_USR3 0x07 - -#define EGPIOE_PIN_DISP 0x07 /* EVE DISP GPIO */ - -#define EGPIO_PIN_ALT 0x08 - -#define EGPIO_PIN_EVE_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EVE_INT) -#define EGPIO_PIN_SDCARD_DET EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_SDCARD_DET) -#define EGPIO_PIN_EXP_IO0 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO0) -#define EGPIO_PIN_EXP_IO1 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO1) -#define EGPIO_PIN_BTN_WAKE EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BTN_WAKE) -#define EGPIO_PIN_BAT_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BAT_INT) -#define EGPIO_PIN_CTP_SEL EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_SEL) -#define EGPIO_PIN_CTP_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_INT) - -#define EGPIO_PIN_MIC_MUTE EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_MIC_MUTE) -#define EGPIO_PIN_HPAMP_CS EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HPAMP_CS) -#define EGPIO_PIN_AUDIO_SEL EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_AUDIO_SEL) -#define EGPIO_PIN_HP_NDET EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HP_NDET) -#define EGPIO_PIN_USR0 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR0) -#define EGPIO_PIN_USR1 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR1) -#define EGPIO_PIN_USR2 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR2) -#define EGPIO_PIN_USR3 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR3) - -/* EVE pins defined in eve.h */ -#define EGPIO_PIN_USR4 EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_USR) -#define EGPIO_PIN_EVEAUDIO_DIS EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_EVEAUDIO_DIS) -#define EGPIO_PIN_LSGAIN_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LSGAIN_SEL | EGPIO_PIN_ALT) -#define EGPIO_PIN_LCD_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LCD_EN) -#define EGPIO_PIN_CAM_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_CAM_EN) -#define EGPIO_PIN_DISP_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EGPIOE_PIN_DISP) - -#define EGPIO_BIT_EVE_INT EGPIO_PIN2BIT(EGPIO0_PIN_EVE_INT) -#define EGPIO_BIT_SDCARD_DET EGPIO_PIN2BIT(EGPIO0_PIN_SDCARD_DET) -#define EGPIO_BIT_EXP_IO0 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO0) -#define EGPIO_BIT_EXP_IO1 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO1) -#define EGPIO_BIT_BTN_WAKE EGPIO_PIN2BIT(EGPIO0_PIN_BTN_WAKE) -#define EGPIO_BIT_BAT_INT EGPIO_PIN2BIT(EGPIO0_PIN_BAT_INT) -#define EGPIO_BIT_CTP_SEL EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL) -#define EGPIO_BIT_CTP_INT EGPIO_PIN2BIT(EGPIO0_PIN_CTP_INT) - -#define EGPIO_BIT_MIC_MUTE EGPIO_PIN2BIT(EGPIO1_PIN_MIC_MUTE) -#define EGPIO_BIT_HPAMP_CS EGPIO_PIN2BIT(EGPIO1_PIN_HPAMP_CS) -#define EGPIO_BIT_AUDIO_SEL EGPIO_PIN2BIT(EGPIO1_PIN_AUDIO_SEL) -#define EGPIO_BIT_HP_NDET EGPIO_PIN2BIT(EGPIO1_PIN_HP_NDET) -#define EGPIO_BIT_USR0 EGPIO_PIN2BIT(EGPIO1_PIN_USR0) -#define EGPIO_BIT_USR1 EGPIO_PIN2BIT(EGPIO1_PIN_USR1) -#define EGPIO_BIT_USR2 EGPIO_PIN2BIT(EGPIO1_PIN_USR2) -#define EGPIO_BIT_USR3 EGPIO_PIN2BIT(EGPIO1_PIN_USR3) +#define EOS_EGPIO_INT_TYPE_BAT 1 +#define EOS_EGPIO_INT_TYPE_WAKE 2 +#define EOS_EGPIO_INT_TYPE_SDCARD 3 +#define EOS_EGPIO_INT_TYPE_MUTE 4 +#define EOS_EGPIO_INT_TYPE_HP 5 typedef void (*eos_egpio_intr_handler_t) (uint8_t type, int data0, int data1); typedef int (*eos_egpio_ext_handler_t) (void); @@ -95,7 +15,6 @@ typedef int (*eos_egpio_ext_handler_t) (void); int eos_egpio_init(void); int eos_egpio_run(void); void eos_egpio_eve_set(uint16_t gpio_reg); -int _eos_egpio_intr_set(int i2s_running, int app_running); int eos_egpio_intr_set(void); int eos_egpio_intr_enable(void); int eos_egpio_intr_disable(void); @@ -106,8 +25,6 @@ void eos_egpio_set_ext_handler(eos_egpio_ext_handler_t handler); int eos_egpio_fxl_get_pin(uint8_t reg, uint8_t pin, uint8_t *val); int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val); -int _eos_egpio_get_val(uint8_t pin); -int _eos_egpio_set_val(uint8_t pin, int val); int eos_egpio_get_val(uint8_t pin); int eos_egpio_set_val(uint8_t pin, int val); diff --git a/fw/fe310/eos/dev/egpio_priv.h b/fw/fe310/eos/dev/egpio_priv.h new file mode 100644 index 0000000..04fe271 --- /dev/null +++ b/fw/fe310/eos/dev/egpio_priv.h @@ -0,0 +1,81 @@ +#include "eve_priv.h" + +#define EGPIO_CHIP_FXL0 0 +#define EGPIO_CHIP_FXL1 1 +#define EGPIO_CHIP_EVE 2 + +#define EGPIO_MAX_CHIP 3 +#define EGPIO_MAX_FXL_CHIP 2 + +#define EGPIO_PIN_MASK 0x07 +#define EGPIO_PIN_MASK_CHIP 0x30 + +#define EGPIO_PIN2BIT(X) (1 << ((X) & EGPIO_PIN_MASK)) +#define EGPIO_PIN2CHIP(X) (((X) & EGPIO_PIN_MASK_CHIP) >> 4) +#define EGPIO_PIN(C,P) (((C) << 4) | (P)) + +#define EGPIO0_PIN_EVE_INT 0x00 /* EVE interrrupt */ +#define EGPIO0_PIN_SDCARD_NDET 0x01 /* SD Card detect: 0 - inserted, 1 - not inserted */ +#define EGPIO0_PIN_EXP_IO0 0x02 /* expansion io 0 */ +#define EGPIO0_PIN_EXP_IO1 0x03 /* expansion io 1 */ +#define EGPIO0_PIN_BTN_WAKE 0x04 /* wake button */ +#define EGPIO0_PIN_BAT_INT 0x05 /* battery charger IC inetrrupt */ +#define EGPIO0_PIN_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:X and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */ +#define EGPIO0_PIN_CTP_INT 0x07 /* CTP interrupt */ + +#define EGPIO1_PIN_MIC_MUTE 0x00 /* microphone disable */ +#define EGPIO1_PIN_HPAMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */ +#define EGPIO1_PIN_AUDIO_SEL 0x02 /* switch audio connection: 0 - connected to app module, 1 - connected to fe310 chip (only when i2s is off) */ +#define EGPIO1_PIN_HP_NDET 0x03 /* headphone detect: 0 - inserted, 1 - not inserted */ +#define EGPIO1_PIN_USR0 0x04 /* user IO */ +#define EGPIO1_PIN_USR1 0x05 +#define EGPIO1_PIN_USR2 0x06 +#define EGPIO1_PIN_USR3 0x07 + +#define EGPIOE_PIN_DISP 0x07 /* EVE DISP GPIO */ + +#define EGPIO_PIN_ALT 0x08 + +#define EGPIO_BIT_EVE_INT EGPIO_PIN2BIT(EGPIO0_PIN_EVE_INT) +#define EGPIO_BIT_SDCARD_NDET EGPIO_PIN2BIT(EGPIO0_PIN_SDCARD_NDET) +#define EGPIO_BIT_EXP_IO0 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO0) +#define EGPIO_BIT_EXP_IO1 EGPIO_PIN2BIT(EGPIO0_PIN_EXP_IO1) +#define EGPIO_BIT_BTN_WAKE EGPIO_PIN2BIT(EGPIO0_PIN_BTN_WAKE) +#define EGPIO_BIT_BAT_INT EGPIO_PIN2BIT(EGPIO0_PIN_BAT_INT) +#define EGPIO_BIT_CTP_SEL EGPIO_PIN2BIT(EGPIO0_PIN_CTP_SEL) +#define EGPIO_BIT_CTP_INT EGPIO_PIN2BIT(EGPIO0_PIN_CTP_INT) + +#define EGPIO_BIT_MIC_MUTE EGPIO_PIN2BIT(EGPIO1_PIN_MIC_MUTE) +#define EGPIO_BIT_HPAMP_CS EGPIO_PIN2BIT(EGPIO1_PIN_HPAMP_CS) +#define EGPIO_BIT_AUDIO_SEL EGPIO_PIN2BIT(EGPIO1_PIN_AUDIO_SEL) +#define EGPIO_BIT_HP_NDET EGPIO_PIN2BIT(EGPIO1_PIN_HP_NDET) +#define EGPIO_BIT_USR0 EGPIO_PIN2BIT(EGPIO1_PIN_USR0) +#define EGPIO_BIT_USR1 EGPIO_PIN2BIT(EGPIO1_PIN_USR1) +#define EGPIO_BIT_USR2 EGPIO_PIN2BIT(EGPIO1_PIN_USR2) +#define EGPIO_BIT_USR3 EGPIO_PIN2BIT(EGPIO1_PIN_USR3) + +#define EGPIO_PIN_EVE_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EVE_INT) +#define EGPIO_PIN_SDCARD_NDET EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_SDCARD_NDET) +#define EGPIO_PIN_EXP_IO0 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO0) +#define EGPIO_PIN_EXP_IO1 EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_EXP_IO1) +#define EGPIO_PIN_BTN_WAKE EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BTN_WAKE) +#define EGPIO_PIN_BAT_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_BAT_INT) +#define EGPIO_PIN_CTP_SEL EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_SEL) +#define EGPIO_PIN_CTP_INT EGPIO_PIN(EGPIO_CHIP_FXL0, EGPIO0_PIN_CTP_INT) + +#define EGPIO_PIN_MIC_MUTE EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_MIC_MUTE) +#define EGPIO_PIN_HPAMP_CS EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HPAMP_CS) +#define EGPIO_PIN_AUDIO_SEL EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_AUDIO_SEL) +#define EGPIO_PIN_HP_NDET EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_HP_NDET) +#define EGPIO_PIN_USR0 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR0) +#define EGPIO_PIN_USR1 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR1) +#define EGPIO_PIN_USR2 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR2) +#define EGPIO_PIN_USR3 EGPIO_PIN(EGPIO_CHIP_FXL1, EGPIO1_PIN_USR3) + +/* EVE pins defined in eve.h */ +#define EGPIO_PIN_USR4 EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_USR) +#define EGPIO_PIN_EVEAUDIO_DIS EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_EVEAUDIO_DIS) +#define EGPIO_PIN_LSGAIN_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LSGAIN_SEL | EGPIO_PIN_ALT) +#define EGPIO_PIN_LCD_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_LCD_EN) +#define EGPIO_PIN_CAM_EN EGPIO_PIN(EGPIO_CHIP_EVE, EVE_GPIO_CAM_EN) +#define EGPIO_PIN_DISP_SEL EGPIO_PIN(EGPIO_CHIP_EVE, EGPIOE_PIN_DISP) diff --git a/fw/fe310/eos/dev/eve.c b/fw/fe310/eos/dev/eve.c index dad7dfe..25a3558 100644 --- a/fw/fe310/eos/dev/eve.c +++ b/fw/fe310/eos/dev/eve.c @@ -2,6 +2,7 @@ #include <stdint.h> #include "eos.h" +#include "log.h" #include "event.h" #include "soc/pwr.h" @@ -11,15 +12,12 @@ #include "eve/eve_touch_engine.h" #include "egpio.h" +#include "egpio_priv.h" #include "spi.h" #include "aon.h" -#include "pwr.h" #include "eve.h" - -#ifdef EOS_DEBUG -#include <stdio.h> -#endif +#include "eve_priv.h" static void handle_time(unsigned char type) { int rv; @@ -36,13 +34,12 @@ int eos_eve_handle_intr(void) { int rv; rv = eve_select(); - if (rv) return 0; + if (rv) return rv; intr_flags = eve_handle_intr(); eve_deselect(); - if (intr_flags == 0) return 0; - return 1; + return intr_flags; } int eos_eve_init(void) { @@ -64,15 +61,12 @@ int eos_eve_init(void) { eve_touch_init_engine(eos_egpio_get_val(EGPIO_PIN_CTP_SEL) ? EVE_TOUCH_ENGINE_HOST : EVE_TOUCH_ENGINE_GOODIX); gpio_reg = EVE_GPIO_DEFAULT; } else { - uint8_t pwr_state; - - pwr_state = eos_aon_load4eve(); - eve_pwr_set_state(pwr_state); + eve_pwr_set_state(eos_aon_load4eve()); eve_activate(); gpio_reg = eve_gpio_read(); eve_cmd_set_offset(); - if (gpio_reg & EVE_GPIO_DISP) { + if (gpio_reg & (1 << EVE_GPIO_DISP)) { eve_pwr_set_state(EVE_PSTATE_ACTIVE); } eve_deactivate(); @@ -92,9 +86,19 @@ eve_init_fin: } int eos_eve_run(void) { - int rv; + uint8_t wakeup_cause; + int rst, rv; + + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); - if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY; + if (!rst) { + /* was active before sleep */ + if (eos_aon_load4eve() == EVE_PSTATE_ACTIVE) return EOS_OK; + + /* DISP pin is off */ + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY; + } rv = eve_select(); if (rv) return rv; @@ -111,10 +115,12 @@ int eos_eve_run(void) { int eos_eve_sleep(void) { int rv; + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR; + rv = eve_select(); if (rv) return rv; - eos_aon_save4eve(eve_pwr_state()); + eve_brightness(0); eve_clk_stop(); eve_intr_disable(); eve_touch_stop(); @@ -125,16 +131,46 @@ int eos_eve_sleep(void) { return EOS_OK; } +int eos_eve_wake(void) { + int disp, rv; + + if (eve_pwr_state() == EVE_PSTATE_ACTIVE) return EOS_ERR; + + rv = eve_select(); + if (rv) return rv; + + eve_activate(); + disp = eve_gpio_get(EVE_GPIO_DISP); + if (disp) { + eve_pwr_set_state(EVE_PSTATE_ACTIVE); + } + eve_deactivate(); + + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) { + rv = EOS_ERR_BUSY; + goto eve_wake_fin; + } + + eve_touch_intr_enable(); + eve_touch_start(); + eve_intr_enable(); + eve_clk_start(); +eve_wake_fin: + eve_deselect(); + + return rv; +} + +void eos_eve_save2aon(void) { + eos_aon_save4eve(eve_pwr_state()); +} + void eve_calibrate(void) { int rv, d; -#ifdef EOS_DEBUG uint32_t matrix[6]; -#endif if (!eve_selected()) { -#ifdef EOS_DEBUG - printf("EVE CALIBRATE: NOT SELECTED\n"); -#endif + EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE: NOT SELECTED\n"); return; } @@ -155,25 +191,21 @@ void eve_calibrate(void) { eos_evtq_exec(); rv = eve_select(); if (rv) { -#ifdef EOS_DEBUG - printf("EVE CALIBRATE ERR:%d\n", rv); -#endif + EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE ERR:%d\n", rv); return; } } while (!d); eve_touch_set_extended(1); -#ifdef EOS_DEBUG if (rv) { - printf("EVE CALIBRATE ERR:%d\n", rv); + EOS_LOG(EOS_LOG_ERR, "EVE CALIBRATE ERR:%d\n", rv); return; } eve_touch_get_matrix(matrix); - printf("TOUCH MATRIX:\n"); - printf("uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); -#endif + EOS_LOG(EOS_LOG_INFO, "TOUCH MATRIX:\n"); + EOS_LOG(EOS_LOG_INFO, "uint32_t touch_matrix[6] = {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x}\n", matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); } int eve_select(void) { diff --git a/fw/fe310/eos/dev/eve.h b/fw/fe310/eos/dev/eve.h index 441cd5a..564e8c1 100644 --- a/fw/fe310/eos/dev/eve.h +++ b/fw/fe310/eos/dev/eve.h @@ -1,22 +1,12 @@ #include <stdint.h> -#define EVE_GPIO_DIR 0x800f -#define EVE_GPIO_DEFAULT 0x2 /* EVEAUDIO_DIS */ -#define EVE_GPIO_MASK 0x800f - -#define EVE_GPIO_USR 0 -#define EVE_GPIO_EVEAUDIO_DIS 1 /* only when lspk is off */ -#define EVE_GPIO_LSGAIN_SEL 1 /* only when lspk is on */ -#define EVE_GPIO_LCD_EN 2 -#define EVE_GPIO_CAM_EN 3 -#define EVE_GPIO_DISP 15 - int eos_eve_handle_intr(void); int eos_eve_init(void); int eos_eve_run(void); int eos_eve_sleep(void); int eos_eve_wake(void); +void eos_eve_save2aon(void); void eve_calibrate(void); int eve_select(void); diff --git a/fw/fe310/eos/dev/eve_priv.h b/fw/fe310/eos/dev/eve_priv.h new file mode 100644 index 0000000..3863f5d --- /dev/null +++ b/fw/fe310/eos/dev/eve_priv.h @@ -0,0 +1,10 @@ +#define EVE_GPIO_DIR 0x800f +#define EVE_GPIO_DEFAULT 0x8002 /* DISP on, EVEAUDIO_DIS */ +#define EVE_GPIO_MASK 0x800f + +#define EVE_GPIO_USR 0 +#define EVE_GPIO_EVEAUDIO_DIS 1 /* only when lspk is off */ +#define EVE_GPIO_LSGAIN_SEL 1 /* only when lspk is on */ +#define EVE_GPIO_LCD_EN 2 +#define EVE_GPIO_CAM_EN 3 +#define EVE_GPIO_DISP 15 diff --git a/fw/fe310/eos/dev/flash.c b/fw/fe310/eos/dev/flash.c index c8f4c98..15811a2 100644 --- a/fw/fe310/eos/dev/flash.c +++ b/fw/fe310/eos/dev/flash.c @@ -9,6 +9,21 @@ #include "flash.h" +#define FLASH_RDSR 0x05 + +#define FLASH_NORD 0x03 +#define FLASH_FRD 0x0b + +#define FLASH_WREN 0x06 +#define FLASH_SER 0x20 +#define FLASH_PP 0x02 + +#define FLASH_QPIEN 0x35 +#define FLASH_QPIDI 0xF5 + +#define FLASH_WIP 0x01 +#define FLASH_WEL 0x02 + #define IDLE_TICKS 10 __attribute__ ((section (".itim.flash"))) @@ -42,7 +57,7 @@ void eos_flash_norm(void) { SPI0_REG(SPI_REG_SCKDIV) = 3; if (SPI0_REG(SPI_REG_FMT) & SPI_FMT_PROTO(SPI_PROTO_Q)) { - send(EOS_FLASH_QPIDI); + send(FLASH_QPIDI); while (!(SPI0_REG(SPI_REG_IP) & SPI_IP_TXWM)); } @@ -59,7 +74,7 @@ void eos_flash_norm(void) { SPI_INSN_CMD_PROTO(SPI_PROTO_S) | SPI_INSN_ADDR_PROTO(SPI_PROTO_S) | SPI_INSN_DATA_PROTO(SPI_PROTO_S) | - SPI_INSN_CMD_CODE(EOS_FLASH_NORD) | + SPI_INSN_CMD_CODE(FLASH_NORD) | SPI_INSN_PAD_CODE(0x00); mtime0 = *mtime; @@ -79,7 +94,7 @@ void eos_flash_fast(void) { SPI0_REG(SPI_REG_SCKDIV) = 2; if (!(SPI0_REG(SPI_REG_FMT) & SPI_FMT_PROTO(SPI_PROTO_Q))) { - send(EOS_FLASH_QPIEN); + send(FLASH_QPIEN); while (!(SPI0_REG(SPI_REG_IP) & SPI_IP_TXWM)); } @@ -96,7 +111,7 @@ void eos_flash_fast(void) { SPI_INSN_CMD_PROTO(SPI_PROTO_Q) | SPI_INSN_ADDR_PROTO(SPI_PROTO_Q) | SPI_INSN_DATA_PROTO(SPI_PROTO_Q) | - SPI_INSN_CMD_CODE(EOS_FLASH_FRD) | + SPI_INSN_CMD_CODE(FLASH_FRD) | SPI_INSN_PAD_CODE(0x00); mtime0 = *mtime; @@ -112,31 +127,31 @@ void eos_flash_wip(void) { do { SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - xfer(EOS_FLASH_RDSR); + xfer(FLASH_RDSR); status = xfer(0); SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - } while (status & EOS_FLASH_WIP); + } while (status & FLASH_WIP); } __attribute__ ((section (".itim.flash"))) void eos_flash_wren(void) { uint8_t status; - xfer(EOS_FLASH_WREN); + xfer(FLASH_WREN); #if 0 do { SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - xfer(EOS_FLASH_RDSR); + xfer(FLASH_RDSR); status = xfer(0); SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; - } while (!(status & EOS_FLASH_WEL)); + } while (!(status & FLASH_WEL)); #endif } __attribute__ ((section (".itim.flash"))) void eos_flash_ser(uint32_t addr) { SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - xfer(EOS_FLASH_SER); + xfer(FLASH_SER); xfer(addr >> 16); xfer(addr >> 8); xfer(addr); @@ -149,7 +164,7 @@ void eos_flash_pp(uint32_t addr, uint8_t *buf) { SPI0_REG(SPI_REG_FMT) |= SPI_FMT_DIR(SPI_DIR_TX); SPI0_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - send(EOS_FLASH_PP); + send(FLASH_PP); send(addr >> 16); send(addr >> 8); send(addr); diff --git a/fw/fe310/eos/dev/flash.h b/fw/fe310/eos/dev/flash.h index 6f792cb..714e9bc 100644 --- a/fw/fe310/eos/dev/flash.h +++ b/fw/fe310/eos/dev/flash.h @@ -1,20 +1,5 @@ #include <stdint.h> -#define EOS_FLASH_RDSR 0x05 - -#define EOS_FLASH_NORD 0x03 -#define EOS_FLASH_FRD 0x0b - -#define EOS_FLASH_WREN 0x06 -#define EOS_FLASH_SER 0x20 -#define EOS_FLASH_PP 0x02 - -#define EOS_FLASH_QPIEN 0x35 -#define EOS_FLASH_QPIDI 0xF5 - -#define EOS_FLASH_WIP 0x01 -#define EOS_FLASH_WEL 0x02 - void eos_flash_init(void); void eos_flash_norm(void); void eos_flash_fast(void); diff --git a/fw/fe310/eos/dev/lcd.c b/fw/fe310/eos/dev/lcd.c index 6c005b9..01d86e9 100644 --- a/fw/fe310/eos/dev/lcd.c +++ b/fw/fe310/eos/dev/lcd.c @@ -13,9 +13,8 @@ #include "eve/eve.h" #include "egpio.h" +#include "egpio_priv.h" #include "spi.h" -#include "eve.h" -#include "pwr.h" #include "drv/ili9806e.h" #include "lcd.h" @@ -38,6 +37,10 @@ static int lcd_disable(void) { return rv; } +static int lcd_enabled(void) { + return eos_egpio_get_val(EGPIO_PIN_LCD_EN); +} + static int lcd_select(void) { int rv; @@ -52,6 +55,7 @@ static int lcd_select(void) { GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << SPI_CSPIN_LCD); + return rv; } @@ -60,6 +64,7 @@ static int lcd_select(void) { static void lcd_deselect(void) { eos_spi_deselect(); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << SPI_CSPIN_LCD); @@ -118,6 +123,8 @@ int eos_lcd_init(void) { int eos_lcd_sleep(void) { int rv; + if (!lcd_enabled()) return EOS_ERR; + rv = lcd_sleep(); return rv; } @@ -125,6 +132,8 @@ int eos_lcd_sleep(void) { int eos_lcd_wake(void) { int rv; + if (lcd_enabled()) return EOS_ERR; + rv = lcd_init(); return rv; } diff --git a/fw/fe310/eos/dev/net.c b/fw/fe310/eos/dev/net.c index c8b90f3..c1fd9b5 100644 --- a/fw/fe310/eos/dev/net.c +++ b/fw/fe310/eos/dev/net.c @@ -6,6 +6,7 @@ #include "board.h" #include "eos.h" +#include "log.h" #include "msgq.h" #include "event.h" @@ -16,17 +17,27 @@ #include "soc/spi_priv.h" #include "spi.h" +#include "aon.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 NET_DETECT_TIMEOUT 1000 + +#define NET_SIZE_HDR 3 +#define NET_STATE_FLAG_RUN 0x0001 +#define NET_STATE_FLAG_INIT 0x0002 +#define NET_STATE_FLAG_XCHG 0x0004 +#define NET_STATE_FLAG_ONEW 0x0010 +#define NET_STATE_FLAG_SYNC 0x0020 +#define NET_STATE_FLAG_RTS 0x0040 +#define NET_STATE_FLAG_CTS 0x0080 +#define NET_STATE_FLAG_SLEEP 0x0100 +#define NET_STATE_FLAG_SLEEP_REQ 0x0200 +#define NET_STATE_FLAG_ABSENT 0x0400 + +#define NET_FLAG_MORE 0x01 +#define NET_FLAG_SYNC 0x02 +#define NET_FLAG_REPL 0x04 #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) @@ -38,7 +49,7 @@ static unsigned char net_bufq_buffer[EOS_NET_SIZE_BUFQ][EOS_NET_SIZE_BUF] __attr static EOSMsgQ net_send_q; static EOSMsgItem net_sndq_array[EOS_NET_SIZE_BUFQ]; -static volatile uint8_t net_state_flags = 0; +static volatile uint16_t net_state_flags = 0; static volatile unsigned char net_state_type = 0; static uint32_t net_state_len_tx = 0; static volatile uint32_t net_state_len_rx = 0; @@ -48,40 +59,35 @@ static volatile uint8_t net_state_next_cnt = 0; static unsigned char * volatile 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 uint16_t net_wrapper_acq; +static uint16_t net_flags_acq[EOS_EVT_MAX]; -static int net_xchg_sleep(void) { - int i; - int rv = EOS_OK; +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) = 0xFF; + SPI1_REG(SPI_REG_TXFIFO) = 0; 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; +static void net_xchg_sleep_req(void) { volatile uint32_t x = 0; + int i; + net_state_flags &= ~NET_STATE_FLAG_CTS; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; - for (i=0; i<8; i++) { + SPI1_REG(SPI_REG_TXFIFO) = EOS_NET_MTYPE_SLEEP | EOS_NET_MTYPE_FLAG_ONEW; + while ((x = SPI1_REG(SPI_REG_RXFIFO)) & SPI_RXFIFO_EMPTY); + + /* minimum 8 bytes for esp32 */ + 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); @@ -90,18 +96,6 @@ static void net_xchg_wake(void) { 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); @@ -126,7 +120,7 @@ static int net_xchg_next(unsigned char *_buffer) { unsigned char type; unsigned char *buffer = NULL; uint16_t len; - int ret = _buffer ? 1 : 0; + int do_release = _buffer ? 1 : 0; eos_msgq_pop(&net_send_q, &type, &buffer, &len); if (type) { @@ -134,14 +128,14 @@ static int net_xchg_next(unsigned char *_buffer) { } else if (net_state_flags & NET_STATE_FLAG_RTS) { if (_buffer) { buffer = _buffer; - ret = 0; + do_release = 0; } else { buffer = eos_bufq_pop(&net_buf_q); } if (buffer) net_xchg_start(0, buffer, 0); } - return ret; + return do_release; } static void net_handle_xchg(void) { @@ -161,7 +155,7 @@ static void net_handle_xchg(void) { r3 = 0; } - net_state_type = (r1 & 0xFF); + net_state_type = (r1 & EOS_NET_MTYPE_MASK); net_state_len_rx = (r2 & 0xFF) << 8; net_state_len_rx |= (r3 & 0xFF); len = MAX(net_state_len_tx, net_state_len_rx); @@ -190,8 +184,18 @@ static void net_handle_xchg(void) { 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 & ~EOS_NET_MTYPE_FLAG_MASK), net_state_buf, net_state_len_rx); - if (r) eos_bufq_push(&net_buf_q, net_state_buf); + if (net_state_type == EOS_NET_MTYPE_SLEEP) { + net_state_flags |= NET_STATE_FLAG_SLEEP; + eos_bufq_push(&net_buf_q, net_state_buf); + } else { + int rv; + + rv = eos_evtq_push_isr(EOS_EVT_NET | (net_state_type & ~EOS_EVT_MASK), net_state_buf, net_state_len_rx); + if (rv) { + EOS_LOG(EOS_LOG_ERR, "NET XCHG EVTQ PUSH ERR:%d\n", rv); + 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 { @@ -203,8 +207,9 @@ static void net_handle_xchg(void) { } static void net_handle_cts(void) { - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); + GPIO_REG(GPIO_FALL_IP) = (1 << NET_PIN_CTS); net_state_flags |= NET_STATE_FLAG_CTS; + net_state_flags &= ~NET_STATE_FLAG_SLEEP; if (net_state_flags & NET_STATE_FLAG_RUN) { net_xchg_next(NULL); @@ -214,23 +219,24 @@ static void net_handle_cts(void) { 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; + if (GPIO_REG(GPIO_FALL_IP) & rts_offset) { + GPIO_REG(GPIO_FALL_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; + } + if (GPIO_REG(GPIO_RISE_IP) & rts_offset) { + GPIO_REG(GPIO_RISE_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; + unsigned char idx = (type & ~EOS_EVT_MASK); - if (idx < EOS_NET_MAX_MTYPE) { - net_handler[idx](type, buffer, len); + if (idx && (idx <= EOS_NET_MAX_MTYPE)) { + net_handler[idx - 1](type, buffer, len); } else { eos_net_bad_handler(type, buffer, len); } @@ -262,29 +268,35 @@ static int net_acquire(unsigned char reserved) { return ret; } -static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char idx, uint16_t flag) { - int ok; +static void evt_handler_wrapper(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t idx) { + uint16_t flag = (uint16_t)1 << idx; + int rv; - ok = net_acquire(net_wrapper_acq[idx] & flag); - if (ok) { + rv = net_acquire(net_wrapper_acq & flag); + if (rv) { eos_evtq_get_handler(type)(type, buffer, len); eos_net_release(); - net_wrapper_acq[idx] &= ~flag; + net_wrapper_acq &= ~flag; } else { - net_wrapper_acq[idx] |= flag; - eos_evtq_push(type, buffer, len); + rv = eos_evtq_push_widx(type, buffer, len, &idx); + if (rv) { + EOS_LOG(EOS_LOG_ERR, "NET WRAPPER EVTQ PUSH ERR:%d\n", rv); + return; + } + flag = (uint16_t)1 << idx; + net_wrapper_acq |= flag; } } -static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) { +static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t _idx) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx && (idx <= EOS_EVT_MAX_EVT)) { + if (idx && (idx <= EOS_EVT_MAX)) { 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); + evt_handler_wrapper(type, buffer, len, _idx); } else { eos_evtq_get_handler(type)(type, buffer, len); } @@ -293,6 +305,14 @@ static void evt_handler(unsigned char type, unsigned char *buffer, uint16_t len) } } +static void net_flushq(void) { + while (eos_msgq_len(&net_send_q)) { + asm volatile ("wfi"); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); + } +} + static void net_wait4xchg(void) { while (net_state_flags & NET_STATE_FLAG_XCHG) { asm volatile ("wfi"); @@ -309,12 +329,47 @@ static void net_wait4cts(void) { } } +static void net_wake(void) { + while (net_state_flags & NET_STATE_FLAG_SLEEP) { + net_xchg_reset(); + eos_sleep(10); + set_csr(mstatus, MSTATUS_MIE); + clear_csr(mstatus, MSTATUS_MIE); + } +} + +static int net_select(int *dsel) { + *dsel = 0; + if (net_state_flags & NET_STATE_FLAG_ABSENT) return EOS_ERR_NOTFOUND; + if (net_state_flags & NET_STATE_FLAG_SLEEP_REQ) return EOS_ERR_BUSY; + + if (!(net_state_flags & NET_STATE_FLAG_RUN)) { + int rv; + + set_csr(mstatus, MSTATUS_MIE); + rv = eos_spi_select(EOS_SPI_DEV_NET); + clear_csr(mstatus, MSTATUS_MIE); + if (rv) return rv; + *dsel = 1; + } + /* wake up remote if sleeping */ + net_wake(); + + return EOS_OK; +} + +static void net_deselect(void) { + eos_spi_deselect(); +} + static void net_pause(void) { net_state_flags &= ~NET_STATE_FLAG_RUN; net_wait4xchg(); } static void net_resume(void) { + if (net_state_flags & NET_STATE_FLAG_ABSENT) return; + net_state_flags |= NET_STATE_FLAG_RUN; if (net_state_flags & NET_STATE_FLAG_CTS) { net_xchg_next(NULL); @@ -342,50 +397,69 @@ int eos_net_init(void) { for (i=0; i<EOS_NET_MAX_MTYPE; i++) { net_handler[i] = eos_net_bad_handler; } - eos_evtq_set_handler(0, evt_handler); + eos_evtq_set_handler_global(evt_handler); eos_evtq_set_handler(EOS_EVT_NET, net_handle_evt); + GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_CTS); GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_CTS); - GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_CTS); + GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_CTS); eos_intr_set(INT_GPIO_BASE + NET_PIN_CTS, IRQ_PRIORITY_NET_CTS, net_handle_cts); + /* XXX: pull-up not needed for new board */ + GPIO_REG(GPIO_PULLUP_EN) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_INPUT_EN) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_RISE_IE) |= (1 << NET_PIN_RTS); GPIO_REG(GPIO_FALL_IE) |= (1 << NET_PIN_RTS); eos_intr_set(INT_GPIO_BASE + NET_PIN_RTS, IRQ_PRIORITY_NET_RTS, net_handle_rts); - /* set initial state */ - clear_csr(mstatus, MSTATUS_MIE); - if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) net_state_flags |= NET_STATE_FLAG_CTS; - if (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS)) net_state_flags |= NET_STATE_FLAG_RTS; - set_csr(mstatus, MSTATUS_MIE); - return EOS_OK; } int eos_net_run(void) { uint8_t wakeup_cause; + int rv; + rv = EOS_OK; net_start(); wakeup_cause = eos_pwr_wakeup_cause(); + clear_csr(mstatus, MSTATUS_MIE); - if (wakeup_cause != EOS_PWR_WAKE_RST) { - if (wakeup_cause != EOS_PWR_WAKE_PIN) { - net_xchg_wake(); - } - if (!(net_state_flags & NET_STATE_FLAG_CTS)) { - while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) { - asm volatile ("wfi"); + if (wakeup_cause == EOS_PWR_WAKE_RST) { + uint32_t start, timeout; + + start = eos_get_tick(); + timeout = NET_DETECT_TIMEOUT; + while (GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS)) { + if (timeout && (eos_tdelta_ms(start) > timeout)) { + rv = EOS_ERR_NOTFOUND; + break; } - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); } - net_xchg_reset(); + if (!rv) { + GPIO_REG(GPIO_PULLUP_EN) &= ~(1 << NET_PIN_CTS); + } else { + net_state_flags |= NET_STATE_FLAG_ABSENT; + EOS_LOG(EOS_LOG_ERR, "NET DEVICE ABSENT\n"); + } + } else { + if (eos_aon_load4net()) { + /* device previously declared as absent */ + net_state_flags |= NET_STATE_FLAG_ABSENT; + } else if (!(net_state_flags & NET_STATE_FLAG_CTS)) { + /* will assume that remote device is sleeping */ + net_state_flags |= NET_STATE_FLAG_SLEEP; + } + } + if (!rv) { + /* set initial state */ + if (!(GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_CTS))) net_state_flags |= NET_STATE_FLAG_CTS; + if (!(GPIO_REG(GPIO_INPUT_VAL) & (1 << NET_PIN_RTS))) net_state_flags |= NET_STATE_FLAG_RTS; + net_resume(); } - net_resume(); set_csr(mstatus, MSTATUS_MIE); - return EOS_OK; + return rv; } void eos_net_start(void) { @@ -404,47 +478,51 @@ void eos_net_stop(void) { net_stop(); } -int eos_net_sleep(uint32_t timeout) { - uint32_t start; - uint8_t done = 0; - int rv = EOS_OK; +int eos_net_sleep(void) { + int dsel = 0; + int rv; clear_csr(mstatus, MSTATUS_MIE); - if (!(net_state_flags & NET_STATE_FLAG_RUN)) rv = EOS_ERR; + rv = net_select(&dsel); + if (rv) { + set_csr(mstatus, MSTATUS_MIE); + return rv; + } + net_state_flags |= NET_STATE_FLAG_SLEEP_REQ; + net_flushq(); + net_pause(); + net_wait4cts(); + net_xchg_sleep_req(); + net_resume(); set_csr(mstatus, MSTATUS_MIE); + if (dsel) net_deselect(); - if (rv) return rv; + return EOS_OK; +} - start = eos_get_tick(); - do { - if (eos_tdelta_ms(start) > timeout) 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); +int eos_net_sleep_rdy(void) { + int rv; - while (!(GPIO_REG(GPIO_RISE_IP) & (1 << NET_PIN_CTS))) { - if (eos_tdelta_ms(start) > timeout) { - rv = EOS_ERR_TIMEOUT; - break; - } - asm volatile ("wfi"); - } + clear_csr(mstatus, MSTATUS_MIE); + rv = !!(net_state_flags & NET_STATE_FLAG_SLEEP); + set_csr(mstatus, MSTATUS_MIE); - if (!rv) { - GPIO_REG(GPIO_RISE_IP) = (1 << NET_PIN_CTS); - net_state_flags &= ~NET_STATE_FLAG_RUN; - } + return rv; +} +void eos_net_wake(void) { + clear_csr(mstatus, MSTATUS_MIE); + net_state_flags &= ~NET_STATE_FLAG_SLEEP_REQ; set_csr(mstatus, MSTATUS_MIE); +} - return rv; +void eos_net_save2aon(void) { + int absent; + + clear_csr(mstatus, MSTATUS_MIE); + absent = !!(net_state_flags & NET_STATE_FLAG_ABSENT); + set_csr(mstatus, MSTATUS_MIE); + eos_aon_save4net(absent); } void eos_net_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) { @@ -461,7 +539,7 @@ 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)) { + if (idx && (idx <= EOS_EVT_MAX)) { idx--; net_flags_acq[idx] &= ~flag; if (acq) net_flags_acq[idx] |= flag; @@ -483,12 +561,12 @@ void eos_net_release(void) { } unsigned char *eos_net_alloc(void) { - unsigned char *ret = NULL; + unsigned char *rv = NULL; - while (ret == NULL) { + while (rv == NULL) { clear_csr(mstatus, MSTATUS_MIE); if (net_state_next_buf) { - ret = net_state_next_buf; + rv = net_state_next_buf; net_state_next_buf = NULL; } else { asm volatile ("wfi"); @@ -496,7 +574,7 @@ unsigned char *eos_net_alloc(void) { set_csr(mstatus, MSTATUS_MIE); } - return ret; + return rv; } void eos_net_free(unsigned char *buffer, unsigned char more) { @@ -519,79 +597,71 @@ void eos_net_free(unsigned char *buffer, unsigned char more) { static int net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len, unsigned char flags) { int rv = EOS_OK; int sync = 0, dsel = 0; - unsigned char _type = *type; + unsigned char _type = *type & EOS_NET_MTYPE_MASK; uint16_t _len = *len; - 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; + if (flags & NET_FLAG_MORE) _type |= EOS_NET_MTYPE_FLAG_ONEW; + if (flags & NET_FLAG_REPL) _type |= EOS_NET_MTYPE_FLAG_REPL; + if (flags & 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)) { + rv = net_select(&dsel); + if (rv) { set_csr(mstatus, MSTATUS_MIE); - - rv = eos_spi_select(EOS_SPI_DEV_NET); - if (rv) return rv; - - dsel = 1; - clear_csr(mstatus, MSTATUS_MIE); + return rv; } + if (dsel) sync = 1; if (sync) { + _type |= EOS_NET_MTYPE_FLAG_ONEW; net_pause(); net_wait4cts(); - if (flags & EOS_NET_FLAG_SYNC) { - net_state_flags |= NET_STATE_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) { - net_wait4cts(); - net_xchg_start(0, buffer, 0); - } - net_wait4xchg(); - net_state_flags &= ~NET_STATE_FLAG_SYNC; - *type = (net_state_type & ~EOS_NET_MTYPE_FLAG_MASK); - *len = net_state_len_rx; + if (flags & NET_FLAG_REPL) { + net_wait4cts(); + net_xchg_start(0, buffer, 0); } + net_wait4xchg(); + net_state_flags &= ~NET_STATE_FLAG_SYNC; + *type = net_state_type & EOS_NET_MTYPE_MASK; + *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 (dsel) eos_spi_deselect(); + if (sync && !(flags & NET_FLAG_SYNC)) eos_net_free(buffer, !!(flags & NET_FLAG_MORE)); + if (dsel) net_deselect(); 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) { +int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more) { int rv; - rv = net_xchg(&type, buffer, &len, more ? EOS_NET_FLAG_ONEW : 0); + rv = net_xchg(&type, buffer, &len, more ? NET_FLAG_MORE : 0); if (rv) eos_net_free(buffer, more); return rv; } +int eos_net_send_sync(unsigned char type, unsigned char *buffer, uint16_t len) { + return net_xchg(&type, buffer, &len, NET_FLAG_SYNC); +} + +int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len) { + return net_xchg(type, buffer, len, (NET_FLAG_SYNC | NET_FLAG_REPL)); +} + int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more) { if (async) { - return eos_net_send_async(type, buffer, len, more); + return eos_net_send(type, buffer, len, more); } else { - return eos_net_send(type, buffer, len); + return eos_net_send_sync(type, buffer, len); } } diff --git a/fw/fe310/eos/dev/net.h b/fw/fe310/eos/dev/net.h index ead88b6..12b4d14 100644 --- a/fw/fe310/eos/dev/net.h +++ b/fw/fe310/eos/dev/net.h @@ -7,32 +7,30 @@ #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 2 +#define EOS_NET_MTYPE_CELL 3 +#define EOS_NET_MTYPE_APP 4 +#define EOS_NET_MTYPE_RNG 5 -#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 5 -#define EOS_NET_MAX_MTYPE 8 +#define EOS_NET_MTYPE_SLEEP 0x10 /* does not have net handler */ #define EOS_NET_MTYPE_FLAG_ONEW 0x40 #define EOS_NET_MTYPE_FLAG_REPL 0x80 -#define EOS_NET_MTYPE_FLAG_MASK 0xc0 +#define EOS_NET_MTYPE_MASK 0x3F /* 0x0F if mtype is handled by evtq */ /* 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(void); int eos_net_run(void); void eos_net_start(void); void eos_net_stop(void); -int eos_net_sleep(uint32_t timeout); +int eos_net_sleep(void); +int eos_net_sleep_rdy(void); +void eos_net_wake(void); +void eos_net_save2aon(void); 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); @@ -42,7 +40,7 @@ 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_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more); +int eos_net_send_sync(unsigned char type, unsigned char *buffer, uint16_t len); int eos_net_xchg(unsigned char *type, unsigned char *buffer, uint16_t *len); -int eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len); -int eos_net_send_async(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char more); int _eos_net_send(unsigned char type, unsigned char *buffer, uint16_t len, unsigned char async, unsigned char more); diff --git a/fw/fe310/eos/dev/pwr.c b/fw/fe310/eos/dev/pwr.c index c6537cb..06a76d8 100644 --- a/fw/fe310/eos/dev/pwr.c +++ b/fw/fe310/eos/dev/pwr.c @@ -2,6 +2,8 @@ #include <stdint.h> #include "eos.h" +#include "log.h" +#include "event.h" #include "soc/pwr.h" #include "eve/eve.h" #include "eve/eve_touch_engine.h" @@ -15,34 +17,33 @@ #include "pwr.h" +static void pwr_sleep_rdy(void) { + if ((eos_evtq_len() == 0) && eos_net_sleep_rdy()) { + eos_eve_save2aon(); + eos_net_save2aon(); + eos_flash_norm(); #ifdef EOS_DEBUG -#include <stdio.h> + EOS_LOG(EOS_LOG_INFO, "PWR SLEEP\n"); + eos_sleep(100); #endif + eos_pwr_sleep(); + } +} void eos_pwr_sys_sleep(void) { int rv; rv = eos_lcd_sleep(); -#ifdef EOS_DEBUG - if (rv) printf("PWR SLEEP: LCD SLEEP ERR:%d\n", rv); -#endif + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: LCD SLEEP ERR:%d\n", rv); rv = eos_ctp_sleep(); -#ifdef EOS_DEBUG - if (rv) printf("PWR SLEEP: CTP SLEEP ERR:%d\n", rv); -#endif + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: CTP SLEEP ERR:%d\n", rv); rv = eos_eve_sleep(); -#ifdef EOS_DEBUG - if (rv) printf("PWR SLEEP: EVE SLEEP ERR:%d\n", rv); -#endif - - rv = eos_net_sleep(1000); -#ifdef EOS_DEBUG - if (rv) printf("PWR SLEEP: NET SLEEP ERR:%d\n", rv); -#endif + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: EVE SLEEP ERR:%d\n", rv); - eos_flash_norm(); + eos_evtq_set_loopf(pwr_sleep_rdy); - eos_pwr_sleep(); + rv = eos_net_sleep(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR SLEEP: NET SLEEP REQ ERR:%d\n", rv); } diff --git a/fw/fe310/eos/dev/sdcard.c b/fw/fe310/eos/dev/sdcard.c index 1edad96..ebdc883 100644 --- a/fw/fe310/eos/dev/sdcard.c +++ b/fw/fe310/eos/dev/sdcard.c @@ -1,38 +1,48 @@ #include <stdlib.h> #include <stdint.h> +#include "encoding.h" +#include "platform.h" +#include "board.h" + #include "eos.h" -#include "board.h" #include "spi.h" #include "drv/sdcard.h" #include "sdcard.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif +#define SDC_DETECT_TIMEOUT 1000 -void eos_sdc_insert(int sdc_det) { - int rv; +int eos_sdc_init(void) { + clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << SPI_CSPIN_SDC); + set_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << SPI_CSPIN_SDC); - rv = EOS_OK; + return EOS_OK; +} + +int eos_sdc_insert(int sdc_det, uint32_t timeout) { + if (timeout == 0) timeout = SDC_DETECT_TIMEOUT; if (sdc_det) { + int rv; + eos_spi_set_div(EOS_SPI_DEV_SDC, 1024); // 100 - 400 kHz rv = eos_spi_select(EOS_SPI_DEV_SDC); if (rv) goto sdc_insert_fin; - rv = sdc_init(1000); + rv = sdc_init(timeout); + if (rv) rv = EOS_ERR_NOTFOUND; eos_spi_deselect(); sdc_insert_fin: eos_spi_set_div(EOS_SPI_DEV_SDC, SPI_DIV_SDC); + if (rv) return rv; } else { sdc_clear(); } -#ifdef EOS_DEBUG - if (rv) printf("SDC INSERT ERR:%d\n", rv); -#endif + return EOS_OK; } diff --git a/fw/fe310/eos/dev/sdcard.h b/fw/fe310/eos/dev/sdcard.h index cefc304..4b338ea 100644 --- a/fw/fe310/eos/dev/sdcard.h +++ b/fw/fe310/eos/dev/sdcard.h @@ -1,3 +1,4 @@ #include <stdint.h> -void eos_sdc_insert(int sdc_det); +int eos_sdc_init(void); +int eos_sdc_insert(int sdc_det, uint32_t timeout); diff --git a/fw/fe310/eos/dev/spi.c b/fw/fe310/eos/dev/spi.c index fef00e1..319816d 100644 --- a/fw/fe310/eos/dev/spi.c +++ b/fw/fe310/eos/dev/spi.c @@ -5,6 +5,7 @@ #include "platform.h" #include "eos.h" +#include "log.h" #include "msgq.h" #include "event.h" @@ -13,33 +14,36 @@ #include "soc/interrupt.h" #include "soc/spi.h" #include "soc/spi_priv.h" +#include "soc/spi9bit.h" #include "net.h" #include "egpio.h" +#include "egpio_priv.h" #include "spi.h" #include "spi_cfg.h" -#ifdef EOS_DEBUG -#include <stdio.h> -#endif - static unsigned char spi_dstack[EOS_SPI_MAX_DSTACK]; static unsigned char spi_dstack_len; -static uint16_t spi_div[EOS_SPI_MAX_DEV]; +static uint16_t spi_div[SPI_MAX_DEV]; static uint8_t spi_dev(void) { return spi_dstack_len ? spi_dstack[spi_dstack_len - 1] : EOS_SPI_DEV_NET; } -static void spi_stop(unsigned char dev) { +static int spi_stop(unsigned char dev) { if (dev == EOS_SPI_DEV_NET) { eos_net_stop(); - } else if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { - eos_spi_enable(); } else { - eos_spi_stop(); + if (eos_spi_get_cs()) return EOS_ERR_BUSY; + if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { + eos_spi9bit_stop(); + eos_spi_enable(); + } else { + eos_spi_stop(); + } } + return EOS_OK; } static void spi_start(unsigned char dev) { @@ -48,6 +52,7 @@ static void spi_start(unsigned char dev) { } else if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { eos_spi_configure(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); eos_spi_disable(); + eos_spi9bit_start(); } else { eos_spi_start(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); } @@ -56,7 +61,8 @@ static void spi_start(unsigned char dev) { int eos_spi_dev_init(void) { int i; - for (i=0; i<EOS_SPI_MAX_DEV; i++) { + /* dev modules are responsibile for configuring cs gpio */ + for (i=0; i<SPI_MAX_DEV; i++) { spi_div[i] = spi_cfg[i].div; } @@ -71,14 +77,10 @@ int eos_spi_select(unsigned char dev) { int rv; int dsel; - if (eos_spi_cs_get()) rv = EOS_ERR_BUSY; - if (!rv && (spi_dstack_len == EOS_SPI_MAX_DSTACK)) rv = EOS_ERR_FULL; - - if (rv) { -#ifdef EOS_DEBUG - printf("SPI SELECT DEV:%d ERR:%d\n", dev, rv); -#endif - return rv; + rv = EOS_OK; + if (spi_dstack_len == EOS_SPI_MAX_DSTACK) { + rv = EOS_ERR_FULL; + goto spi_select_fin; } dsel = 1; @@ -87,13 +89,21 @@ int eos_spi_select(unsigned char dev) { dsel = 0; } - if (dsel) spi_stop(spi_dev()); + if (dsel) { + rv = spi_stop(spi_dev()); + if (rv) goto spi_select_fin; + } spi_dstack[spi_dstack_len] = dev; spi_dstack_len++; if (dsel) spi_start(dev); +spi_select_fin: + if (rv) { + EOS_LOG(EOS_LOG_ERR, "SPI SELECT DEV:%d ERR:%d\n", dev, rv); + return rv; + } return EOS_OK; } @@ -101,23 +111,25 @@ void eos_spi_deselect(void) { int rv; int dsel; - if (eos_spi_cs_get()) rv = EOS_ERR_BUSY; - if (!rv && (spi_dstack_len == 0)) rv = EOS_ERR_EMPTY; - - if (rv) { -#ifdef EOS_DEBUG - printf("SPI DESELECT ERR:%d\n", rv); -#endif - return; + rv = EOS_OK; + if (spi_dstack_len == 0) { + rv = EOS_ERR_EMPTY; + goto spi_deselect_fin; } dsel = !(spi_dev() & EOS_SPI_DEV_FLAG_NDSEL); - if (dsel) spi_stop(spi_dev()); + if (dsel) { + rv = spi_stop(spi_dev()); + if (rv) goto spi_deselect_fin; + } spi_dstack_len--; spi_dstack[spi_dstack_len] = 0xff; if (dsel) spi_start(spi_dev()); + +spi_deselect_fin: + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI DESELECT ERR:%d\n", rv); } void eos_spi_dev_configure(unsigned char dev) { diff --git a/fw/fe310/eos/dev/spi_cfg.h b/fw/fe310/eos/dev/spi_cfg.h index 6ef92aa..0320aa6 100644 --- a/fw/fe310/eos/dev/spi_cfg.h +++ b/fw/fe310/eos/dev/spi_cfg.h @@ -10,9 +10,9 @@ typedef struct { #define SPI_DEV_FLAG_9BIT 0x01 -#define EOS_SPI_MAX_DEV 6 +#define SPI_MAX_DEV 6 -static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { +static const SPIConfig spi_cfg[SPI_MAX_DEV] = { { // DEV_NET .div = SPI_DIV_NET, .csid = SPI_CSID_NET, diff --git a/fw/fe310/eos/eos.c b/fw/fe310/eos/eos.c index 6df8700..73ab29c 100644 --- a/fw/fe310/eos/eos.c +++ b/fw/fe310/eos/eos.c @@ -3,10 +3,12 @@ #include "encoding.h" #include "platform.h" #include "prci_driver.h" +#include "board.h" #include "event.h" #include "soc/interrupt.h" #include "soc/timer.h" +#include "soc/aon.h" #include "soc/pwr.h" #include "soc/i2s.h" #include "soc/i2c.h" @@ -16,18 +18,20 @@ #include "dev/flash.h" #include "dev/spi.h" #include "dev/net.h" +#include "dev/egpio.h" +#include "dev/egpio_priv.h" #include "dev/lcd.h" +#include "dev/ctp.h" #include "dev/sdcard.h" -#include "dev/gt911.h" -#include "dev/bq25895.h" +#include "dev/batt.h" #include "dev/eve.h" -#include "net/pwr.h" #include "net/wifi.h" #include "net/sock.h" #include "net/cell.h" #include "eos.h" +#include "log.h" uint8_t eos_init(void) { uint8_t wakeup_cause; @@ -36,65 +40,94 @@ uint8_t eos_init(void) { PRCI_use_default_clocks(); PRCI_use_pll(PLL_REFSEL_HFXOSC, 0, 1, 31, 1, -1, -1, -1); + /* enable printf */ + eos_uart_preinit(); + /* set flash driver */ eos_flash_init(); wakeup_cause = eos_pwr_wakeup_cause(); - eos_evtq_init(wakeup_cause); - eos_intr_init(wakeup_cause); - eos_timer_init(wakeup_cause); - eos_uart_init(wakeup_cause); + EOS_LOG(EOS_LOG_INFO, "INIT:%d\n", wakeup_cause); + EOS_LOG(EOS_LOG_INFO, "FREQ:%lu\n", PRCI_get_cpu_freq()); - printf("INIT:%d\n", wakeup_cause); + rv = eos_evtq_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EVTQ INIT ERR:%d\n", rv); + rv = eos_intr_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "INTR INIT ERR:%d\n", rv); + rv = eos_timer_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "TIMER INIT ERR:%d\n", rv); - rv = eos_pwr_init(wakeup_cause); - if (rv) printf("PWR INIT ERR:%d\n", rv); - rv = eos_i2s_init(wakeup_cause); - if (rv) printf("I2S INIT ERR:%d\n", rv); - rv = eos_i2c_init(wakeup_cause); - if (rv) printf("I2C INIT ERR:%d\n", rv); - rv = eos_spi_init(wakeup_cause); - if (rv) printf("SPI INIT ERR:%d\n", rv); - rv = eos_spi_dev_init(wakeup_cause); - if (rv) printf("SPI DEV INIT ERR:%d\n", rv); + rv = eos_aon_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "AON INIT ERR:%d\n", rv); + rv = eos_pwr_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "PWR INIT ERR:%d\n", rv); + rv = eos_uart_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "UART INIT ERR:%d\n", rv); - rv = eos_bq25895_init(wakeup_cause); - if (rv) printf("BQ25895 INIT ERR:%d\n", rv); + rv = eos_i2s_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "I2S INIT ERR:%d\n", rv); + rv = eos_i2c_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "I2C INIT ERR:%d\n", rv); - rv = eos_net_init(wakeup_cause); - if (rv) printf("NET INIT ERR:%d\n", rv); + rv = eos_egpio_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO INIT ERR:%d\n", rv); - rv = eos_sdc_init(wakeup_cause); - if (rv) printf("SDC INIT ERR:%d\n", rv); + rv = eos_batt_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "BATT INIT ERR:%d\n", rv); - rv = eos_eve_init(wakeup_cause); - if (rv) printf("EVE INIT ERR:%d\n", rv); + rv = eos_spi_dev_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI DEV INIT ERR:%d\n", rv); + rv = eos_spi_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI INIT ERR:%d\n", rv); + rv = eos_sdc_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INIT ERR:%d\n", rv); - rv = eos_lcd_init(wakeup_cause); - if (rv) printf("LCD INIT ERR:%d\n", rv); + rv = eos_eve_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EVE INIT ERR:%d\n", rv); - rv = eos_eve_run(wakeup_cause); - if (rv) printf("EVE RUN ERR:%d\n", rv); + rv = eos_lcd_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "LCD INIT ERR:%d\n", rv); + + rv = eos_ctp_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "CTP INIT ERR:%d\n", rv); + + rv = eos_net_init(); + if (rv) EOS_LOG(EOS_LOG_ERR, "NET INIT ERR:%d\n", rv); - eos_pwr_net_init(); eos_wifi_init(); eos_sock_init(); eos_cell_init(); + rv = eos_sdc_insert(!eos_egpio_get_val(EGPIO_PIN_SDCARD_NDET), 0); + if (rv) EOS_LOG(EOS_LOG_ERR, "SDC INSERT ERR:%d\n", rv); + return wakeup_cause; } -void eos_run(uint8_t wakeup_cause) { +void eos_run(void) { int rv; - rv = eos_net_run(wakeup_cause); - if (rv) printf("NET RUN ERR:%d\n", rv); + rv = eos_eve_run(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EVE RUN ERR:%d\n", rv); + + rv = eos_egpio_run(); + if (rv) EOS_LOG(EOS_LOG_ERR, "EGPIO RUN ERR:%d\n", rv); + + rv = eos_net_run(); + if (rv) EOS_LOG(EOS_LOG_ERR, "NET RUN ERR:%d\n", rv); } -void eos_run_once(void) { - eos_gt911_cfg_print(); - eos_gt911_configure(); - eos_gt911_cfg_print(); +#include "dev/drv/gt911.h" +#include "eve/eve.h" - eos_eve_calibrate(); +void eos_run_once(void) { + gt911_cfg_print(); + gt911_configure(); + gt911_cfg_print(); + + eve_select(); + eve_brightness(0x40); + eve_calibrate(); + eve_brightness(0); + eve_deselect(); } diff --git a/fw/fe310/eos/eos.h b/fw/fe310/eos/eos.h index 5158acd..75cd0cd 100644 --- a/fw/fe310/eos/eos.h +++ b/fw/fe310/eos/eos.h @@ -14,6 +14,8 @@ #define EOS_ERR_NET -20 +#define EOS_DEBUG 1 + uint8_t eos_init(void); -void eos_run(uint8_t wakeup_cause); +void eos_run(void); void eos_run_once(void);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/eve.c b/fw/fe310/eos/eve/eve.c index 45ac886..e5c5f80 100644 --- a/fw/fe310/eos/eve/eve.c +++ b/fw/fe310/eos/eve/eve.c @@ -12,86 +12,86 @@ static uint16_t cmd_offset; static char dl_burst; static uint32_t dl_addr; -static uint8_t power_state; +static uint8_t power_state = EVE_PSTATE_ACTIVE; static int lcd_absent = 0; void eve_command(uint8_t command, uint8_t parameter) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(((uint32_t)command << 16) | ((uint32_t)parameter << 8), 0); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } uint8_t eve_read8(uint32_t addr) { - uint8_t r; - eve_spi_cs_set(); + uint8_t rv; + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); - r = eve_spi_xchg8(0, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + rv = eve_spi_xchg8(0, EVE_SPI_FLAG_BSWAP); + eve_spi_clear_cs(); - return r; + return rv; } uint16_t eve_read16(uint32_t addr) { - uint16_t r; - eve_spi_cs_set(); + uint16_t rv; + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); - r = eve_spi_xchg16(0, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + rv = eve_spi_xchg16(0, EVE_SPI_FLAG_BSWAP); + eve_spi_clear_cs(); - return r; + return rv; } uint32_t eve_read32(uint32_t addr) { - uint32_t r; - eve_spi_cs_set(); + uint32_t rv; + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); - r = eve_spi_xchg32(0, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + rv = eve_spi_xchg32(0, EVE_SPI_FLAG_BSWAP); + eve_spi_clear_cs(); - return r; + return rv; } void eve_write8(uint32_t addr, uint8_t data) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); eve_spi_xchg8(data, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_write16(uint32_t addr, uint16_t data) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); eve_spi_xchg16(data, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_write32(uint32_t addr, uint32_t data) { - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); eve_spi_xchg32(data, EVE_SPI_FLAG_BSWAP); - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_readb(uint32_t addr, uint8_t *buf, size_t size) { int i; - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg32(addr << 8, 0); for (i=0; i<size; i++) { buf[i] = eve_spi_xchg8(0, 0); } - eve_spi_cs_clear(); + eve_spi_clear_cs(); } void eve_writeb(uint32_t addr, uint8_t *buf, size_t size) { int i; - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); for (i=0; i<size; i++) { eve_spi_xchg8(buf[i], 0); } - eve_spi_cs_clear(); + eve_spi_clear_cs(); } static void dl_inc(uint32_t i) { @@ -102,8 +102,7 @@ void eve_dl_start(uint32_t addr, char burst) { dl_addr = addr; dl_burst = burst; if (burst) { - eve_spi_lock(); - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, EVE_SPI_FLAG_TX); } } @@ -120,8 +119,7 @@ void eve_dl_write(uint32_t dl) { void eve_dl_end(void) { if (dl_burst) { eve_spi_flush(); - eve_spi_cs_clear(); - eve_spi_unlock(); + eve_spi_clear_cs(); dl_burst = 0; } } @@ -142,7 +140,7 @@ static void cmd_inc(uint16_t i) { static void cmd_begin(uint32_t command, uint8_t flags) { if (!cmd_burst) { uint32_t addr = EVE_RAM_CMD + cmd_offset; - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, 0); } eve_spi_xchg32(command, flags); @@ -150,7 +148,7 @@ static void cmd_begin(uint32_t command, uint8_t flags) { } static void cmd_end(void) { - if (!cmd_burst) eve_spi_cs_clear(); + if (!cmd_burst) eve_spi_clear_cs(); } static void cmd_string(const char *str, uint8_t flags) { @@ -256,44 +254,51 @@ void eve_cmd_dl(uint32_t dl) { } int eve_cmd_done(void) { - uint16_t r = eve_read16(REG_CMD_READ); + uint16_t rd = eve_read16(REG_CMD_READ); - if (r == 0xfff) { + if (rd == 0xfff) { eve_copro_reset(); return EVE_ERR; } - return (r == cmd_offset); + return (rd == cmd_offset); } int eve_cmd_exec(int w) { eve_write16(REG_CMD_WRITE, cmd_offset); if (w) { - int r; + int rv; + uint32_t start; + + start = eve_get_tick(); do { - r = eve_cmd_done(); - if (r < 0) break; - } while (!r); - if (r < 0) return EVE_ERR; + rv = eve_cmd_done(); + if (rv < 0) break; + if (eve_tdelta_ms(start) > EVE_CMD_EXEC_TO) break; + } while (!rv); + if (eve_tdelta_ms(start) > EVE_CMD_EXEC_TO) return EVE_ERR_TIMEOUT; + if (rv < 0) return EVE_ERR; } return EVE_OK; } +void eve_cmd_set_offset(void) { + cmd_offset = eve_read16(REG_CMD_READ); +} + void eve_cmd_burst_start(void) { uint32_t addr = EVE_RAM_CMD + cmd_offset; - eve_spi_lock(); - eve_spi_cs_set(); + eve_spi_set_cs(); eve_spi_xchg24(addr | EVE_MEM_WRITE, EVE_SPI_FLAG_TX); cmd_burst = 1; } void eve_cmd_burst_end(void) { eve_spi_flush(); - eve_spi_cs_clear(); - eve_spi_unlock(); + eve_spi_clear_cs(); cmd_burst = 0; } @@ -363,6 +368,7 @@ int eve_init(void) { eve_write8(REG_VOL_PB, 0x00); /* turn recorded audio volume off */ /* configure interrupts */ + eve_write8(REG_INT_EN, 0); eve_write16(REG_INT_MASK, 0); /* write a basic display-list to get things started */ @@ -378,28 +384,22 @@ int eve_init(void) { #endif /* nothing is being displayed yet... the pixel clock is still 0x00 */ + power_state = EVE_PSTATE_ACTIVE; + return EVE_OK; } void eve_clk_start(void) { - uint16_t gpiox; - eve_write8(REG_PCLK, EVE_PCLK); /* start clocking data to the LCD panel */ - gpiox = eve_read16(REG_GPIOX) | 0x8000; - eve_write16(REG_GPIOX, gpiox); /* enable the DISP signal to the LCD panel, it is set to output in REG_GPIOX_DIR */ } void eve_clk_stop(void) { - uint16_t gpiox; - - gpiox = eve_read16(REG_GPIOX) & ~0x8000; - eve_write16(REG_GPIOX, gpiox); eve_write8(REG_PCLK, 0); } void eve_intr_enable(void) { - eve_write8(REG_INT_EN, 0x01); while(eve_read8(REG_INT_FLAGS)); + eve_write8(REG_INT_EN, 0x01); } void eve_intr_disable(void) { @@ -408,8 +408,27 @@ void eve_intr_disable(void) { } void eve_activate(void) { + if (power_state == EVE_PSTATE_ACTIVE) return; + eve_command(EVE_ACTIVE, 0); - eve_sleep(40); + if (power_state == EVE_PSTATE_SLEEP) { + eve_sleep(20); + } +} + +void eve_deactivate(void) { + switch (power_state) { + case EVE_PSTATE_ACTIVE: + return; + + case EVE_PSTATE_STANDBY: + eve_command(EVE_STANDBY, 0); + break; + + case EVE_PSTATE_SLEEP: + eve_command(EVE_SLEEP, 0); + break; + } } void eve_pwr_standby(void) { @@ -423,9 +442,6 @@ void eve_pwr_standby(void) { void eve_pwr_sleep(void) { if (power_state != EVE_PSTATE_ACTIVE) return; - eve_clk_stop(); - eve_intr_disable(); - eve_command(EVE_SLEEP, 0); power_state = EVE_PSTATE_SLEEP; @@ -434,14 +450,17 @@ void eve_pwr_sleep(void) { void eve_pwr_wake(void) { eve_activate(); - if (power_state == EVE_PSTATE_SLEEP) { - eve_intr_enable(); - eve_clk_start(); - } - power_state = EVE_PSTATE_ACTIVE; } +void eve_pwr_set_state(uint8_t state) { + power_state = state; +} + +uint8_t eve_pwr_state(void) { + return power_state; +} + int eve_gpio_get(int gpio) { uint16_t reg = eve_read16(REG_GPIOX); @@ -456,17 +475,33 @@ void eve_gpio_set(int gpio, int val) { eve_write16(REG_GPIOX, reg); } -uint8_t eve_gpio_get_dir(void) { +uint16_t eve_gpio_read(void) { + uint16_t reg = eve_read16(REG_GPIOX); + + return reg & EVE_GPIO_MASK; +} + +void eve_gpio_write(uint16_t gpio) { + uint16_t reg = eve_read16(REG_GPIOX); + + gpio &= EVE_GPIO_MASK; + reg &= ~EVE_GPIO_MASK; + reg |= gpio; + eve_write16(REG_GPIOX, reg); +} + +uint16_t eve_gpio_read_dir(void) { uint16_t reg = eve_read16(REG_GPIOX_DIR); - return reg & 0x000f; + return reg & EVE_GPIO_MASK; } -void eve_gpio_set_dir(uint8_t dir) { +void eve_gpio_write_dir(uint16_t dir) { uint16_t reg = eve_read16(REG_GPIOX_DIR); - reg &= 0xfff0; - reg |= dir & 0x0f; + dir &= EVE_GPIO_MASK; + reg &= ~EVE_GPIO_MASK; + reg |= dir; eve_write16(REG_GPIOX_DIR, reg); } @@ -490,5 +525,8 @@ void eve_copro_reset(void) { eve_write16(REG_CMD_DL, 0); eve_write8(REG_CPURESET, 0); eve_write16(REG_COPRO_PATCH_PTR, ptr); + /* From programming guide: + To enable coprocessor access flash content, send commands CMD_FLASHATTACH following CMD_FLASHFAST. + It will make sure flash enters full speed mode.*/ eve_write8(REG_PCLK, EVE_PCLK); } diff --git a/fw/fe310/eos/eve/eve.h b/fw/fe310/eos/eve/eve.h index ea4ec71..02388bb 100644 --- a/fw/fe310/eos/eve/eve.h +++ b/fw/fe310/eos/eve/eve.h @@ -6,17 +6,16 @@ #include "eve_vtrack.h" #include "eve_platform.h" -#define EVE_OK 0 -#define EVE_ERR -1 - -#define EVE_ERR_FULL -10 -#define EVE_ERR_EMPTY -11 - -#define EVE_ERR_NOMEM -100 +/* defined in eve_platform.h */ +#define EVE_GPIO_MASK 0x800f +#define EVE_GPIO_DISP 15 #define EVE_PSTATE_ACTIVE 0 #define EVE_PSTATE_STANDBY 1 -#define EVE_PSTATE_SLEEP 3 +#define EVE_PSTATE_SLEEP 2 +#define EVE_PSTATE_PDOWN 3 + +#define EVE_CMD_EXEC_TO 1000 // 1s #define COLOR_RGBC(c) ((4UL<<24)|((c)&16777215UL)) #define CLEAR_COLOR_RGBC(c) ((2UL<<24)|((c)&16777215UL)) @@ -53,6 +52,7 @@ uint32_t eve_cmd_result(uint16_t offset); void eve_cmd_dl(uint32_t dl); int eve_cmd_done(void); int eve_cmd_exec(int w); +void eve_cmd_set_offset(void); void eve_cmd_burst_start(void); void eve_cmd_burst_end(void); @@ -65,14 +65,20 @@ void eve_intr_enable(void); void eve_intr_disable(void); void eve_activate(void); +void eve_deactivate(void); void eve_pwr_standby(void); void eve_pwr_sleep(void); void eve_pwr_wake(void); +void eve_pwr_set_state(uint8_t state); + +uint8_t eve_pwr_state(void); int eve_gpio_get(int gpio); void eve_gpio_set(int gpio, int val); -uint8_t eve_gpio_get_dir(void); -void eve_gpio_set_dir(uint8_t dir); +uint16_t eve_gpio_read(void); +void eve_gpio_write(uint16_t gpio); +uint16_t eve_gpio_read_dir(void); +void eve_gpio_write_dir(uint16_t dir); void eve_brightness(uint8_t b); void eve_lcd_absent(void); diff --git a/fw/fe310/eos/eve/eve_font.c b/fw/fe310/eos/eve/eve_font.c index 8f272bc..803c0d2 100644 --- a/fw/fe310/eos/eve/eve_font.c +++ b/fw/fe310/eos/eve/eve_font.c @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <string.h> #include "eve.h" #include "eve_font.h" @@ -19,57 +20,62 @@ int eve_font_ch_w(EVEFont *font, ucp_t ch) { return EVE_ERR; } -static int font_str_w(EVEFont *font, utf8_t *str, int *_str_w, size_t *_str_len) { - uint16_t r = 0; - size_t len = 0; +static int font_str_w(EVEFont *font, utf8_t *str, int *_str_w, size_t *_str_l) { + uint16_t w = 0; + size_t l = 0; ucp_t ch; int ch_w; int ch_l; - while (str[len]) { - ch_l = utf8_dec(str + len, &ch); + while (str[l]) { + ch_l = utf8_dec(str + l, &ch); ch_w = eve_font_ch_w(font, ch); if (ch_w < 0) { - if (_str_w) *_str_w = r; - if (_str_len) *_str_len = len; + if (_str_w) *_str_w = w; + if (_str_l) *_str_l = l; return EVE_ERR; } - r += ch_w; - len += ch_l; + w += ch_w; + l += ch_l; } - if (_str_w) *_str_w = r; - if (_str_len) *_str_len = len; + if (_str_w) *_str_w = w; + if (_str_l) *_str_l = l; return EVE_OK; } -static int font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *_buf_w, size_t *_buf_len) { - uint16_t r = 0; - size_t len = 0; +static int font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len, int *_buf_w, size_t *_buf_l) { + uint16_t w = 0; + size_t l = 0; ucp_t ch; int ch_w; int ch_l; - while (len < buf_len) { - ch_l = utf8_dec(buf + len, &ch); + while (l < buf_len) { + ch_l = utf8_dec(buf + l, &ch); ch_w = eve_font_ch_w(font, ch); if (ch_w < 0) { - if (_buf_w) *_buf_w = r; - if (_buf_len) *_buf_len = len; + if (_buf_w) *_buf_w = w; + if (_buf_l) *_buf_l = l; return EVE_ERR; } - r += ch_w; - len += ch_l; + w += ch_w; + l += ch_l; } - if (_buf_w) *_buf_w = r; - if (_buf_len) *_buf_len = len; + if (_buf_w) *_buf_w = w; + if (_buf_l) *_buf_l = l; return EVE_OK; } -int eve_font_verify(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len) { +int eve_font_verify(EVEFont *font, utf8_t *str, size_t str_size, int *str_w, size_t *str_len) { int rv; + if (str_size == 0) str_size = strlen(str) + 1; + + rv = utf8_verify(str, str_size, str_len); + if (rv) return EVE_ERR; + rv = font_str_w(font, str, str_w, str_len); return rv; } diff --git a/fw/fe310/eos/eve/eve_font.h b/fw/fe310/eos/eve/eve_font.h index 7629106..57715ac 100644 --- a/fw/fe310/eos/eve/eve_font.h +++ b/fw/fe310/eos/eve/eve_font.h @@ -11,7 +11,7 @@ typedef struct EVEFont { void eve_font_init(EVEFont *font, uint8_t font_id); int eve_font_ch_w(EVEFont *font, ucp_t ch); -int eve_font_verify(EVEFont *font, utf8_t *str, int *str_w, size_t *str_len); +int eve_font_verify(EVEFont *font, utf8_t *str, size_t str_size, int *str_w, size_t *str_len); int eve_font_str_w(EVEFont *font, utf8_t *str); int eve_font_buf_w(EVEFont *font, utf8_t *buf, size_t buf_len); uint8_t eve_font_h(EVEFont *font); diff --git a/fw/fe310/eos/eve/eve_kbd.c b/fw/fe310/eos/eve/eve_kbd.c index c8c1362..787e941 100644 --- a/fw/fe310/eos/eve/eve_kbd.c +++ b/fw/fe310/eos/eve/eve_kbd.c @@ -61,10 +61,10 @@ void eve_kbd_set_handler(EVEKbd *kbd, eve_kbd_input_handler_t putc, void *param) kbd->param = param; } -int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0) { - int ret; +int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt) { + int rv; - evt = eve_touch_evt(touch, evt, tag0, 1, 126); + evt = eve_touch_evt(touch, evt, 1, 126); if (touch && evt) { int8_t touch_idx = eve_touch_get_idx(touch); @@ -118,12 +118,12 @@ int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0) { } } } - ret = 1; + rv = 1; } else { - ret = 0; + rv = 0; } - return ret; + return rv; } uint8_t eve_kbd_draw(EVEKbd *kbd) { diff --git a/fw/fe310/eos/eve/eve_kbd.h b/fw/fe310/eos/eve/eve_kbd.h index b4f9874..a1f8abc 100644 --- a/fw/fe310/eos/eve/eve_kbd.h +++ b/fw/fe310/eos/eve/eve_kbd.h @@ -19,5 +19,5 @@ typedef struct EVEKbd { void eve_kbd_init(EVEKbd *kbd, EVERect *g, uint32_t mem_addr, uint32_t *mem_next); void eve_kbd_close(EVEKbd *kbd); void eve_kbd_set_handler(EVEKbd *kbd, eve_kbd_input_handler_t putc, void *param); -int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_kbd_touch(EVEKbd *kbd, EVETouch *touch, uint16_t evt); uint8_t eve_kbd_draw(EVEKbd *kbd); diff --git a/fw/fe310/eos/eve/eve_phy.c b/fw/fe310/eos/eve/eve_phy.c index cfddc80..8f170ba 100644 --- a/fw/fe310/eos/eve/eve_phy.c +++ b/fw/fe310/eos/eve/eve_phy.c @@ -11,69 +11,67 @@ void eve_phy_acc_init(EVEPhyAcc *param, int a) { int eve_phy_acc_start(EVEPhyAcc *param, int x0, int y0, uint32_t t0, int v0x, int v0y) { double v0; - uint32_t dt = eve_get_tick() - t0; v0 = sqrt(v0x * v0x + v0y * v0y); param->k = 2 * v0 / param->a * EVE_RTC_FREQ; - if ((param->k < 0) && (dt >= -param->k / 2)) { + if (param->k == 0) { return 0; } param->x0 = x0; param->y0 = y0; + param->t0 = t0; param->v0x = v0x; param->v0y = v0y; return 1; } -int eve_phy_acc_tick(EVEPhyAcc *param, uint32_t dt, int *x, int *y) { +int eve_phy_acc_tick(void *_param, int *x, int *y) { + EVEPhyAcc *param = (EVEPhyAcc *)_param; int k = param->k; int x0 = param->x0; int y0 = param->y0; int v0x = param->v0x; int v0y = param->v0y; - int _dt = dt; + uint32_t dt = eve_get_tick() - param->t0; int more = 1; - if (k == 0) { - if (x) *x = x0; - if (y) *y = y0; - return 0; - } - if ((k < 0) && (dt >= -k / 2)) { dt = -k / 2; more = 0; } - if (x) *x = x0 + (v0x * _dt + v0x * _dt / k * _dt) / EVE_RTC_FREQ; - if (y) *y = y0 + (v0y * _dt + v0y * _dt / k * _dt) / EVE_RTC_FREQ; + if (x) *x = x0 + (v0x * (int)dt + v0x * (int)dt / k * (int)dt) / EVE_RTC_FREQ; + if (y) *y = y0 + (v0y * (int)dt + v0y * (int)dt / k * (int)dt) / EVE_RTC_FREQ; return more; } /* Linear harmonic oscillator */ -void eve_phy_lho_init(EVEPhyLHO *param, int x, int y, uint32_t T, double d, uint32_t t_max) { +void eve_phy_lho_init(EVEPhyLHO *param, uint32_t T, double d, uint32_t t_max) { double f0 = 2 * M_PI / (T * EVE_RTC_FREQ / 1000); if (d < 0) d = 0; if (d > 1) d = 1; - param->x = x; - param->y = y; param->f = f0 * sqrt(1 - d * d); param->a = -d * f0; param->t_max = t_max * EVE_RTC_FREQ / 1000; } -int eve_phy_lho_start(EVEPhyLHO *param, int x0, int y0) { +int eve_phy_lho_start(EVEPhyLHO *param, int pivot_x, int pivot_y, int x0, int y0, uint32_t t0) { + param->pivot_x = pivot_x; + param->pivot_y = pivot_y; param->x0 = x0; param->y0 = y0; + param->t0 = t0; return 1; } -int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y) { - int ax = param->x0 - param->x; - int ay = param->y0 - param->y; +int eve_phy_lho_tick(void *_param, int *x, int *y) { + EVEPhyLHO *param = (EVEPhyLHO *)_param; + int ax = param->x0 - param->pivot_x; + int ay = param->y0 - param->pivot_y; + uint32_t dt = eve_get_tick() - param->t0; int more = 1; if (param->t_max && (dt >= param->t_max)) { @@ -86,8 +84,8 @@ int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y) { ay = ay * e; if ((ax == 0) && (ay == 0)) more = 0; } - if (x) *x = param->x + ax * cos(param->f * dt); - if (y) *y = param->y + ay * cos(param->f * dt); + if (x) *x = param->pivot_x + ax * cos(param->f * dt); + if (y) *y = param->pivot_y + ay * cos(param->f * dt); return more; } diff --git a/fw/fe310/eos/eve/eve_phy.h b/fw/fe310/eos/eve/eve_phy.h index e747b44..59f6299 100644 --- a/fw/fe310/eos/eve/eve_phy.h +++ b/fw/fe310/eos/eve/eve_phy.h @@ -5,24 +5,26 @@ typedef struct EVEPhyAcc { int k; int x0; int y0; + uint32_t t0; int v0x; int v0y; } EVEPhyAcc; void eve_phy_acc_init(EVEPhyAcc *param, int a); int eve_phy_acc_start(EVEPhyAcc *param, int x0, int y0, uint32_t t0, int v0x, int v0y); -int eve_phy_acc_tick(EVEPhyAcc *param, uint32_t dt, int *x, int *y); +int eve_phy_acc_tick(void *_param, int *x, int *y); typedef struct EVEPhyLHO { - int x; - int y; double f; double a; uint32_t t_max; + int pivot_x; + int pivot_y; int x0; int y0; + uint32_t t0; } EVEPhyLHO; -void eve_phy_lho_init(EVEPhyLHO *param, int x, int y, uint32_t T, double d, uint32_t t_max); -int eve_phy_lho_start(EVEPhyLHO *param, int x0, int y0); -int eve_phy_lho_tick(EVEPhyLHO *param, uint32_t dt, int *x, int *y);
\ No newline at end of file +void eve_phy_lho_init(EVEPhyLHO *param, uint32_t T, double d, uint32_t t_max); +int eve_phy_lho_start(EVEPhyLHO *param, int x, int y, int x0, int y0, uint32_t t0); +int eve_phy_lho_tick(void *_param, int *x, int *y);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/eve_platform.c b/fw/fe310/eos/eve/eve_platform.c index 4c0d551..916b132 100644 --- a/fw/fe310/eos/eve/eve_platform.c +++ b/fw/fe310/eos/eve/eve_platform.c @@ -1,46 +1,35 @@ #include <stdlib.h> -#include <stdio.h> -#include "eos.h" - -#include "eve.h" #include "eve_platform.h" +// #ifdef EVE_DEBUG +#if 0 + void *eve_malloc(size_t size) { void *p = malloc(size); - printf("MALLOC:%p %d\n", p, size); + EVE_LOG(EVE_LOG_INFO, "MALLOC:%p %d\n", p, size); return p; } void eve_free(void *p) { - printf("FREE:%p\n", p); + EVE_LOG(EVE_LOG_INFO, "FREE:%p\n", p); free(p); } +#endif + void eve_sleep(uint32_t ms) { - eos_time_sleep(ms); + eos_sleep(ms); } uint32_t eve_get_tick(void) { - return eos_time_get_tick(); + return eos_get_tick(); } -void eve_sys_timer_set(uint32_t ms) { +void eve_ostimer_set(uint32_t ms) { eos_timer_set(EOS_TIMER_ETYPE_UI, ms); } -void eve_sys_timer_clear(void) { +void eve_ostimer_clear(void) { eos_timer_clear(EOS_TIMER_ETYPE_UI); } - -void eve_select(void) { - eos_spi_select(EOS_SPI_DEV_EVE); -} - -void eve_deselect(void) { - eos_spi_deselect(); -} - -int eve_selected(void) { - return (eos_spi_dev() == EOS_SPI_DEV_EVE); -} diff --git a/fw/fe310/eos/eve/eve_platform.h b/fw/fe310/eos/eve/eve_platform.h index cae7222..6f34b81 100644 --- a/fw/fe310/eos/eve/eve_platform.h +++ b/fw/fe310/eos/eve/eve_platform.h @@ -1,38 +1,56 @@ #include <stdint.h> #include <stdlib.h> +/* included from eve.h - needs relative includes */ +#include "../eos.h" +#include "../log.h" #include "../soc/timer.h" #include "../soc/spi.h" -#include "../dev/spi.h" -#define EVE_ETYPE_INTR 1 +#ifdef EOS_DEBUG +#define EVE_DEBUG 1 +#endif #define EVE_RTC_FREQ EOS_TIMER_RTC_FREQ #define EVE_SPI_FLAG_BSWAP EOS_SPI_FLAG_BSWAP #define EVE_SPI_FLAG_TX EOS_SPI_FLAG_TX -void *eve_malloc(size_t); -void eve_free(void *); +#define EVE_OK EOS_OK +#define EVE_ERR EOS_ERR +#define EVE_ERR_TIMEOUT EOS_ERR_TIMEOUT + +#define EVE_ERR_FULL EOS_ERR_FULL +#define EVE_ERR_EMPTY EOS_ERR_EMPTY -//#define eve_malloc malloc -//#define eve_free free +#define EVE_ERR_NOMEM EOS_ERR_NOMEM -void eve_select(void); -void eve_deselect(void); -int eve_selected(void); +#define EVE_LOG_DEBUG EOS_LOG_DEBUG +#define EVE_LOG_INFO EOS_LOG_INFO +#define EVE_LOG_ERR EOS_LOG_ERR +#define EVE_LOG_NONE EOS_LOG_NONE +#define EVE_LOG_LEVEL EOS_LOG_LEVEL +#define EVE_LOG(l, ...) EOS_LOG(l, __VA_ARGS__) -#define eve_spi_cs_set eos_spi_cs_set -#define eve_spi_cs_clear eos_spi_cs_clear +// #ifdef EVE_DEBUG +#if 0 +void *eve_malloc(size_t); +void eve_free(void *); +#else +#define eve_malloc malloc +#define eve_free free +#endif + +#define eve_tdelta_ms eos_tdelta_ms +#define eve_spi_set_cs eos_spi_set_cs +#define eve_spi_clear_cs eos_spi_clear_cs #define eve_spi_flush eos_spi_flush #define eve_spi_xchg8 eos_spi_xchg8 #define eve_spi_xchg16 eos_spi_xchg16 #define eve_spi_xchg24 eos_spi_xchg24 #define eve_spi_xchg32 eos_spi_xchg32 -#define eve_spi_lock eos_spi_lock -#define eve_spi_unlock eos_spi_unlock void eve_sleep(uint32_t ms); uint32_t eve_get_tick(void); -void eve_sys_timer_set(uint32_t ms); -void eve_sys_timer_clear(void); +void eve_ostimer_set(uint32_t ms); +void eve_ostimer_clear(void); diff --git a/fw/fe310/eos/eve/eve_text.c b/fw/fe310/eos/eve/eve_text.c index b52678d..e31195a 100644 --- a/fw/fe310/eos/eve/eve_text.c +++ b/fw/fe310/eos/eve/eve_text.c @@ -119,8 +119,8 @@ void eve_text_scroll0(EVEText *box) { } } -int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt, uint8_t tag0) { - evt = eve_touch_evt(touch, evt, tag0, box->tag, 1); +int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt) { + evt = eve_touch_evt(touch, evt, box->tag, 1); if (touch && evt) { if ((evt & EVE_TOUCH_ETYPE_TRACK_START) && (box->line_top < 0)) { box->line_top = box->line0; @@ -148,7 +148,7 @@ uint8_t eve_text_draw(EVEText *box, uint8_t tag) { box->tag = tag; if (tag != EVE_NOTAG) { eve_cmd_dl(TAG(tag)); - eve_touch_set_opt(tag, EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_EXT_Y); + eve_tag_set_opt(tag, EVE_TOUCH_OPT_TRACK_Y | EVE_TOUCH_OPT_TRACK_EXT_Y); tag++; } eve_cmd(CMD_APPEND, "ww", box->mem_addr + box->w * 2 * box->line_size, box->dl_size * 4); @@ -161,14 +161,18 @@ void eve_text_putc(EVEText *box, int c) { int line_c, line_n; switch (c) { - case '\b': + case '\b': { eve_text_backspace(box); break; + } + case '\r': - case '\n': + case '\n': { eve_text_newline(box); break; - default: + } + + default: { line_c = box->ch_idx / 2 / box->w; eve_write16(box->mem_addr + box->ch_idx, 0x0200 | (c & 0xff)); @@ -178,6 +182,7 @@ void eve_text_putc(EVEText *box, int c) { line_n = box->ch_idx / 2 / box->w; if ((line_c != line_n) && (LINE_IDX_DIFF(line_n, box->line0, box->line_size) == box->h)) scroll1(box); break; + } } } diff --git a/fw/fe310/eos/eve/eve_text.h b/fw/fe310/eos/eve/eve_text.h index 3b282c9..6a160ad 100644 --- a/fw/fe310/eos/eve/eve_text.h +++ b/fw/fe310/eos/eve/eve_text.h @@ -23,7 +23,7 @@ void eve_text_init(EVEText *box, EVERect *g, uint16_t w, uint16_t h, uint16_t li void eve_text_update(EVEText *box); void eve_text_scroll0(EVEText *box); -int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_text_touch(EVEText *box, EVETouch *touch, uint16_t evt); uint8_t eve_text_draw(EVEText *box, uint8_t tag); void eve_text_putc(EVEText *box, int c); diff --git a/fw/fe310/eos/eve/eve_touch.c b/fw/fe310/eos/eve/eve_touch.c index a729346..d4e5cea 100644 --- a/fw/fe310/eos/eve/eve_touch.c +++ b/fw/fe310/eos/eve/eve_touch.c @@ -4,10 +4,9 @@ #include "eve.h" #include "eve_touch_engine.h" -static uint8_t touch_tag0; - static EVETouch touch_obj[EVE_MAX_TOUCH]; static EVETouchTimer touch_timer; +static EVEPhyAcc touch_acc; static eve_touch_handler_t touch_handler; static void *touch_handler_param; @@ -16,7 +15,6 @@ static uint8_t touch_tag_opt[256]; void eve_touch_init(void) { int i; - touch_tag0 = 0; memset(&touch_timer, 0, sizeof(touch_timer)); for (i=0; i<EVE_MAX_TOUCH; i++) { EVETouch *touch = &touch_obj[i]; @@ -24,7 +22,7 @@ void eve_touch_init(void) { memset(&touch_obj[i], 0, sizeof(EVETouch)); touch->eevt |= EVE_TOUCH_EETYPE_NOTOUCH; } - eve_vtrack_init(); + eve_phy_acc_init(&touch_acc, -EVE_TOUCH_ACC_A); } void eve_handle_touch(uint16_t intr_flags) { @@ -68,23 +66,17 @@ void eve_handle_touch(uint16_t intr_flags) { } } if (timer_evt & EVE_TOUCH_ETYPE_TRACK) { - EVEVTrack *vtrack = eve_vtrack_get(); - _eevt |= EVE_TOUCH_EETYPE_TRACK_ABORT; _touch_evt |= (EVE_TOUCH_ETYPE_TRACK_STOP | EVE_TOUCH_ETYPE_TRACK_ABORT); - if (vtrack->stop) vtrack->stop(touch, vtrack->param); - } - if (timer_evt & EVE_TOUCH_ETYPE_TIMER) { - _eevt |= EVE_TOUCH_EETYPE_TIMER_ABORT; - _touch_evt |= EVE_TOUCH_ETYPE_TIMER_ABORT; + eve_vtrack_stop(); } if (touch_handler && _touch_evt) { - touch_handler(touch_timer.touch, _touch_evt, touch_timer.tag0, touch_handler_param); + touch_handler(touch_timer.touch, _touch_evt, touch_handler_param); } eve_timer_clear(touch); } - touch_evt |= EVE_TOUCH_ETYPE_POINT | _evt; + touch_evt = EVE_TOUCH_ETYPE_POINT0 | _evt; touch->eevt = _eevt; touch->tag0 = 0; touch->tag = 0; @@ -104,10 +96,10 @@ void eve_handle_touch(uint16_t intr_flags) { touch->vx = vx; touch->vy = vy; - touch->t = now; } touch->x = touch_x; touch->y = touch_y; + touch->t = now; timer_evt = eve_timer_get_evt(touch); check_track = touch->tracker.tag && !touch->tracker.track; @@ -120,38 +112,31 @@ void eve_handle_touch(uint16_t intr_flags) { dx = dx < 0 ? -dx : dx; dy = dy < 0 ? -dy : dy; if (check_track) { - if ((dx > EVE_TOUCH_THRESHOLD_X) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X)) { - touch->tracker.tag = 0; - } - if ((dy > EVE_TOUCH_THRESHOLD_Y) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y)) { + if (((dx > EVE_TOUCH_THRESHOLD_X) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X)) || + ((dy > EVE_TOUCH_THRESHOLD_Y) && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y))) { touch->tracker.tag = 0; } if (touch->tracker.tag && ((dx > EVE_TOUCH_THRESHOLD_X) || (dy > EVE_TOUCH_THRESHOLD_Y))) { - int track_x = 0; - - if ((dx > EVE_TOUCH_THRESHOLD_X) && (dx > EVE_TOUCH_THRESHOLD_Y) && ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY) == EVE_TOUCH_OPT_TRACK_XY)) { - if (dx > dy) { - track_x = 1; - } - } else if (dx > EVE_TOUCH_THRESHOLD_X) { - track_x = 1; - } - if (track_x) { - touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT; - } else { - touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP; - } + int track_x, track_y; + + track_x = 0; + track_y = 0; + if ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_X) && (dx > EVE_TOUCH_THRESHOLD_X)) track_x = 1; + if ((touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_Y) && (dy > EVE_TOUCH_THRESHOLD_Y)) track_y = 1; + + if (track_x) touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT; + if (track_y) touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP; + touch_evt |= EVE_TOUCH_ETYPE_TRACK_START; touch->tracker.track = 1; - touch->t = now; } } if (check_timer && ((dx > EVE_TOUCH_THRESHOLD_X) || (dy > EVE_TOUCH_THRESHOLD_Y))) { eve_timer_set_evt(touch, timer_evt & ~(EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP2)); } } - if (touch->tracker.tag && touch->tracker.track) { - if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK) touch_evt |= EVE_TOUCH_ETYPE_TRACK; + if (touch->tracker.track) { + if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY) touch_evt |= EVE_TOUCH_ETYPE_TRACK; if (touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_REG) touch_evt |= EVE_TOUCH_ETYPE_TRACK_REG; } if (touch_evt & EVE_TOUCH_ETYPE_TRACK_REG) { @@ -171,19 +156,17 @@ void eve_handle_touch(uint16_t intr_flags) { if (timer_evt & EVE_TOUCH_ETYPE_LPRESS) { eve_timer_set_evt(touch, timer_evt & ~EVE_TOUCH_ETYPE_LPRESS); } - if (touch->tracker.tag && touch->tracker.track) { + if (touch->tracker.track) { int start = 0; uint8_t opt = touch_tag_opt[touch->tracker.tag]; uint8_t track_ext = ((opt & EVE_TOUCH_OPT_TRACK_EXT_X) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X)) || ((opt & EVE_TOUCH_OPT_TRACK_EXT_Y) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y)); if (!eve_timer_get_evt(NULL) && track_ext) { - EVEVTrack *vtrack = eve_vtrack_get(); - - if (vtrack->start) start = vtrack->start(touch, vtrack->param); + start = eve_phy_acc_start(&touch_acc, touch->x, touch->y, touch->t, touch->vx, touch->vy); } if (start) { - eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, touch_tag0, EVE_TOUCH_TIMEOUT_TRACK); + eos_vtrack_cont(&touch_acc, eve_phy_acc_tick, EVE_TOUCH_TIMEOUT_TRACK, touch); } else { touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP; } @@ -196,23 +179,22 @@ void eve_handle_touch(uint16_t intr_flags) { if (touch_tag != touch->tag) { if (touch_tag) { - if (!touch_tag0) touch_tag0 = touch_tag; if (!touch->tag0) { + touch_evt |= EVE_TOUCH_ETYPE_POINT; touch->tag0 = touch_tag; - if (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_REG)) { + if (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_REG)) { touch->tracker.tag = touch_tag; } if (touch->tracker.tag && !(touch_tag_opt[touch->tracker.tag] & EVE_TOUCH_OPT_TRACK_XY)) { touch_evt |= EVE_TOUCH_ETYPE_TRACK_START; touch->tracker.track = 1; - touch->t = now; } if (!eve_timer_get_evt(NULL) && (touch_tag_opt[touch_tag] & (EVE_TOUCH_OPT_LPRESS | EVE_TOUCH_OPT_TAP2))) { uint16_t _evt = 0; if (touch_tag_opt[touch_tag] & EVE_TOUCH_OPT_LPRESS) _evt |= EVE_TOUCH_ETYPE_LPRESS; if (touch_tag_opt[touch_tag] & EVE_TOUCH_OPT_TAP2) _evt |= EVE_TOUCH_ETYPE_TAP2; - eve_timer_set(touch, _evt, touch_tag0, EVE_TOUCH_TIMEOUT_TAP); + eve_timer_set(touch, _evt, EVE_TOUCH_TIMEOUT_TAP); } } } @@ -224,7 +206,7 @@ void eve_handle_touch(uint16_t intr_flags) { } if (touch_handler && touch_evt) { - touch_handler(touch, touch_evt, touch_tag0, touch_handler_param); + touch_handler(touch, touch_evt, touch_handler_param); } } } @@ -244,30 +226,19 @@ void eve_handle_time(void) { touch_evt |= EVE_TOUCH_ETYPE_TAP1; } if (touch_timer.evt & EVE_TOUCH_ETYPE_TRACK) { - EVEVTrack *vtrack = eve_vtrack_get(); - - if (vtrack->tick) { - touch_evt |= EVE_TOUCH_ETYPE_TRACK; - more = vtrack->tick(touch, vtrack->param); - } + touch_evt |= EVE_TOUCH_ETYPE_TRACK; + more = eve_vtrack_tick(&touch_evt); if (!more) { touch_evt |= EVE_TOUCH_ETYPE_TRACK_STOP; - if (vtrack->stop) vtrack->stop(touch, vtrack->param); } } - if (touch_timer.evt & EVE_TOUCH_ETYPE_TIMER) { - touch_evt |= EVE_TOUCH_ETYPE_TIMER; - more = 1; - } - if (more) { - eve_sys_timer_set(touch_timer.to); - } else { - touch_timer.evt = 0; + if (!more) { + eve_timer_reset(); } if (touch_handler && touch_evt) { - touch_handler(touch, touch_evt, touch_timer.tag0, touch_handler_param); + touch_handler(touch, touch_evt, touch_handler_param); } } } @@ -286,20 +257,17 @@ int8_t eve_touch_get_idx(EVETouch *touch) { return touch - touch_obj; } -uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_min, uint8_t tag_n) { +uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag_min, uint8_t tag_n) { int tag_max; uint8_t _tag; uint16_t _evt; if (tag_min == EVE_NOTAG) return 0; + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; tag_max = tag_min + tag_n; - if ((tag0 < tag_min) || (tag0 >= tag_max)) return 0; + if ((touch->tag0 < tag_min) || (touch->tag0 >= tag_max)) return 0; - _evt = evt & (EVE_TOUCH_ETYPE_TIMER_MASK | EVE_TOUCH_ETYPE_USR_MASK); - if (touch == NULL) return _evt; - - _evt |= evt & EVE_TOUCH_ETYPE_POINT_MASK; if (evt & EVE_TOUCH_ETYPE_TAG) { _tag = touch->tag; if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= EVE_TOUCH_ETYPE_TAG; @@ -312,79 +280,57 @@ uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_ _tag = touch->tracker.tag; if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= evt & EVE_TOUCH_ETYPE_TRACK_MASK; } - if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2)) { - _tag = touch->tag0; - if ((_tag >= tag_min) && (_tag < tag_max)) _evt |= evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2); + if (evt & (EVE_TOUCH_ETYPE_POINT_MASK | EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2 | EVE_TOUCH_ETYPE_USR_MASK)) { + _evt |= evt & (EVE_TOUCH_ETYPE_POINT_MASK | EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TAP1 | EVE_TOUCH_ETYPE_TAP2 | EVE_TOUCH_ETYPE_USR_MASK); } return _evt; } -void eve_touch_set_opt(uint8_t tag, uint8_t opt) { +void eve_tag_set_opt(uint8_t tag, uint8_t opt) { + if (tag == EVE_NOTAG) return; touch_tag_opt[tag] = opt; } -uint8_t eve_touch_get_opt(uint8_t tag) { +uint8_t eve_tag_get_opt(uint8_t tag) { + if (tag == EVE_NOTAG) return 0; return touch_tag_opt[tag]; } -void eve_touch_clear_opt(void) { +void eve_tag_clear_opt(void) { memset(touch_tag_opt, 0, sizeof(touch_tag_opt)); } -void eve_timer_set(EVETouch *touch, uint16_t evt, uint8_t tag0, uint32_t to) { +void eve_timer_set(EVETouch *touch, uint16_t evt, uint32_t tick_ms) { touch_timer.touch = touch; touch_timer.evt = evt; - touch_timer.tag0 = tag0; - touch_timer.to = to; - eve_sys_timer_set(to); + eve_ostimer_set(tick_ms); } void eve_timer_clear(EVETouch *touch) { eve_timer_set_evt(touch, 0); } +void eve_timer_reset(void) { + touch_timer.touch = NULL; + touch_timer.evt = 0; +} + void eve_timer_set_evt(EVETouch *touch, uint16_t evt) { if ((touch == NULL) || (touch == touch_timer.touch)) { touch_timer.evt = evt; - } else if (touch_timer.touch == NULL) { - touch_timer.evt = evt; } if (!touch_timer.evt) { - eve_sys_timer_clear(); + eve_ostimer_clear(); touch_timer.touch = NULL; - touch_timer.tag0 = 0; - touch_timer.to = 0; } } uint16_t eve_timer_get_evt(EVETouch *touch) { - uint16_t ret = 0; + uint16_t rv = 0; if ((touch == NULL) || (touch_timer.touch == touch)) { - ret = touch_timer.evt; - } else if (touch_timer.touch == NULL) { - ret = touch_timer.evt; + rv = touch_timer.evt; } - return ret; -} - -EVETouchTimer *eve_timer_get_obj(void) { - return &touch_timer; -} - -void eve_timer_start(uint8_t tag0, uint32_t to) { - if (!touch_timer.evt) eve_timer_set(NULL, EVE_TOUCH_ETYPE_TIMER, tag0, to); -} - -void eve_timer_stop(void) { - if (touch_timer.touch == NULL) eve_timer_clear(NULL); -} - -int eve_timer_running(void) { - return (touch_timer.evt == EVE_TOUCH_ETYPE_TIMER); -} - -void eve_touch_clear_tag0(void) { - touch_tag0 = 0; + return rv; } diff --git a/fw/fe310/eos/eve/eve_touch.h b/fw/fe310/eos/eve/eve_touch.h index 8ec6e0e..1f639b3 100644 --- a/fw/fe310/eos/eve/eve_touch.h +++ b/fw/fe310/eos/eve/eve_touch.h @@ -1,5 +1,7 @@ #include <stdint.h> +#define EVE_TOUCH_ACC_A 10000 + #define EVE_TOUCH_TIMEOUT_TAP 1000 #define EVE_TOUCH_TIMEOUT_TRACK 20 @@ -13,23 +15,22 @@ /* events */ #define EVE_TOUCH_ETYPE_TAG 0x0001 #define EVE_TOUCH_ETYPE_TAG_UP 0x0002 -#define EVE_TOUCH_ETYPE_POINT 0x0004 -#define EVE_TOUCH_ETYPE_POINT_UP 0x0008 -#define EVE_TOUCH_ETYPE_TRACK 0x0010 -#define EVE_TOUCH_ETYPE_TRACK_START 0x0020 -#define EVE_TOUCH_ETYPE_TRACK_STOP 0x0040 -#define EVE_TOUCH_ETYPE_TRACK_ABORT 0x0080 -#define EVE_TOUCH_ETYPE_TIMER 0x0100 -#define EVE_TOUCH_ETYPE_TIMER_ABORT 0x0200 -#define EVE_TOUCH_ETYPE_TRACK_REG 0x0400 -#define EVE_TOUCH_ETYPE_LPRESS 0x0800 -#define EVE_TOUCH_ETYPE_TAP1 0x1000 -#define EVE_TOUCH_ETYPE_TAP2 0x2000 -#define EVE_TOUCH_ETYPE_USR 0x4000 -#define EVE_TOUCH_ETYPE_USR1 0x8000 +#define EVE_TOUCH_ETYPE_POINT0 0x0004 /* emitted without tag0, possibly useless */ +#define EVE_TOUCH_ETYPE_POINT 0x0008 +#define EVE_TOUCH_ETYPE_POINT_UP 0x0010 +#define EVE_TOUCH_ETYPE_TRACK 0x0020 +#define EVE_TOUCH_ETYPE_TRACK_START 0x0040 +#define EVE_TOUCH_ETYPE_TRACK_STOP 0x0080 +#define EVE_TOUCH_ETYPE_TRACK_ABORT 0x0100 +#define EVE_TOUCH_ETYPE_TRACK_REG 0x0200 +#define EVE_TOUCH_ETYPE_LPRESS 0x0400 +#define EVE_TOUCH_ETYPE_TAP1 0x0800 +#define EVE_TOUCH_ETYPE_TAP2 0x1000 +#define EVE_TOUCH_ETYPE_USR 0x2000 +#define EVE_TOUCH_ETYPE_USR1 0x4000 +#define EVE_TOUCH_ETYPE_EXT 0x8000 /* events emitted outside of eve_touch scope */ #define EVE_TOUCH_ETYPE_TRACK_MASK (EVE_TOUCH_ETYPE_TRACK | EVE_TOUCH_ETYPE_TRACK_START | EVE_TOUCH_ETYPE_TRACK_STOP | EVE_TOUCH_ETYPE_TRACK_ABORT | EVE_TOUCH_ETYPE_TRACK_REG) -#define EVE_TOUCH_ETYPE_TIMER_MASK (EVE_TOUCH_ETYPE_TIMER | EVE_TOUCH_ETYPE_TIMER_ABORT) #define EVE_TOUCH_ETYPE_POINT_MASK (EVE_TOUCH_ETYPE_POINT | EVE_TOUCH_ETYPE_POINT_UP) #define EVE_TOUCH_ETYPE_USR_MASK (EVE_TOUCH_ETYPE_USR | EVE_TOUCH_ETYPE_USR1) @@ -44,7 +45,6 @@ #define EVE_TOUCH_EETYPE_TRACK_DOWN 0x0080 #define EVE_TOUCH_EETYPE_TRACK_ABORT 0x0100 -#define EVE_TOUCH_EETYPE_TIMER_ABORT 0x0200 #define EVE_TOUCH_EETYPE_USR 0x1000 #define EVE_TOUCH_EETYPE_USR1 0x2000 @@ -54,11 +54,9 @@ #define EVE_TOUCH_EETYPE_TRACK_X (EVE_TOUCH_EETYPE_TRACK_LEFT | EVE_TOUCH_EETYPE_TRACK_RIGHT) #define EVE_TOUCH_EETYPE_TRACK_Y (EVE_TOUCH_EETYPE_TRACK_UP | EVE_TOUCH_EETYPE_TRACK_DOWN) #define EVE_TOUCH_EETYPE_TRACK_XY (EVE_TOUCH_EETYPE_TRACK_X | EVE_TOUCH_EETYPE_TRACK_Y) -#define EVE_TOUCH_EETYPE_ABORT (EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_TIMER_ABORT) /* tag options */ -#define EVE_TOUCH_OPT_TRACK 0x01 -#define EVE_TOUCH_OPT_TRACK_REG 0x02 +#define EVE_TOUCH_OPT_TRACK_REG 0x01 #define EVE_TOUCH_OPT_TRACK_X 0x04 #define EVE_TOUCH_OPT_TRACK_Y 0x08 #define EVE_TOUCH_OPT_TRACK_EXT_X 0x10 @@ -90,12 +88,10 @@ typedef struct EVETouch { typedef struct EVETouchTimer { EVETouch *touch; - uint32_t to; uint16_t evt; - uint8_t tag0; } EVETouchTimer; -typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, uint8_t, void *); +typedef void (*eve_touch_handler_t) (EVETouch *, uint16_t, void *); void eve_touch_init(void); void eve_handle_touch(uint16_t intr_flags); @@ -104,19 +100,14 @@ void eve_handle_time(void); void eve_touch_set_handler(eve_touch_handler_t handler, void *handler_param); EVETouch *eve_touch_get_obj(int i); int8_t eve_touch_get_idx(EVETouch *touch); -uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag0, uint8_t tag_min, uint8_t tag_n); +uint16_t eve_touch_evt(EVETouch *touch, uint16_t evt, uint8_t tag_min, uint8_t tag_n); -void eve_touch_set_opt(uint8_t tag, uint8_t opt); -uint8_t eve_touch_get_opt(uint8_t tag); -void eve_touch_clear_opt(void); +void eve_tag_set_opt(uint8_t tag, uint8_t opt); +uint8_t eve_tag_get_opt(uint8_t tag); +void eve_tag_clear_opt(void); -void eve_timer_set(EVETouch *touch, uint16_t evt, uint8_t tag0, uint32_t to); +void eve_timer_set(EVETouch *touch, uint16_t evt, uint32_t to); void eve_timer_clear(EVETouch *touch); +void eve_timer_reset(void); void eve_timer_set_evt(EVETouch *touch, uint16_t evt); uint16_t eve_timer_get_evt(EVETouch *touch); -EVETouchTimer *eve_timer_get_obj(void); - -void eve_timer_start(uint8_t tag0, uint32_t to); -void eve_timer_stop(void); -int eve_timer_running(void); -void eve_touch_clear_tag0(void); diff --git a/fw/fe310/eos/eve/eve_touch_engine.c b/fw/fe310/eos/eve/eve_touch_engine.c index 2c75ca0..7c5b39f 100644 --- a/fw/fe310/eos/eve/eve_touch_engine.c +++ b/fw/fe310/eos/eve/eve_touch_engine.c @@ -26,36 +26,66 @@ static const uint32_t _reg_track[] = { REG_TRACKER_4 }; -void eve_touch_init_engine(void) { +void eve_touch_init_engine(uint16_t engine) { /* configure touch */ eve_write8(REG_CPURESET, 2); /* touch engine reset */ - eve_write16(REG_TOUCH_CONFIG, 0x4000); /* host mode multi touch */ + eve_write16(REG_TOUCH_CONFIG, engine); /* set touch engine */ eve_write8(REG_CTOUCH_EXTENDED, 0x00); /* set extended mode */ eve_write8(REG_CPURESET, 0); /* clear reset */ - eve_touch_ehost_enter(0, 0x8000, 0x8000); - eve_touch_ehost_end(); + if (engine == EVE_TOUCH_ENGINE_HOST) { + eve_touch_ehost_enter(0, 0x8000, 0x8000); + eve_touch_ehost_end(); + } } -void eve_touch_start(void) { +uint16_t eve_touch_get_engine(void) { + return (eve_read16(REG_TOUCH_CONFIG) & EVE_TOUCH_ENGINE_MASK); +} + +void eve_touch_set_engine(uint16_t engine) { + uint16_t reg = eve_read16(REG_TOUCH_CONFIG); + + reg &= ~EVE_TOUCH_ENGINE_MASK; + reg |= engine; + + eve_write8(REG_CPURESET, 2); /* touch engine reset */ + eve_write8(REG_TOUCH_CONFIG, reg); /* set touch engine */ + eve_write8(REG_CPURESET, 0); /* clear reset */ + + if (engine == EVE_TOUCH_ENGINE_HOST) { + eve_touch_ehost_enter(0, 0x8000, 0x8000); + eve_touch_ehost_end(); + } +} + +void eve_touch_intr_enable(void) { uint16_t intr_mask; intr_mask = eve_read16(REG_INT_MASK); eve_write16(REG_INT_MASK, intr_mask | (EVE_INT_CONVCOMPLETE | EVE_INT_TAG)); - - eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS); } -void eve_touch_stop(void) { +void eve_touch_intr_disable(void) { uint16_t intr_mask; intr_mask = eve_read16(REG_INT_MASK); eve_write16(REG_INT_MASK, intr_mask & ~(EVE_INT_CONVCOMPLETE | EVE_INT_TAG)); - eve_timer_clear(NULL); +} +void eve_touch_start(void) { + eve_write8(REG_TOUCH_MODE, EVE_TMODE_CONTINUOUS); +} + +void eve_touch_stop(void) { + eve_timer_clear(NULL); eve_write8(REG_TOUCH_MODE, EVE_TMODE_OFF); } +int eve_touch_get_extended(void) { + return !eve_read8(REG_CTOUCH_EXTENDED); +} + void eve_touch_set_extended(int extended) { eve_write8(REG_CPURESET, 2); /* touch engine reset */ eve_write8(REG_CTOUCH_EXTENDED, !extended); /* set / clear extended mode */ diff --git a/fw/fe310/eos/eve/eve_touch_engine.h b/fw/fe310/eos/eve/eve_touch_engine.h index 3a7508f..8eb7333 100644 --- a/fw/fe310/eos/eve/eve_touch_engine.h +++ b/fw/fe310/eos/eve/eve_touch_engine.h @@ -1,9 +1,20 @@ #include <stdint.h> -void eve_touch_init_engine(void); +#define EVE_TOUCH_ENGINE_HOST 0x4000 +#define EVE_TOUCH_ENGINE_FOCALTECH 0x0380 +#define EVE_TOUCH_ENGINE_GOODIX 0x05D0 + +#define EVE_TOUCH_ENGINE_MASK 0x4FF0 + +void eve_touch_init_engine(uint16_t engine); +uint16_t eve_touch_get_engine(void); +void eve_touch_set_engine(uint16_t engine); +void eve_touch_intr_enable(void); +void eve_touch_intr_disable(void); void eve_touch_start(void); void eve_touch_stop(void); +int eve_touch_get_extended(void); void eve_touch_set_extended(int extended); void eve_touch_get_matrix(uint32_t *touch_matrix); void eve_touch_set_matrix(const uint32_t *touch_matrix); diff --git a/fw/fe310/eos/eve/eve_vtrack.c b/fw/fe310/eos/eve/eve_vtrack.c index a7619fb..6cc3c76 100644 --- a/fw/fe310/eos/eve/eve_vtrack.c +++ b/fw/fe310/eos/eve/eve_vtrack.c @@ -4,53 +4,63 @@ #include "eve.h" static EVEVTrack vtrack; -static EVEPhyAcc vtrack_acc; void eve_vtrack_init(void) { - eve_phy_acc_init(&vtrack_acc, -EVE_VTRACK_ACC_A); eve_vtrack_reset(); } -EVEVTrack *eve_vtrack_get(void) { - return &vtrack; +void eve_vtrack_reset(void) { + vtrack.param = NULL; + vtrack.tick_f = NULL; + vtrack.tick_ms = 0; + vtrack.touch = NULL; } -void eve_vtrack_set(eve_vtrack_start_t start, eve_vtrack_tick_t tick, eve_vtrack_stop_t stop, void *param) { - vtrack.start = start; - vtrack.tick = tick; - vtrack.stop = stop; +static void vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag) { + eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, tick_ms); vtrack.param = param; + vtrack.tick_f = tick_f; + vtrack.tick_ms = tick_ms; + vtrack.touch = touch; + if (tag != EVE_NOTAG) { + touch->tracker.tag = tag; + touch->tracker.track = 1; + } } -void eve_vtrack_reset(void) { - eve_vtrack_set(eve_vtrack_acc_start, eve_vtrack_acc_tick, NULL, &vtrack_acc); -} - -int eve_vtrack_start(EVETouch *touch, uint8_t tag0, uint32_t to) { - if (vtrack.start) { - int start; - - start = vtrack.start(touch, vtrack.param); - if (start) eve_timer_set(touch, EVE_TOUCH_ETYPE_TRACK, tag0, to); +void eve_vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag) { + vtrack_start(param, tick_f, tick_ms, touch, tag); - return start; - } - return 0; + /* ensure that track start event is emitted on first vtrack tick */ + touch->eevt &= ~EVE_TOUCH_EETYPE_TRACK_XY; } -void eve_vtrack_stop(EVETouch *touch) { - eve_timer_clear(touch); - eve_vtrack_reset(); +void eos_vtrack_cont(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch) { + vtrack_start(param, tick_f, tick_ms, touch, EVE_NOTAG); } -int eve_vtrack_acc_start(EVETouch *touch, void *p) { - EVEPhyAcc *param = (EVEPhyAcc *)p; +int eve_vtrack_tick(uint16_t *touch_evt) { + EVETouch *touch = vtrack.touch; + int more = 0; - return eve_phy_acc_start(param, touch->x, touch->y, touch->t, touch->vx, touch->vy); -} + if (vtrack.tick_f) { + more = vtrack.tick_f(vtrack.param, &touch->x, &touch->y); + } + if (more) { + eve_ostimer_set(vtrack.tick_ms); + if (!(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY)) { + if ((eve_tag_get_opt(touch->tracker.tag) & EVE_TOUCH_OPT_TRACK_X) && (touch->x != touch->x0)) touch->eevt |= touch->x > touch->x0 ? EVE_TOUCH_EETYPE_TRACK_RIGHT : EVE_TOUCH_EETYPE_TRACK_LEFT; + if ((eve_tag_get_opt(touch->tracker.tag) & EVE_TOUCH_OPT_TRACK_Y) && (touch->y != touch->y0)) touch->eevt |= touch->y > touch->y0 ? EVE_TOUCH_EETYPE_TRACK_DOWN : EVE_TOUCH_EETYPE_TRACK_UP; + *touch_evt |= EVE_TOUCH_ETYPE_TRACK_START; + } + } else { + eve_timer_reset(); + eve_vtrack_reset(); + } -int eve_vtrack_acc_tick(EVETouch *touch, void *p) { - EVEPhyAcc *param = (EVEPhyAcc *)p; + return more; +} - return eve_phy_acc_tick(param, eve_get_tick() - touch->t, &touch->x, &touch->y); +void eve_vtrack_stop(void) { + eve_vtrack_reset(); } diff --git a/fw/fe310/eos/eve/eve_vtrack.h b/fw/fe310/eos/eve/eve_vtrack.h index 8455502..142d77b 100644 --- a/fw/fe310/eos/eve/eve_vtrack.h +++ b/fw/fe310/eos/eve/eve_vtrack.h @@ -1,24 +1,17 @@ #include <stdint.h> -#define EVE_VTRACK_ACC_A 10000 - -typedef int (*eve_vtrack_start_t) (EVETouch *, void *); -typedef int (*eve_vtrack_tick_t) (EVETouch *, void *); -typedef void (*eve_vtrack_stop_t) (EVETouch *, void *); +typedef int (*eve_vtrack_tick_t) (void *, int *, int *); typedef struct EVEVTrack { - eve_vtrack_start_t start; - eve_vtrack_tick_t tick; - eve_vtrack_stop_t stop; void *param; + eve_vtrack_tick_t tick_f; + uint32_t tick_ms; + EVETouch *touch; } EVEVTrack; void eve_vtrack_init(void); -EVEVTrack *eve_vtrack_get(void); -void eve_vtrack_set(eve_vtrack_start_t start, eve_vtrack_tick_t tick, eve_vtrack_stop_t stop, void *param); void eve_vtrack_reset(void); -int eve_vtrack_start(EVETouch *touch, uint8_t tag0, uint32_t to); -void eve_vtrack_stop(EVETouch *touch); - -int eve_vtrack_acc_start(EVETouch *touch, void *p); -int eve_vtrack_acc_tick(EVETouch *touch, void *p);
\ No newline at end of file +void eve_vtrack_start(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch, uint8_t tag); +void eos_vtrack_cont(void *param, eve_vtrack_tick_t tick_f, uint32_t tick_ms, EVETouch *touch); +int eve_vtrack_tick(uint16_t *touch_evt); +void eve_vtrack_stop(void);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/screen/form.c b/fw/fe310/eos/eve/screen/form.c index 3e5b97c..de03bfd 100644 --- a/fw/fe310/eos/eve/screen/form.c +++ b/fw/fe310/eos/eve/screen/form.c @@ -12,7 +12,8 @@ #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) { +static void widgets_destroy(EVEWidget *widgets, uint16_t widget_size) { + EVEWidget *widget = widgets; int i; for (i=0; i<widget_size; i++) { @@ -20,65 +21,60 @@ static void widgets_destroy(EVEWidget *widget, uint16_t widget_size) { eve_widget_destroy(widget); widget = eve_widget_next(widget); } + eve_free(widgets); } -EVEPage *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { +int eve_form_create(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { EVEWidget *widgets; EVEWidget *widget; EVELabel *label; - EVEPage *page; int w_size = 0; - int i, r; + int i, rv; if (uievt == NULL) uievt = eve_form_uievt; if (destructor == NULL) destructor = eve_form_destroy; - page = eve_malloc(sizeof(EVEPage)); - if (page == NULL) { - return NULL; - } - eve_form_init(page, window, stack, NULL, 0, uievt, destructor); for (i=0; i<spec_size; i++) { w_size += eve_widget_size(spec[i].widget.type); } widgets = eve_malloc(w_size); if (widgets == NULL) { - eve_free(page); - return NULL; + return EVE_ERR_NOMEM; } + eve_form_init(page, window, stack, NULL, 0, uievt, destructor); + widget = widgets; for (i=0; i<spec_size; i++) { - r = eve_widget_create(widget, &spec[i].widget, page); - if (r) { + rv = eve_widget_create(widget, &spec[i].widget, page); + if (rv) { widgets_destroy(widgets, i); - eve_free(widgets); - eve_free(page); - return NULL; + return rv; } if (spec[i].label.title) { + rv = EVE_OK; label = eve_malloc(sizeof(EVELabel)); - if (label == NULL) { + if (label) rv = eve_label_create(label, &spec[i].label, page); + if ((label == NULL) || rv) { + if (label) eve_free(label); eve_widget_destroy(widget); widgets_destroy(widgets, i); - eve_free(widgets); - eve_free(page); - return NULL; + return label ? rv : EVE_ERR_NOMEM; } - eve_label_create(label, &spec[i].label, page); eve_widget_set_label(widget, label); } - if (widget->g.w == 0) widget->g.w = window->g.w - (widget->label ? widget->label->g.w : 0); + if ((widget->g.w == 0) && widget->label) widget->g.w = window->g.w - widget->label->g.w; + if (widget->g.w == 0) widget->g.w = window->g.w; widget = eve_widget_next(widget); } eve_form_set_widget(page, widgets, spec_size); - return page; + return EVE_OK; } -void eve_form_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { - eve_page_init(page, window, stack, NULL, 0, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, uievt, destructor); - if (widget) eve_form_set_widget(page, widget, widget_size); +void eve_form_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { + eve_page_init(page, window, stack, widget, widget_size, EVE_PAGE_OPT_SCROLL_Y | EVE_PAGE_OPT_SCROLL_BACK | EVE_PAGE_OPT_TRACK_EXT_Y, eve_page_draw, eve_page_touch, uievt, destructor); + if (widget) eve_form_update_g(page, NULL); } void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) { @@ -88,42 +84,24 @@ void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) void eve_form_destroy(EVEPage *page) { widgets_destroy(page->widget, page->widget_size); - eve_free(page->widget); - eve_free(page); } -int eve_form_uievt(EVEPage *page, uint16_t evt, void *param) { +void eve_form_uievt(EVEPage *page, uint16_t evt, void *param) { switch (evt) { case EVE_UIEVT_WIDGET_UPDATE_G: eve_form_update_g(page, (EVEWidget *)param); break; - case EVE_UIEVT_WIDGET_FOCUS_IN: - break; - - case EVE_UIEVT_WIDGET_FOCUS_OUT: - break; - - case EVE_UIEVT_GEST_SCROLL_START: - break; - - case EVE_UIEVT_GEST_SCROLL_STOP: - break; - - case EVE_UIEVT_GEST_TRACK_START: - break; - case EVE_UIEVT_GEST_TRACK_STOP: { EVEUIEvtTouch *touch_p = (EVEUIEvtTouch *)param; if (touch_p->touch->eevt & EVE_TOUCH_EETYPE_TRACK_RIGHT) { eve_page_close(page); - return 1; + return; } break; } } - return 0; } void eve_form_update_g(EVEPage *page, EVEWidget *_widget) { diff --git a/fw/fe310/eos/eve/screen/form.h b/fw/fe310/eos/eve/screen/form.h index bc81d2d..c4b8493 100644 --- a/fw/fe310/eos/eve/screen/form.h +++ b/fw/fe310/eos/eve/screen/form.h @@ -7,10 +7,10 @@ typedef struct EVEFormSpec { EVEWidgetSpec widget; } EVEFormSpec; -EVEPage *eve_form_create(EVEWindow *window, EVEViewStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); -void eve_form_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +int eve_form_create(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEFormSpec spec[], uint16_t spec_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +void eve_form_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, eve_page_uievt_t uievt, eve_page_destructor_t destructor); void eve_form_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size); void eve_form_destroy(EVEPage *page); -int eve_form_uievt(EVEPage *page, uint16_t evt, void *param); +void eve_form_uievt(EVEPage *page, uint16_t evt, void *param); void eve_form_update_g(EVEPage *page, EVEWidget *_widget); diff --git a/fw/fe310/eos/eve/screen/page.c b/fw/fe310/eos/eve/screen/page.c index 93b81c5..8c02538 100644 --- a/fw/fe310/eos/eve/screen/page.c +++ b/fw/fe310/eos/eve/screen/page.c @@ -14,15 +14,36 @@ #define PAGE_TMODE_TRACK 1 #define PAGE_TMODE_SCROLL 2 -void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { +void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor) { memset(page, 0, sizeof(EVEPage)); eve_view_init(&page->v, window, (eve_view_draw_t)draw, (eve_view_touch_t)touch, (eve_view_uievt_t)uievt, NULL); + eve_phy_lho_init(&page->lho, 100, 0.5, 0); page->stack = stack; page->opt = opt; page->destructor = destructor; eve_page_set_widget(page, widget, widget_size); } +void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id) { + eve_view_attach(&page->v, window, page_id); +} + +void eve_page_detach(EVEPage *page) { + eve_view_detach(&page->v); +} + +void eve_page_set_param(EVEPage *page, void *param) { + eve_view_set_param(&page->v, param); +} + +EVEView *eve_page_view(EVEPage *page) { + return &page->v; +} + +EVEPage *eve_page_from_view(EVEView *view) { + return (EVEPage *)view; +} + EVEWidget *eve_page_widget(EVEPage *page, uint16_t _idx) { EVEWidget *w = page->widget; int i, idx; @@ -62,53 +83,81 @@ void eve_page_set_widget(EVEPage *page, EVEWidget *widget, uint16_t widget_size) page->widget_size = widget_size; } -void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { - EVEWindow *window = parent->v.window; - EVEViewStack *stack = parent->stack; - eve_page_destructor_t destructor = parent->destructor; - - eve_page_set_focus(parent, NULL); - if (destructor) destructor(parent); - eve_stack_create_view(stack, window, constructor); -} - -void eve_page_close(EVEPage *page) { +static void page_destroy(EVEPage *page) { EVEWindow *window = page->v.window; - EVEViewStack *stack = page->stack; eve_page_destructor_t destructor = page->destructor; - if (stack->level <= 1) return; - eve_page_set_focus(page, NULL); - if (eve_timer_running()) { - eve_timer_stop(); - } - if (eve_window_scroll(window->root, NULL) == window) { + if (eve_window_scroll(window, NULL) == window) { eve_window_scroll_stop(window); } eve_window_kbd_detach(window); + eve_page_detach(page); + if (destructor) destructor(page); - eve_stack_back(stack, window); +} + +void eve_page_open(EVEPage *parent, eve_view_constructor_t constructor) { + EVEWindow *window = parent->v.window; + EVEVStack *stack = parent->stack; + int rv; + + if (eve_vstack_full(stack)) return; + + page_destroy(parent); + rv = eve_vstack_create_view(stack, window, constructor); + if (rv) { + EVEView *view = NULL; + + do { + constructor = eve_vstack_get(stack); + if (constructor) view = constructor(window, stack); + if (view == NULL) eve_vstack_pull(stack); + } while ((view == NULL) && constructor); + if (view) eve_view_attach(view, window, constructor); + } +} + +void eve_page_close(EVEPage *page) { + EVEWindow *window = page->v.window; + EVEVStack *stack = page->stack; + int rv; + + if (eve_vstack_level(stack) == 1) return; + + page_destroy(page); + rv = eve_vstack_back(stack, window); + if (rv) { + eve_view_constructor_t constructor; + EVEView *view = NULL; + + do { + eve_vstack_pull(stack); + constructor = eve_vstack_get(stack); + if (constructor) view = constructor(window, stack); + } while ((view == NULL) && constructor); + if (view) eve_view_attach(view, window, constructor); + } } /* Screen to page coordinates */ int16_t eve_page_x(EVEPage *page, int16_t x) { - return x + page->g.x - page->v.window->g.x; + return x - page->g.x - page->v.window->g.x; } int16_t eve_page_y(EVEPage *page, int16_t y) { - return y + page->g.y - page->v.window->g.y; + return y - page->g.y - page->v.window->g.y; } /* Page to window coordinates */ int16_t eve_page_win_x(EVEPage *page, int16_t x) { - return x - page->g.x; + return x + page->g.x; } int16_t eve_page_win_y(EVEPage *page, int16_t y) { - return y - page->g.y; + return y + page->g.y; } /* Page to screen coordinates */ @@ -120,49 +169,57 @@ int16_t eve_page_scr_y(EVEPage *page, int16_t y) { return eve_page_win_y(page, y) + page->v.window->g.y; } -int eve_page_rect_visible(EVEPage *page, EVERect *g) { - uint16_t w = page->v.window->g.w; - uint16_t h = page->v.window->g.h; +int eve_page_rect_visible(EVEPage *page, EVERect *rect) { + EVERect win_g; - if (((g->x + g->w) >= page->g.x) && ((g->y + g->h) >= page->g.y) && (g->x <= (page->g.x + w)) && (g->y <= (page->g.y + h))) return 1; - return 0; + eve_window_visible_g(page->v.window, &win_g); + win_g.x -= page->v.window->g.x; + win_g.y -= page->v.window->g.y; + + if ((page->g.x + rect->x + rect->w < win_g.x) || + (page->g.y + rect->y + rect->h < win_g.y) || + (page->g.x + rect->x > win_g.x + win_g.w) || + (page->g.y + rect->y > win_g.y + win_g.h)) return 0; + + return 1; } void eve_page_show_rect(EVEPage *page, EVERect *rect) { - EVERect g; + EVERect win_g; - eve_window_visible_g(page->v.window, &g); - g.x -= page->v.window->g.x; - g.y -= page->v.window->g.y; + eve_window_visible_g(page->v.window, &win_g); + win_g.x -= page->v.window->g.x; + win_g.y -= page->v.window->g.y; - if (rect->x < page->g.x + g.x) { - page->g.x = rect->x - g.x; + if (page->g.x + rect->x < win_g.x) { + page->g.x = win_g.x - rect->x; } - if (rect->y < page->g.y + g.y) { - page->g.y = rect->y - g.y; + if (page->g.y + rect->y < win_g.y) { + page->g.y = win_g.y - rect->y; } - if ((rect->x + rect->w) > (page->g.x + g.x + g.w)) { - page->g.x = (rect->x + rect->w) - (g.x + g.w); + + if (page->g.x + rect->x + rect->w > win_g.x + win_g.w) { + page->g.x = win_g.x + win_g.w - (rect->x + rect->w); } - if ((rect->y + rect->h) > (page->g.y + g.y + g.h)) { - page->g.y = (rect->y + rect->h) - (g.y + g.h); + if (page->g.y + rect->y + rect->h > win_g.y + win_g.h) { + page->g.y = win_g.y + win_g.h - (rect->y + rect->h); } } /* returns true if x or y are out of page bounds for window */ -int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y) { - int max_x, max_y; - EVERect vg; +int eve_page_oob(EVEPage *page, int *min_x, int *min_y) { + int _min_x, _min_y; + EVERect win_g; - eve_window_visible_g(page->v.window, &vg); - max_x = page->g.w > vg.w ? page->g.w - vg.w : 0; - max_y = page->g.h > vg.h ? page->g.h - vg.h : 0; + eve_window_visible_g(page->v.window, &win_g); + _min_x = -(page->g.w > win_g.w ? page->g.w - win_g.w : 0); + _min_y = -(page->g.h > win_g.h ? page->g.h - win_g.h : 0); - if (_max_x) *_max_x = max_x; - if (_max_y) *_max_y = max_y; + if (min_x) *min_x = _min_x; + if (min_y) *min_y = _min_y; - return ((page->g.x < 0) || (page->g.x > max_x) || - (page->g.y < 0) || (page->g.y > max_y)); + return ((page->g.x > 0) || (page->g.x < _min_x) || + (page->g.y > 0) || (page->g.y < _min_y)); } EVEWidget *eve_page_focus(EVEPage *page) { @@ -174,159 +231,150 @@ void eve_page_set_focus(EVEPage *page, EVEWidget *widget) { EVEWindow *window = page->v.window; EVEWidget *widget_f = page->widget_f; - if (widget_f && widget_f->putc) { - widget_f->putc(widget_f, EVE_PAGE_KBDCH_CLOSE); - if (!(widget && widget->putc)) eve_window_kbd_detach(window); + if ((widget_f && widget_f->putc) && !(widget && widget->putc)) { + eve_window_kbd_detach(window); } if (widget && widget->putc) { EVEKbd *kbd = eve_window_kbd(window); if (kbd) eve_kbd_set_handler(kbd, widget->putc, widget); - if (!(widget_f && widget_f->putc)) eve_window_kbd_attach(window); + if (!(widget_f && widget_f->putc)) { + eve_window_kbd_attach(window); + eve_page_show_rect(page, &widget->g); + } + } + if (widget_f) { + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, widget_f); + widget_f->touch(widget_f, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_OUT); } - if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_OUT, page->widget_f); page->widget_f = widget; - if (page->widget_f) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, page->widget_f); + if (widget) { + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_FOCUS_IN, widget); + widget->touch(widget, NULL, EVE_TOUCH_ETYPE_EXT | EVE_UIEVT_WIDGET_FOCUS_IN); + } } } -static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { +static int page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) { EVEView *view = &page->v; EVEWindow *window = view->window; int scroll_x = 0, scroll_y = 0, scroll; - int ret = 0; - - if (touch) { - if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) { - scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY); - } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) { - scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X); - } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) { - scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y); - } + int rv = 0; + + if ((page->opt & EVE_PAGE_OPT_SCROLL_XY) == EVE_PAGE_OPT_SCROLL_XY) { + scroll_x = scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY); + } else if (page->opt & EVE_PAGE_OPT_SCROLL_X) { + scroll_x = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_X); + } else if (page->opt & EVE_PAGE_OPT_SCROLL_Y) { + scroll_y = (touch->eevt & EVE_TOUCH_EETYPE_TRACK_Y); + } - scroll = scroll_x || scroll_y; + scroll = scroll_x || scroll_y; - if ((tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT))) { - int _ret = 0; + if ((touch->tag0 == page->v.tag) && (evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT))) { + eve_page_set_focus(page, NULL); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt); + if (eve_window_dirty(window)) return 1; + rv = 1; + } - eve_page_set_focus(page, NULL); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TOUCH, touch, evt, tag0); - if (_ret) return _ret; - ret = 1; + /* Scroll / track start */ + if (evt & EVE_TOUCH_ETYPE_TRACK_START) { + if (page->track_mode == PAGE_TMODE_NONE) { + if (scroll) { + page->track_mode = PAGE_TMODE_SCROLL; + eve_window_scroll_start(window, touch->tag0); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt); + } else { + page->track_mode = PAGE_TMODE_TRACK; + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt); + } + if (eve_window_dirty(window)) return 1; + } + if (scroll_x) { + page->x0 = touch->x0 - page->g.x; + } + if (scroll_y) { + page->y0 = touch->y0 - page->g.y; } + rv = 1; + } - /* Scroll / track start */ - if (evt & EVE_TOUCH_ETYPE_TRACK_START) { - int _ret = 0; - - if (!(touch->eevt & EVE_TOUCH_EETYPE_ABORT)) { - if (scroll) { - page->track_mode = PAGE_TMODE_SCROLL; - eve_window_scroll_start(window, touch->tracker.tag); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_START, touch, evt, tag0); - } else { - page->track_mode = PAGE_TMODE_TRACK; - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_START, touch, evt, tag0); - } - if (_ret) return _ret; - } - if (scroll_x) { - page->x0 = page->g.x; - } - if (scroll_y) { - page->y0 = page->g.y; - } - ret = 1; + if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) { + if (scroll_x) { + page->g.x = touch->x - page->x0; } + if (scroll_y) { + page->g.y = touch->y - page->y0; + } + rv = 1; + } - /* Scroll / track stop */ - if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) || - ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) { - if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { - int max_x, max_y; - int oob; - - oob = eve_page_oob(page, &max_x, &max_y); - if (oob) { - int lho_x, lho_y; - uint8_t _tag; - EVEPhyLHO *lho = &page->lho; - - lho_x = page->g.x < 0 ? 0 : max_x; - lho_y = page->g.y < 0 ? 0 : max_y; - eve_window_scroll(window->root, &_tag); - - page->lho_t0 = eve_get_tick(); - eve_phy_lho_init(lho, lho_x, lho_y, 100, 0.5, 0); - eve_phy_lho_start(lho, page->g.x, page->g.y); - eve_timer_start(_tag, 20); + /* Scroll / track stop */ + if (((evt & EVE_TOUCH_ETYPE_TRACK_STOP) && !(evt & EVE_TOUCH_ETYPE_TRACK_ABORT)) || + ((evt & EVE_TOUCH_ETYPE_POINT_UP) && (touch->eevt & EVE_TOUCH_EETYPE_TRACK_ABORT) && !(touch->eevt & EVE_TOUCH_EETYPE_TRACK_XY))) { + int start = 0; + + if ((page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { + int min_gx, min_gy; + int oob; + + oob = eve_page_oob(page, &min_gx, &min_gy); + if (oob) { + int pivot_x, pivot_y, x0, y0; + int scroll_x, scroll_y; + EVEPhyLHO *lho = &page->lho; + uint8_t scroll_tag; + + pivot_x = touch->x0 - page->g.x + (page->g.x < min_gx ? min_gx : 0); + pivot_y = touch->y0 - page->g.y + (page->g.y < min_gy ? min_gy : 0); + x0 = touch->x0; + y0 = touch->y0; + + scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X; + scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y; + if (!scroll_x) pivot_x = x0; + if (!scroll_y) pivot_y = y0; + + eve_window_scroll(window, &scroll_tag); + start = eve_phy_lho_start(lho, pivot_x, pivot_y, x0, y0, eve_get_tick()); + if (start) { + eve_vtrack_start(lho, eve_phy_lho_tick, EVE_TOUCH_TIMEOUT_TRACK, touch, scroll_tag); } } + } - if (!eve_timer_running()) { - int _ret = 0; - - switch (page->track_mode) { - case PAGE_TMODE_SCROLL: { - page->track_mode = PAGE_TMODE_NONE; - eve_window_scroll_stop(window); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0); - break; - } - - case PAGE_TMODE_TRACK: { - page->track_mode = PAGE_TMODE_NONE; - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt, tag0); - break; - } + if (!start) { + switch (page->track_mode) { + case PAGE_TMODE_SCROLL: { + page->track_mode = PAGE_TMODE_NONE; + eve_window_scroll_stop(window); + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt); + break; } - if (_ret) return _ret; - } - ret = 1; - } - if ((evt & EVE_TOUCH_ETYPE_TRACK) && (page->track_mode == PAGE_TMODE_SCROLL)) { - if (scroll_x) { - page->g.x = page->x0 + touch->x0 - touch->x; - } - if (scroll_y) { - page->g.y = page->y0 + touch->y0 - touch->y; + case PAGE_TMODE_TRACK: { + page->track_mode = PAGE_TMODE_NONE; + eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_TRACK_STOP, touch, evt); + break; + } } - ret = 1; - } - } else if ((evt & EVE_TOUCH_ETYPE_TIMER) && (page->track_mode == PAGE_TMODE_SCROLL) && (page->opt & EVE_PAGE_OPT_SCROLL_BACK)) { - EVEPhyLHO *lho = &page->lho; - int scroll_x = page->opt & EVE_PAGE_OPT_SCROLL_X; - int scroll_y = page->opt & EVE_PAGE_OPT_SCROLL_Y; - int x, y, more; - - more = eve_phy_lho_tick(lho, eve_get_tick() - page->lho_t0, scroll_x ? &x : NULL, scroll_y ? &y : NULL); - if (scroll_x) page->g.x = x; - if (scroll_y) page->g.y = y; - if (!more) { - int _ret = 0; - - page->track_mode = PAGE_TMODE_NONE; - eve_timer_stop(); - eve_window_scroll_stop(window); - _ret = eve_view_uievt_push_gest(view, EVE_UIEVT_GEST_SCROLL_STOP, touch, evt, tag0); - if (_ret) return _ret; + if (eve_window_dirty(window)) return 1; } - ret = 1; + rv = 1; } - return ret; + return rv; } uint8_t eve_page_draw(EVEPage *page, uint8_t tag0) { EVEView *view = &page->v; EVEWidget *widget = page->widget; int i; - uint8_t tagN = tag0; + uint8_t tagN; uint8_t tag_opt; - tag_opt = EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY; + tag_opt = EVE_TOUCH_OPT_TRACK_XY; if (page->opt & EVE_PAGE_OPT_TRACK_EXT_X) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_X; if (page->opt & EVE_PAGE_OPT_TRACK_EXT_Y) tag_opt |= EVE_TOUCH_OPT_TRACK_EXT_Y; @@ -354,52 +402,41 @@ draw_nextw: eve_cmd_dl(RESTORE_CONTEXT()); for (i=tag0; i<tagN; i++) { - if (i != EVE_NOTAG) eve_touch_set_opt(i, eve_touch_get_opt(i) | tag_opt); + if (i != EVE_NOTAG) eve_tag_set_opt(i, eve_tag_get_opt(i) | tag_opt); } return tagN; } -int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0) { +int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt) { EVEWidget *widget = page->widget; - EVEViewStack *stack = page->stack; + EVEWindow *window = page->v.window; int8_t touch_idx = eve_touch_get_idx(touch); uint16_t _evt; - int i, ret; + int i, rv; if (touch_idx > 0) return 0; - _evt = eve_touch_evt(touch, evt, tag0, page->v.tag, 1); + _evt = eve_touch_evt(touch, evt, page->v.tag, 1); if (_evt) { - ret = page_touch(page, touch, _evt, tag0); - if (stack->dirty) { - stack->dirty = 0; - return 1; - } - if (ret) return 1; + rv = page_touch(page, touch, _evt); + if (rv || eve_window_dirty(window)) return 1; } for (i=0; i<page->widget_size; i++) { if (!eve_page_rect_visible(page, &widget->g) || (widget->flags & (EVE_WIDGET_FLAG_SKIP | EVE_WIDGET_FLAG_RO | EVE_WIDGET_FLAG_HIDDEN))) goto touch_nextw; - _evt = eve_touch_evt(touch, evt, tag0, widget->tag0, widget->tagN - widget->tag0); + _evt = eve_touch_evt(touch, evt, widget->tag0, widget->tagN - widget->tag0); if (_evt) { if (page->track_mode == PAGE_TMODE_NONE) { - ret = widget->touch(widget, touch, _evt); - if (stack->dirty) { - stack->dirty = 0; + rv = widget->touch(widget, touch, _evt); + if (eve_window_dirty(window)) return 1; + if (rv) { + eve_page_set_focus(page, widget); return 1; } - if (ret) { - eve_widget_set_focus(widget); - return 1; - } - } - ret = page_touch(page, touch, _evt, tag0); - if (stack->dirty) { - stack->dirty = 0; - return 1; } - if (ret) return 1; + rv = page_touch(page, touch, _evt); + if (rv || eve_window_dirty(window)) return 1; } touch_nextw: diff --git a/fw/fe310/eos/eve/screen/page.h b/fw/fe310/eos/eve/screen/page.h index 6874a2d..067565b 100644 --- a/fw/fe310/eos/eve/screen/page.h +++ b/fw/fe310/eos/eve/screen/page.h @@ -1,7 +1,5 @@ #include <stdint.h> -#define EVE_PAGE_KBDCH_CLOSE 0x1a - #define EVE_PAGE_OPT_SCROLL_X 0x01 #define EVE_PAGE_OPT_SCROLL_Y 0x02 #define EVE_PAGE_OPT_SCROLL_BACK 0x04 @@ -15,8 +13,8 @@ struct EVEWidget; struct EVEPage; typedef uint8_t (*eve_page_draw_t) (struct EVEPage *, uint8_t); -typedef int (*eve_page_touch_t) (struct EVEPage *, EVETouch *, uint16_t, uint8_t); -typedef int (*eve_page_uievt_t) (struct EVEPage *, uint16_t, void *); +typedef int (*eve_page_touch_t) (struct EVEPage *, EVETouch *, uint16_t); +typedef void (*eve_page_uievt_t) (struct EVEPage *, uint16_t, void *); typedef void (*eve_page_destructor_t) (struct EVEPage *); typedef struct EVEPage { @@ -24,19 +22,23 @@ typedef struct EVEPage { EVERect g; int16_t x0; int16_t y0; - EVEViewStack *stack; + EVEVStack *stack; eve_page_destructor_t destructor; struct EVEWidget *widget; uint16_t widget_size; struct EVEWidget *widget_f; EVEPhyLHO lho; - uint32_t lho_t0; uint8_t track_mode; uint8_t opt; } EVEPage; -void eve_page_init(EVEPage *page, EVEWindow *window, EVEViewStack *stack, struct EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +void eve_page_init(EVEPage *page, EVEWindow *window, EVEVStack *stack, struct EVEWidget *widget, uint16_t widget_size, uint8_t opt, eve_page_draw_t draw, eve_page_touch_t touch, eve_page_uievt_t uievt, eve_page_destructor_t destructor); +void eve_page_attach(EVEPage *page, EVEWindow *window, void *page_id); +void eve_page_detach(EVEPage *page); +void eve_page_set_param(EVEPage *page, void *param); +EVEView *eve_page_view(EVEPage *page); +EVEPage *eve_page_from_view(EVEView *view); struct EVEWidget *eve_page_widget(EVEPage *page, uint16_t idx); struct EVEWidget *eve_page_widget_search(EVEPage *page, char *label); void eve_page_set_widget(EVEPage *page, struct EVEWidget *widget, uint16_t widget_size); @@ -53,12 +55,12 @@ int16_t eve_page_win_y(EVEPage *page, int16_t y); /* Page to screen coordinates */ int16_t eve_page_scr_x(EVEPage *page, int16_t x); int16_t eve_page_scr_y(EVEPage *page, int16_t y); -int eve_page_rect_visible(EVEPage *page, EVERect *g); +int eve_page_rect_visible(EVEPage *page, EVERect *rect); void eve_page_show_rect(EVEPage *page, EVERect *rect); -int eve_page_oob(EVEPage *page, int *_max_x, int *_max_y); +int eve_page_oob(EVEPage *page, int *min_x, int *min_y); struct EVEWidget *eve_page_focus(EVEPage *page); void eve_page_set_focus(EVEPage *page, struct EVEWidget *widget); uint8_t eve_page_draw(EVEPage *page, uint8_t tag0); -int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_page_touch(EVEPage *page, EVETouch *touch, uint16_t evt); diff --git a/fw/fe310/eos/eve/screen/uievt.h b/fw/fe310/eos/eve/screen/uievt.h index 8e1e682..e40624a 100644 --- a/fw/fe310/eos/eve/screen/uievt.h +++ b/fw/fe310/eos/eve/screen/uievt.h @@ -5,12 +5,12 @@ #define EVE_UIEVT_GEST_TRACK_STOP 5 #define EVE_UIEVT_WIN_UPDATE_G 6 #define EVE_UIEVT_PAGE_UPDATE_G 7 -#define EVE_UIEVT_WIDGET_UPDATE_G 8 -#define EVE_UIEVT_WIDGET_FOCUS_IN 9 -#define EVE_UIEVT_WIDGET_FOCUS_OUT 10 +#define EVE_UIEVT_WIDGET_UPDATE 8 +#define EVE_UIEVT_WIDGET_UPDATE_G 9 +#define EVE_UIEVT_WIDGET_FOCUS_IN 10 +#define EVE_UIEVT_WIDGET_FOCUS_OUT 11 typedef struct EVEUIEvtTouch { EVETouch *touch; uint16_t evt; - uint8_t tag0; } EVEUIEvtTouch; diff --git a/fw/fe310/eos/eve/screen/view.c b/fw/fe310/eos/eve/screen/view.c index d6e9ede..a1290f0 100644 --- a/fw/fe310/eos/eve/screen/view.c +++ b/fw/fe310/eos/eve/screen/view.c @@ -15,7 +15,19 @@ void eve_view_init(EVEView *view, EVEWindow *window, eve_view_draw_t draw, eve_v view->window = window; view->color_bg = 0x000000; view->color_fg = 0xffffff; - window->view = view; +} + +void eve_view_attach(EVEView *view, EVEWindow *window, void *view_id) { + view->window = window; + eve_window_attach_view(window, view, view_id); +} + +void eve_view_detach(EVEView *view) { + eve_window_detach_view(view->window); +} + +void eve_view_set_param(EVEView *view, void *param) { + view->param = param; } void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) { @@ -29,78 +41,121 @@ void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b) { uint8_t eve_view_clear(EVEView *view, uint8_t tag0, uint8_t tag_opt) { EVEWindow *win_scroll = NULL; EVEWindow *window = view->window; - uint8_t _tag; + uint8_t scroll_tag; - win_scroll = eve_window_scroll(window->root, &_tag); + win_scroll = eve_window_scroll(window, &scroll_tag); eve_cmd_dl(CLEAR_COLOR_RGBC(view->color_bg)); eve_cmd_dl(COLOR_RGBC(view->color_fg)); if (win_scroll == window) { - view->tag = _tag; - eve_touch_set_opt(view->tag, tag_opt); - eve_cmd_dl(TAG(view->tag)); - eve_cmd_dl(CLEAR_TAG(view->tag)); + view->tag = scroll_tag; } else if (win_scroll) { view->tag = EVE_NOTAG; - eve_cmd_dl(TAG(view->tag)); - eve_cmd_dl(CLEAR_TAG(view->tag)); } else { view->tag = tag0; if (tag0 != EVE_NOTAG) { - eve_touch_set_opt(tag0, tag_opt); - eve_cmd_dl(CLEAR_TAG(tag0)); + eve_tag_set_opt(tag0, tag_opt); tag0++; } } + eve_cmd_dl(CLEAR_TAG(view->tag)); eve_cmd_dl(CLEAR(1,1,1)); return tag0; } -int eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) { - if (view->uievt) return view->uievt(view, evt, param); - return 0; +uint8_t eve_view_tag(EVEView *view, uint8_t tag, uint8_t tag_opt) { + if (tag != EVE_NOTAG) { + eve_tag_set_opt(tag, tag_opt); + eve_cmd_dl(TAG(tag)); + tag++; + } + return tag; } -int eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0) { - if (view->uievt) { - EVEUIEvtTouch param; +void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param) { + if (view->uievt) view->uievt(view, evt, param); +} - param.touch = touch; - param.evt = t_evt; - param.tag0 = tag0; - return view->uievt(view, evt, ¶m); - } - return 0; +void eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt) { + EVEUIEvtTouch param; + + if (view->uievt == NULL) return; + + param.touch = touch; + param.evt = t_evt; + view->uievt(view, evt, ¶m); } -void eve_stack_init(EVEViewStack *stack) { - memset(stack, 0, sizeof(EVEViewStack)); +void eve_vstack_init(EVEVStack *stack) { + memset(stack, 0, sizeof(EVEVStack)); } -void eve_stack_create_view(EVEViewStack *stack, EVEWindow *window, eve_view_constructor_t constructor) { - int rv; +int eve_vstack_push(EVEVStack *stack, eve_view_constructor_t constructor) { + if (stack->level == EVE_VIEW_SIZE_STACK) return EVE_ERR_FULL; - stack->dirty = 1; - if (stack->level < EVE_VIEW_SIZE_STACK - 1) { - stack->constructor[stack->level] = constructor; - stack->level++; - rv = constructor(window, stack); - if (rv) eve_stack_back(stack, window); - } + stack->constructor[stack->level] = constructor; + stack->level++; + + return EVE_OK; } -void eve_stack_back(EVEViewStack *stack, EVEWindow *window) { +eve_view_constructor_t eve_vstack_pull(EVEVStack *stack) { eve_view_constructor_t constructor; - int rv = 1; - stack->dirty = 1; - while ((stack->level > 1) && rv) { + constructor = eve_vstack_get(stack); + if (stack->level) { stack->level--; - constructor = stack->constructor[stack->level - 1]; - rv = constructor(window, stack); + stack->constructor[stack->level] = NULL; } + return constructor; } -eve_view_constructor_t eve_stack_get(EVEViewStack *stack) { +eve_view_constructor_t eve_vstack_get(EVEVStack *stack) { if (stack->level) return stack->constructor[stack->level - 1]; return NULL; } + +int eve_vstack_empty(EVEVStack *stack) { + return (stack->level == 0); +} + +int eve_vstack_full(EVEVStack *stack) { + return (stack->level == EVE_VIEW_SIZE_STACK); +} + +int eve_vstack_level(EVEVStack *stack) { + return stack->level; +} + +int eve_vstack_create_view(EVEVStack *stack, EVEWindow *window, eve_view_constructor_t constructor) { + EVEView *view; + int rv; + + rv = eve_vstack_push(stack, constructor); + if (rv) return rv; + + view = constructor(window, stack); + if (view == NULL) { + eve_vstack_pull(stack); + return EVE_ERR; + } + + eve_view_attach(view, window, constructor); + + return EVE_OK; +} + +int eve_vstack_back(EVEVStack *stack, EVEWindow *window) { + EVEView *view; + eve_view_constructor_t constructor; + + eve_vstack_pull(stack); + constructor = eve_vstack_get(stack); + if (constructor == NULL) return EVE_ERR_EMPTY; + + view = constructor(window, stack); + if (view == NULL) return EVE_ERR; + + eve_view_attach(view, window, constructor); + + return EVE_OK; +} diff --git a/fw/fe310/eos/eve/screen/view.h b/fw/fe310/eos/eve/screen/view.h index 3e8c0a0..c40a620 100644 --- a/fw/fe310/eos/eve/screen/view.h +++ b/fw/fe310/eos/eve/screen/view.h @@ -5,13 +5,13 @@ #define EVE_VIEW_SIZE_STACK 16 struct EVEView; -struct EVEViewStack; +struct EVEVStack; struct EVEWindow; typedef uint8_t (*eve_view_draw_t) (struct EVEView *, uint8_t); -typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t, uint8_t); -typedef int (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *); -typedef int (*eve_view_constructor_t) (struct EVEWindow *window, struct EVEViewStack *); +typedef int (*eve_view_touch_t) (struct EVEView *, EVETouch *, uint16_t); +typedef void (*eve_view_uievt_t) (struct EVEView *, uint16_t, void *); +typedef struct EVEView *(*eve_view_constructor_t) (struct EVEWindow *window, struct EVEVStack *); typedef struct EVEView { eve_view_draw_t draw; @@ -24,21 +24,29 @@ typedef struct EVEView { uint8_t tag; } EVEView; -typedef struct EVEViewStack { +typedef struct EVEVStack { eve_view_constructor_t constructor[EVE_VIEW_SIZE_STACK]; uint8_t level; - uint8_t dirty; -} EVEViewStack; +} EVEVStack; void eve_view_init(EVEView *view, struct EVEWindow *window, eve_view_draw_t draw, eve_view_touch_t touch, eve_view_uievt_t uievt, void *param); +void eve_view_attach(EVEView *view, struct EVEWindow *window, void *view_id); +void eve_view_detach(EVEView *view); +void eve_view_set_param(EVEView *view, void *param); void eve_view_set_color_bg(EVEView *view, uint8_t r, uint8_t g, uint8_t b); void eve_view_set_color_fg(EVEView *view, uint8_t r, uint8_t g, uint8_t b); uint8_t eve_view_clear(EVEView *view, uint8_t tag0, uint8_t tag_opt); - -int eve_view_uievt_push(EVEView *view, uint16_t evt, void *param); -int eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt, uint8_t tag0); - -void eve_stack_init(EVEViewStack *stack); -void eve_stack_create_view(EVEViewStack *stack, struct EVEWindow *window, eve_view_constructor_t constructor); -void eve_stack_back(EVEViewStack *stack, struct EVEWindow *window); -eve_view_constructor_t eve_stack_get(EVEViewStack *stack);
\ No newline at end of file +uint8_t eve_view_tag(EVEView *view, uint8_t tag, uint8_t tag_opt); + +void eve_view_uievt_push(EVEView *view, uint16_t evt, void *param); +void eve_view_uievt_push_gest(EVEView *view, uint16_t evt, EVETouch *touch, uint16_t t_evt); + +void eve_vstack_init(EVEVStack *stack); +int eve_vstack_push(EVEVStack *stack, eve_view_constructor_t constructor); +eve_view_constructor_t eve_vstack_pull(EVEVStack *stack); +eve_view_constructor_t eve_vstack_get(EVEVStack *stack); +int eve_vstack_empty(EVEVStack *stack); +int eve_vstack_full(EVEVStack *stack); +int eve_vstack_level(EVEVStack *stack); +int eve_vstack_create_view(EVEVStack *stack, struct EVEWindow *window, eve_view_constructor_t constructor); +int eve_vstack_back(EVEVStack *stack, struct EVEWindow *window); diff --git a/fw/fe310/eos/eve/screen/window.c b/fw/fe310/eos/eve/screen/window.c index 34d265a..90f4e20 100644 --- a/fw/fe310/eos/eve/screen/window.c +++ b/fw/fe310/eos/eve/screen/window.c @@ -1,6 +1,5 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> #include "eve.h" #include "eve_kbd.h" @@ -28,7 +27,7 @@ void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont * root->font = font; root->win_kbd = NULL; root->win_scroll = NULL; - root->tag0 = EVE_NOTAG; + root->tag_scroll = EVE_NOTAG; eve_touch_set_handler(eve_window_root_touch, root); } @@ -41,10 +40,10 @@ static uint8_t kbd_draw(EVEView *view, uint8_t tag0) { return tag0; } -static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt, uint8_t tag0) { +static int kbd_touch(EVEView *view, EVETouch *touch, uint16_t evt) { EVEKbd *kbd = view->param; - return eve_kbd_touch(kbd, touch, evt, tag0); + return eve_kbd_touch(kbd, touch, evt); } void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd) { @@ -55,6 +54,7 @@ void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, win_kbd->kbd = kbd; root->win_kbd = win_kbd; eve_view_init(&win_kbd->v, _window, kbd_draw, kbd_touch, NULL, kbd); + eve_view_attach(&win_kbd->v, _window, NULL); } void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) { @@ -62,6 +62,26 @@ void eve_window_set_parent(EVEWindow *window, EVEWindow *parent) { window->root = parent->root; } +void eve_window_attach_view(EVEWindow *window, EVEView *view, void *view_id) { + if (window->view) window->dirty = 1; + window->view = view; + window->view_id = view_id; +} + +void eve_window_detach_view(EVEWindow *window) { + if (window->view) window->dirty = 1; + window->view = NULL; + window->view_id = NULL; +} + +int eve_window_dirty(EVEWindow *window) { + return window->dirty; +} + +void eve_window_clean(EVEWindow *window) { + window->dirty = 0; +} + int eve_window_visible(EVEWindow *window) { if (window->g.x >= window->root->w.g.w) return 0; if (window->g.y >= window->root->w.g.h) return 0; @@ -70,31 +90,32 @@ int eve_window_visible(EVEWindow *window) { return 1; } -static void window_visible_g(EVEWindow *w, EVERect *g) { - while (w) { - if (eve_window_visible(w)) { - if (w->g.x > g->x) g->w = MIN(g->w, w->g.x - g->x); - if (w->g.y > g->y) g->h = MIN(g->h, w->g.y - g->y); - if (w->g.x + w->g.w < g->x + g->w) { - uint16_t x0 = g->w - MIN(g->w, (g->x + g->w) - (w->g.x + w->g.w)); - g->x += x0; - g->w -= x0; +static void window_visible_g(EVEWindow *win, EVERect *rect) { + while (win) { + if (eve_window_visible(win)) { + if (win->g.x > rect->x) rect->w = MIN(rect->w, win->g.x - rect->x); + if (win->g.y > rect->y) rect->h = MIN(rect->h, win->g.y - rect->y); + if (win->g.x + win->g.w < rect->x + rect->w) { + uint16_t x0 = rect->w - MIN(rect->w, (rect->x + rect->w) - (win->g.x + win->g.w)); + rect->x += x0; + rect->w -= x0; } - if (w->g.y + w->g.h < g->y + g->h) { - uint16_t y0 = g->h - MIN(g->h, (g->y + g->h) - (w->g.y + w->g.h)); - g->y += y0; - g->h -= y0; + if (win->g.y + win->g.h < rect->y + rect->h) { + uint16_t y0 = rect->h - MIN(rect->h, (rect->y + rect->h) - (win->g.y + win->g.h)); + rect->y += y0; + rect->h -= y0; } + if ((rect->w == 0) || (rect->h == 0)) return; } - if (w->child_head) window_visible_g(w->child_head, g); - w = w->next; + if (win->child_head) window_visible_g(win->child_head, rect); + win = win->next; } } -void eve_window_visible_g(EVEWindow *window, EVERect *g) { - *g = window->g; - if (window->child_head) window_visible_g(window->child_head, g); - window_visible_g(window->next, g); +void eve_window_visible_g(EVEWindow *window, EVERect *rect) { + *rect = window->g; + if (window->child_head) window_visible_g(window->child_head, rect); + window_visible_g(window->next, rect); } void eve_window_append(EVEWindow *window) { @@ -160,8 +181,8 @@ EVEWindow *eve_window_search(EVEWindow *window, char *name) { while (window) { if (window->name && (strcmp(name, window->name) == 0)) return window; if (window->child_head) { - EVEWindow *ret = eve_window_search(window->child_head, name); - if (ret) return ret; + EVEWindow *rv = eve_window_search(window->child_head, name); + if (rv) return rv; } window = window->next; } @@ -198,17 +219,18 @@ uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0) { return tag0; } -int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0) { - int ret = 0; +int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt) { + int rv = 0; while (window) { if (window->child_tail) { - ret = eve_window_touch(window->child_tail, touch, evt, tag0); - if (ret) return 1; + rv = eve_window_touch(window->child_tail, touch, evt); + if (rv) return 1; } if (eve_window_visible(window) && window->view) { - ret = window->view->touch(window->view, touch, evt, tag0); - if (ret) return 1; + rv = window->view->touch(window->view, touch, evt); + window->dirty = 0; + if (rv) return 1; } window = window->prev; } @@ -223,24 +245,31 @@ void eve_window_root_draw(EVEWindowRoot *root) { eve_cmd_burst_start(); eve_cmd_dl(CMD_DLSTART); - if (root->tag0 != EVE_NOTAG) tag0 = EVE_NOTAG; + if (root->tag_scroll != EVE_NOTAG) tag0 = EVE_NOTAG; eve_window_draw(&root->w, tag0); eve_cmd_dl(DISPLAY()); eve_cmd_dl(CMD_SWAP); eve_cmd_burst_end(); rv = eve_cmd_exec(1); - if (rv) printf("EVE EXEC ERR\n"); + if (rv) EVE_LOG(EVE_LOG_ERR, "EVE CMD EXEC ERR:%d\n", rv); } -void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win) { +void eve_window_root_touch(EVETouch *touch, uint16_t evt, void *win) { EVEWindowRoot *root = (EVEWindowRoot *)win; - int ret; + int rv; - if (root->tag0 != EVE_NOTAG) tag0 = root->tag0; - ret = eve_window_touch(&root->w, touch, evt, tag0); - if (ret) { - eve_touch_clear_opt(); + rv = eve_window_touch(&root->w, touch, evt); + if (rv) { + uint8_t tag_opt = 0; + + if (root->tag_scroll != EVE_NOTAG) { + tag_opt = eve_tag_get_opt(root->tag_scroll); + } + eve_tag_clear_opt(); + if (root->tag_scroll != EVE_NOTAG) { + eve_tag_set_opt(root->tag_scroll, tag_opt); + } eve_window_root_draw(root); } } @@ -275,14 +304,10 @@ void eve_window_kbd_detach(EVEWindow *window) { } } -EVEFont *eve_window_font(EVEWindow *window) { +EVEWindow *eve_window_scroll(EVEWindow *window, uint8_t *tag) { EVEWindowRoot *root = window->root; - return root->font; -} - -EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag) { - if (tag) *tag = root->tag0; + if (tag) *tag = root->tag_scroll; return root->win_scroll; } @@ -290,12 +315,18 @@ void eve_window_scroll_start(EVEWindow *window, uint8_t tag) { EVEWindowRoot *root = window->root; root->win_scroll = window; - root->tag0 = tag; + root->tag_scroll = tag; } void eve_window_scroll_stop(EVEWindow *window) { EVEWindowRoot *root = window->root; root->win_scroll = NULL; - root->tag0 = EVE_NOTAG; + root->tag_scroll = EVE_NOTAG; +} + +EVEFont *eve_window_font(EVEWindow *window) { + EVEWindowRoot *root = window->root; + + return root->font; } diff --git a/fw/fe310/eos/eve/screen/window.h b/fw/fe310/eos/eve/screen/window.h index 27465c4..ac52fb8 100644 --- a/fw/fe310/eos/eve/screen/window.h +++ b/fw/fe310/eos/eve/screen/window.h @@ -8,12 +8,14 @@ typedef struct EVEWindow { EVERect g; char *name; EVEView *view; + void *view_id; struct EVEWindowRoot *root; struct EVEWindow *parent; struct EVEWindow *next; struct EVEWindow *prev; struct EVEWindow *child_head; struct EVEWindow *child_tail; + int dirty; } EVEWindow; typedef struct EVEWindowKbd { @@ -28,7 +30,7 @@ typedef struct EVEWindowRoot { EVEFont *font; EVEWindowKbd *win_kbd; EVEWindow *win_scroll; - uint8_t tag0; + uint8_t tag_scroll; } EVEWindowRoot; void eve_window_init(EVEWindow *window, EVERect *g, EVEWindow *parent, char *name); @@ -36,8 +38,13 @@ void eve_window_init_root(EVEWindowRoot *root, EVERect *g, char *name, EVEFont * void eve_window_init_kbd(EVEWindowKbd *win_kbd, EVERect *g, EVEWindowRoot *root, char *name, EVEKbd *kbd); void eve_window_set_parent(EVEWindow *window, EVEWindow *parent); +void eve_window_attach_view(EVEWindow *window, EVEView *view, void *view_id); +void eve_window_detach_view(EVEWindow *window); +int eve_window_dirty(EVEWindow *window); +void eve_window_clean(EVEWindow *window); + int eve_window_visible(EVEWindow *window); -void eve_window_visible_g(EVEWindow *window, EVERect *g); +void eve_window_visible_g(EVEWindow *window, EVERect *rect); void eve_window_append(EVEWindow *window); void eve_window_insert_above(EVEWindow *window, EVEWindow *win_prev); @@ -46,15 +53,16 @@ void eve_window_remove(EVEWindow *window); EVEWindow *eve_window_search(EVEWindow *window, char *name); uint8_t eve_window_draw(EVEWindow *window, uint8_t tag0); -int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt, uint8_t tag0); +int eve_window_touch(EVEWindow *window, EVETouch *touch, uint16_t evt); void eve_window_root_draw(EVEWindowRoot *root); -void eve_window_root_touch(EVETouch *touch, uint16_t evt, uint8_t tag0, void *win); +void eve_window_root_touch(EVETouch *touch, uint16_t evt, void *win); EVEKbd *eve_window_kbd(EVEWindow *window); void eve_window_kbd_attach(EVEWindow *window); void eve_window_kbd_detach(EVEWindow *window); -EVEFont *eve_window_font(EVEWindow *window); -EVEWindow *eve_window_scroll(EVEWindowRoot *root, uint8_t *tag); +EVEWindow *eve_window_scroll(EVEWindow *window, uint8_t *tag); void eve_window_scroll_start(EVEWindow *window, uint8_t tag); void eve_window_scroll_stop(EVEWindow *window); + +EVEFont *eve_window_font(EVEWindow *window); diff --git a/fw/fe310/eos/eve/widget/freew.c b/fw/fe310/eos/eve/widget/freew.c index 11b8e50..f88f81e 100644 --- a/fw/fe310/eos/eve/widget/freew.c +++ b/fw/fe310/eos/eve/widget/freew.c @@ -10,22 +10,28 @@ #include "widget.h" -void eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc) { +int eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc) { EVEWidget *_widget = &widget->w; memset(widget, 0, sizeof(EVEFreeWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_FREE, g, page, eve_freew_draw, eve_freew_touch, putc); widget->_draw = draw; widget->_touch = touch; + + return EVE_OK; +} + +void eve_freew_set_uievt_handler(EVEFreeWidget *widget, eve_freew_uievt_t handler) { + widget->_uievt = handler; } int eve_freew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEFreeWidget *widget = (EVEFreeWidget *)_widget; EVEFreeSpec *tspec = &spec->tspec.free; + int rv; - eve_freew_init(widget, &spec->g, page, tspec->draw, tspec->touch, tspec->putc); - - return EVE_OK; + rv = eve_freew_init(widget, &spec->g, page, tspec->draw, tspec->touch, tspec->putc); + return rv; } uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0) { @@ -42,27 +48,53 @@ uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0) { int eve_freew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEFreeWidget *widget = (EVEFreeWidget *)_widget; - int ret; + int rv; + + /* widget received non-touch event */ + if (evt & EVE_TOUCH_ETYPE_EXT) { + evt &= ~EVE_TOUCH_ETYPE_EXT; + if (widget->_uievt) widget->_uievt(widget, evt); - ret = widget->_touch(widget, touch, evt); - return ret; + /* always return 0 for non-touch events */ + return 0; + } + + rv = widget->_touch(widget, touch, evt); + return rv; } -uint8_t eve_freew_tag(EVEFreeWidget *widget) { +uint8_t eve_freew_tag0(EVEFreeWidget *widget) { + EVEWidget *_widget = &widget->w; + + return _widget->tag0; +} + +void eve_freew_tag(EVEFreeWidget *widget, uint8_t tag_opt) { EVEWidget *_widget = &widget->w; - uint8_t ret = EVE_NOTAG; if (_widget->tagN != EVE_NOTAG) { - ret = _widget->tagN; - eve_cmd_dl(TAG(ret)); + eve_tag_set_opt(_widget->tagN, tag_opt); + eve_cmd_dl(TAG(_widget->tagN)); _widget->tagN++; } +} - return ret; +void eve_freew_tag_idx(EVEFreeWidget *widget, uint8_t i) { + EVEWidget *_widget = &widget->w; + uint8_t tag = _widget->tag0; + + if (tag != EVE_NOTAG) { + tag += i; + + /* prevents overflow */ + if ((tag >= _widget->tag0) && (tag < _widget->tagN)) { + eve_cmd_dl(TAG(tag)); + } + } } -uint8_t eve_widget_tag_index(EVEFreeWidget *widget, uint8_t tag) { +uint8_t eve_freew_get_tag_idx(EVEFreeWidget *widget, uint8_t tag) { EVEWidget *_widget = &widget->w; return tag - _widget->tag0; -}
\ No newline at end of file +} diff --git a/fw/fe310/eos/eve/widget/freew.h b/fw/fe310/eos/eve/widget/freew.h index cbcd08b..82038c4 100644 --- a/fw/fe310/eos/eve/widget/freew.h +++ b/fw/fe310/eos/eve/widget/freew.h @@ -5,11 +5,13 @@ struct EVEWidgetSpec; typedef void (*eve_freew_draw_t) (struct EVEFreeWidget *); typedef int (*eve_freew_touch_t) (struct EVEFreeWidget *, EVETouch *, uint16_t); +typedef void (*eve_freew_uievt_t) (struct EVEFreeWidget *, uint16_t); typedef struct EVEFreeWidget { EVEWidget w; eve_freew_draw_t _draw; eve_freew_touch_t _touch; + eve_freew_uievt_t _uievt; } EVEFreeWidget; typedef struct EVEFreeSpec { @@ -18,11 +20,14 @@ typedef struct EVEFreeSpec { eve_kbd_input_handler_t putc; } EVEFreeSpec; -void eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc); +int eve_freew_init(EVEFreeWidget *widget, EVERect *g, EVEPage *page, eve_freew_draw_t draw, eve_freew_touch_t touch, eve_kbd_input_handler_t putc); +void eve_freew_set_uievt_handler(EVEFreeWidget *widget, eve_freew_uievt_t handler); int eve_freew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_freew_draw(EVEWidget *_widget, uint8_t tag0); int eve_freew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt); -uint8_t eve_freew_tag(EVEFreeWidget *widget); -uint8_t eve_widget_tag_index(EVEFreeWidget *widget, uint8_t tag);
\ No newline at end of file +uint8_t eve_freew_tag0(EVEFreeWidget *widget); +void eve_freew_tag(EVEFreeWidget *widget, uint8_t tag_opt); +void eve_freew_tag_idx(EVEFreeWidget *widget, uint8_t i); +uint8_t eve_freew_get_tag_idx(EVEFreeWidget *widget, uint8_t tag); diff --git a/fw/fe310/eos/eve/widget/label.c b/fw/fe310/eos/eve/widget/label.c index 43c710c..d596677 100644 --- a/fw/fe310/eos/eve/widget/label.c +++ b/fw/fe310/eos/eve/widget/label.c @@ -10,26 +10,31 @@ #include "label.h" -void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) { +int eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title) { size_t title_len; int title_w, rv; - memset(label, 0, sizeof(EVELabel)); - if (g) label->g = *g; + if (font == NULL) return EVE_ERR; - rv = eve_font_verify(font, label->title, &title_w, &title_len); - if (rv) title[title_len] = '\0'; + rv = eve_font_verify(font, title, 0, &title_w, &title_len); + if (rv) return rv; + memset(label, 0, sizeof(EVELabel)); + if (g) label->g = *g; label->font = font; label->title = title; if (label->g.h == 0) label->g.h = eve_font_h(font); if (label->g.w == 0) label->g.w = title_w + EVE_LABEL_MARGIN; + + return EVE_OK; } -void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) { +int eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page) { EVEFont *font = spec->font ? spec->font : eve_window_font(page->v.window); + int rv; - eve_label_init(label, &spec->g, font, spec->title); + rv = eve_label_init(label, &spec->g, font, spec->title); + return rv; } void eve_label_draw(EVELabel *label) { diff --git a/fw/fe310/eos/eve/widget/label.h b/fw/fe310/eos/eve/widget/label.h index 9992f8c..f9c192b 100644 --- a/fw/fe310/eos/eve/widget/label.h +++ b/fw/fe310/eos/eve/widget/label.h @@ -15,7 +15,7 @@ typedef struct EVELabelSpec { int16_t margin; } EVELabelSpec; -void eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title); +int eve_label_init(EVELabel *label, EVERect *g, EVEFont *font, char *title); -void eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page); +int eve_label_create(EVELabel *label, EVELabelSpec *spec, EVEPage *page); void eve_label_draw(EVELabel *label);
\ No newline at end of file diff --git a/fw/fe310/eos/eve/widget/pagew.c b/fw/fe310/eos/eve/widget/pagew.c index 77e8f01..0ce4e82 100644 --- a/fw/fe310/eos/eve/widget/pagew.c +++ b/fw/fe310/eos/eve/widget/pagew.c @@ -10,8 +10,12 @@ #include "widget.h" -void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor) { +int eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor) { EVEWidget *_widget = &widget->w; + int title_w, rv; + + rv = eve_font_verify(font, title, 0, &title_w, NULL); + if (rv) return rv; memset(widget, 0, sizeof(EVEPageWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_PAGE, g, page, eve_pagew_draw, eve_pagew_touch, NULL); @@ -19,16 +23,19 @@ void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *f widget->title = title; widget->constructor = constructor; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); + if (_widget->g.w == 0) _widget->g.w = title_w; + + return EVE_OK; } int eve_pagew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEPageWidget *widget = (EVEPageWidget *)_widget; EVEPageSpec *tspec = &spec->tspec.page; EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); + int rv; - eve_pagew_init(widget, &spec->g, page, font, tspec->title, tspec->constructor); - - return EVE_OK; + rv = eve_pagew_init(widget, &spec->g, page, font, tspec->title, tspec->constructor); + return rv; } uint8_t eve_pagew_draw(EVEWidget *_widget, uint8_t tag0) { @@ -50,6 +57,9 @@ int eve_pagew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEPage *parent = _widget->page; EVEPageWidget *widget = (EVEPageWidget *)_widget; + /* widget received non-touch event, always return 0 */ + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; + if (evt & EVE_TOUCH_ETYPE_TAG_UP) { eve_page_open(parent, widget->constructor); return 1; diff --git a/fw/fe310/eos/eve/widget/pagew.h b/fw/fe310/eos/eve/widget/pagew.h index b1a91b2..9a1f1a1 100644 --- a/fw/fe310/eos/eve/widget/pagew.h +++ b/fw/fe310/eos/eve/widget/pagew.h @@ -15,7 +15,7 @@ typedef struct EVEPageSpec { eve_view_constructor_t constructor; } EVEPageSpec; -void eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor); +int eve_pagew_init(EVEPageWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *title, eve_view_constructor_t constructor); int eve_pagew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_pagew_draw(EVEWidget *_widget, uint8_t tag0); diff --git a/fw/fe310/eos/eve/widget/selectw.c b/fw/fe310/eos/eve/widget/selectw.c index f0dfed9..c0e2bfe 100644 --- a/fw/fe310/eos/eve/widget/selectw.c +++ b/fw/fe310/eos/eve/widget/selectw.c @@ -14,19 +14,26 @@ #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) -static int selectw_verify(utf8_t *option, uint16_t option_size) { +static int selectw_verify(utf8_t *option, uint16_t option_size, EVEFont *font, size_t *_o_len) { size_t o_len; uint16_t o_curr; int rv; o_curr = 0; while (o_curr < option_size) { - rv = utf8_verify(option + o_curr, option_size - o_curr, &o_len); - if (rv) return EVE_ERR; - if (o_len == 0) return EVE_OK; + rv = eve_font_verify(font, option + o_curr, option_size - o_curr, NULL, &o_len); + if (rv) { + if (_o_len) *_o_len = o_curr; + return rv; + } o_curr += o_len + 1; + if (o_len == 0) { + if (_o_len) *_o_len = o_curr; + return EVE_OK; + } } + if (_o_len) *_o_len = o_curr; return EVE_OK; } @@ -57,28 +64,32 @@ static void selectw_update_sz(EVESelectWidget *widget, int uievt) { if (uievt) eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE_G, _widget); } -void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) { +int eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi) { EVEWidget *_widget = &widget->w; int rv; + rv = selectw_verify(option, option_size, font, NULL); + if (rv) return rv; + memset(widget, 0, sizeof(EVESelectWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_SELECT, g, page, eve_selectw_draw, eve_selectw_touch, NULL); + widget->font = font; - rv = selectw_verify(option, option_size); - if (rv == EVE_OK) { - widget->option = option; - widget->option_size = option_size; - widget->option_count = selectw_count(widget); - selectw_update_sz(widget, 0); - } + widget->option = option; + widget->option_size = option_size; + widget->option_count = selectw_count(widget); + selectw_update_sz(widget, 0); + widget->multi = multi; widget->select = widget->multi ? 0 : SELECTW_NOSELECT; + + return EVE_OK; } int eve_selectw_update(EVESelectWidget *widget) { int rv, i; - rv = selectw_verify(widget->option, widget->option_size); + rv = selectw_verify(widget->option, widget->option_size, widget->font, NULL); if (rv) return rv; widget->option_count = selectw_count(widget); @@ -92,6 +103,7 @@ int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVESelectSpec *tspec = &spec->tspec.select; EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); utf8_t *option; + int rv; option = eve_malloc(tspec->option_size); if (option == NULL) { @@ -99,9 +111,8 @@ int eve_selectw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { } memset(option, 0, tspec->option_size); - eve_selectw_init(widget, &spec->g, page, font, option, tspec->option_size, tspec->multi); - - return EVE_OK; + rv = eve_selectw_init(widget, &spec->g, page, font, option, tspec->option_size, tspec->multi); + return rv; } void eve_selectw_destroy(EVEWidget *_widget) { @@ -172,6 +183,10 @@ uint8_t eve_selectw_draw(EVEWidget *_widget, uint8_t tag0) { int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVESelectWidget *widget = (EVESelectWidget *)_widget; + EVEPage *page = _widget->page; + + /* widget received non-touch event, always return 0 */ + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; if (evt & EVE_TOUCH_ETYPE_TAG_UP) { int i = touch->tag0 - _widget->tag0 + widget->line0; @@ -192,6 +207,8 @@ int eve_selectw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } } + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget); + return 1; } @@ -226,8 +243,8 @@ int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) { int o_curr; int rv, i; - rv = utf8_verify(option, strlen(option) + 1, NULL); - if (rv) return EVE_ERR; + rv = eve_font_verify(widget->font, option, 0, NULL, NULL); + if (rv) return rv; o_curr = 0; i = 0; @@ -252,10 +269,11 @@ int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option) { int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size) { int rv, i; - rv = selectw_verify(option, option_size); - if (rv) return rv; if (option_size > widget->option_size) return EVE_ERR_FULL; + rv = selectw_verify(option, option_size, widget->font, NULL); + if (rv) return rv; + memcpy(widget->option, option, option_size); memset(widget->option + option_size, 0, widget->option_size - option_size); @@ -264,3 +282,23 @@ int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t opt return EVE_OK; } + +void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size) { + size_t good_l, bad_l; + int rv; + + do { + rv = selectw_verify(option, option_size, widget->font, &good_l); + if (rv == EVE_OK) return; + + option += good_l; + option_size -= good_l; + + bad_l = strnlen(option, option_size); + if (bad_l != option_size) { + bad_l++; + } + memmove(option, option + bad_l, option_size - bad_l); + memset(option + option_size - bad_l, 0, bad_l); + } while (bad_l != option_size); +} diff --git a/fw/fe310/eos/eve/widget/selectw.h b/fw/fe310/eos/eve/widget/selectw.h index aa49866..185d787 100644 --- a/fw/fe310/eos/eve/widget/selectw.h +++ b/fw/fe310/eos/eve/widget/selectw.h @@ -19,7 +19,7 @@ typedef struct EVESelectSpec { uint8_t multi; } EVESelectSpec; -void eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi); +int eve_selectw_init(EVESelectWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *option, uint16_t option_size, uint8_t multi); int eve_selectw_update(EVESelectWidget *widget); int eve_selectw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); @@ -31,3 +31,4 @@ utf8_t *eve_selectw_option(EVESelectWidget *widget, int idx); utf8_t *eve_selectw_option_selected(EVESelectWidget *widget); int eve_selectw_add_option(EVESelectWidget *widget, utf8_t *option); int eve_selectw_set_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size); +void eve_selectw_fix_option(EVESelectWidget *widget, utf8_t *option, uint16_t option_size); diff --git a/fw/fe310/eos/eve/widget/spacerw.c b/fw/fe310/eos/eve/widget/spacerw.c index aa5bec1..f597a2d 100644 --- a/fw/fe310/eos/eve/widget/spacerw.c +++ b/fw/fe310/eos/eve/widget/spacerw.c @@ -10,15 +10,18 @@ #include "widget.h" -void eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page) { +int eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page) { memset(widget, 0, sizeof(EVEWidget)); eve_widget_init(widget, EVE_WIDGET_TYPE_SPACER, g, page, eve_spacerw_draw, eve_spacerw_touch, NULL); + + return EVE_OK; } int eve_spacerw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { - eve_spacerw_init(_widget, &spec->g, page); + int rv; - return EVE_OK; + rv = eve_spacerw_init(_widget, &spec->g, page); + return rv; } uint8_t eve_spacerw_draw(EVEWidget *_widget, uint8_t tag0) { diff --git a/fw/fe310/eos/eve/widget/spacerw.h b/fw/fe310/eos/eve/widget/spacerw.h index 621b45b..ae97479 100644 --- a/fw/fe310/eos/eve/widget/spacerw.h +++ b/fw/fe310/eos/eve/widget/spacerw.h @@ -2,7 +2,7 @@ struct EVEWidgetSpec; -void eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page); +int eve_spacerw_init(EVEWidget *widget, EVERect *g, EVEPage *page); int eve_spacerw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_spacerw_draw(EVEWidget *_widget, uint8_t tag0); diff --git a/fw/fe310/eos/eve/widget/strw.c b/fw/fe310/eos/eve/widget/strw.c index 6a2692b..847de49 100644 --- a/fw/fe310/eos/eve/widget/strw.c +++ b/fw/fe310/eos/eve/widget/strw.c @@ -12,7 +12,7 @@ #include "widget.h" -#define STRW_TOUCH_OPT EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_X | EVE_TOUCH_OPT_TRACK_EXT_X | EVE_TOUCH_OPT_LPRESS +#define STRW_TOUCH_OPT EVE_TOUCH_OPT_TRACK_X | EVE_TOUCH_OPT_TRACK_EXT_X | EVE_TOUCH_OPT_LPRESS #define STRW_TMODE_NONE 0 #define STRW_TMODE_CRSR 1 @@ -27,37 +27,33 @@ #define CHAR_VALID_INPUT(c) ((c >= 0x20) && (c < 0x7f)) -void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) { +int eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size) { EVEWidget *_widget = &widget->w; size_t str_len; int str_w, rv; + rv = eve_font_verify(font, str, str_size, &str_w, &str_len); + if (rv) return rv; + memset(widget, 0, sizeof(EVEStrWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_STR, g, page, eve_strw_draw, eve_strw_touch, eve_strw_putc); - rv = utf8_verify(str, str_size, &str_len); - if (rv) str[str_len] = '\0'; - - rv = eve_font_verify(font, str, &str_w, &str_len); - if (rv) str[str_len] = '\0'; - widget->font = font; widget->str = str; widget->str_size = str_size; widget->str_len = str_len; widget->str_g.w = str_w; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); + + return EVE_OK; } int eve_strw_update(EVEStrWidget *widget) { size_t str_len; int str_w, rv; - rv = utf8_verify(widget->str, widget->str_size, &str_len); - if (rv) widget->str[str_len] = '\0'; - - rv = eve_font_verify(widget->font, widget->str, &str_w, &str_len); - if (rv) widget->str[str_len] = '\0'; + rv = eve_font_verify(widget->font, widget->str, widget->str_size, &str_w, &str_len); + if (rv) return rv; widget->str_len = str_len; widget->str_g.w = str_w; @@ -71,14 +67,15 @@ int eve_strw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); utf8_t *str; uint16_t *line; + int rv; str = eve_malloc(tspec->str_size); if (str == NULL) return EVE_ERR_NOMEM; str[0] = '\0'; - eve_strw_init(widget, &spec->g, page, font, str, tspec->str_size); - - return EVE_OK; + rv = eve_strw_init(widget, &spec->g, page, font, str, tspec->str_size); + if (rv) eve_free(str); + return rv; } void eve_strw_destroy(EVEWidget *_widget) { @@ -87,15 +84,20 @@ void eve_strw_destroy(EVEWidget *_widget) { eve_free(widget->str); } -static void show_rect(EVEStrWidget *widget) { +static void show_text(EVEStrWidget *widget, EVEStrCursor *cursor, int del_w) { EVEWidget *_widget = &widget->w; - EVERect focus; + int w0 = widget->font->w; + int w1 = _widget->g.w - widget->font->w; - focus.x = _widget->g.x; - focus.y = _widget->g.y; - focus.w = _widget->g.w; - focus.h = 2 * widget->font->h; - eve_page_show_rect(_widget->page, &focus); + if (del_w && (widget->str_g.w - widget->str_g.x < w1)) { + widget->str_g.x = (widget->str_g.x > del_w ? widget->str_g.x - del_w : 0); + } + if (cursor->x - widget->str_g.x < w0) { + widget->str_g.x = (cursor->x > w0 ? cursor->x - w0 : 0); + } + if (cursor->x - widget->str_g.x > w1) { + widget->str_g.x = cursor->x - w1; + } } static EVEStrCursor *cursor_prox(EVEStrWidget *widget, EVEStrCursor *cursor, EVETouch *touch, short *dx) { @@ -156,7 +158,7 @@ uint8_t eve_strw_draw(EVEWidget *_widget, uint8_t tag0) { _widget->tag0 = tag0; if (tag0 != EVE_NOTAG) { eve_cmd_dl(TAG(tag0)); - eve_touch_set_opt(tag0, STRW_TOUCH_OPT); + eve_tag_set_opt(tag0, STRW_TOUCH_OPT); tag0++; } _widget->tagN = tag0; @@ -228,7 +230,22 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEPage *page = _widget->page; EVEStrCursor *t_cursor = NULL; short dx; - int ret = 0; + int rv = 0; + + /* widget received non-touch event */ + if (evt & EVE_TOUCH_ETYPE_EXT) { + evt &= ~EVE_TOUCH_ETYPE_EXT; + switch (evt) { + case EVE_UIEVT_WIDGET_FOCUS_OUT: { + if (widget->cursor1.on) eve_strw_cursor_clear(widget, &widget->cursor1); + if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2); + break; + } + } + + /* always return 0 for non-touch events */ + return 0; + } if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TRACK_START)) { if (widget->cursor2.on) { @@ -266,10 +283,11 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { case STRW_TMODE_CRSR: eve_strw_cursor_set(widget, widget->track.cursor, eve_page_x(page, touch->x) + widget->track.dx); + show_text(widget, widget->track.cursor, 0); break; } } - ret = 1; + rv = 1; } else { if (evt & EVE_TOUCH_ETYPE_LPRESS) { if (widget->cursor2.on) { @@ -283,13 +301,12 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } else { // select } - ret = 1; + rv = 1; } - if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { + if ((evt & EVE_TOUCH_ETYPE_POINT_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { eve_strw_cursor_set(widget, &widget->cursor1, eve_page_x(page, touch->x0)); if (widget->cursor2.on) eve_strw_cursor_clear(widget, &widget->cursor2); - show_rect(widget); - ret = 1; + rv = 1; } } @@ -299,7 +316,7 @@ int eve_strw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { widget->track.dx = 0; } - return ret; + return rv; } void eve_strw_putc(void *w, int c) { @@ -309,19 +326,18 @@ void eve_strw_putc(void *w, int c) { EVEStrCursor *cursor2 = &widget->cursor2; utf8_t *str; utf8_t *clipb = NULL; - int w0 = widget->font->w; - int w1 = _widget->g.w - widget->font->w; int ins_c = 0, del_c = 0; int ins_w = 0, del_w = 0; - if (c == EVE_PAGE_KBDCH_CLOSE) { - if (cursor1->on) eve_strw_cursor_clear(widget, cursor1); - if (cursor2->on) eve_strw_cursor_clear(widget, cursor2); + if (!cursor1->on) return; + + if (c == '\n') { + EVEPage *page = _widget->page; + + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget); return; } - if (!cursor1->on) return; - if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) { ucp_t uc; @@ -349,10 +365,6 @@ void eve_strw_putc(void *w, int c) { } break; } - if (widget->str_g.w - widget->str_g.x < w1) { - widget->str_g.x -= del_w; - if (widget->str_g.x < 0) widget->str_g.x = 0; - } } else { EVEStrCursor *c1 = cursor1; EVEStrCursor *c2 = cursor1; @@ -387,9 +399,8 @@ void eve_strw_putc(void *w, int c) { clipb = eve_clipb_get(); if (clipb) { - rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len); - if (!rv) ins_w = eve_font_str_w(widget->font, clipb); - if (rv || (ins_w < 0)) { + rv = eve_font_verify(widget->font, clipb, EVE_CLIPB_SIZE_BUF, &ins_w, &clipb_len); + if (rv) { clipb = NULL; clipb_len = 0; ins_w = 0; @@ -419,8 +430,7 @@ void eve_strw_putc(void *w, int c) { if (cursor2->on) eve_strw_cursor_clear(widget, cursor2); } - if (cursor1->x - widget->str_g.x < w0) widget->str_g.x = cursor1->x > w0 ? cursor1->x - w0 : 0; - if (cursor1->x - widget->str_g.x > w1) widget->str_g.x = cursor1->x - w1; + show_text(widget, cursor1, del_w); } void eve_strw_cursor_set(EVEStrWidget *widget, EVEStrCursor *cursor, int16_t x) { diff --git a/fw/fe310/eos/eve/widget/strw.h b/fw/fe310/eos/eve/widget/strw.h index acfd74b..a2817d0 100644 --- a/fw/fe310/eos/eve/widget/strw.h +++ b/fw/fe310/eos/eve/widget/strw.h @@ -33,7 +33,7 @@ typedef struct EVEStrSpec { uint16_t str_size; } EVEStrSpec; -void eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size); +int eve_strw_init(EVEStrWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *str, uint16_t str_size); int eve_strw_update(EVEStrWidget *widget); int eve_strw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); diff --git a/fw/fe310/eos/eve/widget/textw.c b/fw/fe310/eos/eve/widget/textw.c index 7998e75..0a6a700 100644 --- a/fw/fe310/eos/eve/widget/textw.c +++ b/fw/fe310/eos/eve/widget/textw.c @@ -12,7 +12,7 @@ #include "widget.h" -#define TEXTW_TOUCH_OPT EVE_TOUCH_OPT_TRACK | EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_XY | EVE_TOUCH_OPT_LPRESS +#define TEXTW_TOUCH_OPT EVE_TOUCH_OPT_TRACK_XY | EVE_TOUCH_OPT_TRACK_EXT_XY | EVE_TOUCH_OPT_LPRESS #define CH_BS 0x08 #define CH_DEL 0x7f @@ -30,20 +30,17 @@ #define DIVC(x,y) ((x) / (y) + ((x) % (y) != 0)) -void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size) { +int eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size) { EVEWidget *_widget = &widget->w; size_t text_len; int rv; + rv = eve_font_verify(font, text, text_size, NULL, &text_len); + if (rv) return rv; + memset(widget, 0, sizeof(EVETextWidget)); eve_widget_init(_widget, EVE_WIDGET_TYPE_TEXT, g, page, eve_textw_draw, eve_textw_touch, eve_textw_putc); - rv = utf8_verify(text, text_size, &text_len); - if (rv) text[text_len] = '\0'; - - rv = eve_font_verify(font, text, NULL, &text_len); - if (rv) text[text_len] = '\0'; - widget->font = font; widget->text = text; widget->text_size = text_size; @@ -52,17 +49,16 @@ void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *f widget->line_size = line_size; memset(widget->line, 0xff, line_size * sizeof(uint16_t)); eve_textw_text_update(widget, 0, 0); + + return EVE_OK; } int eve_textw_update(EVETextWidget *widget) { size_t text_len; int rv; - rv = utf8_verify(widget->text, widget->text_size, &text_len); - if (rv) widget->text[text_len] = '\0'; - - rv = eve_font_verify(widget->font, widget->text, NULL, &text_len); - if (rv) widget->text[text_len] = '\0'; + rv = eve_font_verify(widget->font, widget->text, widget->text_size, NULL, &text_len); + if (rv) return rv; widget->text_len = text_len; memset(widget->line, 0xff, widget->line_size * sizeof(uint16_t)); @@ -77,6 +73,7 @@ int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); utf8_t *text; uint16_t *line; + int rv; text = eve_malloc(tspec->text_size); if (text == NULL) { @@ -89,9 +86,12 @@ int eve_textw_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { return EVE_ERR_NOMEM; } - eve_textw_init(widget, &spec->g, page, font, text, tspec->text_size, line, tspec->line_size); - - return EVE_OK; + rv = eve_textw_init(widget, &spec->g, page, font, text, tspec->text_size, line, tspec->line_size); + if (rv) { + eve_free(line); + eve_free(text); + } + return rv; } void eve_textw_destroy(EVEWidget *_widget) { @@ -214,7 +214,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) { for (i=line0; i<lineN; i++) { if (_widget->tagN != EVE_NOTAG) { eve_cmd_dl(TAG(_widget->tagN)); - eve_touch_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); + eve_tag_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); _widget->tagN++; } if (!s && c1 && (c1->line == i)) { @@ -257,7 +257,7 @@ uint8_t eve_textw_draw(EVEWidget *_widget, uint8_t tag0) { if (lineNvisible) { if (_widget->tagN != EVE_NOTAG) { eve_cmd_dl(TAG(_widget->tagN)); - eve_touch_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); + eve_tag_set_opt(_widget->tagN, TEXTW_TOUCH_OPT); _widget->tagN++; } draw_line(widget, lineN, 0, 0, 0, _widget->g.w, 0); @@ -276,7 +276,27 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEPage *page = _widget->page; EVETextCursor *t_cursor = NULL; short dx, dl; - int ret = 0; + int rv = 0; + + /* widget received non-touch event */ + if (evt & EVE_TOUCH_ETYPE_EXT) { + evt &= ~EVE_TOUCH_ETYPE_EXT; + switch (evt) { + case EVE_UIEVT_WIDGET_FOCUS_IN: { + if (widget->cursor1.on) show_rect(widget, &widget->cursor1); + break; + } + + case EVE_UIEVT_WIDGET_FOCUS_OUT: { + if (widget->cursor1.on) eve_textw_cursor_clear(widget, &widget->cursor1); + if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2); + break; + } + } + + /* always return 0 for non-touch events */ + return 0; + } if (evt & (EVE_TOUCH_ETYPE_LPRESS | EVE_TOUCH_ETYPE_TRACK_START)) { if (widget->cursor2.on) { @@ -294,7 +314,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { if (widget->track.cursor) { if (evt & EVE_TOUCH_ETYPE_TRACK) eve_textw_cursor_set(widget, widget->track.cursor, touch->tag + widget->track.dl, eve_page_x(page, touch->x) + widget->track.dx); - ret = 1; + rv = 1; } else { if (evt & EVE_TOUCH_ETYPE_LPRESS) { if (widget->cursor2.on) { @@ -308,13 +328,12 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { } else { // select } - ret = 1; + rv = 1; } - if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { + if ((evt & EVE_TOUCH_ETYPE_TAG_UP) && !(touch->eevt & (EVE_TOUCH_EETYPE_TRACK_XY | EVE_TOUCH_EETYPE_TRACK_ABORT | EVE_TOUCH_EETYPE_LPRESS))) { eve_textw_cursor_set(widget, &widget->cursor1, touch->tag_up, eve_page_x(page, touch->x0)); if (widget->cursor2.on) eve_textw_cursor_clear(widget, &widget->cursor2); - show_rect(widget, &widget->cursor1); - ret = 1; + rv = 1; } } @@ -324,7 +343,7 @@ int eve_textw_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { widget->track.dl = 0; } - return ret; + return rv; } void eve_textw_putc(void *w, int c) { @@ -334,16 +353,10 @@ void eve_textw_putc(void *w, int c) { EVETextCursor *cursor2 = &widget->cursor2; utf8_t *text; utf8_t *clipb = NULL; - int i, r; + int i, line; int ins_c = 0, del_c = 0; int ch_w = 0; - if (c == EVE_PAGE_KBDCH_CLOSE) { - if (cursor1->on) eve_textw_cursor_clear(widget, cursor1); - if (cursor2->on) eve_textw_cursor_clear(widget, cursor2); - return; - } - if (!cursor1->on) return; if (!cursor2->on && ((c == CH_BS) || (c == CH_DEL))) { @@ -401,9 +414,8 @@ void eve_textw_putc(void *w, int c) { clipb = eve_clipb_get(); if (clipb) { - rv = utf8_verify(clipb, EVE_CLIPB_SIZE_BUF, &clipb_len); - if (!rv) ch_w = eve_font_str_w(widget->font, clipb); - if (rv || (ch_w < 0)) { + rv = eve_font_verify(widget->font, clipb, EVE_CLIPB_SIZE_BUF, &ch_w, &clipb_len); + if (rv) { clipb = NULL; clipb_len = 0; ch_w = 0; @@ -437,9 +449,9 @@ void eve_textw_putc(void *w, int c) { widget->line[i] += ins_c - del_c; } - r = cursor1->line; - if (cursor1->line) r = eve_textw_text_update(widget, cursor1->line - 1, 1); - if (r == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1); + line = cursor1->line; + if (cursor1->line) line = eve_textw_text_update(widget, cursor1->line - 1, 1); + if (line == cursor1->line) eve_textw_text_update(widget, cursor1->line, 1); if (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) { while (cursor1->line && (cursor1->ch < LINE_START(widget, cursor1->line))) cursor1->line--; @@ -449,7 +461,7 @@ void eve_textw_putc(void *w, int c) { while ((cursor1->line != widget->line_len - 1) && (cursor1->ch > LINE_END(widget, cursor1->line))) cursor1->line++; eve_textw_cursor_update(widget, cursor1); show_rect(widget, cursor1); - } else if ((cursor1->line) && (r != cursor1->line)) { + } else if ((cursor1->line) && (line != cursor1->line)) { eve_textw_cursor_update(widget, cursor1); } else { cursor1->x += ch_w; diff --git a/fw/fe310/eos/eve/widget/textw.h b/fw/fe310/eos/eve/widget/textw.h index 0fb3505..d3d544b 100644 --- a/fw/fe310/eos/eve/widget/textw.h +++ b/fw/fe310/eos/eve/widget/textw.h @@ -34,7 +34,7 @@ typedef struct EVETextSpec { uint16_t line_size; } EVETextSpec; -void eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size); +int eve_textw_init(EVETextWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, utf8_t *text, uint16_t text_size, uint16_t *line, uint16_t line_size); int eve_textw_update(EVETextWidget *widget); int eve_textw_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); diff --git a/fw/fe310/eos/eve/widget/togglew.c b/fw/fe310/eos/eve/widget/togglew.c index c68e191..06d5fc3 100644 --- a/fw/fe310/eos/eve/widget/togglew.c +++ b/fw/fe310/eos/eve/widget/togglew.c @@ -10,7 +10,7 @@ #include "widget.h" -void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels) { +int eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels) { EVEWidget *_widget = &widget->w; memset(widget, 0, sizeof(EVEToggleWidget)); @@ -18,16 +18,18 @@ void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFon widget->font = font; widget->labels = labels; if (_widget->g.h == 0) _widget->g.h = eve_font_h(widget->font); + + return EVE_OK; } int eve_togglew_create(EVEWidget *_widget, EVEWidgetSpec *spec, EVEPage *page) { EVEToggleWidget *widget = (EVEToggleWidget *)_widget; EVEToggleSpec *tspec = &spec->tspec.toggle; EVEFont *font = tspec->font ? tspec->font : eve_window_font(page->v.window); + int rv; - eve_togglew_init(widget, &spec->g, page, font, tspec->labels); - - return EVE_OK; + rv = eve_togglew_init(widget, &spec->g, page, font, tspec->labels); + return rv; } uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0) { @@ -46,23 +48,30 @@ uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0) { int eve_togglew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt) { EVEToggleWidget *widget = (EVEToggleWidget *)_widget; + EVEPage *page = _widget->page; + + /* widget received non-touch event, always return 0 */ + if (evt & EVE_TOUCH_ETYPE_EXT) return 0; if (evt & EVE_TOUCH_ETYPE_TAG_UP) { widget->state = !widget->state; + + eve_view_uievt_push(&page->v, EVE_UIEVT_WIDGET_UPDATE, _widget); + return 1; } return 0; } +uint8_t eve_togglew_get(EVEToggleWidget *widget) { + return widget->state; +} + void eve_togglew_set(EVEToggleWidget *widget) { widget->state = 1; } -void eve_togglew_clr(EVEToggleWidget *widget) { +void eve_togglew_clear(EVEToggleWidget *widget) { widget->state = 0; } - -uint8_t eve_togglew_get(EVEToggleWidget *widget) { - return widget->state; -}
\ No newline at end of file diff --git a/fw/fe310/eos/eve/widget/togglew.h b/fw/fe310/eos/eve/widget/togglew.h index aa5485d..af37672 100644 --- a/fw/fe310/eos/eve/widget/togglew.h +++ b/fw/fe310/eos/eve/widget/togglew.h @@ -17,12 +17,12 @@ typedef struct EVEToggleSpec { uint8_t state; } EVEToggleSpec; -void eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels); +int eve_togglew_init(EVEToggleWidget *widget, EVERect *g, EVEPage *page, EVEFont *font, char *labels); int eve_togglew_create(EVEWidget *_widget, struct EVEWidgetSpec *spec, EVEPage *page); uint8_t eve_togglew_draw(EVEWidget *_widget, uint8_t tag0); int eve_togglew_touch(EVEWidget *_widget, EVETouch *touch, uint16_t evt); +uint8_t eve_togglew_get(EVEToggleWidget *widget); void eve_togglew_set(EVEToggleWidget *widget); -void eve_togglew_clr(EVEToggleWidget *widget); -uint8_t eve_togglew_get(EVEToggleWidget *widget);
\ No newline at end of file +void eve_togglew_clear(EVEToggleWidget *widget); diff --git a/fw/fe310/eos/eve/widget/widget.c b/fw/fe310/eos/eve/widget/widget.c index 88b90a9..8b0a2e4 100644 --- a/fw/fe310/eos/eve/widget/widget.c +++ b/fw/fe310/eos/eve/widget/widget.c @@ -49,16 +49,10 @@ void eve_widget_destroy(EVEWidget *widget) { if (_eve_widget_destroy[widget->type]) _eve_widget_destroy[widget->type](widget); } -void eve_widget_set_focus(EVEWidget *widget) { - EVEPage *page = widget->page; - - eve_page_set_focus(page, widget); -} - void eve_widget_set_flags(EVEWidget *widget, uint8_t flags) { widget->flags |= flags; } -void eve_widget_clr_flags(EVEWidget *widget, uint8_t flags) { +void eve_widget_clear_flags(EVEWidget *widget, uint8_t flags) { widget->flags &= ~flags; } diff --git a/fw/fe310/eos/eve/widget/widget.h b/fw/fe310/eos/eve/widget/widget.h index a565b53..e7ab2f2 100644 --- a/fw/fe310/eos/eve/widget/widget.h +++ b/fw/fe310/eos/eve/widget/widget.h @@ -45,6 +45,5 @@ size_t eve_widget_size(uint8_t type); void eve_widget_set_label(EVEWidget *widget, EVELabel *label); EVEWidget *eve_widget_next(EVEWidget *widget); -void eve_widget_set_focus(EVEWidget *widget); void eve_widget_set_flags(EVEWidget *widget, uint8_t flags); -void eve_widget_clr_flags(EVEWidget *widget, uint8_t flags);
\ No newline at end of file +void eve_widget_clear_flags(EVEWidget *widget, uint8_t flags);
\ No newline at end of file diff --git a/fw/fe310/eos/event.c b/fw/fe310/eos/event.c index f76384a..b21e5ea 100644 --- a/fw/fe310/eos/event.c +++ b/fw/fe310/eos/event.c @@ -1,69 +1,110 @@ #include <stdlib.h> #include <stdint.h> #include <unistd.h> -#include <stdio.h> #include "encoding.h" #include "platform.h" #include "eos.h" +#include "log.h" #include "msgq.h" #include "event.h" EOSMsgQ _eos_event_q; static EOSMsgItem event_q_array[EOS_EVT_SIZE_Q]; -static eos_evt_handler_t evt_handler[EOS_EVT_MAX_EVT + 1]; +static eos_evt_handler_t evt_handler[EOS_EVT_MAX]; +static eos_evt_handler_global_t evt_handler_global; +static eos_evt_loopf_t evt_loop_f; -static void evtq_handler(unsigned char type, unsigned char *buffer, uint16_t len) { +static void evtq_handler(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t _idx) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx && (idx <= EOS_EVT_MAX_EVT)) { - evt_handler[idx](type, buffer, len); + if (idx && (idx <= EOS_EVT_MAX)) { + evt_handler[idx - 1](type, buffer, len); } else { eos_evtq_bad_handler(type, buffer, len); } } -int eos_evtq_init(uint8_t wakeup_cause) { +int eos_evtq_init(void) { int i; - evt_handler[0] = evtq_handler; - for (i=0; i<EOS_EVT_MAX_EVT; i++) { - evt_handler[i + 1] = eos_evtq_bad_handler; + evt_handler_global = evtq_handler; + for (i=0; i<EOS_EVT_MAX; i++) { + evt_handler[i] = eos_evtq_bad_handler; } eos_msgq_init(&_eos_event_q, event_q_array, EOS_EVT_SIZE_Q); return EOS_OK; } +int eos_evtq_len(void) { + int rv; + + clear_csr(mstatus, MSTATUS_MIE); + rv = eos_msgq_len(&_eos_event_q); + set_csr(mstatus, MSTATUS_MIE); + + return rv; +} + int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len) { + int rv; + + clear_csr(mstatus, MSTATUS_MIE); + rv = eos_msgq_push(&_eos_event_q, type, buffer, len); + set_csr(mstatus, MSTATUS_MIE); + + return rv; +} + +int eos_evtq_push_widx(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx) { + int rv; + clear_csr(mstatus, MSTATUS_MIE); - int ret = eos_msgq_push(&_eos_event_q, type, buffer, len); + rv = eos_msgq_push_widx(&_eos_event_q, type, buffer, len, idx); set_csr(mstatus, MSTATUS_MIE); - return ret; + + return rv; } int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len) { return eos_msgq_push(&_eos_event_q, type, buffer, len); } +int eos_evtq_push_widx_isr(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx) { + return eos_msgq_push_widx(&_eos_event_q, type, buffer, len, idx); +} + void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len) { clear_csr(mstatus, MSTATUS_MIE); eos_msgq_pop(&_eos_event_q, type, buffer, len); set_csr(mstatus, MSTATUS_MIE); } +void eos_evtq_pop_widx(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) { + clear_csr(mstatus, MSTATUS_MIE); + eos_msgq_pop_widx(&_eos_event_q, type, buffer, len, idx); + set_csr(mstatus, MSTATUS_MIE); +} + void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len) { eos_msgq_pop(&_eos_event_q, type, buffer, len); } +void eos_evtq_pop_widx_isr(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) { + eos_msgq_pop_widx(&_eos_event_q, type, buffer, len, idx); +} + int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len) { int rv = 0; clear_csr(mstatus, MSTATUS_MIE); rv = eos_msgq_find(&_eos_event_q, type, NULL, 0, buffer, len); set_csr(mstatus, MSTATUS_MIE); + + return rv; } int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { @@ -72,23 +113,30 @@ int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, clear_csr(mstatus, MSTATUS_MIE); rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); set_csr(mstatus, MSTATUS_MIE); + + return rv; } -void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { +int eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len) { int rv = 0; while(!rv) { clear_csr(mstatus, MSTATUS_MIE); rv = eos_msgq_find(&_eos_event_q, type, selector, sel_len, buffer, len); - if (!rv) { + if (rv && (rv != EOS_ERR_NOTFOUND)) { + set_csr(mstatus, MSTATUS_MIE); + return rv; + } + if (rv) { unsigned char _type; unsigned char *_buffer; uint16_t _len; + uint8_t idx; - eos_msgq_pop(&_eos_event_q, &_type, &_buffer, &_len); + eos_msgq_pop_widx(&_eos_event_q, &_type, &_buffer, &_len, &idx); if (_type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](_type, _buffer, _len); + evt_handler_global(_type, _buffer, _len, idx); } else { asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); @@ -109,12 +157,13 @@ void eos_evtq_flush_isr(void) { unsigned char type; unsigned char *buffer; uint16_t len; + uint8_t idx; do { - eos_msgq_pop(&_eos_event_q, &type, &buffer, &len); + eos_msgq_pop_widx(&_eos_event_q, &type, &buffer, &len, &idx); if (type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](type, buffer, len); + evt_handler_global(type, buffer, len, idx); clear_csr(mstatus, MSTATUS_MIE); } } while (type); @@ -125,6 +174,7 @@ void eos_evtq_loop(void) { while(foo) { eos_evtq_exec(); + if (evt_loop_f) evt_loop_f(); } } @@ -132,33 +182,46 @@ void eos_evtq_exec(void) { unsigned char type; unsigned char *buffer; uint16_t len; + uint8_t idx; clear_csr(mstatus, MSTATUS_MIE); - eos_msgq_pop(&_eos_event_q, &type, &buffer, &len); + eos_msgq_pop_widx(&_eos_event_q, &type, &buffer, &len, &idx); if (type) { set_csr(mstatus, MSTATUS_MIE); - evt_handler[0](type, buffer, len); + evt_handler_global(type, buffer, len, idx); } else { asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); } +} +void eos_evtq_set_loopf(eos_evt_loopf_t loop_f) { + evt_loop_f = loop_f; } + void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len) { - printf("EVT BAD HANDLER:0x%x\n", type); + EOS_LOG(EOS_LOG_ERR, "EVT BAD HANDLER:0x%.2X\n", type); } void eos_evtq_set_handler(unsigned char type, eos_evt_handler_t handler) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; if (handler == NULL) handler = eos_evtq_bad_handler; - if (idx <= EOS_EVT_MAX_EVT) evt_handler[idx] = handler; + if (idx && (idx <= EOS_EVT_MAX)) evt_handler[idx - 1] = handler; } eos_evt_handler_t eos_evtq_get_handler(unsigned char type) { unsigned char idx = (type & EOS_EVT_MASK) >> 4; - if (idx <= EOS_EVT_MAX_EVT) return evt_handler[idx]; + if (idx && (idx <= EOS_EVT_MAX)) return evt_handler[idx - 1]; return NULL; } + +void eos_evtq_set_handler_global(eos_evt_handler_global_t handler) { + evt_handler_global = handler; +} + +eos_evt_handler_global_t eos_evtq_get_handler_global(void) { + return evt_handler_global; +} diff --git a/fw/fe310/eos/event.h b/fw/fe310/eos/event.h index 9501a15..bdc1af1 100644 --- a/fw/fe310/eos/event.h +++ b/fw/fe310/eos/event.h @@ -3,20 +3,35 @@ #include "evt_def.h" typedef void (*eos_evt_handler_t) (unsigned char, unsigned char *, uint16_t); +typedef void (*eos_evt_handler_global_t) (unsigned char, unsigned char *, uint16_t, uint8_t); + +typedef void (*eos_evt_loopf_t) (void); + +int eos_evtq_init(void); +int eos_evtq_len(void); -int eos_evtq_init(uint8_t wakeup_cause); int eos_evtq_push(unsigned char type, unsigned char *buffer, uint16_t len); +int eos_evtq_push_widx(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx); int eos_evtq_push_isr(unsigned char type, unsigned char *buffer, uint16_t len); +int eos_evtq_push_widx_isr(unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *idx); + void eos_evtq_pop(unsigned char *type, unsigned char **buffer, uint16_t *len); +void eos_evtq_pop_widx(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx) ; void eos_evtq_pop_isr(unsigned char *type, unsigned char **buffer, uint16_t *len); +void eos_evtq_pop_widx_isr(unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *idx); + int eos_evtq_get(unsigned char type, unsigned char **buffer, uint16_t *len); int eos_evtq_find(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); -void eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); +int eos_evtq_wait(unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); + void eos_evtq_flush(void); void eos_evtq_flush_isr(void); void eos_evtq_loop(void); void eos_evtq_exec(void); +void eos_evtq_set_loopf(eos_evt_loopf_t loop_f); void eos_evtq_bad_handler(unsigned char type, unsigned char *buffer, uint16_t len); void eos_evtq_set_handler(unsigned char type, eos_evt_handler_t handler); eos_evt_handler_t eos_evtq_get_handler(unsigned char type); +void eos_evtq_set_handler_global(eos_evt_handler_global_t handler); +eos_evt_handler_global_t eos_evtq_get_handler_global(void); diff --git a/fw/fe310/eos/evt_def.h b/fw/fe310/eos/evt_def.h index e34b2d2..0105457 100644 --- a/fw/fe310/eos/evt_def.h +++ b/fw/fe310/eos/evt_def.h @@ -3,11 +3,11 @@ #define EOS_EVT_NET 0x30 #define EOS_EVT_SPI 0x40 #define EOS_EVT_UART 0x50 -#define EOS_EVT_EVE 0x60 -#define EOS_EVT_CTP 0x70 -#define EOS_EVT_USER 0x80 +#define EOS_EVT_EGPIO 0x60 +#define EOS_EVT_USER 0x70 +#define EOS_EVT_USER1 0x80 -#define EOS_EVT_MAX_EVT 8 +#define EOS_EVT_MAX 8 #define EOS_EVT_MASK 0xF0 #define EOS_EVT_SIZE_Q 4 diff --git a/fw/fe310/eos/irq_def.h b/fw/fe310/eos/irq_def.h index fc16489..62a2b90 100644 --- a/fw/fe310/eos/irq_def.h +++ b/fw/fe310/eos/irq_def.h @@ -1,8 +1,7 @@ -#define IRQ_PRIORITY_I2S_SD 7 - -#define IRQ_PRIORITY_EVE 5 -#define IRQ_PRIORITY_CTP 5 +#define IRQ_PRIORITY_I2S 7 +#define IRQ_PRIORITY_CTP 6 +#define IRQ_PRIORITY_EGPIO 5 #define IRQ_PRIORITY_SPI_XCHG 5 #define IRQ_PRIORITY_NET_CTS 4 diff --git a/fw/fe310/eos/log.h b/fw/fe310/eos/log.h new file mode 100644 index 0000000..be9b024 --- /dev/null +++ b/fw/fe310/eos/log.h @@ -0,0 +1,15 @@ +#include <stdio.h> + +#define EOS_LOG_DEBUG 1 +#define EOS_LOG_INFO 2 +#define EOS_LOG_ERR 3 + +#define EOS_LOG_NONE 255 + +#ifdef EOS_DEBUG +#define EOS_LOG_LEVEL EOS_LOG_DEBUG +#else +#define EOS_LOG_LEVEL EOS_LOG_NONE +#endif + +#define EOS_LOG(l, ...) ((l) >= EOS_LOG_LEVEL ? printf(__VA_ARGS__) : 0 ) diff --git a/fw/fe310/eos/msgq.c b/fw/fe310/eos/msgq.c index a483a58..2af3b14 100644 --- a/fw/fe310/eos/msgq.c +++ b/fw/fe310/eos/msgq.c @@ -17,7 +17,15 @@ void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size) { msgq->array = array; } +uint8_t eos_msgq_len(EOSMsgQ *msgq) { + return (uint8_t)(msgq->idx_w - msgq->idx_r); +} + int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len) { + return eos_msgq_push_widx(msgq, type, buffer, len, NULL); +} + +int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *_idx) { if ((uint8_t)(msgq->idx_w - msgq->idx_r) == msgq->size) return EOS_ERR_FULL; uint8_t idx = IDX_MASK(msgq->idx_w, msgq->size); @@ -25,10 +33,15 @@ int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint msgq->array[idx].buffer = buffer; msgq->array[idx].len = len; msgq->idx_w++; + if (_idx) *_idx = idx; return EOS_OK; } void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len) { + eos_msgq_pop_widx(msgq, type, buffer, len, NULL); +} + +void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *_idx) { if (msgq->idx_r == msgq->idx_w) { *type = 0; *buffer = NULL; @@ -39,6 +52,7 @@ void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, ui *buffer = msgq->array[idx].buffer; *len = msgq->array[idx].len; msgq->idx_r++; + if (_idx) *_idx = idx; } } @@ -52,7 +66,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = NULL; *len = 0; } - return 0; + return EOS_ERR_NOTFOUND; } idx = IDX_MASK(msgq->idx_r, msgq->size); @@ -65,7 +79,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = _buffer; *len = _len; } - return 1; + return EOS_OK; } } for (i = msgq->idx_r + 1; IDX_LT(i, msgq->idx_w); i++) { @@ -82,7 +96,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = _buffer; *len = _len; } - return 1; + return EOS_OK; } } } @@ -90,11 +104,7 @@ int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, ui *buffer = NULL; *len = 0; } - return 0; -} - -uint8_t eos_msgq_len(EOSMsgQ *msgq) { - return (uint8_t)(msgq->idx_w - msgq->idx_r); + return EOS_ERR_NOTFOUND; } void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) { @@ -104,6 +114,10 @@ void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size) { bufq->array = array; } +uint8_t eos_bufq_len(EOSBufQ *bufq) { + return (uint8_t)(bufq->idx_w - bufq->idx_r); +} + int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer) { if ((uint8_t)(bufq->idx_w - bufq->idx_r) == bufq->size) return EOS_ERR_FULL; @@ -116,7 +130,3 @@ unsigned char *eos_bufq_pop(EOSBufQ *bufq) { return bufq->array[IDX_MASK(bufq->idx_r++, bufq->size)]; } - -uint8_t eos_bufq_len(EOSBufQ *bufq) { - return (uint8_t)(bufq->idx_w - bufq->idx_r); -} diff --git a/fw/fe310/eos/msgq.h b/fw/fe310/eos/msgq.h index 7e3b5e5..0634144 100644 --- a/fw/fe310/eos/msgq.h +++ b/fw/fe310/eos/msgq.h @@ -14,10 +14,12 @@ typedef struct EOSMsgQ { } EOSMsgQ; void eos_msgq_init(EOSMsgQ *msgq, EOSMsgItem *array, uint8_t size); +uint8_t eos_msgq_len(EOSMsgQ *msgq); int eos_msgq_push(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len); +int eos_msgq_push_widx(EOSMsgQ *msgq, unsigned char type, unsigned char *buffer, uint16_t len, uint8_t *_idx); void eos_msgq_pop(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len); +void eos_msgq_pop_widx(EOSMsgQ *msgq, unsigned char *type, unsigned char **buffer, uint16_t *len, uint8_t *_idx); int eos_msgq_find(EOSMsgQ *msgq, unsigned char type, unsigned char *selector, uint16_t sel_len, unsigned char **buffer, uint16_t *len); -uint8_t eos_msgq_len(EOSMsgQ *msgq); typedef struct EOSBufQ { uint8_t idx_r; @@ -27,6 +29,6 @@ typedef struct EOSBufQ { } EOSBufQ; void eos_bufq_init(EOSBufQ *bufq, unsigned char **array, uint8_t size); +uint8_t eos_bufq_len(EOSBufQ *bufq); int eos_bufq_push(EOSBufQ *bufq, unsigned char *buffer); unsigned char *eos_bufq_pop(EOSBufQ *bufq); -uint8_t eos_bufq_len(EOSBufQ *bufq); diff --git a/fw/fe310/eos/net/Makefile b/fw/fe310/eos/net/Makefile index fc65454..0646956 100644 --- a/fw/fe310/eos/net/Makefile +++ b/fw/fe310/eos/net/Makefile @@ -1,6 +1,6 @@ include ../../common.mk -obj = rng.o pwr.o wifi.o sock.o cell.o +obj = rng.o wifi.o sock.o cell.o lib = ../../libeos-net.a diff --git a/fw/fe310/eos/net/cell.c b/fw/fe310/eos/net/cell.c index 96216ba..c0c77af 100644 --- a/fw/fe310/eos/net/cell.c +++ b/fw/fe310/eos/net/cell.c @@ -10,21 +10,21 @@ 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) { +static void cell_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) { unsigned char mtype; unsigned char idx; - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); + if ((buffer == NULL) || (buf_len < 1)) { + eos_net_bad_handler(type, buffer, buf_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); + evt_handler[idx](mtype & ~EOS_CELL_MTYPE_MASK, buffer, buf_len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, buffer, buf_len); } } @@ -52,32 +52,32 @@ eos_evt_handler_t eos_cell_get_handler(unsigned char mtype) { int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync) { buffer -= offset; - return eos_net_send_async(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, 1); + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, buf_len + offset, !sync, 1); } -int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected) { - if (len < 2) return EOS_ERR_SIZE; +int eos_cell_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t *connected) { + if (buf_len < 2) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS)) return EOS_ERR_NET; buffer++; - len--; + buf_len--; *status = buffer[0]; buffer++; - len--; + buf_len--; if (*status == EOS_CELL_STATUS_PPP) { - if (len < 1) return EOS_ERR_SIZE; + if (buf_len < 1) return EOS_ERR_SIZE; if (connected) *connected = buffer[0]; buffer++; - len--; + buf_len--; } return EOS_OK; } int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv; @@ -88,10 +88,10 @@ int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) } type = EOS_NET_MTYPE_CELL; - len = 1; + buf_len = 1; buffer[0] = EOS_CELL_MTYPE_DEV | EOS_CELL_MTYPE_STATUS; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto cell_status_fin; if (type != EOS_NET_MTYPE_CELL) { @@ -99,7 +99,7 @@ int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer) goto cell_status_fin; } - rv = eos_cell_status_parse(buffer, len, status, connected); + rv = eos_cell_status_parse(buffer, buf_len, status, connected); cell_status_fin: if (do_release) eos_net_free(buffer, 1); @@ -132,7 +132,7 @@ int eos_cell_uart_give(unsigned char *buffer, int sync) { return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } -unsigned char *eos_cell_uart_data_buffer(uint16_t *offset) { +unsigned char *eos_cell_uart_data_alloc(uint16_t *offset) { unsigned char *buffer; buffer = eos_net_alloc(); @@ -185,7 +185,7 @@ int eos_cell_voice_hangup(unsigned char *buffer, int sync) { return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, 1, async, 1); } -unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) { +unsigned char *eos_cell_voice_pcm_alloc(uint16_t *offset) { unsigned char *buffer; buffer = eos_net_alloc(); @@ -197,7 +197,7 @@ unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset) { int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) { int async; size_t addr_len, txt_len; - uint16_t len; + uint16_t buf_len; addr_len = strlen(addr); txt_len = strlen(txt); @@ -221,48 +221,48 @@ int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync) { buffer[3] = EOS_CELL_SMS_ADDRTYPE_OTHER; } buffer[4] = addr_len; - len = 5; - memcpy(buffer + len, addr, addr_len); - len += addr_len; - memcpy(buffer + len, txt, txt_len); - len += txt_len; - return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, len, async, 1); + buf_len = 5; + memcpy(buffer + buf_len, addr, addr_len); + buf_len += addr_len; + memcpy(buffer + buf_len, txt, txt_len); + buf_len += txt_len; + return _eos_net_send(EOS_NET_MTYPE_CELL, buffer, buf_len, async, 1); } -int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { +int _eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len) { uint16_t _addr_len; - if (len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; + if (buf_len < 4 + EOS_CELL_SMS_SIZE_TS) return EOS_ERR_SIZE; if (buffer[0] != (EOS_CELL_MTYPE_SMS | EOS_CELL_MTYPE_SMS_MSG)) return EOS_ERR_NET; buffer += 3 + EOS_CELL_SMS_SIZE_TS; - len -= 3 + EOS_CELL_SMS_SIZE_TS; + buf_len -= 3 + EOS_CELL_SMS_SIZE_TS; _addr_len = *buffer; if (_addr_len > EOS_CELL_SMS_SIZE_ADDR) return EOS_ERR_SIZE; - if ((_addr_len == 0) || (len < (_addr_len + 1))) return EOS_ERR_SIZE; + if ((_addr_len == 0) || (buf_len < (_addr_len + 1))) return EOS_ERR_SIZE; if (addr && addr_len) { *addr = buffer + 1; *addr_len = _addr_len; } buffer += _addr_len + 1; - len -= _addr_len + 1; + buf_len -= _addr_len + 1; - if (len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; + if (buf_len > EOS_CELL_SMS_SIZE_TXT) return EOS_ERR_SIZE; if (txt && txt_len) { *txt = buffer; - *txt_len = len; + *txt_len = buf_len; } return EOS_OK; } -int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) { +int eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size) { char *_addr, *_txt; uint16_t _addr_len, _txt_len; int rv; - rv = _eos_cell_sms_parse(buffer, len, &_addr, &_addr_len, &_txt, &_txt_len); + rv = _eos_cell_sms_parse(buffer, buf_len, &_addr, &_addr_len, &_txt, &_txt_len); if (rv) return rv; if (addr_size < _addr_len + 1) return EOS_ERR_SIZE; if (txt_size < _txt_len + 1) return EOS_ERR_SIZE; @@ -276,7 +276,7 @@ int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv; @@ -287,24 +287,24 @@ int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned } type = EOS_NET_MTYPE_CELL; - len = 1; + buf_len = 1; buffer[0] = EOS_CELL_MTYPE_PDP | atype; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto cell_pdp_get_fin; - if ((type != EOS_NET_MTYPE_CELL) || (len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) { + if ((type != EOS_NET_MTYPE_CELL) || (buf_len == 0) || (buffer[0] != EOS_CELL_MTYPE_PDP | atype)) { rv = EOS_ERR_NET; goto cell_pdp_get_fin; } - len--; - if ((len > EOS_CELL_PDP_SIZE_ARG) || (len > arg_size - 1)) { + buf_len--; + if ((buf_len > EOS_CELL_PDP_SIZE_ARG) || (buf_len > arg_size - 1)) { rv = EOS_ERR_SIZE; goto cell_pdp_get_fin; } - memcpy(buffer + 1, arg, len); - arg[len] = '\0'; + memcpy(buffer + 1, arg, buf_len); + arg[buf_len] = '\0'; cell_pdp_get_fin: if (do_release) eos_net_free(buffer, 1); diff --git a/fw/fe310/eos/net/cell.h b/fw/fe310/eos/net/cell.h index ac334e9..3264022 100644 --- a/fw/fe310/eos/net/cell.h +++ b/fw/fe310/eos/net/cell.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_CELL_MTYPE_DEV 0x10 @@ -27,7 +28,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_MSG 1 #define EOS_CELL_MTYPE_SMS_LIST 2 @@ -73,20 +73,20 @@ void eos_cell_set_handler(unsigned char mtype, eos_evt_handler_t handler); eos_evt_handler_t eos_cell_get_handler(unsigned char mtype); int eos_cell_send_buffer(unsigned char *buffer, uint16_t buf_len, uint16_t offset, int sync); -int eos_cell_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t *connected); +int eos_cell_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t *connected); int eos_cell_status(uint8_t *status, uint8_t *connected, unsigned char *buffer); int eos_cell_uart_take(unsigned char *buffer, int sync); int eos_cell_uart_give(unsigned char *buffer, int sync); -unsigned char *eos_cell_uart_data_buffer(uint16_t *offset); +unsigned char *eos_cell_uart_data_alloc(uint16_t *offset); int eos_cell_voice_dial(char *num, unsigned char *buffer, int sync); int eos_cell_voice_answer(unsigned char *buffer, int sync); int eos_cell_voice_hangup(unsigned char *buffer, int sync); -unsigned char *eos_cell_voice_pcm_buffer(uint16_t *offset); +unsigned char *eos_cell_voice_pcm_alloc(uint16_t *offset); int eos_cell_sms_send(char *addr, char *txt, unsigned char *buffer, int sync); -int _eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len); -int eos_cell_sms_parse(unsigned char *buffer, uint16_t len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size); +int _eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char **addr, uint16_t *addr_len, char **txt, uint16_t *txt_len); +int eos_cell_sms_parse(unsigned char *buffer, uint16_t buf_len, char *addr, uint16_t addr_size, char *txt, uint16_t txt_size); int eos_cell_pdp_get(unsigned char atype, char *arg, uint16_t arg_size, unsigned char *buffer); int eos_cell_pdp_set(unsigned char atype, char *arg, unsigned char *buffer, int sync); diff --git a/fw/fe310/eos/net/sock.c b/fw/fe310/eos/net/sock.c index c9934e8..c55b8e8 100644 --- a/fw/fe310/eos/net/sock.c +++ b/fw/fe310/eos/net/sock.c @@ -10,26 +10,40 @@ 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) { +static void sock_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) { unsigned char sock; + int i; - 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); + if ((buffer == NULL) || (buf_len < 2)) { + eos_net_bad_handler(type, buffer, buf_len); return; } switch(buffer[0]) { - case EOS_SOCK_MTYPE_PKT: - evt_handler[sock - 1](type, buffer, len); + case EOS_SOCK_MTYPE_PKT: { + sock = buffer[1]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, buffer, buf_len); + return; + } + evt_handler[sock - 1](type, buffer, buf_len); + break; + } + + case EOS_SOCK_MTYPE_CLOSE: { + for (i=1; i<buf_len; i++) { + sock = buffer[i]; + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK) || (evt_handler[sock - 1] == NULL)) { + eos_net_bad_handler(type, buffer, buf_len); + return; + } + evt_handler[sock - 1](type, buffer, buf_len); + } break; + } + default: - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, buffer, buf_len); break; } } @@ -54,7 +68,7 @@ eos_evt_handler_t eos_sock_get_handler(unsigned char sock) { int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv, sock; @@ -65,23 +79,23 @@ int eos_sock_open_udp(eos_evt_handler_t handler, unsigned char *buffer) { } type = EOS_NET_MTYPE_SOCK; - len = 1; + buf_len = 1; buffer[0] = EOS_SOCK_MTYPE_OPEN_DGRAM; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto sock_open_udp_fin; if (type != EOS_NET_MTYPE_SOCK) { rv = EOS_ERR_NET; goto sock_open_udp_fin; } - if (len < 2) { + if (buf_len < 2) { rv = EOS_ERR_SIZE; goto sock_open_udp_fin; } sock = buffer[1]; - if (sock == 0) { + if ((sock == 0) || (sock > EOS_SOCK_MAX_SOCK)) { rv = EOS_ERR_NET; goto sock_open_udp_fin; } @@ -108,7 +122,29 @@ void eos_sock_close(unsigned char sock, unsigned char *buffer) { eos_sock_set_handler(sock, NULL); } -static int sock_send(unsigned char sock, unsigned char *msg, uint16_t msg_len, EOSNetAddr *addr, unsigned char *buffer) { +int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len) { + *buffer = NULL; + + if (pkt && (pkt_len + EOS_SOCK_SIZE_UDP_HDR > EOS_NET_SIZE_BUF)) return EOS_ERR_SIZE; + + *buffer = eos_net_alloc(); + *buffer += EOS_SOCK_SIZE_UDP_HDR; + if (pkt) memcpy(*buffer, pkt, pkt_len); + + return EOS_OK; +} + +unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len) { + if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return NULL; + + return buf + EOS_SOCK_SIZE_UDP_HDR; +} + +unsigned char *eos_sock_pkt2buf(unsigned char *pkt) { + return pkt - EOS_SOCK_SIZE_UDP_HDR; +} + +static void sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer) { buffer[0] = EOS_SOCK_MTYPE_PKT; buffer[1] = sock; buffer += 2; @@ -117,46 +153,47 @@ static int sock_send(unsigned char sock, unsigned char *msg, uint16_t msg_len, E 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_SIZE_BUF) 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 eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more) { int rv; - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; + buffer -= EOS_SOCK_SIZE_UDP_HDR; + sock_sendto(sock, addr, buffer); - return eos_net_send(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR); + rv = eos_net_send(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR, more); + return rv; } -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_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len) { int rv; - rv = sock_send(sock, msg, msg_len, addr, buffer); - if (rv) return rv; + buffer -= EOS_SOCK_SIZE_UDP_HDR; + sock_sendto(sock, addr, buffer); - return eos_net_send_async(EOS_NET_MTYPE_SOCK, buffer, msg_len + EOS_SOCK_SIZE_UDP_HDR, more); + rv = eos_net_send_sync(EOS_NET_MTYPE_SOCK, buffer, buf_len + EOS_SOCK_SIZE_UDP_HDR); + return rv; } -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; +int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size) { + if (buf_len < EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + if (buffer[0] == EOS_SOCK_MTYPE_CLOSE) return EOS_SOCK_ERR_CLOSED; if (buffer[0] != EOS_SOCK_MTYPE_PKT) return EOS_ERR_NET; buffer += 2; - memcpy(addr->host, buffer, sizeof(addr->host)); + if (addr) { + memcpy(addr->host, buffer, sizeof(addr->host)); + } buffer += sizeof(addr->host); - addr->port = (uint16_t)buffer[0] << 8; - addr->port |= (uint16_t)buffer[1]; + if (addr) { + 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); + if (pkt) { + if (pkt_size < buf_len - EOS_SOCK_SIZE_UDP_HDR) return EOS_ERR_SIZE; + memcpy(pkt, buffer, buf_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 index e2f8637..8dbb111 100644 --- a/fw/fe310/eos/net/sock.h +++ b/fw/fe310/eos/net/sock.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_SOCK_MTYPE_PKT 0 @@ -11,6 +12,8 @@ #define EOS_IPv4_ADDR_SIZE 4 +#define EOS_SOCK_ERR_CLOSED -1021 + typedef struct EOSNetAddr { unsigned char host[EOS_IPv4_ADDR_SIZE]; uint16_t port; @@ -23,6 +26,10 @@ 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); +int eos_sock_pkt_alloc(unsigned char **buffer, unsigned char *pkt, size_t pkt_len); +unsigned char *eos_sock_buf2pkt(unsigned char *buf, uint16_t buf_len); +unsigned char *eos_sock_pkt2buf(unsigned char *pkt); + +int eos_sock_sendto(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len, unsigned char more); +int eos_sock_sendto_sync(unsigned char sock, EOSNetAddr *addr, unsigned char *buffer, uint16_t buf_len); +int eos_sock_recvfrom(unsigned char *buffer, uint16_t buf_len, EOSNetAddr *addr, unsigned char *pkt, size_t pkt_size); diff --git a/fw/fe310/eos/net/wifi.c b/fw/fe310/eos/net/wifi.c index ebbb9ca..1391121 100644 --- a/fw/fe310/eos/net/wifi.c +++ b/fw/fe310/eos/net/wifi.c @@ -10,19 +10,19 @@ 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) { +static void wifi_handle_msg(unsigned char type, unsigned char *buffer, uint16_t buf_len) { unsigned char mtype; - if ((buffer == NULL) || (len < 1)) { - eos_net_bad_handler(type, buffer, len); + if ((buffer == NULL) || (buf_len < 1)) { + eos_net_bad_handler(type, buffer, buf_len); return; } mtype = buffer[0]; if ((mtype < EOS_WIFI_MAX_MTYPE) && evt_handler[mtype]) { - evt_handler[mtype](mtype, buffer, len); + evt_handler[mtype](mtype, buffer, buf_len); } else { - eos_net_bad_handler(type, buffer, len); + eos_net_bad_handler(type, buffer, buf_len); } } @@ -44,28 +44,28 @@ eos_evt_handler_t eos_wifi_get_handler(unsigned char mtype) { return NULL; } -int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) { - if (len < 2) return EOS_ERR_SIZE; +int eos_wifi_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size) { + if (buf_len < 2) return EOS_ERR_SIZE; if (buffer[0] != EOS_WIFI_MTYPE_STATUS) return EOS_ERR_NET; buffer++; - len--; + buf_len--; *status = buffer[0]; buffer++; - len--; + buf_len--; switch (*status) { case EOS_WIFI_STATUS_GOT_IP: - if (len < sizeof(uint32_t)) return EOS_ERR_SIZE; + if (buf_len < sizeof(uint32_t)) return EOS_ERR_SIZE; if (ip_addr) memcpy(ip_addr, buffer, sizeof(uint32_t)); buffer += sizeof(uint32_t); - len -= sizeof(uint32_t); + buf_len -= sizeof(uint32_t); case EOS_WIFI_STATUS_CONNECTED: if (ssid) { - if ((len == 0) || (len > EOS_WIFI_SIZE_SSID) || (len > ssid_size - 1)) return EOS_ERR_SIZE; - memcpy(ssid, buffer, len); - ssid[len] = '\0'; + if ((buf_len == 0) || (buf_len > EOS_WIFI_SIZE_SSID) || (buf_len > ssid_size - 1)) return EOS_ERR_SIZE; + memcpy(ssid, buffer, buf_len); + ssid[buf_len] = '\0'; } break; } @@ -74,7 +74,7 @@ int eos_wifi_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer) { unsigned char type; - uint16_t len; + uint16_t buf_len; int do_release; int rv; @@ -85,17 +85,17 @@ int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssi } type = EOS_NET_MTYPE_WIFI; - len = 1; + buf_len = 1; buffer[0] = EOS_WIFI_MTYPE_STATUS; - rv = eos_net_xchg(&type, buffer, &len); + rv = eos_net_xchg(&type, buffer, &buf_len); if (rv) goto wifi_status_fin; if (type != EOS_NET_MTYPE_WIFI) { rv = EOS_ERR_NET; goto wifi_status_fin; } - rv = eos_wifi_status_parse(buffer, len, status, ip_addr, ssid, ssid_size); + rv = eos_wifi_status_parse(buffer, buf_len, status, ip_addr, ssid, ssid_size); wifi_status_fin: if (do_release) eos_net_free(buffer, 1); diff --git a/fw/fe310/eos/net/wifi.h b/fw/fe310/eos/net/wifi.h index 93d2fc4..800723e 100644 --- a/fw/fe310/eos/net/wifi.h +++ b/fw/fe310/eos/net/wifi.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_WIFI_MTYPE_STATUS 0 @@ -24,10 +25,10 @@ void eos_wifi_init(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_status_parse(unsigned char *buffer, uint16_t len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size); +int eos_wifi_status_parse(unsigned char *buffer, uint16_t buf_len, uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size); int eos_wifi_status(uint8_t *status, uint8_t ip_addr[], char *ssid, uint16_t ssid_size, unsigned char *buffer); int eos_wifi_start(unsigned char *buffer, int sync); int eos_wifi_stop(unsigned char *buffer, int sync); int eos_wifi_scan(unsigned char *buffer, int sync); int eos_wifi_connect(char *ssid, char *pwd, unsigned char *buffer, int sync); -int eos_wifi_disconnect(unsigned char *buffer, int sync);
\ No newline at end of file +int eos_wifi_disconnect(unsigned char *buffer, int sync); diff --git a/fw/fe310/eos/soc/Makefile b/fw/fe310/eos/soc/Makefile index f5f072a..39d8b8c 100644 --- a/fw/fe310/eos/soc/Makefile +++ b/fw/fe310/eos/soc/Makefile @@ -1,7 +1,7 @@ include ../../common.mk CFLAGS += -I$(bsp_dir)/include -I$(bsp_dir)/drivers -obj = trap_entry.o interrupt.o timer.o pwr.o i2s.o i2c.o uart.o spi.o spi9bit.o +obj = trap_entry.o interrupt.o timer.o pwr.o aon.o gpio.o i2s.o i2c.o uart.o spi.o spi9bit.o lib = ../../libeos-soc.a diff --git a/fw/fe310/eos/soc/aon.c b/fw/fe310/eos/soc/aon.c new file mode 100644 index 0000000..a11259e --- /dev/null +++ b/fw/fe310/eos/soc/aon.c @@ -0,0 +1,46 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "encoding.h" +#include "platform.h" + +#include "eos.h" +#include "pwr.h" + +#include "aon.h" + +#define AON_MAX_BACKUP 16 + +int eos_aon_init(void) { + uint8_t wakeup_cause; + int i, rst; + + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); + if (rst) { + for (i=0; i<AON_MAX_BACKUP; i++) { + eos_aon_set_reg(i, 0); + } + } + + return EOS_OK; +} + +uint32_t eos_aon_get_reg(int idx) { + uint32_t addr; + + if ((idx < 0) || (idx >= AON_MAX_BACKUP)) return -1; + + addr = AON_BACKUP0 + sizeof(uint32_t) * idx; + return AON_REG(addr); +} + +void eos_aon_set_reg(int idx, uint32_t reg) { + uint32_t addr; + + if ((idx < 0) || (idx > 15)) return; + + addr = AON_BACKUP0 + sizeof(uint32_t) * idx; + AON_REG(addr) = reg; +} + diff --git a/fw/fe310/eos/soc/aon.h b/fw/fe310/eos/soc/aon.h new file mode 100644 index 0000000..41bdfab --- /dev/null +++ b/fw/fe310/eos/soc/aon.h @@ -0,0 +1,5 @@ +#include <stdint.h> + +int eos_aon_init(void); +uint32_t eos_aon_get_reg(int idx); +void eos_aon_set_reg(int idx, uint32_t reg);
\ No newline at end of file diff --git a/fw/fe310/eos/soc/gpio.c b/fw/fe310/eos/soc/gpio.c new file mode 100644 index 0000000..4fa93dd --- /dev/null +++ b/fw/fe310/eos/soc/gpio.c @@ -0,0 +1,20 @@ +#include <stdint.h> + +#include "encoding.h" +#include "platform.h" + +int eos_gpio_get(uint32_t reg, int pin) { + return !!(GPIO_REG(reg) & (1 << pin)); +} + +void eos_gpio_set(uint32_t reg, int pin) { + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(reg) |= (1 << pin); + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) set_csr(mstatus, MSTATUS_MIE); +} + +void eos_gpio_clear(uint32_t reg, int pin) { + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(reg) &= ~(1 << pin); + if ((reg == GPIO_OUTPUT_VAL) || (reg == GPIO_LOW_IE)) set_csr(mstatus, MSTATUS_MIE); +} diff --git a/fw/fe310/eos/soc/gpio.h b/fw/fe310/eos/soc/gpio.h new file mode 100644 index 0000000..2ba5787 --- /dev/null +++ b/fw/fe310/eos/soc/gpio.h @@ -0,0 +1,5 @@ +#include <stdint.h> + +int eos_gpio_get(uint32_t reg, int pin); +void eos_gpio_set(uint32_t reg, int pin); +void eos_gpio_clear(uint32_t reg, int pin); diff --git a/fw/fe310/eos/soc/i2c.c b/fw/fe310/eos/soc/i2c.c index 553a9bf..feed936 100644 --- a/fw/fe310/eos/soc/i2c.c +++ b/fw/fe310/eos/soc/i2c.c @@ -9,7 +9,7 @@ #include "i2s.h" #include "i2c.h" -int eos_i2c_init(uint8_t wakeup_cause) { +int eos_i2c_init(void) { eos_i2c_speed(EOS_I2C_SPEED); eos_i2c_enable(); diff --git a/fw/fe310/eos/soc/i2c.h b/fw/fe310/eos/soc/i2c.h index 5032988..a99b8ee 100644 --- a/fw/fe310/eos/soc/i2c.h +++ b/fw/fe310/eos/soc/i2c.h @@ -2,7 +2,7 @@ #define EOS_I2C_SPEED 100000 -int eos_i2c_init(uint8_t wakeup_cause); +int eos_i2c_init(void); void eos_i2c_enable(void); void eos_i2c_disable(void); int eos_i2c_enabled(void); diff --git a/fw/fe310/eos/soc/i2s.c b/fw/fe310/eos/soc/i2s.c index bcce0b7..8bd5600 100644 --- a/fw/fe310/eos/soc/i2s.c +++ b/fw/fe310/eos/soc/i2s.c @@ -3,17 +3,19 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "prci_driver.h" #include "eos.h" +#include "log.h" #include "event.h" #include "interrupt.h" -#include "board.h" - -#include "dev/eve.h" - #include "uart.h" +#include "dev/egpio.h" +#include "dev/egpio_priv.h" + +#include "dev/hpamp.h" #include "i2s.h" #include "i2s_priv.h" @@ -32,80 +34,63 @@ 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 */ +static uint8_t i2s_mic_volume = 0; /* 0 - 8 */ +static uint8_t i2s_spk_volume = 16; /* 0 - 16 */ EOSABuf _eos_i2s_mic_buf; EOSABuf _eos_i2s_spk_buf; uint32_t _eos_i2s_drvr[] = { - 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_WM */ + 0, /* I2S_SPK_WM */ + 0, /* I2S_MIC_EVT */ + 0, /* I2S_SPK_EVT */ }; -#define I2S_FMT 0 -#define I2S_MODE 1 -#define I2S_MIC_WM 2 -#define I2S_SPK_WM 3 -#define I2S_MIC_EVT 4 -#define I2S_SPK_EVT 5 +#define I2S_MIC_WM 0 +#define I2S_SPK_WM 1 +#define I2S_MIC_EVT 2 +#define I2S_SPK_EVT 3 -static void _abuf_init(EOSABuf *buf, uint8_t *array, uint16_t size) { +static void _abuf_init(EOSABuf *buf, uint16_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 void _abuf_flush(EOSABuf *buf) { + buf->idx_r = 0; + buf->idx_w = 0; } -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 uint16_t _abuf_len(EOSABuf *buf) { + return (uint16_t)(buf->idx_w - buf->idx_r); } -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 uint16_t _abuf_size(EOSABuf *buf) { + return buf->size; } -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; - } -} +/* mic buffer only */ +static int _mbuf_pop(uint16_t *sample) { + if (_eos_i2s_mic_buf.idx_r == _eos_i2s_mic_buf.idx_w) return EOS_ERR_EMPTY; -static void _abuf_flush(EOSABuf *buf) { - buf->idx_r = 0; - buf->idx_w = 0; + *sample = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r, _eos_i2s_mic_buf.size)]; + _eos_i2s_mic_buf.idx_r += 1; + return EOS_OK; } -static uint16_t _abuf_len(EOSABuf *buf) { - return buf->idx_w - buf->idx_r; +/* spk buffer only */ +static int _sbuf_push(uint16_t sample) { + if ((uint16_t)(_eos_i2s_spk_buf.idx_w - _eos_i2s_spk_buf.idx_r) == _eos_i2s_spk_buf.size) return EOS_ERR_FULL; + + if (_eos_i2s_spk_buf.idx_r != _eos_i2s_spk_buf.idx_w) { + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w - 1, _eos_i2s_spk_buf.size)] |= sample >> 15; + } + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w, _eos_i2s_spk_buf.size)] = sample << 1; + _eos_i2s_spk_buf.idx_w += 1; + return EOS_OK; } static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { @@ -135,7 +120,9 @@ static void i2s_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l } static void i2s_set_cmp(void) { - int spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; + int spk_ws_offset; + + spk_ws_offset = i2s_spk_volume - 16 + i2s_mic_volume; /* adjust spk ws relative to mic ws */ if (spk_ws_offset <= 0) { @@ -147,36 +134,50 @@ static void i2s_set_cmp(void) { I2S_REG_WS(PWM_CMP2) = spk_ws_offset * i2s_clk_period - i2s_clk_period / 2; I2S_REG_WS(PWM_CMP3) = (32 + spk_ws_offset) * i2s_clk_period - i2s_clk_period / 2; - I2S_REG_SR_SEL(PWM_CMP1) = (1 + i2s_mic_volume) * i2s_clk_period; - I2S_REG_SR_SEL(PWM_CMP2) = (17 + i2s_mic_volume) * i2s_clk_period - (i2s_clk_period / 4); + I2S_REG_SR_SEL(PWM_CMP1) = (1 + i2s_mic_volume) * i2s_clk_period + i2s_clk_period / 4; + I2S_REG_SR_SEL(PWM_CMP2) = (17 + i2s_mic_volume) * i2s_clk_period - i2s_clk_period / 4; } -extern void _eos_i2s_start_pwm(void); +extern void _eos_i2s_start_pwm(unsigned int); -int eos_i2s_init(uint8_t wakeup_cause) { +int eos_i2s_init(void) { eos_evtq_set_handler(EOS_EVT_I2S, i2s_handle_evt); I2S_REG_CK(PWM_CFG) = 0; I2S_REG_WS(PWM_CFG) = 0; I2S_REG_SR_SEL(PWM_CFG) = 0; + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_SEL); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SR_CK); + GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SD_OUT); + set_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_SR_SEL); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << I2S_PIN_SR_CK); GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_IN); + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_SD_OUT); + GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_INT); return EOS_OK; } -void eos_i2s_start(uint32_t sample_rate) { - uint32_t iof_mask; +int eos_i2s_start(uint32_t sample_rate, int mode) { + unsigned int scale_ck; + int rv; + i2s_clk_period = PRCI_get_cpu_freq() / (sample_rate * 64); - i2s_clk_period = (i2s_clk_period & ~I2S_PWM_SCALE_CK_MASK) + 1; + i2s_clk_period &= ~0x01; /* clear last bit */ - I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> I2S_PWM_SCALE_CK; + /* if half of clock period does not fit in 8 bits we need to scale clock */ + scale_ck = 0; + if ((i2s_clk_period >> 1) & ~0xFF) { + scale_ck = 1; + i2s_clk_period &= ~0x03; /* clear last two bits */ + } + + I2S_REG_CK(PWM_CMP0) = i2s_clk_period >> (1 + scale_ck); /* master clock: double bit clock frequency */ I2S_REG_CK(PWM_CMP1) = I2S_REG_CK(PWM_CMP0) / 2; I2S_REG_CK(PWM_CMP2) = 0; I2S_REG_CK(PWM_CMP3) = 0; @@ -184,42 +185,64 @@ void eos_i2s_start(uint32_t sample_rate) { I2S_REG_WS(PWM_CMP0) = i2s_clk_period * 64 - 1; I2S_REG_WS(PWM_CMP1) = i2s_clk_period * 32; - I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 32 - 1; + if (mode == EOS_I2S_MODE_STEREO) { + I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 32 - 1; + } else { + I2S_REG_SR_SEL(PWM_CMP0) = i2s_clk_period * 64 - 1; + } I2S_REG_SR_SEL(PWM_CMP3) = 0; i2s_set_cmp(); - I2S_REG_CK(PWM_COUNT) = 0; + I2S_REG_CK(PWM_COUNT) = I2S_REG_CK(PWM_CMP1); /* master clock starts high */ I2S_REG_WS(PWM_COUNT) = 0; - I2S_REG_SR_SEL(PWM_COUNT) = 0; + if (mode == EOS_I2S_MODE_MONO_R) { + I2S_REG_SR_SEL(PWM_COUNT) = i2s_clk_period * 32; + } else { + I2S_REG_SR_SEL(PWM_COUNT) = 0; + } - eos_eve_intr_disable(); eos_uart_disable(); + rv = eos_egpio_i2s_start(); + if (rv) { + eos_i2s_stop(); + return rv; + } + + GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; + GPIO_REG(GPIO_IOF_EN) |= I2S_PIN_PWM; - GPIO_REG(GPIO_INPUT_EN) |= (1 << I2S_PIN_INT); GPIO_REG(GPIO_FALL_IE) |= (1 << I2S_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_CK); + set_csr(mstatus, MSTATUS_MIE); - iof_mask = I2S_PIN_PWM; - if (_eos_i2s_mic_buf.size == 0) { - iof_mask &= ~(1 << I2S_PIN_WS_MIC); - } - if (_eos_i2s_spk_buf.size == 0) { - iof_mask &= ~(1 << I2S_PIN_WS_SPK); + /* XXX should set stereo pin to 1 !!! */ + + eos_intr_set_priority(I2S_IRQ_ID, IRQ_PRIORITY_I2S); + eos_intr_enable(I2S_IRQ_ID); + + /* initialise headphones if present */ + if (!eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { + rv = eos_hpamp_init(); + if (rv) { + eos_i2s_stop(); + return rv; + } } - GPIO_REG(GPIO_IOF_SEL) |= I2S_PIN_PWM; - GPIO_REG(GPIO_IOF_EN) |= iof_mask; - eos_intr_set_priority(I2S_IRQ_SD_ID, IRQ_PRIORITY_I2S_SD); - eos_intr_enable(I2S_IRQ_SD_ID); - _eos_i2s_start_pwm(); + clear_csr(mstatus, MSTATUS_MIE); + _eos_i2s_start_pwm(scale_ck); + set_csr(mstatus, MSTATUS_MIE); /* - I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK; + I2S_REG_CK(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | scale_ck; I2S_REG_WS(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP2GANG; I2S_REG_SR_SEL(PWM_CFG) = PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | PWM_CFG_CMP1GANG; */ } void eos_i2s_stop(void) { + int rv; + I2S_REG_CK(PWM_CFG) = 0; I2S_REG_WS(PWM_CFG) = 0; I2S_REG_SR_SEL(PWM_CFG) = 0; @@ -227,17 +250,18 @@ void eos_i2s_stop(void) { I2S_REG_WS(PWM_COUNT) = 0; I2S_REG_SR_SEL(PWM_COUNT) = 0; - eos_intr_disable(I2S_IRQ_SD_ID); + eos_intr_disable(I2S_IRQ_ID); GPIO_REG(GPIO_FALL_IE) &= ~(1 << I2S_PIN_INT); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << I2S_PIN_INT); - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << I2S_PIN_SR_SEL); + clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << I2S_PIN_SR_CK); + set_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_XOR) &= ~(1 << I2S_PIN_WS_SPK); GPIO_REG(GPIO_IOF_EN) &= ~I2S_PIN_PWM; eos_uart_enable(); - eos_eve_intr_enable(); + rv = eos_egpio_i2s_stop(); + if (rv) EOS_LOG(EOS_LOG_ERR, "I2S STOP: EGPIO ERR:%d\n", rv); _eos_i2s_drvr[I2S_MIC_EVT] = 0; _eos_i2s_drvr[I2S_SPK_EVT] = 0; @@ -253,12 +277,8 @@ 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; +int eos_i2s_set_lsgain(int gain) { + return eos_egpio_set_val(EGPIO_PIN_LSGAIN_SEL, gain); } void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) { @@ -270,72 +290,55 @@ void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm) { set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size) { - int run = eos_i2s_running(); - +void eos_i2s_mic_set_buf(uint16_t *mic_arr, uint16_t mic_arr_size) { clear_csr(mstatus, MSTATUS_MIE); _abuf_init(&_eos_i2s_mic_buf, mic_arr, mic_arr_size); - if (run) { - if (mic_arr_size == 0) { - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_MIC); - } else { - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_MIC); - } - } set_csr(mstatus, MSTATUS_MIE); } -uint8_t *eos_i2s_mic_get_buf(void) { +uint16_t *eos_i2s_mic_get_buf(void) { return _eos_i2s_mic_buf.array; } uint16_t eos_i2s_mic_len(void) { - uint16_t ret; + uint16_t rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_len(&_eos_i2s_mic_buf); + rv = _abuf_len(&_eos_i2s_mic_buf); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } -uint16_t eos_i2s_mic_read(uint8_t *sample, uint16_t ssize) { - uint16_t i; - uint16_t _ssize = 0; +uint16_t eos_i2s_mic_read(uint16_t *smpl_buf, uint16_t buf_size) { + int i; + uint16_t smpl_len; clear_csr(mstatus, MSTATUS_MIE); - _ssize = MIN(ssize, _abuf_len(&_eos_i2s_mic_buf)); + smpl_len = MIN(buf_size, _abuf_len(&_eos_i2s_mic_buf)); set_csr(mstatus, MSTATUS_MIE); - for (i=0; i<_ssize; i++) { - sample[i] = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r + i, _eos_i2s_mic_buf.size)]; - } - - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_mic_buf.idx_r += _ssize; - set_csr(mstatus, MSTATUS_MIE); - - return _ssize; -} + if (smpl_len == 0) return 0; -int eos_i2s_mic_pop8(uint8_t *sample) { - int ret; + for (i=0; i<smpl_len; i++) { + smpl_buf[i] = _eos_i2s_mic_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_mic_buf.idx_r + i, _eos_i2s_mic_buf.size)]; + } clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop8(&_eos_i2s_mic_buf, sample); + _eos_i2s_mic_buf.idx_r += smpl_len; set_csr(mstatus, MSTATUS_MIE); - return ret; + return smpl_len; } -int eos_i2s_mic_pop16(uint16_t *sample) { - int ret; +int eos_i2s_mic_pop(uint16_t *sample) { + int rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_pop16(&_eos_i2s_mic_buf, sample); + rv = _mbuf_pop(sample); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } int eos_i2s_mic_get_vol(void) { @@ -361,95 +364,65 @@ void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm) { set_csr(mstatus, MSTATUS_MIE); } -void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size) { - int run = eos_i2s_running(); - +void eos_i2s_spk_set_buf(uint16_t *spk_arr, uint16_t spk_arr_size) { clear_csr(mstatus, MSTATUS_MIE); _abuf_init(&_eos_i2s_spk_buf, spk_arr, spk_arr_size); - if (run) { - if (spk_arr_size == 0) { - GPIO_REG(GPIO_IOF_EN) &= ~(1 << I2S_PIN_WS_SPK); - } else { - GPIO_REG(GPIO_IOF_EN) |= (1 << I2S_PIN_WS_SPK); - } - } set_csr(mstatus, MSTATUS_MIE); } -uint8_t *eos_i2s_spk_get_buf(void) { +uint16_t *eos_i2s_spk_get_buf(void) { return _eos_i2s_spk_buf.array; } uint16_t eos_i2s_spk_len(void) { - uint16_t ret; + uint16_t rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_len(&_eos_i2s_spk_buf); + rv = _abuf_len(&_eos_i2s_spk_buf); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform) { - uint16_t i; - uint16_t abuf_free; - uint8_t transform_l, transform_r; +uint16_t eos_i2s_spk_write(uint16_t *smpl_buf, uint16_t buf_len) { + int i; + uint16_t sample; + uint16_t abuf_size, abuf_len, smpl_len; clear_csr(mstatus, MSTATUS_MIE); - abuf_free = _eos_i2s_spk_buf.size - _abuf_len(&_eos_i2s_spk_buf); - if (transform) abuf_free = abuf_free / 2; - ssize = MIN(ssize, abuf_free); - set_csr(mstatus, MSTATUS_MIE); - - transform_l = (transform == EOS_I2S_TRANS_MONO2D) || (transform == EOS_I2S_TRANS_MONO2L); - transform_r = (transform == EOS_I2S_TRANS_MONO2D) || (transform == EOS_I2S_TRANS_MONO2R); - if (transform) { - if (_eos_i2s_drvr[I2S_FMT] == EOS_I2S_FMT_PCM16) { - for (i=0; i<ssize / 2; i++) { - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4, _eos_i2s_spk_buf.size)] = transform_l ? sample[i * 2] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 2, _eos_i2s_spk_buf.size)] = transform_r ? sample[i * 2] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 1, _eos_i2s_spk_buf.size)] = transform_l ? sample[i * 2 + 1] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 4 + 3, _eos_i2s_spk_buf.size)] = transform_r ? sample[i * 2 + 1] : 0; - } - } else { - for (i=0; i<ssize; i++) { - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 2, _eos_i2s_spk_buf.size)] = transform_l ? sample[i] : 0; - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i * 2 + 1, _eos_i2s_spk_buf.size)] = transform_r ? sample[i] : 0; - } - } - } else { - for (i=0; i<ssize; i++) { - _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample[i]; - } + abuf_size = _abuf_size(&_eos_i2s_spk_buf); + abuf_len = _abuf_len(&_eos_i2s_spk_buf); + smpl_len = MIN(buf_len, abuf_size - abuf_len); + if (smpl_len && abuf_len) { + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w - 1, _eos_i2s_spk_buf.size)] |= smpl_buf[0] >> 15; } - - if (transform) ssize *= 2; - - clear_csr(mstatus, MSTATUS_MIE); - _eos_i2s_spk_buf.idx_w += ssize; set_csr(mstatus, MSTATUS_MIE); - return ssize; -} + if (smpl_len == 0) return 0; -int eos_i2s_spk_push8(uint8_t sample) { - int ret; + for (i=0; i<smpl_len; i++) { + sample = smpl_buf[i] << 1; + if (i + 1 < smpl_len) { + sample |= (smpl_buf[i + 1] >> 15); + } + _eos_i2s_spk_buf.array[EOS_ABUF_IDX_MASK(_eos_i2s_spk_buf.idx_w + i, _eos_i2s_spk_buf.size)] = sample; + } clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push8(&_eos_i2s_spk_buf, sample); + _eos_i2s_spk_buf.idx_w += smpl_len; set_csr(mstatus, MSTATUS_MIE); - return ret; + return smpl_len; } -int eos_i2s_spk_push16(uint16_t sample) { - int ret; +int eos_i2s_spk_push(uint16_t sample) { + int rv; clear_csr(mstatus, MSTATUS_MIE); - ret = _abuf_push16(&_eos_i2s_spk_buf, sample); + rv = _sbuf_push(sample); set_csr(mstatus, MSTATUS_MIE); - return ret; + return rv; } int eos_i2s_spk_get_vol(void) { @@ -465,3 +438,15 @@ void eos_i2s_spk_set_vol(int vol) { i2s_set_cmp(); set_csr(mstatus, MSTATUS_MIE); } + +void eos_i2s_hp_change(int hp_det) { + if (hp_det) { + int rv; + + rv = eos_hpamp_init(); + if (rv) { + EOS_LOG(EOS_LOG_ERR, "I2S HP CHANGE: PCM1770 INIT ERR:%d\n", rv); + return; + } + } +} diff --git a/fw/fe310/eos/soc/i2s.h b/fw/fe310/eos/soc/i2s.h index c5e92b7..e2155a4 100644 --- a/fw/fe310/eos/soc/i2s.h +++ b/fw/fe310/eos/soc/i2s.h @@ -2,39 +2,41 @@ #include "i2s_def.h" +#define EOS_I2S_MODE_STEREO 0 +#define EOS_I2S_MODE_MONO_L 1 +#define EOS_I2S_MODE_MONO_R 2 + typedef struct EOSABuf { uint16_t idx_r; uint16_t idx_w; uint16_t size; - uint8_t *array; + uint16_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); +int eos_i2s_init(void); +int eos_i2s_start(uint32_t sample_rate, int mode); 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); +int eos_i2s_set_lsgain(int gain); void eos_i2s_mic_set_handler(eos_i2s_handler_t handler, uint16_t wm); -void eos_i2s_mic_set_buf(uint8_t *mic_arr, uint16_t mic_arr_size); -uint8_t *eos_i2s_mic_get_buf(void); +void eos_i2s_mic_set_buf(uint16_t *mic_arr, uint16_t mic_arr_size); +uint16_t *eos_i2s_mic_get_buf(void); 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); +uint16_t eos_i2s_mic_read(uint16_t *smpl_buf, uint16_t buf_size); +int eos_i2s_mic_pop(uint16_t *sample); int eos_i2s_mic_get_vol(void); void eos_i2s_mic_set_vol(int vol); void eos_i2s_spk_set_handler(eos_i2s_handler_t handler, uint16_t wm); -void eos_i2s_spk_set_buf(uint8_t *spk_arr, uint16_t spk_arr_size); -uint8_t *eos_i2s_spk_get_buf(void); +void eos_i2s_spk_set_buf(uint16_t *spk_arr, uint16_t spk_arr_size); +uint16_t *eos_i2s_spk_get_buf(void); uint16_t eos_i2s_spk_len(void); -uint16_t eos_i2s_spk_write(uint8_t *sample, uint16_t ssize, uint8_t transform); -int eos_i2s_spk_push8(uint8_t sample); -int eos_i2s_spk_push16(uint16_t sample); +uint16_t eos_i2s_spk_write(uint16_t *smpl_buf, uint16_t buf_len); +int eos_i2s_spk_push(uint16_t sample); int eos_i2s_spk_get_vol(void); void eos_i2s_spk_set_vol(int vol); + +void eos_i2s_hp_change(int hp_det); diff --git a/fw/fe310/eos/soc/i2s_def.h b/fw/fe310/eos/soc/i2s_def.h index 44eed25..d8c4b4b 100644 --- a/fw/fe310/eos/soc/i2s_def.h +++ b/fw/fe310/eos/soc/i2s_def.h @@ -1,13 +1,2 @@ -#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 - -#define EOS_I2S_TRANS_NONE 0 -#define EOS_I2S_TRANS_MONO2D 1 -#define EOS_I2S_TRANS_MONO2L 2 -#define EOS_I2S_TRANS_MONO2R 3
\ No newline at end of file diff --git a/fw/fe310/eos/soc/i2s_priv.h b/fw/fe310/eos/soc/i2s_priv.h index 25014a5..6927c36 100644 --- a/fw/fe310/eos/soc/i2s_priv.h +++ b/fw/fe310/eos/soc/i2s_priv.h @@ -1,13 +1,10 @@ -#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 -#define I2S_IRQ_SD_ID INT_GPIO_BASE + I2S_PIN_INT +#define I2S_IRQ_ID INT_GPIO_BASE + I2S_PIN_INT #define I2S_CTRL_ADDR_CK PWM0_CTRL_ADDR #define I2S_CTRL_ADDR_WS PWM1_CTRL_ADDR diff --git a/fw/fe310/eos/soc/interrupt.c b/fw/fe310/eos/soc/interrupt.c index dab6fab..2243f0a 100644 --- a/fw/fe310/eos/soc/interrupt.c +++ b/fw/fe310/eos/soc/interrupt.c @@ -1,13 +1,13 @@ #include <stdlib.h> #include <stdint.h> #include <unistd.h> -#include <stdio.h> #include "encoding.h" #include "platform.h" #include "plic_driver.h" #include "eos.h" +#include "log.h" #include "interrupt.h" // Global Instance data for the PLIC @@ -20,13 +20,13 @@ 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); + EOS_LOG(EOS_LOG_ERR, "INTR ERROR:%d\n", int_num); exit(int_num); } return int_num; } -int eos_intr_init(uint8_t wakeup_cause) { +int eos_intr_init(void) { for (int i = 0; i < PLIC_NUM_INTERRUPTS; i++){ ext_interrupt_handler[i] = NULL; } diff --git a/fw/fe310/eos/soc/interrupt.h b/fw/fe310/eos/soc/interrupt.h index c6252b5..6cb446f 100644 --- a/fw/fe310/eos/soc/interrupt.h +++ b/fw/fe310/eos/soc/interrupt.h @@ -4,7 +4,7 @@ typedef void (*eos_intr_handler_t) (void); -int eos_intr_init(uint8_t wakeup_cause); +int eos_intr_init(void); 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); diff --git a/fw/fe310/eos/soc/pwr.c b/fw/fe310/eos/soc/pwr.c index db9f273..84915ef 100644 --- a/fw/fe310/eos/soc/pwr.c +++ b/fw/fe310/eos/soc/pwr.c @@ -12,8 +12,8 @@ #define PWR_RTC_SCALE 15 #define PWR_RTC_SFREQ (EOS_TIMER_RTC_FREQ >> PWR_RTC_SCALE) -int eos_pwr_init(uint8_t wakeup_cause) { - AON_REG(AON_PMUKEY) = 0x51F15E; +int eos_pwr_init(void) { + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUIE) = 0x5; AON_REG(AON_RTCCMP) = 0xFFFFFFFF; @@ -33,7 +33,7 @@ uint8_t eos_pwr_reset_cause(void) { } void eos_pwr_sleep(void) { - AON_REG(AON_PMUKEY) = 0x51F15E; + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUSLEEP) = 1; } @@ -43,8 +43,8 @@ void eos_pwr_wake_at(uint32_t msec) { 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; + pmuie = AON_REG(AON_PMUIE) | (1 << AON_WAKEUPCAUSE_RTC); + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUIE) = pmuie; } @@ -56,7 +56,7 @@ void eos_pwr_wake_disable(void) { AON_REG(AON_RTCHI) = 0; AON_REG(AON_RTCLO) = 0; - pmuie = AON_REG(AON_PMUIE) & ~0x2; - AON_REG(AON_PMUKEY) = 0x51F15E; + pmuie = AON_REG(AON_PMUIE) & ~(1 << AON_WAKEUPCAUSE_RTC); + AON_REG(AON_PMUKEY) = AON_WDOGKEY_VALUE; AON_REG(AON_PMUIE) = pmuie; } diff --git a/fw/fe310/eos/soc/pwr.h b/fw/fe310/eos/soc/pwr.h index 0af4c1b..8aeb0a8 100644 --- a/fw/fe310/eos/soc/pwr.h +++ b/fw/fe310/eos/soc/pwr.h @@ -2,13 +2,13 @@ #define EOS_PWR_WAKE_RST 0 #define EOS_PWR_WAKE_RTC 1 -#define EOS_PWR_WAKE_BTN 2 +#define EOS_PWR_WAKE_PIN 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); +int eos_pwr_init(void); uint8_t eos_pwr_wakeup_cause(void); uint8_t eos_pwr_reset_cause(void); void eos_pwr_sleep(void); diff --git a/fw/fe310/eos/soc/spi.c b/fw/fe310/eos/soc/spi.c index 1806f50..64a057b 100644 --- a/fw/fe310/eos/soc/spi.c +++ b/fw/fe310/eos/soc/spi.c @@ -3,13 +3,16 @@ #include "encoding.h" #include "platform.h" +#include "board.h" #include "eos.h" +#include "log.h" #include "msgq.h" #include "interrupt.h" #include "event.h" -#include "board.h" +#include "dev/egpio.h" +#include "dev/egpio_priv.h" #include "spi.h" #include "spi_priv.h" @@ -21,15 +24,12 @@ #define SPI_FLAG_XCHG 0x10 -#define SPI_CSID_NONE 1 - #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; @@ -40,6 +40,7 @@ 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 { @@ -47,7 +48,7 @@ static void spi_handle_evt(unsigned char type, unsigned char *buffer, uint16_t l } } -int eos_spi_init(uint8_t wakeup_cause) { +int eos_spi_init(void) { int i; for (i=0; i<EOS_SPI_MAX_EVT; i++) { @@ -63,31 +64,31 @@ int eos_spi_init(uint8_t wakeup_cause) { SPI_FMT_DIR(SPI_DIR_RX) | SPI_FMT_LEN(8); - /* for spi 9bit protocol */ - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_MOSI); - GPIO_REG(GPIO_INPUT_EN) |= (1 << IOF_SPI1_MISO); + /* CS assert to SCK: 1 clock cycles + SCK to CS deassert: 0 clock cycles */ + SPI1_REG(SPI_REG_DCSSCK) = 0x01; + + GPIO_REG(GPIO_OUTPUT_XOR) |= SPI_IOF_CSXOR; eos_spi_enable(); return EOS_OK; } -void eos_spi_configure(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt) { +void eos_spi_configure(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt) { spi_state_flags = 0; spi_evt = evt; SPI1_REG(SPI_REG_SCKDIV) = div; - if (csid != -1) { - SPI1_REG(SPI_REG_CSID) = csid; + SPI1_REG(SPI_REG_CSID) = csid; + if (csid != SPI_CSID_NONE) { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; } else { spi_cspin = cspin; - SPI1_REG(SPI_REG_CSID) = SPI_CSID_NONE; SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_OFF; } } -void eos_spi_start(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt) { +void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt) { eos_spi_configure(div, csid, cspin, evt); eos_intr_set_handler(INT_SPI1_BASE, eos_spi_handle_xchg); } @@ -126,7 +127,7 @@ void _eos_spi_xchg_init(unsigned char *buffer, uint16_t len, uint8_t flags) { } static void spi_wait4xchg(void) { - uint8_t done = 0; + int done = 0; while (!done) { clear_csr(mstatus, MSTATUS_MIE); @@ -134,23 +135,25 @@ static void spi_wait4xchg(void) { if (!done) asm volatile ("wfi"); set_csr(mstatus, MSTATUS_MIE); } - spi_in_xchg = 0; } -void eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) { - if (spi_in_xchg) spi_wait4xchg(); +int eos_spi_xchg(unsigned char *buffer, uint16_t len, uint8_t flags) { + if (!spi_evt) return EOS_ERR; + + spi_wait4xchg(); - spi_in_xchg = 1; _eos_spi_xchg_init(buffer, len, flags); - eos_spi_cs_set(); + eos_spi_set_cs(); SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(SPI_SIZE_WM); SPI1_REG(SPI_REG_IE) = SPI_IP_TXWM; + + return EOS_OK; } void eos_spi_handle_xchg(void) { - int i; uint16_t sz_chunk = MIN(spi_state_len - spi_state_idx_tx, SPI_SIZE_CHUNK); + int i; for (i=0; i<sz_chunk; i++) { volatile uint32_t x = SPI1_REG(SPI_REG_TXFIFO); @@ -174,10 +177,18 @@ void eos_spi_handle_xchg(void) { SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); return; } - spi_state_flags &= ~SPI_FLAG_XCHG; - if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_cs_clear(); - SPI1_REG(SPI_REG_IE) = 0x0; - if (spi_evt) eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, spi_state_buf, spi_state_len); + SPI1_REG(SPI_REG_IE) = 0; + if (!(spi_state_flags & EOS_SPI_FLAG_MORE)) eos_spi_clear_cs(); + + /* clear SPI_FLAG_XCHG flag and all of EOS_SPI_FLAG_* */ + spi_state_flags &= (~SPI_FLAG_XCHG & 0xF0); + + if (spi_evt) { + int rv; + + rv = eos_evtq_push_isr(EOS_EVT_SPI | spi_evt, spi_state_buf, spi_state_len); + if (rv) EOS_LOG(EOS_LOG_ERR, "SPI XCHG EVTQ PUSH ERR:%d\n", rv); + } } else { SPI1_REG(SPI_REG_RXCTRL) = SPI_RXWM(MIN(spi_state_len - spi_state_idx_rx - 1, SPI_SIZE_WM - 1)); SPI1_REG(SPI_REG_IE) = SPI_IP_RXWM; @@ -185,23 +196,40 @@ void eos_spi_handle_xchg(void) { } } -void eos_spi_cs_set(void) { - /* cs low */ +int eos_spi_get_cs(void) { if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { - clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << spi_cspin); - set_csr(mstatus, MSTATUS_MIE); + if (spi_cspin & SPI_CSFLAG_EGPIO) { + return !eos_egpio_get_val(spi_cspin & ~SPI_CSFLAG_EGPIO); + } else { + return !(GPIO_REG(GPIO_OUTPUT_VAL) & (1 << spi_cspin)); + } + } else { + return (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_HOLD); + } +} + +void eos_spi_set_cs(void) { + /* cs low */ + if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { + if (spi_cspin & SPI_CSFLAG_EGPIO) { + eos_egpio_set_val(spi_cspin & ~SPI_CSFLAG_EGPIO, 0); + } else { + GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << spi_cspin); + } } else { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_HOLD; } } -void eos_spi_cs_clear(void) { - /* cs high */ +/* can be called from interrupt handler */ +void eos_spi_clear_cs(void) { + /* cs high */ if (SPI1_REG(SPI_REG_CSMODE) == SPI_CSMODE_OFF) { - clear_csr(mstatus, MSTATUS_MIE); - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cspin); - set_csr(mstatus, MSTATUS_MIE); + if (spi_cspin & SPI_CSFLAG_EGPIO) { + eos_egpio_set_val(spi_cspin & ~SPI_CSFLAG_EGPIO, 1); + } else { + GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cspin); + } } else { SPI1_REG(SPI_REG_CSMODE) = SPI_CSMODE_AUTO; } @@ -360,11 +388,18 @@ uint32_t eos_spi_xchg32(uint32_t data, uint8_t flags) { } void eos_spi_flush(void) { - if (spi_in_xchg) { - spi_wait4xchg(); - } else { - SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); - while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM)); - while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY)); - } + uint32_t mcycle_start, mcycle_wait; + + spi_wait4xchg(); + + SPI1_REG(SPI_REG_TXCTRL) = SPI_TXWM(1); + while (!(SPI1_REG(SPI_REG_IP) & SPI_IP_TXWM)); + + /* wait for last frame to be transmitted: 9 spi clock cycles */ + mcycle_wait = 9*2*((SPI1_REG(SPI_REG_SCKDIV) & 0xFFF)+1); + mcycle_start = read_csr(mcycle); + + while ((read_csr(mcycle) - mcycle_start) < mcycle_wait); + + while (!(SPI1_REG(SPI_REG_RXFIFO) & SPI_RXFIFO_EMPTY)); } diff --git a/fw/fe310/eos/soc/spi.h b/fw/fe310/eos/soc/spi.h index 0c2de4b..20999b5 100644 --- a/fw/fe310/eos/soc/spi.h +++ b/fw/fe310/eos/soc/spi.h @@ -1,4 +1,5 @@ #include <stdint.h> + #include "../event.h" #define EOS_SPI_FLAG_TX 0x01 @@ -10,9 +11,9 @@ #define EOS_SPI_MAX_EVT 2 -int eos_spi_init(uint8_t wakeup_cause); -void eos_spi_configure(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt); -void eos_spi_start(uint16_t div, int8_t csid, int8_t cspin, unsigned char evt); +int eos_spi_init(void); +void eos_spi_configure(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt); +void eos_spi_start(uint16_t div, uint8_t csid, uint8_t cspin, unsigned char evt); void eos_spi_stop(void); void eos_spi_enable(void); void eos_spi_disable(void); @@ -20,11 +21,12 @@ void eos_spi_disable(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); +int 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); +int eos_spi_get_cs(void); +void eos_spi_set_cs(void); +void eos_spi_clear_cs(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); diff --git a/fw/fe310/eos/soc/spi9bit.c b/fw/fe310/eos/soc/spi9bit.c index e48e9e2..a536637 100644 --- a/fw/fe310/eos/soc/spi9bit.c +++ b/fw/fe310/eos/soc/spi9bit.c @@ -11,10 +11,10 @@ #include "spi9bit.h" #define BIT_GET ((GPIO_REG(GPIO_INPUT_VAL) & (1 << IOF_SPI1_MISO)) >> IOF_SPI1_MISO) -#define BIT_PUT(b) { clear_csr(mstatus, MSTATUS_MIE); if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); set_csr(mstatus, MSTATUS_MIE); } +#define BIT_PUT(b) { if (b) GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_MOSI); else GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_MOSI); } -#define SCK_UP { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); } -#define SCK_DN { clear_csr(mstatus, MSTATUS_MIE); GPIO_REG(GPIO_OUTPUT_VAL) &= ~(1 << IOF_SPI1_SCK); set_csr(mstatus, MSTATUS_MIE); } +#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; @@ -22,7 +22,19 @@ static inline void _sleep(int n) { while(x) x--; } -/* sck frequency for r/w operations is 0.8Mhz */ +void eos_spi9bit_start(void) { + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_SCK); + GPIO_REG(GPIO_OUTPUT_EN) |= (1 << IOF_SPI1_MOSI); + GPIO_REG(GPIO_INPUT_EN) |= (1 << IOF_SPI1_MISO); +} + +void eos_spi9bit_stop(void) { + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << IOF_SPI1_SCK); + GPIO_REG(GPIO_OUTPUT_EN) &= ~(1 << IOF_SPI1_MOSI); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << IOF_SPI1_MISO); +} + +/* sck frequency for r/w operations is ~ 0.8Mhz */ void eos_spi9bit_read(uint8_t *data) { int i; diff --git a/fw/fe310/eos/soc/spi9bit.h b/fw/fe310/eos/soc/spi9bit.h index dd3c254..fb89856 100644 --- a/fw/fe310/eos/soc/spi9bit.h +++ b/fw/fe310/eos/soc/spi9bit.h @@ -1,4 +1,6 @@ #include <stdint.h> +void eos_spi9bit_start(void); +void eos_spi9bit_stop(void); void eos_spi9bit_read(uint8_t *data); void eos_spi9bit_write(uint8_t dc, uint8_t data); diff --git a/fw/fe310/eos/soc/spi_priv.h b/fw/fe310/eos/soc/spi_priv.h index 17081a3..20e4088 100644 --- a/fw/fe310/eos/soc/spi_priv.h +++ b/fw/fe310/eos/soc/spi_priv.h @@ -3,3 +3,6 @@ /* DO NOT TOUCH THEESE */ #define SPI_SIZE_CHUNK 4 #define SPI_SIZE_WM 2 + +#define SPI_CSFLAG_EGPIO 0x80 +#define SPI_CSID_NONE 1 diff --git a/fw/fe310/eos/soc/timer.c b/fw/fe310/eos/soc/timer.c index 8d74c6d..0573e84 100644 --- a/fw/fe310/eos/soc/timer.c +++ b/fw/fe310/eos/soc/timer.c @@ -48,7 +48,7 @@ void _eos_timer_handle(void) { if (*mtimecmp == 0) clear_csr(mie, MIP_MTIP); } -int eos_timer_init(uint8_t wakeup_cause) { +int eos_timer_init(void) { uint64_t *mtimecmp = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); int i; @@ -75,18 +75,18 @@ 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; + uint32_t rv; 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; + rv = (timer_next[evt] > now) ? (timer_next[evt] - now) * 1000 / EOS_TIMER_RTC_FREQ : 0; } else { - ret = EOS_TIMER_NONE; + rv = EOS_TIMER_NONE; } if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); - return ret; + return rv; } void eos_timer_set(unsigned char evt, uint32_t msec) { @@ -121,24 +121,24 @@ void eos_timer_clear(unsigned char evt) { if (*mtimecmp != 0) set_csr(mie, MIP_MTIP); } -void eos_time_sleep(uint32_t msec) { +void eos_sleep(uint32_t msec) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); uint32_t mtime0 = *mtime; while ((*mtime - mtime0) < (msec * EOS_TIMER_RTC_FREQ / 1000 + 1)); } -uint32_t eos_time_get_tick(void) { +uint32_t eos_get_tick(void) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); return *mtime; } -uint64_t eos_time_get_tick64(void) { +uint64_t eos_get_tick64(void) { volatile uint64_t *mtime = (uint64_t *) (CLINT_CTRL_ADDR + CLINT_MTIME); return *mtime; } -uint32_t eos_time_delta_ms(uint32_t tick) { - return (eos_time_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; +uint32_t eos_tdelta_ms(uint32_t tick) { + return (eos_get_tick() - tick) * 1000 / EOS_TIMER_RTC_FREQ; } diff --git a/fw/fe310/eos/soc/timer.h b/fw/fe310/eos/soc/timer.h index 227aeee..f5c7b4e 100644 --- a/fw/fe310/eos/soc/timer.h +++ b/fw/fe310/eos/soc/timer.h @@ -12,14 +12,14 @@ typedef void (*eos_timer_handler_t) (unsigned char); -int eos_timer_init(uint8_t wakeup_cause); +int eos_timer_init(void); 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); -uint32_t eos_time_get_tick(void); -uint64_t eos_time_get_tick64(void); -uint32_t eos_time_delta_ms(uint32_t tick); +void eos_sleep(uint32_t msec); +uint32_t eos_get_tick(void); +uint64_t eos_get_tick64(void); +uint32_t eos_tdelta_ms(uint32_t tick); diff --git a/fw/fe310/eos/soc/trap_entry.S b/fw/fe310/eos/soc/trap_entry.S index 98f9267..19f4502 100644 --- a/fw/fe310/eos/soc/trap_entry.S +++ b/fw/fe310/eos/soc/trap_entry.S @@ -28,12 +28,10 @@ #define INT_PWM1_BASE 44 #define INT_PWM2_BASE 48 -#define I2S_FMT (0*4) -#define I2S_MODE (1*4) -#define I2S_MIC_WM (2*4) -#define I2S_SPK_WM (3*4) -#define I2S_MIC_EVT (4*4) -#define I2S_SPK_EVT (5*4) +#define I2S_MIC_WM (0*4) +#define I2S_SPK_WM (1*4) +#define I2S_MIC_EVT (2*4) +#define I2S_SPK_EVT (3*4) #include "board.h" #include "irq_def.h" @@ -57,8 +55,8 @@ eos_trap_vector: STORE x22, 6*REGBYTES(sp) STORE x23, 7*REGBYTES(sp) STORE x24, 8*REGBYTES(sp) - STORE x25, 9*REGBYTES(sp) # channel: 0 - left; 1 - right - STORE x26, 10*REGBYTES(sp) # format: 0 - PCM16; 1 - ALAW + STORE x25, 9*REGBYTES(sp) + STORE x26, 10*REGBYTES(sp) # unused STORE x27, 11*REGBYTES(sp) # _eos_i2s_drvr addr csrr x8, mcause @@ -66,7 +64,7 @@ eos_trap_vector: bne x8, x18, handle_intr li x18, PLIC_CLAIM lw x9, 0(x18) - li x18, I2S_IRQ_SD_ID + li x18, I2S_IRQ_ID beq x9, x18, i2s_handle_sd j handle_intr @@ -82,30 +80,22 @@ evtq_push: addi x20, x20, -1 and x20, x20, x19 + + addi x19, x19, 1 + sb x19, MSGQ_OFF_IDXW(x9) + 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 + mv x21, x0 + jalr x0, x22 i2s_handle_sd: - # store channel bit to x25 - li x18, I2S_CTRL_ADDR_WS - lw x18, PWM_CFG(x18) - # 29th - pwmcmp1ip bit - li x19, (1 << 29) - and x25, x18, x19 - srli x25, x25, 29 - la x27, _eos_i2s_drvr - lw x26, I2S_FMT(x27) i2s_abuf_pop: # pop from spk buf -> x8 @@ -115,107 +105,55 @@ i2s_abuf_pop: lhu x20, I2S_ABUF_OFF_SIZE(x9) beqz x20, i2s_sd_xchg - beq x18, x19, 2f + beq x18, x19, 0f addi x20, x20, -1 and x20, x20, x18 - lw x21, I2S_ABUF_OFF_ARRAY(x9) - add x21, x21, x20 - beqz x26, 0f - mv x22, x18 - lbu x8, 0(x21) + addi x18, x18, 1 - j 1f -0: - srli x22, x18, 1 - 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) - # check if buf data is for correct channel if mode is stereo - lw x21, I2S_MODE(x27) - bnez x21, 2f - andi x22, x22, 1 - xor x22, x22, x25 - beqz x22, i2s_abuf_pop + # uint16_t array + slli x20, x20, 1 + lw x21, I2S_ABUF_OFF_ARRAY(x9) + add x21, x21, x20 + lh x8, 0(x21) -2: +0: 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 + bgtu x18, x9, i2s_sd_xchg lw x9, I2S_SPK_EVT(x27) - beqz x9, i2s_decode + beqz x9, i2s_sd_xchg sw x0, I2S_SPK_EVT(x27) # push to event queue jal x22, evtq_push - beqz x21, i2s_decode + beqz x21, i2s_sd_xchg li x18, (EOS_EVT_I2S | EOS_I2S_ETYPE_SPK) sb x18, MSGQ_ITEM_OFF_TYPE(x21) -i2s_decode: - beqz x26, 3f - # aLaw decode -> x8 - xori x8, x8, 0x55 - andi x9, x8, 0x80 - beqz x9, 0f - li x9, (1 << 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: - i2s_sd_xchg: # read/write shift reg: x8 -> sr -> x8 + # values of GPIO_OUTPUT_EN, GPIO_INPUT_EN, GPIO_OUTPUT_VAL registers are NOT changed (no need for clear_csr / set_csr guards outside of interrupt) li x18, GPIO_CTRL_ADDR li x19, (1 << I2S_PIN_SD_IN) li x20, (1 << I2S_PIN_SD_OUT) li x21, (1 << I2S_PIN_SR_CK) lw x22, GPIO_OUTPUT_VAL(x18) - # disable intpu, enable output for I2S_PIN_SD_OUT (pin is low) - lw x9, GPIO_OUTPUT_EN(x18) - or x9, x9, x20 + # disable intput, enable output for I2S_PIN_SD_OUT (pin is low) + lw x24, GPIO_OUTPUT_EN(x18) + or x9, x24, x20 sw x9, GPIO_OUTPUT_EN(x18) not x20, x20 - lw x9, GPIO_INPUT_EN(x18) - and x9, x9, x20 + lw x25, GPIO_INPUT_EN(x18) + and x9, x25, x20 sw x9, GPIO_INPUT_EN(x18) # I2S_PIN_SR_CK bit low (was high) @@ -268,58 +206,19 @@ i2s_sd_xchg: addi x23, x23, -1 bnez x23, 0b - # I2S_PIN_SD_OUT pin low (has pull-dn) + # I2S_PIN_SD_OUT pin low (was low) and x22, x22, x20 # I2S_PIN_SR_CK pin high (74HC595 ck low) xor x22, x22, x21 sw x22, GPIO_OUTPUT_VAL(x18) - # disable output, enable input for I2S_PIN_SD_OUT - lw x9, GPIO_OUTPUT_EN(x18) - xor x9, x9, x20 - sw x9, GPIO_OUTPUT_EN(x18) - lw x9, GPIO_INPUT_EN(x18) - xor x9, x9, x20 - sw x9, GPIO_INPUT_EN(x18) + # restore input/output for I2S_PIN_SD_OUT + sw x24, GPIO_OUTPUT_EN(x18) + sw x25, GPIO_INPUT_EN(x18) slli x8, x8, 16 srai x8, x8, 16 - # skip right mic channel - bnez x25, i2s_sd_complete - -i2s_encode: - beqz x26, 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: # push to mic buf la x9, _eos_i2s_mic_buf @@ -331,27 +230,22 @@ i2s_abuf_push: sub x18, x19, x18 and x18, x18, x21 - beq x18, x20, 2f + beq x18, x20, 0f addi x20, x20, -1 and x20, x20, x19 + + addi x19, x19, 1 + sh x19, I2S_ABUF_OFF_IDXW(x9) + + # uint16_t array + slli x20, x20, 1 lw x21, I2S_ABUF_OFF_ARRAY(x9) add x21, x21, x20 - beqz x26, 0f - sb x8, 0(x21) - addi x19, x19, 1 + sh x8, 0(x21) 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: +0: # check for push to event queue lw x9, I2S_MIC_WM(x27) bltu x18, x9, i2s_sd_complete @@ -371,7 +265,7 @@ i2s_sd_complete: li x19, (1 << I2S_PIN_INT) sw x19, GPIO_FALL_IP(x18) - li x18, I2S_IRQ_SD_ID + li x18, I2S_IRQ_ID li x19, PLIC_CLAIM sw x18, 0(x19) @@ -393,7 +287,8 @@ _eos_i2s_start_pwm: li x18, I2S_CTRL_ADDR_CK li x19, I2S_CTRL_ADDR_WS li x20, I2S_CTRL_ADDR_SR_SEL - li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP | I2S_PWM_SCALE_CK + li x21, PWM_CFG_ENALWAYS | PWM_CFG_ZEROCMP + or x21, x21, a0 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) @@ -414,8 +309,8 @@ _eos_i2s_start_pwm: trap_exit_data: # Remain in M-mode after mret - li x18, MSTATUS_MPP - csrs mstatus, x18 + # li x18, MSTATUS_MPP + # csrs mstatus, x18 LOAD x8, 0*REGBYTES(sp) LOAD x9, 1*REGBYTES(sp) @@ -483,8 +378,8 @@ handle_ext: trap_exit_text: # Remain in M-mode after mret - li t0, MSTATUS_MPP - csrs mstatus, t0 + # li t0, MSTATUS_MPP + # csrs mstatus, t0 LOAD x1, 0*REGBYTES(sp) LOAD x2, 1*REGBYTES(sp) diff --git a/fw/fe310/eos/soc/uart.c b/fw/fe310/eos/soc/uart.c index 1cff781..44c9a52 100644 --- a/fw/fe310/eos/soc/uart.c +++ b/fw/fe310/eos/soc/uart.c @@ -36,7 +36,12 @@ static void uart_handle_intr(void) { } } -int eos_uart_init(uint8_t wakeup_cause) { +void eos_uart_preinit(void) { + eos_uart_speed(EOS_UART_SPEED); + eos_uart_enable(); +} + +int eos_uart_init(void) { int i; for (i=0; i<EOS_UART_MAX_ETYPE; i++) { @@ -45,10 +50,6 @@ int eos_uart_init(uint8_t wakeup_cause) { eos_evtq_set_handler(EOS_EVT_UART, uart_handle_evt); eos_intr_set(INT_UART0_BASE, IRQ_PRIORITY_UART, uart_handle_intr); - eos_uart_speed(EOS_UART_SPEED); - - eos_uart_enable(); - return EOS_OK; } diff --git a/fw/fe310/eos/soc/uart.h b/fw/fe310/eos/soc/uart.h index 41329fb..474942d 100644 --- a/fw/fe310/eos/soc/uart.h +++ b/fw/fe310/eos/soc/uart.h @@ -9,7 +9,8 @@ typedef void (*eos_uart_handler_t) (unsigned char); -int eos_uart_init(uint8_t wakeup_cause); +void eos_uart_preinit(void); +int eos_uart_init(void); void eos_uart_enable(void); void eos_uart_disable(void); int eos_uart_enabled(void); diff --git a/fw/fe310/eos/unicode.c b/fw/fe310/eos/unicode.c index af41d24..ce02ddb 100644 --- a/fw/fe310/eos/unicode.c +++ b/fw/fe310/eos/unicode.c @@ -107,6 +107,7 @@ int utf8_verify(utf8_t *str, size_t str_size, size_t *str_len) { size_t len = 0; int ch_l, rv; + ch_l = 0; while (len < str_size) { if (str_size - len < 4) { rv = utf8_len_str(str + len); |