diff --git a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp index ed78c7ca3..03f932559 100644 --- a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp @@ -187,17 +187,22 @@ int stm32_i2c_write(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, return 0; } -int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout) +int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t retries, uint32_t timeout) { I2C_HandleTypeDef* h = get_i2c_handle(bus); - if (!h) return -1; + if (!h) return -1; - HAL_StatusTypeDef err = HAL_I2C_IsDeviceReady(h, addr << 1, (uint32_t)-1, timeout); + HAL_StatusTypeDef err = HAL_I2C_IsDeviceReady(h, addr << 1, retries, timeout); if (err != HAL_OK) return -1; return 0; } +int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout) +{ + return stm32_i2c_is_dev_ready(bus, addr, 1, timeout); +} + static int i2c_enable_gpio_clock(GPIO_TypeDef *GPIOx) { if (GPIOx == GPIOA) diff --git a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h index a5632b6a5..8458a1f37 100644 --- a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h +++ b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.h @@ -51,4 +51,6 @@ int stm32_i2c_read(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, int stm32_i2c_write(uint8_t bus, uint16_t addr, uint16_t reg, uint16_t reg_size, uint8_t* data, uint16_t len, uint32_t timeout); +int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t retries, uint32_t timeout); int stm32_i2c_is_dev_ready(uint8_t bus, uint16_t addr, uint32_t timeout); + diff --git a/radio/src/targets/nv14/touch_driver.cpp b/radio/src/targets/nv14/touch_driver.cpp index 875f92a74..079ddc6fb 100644 --- a/radio/src/targets/nv14/touch_driver.cpp +++ b/radio/src/targets/nv14/touch_driver.cpp @@ -41,15 +41,28 @@ volatile static bool touchEventOccured; #define TOUCH_SDA_GPIO_PIN I2C_B1_SDA_GPIO_PIN // PB.09 #define TOUCH_FT6236_I2C_ADDRESS (0x70>>1) +#define TOUCH_CST836U_I2C_ADDRESS (0x15) -uint8_t ft6x06[FT6x06_MAX_INSTANCE] = {0}; -static ft6x06_handle_TypeDef ft6x06_handle = {FT6206_I2C_NOT_INITIALIZED, 0, 0}; +enum TouchControllers {TC_NONE, TC_FT6236, TC_CST836U}; +TouchControllers touchController = TC_NONE; + +static tc_handle_TypeDef tc_handle = {0, 0}; tmr10ms_t downTime = 0; tmr10ms_t tapTime = 0; short tapCount = 0; #define TAP_TIME 25 +struct TouchControllerDescriptor +{ + void (*read)(uint16_t * X, uint16_t * Y, uint32_t * event); + uint8_t (*detectTouch)(); + void (*printDebugInfo)(); + uint32_t contactEvent; +}; + +static const TouchControllerDescriptor *tc = nullptr; + static TouchState internalTouchState = {}; void I2C_FreeBus() @@ -179,12 +192,22 @@ void I2C_Init() bool touch_i2c_read(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t len) { - if (stm32_i2c_read(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0) - return false; + if(touchController == TC_CST836U) + { + if(stm32_i2c_master_tx(TOUCH_I2C_BUS, addr, ®, 1, 3) < 0) + return false; + delay_us(5); + if(stm32_i2c_master_rx(TOUCH_I2C_BUS, addr, data, len, I2C_TIMEOUT_MAX) < 0) + return false; + } else { + if (stm32_i2c_read(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0) + return false; + } return true; } +#if 0 static bool touch_i2c_write(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t len) { if (stm32_i2c_write(TOUCH_I2C_BUS, addr, reg, 1, data, len, I2C_TIMEOUT_MAX) < 0) @@ -193,7 +216,6 @@ static bool touch_i2c_write(uint8_t addr, uint8_t reg, uint8_t * data, uint8_t l return true; } - static void TS_IO_Write(uint8_t addr, uint8_t reg, uint8_t data) { uint8_t tryCount = 3; @@ -202,6 +224,7 @@ static void TS_IO_Write(uint8_t addr, uint8_t reg, uint8_t data) I2C_Init(); } } +#endif static uint8_t TS_IO_Read(uint8_t addr, uint8_t reg) { @@ -224,21 +247,16 @@ static uint16_t TS_IO_ReadMultiple(uint8_t addr, uint8_t reg, uint8_t * buffer, return 1; } -static uint8_t TS_IO_Read(uint8_t reg) -{ - return TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, reg); -} - static void touch_ft6236_debug_info(void) { #if defined(DEBUG) - TRACE("ft6x36: thrhld = %d", TS_IO_Read(TOUCH_FT6236_REG_TH_GROUP) * 4); - TRACE("ft6x36: rep rate=", TS_IO_Read(TOUCH_FT6236_REG_PERIODACTIVE) * 10); - TRACE("ft6x36: fw lib 0x%02X %02X", TS_IO_Read(TOUCH_FT6236_REG_LIB_VER_H), TS_IO_Read(TOUCH_FT6236_REG_LIB_VER_L)); - TRACE("ft6x36: fw v 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_FIRMID)); - TRACE("ft6x36: CHIP ID 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_CIPHER)); - TRACE("ft6x36: CTPM ID 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_FOCALTECH_ID)); - TRACE("ft6x36: rel code 0x%02X", TS_IO_Read(TOUCH_FT6236_REG_RELEASE_CODE_ID)); + TRACE("ft6x36: thrhld = %d", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_TH_GROUP) * 4); + TRACE("ft6x36: rep rate=", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_PERIODACTIVE) * 10); + TRACE("ft6x36: fw lib 0x%02X %02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_H), TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_LIB_VER_L)); + TRACE("ft6x36: fw v 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FIRMID)); + TRACE("ft6x36: CHIP ID 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_CIPHER)); + TRACE("ft6x36: CTPM ID 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_FOCALTECH_ID)); + TRACE("ft6x36: rel code 0x%02X", TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, TOUCH_FT6236_REG_RELEASE_CODE_ID)); #endif } @@ -249,22 +267,22 @@ static void touch_ft6236_debug_info(void) * @param DeviceAddr: Device address on communication Bus. * @retval : Number of active touches detected (can be 0, 1 or 2). */ -static uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr) +static uint8_t ft6x06_TS_DetectTouch() { volatile uint8_t nbTouch = 0; /* Read register FT6206_TD_STAT_REG to check number of touches detection */ - nbTouch = TS_IO_Read(DeviceAddr, FT6206_TD_STAT_REG); + nbTouch = TS_IO_Read(TOUCH_FT6236_I2C_ADDRESS, FT6206_TD_STAT_REG); nbTouch &= FT6206_TD_STAT_MASK; if (nbTouch > FT6206_MAX_DETECTABLE_TOUCH) { /* If invalid number of touch detected, set it to zero */ nbTouch = 0; } /* Update ft6x06 driver internal global : current number of active touches */ - ft6x06_handle.currActiveTouchNb = nbTouch; + tc_handle.currActiveTouchNb = nbTouch; /* Reset current active touch index on which to work on */ - ft6x06_handle.currActiveTouchIdx = 0; + tc_handle.currActiveTouchIdx = 0; return (nbTouch); } @@ -325,19 +343,19 @@ static void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr, /** * @brief Get the touch screen X and Y positions values * Manage multi touch thanks to touch Index global - * variable 'ft6x06_handle.currActiveTouchIdx'. + * variable 'tc_handle.currActiveTouchIdx'. * @param DeviceAddr: Device address on communication Bus. * @param X: Pointer to X position value * @param Y: Pointer to Y position value * @retval None. */ -static void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t * X, uint16_t * Y, uint32_t * event) +static void ft6x06_TS_GetXY(uint16_t * X, uint16_t * Y, uint32_t * event) { uint8_t regAddress = 0; uint8_t dataxy[4]; - if (ft6x06_handle.currActiveTouchIdx < ft6x06_handle.currActiveTouchNb) { - switch (ft6x06_handle.currActiveTouchIdx) { + if (tc_handle.currActiveTouchIdx < tc_handle.currActiveTouchNb) { + switch (tc_handle.currActiveTouchIdx) { case 0 : regAddress = FT6206_P1_XH_REG; break; @@ -350,7 +368,7 @@ static void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t * X, uint16_t * Y, uin } /* Read X and Y positions */ - TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy)); + TS_IO_ReadMultiple(TOUCH_FT6236_I2C_ADDRESS, regAddress, dataxy, sizeof(dataxy)); /* Send back ready X position to caller */ *X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK); /* Send back ready Y position to caller */ @@ -362,29 +380,127 @@ static void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t * X, uint16_t * Y, uin uint32_t area; ft6x06_TS_GetTouchInfo(DeviceAddr, ft6x06_handle.currActiveTouchIdx, &weight, &area, event); */ - ft6x06_handle.currActiveTouchIdx++; + tc_handle.currActiveTouchIdx++; } } +static void touch_cst836u_debug_info(void) +{ +#if defined(DEBUG) + TRACE("cst836u: fw ver 0x%02X %02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_FW_VERSION_H_REG), TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_FW_VERSION_L_REG)); + TRACE("cst836u: module version 0x%02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_MODULE_VERSION_REG)); + TRACE("cst836u: project name 0x%02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_PROJECT_NAME_REG)); + TRACE("cst836u: chip type 0x%02X 0x%02X", TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_CHIP_TYPE_H_REG), TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_CHIP_TYPE_L_REG)); +#endif +} + +/** + * @brief Get the touch screen X and Y positions values + * Manage multi touch thanks to touch Index global + * variable 'tc_handle.currActiveTouchIdx'. + * @param DeviceAddr: Device address on communication Bus. + * @param X: Pointer to X position value + * @param Y: Pointer to Y position value + * @retval None. + */ +static void cst836u_TS_GetXY(uint16_t * X, uint16_t * Y, uint32_t * event) +{ + uint8_t regAddress = 0; + uint8_t dataxy[4]; + + if (tc_handle.currActiveTouchIdx < tc_handle.currActiveTouchNb) { + switch (tc_handle.currActiveTouchIdx) { + case 0 : + regAddress = CST836U_TOUCH1_XH_REG; + break; + case 1 : + regAddress = CST836U_TOUCH2_XH_REG; + break; + default : + break; + } + + /* Read X and Y positions */ + TS_IO_ReadMultiple(TOUCH_CST836U_I2C_ADDRESS, regAddress, dataxy, sizeof(dataxy)); + /* Send back ready X position to caller */ + *X = ((dataxy[0] & CST836U_MSB_MASK) << 8) | dataxy[1]; + /* Send back ready Y position to caller */ + *Y = ((dataxy[2] & CST836U_MSB_MASK) << 8) | dataxy[3]; + + *event = (dataxy[0] & CST836U_TOUCH_EVT_FLAG_MASK) >> CST836U_TOUCH_EVT_FLAG_SHIFT; + /* + uint32_t weight; + uint32_t area; + */ + tc_handle.currActiveTouchIdx++; + } +} + +/** + * @brief Return if there is touches detected or not. + * Try to detect new touches and forget the old ones (reset internal global + * variables). + * @param DeviceAddr: Device address on communication Bus. + * @retval : Number of active touches detected (can be 0, 1 or 2). + */ +static uint8_t cst836u_TS_DetectTouch() +{ + volatile uint8_t nbTouch = 0; + + /* Read register CST836U_TOUCH_NUM_REG to check number of touches detection */ + nbTouch = TS_IO_Read(TOUCH_CST836U_I2C_ADDRESS, CST836U_TOUCH_NUM_REG); + if (nbTouch > CST836U_MAX_DETECTABLE_TOUCH) { + /* If invalid number of touch detected, set it to zero */ + nbTouch = 0; + } + tc_handle.currActiveTouchNb = nbTouch; + + tc_handle.currActiveTouchIdx = 0; + return (nbTouch); +} + void TouchReset() { LL_GPIO_ResetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN); - delay_ms(20); + delay_ms(10); LL_GPIO_SetOutputPin(TOUCH_RST_GPIO, TOUCH_RST_GPIO_PIN); delay_ms(300); } + +static const TouchControllerDescriptor FT6236 = +{ + .read = ft6x06_TS_GetXY, + .detectTouch = ft6x06_TS_DetectTouch, + .printDebugInfo = touch_ft6236_debug_info, + .contactEvent = FT6206_TOUCH_EVT_FLAG_CONTACT +}; +static const TouchControllerDescriptor CST836U = +{ + .read = cst836u_TS_GetXY, + .detectTouch = cst836u_TS_DetectTouch, + .printDebugInfo = touch_cst836u_debug_info, + .contactEvent = CST836U_TOUCH_EVT_FLAG_CONTACT +}; + +void detectTouchController() +{ + if( stm32_i2c_is_dev_ready(TOUCH_I2C_BUS, TOUCH_CST836U_I2C_ADDRESS, 3, 5) == 0) + { + touchController = TC_CST836U; + tc = &CST836U; + } else { + touchController = TC_FT6236; + tc = &FT6236; + } +} + void TouchInit(void) { I2C_Init(); TouchReset(); - touch_ft6236_debug_info(); - /* INT generation for new touch available */ - /* Note TS_INT is active low */ - uint8_t regValue = 0; - regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT; - /* Set interrupt TOUCH_FT6236_I2C_ADDRESS mode in FT6206_GMODE_REG */ - TS_IO_Write(TOUCH_FT6236_I2C_ADDRESS, FT6206_GMODE_REG, regValue); + detectTouchController(); + tc->printDebugInfo(); } void handleTouch() @@ -392,9 +508,8 @@ void handleTouch() unsigned short touchX; unsigned short touchY; uint32_t tEvent = 0; - ft6x06_TS_GetXY(TOUCH_FT6236_I2C_ADDRESS, &touchX, &touchY, &tEvent); - // uint32_t gesture; - // ft6x06_TS_GetGestureID(TOUCH_FT6236_I2C_ADDRESS, &gesture); + tc->read(&touchX, &touchY, &tEvent); + #if defined( LCD_DIRECTION ) && (LCD_DIRECTION == LCD_VERTICAL) touchX = LCD_WIDTH - touchX; touchY = LCD_HEIGHT - touchY; @@ -403,7 +518,7 @@ void handleTouch() touchY = touchX; touchX = tmp; #endif - if (tEvent == FT6206_TOUCH_EVT_FLAG_CONTACT) { + if (tEvent == tc->contactEvent) { int dx = touchX - internalTouchState.x; int dy = touchY - internalTouchState.y; @@ -462,7 +577,7 @@ TouchState touchPanelRead() tmr10ms_t now = get_tmr10ms(); internalTouchState.tapCount = 0; - if (ft6x06_TS_DetectTouch(TOUCH_FT6236_I2C_ADDRESS)) { + if (tc->detectTouch()) { handleTouch(); if (internalTouchState.event == TE_DOWN && downTime == 0) { downTime = now; diff --git a/radio/src/targets/nv14/touch_driver.h b/radio/src/targets/nv14/touch_driver.h index 7fe3eae4b..f722edb67 100644 --- a/radio/src/targets/nv14/touch_driver.h +++ b/radio/src/targets/nv14/touch_driver.h @@ -98,15 +98,13 @@ extern "C" { */ typedef struct { - uint8_t i2cInitialized; - /* field holding the current number of simultaneous active touches */ uint8_t currActiveTouchNb; /* field holding the touch index currently managed */ uint8_t currActiveTouchIdx; -} ft6x06_handle_TypeDef; +} tc_handle_TypeDef; @@ -154,10 +152,6 @@ typedef struct #define FT6206_STATUS_OK 0 #define FT6206_STATUS_NOT_OK 1 - /* Possible values of global variable 'TS_I2C_Initialized' */ -#define FT6206_I2C_NOT_INITIALIZED 0 -#define FT6206_I2C_INITIALIZED 1 - /* Max detectable simultaneous touches */ #define FT6206_MAX_DETECTABLE_TOUCH 2 @@ -322,6 +316,40 @@ typedef struct #define FT6206_STATE_REG 0xBC +#define CST836U_WORK_MODE_REG 0x00 +#define CST836U_PROXIMITY_ID_REG 0x01 +#define CST836U_TOUCH_NUM_REG 0x02 +#define CST836U_TOUCH1_XH_REG 0x03 +#define CST836U_TOUCH1_XL_REG 0x04 +#define CST836U_TOUCH1_YH_REG 0x05 +#define CST836U_TOUCH1_YL_REG 0x06 + +#define CST836U_TOUCH2_XH_REG 0x09 +#define CST836U_TOUCH2_XL_REG 0x0A +#define CST836U_TOUCH2_YH_REG 0x0B +#define CST836U_TOUCH2_YL_REG 0x0C + +#define CST836U_FW_VERSION_L_REG 0xA6 +#define CST836U_FW_VERSION_H_REG 0xA7 +#define CST836U_MODULE_VERSION_REG 0xA8 +#define CST836U_PROJECT_NAME_REG 0xA9 +#define CST836U_CHIP_TYPE_L_REG 0xAA +#define CST836U_CHIP_TYPE_H_REG 0xAB +#define CST836U_CHECKSUM_L_REG 0xAC +#define CST836U_CHECKSUM_H_REG 0xAD + +#define CST836U_PROX_STATE_REG 0xB0 +#define CST836U_GES_STATE_REG 0xD0 +#define CST836U_GES_ID_REG_REG 0xD3 + +#define CST836U_MAX_DETECTABLE_TOUCH 2 + +#define CST836U_MSB_MASK 0x0F + +#define CST836U_TOUCH_EVT_FLAG_SHIFT 6 +#define CST836U_TOUCH_EVT_FLAG_MASK (3 << CST836U_TOUCH_EVT_FLAG_SHIFT) +#define CST836U_TOUCH_EVT_FLAG_CONTACT 0x02 + #define LCD_VERTICAL ( 0x00 ) #define LCD_HORIZONTAL ( 0x01 ) #define LCD_DIRECTION ( LCD_VERTICAL )