STM32Cube BSP FW for STM32F769I-Discovery
Dependents: mbed-os-example-blinky-5 DISCO-F769NI_TOUCHSCREEN_demo_custom_1 Datarecorder2 DISCO-F769NI_TOUCHSCREEN_demo ... more
ft6x06.c
00001 /** 00002 ****************************************************************************** 00003 * @file ft6x06.c 00004 * @author MCD Application Team 00005 * @brief This file provides a set of functions needed to manage the FT6X06 00006 * IO Expander devices. 00007 ****************************************************************************** 00008 * @attention 00009 * 00010 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00011 * 00012 * Redistribution and use in source and binary forms, with or without modification, 00013 * are permitted provided that the following conditions are met: 00014 * 1. Redistributions of source code must retain the above copyright notice, 00015 * this list of conditions and the following disclaimer. 00016 * 2. Redistributions in binary form must reproduce the above copyright notice, 00017 * this list of conditions and the following disclaimer in the documentation 00018 * and/or other materials provided with the distribution. 00019 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00020 * may be used to endorse or promote products derived from this software 00021 * without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00024 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00025 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00027 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00028 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00030 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00031 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00032 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00033 * 00034 ****************************************************************************** 00035 */ 00036 00037 /* Includes ------------------------------------------------------------------*/ 00038 #include "ft6x06.h" 00039 00040 /** @addtogroup BSP 00041 * @{ 00042 */ 00043 00044 /** @addtogroup Component 00045 * @{ 00046 */ 00047 00048 /** @defgroup FT6X06 00049 * @{ 00050 */ 00051 00052 /* Private typedef -----------------------------------------------------------*/ 00053 00054 /** @defgroup FT6X06_Private_Defines FT6X06 Private Defines 00055 * @{ 00056 */ 00057 #define FT6x06_MAX_INSTANCE 2 00058 /** 00059 * @} 00060 */ 00061 00062 /* Private macro -------------------------------------------------------------*/ 00063 00064 /** @defgroup FT6X06_Private_Variables FT6X06 Private Variables 00065 * @{ 00066 */ 00067 00068 /* Touch screen driver structure initialization */ 00069 TS_DrvTypeDef ft6x06_ts_drv = 00070 { 00071 ft6x06_Init, 00072 ft6x06_ReadID, 00073 ft6x06_Reset, 00074 00075 ft6x06_TS_Start, 00076 ft6x06_TS_DetectTouch, 00077 ft6x06_TS_GetXY, 00078 00079 ft6x06_TS_EnableIT, 00080 ft6x06_TS_ClearIT, 00081 ft6x06_TS_ITStatus, 00082 ft6x06_TS_DisableIT 00083 }; 00084 00085 /* ft6x06 instances by address */ 00086 uint8_t ft6x06[FT6x06_MAX_INSTANCE] = {0}; 00087 00088 /* Global ft6x06 handle */ 00089 static ft6x06_handle_TypeDef ft6x06_handle = { FT6206_I2C_NOT_INITIALIZED, 0, 0}; 00090 00091 /** 00092 * @} 00093 */ 00094 00095 /** @defgroup ft6x06_Private_Function_Prototypes ft6x06 Private Function Prototypes 00096 * @{ 00097 */ 00098 static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr); 00099 /* Private functions prototypes-----------------------------------------------*/ 00100 #if (TS_AUTO_CALIBRATION_SUPPORTED == 1) 00101 /** 00102 * @brief Start TouchScreen calibration phase 00103 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00104 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00105 */ 00106 static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr); 00107 #endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */ 00108 00109 /** 00110 * @brief Basic static configuration of TouchScreen 00111 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00112 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00113 */ 00114 static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr); 00115 00116 /** 00117 * @} 00118 */ 00119 00120 /** @defgroup ft6x06_Private_Functions ft6x06 Private Functions 00121 * @{ 00122 */ 00123 00124 /** 00125 * @brief Initialize the ft6x06 communication bus 00126 * from MCU to FT6206 : ie I2C channel initialization (if required). 00127 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00128 * @retval None 00129 */ 00130 void ft6x06_Init(uint16_t DeviceAddr) 00131 { 00132 uint8_t instance; 00133 uint8_t empty; 00134 00135 /* Check if device instance already exists */ 00136 instance = ft6x06_GetInstance(DeviceAddr); 00137 00138 /* To prevent double initialization */ 00139 if(instance == 0xFF) 00140 { 00141 /* Look for empty instance */ 00142 empty = ft6x06_GetInstance(0); 00143 00144 if(empty < FT6x06_MAX_INSTANCE) 00145 { 00146 /* Register the current device instance */ 00147 ft6x06[empty] = DeviceAddr; 00148 00149 /* Initialize IO BUS layer */ 00150 TS_IO_Init(); 00151 } 00152 } 00153 } 00154 00155 /** 00156 * @brief Software Reset the ft6x06. 00157 * @note : Not applicable to FT6206. 00158 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00159 * @retval None 00160 */ 00161 void ft6x06_Reset(uint16_t DeviceAddr) 00162 { 00163 /* Do nothing */ 00164 /* No software reset sequence available in FT6206 IC */ 00165 } 00166 00167 /** 00168 * @brief Read the ft6x06 device ID, pre initialize I2C in case of need to be 00169 * able to read the FT6206 device ID, and verify this is a FT6206. 00170 * @param DeviceAddr: I2C FT6x06 Slave address. 00171 * @retval The Device ID (two bytes). 00172 */ 00173 uint16_t ft6x06_ReadID(uint16_t DeviceAddr) 00174 { 00175 /* Initialize I2C link if needed */ 00176 TS_IO_Init(); 00177 00178 /* Return the device ID value */ 00179 return (TS_IO_Read(DeviceAddr, FT6206_CHIP_ID_REG)); 00180 } 00181 00182 /** 00183 * @brief Configures the touch Screen IC device to start detecting touches 00184 * It goes through an internal calibration process (Hw calibration sequence of 00185 * the touch screen). 00186 * @param DeviceAddr: Device address on communication Bus (I2C slave address). 00187 * @retval None. 00188 */ 00189 void ft6x06_TS_Start(uint16_t DeviceAddr) 00190 { 00191 #if (TS_AUTO_CALIBRATION_SUPPORTED == 1) 00192 /* Hw Calibration sequence start : should be done once after each power up */ 00193 /* This is called internal calibration of the touch screen */ 00194 ft6x06_TS_Calibration(DeviceAddr); 00195 #endif 00196 /* Minimum static configuration of FT6206 */ 00197 ft6x06_TS_Configure(DeviceAddr); 00198 00199 /* By default set FT6206 IC in Polling mode : no INT generation on FT6206 for new touch available */ 00200 /* Note TS_INT is active low */ 00201 ft6x06_TS_DisableIT(DeviceAddr); 00202 } 00203 00204 /** 00205 * @brief Return if there is touches detected or not. 00206 * Try to detect new touches and forget the old ones (reset internal global 00207 * variables). 00208 * @param DeviceAddr: Device address on communication Bus. 00209 * @retval : Number of active touches detected (can be 0, 1 or 2). 00210 */ 00211 uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr) 00212 { 00213 volatile uint8_t nbTouch = 0; 00214 00215 /* Read register FT6206_TD_STAT_REG to check number of touches detection */ 00216 nbTouch = TS_IO_Read(DeviceAddr, FT6206_TD_STAT_REG); 00217 nbTouch &= FT6206_TD_STAT_MASK; 00218 00219 if(nbTouch > FT6206_MAX_DETECTABLE_TOUCH) 00220 { 00221 /* If invalid number of touch detected, set it to zero */ 00222 nbTouch = 0; 00223 } 00224 00225 /* Update ft6x06 driver internal global : current number of active touches */ 00226 ft6x06_handle.currActiveTouchNb = nbTouch; 00227 00228 /* Reset current active touch index on which to work on */ 00229 ft6x06_handle.currActiveTouchIdx = 0; 00230 00231 return(nbTouch); 00232 } 00233 00234 /** 00235 * @brief Get the touch screen X and Y positions values 00236 * Manage multi touch thanks to touch Index global 00237 * variable 'ft6x06_handle.currActiveTouchIdx'. 00238 * @param DeviceAddr: Device address on communication Bus. 00239 * @param X: Pointer to X position value 00240 * @param Y: Pointer to Y position value 00241 * @retval None. 00242 */ 00243 void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y) 00244 { 00245 uint8_t regAddress = 0; 00246 uint8_t dataxy[4]; 00247 00248 if(ft6x06_handle.currActiveTouchIdx < ft6x06_handle.currActiveTouchNb) 00249 { 00250 switch(ft6x06_handle.currActiveTouchIdx) 00251 { 00252 case 0 : 00253 regAddress = FT6206_P1_XH_REG; 00254 break; 00255 case 1 : 00256 regAddress = FT6206_P2_XH_REG; 00257 break; 00258 00259 default : 00260 break; 00261 } 00262 00263 /* Read X and Y positions */ 00264 TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy)); 00265 00266 /* Send back ready X position to caller */ 00267 *X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK); 00268 00269 /* Send back ready Y position to caller */ 00270 *Y = ((dataxy[2] & FT6206_MSB_MASK) << 8) | (dataxy[3] & FT6206_LSB_MASK); 00271 00272 ft6x06_handle.currActiveTouchIdx++; 00273 } 00274 } 00275 00276 /** 00277 * @brief Configure the FT6206 device to generate IT on given INT pin 00278 * connected to MCU as EXTI. 00279 * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206). 00280 * @retval None 00281 */ 00282 void ft6x06_TS_EnableIT(uint16_t DeviceAddr) 00283 { 00284 uint8_t regValue = 0; 00285 regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT; 00286 00287 /* Set interrupt trigger mode in FT6206_GMODE_REG */ 00288 TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue); 00289 } 00290 00291 /** 00292 * @brief Configure the FT6206 device to stop generating IT on the given INT pin 00293 * connected to MCU as EXTI. 00294 * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206). 00295 * @retval None 00296 */ 00297 void ft6x06_TS_DisableIT(uint16_t DeviceAddr) 00298 { 00299 uint8_t regValue = 0; 00300 regValue = (FT6206_G_MODE_INTERRUPT_POLLING & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT; 00301 00302 /* Set interrupt polling mode in FT6206_GMODE_REG */ 00303 TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue); 00304 } 00305 00306 /** 00307 * @brief Get IT status from FT6206 interrupt status registers 00308 * Should be called Following an EXTI coming to the MCU to know the detailed 00309 * reason of the interrupt. 00310 * @note : This feature is not applicable to FT6206. 00311 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00312 * @retval TS interrupts status : always return 0 here 00313 */ 00314 uint8_t ft6x06_TS_ITStatus(uint16_t DeviceAddr) 00315 { 00316 /* Always return 0 as feature not applicable to FT6206 */ 00317 return 0; 00318 } 00319 00320 /** 00321 * @brief Clear IT status in FT6206 interrupt status clear registers 00322 * Should be called Following an EXTI coming to the MCU. 00323 * @note : This feature is not applicable to FT6206. 00324 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00325 * @retval None 00326 */ 00327 void ft6x06_TS_ClearIT(uint16_t DeviceAddr) 00328 { 00329 /* Nothing to be done here for FT6206 */ 00330 } 00331 00332 /**** NEW FEATURES enabled when Multi-touch support is enabled ****/ 00333 00334 #if (TS_MULTI_TOUCH_SUPPORTED == 1) 00335 /** 00336 * @brief Get the last touch gesture identification (zoom, move up/down...). 00337 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06). 00338 * @param pGestureId : Pointer to get last touch gesture Identification. 00339 * @retval None. 00340 */ 00341 void ft6x06_TS_GetGestureID(uint16_t DeviceAddr, uint32_t * pGestureId) 00342 { 00343 volatile uint8_t ucReadData = 0; 00344 00345 ucReadData = TS_IO_Read(DeviceAddr, FT6206_GEST_ID_REG); 00346 00347 * pGestureId = ucReadData; 00348 } 00349 00350 /** 00351 * @brief Get the touch detailed informations on touch number 'touchIdx' (0..1) 00352 * This touch detailed information contains : 00353 * - weight that was applied to this touch 00354 * - sub-area of the touch in the touch panel 00355 * - event of linked to the touch (press down, lift up, ...) 00356 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06). 00357 * @param touchIdx : Passed index of the touch (0..1) on which we want to get the 00358 * detailed information. 00359 * @param pWeight : Pointer to to get the weight information of 'touchIdx'. 00360 * @param pArea : Pointer to to get the sub-area information of 'touchIdx'. 00361 * @param pEvent : Pointer to to get the event information of 'touchIdx'. 00362 00363 * @retval None. 00364 */ 00365 void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr, 00366 uint32_t touchIdx, 00367 uint32_t * pWeight, 00368 uint32_t * pArea, 00369 uint32_t * pEvent) 00370 { 00371 uint8_t regAddress = 0; 00372 uint8_t dataxy[3]; 00373 00374 if(touchIdx < ft6x06_handle.currActiveTouchNb) 00375 { 00376 switch(touchIdx) 00377 { 00378 case 0 : 00379 regAddress = FT6206_P1_WEIGHT_REG; 00380 break; 00381 00382 case 1 : 00383 regAddress = FT6206_P2_WEIGHT_REG; 00384 break; 00385 00386 default : 00387 break; 00388 00389 } /* end switch(touchIdx) */ 00390 00391 /* Read weight, area and Event Id of touch index */ 00392 TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy)); 00393 00394 /* Return weight of touch index */ 00395 * pWeight = (dataxy[0] & FT6206_TOUCH_WEIGHT_MASK) >> FT6206_TOUCH_WEIGHT_SHIFT; 00396 /* Return area of touch index */ 00397 * pArea = (dataxy[1] & FT6206_TOUCH_AREA_MASK) >> FT6206_TOUCH_AREA_SHIFT; 00398 /* Return Event Id of touch index */ 00399 * pEvent = (dataxy[2] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT; 00400 00401 } /* of if(touchIdx < ft6x06_handle.currActiveTouchNb) */ 00402 } 00403 00404 #endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */ 00405 00406 #if (TS_AUTO_CALIBRATION_SUPPORTED == 1) 00407 /** 00408 * @brief Start TouchScreen calibration phase 00409 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00410 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00411 */ 00412 static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr) 00413 { 00414 uint32_t nbAttempt = 0; 00415 volatile uint8_t ucReadData; 00416 volatile uint8_t regValue; 00417 uint32_t status = FT6206_STATUS_OK; 00418 uint8_t bEndCalibration = 0; 00419 00420 /* >> Calibration sequence start */ 00421 00422 /* Switch FT6206 back to factory mode to calibrate */ 00423 regValue = (FT6206_DEV_MODE_FACTORY & FT6206_DEV_MODE_MASK) << FT6206_DEV_MODE_SHIFT; 00424 TS_IO_Write(DeviceAddr, FT6206_DEV_MODE_REG, regValue); /* 0x40 */ 00425 00426 /* Read back the same register FT6206_DEV_MODE_REG */ 00427 ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG); 00428 TS_IO_Delay(300); /* Wait 300 ms */ 00429 00430 if(((ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT) != FT6206_DEV_MODE_FACTORY ) 00431 { 00432 /* Return error to caller */ 00433 return(FT6206_STATUS_NOT_OK); 00434 } 00435 00436 /* Start calibration command */ 00437 TS_IO_Write(DeviceAddr, FT6206_TD_STAT_REG, 0x04); 00438 TS_IO_Delay(300); /* Wait 300 ms */ 00439 00440 /* 100 attempts to wait switch from factory mode (calibration) to working mode */ 00441 for (nbAttempt=0; ((nbAttempt < 100) && (!bEndCalibration)) ; nbAttempt++) 00442 { 00443 ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG); 00444 ucReadData = (ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT; 00445 if(ucReadData == FT6206_DEV_MODE_WORKING) 00446 { 00447 /* Auto Switch to FT6206_DEV_MODE_WORKING : means calibration have ended */ 00448 bEndCalibration = 1; /* exit for loop */ 00449 } 00450 00451 TS_IO_Delay(200); /* Wait 200 ms */ 00452 } 00453 00454 /* Calibration sequence end << */ 00455 00456 return(status); 00457 } 00458 #endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */ 00459 00460 /** 00461 * @brief Basic static configuration of TouchScreen 00462 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00463 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00464 */ 00465 static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr) 00466 { 00467 uint32_t status = FT6206_STATUS_OK; 00468 00469 /* Nothing special to be done for FT6206 */ 00470 00471 return(status); 00472 } 00473 00474 /** 00475 * @brief Check if the device instance of the selected address is already registered 00476 * and return its index 00477 * @param DeviceAddr: Device address on communication Bus. 00478 * @retval Index of the device instance if registered, 0xFF if not. 00479 */ 00480 static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr) 00481 { 00482 uint8_t idx = 0; 00483 00484 /* Check all the registered instances */ 00485 for(idx = 0; idx < FT6x06_MAX_INSTANCE ; idx ++) 00486 { 00487 if(ft6x06[idx] == DeviceAddr) 00488 { 00489 return idx; 00490 } 00491 } 00492 00493 return 0xFF; 00494 } 00495 00496 /** 00497 * @} 00498 */ 00499 00500 /** 00501 * @} 00502 */ 00503 00504 /** 00505 * @} 00506 */ 00507 00508 /** 00509 * @} 00510 */ 00511 00512 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 17:55:04 by 1.7.2