diff options
-rw-r--r-- | fw/fe310/eos/dev/app.c | 25 | ||||
-rw-r--r-- | fw/fe310/eos/dev/app.h | 3 | ||||
-rw-r--r-- | fw/fe310/eos/dev/ctp.c | 212 | ||||
-rw-r--r-- | fw/fe310/eos/dev/ctp.h | 7 | ||||
-rw-r--r-- | fw/fe310/eos/dev/egpio.c | 585 | ||||
-rw-r--r-- | fw/fe310/eos/dev/egpio.h | 151 | ||||
-rw-r--r-- | fw/fe310/eos/dev/eve.c | 213 | ||||
-rw-r--r-- | fw/fe310/eos/dev/eve.h | 33 | ||||
-rw-r--r-- | fw/fe310/eos/dev/hpamp.c | 22 | ||||
-rw-r--r-- | fw/fe310/eos/dev/hpamp.h | 3 | ||||
-rw-r--r-- | fw/fe310/eos/dev/lcd.c | 80 | ||||
-rw-r--r-- | fw/fe310/eos/dev/lcd.h | 2 | ||||
-rw-r--r-- | fw/fe310/eos/dev/spi.c | 122 | ||||
-rw-r--r-- | fw/fe310/eos/dev/spi.h | 12 | ||||
-rw-r--r-- | fw/fe310/eos/dev/spi_cfg.h | 24 |
15 files changed, 1236 insertions, 258 deletions
diff --git a/fw/fe310/eos/dev/app.c b/fw/fe310/eos/dev/app.c new file mode 100644 index 0000000..3c215f4 --- /dev/null +++ b/fw/fe310/eos/dev/app.c @@ -0,0 +1,25 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.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 + return; + } + } +} diff --git a/fw/fe310/eos/dev/app.h b/fw/fe310/eos/dev/app.h new file mode 100644 index 0000000..4ee2e8d --- /dev/null +++ b/fw/fe310/eos/dev/app.h @@ -0,0 +1,3 @@ +#include <stdint.h> + +void eos_app_hp_change(int hp_det);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/ctp.c b/fw/fe310/eos/dev/ctp.c new file mode 100644 index 0000000..fcc3c68 --- /dev/null +++ b/fw/fe310/eos/dev/ctp.c @@ -0,0 +1,212 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.h" + +#include "soc/pwr.h" +#include "soc/i2s.h" +#include "soc/timer.h" +#include "eve/eve.h" +#include "eve/eve_touch_engine.h" + +#include "egpio.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; + + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); + if (rst) { + rv = eos_ctp_reset(); + } else { + rv = eos_ctp_wake(); + } + + return rv; +} + +int eos_ctp_reset(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; + + rv = eos_egpio_intr_disable(); + if (rv) return rv; + + gt911_reset(); + + rv = eos_egpio_intr_set(); + if (rv) return rv; + + return EOS_OK; +} + +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; + + rv = eos_egpio_intr_disable(); + if (rv) return rv; + + rv = gt911_sleep(); + if (rv) return rv; + + rv = eos_egpio_fxl_set_pin(EGPIO_PIN_CTP_INT, FXL6408_REG_PULL_DIR, 0); + if (rv) return rv; + + return EOS_OK; +} + +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; + + rv = eos_egpio_fxl_set_pin(EGPIO_PIN_CTP_INT, FXL6408_REG_PULL_DIR, 1); + if (rv) return rv; + + gt911_wake(); + + rv = eos_egpio_intr_set(); + if (rv) return rv; + + return EOS_OK; +} + +int eos_ctp_give(void) { + int rv; + + if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + if (!eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR; + + rv = eos_egpio_intr_disable(); + if (rv) return rv; + + rv = eve_select(); + if (rv) return rv; + + rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 0); + if (rv) return rv; + + eve_touch_set_engine(EVE_TOUCH_ENGINE_GOODIX); + eve_deselect(); + + rv = eos_egpio_intr_set(); + if (rv) return rv; + + return EOS_OK; +} + +int eos_ctp_take(void) { + int rv; + + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) return EOS_ERR; + + rv = eos_egpio_intr_disable(); + if (rv) return rv; + + rv = eve_select(); + if (rv) return rv; + + eve_touch_set_engine(EVE_TOUCH_ENGINE_HOST); + eve_deselect(); + + rv = eos_egpio_set_val(EGPIO_PIN_CTP_SEL, 1); + if (rv) return rv; + + gt911_reset(); + + rv = eos_egpio_intr_set(); + if (rv) return rv; + + return EOS_OK; +} + +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; + + rv = gt911_get_status(&status); + if (rv) return rv; + if (!(status & 0x80)) return 0; + + num_points = status & 0xf; + if (num_points > 5) { + rv = EOS_ERR; + goto handle_intr_fin; + } + + rv = eve_select(); + if (rv) goto handle_intr_fin; + + start = eos_get_tick(); + while (!eve_touch_ehost_ready()) { + if (eos_tdelta_ms(start) > EVE_CMD_EXEC_TO) break; + } + + if (eos_tdelta_ms(start) > EVE_CMD_EXEC_TO) { + rv = EOS_ERR_TIMEOUT; + eve_deselect(); + goto handle_intr_fin; + } + + 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; + } + + for (i=0; i<num_points; i++) { + uint8_t *point_buf; + uint8_t point_id; + uint16_t point_x; + uint16_t point_y; + + point_buf = points + GT911_SIZE_PBUF * i; + point_id = point_buf[0]; + point_x = point_buf[1] | (point_buf[2] << 8); + point_y = point_buf[3] | (point_buf[4] << 8); + eve_touch_ehost_enter(point_id, point_x, point_y); + } + } else { + eve_touch_ehost_enter(0, 0x8000, 0x8000); + clear_tag0 = 1; + } + + eve_touch_ehost_end(); + eve_deselect(); + +handle_intr_fin: + gt911_set_status(0); + if (rv) { +#ifdef EOS_DEBUG + printf("CTP HANDLE INTR ERR:%d\n", rv); +#endif + return rv; + } + + return 1; +} diff --git a/fw/fe310/eos/dev/ctp.h b/fw/fe310/eos/dev/ctp.h new file mode 100644 index 0000000..72a0a75 --- /dev/null +++ b/fw/fe310/eos/dev/ctp.h @@ -0,0 +1,7 @@ +#include <stdint.h> + +int eos_ctp_init(void); +int eos_ctp_reset(void); +int eos_ctp_sleep(void); +int eos_ctp_wake(void); +int eos_ctp_handle_intr(void);
\ No newline at end of file diff --git a/fw/fe310/eos/dev/egpio.c b/fw/fe310/eos/dev/egpio.c index c17fe81..7358082 100644 --- a/fw/fe310/eos/dev/egpio.c +++ b/fw/fe310/eos/dev/egpio.c @@ -1,30 +1,595 @@ #include <stdlib.h> #include <stdint.h> +#include "encoding.h" +#include "platform.h" +#include "board.h" + #include "eos.h" -#include "soc/i2c.h" +#include "event.h" + +#include "soc/interrupt.h" +#include "soc/timer.h" +#include "soc/pwr.h" +#include "soc/i2s.h" +#include "eve/eve.h" + +#include "batt.h" +#include "sdcard.h" +#include "ctp.h" +#include "eve.h" +#include "app.h" -#include "fxl6408.h" +#include "drv/fxl6408.h" #include "egpio.h" -int eos_egpio_pin_get(uint8_t reg, uint8_t pin, uint8_t *val) { +/* FXL chip only */ +static const uint8_t egpio_switch[2] = { + EGPIO_BIT_SDCARD_DET | EGPIO_BIT_BTN_WAKE, + EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET, +}; + +static uint8_t egpio_pinval[EGPIO_MAX_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; + +#define EGPIO_ALT_EVEAUDIO_DIS 0x01 +#define EGPIO_ALT_LSGAIN_SEL 0x02 +#define EGPIO_ALT_AUDIO_SEL 0x04 + +#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))); \ + if (rv) return rv; \ + } + +static uint8_t pin2alt_bit(uint8_t pin) { + switch (pin) { + case EGPIO_PIN_EVEAUDIO_DIS: + return EGPIO_ALT_EVEAUDIO_DIS; + case EGPIO_PIN_LSGAIN_SEL: + return EGPIO_ALT_LSGAIN_SEL; + case EGPIO_PIN_AUDIO_SEL: + return EGPIO_ALT_AUDIO_SEL; + } + + return 0x00; +} + +static int handle_egpio_intr(uint8_t chip_id, uint8_t intr) { + int rv; + + switch (chip_id) { + case 0: { + 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 (intr & EGPIO_BIT_CTP_INT) { + eos_ctp_handle_intr(); + } + if (intr & EGPIO_BIT_EVE_INT) { + eos_eve_handle_intr(); + } + if (intr & EGPIO_BIT_BTN_WAKE) { + int btn_wake, tdelta; + + btn_wake = eos_egpio_get_val(EGPIO_PIN_BTN_WAKE); + if (btn_wake == 0) { + wake_start = eos_get_tick(); + } 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 (intr & EGPIO_BIT_SDCARD_DET) { + int sdc_det = eos_egpio_get_val(EGPIO_PIN_SDCARD_DET); + + eos_sdc_insert(sdc_det); + if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_SDCARD, sdc_det, 0); + } + break; + } + + case 1: { + 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 (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); + if (i2s_running || app_audio) { + if (i2s_running) { + eos_i2s_hp_change(hp_det); + } else { + eos_app_hp_change(hp_det); + } + + if (hp_det) { + /* store LSGAIN_SEL pin and set EVEAUDIO_DIS pin */ + PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS); + } else { + /* store EVEAUDIO_DIS pin and set LSGAIN_SEL pin */ + PINSWITCH(EGPIO_PIN_EVEAUDIO_DIS, EGPIO_PIN_LSGAIN_SEL); + } + } + if (egpio_intr_handler) egpio_intr_handler(EGPIO_INT_TYPE_HP, hp_det, 0); + } + break; + } + } + + return EOS_OK; +} + +static int handle_egpio_evt(uint8_t chip_id) { + uint8_t intr_reg, def_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 (intr_reg & egpio_switch[chip_id]) { + rv = fxl6408_reg_read(chip_id, FXL6408_REG_I_DEFAULT, &def_reg); + if (rv) return rv; + + def_reg ^= (intr_reg & egpio_switch[chip_id]); + + rv = fxl6408_reg_write(chip_id, FXL6408_REG_I_DEFAULT, def_reg); + if (rv) return rv; + + egpio_pinval[chip_id] ^= (intr_reg & egpio_switch[chip_id]); + } + + rv = handle_egpio_intr(chip_id, intr_reg); + if (rv) return rv; + + return 1; +} + +static void handle_evt(unsigned char type, unsigned char *buffer, uint16_t len) { + type &= ~EOS_EVT_MASK; + + switch (type) { + case EGPIO_ETYPE_INT: { + int rv; + + rv = handle_egpio_evt(0); + if (rv < 0) 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; + 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); + GPIO_REG(GPIO_LOW_IE) |= (1 << EGPIO_PIN_INT); + set_csr(mstatus, MSTATUS_MIE); + break; + } + + case EGPIO_ETYPE_INT_CTP: + case EGPIO_ETYPE_INT_EVE: { + if (eos_egpio_get_val(EGPIO_PIN_CTP_SEL)) { + eos_ctp_handle_intr(); + } else { + eos_eve_handle_intr(); + } + +handle_evt_eve_fin: + clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INT); + GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); + set_csr(mstatus, MSTATUS_MIE); + break; + } + } +} + +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); +} + +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); + } +} + +int eos_egpio_init(void) { + uint8_t wakeup_cause, data, data_dir; + int rst, rv; + + 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); + if (rv) return rv; + rv = fxl6408_reg_read(1, FXL6408_REG_ID_CTRL, &data); + if (rv) return rv; + + rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, 0xff); + if (rv) return rv; + rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, 0xff); + 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); + if (rv) return rv; + + data = EGPIO_BIT_CTP_SEL; + rv = fxl6408_reg_write(0, 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); + 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); + 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); + 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); + if (rv) return rv; + + data = EGPIO_BIT_HPAMP_CS | EGPIO_BIT_AUDIO_SEL; + rv = fxl6408_reg_write(1, 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); + if (rv) return rv; + + data = 0; + rv = fxl6408_reg_write(1, FXL6408_REG_PULL_ENA, data); + if (rv) return rv; + + data = 0; + rv = fxl6408_reg_write(1, FXL6408_REG_PULL_DIR, data); + if (rv) return rv; + } + + rv = fxl6408_reg_read(0, FXL6408_REG_I_STATE, &data); + if (rv) return rv; + data &= egpio_switch[0]; + 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); + if (rv) return rv; + + rv = fxl6408_reg_read(0, FXL6408_REG_IO_DIR, &data_dir); + if (rv) return rv; + rv = fxl6408_reg_read(0, 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); + if (rv) return rv; + data &= egpio_switch[1]; + egpio_pinval[EGPIO_CHIP_FXL1] = data; + rv = fxl6408_reg_write(1, FXL6408_REG_I_DEFAULT, data); + if (rv) return rv; + + rv = fxl6408_reg_read(1, FXL6408_REG_IO_DIR, &data_dir); + if (rv) return rv; + rv = fxl6408_reg_read(1, FXL6408_REG_O_STATE, &data); + if (rv) return rv; + egpio_pinval[EGPIO_CHIP_FXL1] |= (data & data_dir); + + return EOS_OK; +} + +int eos_egpio_run(void) { + uint8_t wakeup_cause, data; + int rst, rv; + + 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); + if (rv) return rv; + + data = ~(EGPIO_BIT_MIC_MUTE | EGPIO_BIT_HP_NDET); + rv = fxl6408_reg_write(1, FXL6408_REG_INT_MASK, data); + if (rv) return rv; + } + + rv = eos_egpio_intr_set(); + if (rv) return rv; + + return EOS_OK; +} + +void eos_egpio_eve_set(uint16_t gpio_reg) { + egpio_pinval[EGPIO_CHIP_EVE] = gpio_reg & 0xff; + 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; + 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); + 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; + } else { + data |= EGPIO_BIT_EVE_INT; + } + } + + rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + if (rv) return rv; + + GPIO_REG(GPIO_INPUT_EN) |= (1 << EVE_PIN_INT); + clear_csr(mstatus, MSTATUS_MIE); + if (app_disp || i2s_running) { + GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); + } else { + GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INT); + } + set_csr(mstatus, MSTATUS_MIE); + + return EOS_OK; +} + +int eos_egpio_intr_set(void) { + return _eos_egpio_intr_set(eos_i2s_running(), !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)); +} + +int eos_egpio_intr_disable(void) { + uint8_t data; + 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); + + rv = fxl6408_reg_write(0, FXL6408_REG_INT_MASK, data); + if (rv) return rv; + + clear_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INT); + set_csr(mstatus, MSTATUS_MIE); + GPIO_REG(GPIO_INPUT_EN) &= ~(1 << EVE_PIN_INT); + + return EOS_OK; +} + +void eos_egpio_set_intr_handler(eos_egpio_intr_handler_t handler) { + egpio_intr_handler = handler; +} + +void eos_egpio_set_ext_handler(eos_egpio_ext_handler_t handler) { + egpio_ext_handler = handler; +} + +int eos_egpio_fxl_get_pin(uint8_t reg, uint8_t pin, uint8_t *val) { uint8_t chip_id; int rv; - chip_id = (pin & EGPIO_PIN_MASK_CHIP_ID) >> 4; + chip_id = EGPIO_PIN2CHIP(pin); pin &= EGPIO_PIN_MASK; - rv = eos_fxl6408_pin_get(chip_id, reg, pin, val); + rv = fxl6408_get_pin(chip_id, reg, pin, val); return rv; } -int eos_egpio_pin_set(uint8_t reg, uint8_t pin, uint8_t val) { +int eos_egpio_fxl_set_pin(uint8_t reg, uint8_t pin, uint8_t val) { uint8_t chip_id; int rv; - chip_id = (pin & EGPIO_PIN_MASK_CHIP_ID) >> 4; + chip_id = EGPIO_PIN2CHIP(pin); pin &= EGPIO_PIN_MASK; - rv = eos_fxl6408_pin_set(chip_id, reg, pin, val); - return rv; -}
\ No newline at end of file + rv = fxl6408_set_pin(chip_id, reg, pin, val); + if (rv) return rv; + + return EOS_OK; +} + +int _eos_egpio_get_val(uint8_t pin) { + uint8_t chip_id; + + chip_id = EGPIO_PIN2CHIP(pin); + + return !!(egpio_pinval[chip_id] & EGPIO_PIN2BIT(pin)); +} + +int _eos_egpio_set_val(uint8_t pin, int val) { + uint8_t chip_id; + int rv; + + val = !!val; + chip_id = EGPIO_PIN2CHIP(pin); + pin &= EGPIO_PIN_MASK; + + if (chip_id == EGPIO_CHIP_EVE) { + rv = eve_select(); + if (rv) return rv; + + /* activate if needed */ + eve_activate(); + + if (pin == EGPIOE_PIN_DISP) pin = EVE_GPIO_DISP; + eve_gpio_set(pin, val); + + /* restore previous power state */ + eve_deactivate(); + eve_deselect(); + } else { + rv = fxl6408_set_pin(chip_id, FXL6408_REG_O_STATE, pin, val); + if (rv) return rv; + } + + BITSET(egpio_pinval[chip_id], EGPIO_PIN2BIT(pin), val); + + return EOS_OK; +} + +int eos_egpio_get_val(uint8_t pin) { + switch (pin) { + case EGPIO_PIN_AUDIO_SEL: { + if (eos_i2s_running()) { + return !!(egpio_alt_pin & pin2alt_bit(pin)); + } + break; + } + + 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); + + if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) { + return !!(egpio_alt_pin & pin2alt_bit(pin)); + } + + if ((pin == EGPIO_PIN_LSGAIN_SEL) && !lspk_on) { + return !!(egpio_alt_pin & pin2alt_bit(pin)); + } + break; + } + } + + return _eos_egpio_get_val(pin); +} + +int eos_egpio_set_val(uint8_t pin, int val) { + uint8_t chip_id; + int rv; + + val = !!val; + switch (pin) { + case EGPIO_PIN_CTP_SEL: { + if (!eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) { + return EOS_ERR_BUSY; + } + break; + } + + case EGPIO_PIN_AUDIO_SEL: { + if (eos_i2s_running()) { + BITSET(egpio_alt_pin, pin2alt_bit(pin), val); + return EOS_OK; + } + + if ((val != _eos_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); + } else { + /* store EVEAUDIO_DIS pin and set LSGAIN_SEL pin */ + PINSWITCH(EGPIO_PIN_EVEAUDIO_DIS, EGPIO_PIN_LSGAIN_SEL); + } + } + break; + } + + 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); + + if ((pin == EGPIO_PIN_EVEAUDIO_DIS) && lspk_on) { + BITSET(egpio_alt_pin, pin2alt_bit(pin), val); + return EOS_OK; + } + + if ((pin == EGPIO_PIN_LSGAIN_SEL) && !lspk_on) { + BITSET(egpio_alt_pin, pin2alt_bit(pin), val); + return EOS_OK; + } + break; + } + } + + rv = _eos_egpio_set_val(pin, val); + if (rv) return rv; + + return EOS_OK; +} + +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)); + if (rv) return rv; + + audio_sel = _eos_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); + if (rv) return rv; + + if (!audio_sel && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { + /* store EVEAUDIO_DIS pin and set LSGAIN_SEL pin */ + PINSWITCH(EGPIO_PIN_EVEAUDIO_DIS, EGPIO_PIN_LSGAIN_SEL); + } + + return EOS_OK; +} + +int eos_egpio_i2s_stop(void) { + int rv, audio_sel; + + rv = _eos_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)); + if (!audio_sel && eos_egpio_get_val(EGPIO_PIN_HP_NDET)) { + /* store LSGAIN_SEL pin and set EVEAUDIO_DIS pin */ + PINSWITCH(EGPIO_PIN_LSGAIN_SEL, EGPIO_PIN_EVEAUDIO_DIS); + } + + rv = _eos_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 e9573a7..7d20443 100644 --- a/fw/fe310/eos/dev/egpio.h +++ b/fw/fe310/eos/dev/egpio.h @@ -1,46 +1,115 @@ #include <stdint.h> -#define EGPIO0_EVE_INT 0x00 /* EVE interrrupt */ -#define EGPIO0_SDCARD_DET 0x01 /* SD Card detect */ -#define EGPIO0_EXP_IO0 0x02 /* expansion io 0 */ -#define EGPIO0_EXP_IO1 0x03 /* expansion io 1 */ -#define EGPIO0_BTN_WAKE 0x04 /* wake button */ -#define EGPIO0_BAT_INT 0x05 /* battery charger IC inetrrupt */ -#define EGPIO0_CTP_SEL 0x06 /* switch CTP connection: EVE_DISP:1 and CTP_SEL:0 - connected to EVE chip, EVE_DISP:1 and CTP_SEL:1 - connected to fe310 chip, EVE_DISP:0 and CTP_SEL:0 - connected to app module */ -#define EGPIO0_CTP_INT 0x07 /* CTP interrupt */ - -#define EGPIO1_MIC_DIS 0x00 /* microphone disable */ -#define EGPIO1_HP_AMP_CS 0x01 /* SPI chip select for headphone amplifier (pcm1770) */ -#define EGPIO1_MIC_SEL 0x02 /* switch mic connection: 0 - connected to app module, 1 - connected to fe310 chip */ -#define EGPIO1_HP_DET 0x03 /* headphone detect */ -#define EGPIO1_USR0 0x04 /* user IO */ -#define EGPIO1_USR1 0x05 -#define EGPIO1_USR2 0x06 -#define EGPIO1_USR3 0x07 - -#define EGPIO_CHIP_ID0 0x00 -#define EGPIO_CHIP_ID1 0x10 - -#define EGPIO_PIN_EVE_INT (EGPIO_CHIP_ID0 | EGPIO0_EVE_INT) -#define EGPIO_PIN_SDCARD_DET (EGPIO_CHIP_ID0 | EGPIO0_SDCARD_DET) -#define EGPIO_PIN_EXP_IO0 (EGPIO_CHIP_ID0 | EGPIO0_EXP_IO0) -#define EGPIO_PIN_EXP_IO1 (EGPIO_CHIP_ID0 | EGPIO0_EXP_IO1) -#define EGPIO_PIN_BTN_WAKE (EGPIO_CHIP_ID0 | EGPIO0_BTN_WAKE) -#define EGPIO_PIN_BAT_INT (EGPIO_CHIP_ID0 | EGPIO0_BAT_INT) -#define EGPIO_PIN_CTP_SEL (EGPIO_CHIP_ID0 | EGPIO0_CTP_SEL) -#define EGPIO_PIN_CTP_INT (EGPIO_CHIP_ID0 | EGPIO0_CTP_INT) - -#define EGPIO_PIN_MIC_DIS (EGPIO_CHIP_ID1 | EGPIO1_MIC_DIS) -#define EGPIO_PIN_HP_AMP_CS (EGPIO_CHIP_ID1 | EGPIO1_HP_AMP_CS) -#define EGPIO_PIN_MIC_SEL (EGPIO_CHIP_ID1 | EGPIO1_MIC_SEL) -#define EGPIO_PIN_HP_DET (EGPIO_CHIP_ID1 | EGPIO1_HP_DET) -#define EGPIO_PIN_USR0 (EGPIO_CHIP_ID1 | EGPIO1_USR0) -#define EGPIO_PIN_USR1 (EGPIO_CHIP_ID1 | EGPIO1_USR1) -#define EGPIO_PIN_USR2 (EGPIO_CHIP_ID1 | EGPIO1_USR2) -#define EGPIO_PIN_USR3 (EGPIO_CHIP_ID1 | EGPIO1_USR3) +#define EGPIO_ETYPE_INT 1 +#define EGPIO_ETYPE_INT_CTP 2 +#define EGPIO_ETYPE_INT_EVE 3 + +#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_ID 0x10 +#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) + +typedef void (*eos_egpio_intr_handler_t) (uint8_t type, int data0, int data1); +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); + +void eos_egpio_set_intr_handler(eos_egpio_intr_handler_t handler); +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); -int eos_egpio_pin_get(uint8_t reg, uint8_t pin, uint8_t *val); -int eos_egpio_pin_set(uint8_t reg, uint8_t pin, uint8_t val); +int eos_egpio_i2s_start(void); +int eos_egpio_i2s_stop(void); diff --git a/fw/fe310/eos/dev/eve.c b/fw/fe310/eos/dev/eve.c index dd72b0f..dad7dfe 100644 --- a/fw/fe310/eos/dev/eve.c +++ b/fw/fe310/eos/dev/eve.c @@ -1,153 +1,192 @@ #include <stdlib.h> -#include <stdio.h> - -#include "platform.h" +#include <stdint.h> #include "eos.h" #include "event.h" -#include "board.h" - -#include "soc/interrupt.h" #include "soc/pwr.h" -#include "soc/i2s.h" +#include "soc/timer.h" #include "eve/eve.h" #include "eve/eve_touch_engine.h" +#include "egpio.h" +#include "spi.h" +#include "aon.h" +#include "pwr.h" + #include "eve.h" -#define EVE_POLL_INTERVAL 2 +#ifdef EOS_DEBUG +#include <stdio.h> +#endif static void handle_time(unsigned char type) { - eve_select(); - eve_handle_time(); - eve_deselect(); -} + int rv; -static void handle_poll(unsigned char type) { - if (eos_eve_intr_enabled()) return; + rv = eve_select(); + if (rv) return; - eve_select(); - eve_handle_intr(); + eve_handle_time(); eve_deselect(); } -static void handle_intr_evt(unsigned char type, unsigned char *buffer, uint16_t len) { - if (!eos_eve_intr_enabled()) return; +int eos_eve_handle_intr(void) { + uint16_t intr_flags; + int rv; + + rv = eve_select(); + if (rv) return 0; - eve_select(); - eve_handle_intr(); + intr_flags = eve_handle_intr(); eve_deselect(); - GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INTR); + if (intr_flags == 0) return 0; + return 1; } -static void handle_intr(void) { - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INTR); - GPIO_REG(GPIO_LOW_IP) = (1 << EVE_PIN_INTR); - eos_evtq_push_isr(EOS_EVT_EVE | EVE_ETYPE_INTR, NULL, 0); -} +int eos_eve_init(void) { + uint8_t wakeup_cause; + uint16_t gpio_reg; + int rst, rv; -int eos_eve_init(uint8_t wakeup_cause) { - int rst = (wakeup_cause == EOS_PWR_WAKE_RST); - int rv = EVE_OK; + rv = eve_select(); + if (rv) return rv; - eve_select(); + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); if (rst) { rv = eve_init(); - if (!rv) { - eve_gpio_set_dir(EVE_GPIO_DIR); - eve_touch_init_engine(); - } + if (rv) goto eve_init_fin; + + eve_gpio_write(EVE_GPIO_DEFAULT); + eve_gpio_write_dir(EVE_GPIO_DIR); + 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_activate(); + gpio_reg = eve_gpio_read(); + eve_cmd_set_offset(); + if (gpio_reg & EVE_GPIO_DISP) { + eve_pwr_set_state(EVE_PSTATE_ACTIVE); + } + eve_deactivate(); } + +eve_init_fin: eve_deselect(); - if (rv) return EOS_ERR; + if (rv) return rv; - eve_touch_init(); + eos_egpio_eve_set(gpio_reg); - eos_evtq_set_handler(EOS_EVT_EVE, handle_intr_evt); + eve_touch_init(); eos_timer_set_handler(EOS_TIMER_ETYPE_UI, handle_time); - eos_intr_set_handler(INT_GPIO_BASE + EVE_PIN_INTR, handle_intr); - eos_intr_set_priority(INT_GPIO_BASE + EVE_PIN_INTR, IRQ_PRIORITY_EVE); return EOS_OK; } -void eos_eve_calibrate(void) { +int eos_eve_run(void) { + int rv; + + if (eve_pwr_state() != EVE_PSTATE_ACTIVE) return EOS_ERR_BUSY; + + rv = eve_select(); + if (rv) return rv; + + eve_touch_intr_enable(); + eve_touch_start(); + eve_intr_enable(); + eve_clk_start(); + eve_deselect(); + + return EOS_OK; +} + +int eos_eve_sleep(void) { + int rv; + + rv = eve_select(); + if (rv) return rv; + + eos_aon_save4eve(eve_pwr_state()); + eve_clk_stop(); + eve_intr_disable(); + eve_touch_stop(); + eve_touch_intr_disable(); + eve_pwr_sleep(); + eve_deselect(); + + return EOS_OK; +} + +void eve_calibrate(void) { + int rv, d; +#ifdef EOS_DEBUG uint32_t matrix[6]; - int r; +#endif - eve_select(); + if (!eve_selected()) { +#ifdef EOS_DEBUG + printf("EVE CALIBRATE: NOT SELECTED\n"); +#endif + return; + } - eve_brightness(0x40); eve_touch_set_extended(0); eve_cmd(CMD_TEXT, "hhhhs", EVE_HSIZE/2, EVE_VSIZE/2, 27, EVE_OPT_CENTER, "Please tap on the dot."); eve_cmd(CMD_CALIBRATE, "w", 0); eve_cmd_exec(0); + rv = EOS_OK; do { - r = eve_cmd_done(); - if (r < 0) break; + d = eve_cmd_done(); + if (d < 0) { + rv = d; + break; + } eve_deselect(); eos_evtq_exec(); - eve_select(); - } while (!r); + rv = eve_select(); + if (rv) { +#ifdef EOS_DEBUG + printf("EVE CALIBRATE ERR:%d\n", rv); +#endif + return; + } + } while (!d); eve_touch_set_extended(1); - eve_brightness(0); - eve_touch_get_matrix(matrix); - eve_deselect(); +#ifdef EOS_DEBUG + if (rv) { + printf("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 } -void eos_eve_set_tmatrix(const uint32_t *matrix) { - eve_select(); - eve_touch_set_matrix(matrix); - eve_deselect(); -} - -int eos_eve_run(uint8_t wakeup_cause) { - eve_select(); - eve_touch_start(); - eve_intr_enable(); - eve_clk_start(); - eve_deselect(); - - eos_eve_intr_enable(); - return EOS_OK; -} +int eve_select(void) { + int rv; -void eos_eve_intr_enable(void) { - GPIO_REG(GPIO_INPUT_EN) |= (1 << EVE_PIN_INTR); - GPIO_REG(GPIO_LOW_IE) |= (1 << EVE_PIN_INTR); - - eos_intr_enable(INT_GPIO_BASE + EVE_PIN_INTR); - eos_timer_set_handler(EOS_TIMER_ETYPE_EVE, NULL); + rv = eos_spi_select(EOS_SPI_DEV_EVE); + return rv; } -void eos_eve_intr_disable(void) { - eos_intr_disable(INT_GPIO_BASE + EVE_PIN_INTR); - - GPIO_REG(GPIO_LOW_IE) &= ~(1 << EVE_PIN_INTR); - GPIO_REG(GPIO_INPUT_EN) &= ~(1 << EVE_PIN_INTR); - eos_timer_set_handler(EOS_TIMER_ETYPE_EVE, handle_poll); +void eve_deselect(void) { + eos_spi_deselect(); } -int eos_eve_intr_enabled(void) { - return !!(GPIO_REG(GPIO_INPUT_EN) & (1 << EVE_PIN_INTR)); -} - -void eos_eve_poll(void) { - if (eos_eve_intr_enabled()) return; - if (eos_timer_get(EOS_TIMER_ETYPE_EVE) != EOS_TIMER_NONE) return; - - eos_timer_set(EOS_TIMER_ETYPE_EVE, EVE_POLL_INTERVAL); +int eve_selected(void) { + return (eos_spi_dev() == EOS_SPI_DEV_EVE); } diff --git a/fw/fe310/eos/dev/eve.h b/fw/fe310/eos/dev/eve.h index 1317bec..441cd5a 100644 --- a/fw/fe310/eos/dev/eve.h +++ b/fw/fe310/eos/dev/eve.h @@ -1,17 +1,24 @@ #include <stdint.h> -#define EVE_GPIO_DIR 0xf +#define EVE_GPIO_DIR 0x800f +#define EVE_GPIO_DEFAULT 0x2 /* EVEAUDIO_DIS */ +#define EVE_GPIO_MASK 0x800f -#define EVE_GPIO_CAM 0 -#define EVE_GPIO_LCD_EN 1 -#define EVE_GPIO_GAIN 2 -#define EVE_GPIO_HAPT 3 +#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_init(uint8_t wakeup_cause); -void eos_eve_calibrate(void); -void eos_eve_set_tmatrix(const uint32_t *matrix); -int eos_eve_run(uint8_t wakeup_cause); -void eos_eve_intr_enable(void); -void eos_eve_intr_disable(void); -int eos_eve_intr_enabled(void); -void eos_eve_poll(void); +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 eve_calibrate(void); +int eve_select(void); +void eve_deselect(void); +int eve_selected(void); diff --git a/fw/fe310/eos/dev/hpamp.c b/fw/fe310/eos/dev/hpamp.c new file mode 100644 index 0000000..10a95fa --- /dev/null +++ b/fw/fe310/eos/dev/hpamp.c @@ -0,0 +1,22 @@ +#include <stdlib.h> +#include <stdint.h> + +#include "eos.h" + +#include "soc/spi.h" +#include "spi.h" + +#include "drv/pcm1770.h" +#include "hpamp.h" + +int eos_hpamp_init(void) { + int rv; + + rv = eos_spi_select(EOS_SPI_DEV_HPAMP); + if (rv) return rv; + + pcm1770_reg_write(0x03, 0x01); + eos_spi_deselect(); + + return EOS_OK; +} diff --git a/fw/fe310/eos/dev/hpamp.h b/fw/fe310/eos/dev/hpamp.h new file mode 100644 index 0000000..07157bb --- /dev/null +++ b/fw/fe310/eos/dev/hpamp.h @@ -0,0 +1,3 @@ +#include <stdint.h> + +int eos_hpamp_init(void); diff --git a/fw/fe310/eos/dev/lcd.c b/fw/fe310/eos/dev/lcd.c index 59215dc..6c005b9 100644 --- a/fw/fe310/eos/dev/lcd.c +++ b/fw/fe310/eos/dev/lcd.c @@ -2,48 +2,47 @@ #include <stdint.h> #include "platform.h" +#include "board.h" #include "eos.h" -#include "board.h" - -#include "soc/timer.h" +#include "soc/pwr.h" #include "soc/i2s.h" +#include "soc/timer.h" + #include "eve/eve.h" +#include "egpio.h" +#include "spi.h" #include "eve.h" -#include "gt911.h" -#include "ili9806e.h" +#include "pwr.h" +#include "drv/ili9806e.h" #include "lcd.h" static int lcd_enable(void) { int rv; - rv = eos_spi_select(EOS_SPI_DEV_EVE); - if (rv) return rv; - - eve_gpio_set(EVE_GPIO_LCD_EN, 1); - eos_spi_deselect(); + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; - return EOS_OK; + rv = eos_egpio_set_val(EGPIO_PIN_LCD_EN, 1); + return rv; } static int lcd_disable(void) { int rv; - rv = eos_spi_select(EOS_SPI_DEV_EVE); - if (rv) return rv; - - eve_gpio_set(EVE_GPIO_LCD_EN, 0); - eos_spi_deselect(); + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; - return EOS_OK; + rv = eos_egpio_set_val(EGPIO_PIN_LCD_EN, 0); + return rv; } static int lcd_select(void) { int rv; + if (eos_i2s_running() || !eos_egpio_get_val(EGPIO_PIN_DISP_SEL)) return EOS_ERR_BUSY; + GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << SPI_CSPIN_LCD); GPIO_REG(GPIO_OUTPUT_EN) |= (1 << SPI_CSPIN_LCD); @@ -72,7 +71,7 @@ static int lcd_init(void) { rv = lcd_enable(); if (rv) return rv; - eos_time_sleep(200); + eos_sleep(200); rv = lcd_select(); if (rv) { @@ -80,7 +79,7 @@ static int lcd_init(void) { return rv; } - rv = eos_ili9806e_init(); + rv = ili9806e_init(); if (rv == EOS_ERR_NOTFOUND) eve_lcd_absent(); lcd_deselect(); @@ -94,51 +93,38 @@ static int lcd_sleep(void) { rv = lcd_select(); if (rv) return rv; - eos_ili9806e_sleep(); + ili9806e_sleep(); lcd_deselect(); rv = lcd_disable(); - if (rv) return rv; - - return EOS_OK; + return rv; } -int eos_lcd_init(uint8_t wakeup_cause) { - int rv; +int eos_lcd_init(void) { + uint8_t wakeup_cause; + int rv, rst; - rv = lcd_init(); - if (rv) return rv; - - rv = eos_gt911_init(wakeup_cause); - if (rv) return rv; + wakeup_cause = eos_pwr_wakeup_cause(); + rst = (wakeup_cause == EOS_PWR_WAKE_RST); + if (rst) { + rv = lcd_init(); + } else { + rv = eos_lcd_wake(); + } - return EOS_OK; + return rv; } int eos_lcd_sleep(void) { int rv; - if (eos_i2s_running()) return EOS_ERR_BUSY; - - /* There is a problem with GT911 and sleep */ - // eos_gt911_sleep(); - rv = lcd_sleep(); - if (rv) return rv; - - return EOS_OK; + return rv; } int eos_lcd_wake(void) { int rv; - if (eos_i2s_running()) return EOS_ERR_BUSY; - rv = lcd_init(); - if (rv) return rv; - - /* There is a problem with GT911 and sleep */ - // eos_gt911_wake(); - - return EOS_OK; + return rv; } diff --git a/fw/fe310/eos/dev/lcd.h b/fw/fe310/eos/dev/lcd.h index 7ca2f7d..fafe2b4 100644 --- a/fw/fe310/eos/dev/lcd.h +++ b/fw/fe310/eos/dev/lcd.h @@ -1,5 +1,5 @@ #include <stdint.h> -int eos_lcd_init(uint8_t wakeup_cause); +int eos_lcd_init(void); int eos_lcd_sleep(void); int eos_lcd_wake(void); diff --git a/fw/fe310/eos/dev/spi.c b/fw/fe310/eos/dev/spi.c index 12549fc..fef00e1 100644 --- a/fw/fe310/eos/dev/spi.c +++ b/fw/fe310/eos/dev/spi.c @@ -12,72 +12,112 @@ #include "soc/interrupt.h" #include "soc/spi.h" +#include "soc/spi_priv.h" #include "net.h" +#include "egpio.h" #include "spi.h" #include "spi_cfg.h" -static uint8_t spi_dev; -static uint8_t spi_lock; +#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]; -int eos_spi_dev_init(uint8_t wakeup_cause) { +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) { + 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(); + } +} + +static void spi_start(unsigned char dev) { + if (dev == EOS_SPI_DEV_NET) { + eos_net_start(); + } 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(); + } else { + eos_spi_start(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); + } +} + +int eos_spi_dev_init(void) { int i; for (i=0; i<EOS_SPI_MAX_DEV; i++) { spi_div[i] = spi_cfg[i].div; - if (!(spi_cfg[i].flags & SPI_DEV_FLAG_CSFLOAT) && (spi_cfg[i].cspin != -1)) { - GPIO_REG(GPIO_OUTPUT_VAL) |= (1 << spi_cfg[i].cspin); - GPIO_REG(GPIO_OUTPUT_EN) |= (1 << spi_cfg[i].cspin); - } + } + + for (i=0; i<EOS_SPI_MAX_DSTACK; i++) { + spi_dstack[i] = 0xff; } return EOS_OK; } int eos_spi_select(unsigned char dev) { - if (spi_lock) return EOS_ERR_BUSY; + int rv; + int dsel; - if (spi_cfg[spi_dev].flags & SPI_DEV_FLAG_9BIT) { - eos_spi_enable(); - } else { - if (spi_dev == EOS_SPI_DEV_NET) { - eos_net_stop(); - } else { - eos_spi_stop(); - } + 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; } - spi_dev = dev; - if (spi_cfg[dev].flags & SPI_DEV_FLAG_9BIT) { - eos_spi_configure(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); - eos_spi_disable(); - } else { - if (dev == EOS_SPI_DEV_NET) { - eos_net_start(); - } else { - eos_spi_start(spi_div[dev], spi_cfg[dev].csid, spi_cfg[dev].cspin, spi_cfg[dev].evt); - } + dsel = 1; + if (spi_dev() == dev) { + dev |= EOS_SPI_DEV_FLAG_NDSEL; + dsel = 0; } + if (dsel) spi_stop(spi_dev()); + + spi_dstack[spi_dstack_len] = dev; + spi_dstack_len++; + + if (dsel) spi_start(dev); + return EOS_OK; } -int eos_spi_deselect(void) { - if (spi_lock) return EOS_ERR_BUSY; - if (spi_dev == EOS_SPI_DEV_NET) return EOS_ERR; +void eos_spi_deselect(void) { + int rv; + int dsel; - if (spi_cfg[spi_dev].flags & SPI_DEV_FLAG_9BIT) { - eos_spi_enable(); - } else { - eos_spi_stop(); + 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; } - spi_dev = EOS_SPI_DEV_NET; - eos_net_start(); + dsel = !(spi_dev() & EOS_SPI_DEV_FLAG_NDSEL); + if (dsel) spi_stop(spi_dev()); - return EOS_OK; + spi_dstack_len--; + spi_dstack[spi_dstack_len] = 0xff; + + if (dsel) spi_start(spi_dev()); } void eos_spi_dev_configure(unsigned char dev) { @@ -85,7 +125,7 @@ void eos_spi_dev_configure(unsigned char dev) { } uint8_t eos_spi_dev(void) { - return spi_dev; + return spi_dev(); } uint16_t eos_spi_div(unsigned char dev) { @@ -100,14 +140,6 @@ uint8_t eos_spi_cspin(unsigned char dev) { return spi_cfg[dev].cspin; } -void eos_spi_lock(void) { - spi_lock = 1; -} - -void eos_spi_unlock(void) { - spi_lock = 0; -} - void eos_spi_set_div(unsigned char dev, uint16_t div) { spi_div[dev] = div; } diff --git a/fw/fe310/eos/dev/spi.h b/fw/fe310/eos/dev/spi.h index c899e83..29315af 100644 --- a/fw/fe310/eos/dev/spi.h +++ b/fw/fe310/eos/dev/spi.h @@ -4,11 +4,15 @@ #define EOS_SPI_DEV_EVE 1 #define EOS_SPI_DEV_SDC 2 #define EOS_SPI_DEV_CAM 3 -#define EOS_SPI_DEV_LCD 4 +#define EOS_SPI_DEV_HPAMP 4 +#define EOS_SPI_DEV_LCD 5 -int eos_spi_dev_init(uint8_t wakeup_cause); +#define EOS_SPI_MAX_DSTACK 3 +#define EOS_SPI_DEV_FLAG_NDSEL 0x80 + +int eos_spi_dev_init(void); int eos_spi_select(unsigned char dev); -int eos_spi_deselect(void); +void eos_spi_deselect(void); void eos_spi_dev_configure(unsigned char dev); uint8_t eos_spi_dev(void); @@ -16,6 +20,4 @@ uint16_t eos_spi_div(unsigned char dev); uint8_t eos_spi_csid(unsigned char dev); uint8_t eos_spi_cspin(unsigned char dev); -void eos_spi_lock(void); -void eos_spi_unlock(void); void eos_spi_set_div(unsigned char dev, uint16_t div); diff --git a/fw/fe310/eos/dev/spi_cfg.h b/fw/fe310/eos/dev/spi_cfg.h index 6a5d7b4..6ef92aa 100644 --- a/fw/fe310/eos/dev/spi_cfg.h +++ b/fw/fe310/eos/dev/spi_cfg.h @@ -1,17 +1,16 @@ #include <stdint.h> -#define EOS_SPI_MAX_DEV 5 - typedef struct { uint16_t div; - int8_t csid; - int8_t cspin; + uint8_t csid; + uint8_t cspin; uint8_t flags; unsigned char evt; } SPIConfig; -#define SPI_DEV_FLAG_9BIT 0x1 -#define SPI_DEV_FLAG_CSFLOAT 0x2 +#define SPI_DEV_FLAG_9BIT 0x01 + +#define EOS_SPI_MAX_DEV 6 static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { { // DEV_NET @@ -42,11 +41,18 @@ static const SPIConfig spi_cfg[EOS_SPI_MAX_DEV] = { .flags = 0, .evt = EOS_SPI_EVT_CAM, }, + { // DEV_HPAMP + .div = SPI_DIV_HPAMP, + .csid = SPI_CSID_HPAMP, + .cspin = SPI_CSPIN_HPAMP, + .flags = 0, + .evt = 0, + }, { // DEV_LCD 9bit spi - .div = 0, - .csid = -1, + .div = SPI_DIV_LCD, + .csid = SPI_CSID_LCD, .cspin = SPI_CSPIN_LCD, - .flags = SPI_DEV_FLAG_9BIT | SPI_DEV_FLAG_CSFLOAT, + .flags = SPI_DEV_FLAG_9BIT, .evt = 0, }, }; |