diff options
Diffstat (limited to 'fw/fe310/eos/dev/ctp.c')
-rw-r--r-- | fw/fe310/eos/dev/ctp.c | 212 |
1 files changed, 212 insertions, 0 deletions
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; +} |