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