BSP files for STM32H747I-Discovery Copy from ST Cube delivery
Dependents: DISCO_H747I_LCD_demo DISCO_H747I_AUDIO_demo
ft6x06.c
00001 /** 00002 ****************************************************************************** 00003 * @file ft6x06.c 00004 * @author MCD Application Team 00005 * @version V1.0.0 00006 * @date 03-August-2015 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) 2015 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 00088 /* ft6x06 instances by address */ 00089 uint8_t ft6x06[FT6x06_MAX_INSTANCE] = {0}; 00090 00091 /* Global ft6x06 handle */ 00092 static ft6x06_handle_TypeDef ft6x06_handle = { FT6206_I2C_NOT_INITIALIZED, 0, 0}; 00093 00094 /** 00095 * @} 00096 */ 00097 00098 /** @defgroup ft6x06_Private_Function_Prototypes ft6x06 Private Function Prototypes 00099 * @{ 00100 */ 00101 static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr); 00102 /* Private functions prototypes-----------------------------------------------*/ 00103 #if (TS_AUTO_CALIBRATION_SUPPORTED == 1) 00104 /** 00105 * @brief Start TouchScreen calibration phase 00106 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00107 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00108 */ 00109 static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr); 00110 #endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */ 00111 00112 /** 00113 * @brief Basic static configuration of TouchScreen 00114 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00115 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00116 */ 00117 static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr); 00118 00119 /** 00120 * @} 00121 */ 00122 00123 /** @defgroup ft6x06_Private_Functions ft6x06 Private Functions 00124 * @{ 00125 */ 00126 00127 /** 00128 * @brief Initialize the ft6x06 communication bus 00129 * from MCU to FT6206 : ie I2C channel initialization (if required). 00130 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00131 * @retval None 00132 */ 00133 void ft6x06_Init(uint16_t DeviceAddr) 00134 { 00135 uint8_t instance; 00136 uint8_t empty; 00137 00138 /* Check if device instance already exists */ 00139 instance = ft6x06_GetInstance(DeviceAddr); 00140 00141 /* To prevent double initialization */ 00142 if(instance == 0xFF) 00143 { 00144 /* Look for empty instance */ 00145 empty = ft6x06_GetInstance(0); 00146 00147 if(empty < FT6x06_MAX_INSTANCE) 00148 { 00149 /* Register the current device instance */ 00150 ft6x06[empty] = DeviceAddr; 00151 00152 /* Initialize IO BUS layer */ 00153 TS_IO_Init(); 00154 } 00155 } 00156 } 00157 00158 /** 00159 * @brief Software Reset the ft6x06. 00160 * @note : Not applicable to FT6206. 00161 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00162 * @retval None 00163 */ 00164 void ft6x06_Reset(uint16_t DeviceAddr) 00165 { 00166 /* Do nothing */ 00167 /* No software reset sequence available in FT6206 IC */ 00168 } 00169 00170 /** 00171 * @brief Read the ft6x06 device ID, pre initialize I2C in case of need to be 00172 * able to read the FT6206 device ID, and verify this is a FT6206. 00173 * @param DeviceAddr: I2C FT6x06 Slave address. 00174 * @retval The Device ID (two bytes). 00175 */ 00176 uint16_t ft6x06_ReadID(uint16_t DeviceAddr) 00177 { 00178 /* Initialize I2C link if needed */ 00179 TS_IO_Init(); 00180 00181 /* Return the device ID value */ 00182 return (TS_IO_Read(DeviceAddr, FT6206_CHIP_ID_REG)); 00183 } 00184 00185 /** 00186 * @brief Configures the touch Screen IC device to start detecting touches 00187 * It goes through an internal calibration process (Hw calibration sequence of 00188 * the touch screen). 00189 * @param DeviceAddr: Device address on communication Bus (I2C slave address). 00190 * @retval None. 00191 */ 00192 void ft6x06_TS_Start(uint16_t DeviceAddr) 00193 { 00194 #if (TS_AUTO_CALIBRATION_SUPPORTED == 1) 00195 /* Hw Calibration sequence start : should be done once after each power up */ 00196 /* This is called internal calibration of the touch screen */ 00197 ft6x06_TS_Calibration(DeviceAddr); 00198 #endif 00199 /* Minimum static configuration of FT6206 */ 00200 ft6x06_TS_Configure(DeviceAddr); 00201 00202 /* By default set FT6206 IC in Polling mode : no INT generation on FT6206 for new touch available */ 00203 /* Note TS_INT is active low */ 00204 ft6x06_TS_DisableIT(DeviceAddr); 00205 } 00206 00207 /** 00208 * @brief Return if there is touches detected or not. 00209 * Try to detect new touches and forget the old ones (reset internal global 00210 * variables). 00211 * @param DeviceAddr: Device address on communication Bus. 00212 * @retval : Number of active touches detected (can be 0, 1 or 2). 00213 */ 00214 uint8_t ft6x06_TS_DetectTouch(uint16_t DeviceAddr) 00215 { 00216 volatile uint8_t nbTouch = 0; 00217 00218 /* Read register FT6206_TD_STAT_REG to check number of touches detection */ 00219 nbTouch = TS_IO_Read(DeviceAddr, FT6206_TD_STAT_REG); 00220 nbTouch &= FT6206_TD_STAT_MASK; 00221 00222 if(nbTouch > FT6206_MAX_DETECTABLE_TOUCH) 00223 { 00224 /* If invalid number of touch detected, set it to zero */ 00225 nbTouch = 0; 00226 } 00227 00228 /* Update ft6x06 driver internal global : current number of active touches */ 00229 ft6x06_handle.currActiveTouchNb = nbTouch; 00230 00231 /* Reset current active touch index on which to work on */ 00232 ft6x06_handle.currActiveTouchIdx = 0; 00233 00234 return(nbTouch); 00235 } 00236 00237 /** 00238 * @brief Get the touch screen X and Y positions values 00239 * Manage multi touch thanks to touch Index global 00240 * variable 'ft6x06_handle.currActiveTouchIdx'. 00241 * @param DeviceAddr: Device address on communication Bus. 00242 * @param X: Pointer to X position value 00243 * @param Y: Pointer to Y position value 00244 * @retval None. 00245 */ 00246 void ft6x06_TS_GetXY(uint16_t DeviceAddr, uint16_t *X, uint16_t *Y) 00247 { 00248 uint8_t regAddress = 0; 00249 uint8_t dataxy[4]; 00250 00251 if(ft6x06_handle.currActiveTouchIdx < ft6x06_handle.currActiveTouchNb) 00252 { 00253 switch(ft6x06_handle.currActiveTouchIdx) 00254 { 00255 case 0 : 00256 regAddress = FT6206_P1_XH_REG; 00257 break; 00258 case 1 : 00259 regAddress = FT6206_P2_XH_REG; 00260 break; 00261 00262 default : 00263 break; 00264 } 00265 00266 /* Read X and Y positions */ 00267 TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy)); 00268 00269 /* Send back ready X position to caller */ 00270 *X = ((dataxy[0] & FT6206_MSB_MASK) << 8) | (dataxy[1] & FT6206_LSB_MASK); 00271 00272 /* Send back ready Y position to caller */ 00273 *Y = ((dataxy[2] & FT6206_MSB_MASK) << 8) | (dataxy[3] & FT6206_LSB_MASK); 00274 00275 ft6x06_handle.currActiveTouchIdx++; 00276 } 00277 } 00278 00279 /** 00280 * @brief Configure the FT6206 device to generate IT on given INT pin 00281 * connected to MCU as EXTI. 00282 * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206). 00283 * @retval None 00284 */ 00285 void ft6x06_TS_EnableIT(uint16_t DeviceAddr) 00286 { 00287 uint8_t regValue = 0; 00288 regValue = (FT6206_G_MODE_INTERRUPT_TRIGGER & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT; 00289 00290 /* Set interrupt trigger mode in FT6206_GMODE_REG */ 00291 TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue); 00292 } 00293 00294 /** 00295 * @brief Configure the FT6206 device to stop generating IT on the given INT pin 00296 * connected to MCU as EXTI. 00297 * @param DeviceAddr: Device address on communication Bus (Slave I2C address of FT6206). 00298 * @retval None 00299 */ 00300 void ft6x06_TS_DisableIT(uint16_t DeviceAddr) 00301 { 00302 uint8_t regValue = 0; 00303 regValue = (FT6206_G_MODE_INTERRUPT_POLLING & (FT6206_G_MODE_INTERRUPT_MASK >> FT6206_G_MODE_INTERRUPT_SHIFT)) << FT6206_G_MODE_INTERRUPT_SHIFT; 00304 00305 /* Set interrupt polling mode in FT6206_GMODE_REG */ 00306 TS_IO_Write(DeviceAddr, FT6206_GMODE_REG, regValue); 00307 } 00308 00309 /** 00310 * @brief Get IT status from FT6206 interrupt status registers 00311 * Should be called Following an EXTI coming to the MCU to know the detailed 00312 * reason of the interrupt. 00313 * @note : This feature is not applicable to FT6206. 00314 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00315 * @retval TS interrupts status : always return 0 here 00316 */ 00317 uint8_t ft6x06_TS_ITStatus(uint16_t DeviceAddr) 00318 { 00319 /* Always return 0 as feature not applicable to FT6206 */ 00320 return 0; 00321 } 00322 00323 /** 00324 * @brief Clear IT status in FT6206 interrupt status clear registers 00325 * Should be called Following an EXTI coming to the MCU. 00326 * @note : This feature is not applicable to FT6206. 00327 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6206). 00328 * @retval None 00329 */ 00330 void ft6x06_TS_ClearIT(uint16_t DeviceAddr) 00331 { 00332 /* Nothing to be done here for FT6206 */ 00333 } 00334 00335 /**** NEW FEATURES enabled when Multi-touch support is enabled ****/ 00336 00337 #if (TS_MULTI_TOUCH_SUPPORTED == 1) 00338 00339 /** 00340 * @brief Get the last touch gesture identification (zoom, move up/down...). 00341 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06). 00342 * @param pGestureId : Pointer to get last touch gesture Identification. 00343 * @retval None. 00344 */ 00345 void ft6x06_TS_GetGestureID(uint16_t DeviceAddr, uint32_t * pGestureId) 00346 { 00347 volatile uint8_t ucReadData = 0; 00348 00349 ucReadData = TS_IO_Read(DeviceAddr, FT6206_GEST_ID_REG); 00350 00351 * pGestureId = ucReadData; 00352 } 00353 00354 /** 00355 * @brief Get the touch detailed informations on touch number 'touchIdx' (0..1) 00356 * This touch detailed information contains : 00357 * - weight that was applied to this touch 00358 * - sub-area of the touch in the touch panel 00359 * - event of linked to the touch (press down, lift up, ...) 00360 * @param DeviceAddr: Device address on communication Bus (I2C slave address of FT6x06). 00361 * @param touchIdx : Passed index of the touch (0..1) on which we want to get the 00362 * detailed information. 00363 * @param pWeight : Pointer to to get the weight information of 'touchIdx'. 00364 * @param pArea : Pointer to to get the sub-area information of 'touchIdx'. 00365 * @param pEvent : Pointer to to get the event information of 'touchIdx'. 00366 00367 * @retval None. 00368 */ 00369 void ft6x06_TS_GetTouchInfo(uint16_t DeviceAddr, 00370 uint32_t touchIdx, 00371 uint32_t * pWeight, 00372 uint32_t * pArea, 00373 uint32_t * pEvent) 00374 { 00375 uint8_t regAddress = 0; 00376 uint8_t dataxy[3]; 00377 00378 if(touchIdx < ft6x06_handle.currActiveTouchNb) 00379 { 00380 switch(touchIdx) 00381 { 00382 case 0 : 00383 regAddress = FT6206_P1_WEIGHT_REG; 00384 break; 00385 00386 case 1 : 00387 regAddress = FT6206_P2_WEIGHT_REG; 00388 break; 00389 00390 default : 00391 break; 00392 00393 } /* end switch(touchIdx) */ 00394 00395 /* Read weight, area and Event Id of touch index */ 00396 TS_IO_ReadMultiple(DeviceAddr, regAddress, dataxy, sizeof(dataxy)); 00397 00398 /* Return weight of touch index */ 00399 * pWeight = (dataxy[0] & FT6206_TOUCH_WEIGHT_MASK) >> FT6206_TOUCH_WEIGHT_SHIFT; 00400 /* Return area of touch index */ 00401 * pArea = (dataxy[1] & FT6206_TOUCH_AREA_MASK) >> FT6206_TOUCH_AREA_SHIFT; 00402 /* Return Event Id of touch index */ 00403 * pEvent = (dataxy[2] & FT6206_TOUCH_EVT_FLAG_MASK) >> FT6206_TOUCH_EVT_FLAG_SHIFT; 00404 00405 } /* of if(touchIdx < ft6x06_handle.currActiveTouchNb) */ 00406 } 00407 00408 #endif /* TS_MULTI_TOUCH_SUPPORTED == 1 */ 00409 00410 #if (TS_AUTO_CALIBRATION_SUPPORTED == 1) 00411 /** 00412 * @brief Start TouchScreen calibration phase 00413 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00414 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00415 */ 00416 static uint32_t ft6x06_TS_Calibration(uint16_t DeviceAddr) 00417 { 00418 uint32_t nbAttempt = 0; 00419 volatile uint8_t ucReadData; 00420 volatile uint8_t regValue; 00421 uint32_t status = FT6206_STATUS_OK; 00422 uint8_t bEndCalibration = 0; 00423 00424 /* >> Calibration sequence start */ 00425 00426 /* Switch FT6206 back to factory mode to calibrate */ 00427 regValue = (FT6206_DEV_MODE_FACTORY & FT6206_DEV_MODE_MASK) << FT6206_DEV_MODE_SHIFT; 00428 TS_IO_Write(DeviceAddr, FT6206_DEV_MODE_REG, regValue); /* 0x40 */ 00429 00430 /* Read back the same register FT6206_DEV_MODE_REG */ 00431 ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG); 00432 TS_IO_Delay(300); /* Wait 300 ms */ 00433 00434 if(((ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT) != FT6206_DEV_MODE_FACTORY ) 00435 { 00436 /* Return error to caller */ 00437 return(FT6206_STATUS_NOT_OK); 00438 } 00439 00440 /* Start calibration command */ 00441 TS_IO_Write(DeviceAddr, FT6206_TD_STAT_REG, 0x04); 00442 TS_IO_Delay(300); /* Wait 300 ms */ 00443 00444 /* 100 attempts to wait switch from factory mode (calibration) to working mode */ 00445 for (nbAttempt=0; ((nbAttempt < 100) && (!bEndCalibration)) ; nbAttempt++) 00446 { 00447 ucReadData = TS_IO_Read(DeviceAddr, FT6206_DEV_MODE_REG); 00448 ucReadData = (ucReadData & (FT6206_DEV_MODE_MASK << FT6206_DEV_MODE_SHIFT)) >> FT6206_DEV_MODE_SHIFT; 00449 if(ucReadData == FT6206_DEV_MODE_WORKING) 00450 { 00451 /* Auto Switch to FT6206_DEV_MODE_WORKING : means calibration have ended */ 00452 bEndCalibration = 1; /* exit for loop */ 00453 } 00454 00455 TS_IO_Delay(200); /* Wait 200 ms */ 00456 } 00457 00458 /* Calibration sequence end << */ 00459 00460 return(status); 00461 } 00462 #endif /* TS_AUTO_CALIBRATION_SUPPORTED == 1 */ 00463 00464 /** 00465 * @brief Basic static configuration of TouchScreen 00466 * @param DeviceAddr: FT6206 Device address for communication on I2C Bus. 00467 * @retval Status FT6206_STATUS_OK or FT6206_STATUS_NOT_OK. 00468 */ 00469 static uint32_t ft6x06_TS_Configure(uint16_t DeviceAddr) 00470 { 00471 uint32_t status = FT6206_STATUS_OK; 00472 00473 /* Nothing special to be done for FT6206 */ 00474 00475 return(status); 00476 } 00477 00478 /** 00479 * @brief Check if the device instance of the selected address is already registered 00480 * and return its index 00481 * @param DeviceAddr: Device address on communication Bus. 00482 * @retval Index of the device instance if registered, 0xFF if not. 00483 */ 00484 static uint8_t ft6x06_GetInstance(uint16_t DeviceAddr) 00485 { 00486 uint8_t idx = 0; 00487 00488 /* Check all the registered instances */ 00489 for(idx = 0; idx < FT6x06_MAX_INSTANCE ; idx ++) 00490 { 00491 if(ft6x06[idx] == DeviceAddr) 00492 { 00493 return idx; 00494 } 00495 } 00496 00497 return 0xFF; 00498 } 00499 00500 /** 00501 * @} 00502 */ 00503 00504 /** 00505 * @} 00506 */ 00507 00508 /** 00509 * @} 00510 */ 00511 00512 /** 00513 * @} 00514 */ 00515 00516 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 18:45:41 by 1.7.2