|
|
|
#include STM32_HAL_H
|
|
|
|
#include TREZOR_BOARD
|
|
|
|
|
|
|
|
#include "i2c.h"
|
|
|
|
|
|
|
|
/** @addtogroup STM32U5x9J_DISCOVERY
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @addtogroup STM32U5x9J_DISCOVERY_BUS
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_BUS_Exported_Types BUS Exported Types
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/* Common Error codes */
|
|
|
|
#define BSP_ERROR_NONE 0
|
|
|
|
#define BSP_ERROR_NO_INIT -1
|
|
|
|
#define BSP_ERROR_WRONG_PARAM -2
|
|
|
|
#define BSP_ERROR_BUSY -3
|
|
|
|
#define BSP_ERROR_PERIPH_FAILURE -4
|
|
|
|
#define BSP_ERROR_COMPONENT_FAILURE -5
|
|
|
|
#define BSP_ERROR_UNKNOWN_FAILURE -6
|
|
|
|
#define BSP_ERROR_UNKNOWN_COMPONENT -7
|
|
|
|
#define BSP_ERROR_BUS_FAILURE -8
|
|
|
|
#define BSP_ERROR_CLOCK_FAILURE -9
|
|
|
|
#define BSP_ERROR_MSP_FAILURE -10
|
|
|
|
#define BSP_ERROR_FEATURE_NOT_SUPPORTED -11
|
|
|
|
|
|
|
|
/* BSP OSPI error codes */
|
|
|
|
#define BSP_ERROR_OSPI_SUSPENDED -20
|
|
|
|
#define BSP_ERROR_OSPI_MMP_UNLOCK_FAILURE -21
|
|
|
|
#define BSP_ERROR_OSPI_MMP_LOCK_FAILURE -22
|
|
|
|
|
|
|
|
/* BSP HSPI error codes */
|
|
|
|
#define BSP_ERROR_HSPI_MMP_UNLOCK_FAILURE -31
|
|
|
|
#define BSP_ERROR_HSPI_MMP_LOCK_FAILURE -32
|
|
|
|
|
|
|
|
/* BSP BUS error codes */
|
|
|
|
#define BSP_ERROR_BUS_TRANSACTION_FAILURE -100
|
|
|
|
#define BSP_ERROR_BUS_ARBITRATION_LOSS -101
|
|
|
|
#define BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE -102
|
|
|
|
#define BSP_ERROR_BUS_PROTOCOL_FAILURE -103
|
|
|
|
|
|
|
|
#define BSP_ERROR_BUS_MODE_FAULT -104
|
|
|
|
#define BSP_ERROR_BUS_FRAME_ERROR -105
|
|
|
|
#define BSP_ERROR_BUS_CRC_ERROR -106
|
|
|
|
#define BSP_ERROR_BUS_DMA_FAILURE -107
|
|
|
|
|
|
|
|
/* TS I2C address */
|
|
|
|
#define TS_I2C_ADDRESS 0xE0U
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* Function Name : sitronix_read_reg
|
|
|
|
* Description : Generic Reading function. It must be full-filled with either
|
|
|
|
* I2C or SPI reading functions
|
|
|
|
* Input : Register Address, length of buffer
|
|
|
|
* Output : pdata Read
|
|
|
|
*******************************************************************************/
|
|
|
|
int32_t sitronix_read_reg(uint8_t reg, uint8_t *pdata, uint16_t length) {
|
|
|
|
return i2c_mem_read(TOUCH_I2C_INSTANCE, TS_I2C_ADDRESS, reg, length, pdata,
|
|
|
|
length, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* Function Name : sitronix_write_reg
|
|
|
|
* Description : Generic Writing function. It must be full-filled with either
|
|
|
|
* I2C or SPI writing function
|
|
|
|
* Input : Register Address, pdata to be written, length of buffer
|
|
|
|
* Output : None
|
|
|
|
*******************************************************************************/
|
|
|
|
int32_t sitronix_write_reg(uint8_t reg, uint8_t *pdata, uint16_t length) {
|
|
|
|
return i2c_mem_write(TOUCH_I2C_INSTANCE, TS_I2C_ADDRESS, reg, length, pdata,
|
|
|
|
length, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* Function Name : sitronix_read_data
|
|
|
|
* Description : Generic Reading function. It must be full-filled with either
|
|
|
|
* I2C or SPI reading functions
|
|
|
|
* Input : Register Address, length of buffer
|
|
|
|
* Output : pdata Read
|
|
|
|
*******************************************************************************/
|
|
|
|
int32_t sitronix_read_data(uint8_t *pdata, uint16_t length) {
|
|
|
|
return i2c_receive(TOUCH_I2C_INSTANCE, TS_I2C_ADDRESS, pdata, length, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
|
/* Macros --------------------------------------------------------------------*/
|
|
|
|
/* Exported types ------------------------------------------------------------*/
|
|
|
|
/* Exported constants --------------------------------------------------------*/
|
|
|
|
#define SITRONIX_MAX_X_LENGTH 480U
|
|
|
|
#define SITRONIX_MAX_Y_LENGTH 480U
|
|
|
|
|
|
|
|
/** @defgroup SITRONIX_Exported_Constants SITRONIX Exported Constants
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#define SITRONIX_OK (0)
|
|
|
|
#define SITRONIX_ERROR (-1)
|
|
|
|
|
|
|
|
/* Max detectable simultaneous touches */
|
|
|
|
#define SITRONIX_MAX_DETECTABLE_TOUCH 10U
|
|
|
|
|
|
|
|
/* Touch FT6XX6 IDs */
|
|
|
|
#define SITRONIX_ID 0x02U
|
|
|
|
|
|
|
|
/* Values Pn_XH and Pn_YH related */
|
|
|
|
#define SITRONIX_TOUCH_EVT_FLAG_PRESS_DOWN 0x20U
|
|
|
|
#define SITRONIX_TOUCH_EVT_FLAG_LIFT_UP 0x60U
|
|
|
|
#define SITRONIX_TOUCH_EVT_FLAG_CONTACT 0x80U
|
|
|
|
#define SITRONIX_TOUCH_EVT_FLAG_NO_EVENT 0x00U
|
|
|
|
#define SITRONIX_TOUCH_POS_MSB_MASK 0x07U
|
|
|
|
#define SITRONIX_TOUCH_POS_LSB_MASK 0x70U
|
|
|
|
|
|
|
|
/* Point 1 registers */
|
|
|
|
#define SITRONIX_P1_XH_REG 0x09U
|
|
|
|
#define SITRONIX_P1_XL_REG 0x0AU
|
|
|
|
#define SITRONIX_P1_YH_REG 0x0BU
|
|
|
|
#define SITRONIX_P1_YL_REG 0x0CU
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Exported types ------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/** @defgroup SITRONIX_Exported_Types SITRONIX Exported Types
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
uint32_t Radian;
|
|
|
|
uint32_t OffsetLeftRight;
|
|
|
|
uint32_t OffsetUpDown;
|
|
|
|
uint32_t DistanceLeftRight;
|
|
|
|
uint32_t DistanceUpDown;
|
|
|
|
uint32_t DistanceZoom;
|
|
|
|
} SITRONIX_Gesture_Init_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t TouchDetected;
|
|
|
|
uint32_t TouchX;
|
|
|
|
uint32_t TouchY;
|
|
|
|
} SITRONIX_State_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t TouchDetected;
|
|
|
|
uint32_t TouchX[SITRONIX_MAX_DETECTABLE_TOUCH];
|
|
|
|
uint32_t TouchY[SITRONIX_MAX_DETECTABLE_TOUCH];
|
|
|
|
uint32_t TouchWeight[SITRONIX_MAX_DETECTABLE_TOUCH];
|
|
|
|
uint32_t TouchEvent[SITRONIX_MAX_DETECTABLE_TOUCH];
|
|
|
|
uint32_t TouchArea[SITRONIX_MAX_DETECTABLE_TOUCH];
|
|
|
|
} SITRONIX_MultiTouch_State_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t IsInitialized;
|
|
|
|
} SITRONIX_Object_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t MultiTouch;
|
|
|
|
uint8_t Gesture;
|
|
|
|
uint8_t MaxTouch;
|
|
|
|
uint32_t MaxXl;
|
|
|
|
uint32_t MaxYl;
|
|
|
|
} SITRONIX_Capabilities_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int32_t (*Init)(SITRONIX_Object_t *);
|
|
|
|
int32_t (*DeInit)(SITRONIX_Object_t *);
|
|
|
|
int32_t (*GestureConfig)(SITRONIX_Object_t *, SITRONIX_Gesture_Init_t *);
|
|
|
|
int32_t (*ReadID)(SITRONIX_Object_t *, uint32_t *);
|
|
|
|
int32_t (*GetState)(SITRONIX_Object_t *, SITRONIX_State_t *);
|
|
|
|
int32_t (*GetMultiTouchState)(SITRONIX_Object_t *,
|
|
|
|
SITRONIX_MultiTouch_State_t *);
|
|
|
|
int32_t (*GetGesture)(SITRONIX_Object_t *, uint8_t *);
|
|
|
|
int32_t (*GetCapabilities)(SITRONIX_Object_t *, SITRONIX_Capabilities_t *);
|
|
|
|
int32_t (*EnableIT)(SITRONIX_Object_t *);
|
|
|
|
int32_t (*DisableIT)(SITRONIX_Object_t *);
|
|
|
|
int32_t (*ClearIT)(SITRONIX_Object_t *);
|
|
|
|
int32_t (*ITStatus)(SITRONIX_Object_t *);
|
|
|
|
} SITRONIX_TS_Drv_t;
|
|
|
|
|
|
|
|
int32_t SITRONIX_Init(SITRONIX_Object_t *pObj);
|
|
|
|
int32_t SITRONIX_DeInit(SITRONIX_Object_t *pObj);
|
|
|
|
int32_t SITRONIX_GestureConfig(SITRONIX_Object_t *pObj,
|
|
|
|
SITRONIX_Gesture_Init_t *GestureInit);
|
|
|
|
int32_t SITRONIX_ReadID(SITRONIX_Object_t *pObj, uint32_t *Id);
|
|
|
|
int32_t SITRONIX_GetState(SITRONIX_Object_t *pObj, SITRONIX_State_t *State);
|
|
|
|
int32_t SITRONIX_GetMultiTouchState(SITRONIX_Object_t *pObj,
|
|
|
|
SITRONIX_MultiTouch_State_t *State);
|
|
|
|
int32_t SITRONIX_GetGesture(SITRONIX_Object_t *pObj, uint8_t *GestureId);
|
|
|
|
int32_t SITRONIX_EnableIT(SITRONIX_Object_t *pObj);
|
|
|
|
int32_t SITRONIX_DisableIT(SITRONIX_Object_t *pObj);
|
|
|
|
int32_t SITRONIX_ITStatus(SITRONIX_Object_t *pObj);
|
|
|
|
int32_t SITRONIX_ClearIT(SITRONIX_Object_t *pObj);
|
|
|
|
int32_t SITRONIX_GetCapabilities(SITRONIX_Object_t *pObj,
|
|
|
|
SITRONIX_Capabilities_t *Capabilities);
|
|
|
|
|
|
|
|
/* Touch screen driver structure initialization */
|
|
|
|
SITRONIX_TS_Drv_t SITRONIX_TS_Driver = {
|
|
|
|
SITRONIX_Init, SITRONIX_DeInit, SITRONIX_GestureConfig,
|
|
|
|
SITRONIX_ReadID, SITRONIX_GetState, SITRONIX_GetMultiTouchState,
|
|
|
|
SITRONIX_GetGesture, SITRONIX_GetCapabilities, SITRONIX_EnableIT,
|
|
|
|
SITRONIX_DisableIT, SITRONIX_ClearIT, SITRONIX_ITStatus};
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup SITRONIX_Private_Function_Prototypes SITRONIX Private Function
|
|
|
|
* Prototypes
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
#if (SITRONIX_AUTO_CALIBRATION_ENABLED == 1)
|
|
|
|
static int32_t SITRONIX_TS_Calibration(SITRONIX_Object_t *pObj);
|
|
|
|
static int32_t SITRONIX_Delay(SITRONIX_Object_t *pObj, uint32_t Delay);
|
|
|
|
#endif /* SITRONIX_AUTO_CALIBRATION_ENABLED == 1 */
|
|
|
|
static int32_t SITRONIX_DetectTouch(SITRONIX_Object_t *pObj);
|
|
|
|
// static int32_t ReadRegWrap(void *handle, uint8_t Reg, uint8_t *Data,
|
|
|
|
// uint16_t Length);
|
|
|
|
// static int32_t WriteRegWrap(void *handle, uint8_t Reg, uint8_t *Data,
|
|
|
|
// uint16_t Length);
|
|
|
|
// static int32_t ReadDataWrap(void *handle, uint8_t *pData, uint16_t Length);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup SITRONIX_Exported_Functions SITRONIX Exported Functions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get SITRONIX sensor capabilities
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @param Capabilities pointer to SITRONIX sensor capabilities
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_GetCapabilities(SITRONIX_Object_t *pObj,
|
|
|
|
SITRONIX_Capabilities_t *Capabilities) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
(void)(pObj);
|
|
|
|
|
|
|
|
/* Store component's capabilities */
|
|
|
|
Capabilities->MultiTouch = 1;
|
|
|
|
Capabilities->Gesture =
|
|
|
|
0; /* Gesture feature is currently not activated on FW chipset */
|
|
|
|
Capabilities->MaxTouch = SITRONIX_MAX_DETECTABLE_TOUCH;
|
|
|
|
Capabilities->MaxXl = SITRONIX_MAX_X_LENGTH;
|
|
|
|
Capabilities->MaxYl = SITRONIX_MAX_Y_LENGTH;
|
|
|
|
|
|
|
|
return SITRONIX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize the SITRONIX communication bus
|
|
|
|
* from MCU to SITRONIX : ie I2C channel initialization (if required).
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_Init(SITRONIX_Object_t *pObj) {
|
|
|
|
int32_t ret = SITRONIX_OK;
|
|
|
|
uint8_t data[28U];
|
|
|
|
|
|
|
|
if (pObj->IsInitialized == 0U) {
|
|
|
|
if (sitronix_read_data(data, (uint16_t)sizeof(data)) != SITRONIX_OK) {
|
|
|
|
ret = SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
pObj->IsInitialized = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret != SITRONIX_OK) {
|
|
|
|
ret = SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief De-Initialize the SITRONIX communication bus
|
|
|
|
* from MCU to SITRONIX : ie I2C channel initialization (if required).
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_DeInit(SITRONIX_Object_t *pObj) {
|
|
|
|
if (pObj->IsInitialized == 1U) {
|
|
|
|
pObj->IsInitialized = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SITRONIX_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Configure the SITRONIX gesture
|
|
|
|
* from MCU to SITRONIX : ie I2C channel initialization (if required).
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @param GestureInit Gesture init structure
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_GestureConfig(SITRONIX_Object_t *pObj,
|
|
|
|
SITRONIX_Gesture_Init_t *GestureInit) {
|
|
|
|
return SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Read the SITRONIX device ID, pre initialize I2C in case of need to be
|
|
|
|
* able to read the SITRONIX device ID, and verify this is a SITRONIX.
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @param Id Pointer to component's ID
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_ReadID(SITRONIX_Object_t *pObj, uint32_t *Id) {
|
|
|
|
int32_t ret = SITRONIX_OK;
|
|
|
|
uint8_t data[28];
|
|
|
|
uint8_t trial = 0;
|
|
|
|
|
|
|
|
for (trial = 0; trial < 10; trial++) {
|
|
|
|
if (sitronix_read_data(data, 28) != SITRONIX_OK) {
|
|
|
|
ret = SITRONIX_ERROR;
|
|
|
|
} else {
|
|
|
|
if ((uint32_t)data[0] == SITRONIX_ID) {
|
|
|
|
*Id = (uint32_t)data[0];
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t sitronix_touching = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the touch screen X and Y positions values
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @param State Single Touch structure pointer
|
|
|
|
* @retval Component status.
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_GetState(SITRONIX_Object_t *pObj, SITRONIX_State_t *State) {
|
|
|
|
int32_t ret = SITRONIX_OK;
|
|
|
|
uint8_t data[64];
|
|
|
|
|
|
|
|
State->TouchDetected = (uint32_t)SITRONIX_DetectTouch(pObj);
|
|
|
|
if (sitronix_read_data(data, (uint16_t)sizeof(data)) != SITRONIX_OK) {
|
|
|
|
ret = SITRONIX_ERROR;
|
|
|
|
} else {
|
|
|
|
if ((uint32_t)data[2] & 0x80) {
|
|
|
|
sitronix_touching = 1;
|
|
|
|
} else {
|
|
|
|
sitronix_touching = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
State->TouchX = (((uint32_t)data[2] & SITRONIX_TOUCH_POS_LSB_MASK) << 4);
|
|
|
|
|
|
|
|
/* Send back first ready X position to caller */
|
|
|
|
State->TouchX = ((((uint32_t)data[2] & SITRONIX_TOUCH_POS_LSB_MASK) << 4) |
|
|
|
|
((uint32_t)data[3]));
|
|
|
|
/* Send back first ready Y position to caller */
|
|
|
|
State->TouchY = (((uint32_t)data[2] & SITRONIX_TOUCH_POS_MSB_MASK) << 8) |
|
|
|
|
((uint32_t)data[4]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the touch screen Xn and Yn positions values in multi-touch mode
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @param State Multi Touch structure pointer
|
|
|
|
* @retval Component status.
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_GetMultiTouchState(SITRONIX_Object_t *pObj,
|
|
|
|
SITRONIX_MultiTouch_State_t *State) {
|
|
|
|
int32_t ret = SITRONIX_OK;
|
|
|
|
uint8_t data[28];
|
|
|
|
|
|
|
|
State->TouchDetected = (uint32_t)SITRONIX_DetectTouch(pObj);
|
|
|
|
|
|
|
|
if (sitronix_read_reg(SITRONIX_P1_XH_REG, data, (uint16_t)sizeof(data)) !=
|
|
|
|
SITRONIX_OK) {
|
|
|
|
ret = SITRONIX_ERROR;
|
|
|
|
} else {
|
|
|
|
/* To be implemented */
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get Gesture ID
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @param GestureId gesture ID
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_GetGesture(SITRONIX_Object_t *pObj, uint8_t *GestureId) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
(void)(pObj);
|
|
|
|
|
|
|
|
/* Always return SITRONIX_OK as feature not supported by SITRONIX */
|
|
|
|
return SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Configure the SITRONIX device to generate IT on given INT pin
|
|
|
|
* connected to MCU as EXTI.
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_EnableIT(SITRONIX_Object_t *pObj) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
(void)(pObj);
|
|
|
|
|
|
|
|
/* Always return SITRONIX_OK as feature not supported by SITRONIX */
|
|
|
|
return SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Configure the SITRONIX device to stop generating IT on the given INT
|
|
|
|
* pin connected to MCU as EXTI.
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_DisableIT(SITRONIX_Object_t *pObj) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
(void)(pObj);
|
|
|
|
|
|
|
|
/* Always return SITRONIX_OK as feature not supported by SITRONIX */
|
|
|
|
return SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get IT status from SITRONIX interrupt status registers
|
|
|
|
* Should be called Following an EXTI coming to the MCU to know the
|
|
|
|
* detailed reason of the interrupt.
|
|
|
|
* @note : This feature is not supported by SITRONIX.
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_ITStatus(SITRONIX_Object_t *pObj) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
(void)(pObj);
|
|
|
|
|
|
|
|
/* Always return SITRONIX_OK as feature not supported by SITRONIX */
|
|
|
|
return SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Clear IT status in SITRONIX interrupt status clear registers
|
|
|
|
* Should be called Following an EXTI coming to the MCU.
|
|
|
|
* @note : This feature is not supported by SITRONIX.
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Component status
|
|
|
|
*/
|
|
|
|
int32_t SITRONIX_ClearIT(SITRONIX_Object_t *pObj) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
(void)(pObj);
|
|
|
|
|
|
|
|
/* Always return SITRONIX_OK as feature not supported by SITRONIX */
|
|
|
|
return SITRONIX_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup SITRONIX_Private_Functions SITRONIX Private Functions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Return if there is touches detected or not.
|
|
|
|
* Try to detect new touches and forget the old ones (reset internal
|
|
|
|
* global variables).
|
|
|
|
* @param pObj Component object pointer
|
|
|
|
* @retval Number of active touches detected (can be between 0 and10) or
|
|
|
|
* SITRONIX_ERROR in case of error
|
|
|
|
*/
|
|
|
|
__attribute__((optimize("-O0"))) int32_t SITRONIX_DetectTouch(
|
|
|
|
SITRONIX_Object_t *pObj) {
|
|
|
|
int32_t ret;
|
|
|
|
uint8_t nb_touch = 0;
|
|
|
|
static uint8_t first_event = 0;
|
|
|
|
uint8_t data[28];
|
|
|
|
|
|
|
|
if (sitronix_read_data((uint8_t *)&data, 28) != SITRONIX_OK) {
|
|
|
|
ret = SITRONIX_ERROR;
|
|
|
|
} else {
|
|
|
|
if (first_event == 0) {
|
|
|
|
if ((data[0] == 0x09)) {
|
|
|
|
nb_touch = 1;
|
|
|
|
first_event = 1;
|
|
|
|
} else {
|
|
|
|
nb_touch = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (data[8] == 0x60) {
|
|
|
|
nb_touch = 0;
|
|
|
|
} else {
|
|
|
|
nb_touch = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret = (int32_t)nb_touch;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
///**
|
|
|
|
// * @brief Wrap IO bus read function to component register red function
|
|
|
|
// * @param handle Component object handle
|
|
|
|
// * @param Reg The target register address to read
|
|
|
|
// * @param pData The target register value to be read
|
|
|
|
// * @param Length buffer size to be read
|
|
|
|
// * @retval Component status.
|
|
|
|
// */
|
|
|
|
// static int32_t ReadRegWrap(void *handle, uint8_t Reg, uint8_t *pData,
|
|
|
|
// uint16_t Length) {
|
|
|
|
// return i2c_mem_read(TOUCH_I2C_INSTANCE, TS_I2C_ADDRESS, Reg, Length, pData,
|
|
|
|
// Length, 1000);
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
///**
|
|
|
|
// * @brief Wrap IO bus write function to component register write function
|
|
|
|
// * @param handle Component object handle
|
|
|
|
// * @param Reg The target register address to write
|
|
|
|
// * @param pData The target register value to be written
|
|
|
|
// * @param Length buffer size to be written
|
|
|
|
// * @retval Component status.
|
|
|
|
// */
|
|
|
|
// static int32_t WriteRegWrap(void *handle, uint8_t Reg, uint8_t *pData,
|
|
|
|
// uint16_t Length) {
|
|
|
|
// return i2c_mem_write(TOUCH_I2C_INSTANCE, TS_I2C_ADDRESS, Reg, Length, pData,
|
|
|
|
// Length, 1000);
|
|
|
|
//}
|
|
|
|
//
|
|
|
|
///**
|
|
|
|
// * @brief Wrap IO bus read function to component register red function
|
|
|
|
// * @param handle Component object handle
|
|
|
|
// * @param pData The target register value to be read
|
|
|
|
// * @param Length buffer size to be read
|
|
|
|
// * @retval Component status.
|
|
|
|
// */
|
|
|
|
// static int32_t ReadDataWrap(void *handle, uint8_t *pData, uint16_t Length) {
|
|
|
|
// return i2c_receive(TOUCH_I2C_INSTANCE, TS_I2C_ADDRESS, pData, Length, 1000);
|
|
|
|
//}
|
|
|
|
|
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* @file stm32u5x9j_discovery_ts.c
|
|
|
|
* @author MCD Application Team
|
|
|
|
* @brief This file provides a set of functions needed to manage the Touch
|
|
|
|
* Screen on STM32U5x9J-DISCOVERY board.
|
|
|
|
@verbatim
|
|
|
|
1. How To use this driver:
|
|
|
|
--------------------------
|
|
|
|
- This driver is used to drive the touch screen module of the
|
|
|
|
STM32U5x9J-DISCOVERY board on the LCD mounted on MB1829A daughter board. The
|
|
|
|
touch screen driver IC is a SITRONIX.
|
|
|
|
|
|
|
|
2. Driver description:
|
|
|
|
---------------------
|
|
|
|
+ Initialization steps:
|
|
|
|
o Initialize the TS using the BSP_TS_Init() function. You can select
|
|
|
|
display orientation with "Orientation" parameter of TS_Init_t structure
|
|
|
|
(portrait, landscape, portrait with 180 degrees rotation or landscape
|
|
|
|
with 180 degrees rotation). The LCD size properties (width and height)
|
|
|
|
are also parameters of TS_Init_t and depend on the orientation
|
|
|
|
selected.
|
|
|
|
|
|
|
|
+ Touch screen use
|
|
|
|
o Call BSP_TS_EnableIT() (BSP_TS_DisableIT()) to enable (disable) touch
|
|
|
|
screen interrupt. BSP_TS_Callback() is called when TS interrupt occurs.
|
|
|
|
o Call BSP_TS_GetState() to get the current touch status (detection and
|
|
|
|
coordinates).
|
|
|
|
o Call BSP_TS_Set_Orientation() to change the current orientation.
|
|
|
|
Call BSP_TS_Get_Orientation() to get the current orientation.
|
|
|
|
o Call BSP_TS_GetCapabilities() to get the SITRONIX capabilities.
|
|
|
|
o SITRONIX doesn't support multi touch and gesture features.
|
|
|
|
BSP_TS_Get_MultiTouchState(), BSP_TS_GestureConfig() and
|
|
|
|
BSP_TS_GetGestureId() functions will return
|
|
|
|
BSP_ERROR_FEATURE_NOT_SUPPORTED.
|
|
|
|
|
|
|
|
+ De-initialization steps:
|
|
|
|
o De-initialize the touch screen using the BSP_TS_DeInit() function.
|
|
|
|
|
|
|
|
@endverbatim
|
|
|
|
******************************************************************************
|
|
|
|
* @attention
|
|
|
|
*
|
|
|
|
* Copyright (c) 2023 STMicroelectronics.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
|
|
* in the root directory of this software component.
|
|
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
/* TS instances */
|
|
|
|
#define TS_INSTANCES_NBR 1U
|
|
|
|
#define TS_TOUCH_NBR 10U
|
|
|
|
|
|
|
|
/* TS orientations */
|
|
|
|
#define TS_ORIENTATION_PORTRAIT 0U
|
|
|
|
#define TS_ORIENTATION_LANDSCAPE 1U
|
|
|
|
#define TS_ORIENTATION_PORTRAIT_ROT180 2U
|
|
|
|
#define TS_ORIENTATION_LANDSCAPE_ROT180 3U
|
|
|
|
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_TS_Exported_Types TS Exported Types
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
uint32_t Width; /* Screen width */
|
|
|
|
uint32_t Height; /* Screen height */
|
|
|
|
uint32_t Orientation; /* Touch screen orientation */
|
|
|
|
uint32_t Accuracy; /* Expressed in pixel and means the x or y difference vs
|
|
|
|
old position to consider the new values valid */
|
|
|
|
} TS_Init_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t MultiTouch;
|
|
|
|
uint8_t Gesture;
|
|
|
|
uint8_t MaxTouch;
|
|
|
|
uint32_t MaxXl;
|
|
|
|
uint32_t MaxYl;
|
|
|
|
} TS_Capabilities_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t TouchDetected;
|
|
|
|
uint32_t TouchX;
|
|
|
|
uint32_t TouchY;
|
|
|
|
} TS_State_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t TouchDetected;
|
|
|
|
uint32_t TouchX[2];
|
|
|
|
uint32_t TouchY[2];
|
|
|
|
uint32_t TouchWeight[2];
|
|
|
|
uint32_t TouchEvent[2];
|
|
|
|
uint32_t TouchArea[2];
|
|
|
|
} TS_MultiTouch_State_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t Radian;
|
|
|
|
uint32_t OffsetLeftRight;
|
|
|
|
uint32_t OffsetUpDown;
|
|
|
|
uint32_t DistanceLeftRight;
|
|
|
|
uint32_t DistanceUpDown;
|
|
|
|
uint32_t DistanceZoom;
|
|
|
|
} TS_Gesture_Config_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint32_t Width;
|
|
|
|
uint32_t Height;
|
|
|
|
uint32_t Orientation;
|
|
|
|
uint32_t Accuracy;
|
|
|
|
uint32_t MaxX;
|
|
|
|
uint32_t MaxY;
|
|
|
|
uint32_t PreviousX[TS_TOUCH_NBR];
|
|
|
|
uint32_t PreviousY[TS_TOUCH_NBR];
|
|
|
|
} TS_Ctx_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int32_t (*Init)(void *);
|
|
|
|
int32_t (*DeInit)(void *);
|
|
|
|
int32_t (*GestureConfig)(void *, void *);
|
|
|
|
int32_t (*ReadID)(void *, uint32_t *);
|
|
|
|
int32_t (*GetState)(void *, void *);
|
|
|
|
int32_t (*GetMultiTouchState)(void *, void *);
|
|
|
|
int32_t (*GetGesture)(void *, void *);
|
|
|
|
int32_t (*GetCapabilities)(void *, void *);
|
|
|
|
int32_t (*EnableIT)(void *);
|
|
|
|
int32_t (*DisableIT)(void *);
|
|
|
|
int32_t (*ClearIT)(void *);
|
|
|
|
int32_t (*ITStatus)(void *);
|
|
|
|
} TS_Drv_t;
|
|
|
|
|
|
|
|
/* DSI TS INT pin */
|
|
|
|
#define TS_INT_PIN GPIO_PIN_8
|
|
|
|
#define TS_INT_GPIO_PORT GPIOE
|
|
|
|
#define TS_INT_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
|
|
|
|
#define TS_INT_GPIO_CLK_DISABLE() __HAL_RCC_GPIOE_CLK_DISABLE()
|
|
|
|
#define TS_INT_EXTI_IRQn EXTI8_IRQn
|
|
|
|
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
|
//#include "stm32u5x9j_discovery_ts.h"
|
|
|
|
//#include "stm32u5x9j_discovery.h"
|
|
|
|
|
|
|
|
/** @addtogroup BSP
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @addtogroup STM32U5x9J_DISCOVERY
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_TS TS
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_TS_Private_Defines TS Private Defines
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_TS_Private_TypesDefinitions TS Private
|
|
|
|
* TypesDefinitions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
typedef void (*BSP_EXTI_LineCallback)(void);
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @addtogroup STM32U5x9J_DISCOVERY_TS_Exported_Variables TS Exported Variables
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
void *Ts_CompObj[TS_INSTANCES_NBR] = {0};
|
|
|
|
TS_Drv_t *Ts_Drv[TS_INSTANCES_NBR] = {0};
|
|
|
|
TS_Ctx_t Ts_Ctx[TS_INSTANCES_NBR] = {0};
|
|
|
|
EXTI_HandleTypeDef hts_exti[TS_INSTANCES_NBR];
|
|
|
|
IRQn_Type Ts_IRQn[TS_INSTANCES_NBR] = {EXTI15_IRQn};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_TS_Private_FunctionPrototypes TS Private
|
|
|
|
* Function Prototypes
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
static int32_t SITRONIX_Probe(uint32_t Instance);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @addtogroup STM32U5x9J_DISCOVERY_TS_Exported_Functions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @brief Initialize the TS.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param TS_Init Pointer to TS initialization structure.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_Init(uint32_t Instance, TS_Init_t *TS_Init) {
|
|
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
|
|
|
|
if ((TS_Init == NULL) || (Instance >= TS_INSTANCES_NBR)) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Probe the TS driver */
|
|
|
|
if (SITRONIX_Probe(Instance) != BSP_ERROR_NONE) {
|
|
|
|
status = BSP_ERROR_COMPONENT_FAILURE;
|
|
|
|
} else {
|
|
|
|
TS_Capabilities_t Capabilities;
|
|
|
|
uint32_t i;
|
|
|
|
/* Store parameters on TS context */
|
|
|
|
Ts_Ctx[Instance].Width = TS_Init->Width;
|
|
|
|
Ts_Ctx[Instance].Height = TS_Init->Height;
|
|
|
|
Ts_Ctx[Instance].Orientation = TS_Init->Orientation;
|
|
|
|
Ts_Ctx[Instance].Accuracy = TS_Init->Accuracy;
|
|
|
|
/* Get capabilities to retrieve maximum values of X and Y */
|
|
|
|
if (Ts_Drv[Instance]->GetCapabilities(Ts_CompObj[Instance],
|
|
|
|
&Capabilities) < 0) {
|
|
|
|
status = BSP_ERROR_COMPONENT_FAILURE;
|
|
|
|
} else {
|
|
|
|
/* Store maximum X and Y on context */
|
|
|
|
Ts_Ctx[Instance].MaxX = Capabilities.MaxXl;
|
|
|
|
Ts_Ctx[Instance].MaxY = Capabilities.MaxYl;
|
|
|
|
/* Initialize previous position in order to always detect first touch */
|
|
|
|
for (i = 0; i < TS_TOUCH_NBR; i++) {
|
|
|
|
Ts_Ctx[Instance].PreviousX[i] =
|
|
|
|
TS_Init->Width + TS_Init->Accuracy + 1U;
|
|
|
|
Ts_Ctx[Instance].PreviousY[i] =
|
|
|
|
TS_Init->Height + TS_Init->Accuracy + 1U;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief De-Initialize the TS.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_DeInit(uint32_t Instance) {
|
|
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
|
|
|
|
if (Instance >= TS_INSTANCES_NBR) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* De-Init the TS driver */
|
|
|
|
if (Ts_Drv[Instance]->DeInit(Ts_CompObj[Instance]) < 0) {
|
|
|
|
status = BSP_ERROR_COMPONENT_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Enable the TS interrupt.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_EnableIT(uint32_t Instance) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
UNUSED(Instance);
|
|
|
|
|
|
|
|
GPIO_InitTypeDef gpio_init_structure;
|
|
|
|
|
|
|
|
__HAL_RCC_GPIOE_CLK_ENABLE();
|
|
|
|
|
|
|
|
/* Configure Interrupt mode for TS detection pin */
|
|
|
|
gpio_init_structure.Pin = TS_INT_PIN;
|
|
|
|
gpio_init_structure.Pull = GPIO_PULLUP;
|
|
|
|
gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
|
|
gpio_init_structure.Mode = GPIO_MODE_IT_FALLING;
|
|
|
|
HAL_GPIO_Init(TS_INT_GPIO_PORT, &gpio_init_structure);
|
|
|
|
|
|
|
|
/* Enable and set Touch screen EXTI Interrupt to the lowest priority */
|
|
|
|
HAL_NVIC_SetPriority((IRQn_Type)(TS_INT_EXTI_IRQn), 0x0F, 0x00);
|
|
|
|
HAL_NVIC_EnableIRQ((IRQn_Type)(TS_INT_EXTI_IRQn));
|
|
|
|
|
|
|
|
return BSP_ERROR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Disable the TS interrupt.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_DisableIT(uint32_t Instance) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
UNUSED(Instance);
|
|
|
|
|
|
|
|
/* To be Implemented */
|
|
|
|
return BSP_ERROR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Set the TS orientation.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param Orientation TS orientation.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_Set_Orientation(uint32_t Instance, uint32_t Orientation) {
|
|
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
uint32_t temp;
|
|
|
|
uint32_t i;
|
|
|
|
|
|
|
|
if ((Instance >= TS_INSTANCES_NBR) ||
|
|
|
|
(Orientation > TS_ORIENTATION_LANDSCAPE_ROT180)) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Update TS context if orientation is changed from/to portrait to/from
|
|
|
|
* landscape */
|
|
|
|
if ((((Ts_Ctx[Instance].Orientation == TS_ORIENTATION_LANDSCAPE) ||
|
|
|
|
(Ts_Ctx[Instance].Orientation == TS_ORIENTATION_LANDSCAPE_ROT180)) &&
|
|
|
|
((Orientation == TS_ORIENTATION_PORTRAIT) ||
|
|
|
|
(Orientation == TS_ORIENTATION_PORTRAIT_ROT180))) ||
|
|
|
|
(((Ts_Ctx[Instance].Orientation == TS_ORIENTATION_PORTRAIT) ||
|
|
|
|
(Ts_Ctx[Instance].Orientation == TS_ORIENTATION_PORTRAIT_ROT180)) &&
|
|
|
|
((Orientation == TS_ORIENTATION_LANDSCAPE) ||
|
|
|
|
(Orientation == TS_ORIENTATION_LANDSCAPE_ROT180)))) {
|
|
|
|
/* Invert width and height */
|
|
|
|
temp = Ts_Ctx[Instance].Width;
|
|
|
|
Ts_Ctx[Instance].Width = Ts_Ctx[Instance].Height;
|
|
|
|
Ts_Ctx[Instance].Height = temp;
|
|
|
|
/* Invert MaxX and MaxY */
|
|
|
|
temp = Ts_Ctx[Instance].MaxX;
|
|
|
|
Ts_Ctx[Instance].MaxX = Ts_Ctx[Instance].MaxY;
|
|
|
|
Ts_Ctx[Instance].MaxY = temp;
|
|
|
|
}
|
|
|
|
/* Store orientation on TS context */
|
|
|
|
Ts_Ctx[Instance].Orientation = Orientation;
|
|
|
|
/* Reset previous position */
|
|
|
|
for (i = 0; i < TS_TOUCH_NBR; i++) {
|
|
|
|
Ts_Ctx[Instance].PreviousX[i] =
|
|
|
|
Ts_Ctx[Instance].Width + Ts_Ctx[Instance].Accuracy + 1U;
|
|
|
|
Ts_Ctx[Instance].PreviousY[i] =
|
|
|
|
Ts_Ctx[Instance].Height + Ts_Ctx[Instance].Accuracy + 1U;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the TS orientation.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param Orientation Pointer to TS orientation.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_Get_Orientation(uint32_t Instance, uint32_t *Orientation) {
|
|
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
|
|
|
|
if ((Instance >= TS_INSTANCES_NBR) || (Orientation == NULL)) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Get orientation from TS context */
|
|
|
|
*Orientation = Ts_Ctx[Instance].Orientation;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get position of a single touch.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param TS_State Pointer to single touch structure.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_GetState(uint32_t Instance, TS_State_t *TS_State) {
|
|
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
uint32_t x_oriented;
|
|
|
|
uint32_t y_oriented;
|
|
|
|
uint32_t x_diff;
|
|
|
|
uint32_t y_diff;
|
|
|
|
|
|
|
|
if (Instance >= TS_INSTANCES_NBR) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
SITRONIX_State_t state;
|
|
|
|
|
|
|
|
/* Get each touch coordinates */
|
|
|
|
if (Ts_Drv[Instance]->GetState(Ts_CompObj[Instance], &state) < 0) {
|
|
|
|
status = BSP_ERROR_COMPONENT_FAILURE;
|
|
|
|
} /* Check and update the number of touches active detected */
|
|
|
|
else if (state.TouchDetected != 0U) {
|
|
|
|
x_oriented = /*Ts_Ctx[Instance].MaxX -*/ state.TouchX;
|
|
|
|
y_oriented = /*Ts_Ctx[Instance].MaxY -*/ state.TouchY;
|
|
|
|
|
|
|
|
/* Apply boundary */
|
|
|
|
TS_State->TouchX =
|
|
|
|
(x_oriented * Ts_Ctx[Instance].Width) / (Ts_Ctx[Instance].MaxX);
|
|
|
|
TS_State->TouchY =
|
|
|
|
(y_oriented * Ts_Ctx[Instance].Height) / (Ts_Ctx[Instance].MaxY);
|
|
|
|
/* Store Current TS state */
|
|
|
|
TS_State->TouchDetected = state.TouchDetected;
|
|
|
|
|
|
|
|
/* Check accuracy */
|
|
|
|
x_diff = (TS_State->TouchX > Ts_Ctx[Instance].PreviousX[0])
|
|
|
|
? (TS_State->TouchX - Ts_Ctx[Instance].PreviousX[0])
|
|
|
|
: (Ts_Ctx[Instance].PreviousX[0] - TS_State->TouchX);
|
|
|
|
|
|
|
|
y_diff = (TS_State->TouchY > Ts_Ctx[Instance].PreviousY[0])
|
|
|
|
? (TS_State->TouchY - Ts_Ctx[Instance].PreviousY[0])
|
|
|
|
: (Ts_Ctx[Instance].PreviousY[0] - TS_State->TouchY);
|
|
|
|
|
|
|
|
if ((x_diff > Ts_Ctx[Instance].Accuracy) ||
|
|
|
|
(y_diff > Ts_Ctx[Instance].Accuracy)) {
|
|
|
|
/* New touch detected */
|
|
|
|
Ts_Ctx[Instance].PreviousX[0] = TS_State->TouchX;
|
|
|
|
Ts_Ctx[Instance].PreviousY[0] = TS_State->TouchY;
|
|
|
|
} else {
|
|
|
|
TS_State->TouchX = Ts_Ctx[Instance].PreviousX[0];
|
|
|
|
TS_State->TouchY = Ts_Ctx[Instance].PreviousY[0];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TS_State->TouchDetected = 0U;
|
|
|
|
TS_State->TouchX = Ts_Ctx[Instance].PreviousX[0];
|
|
|
|
TS_State->TouchY = Ts_Ctx[Instance].PreviousY[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get positions of multiple touch.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param TS_State Pointer to multiple touch structure.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_Get_MultiTouchState(const uint32_t Instance,
|
|
|
|
TS_MultiTouch_State_t *TS_State) {
|
|
|
|
int32_t status;
|
|
|
|
|
|
|
|
UNUSED(TS_State);
|
|
|
|
|
|
|
|
if (Instance >= TS_INSTANCES_NBR) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Feature not supported in this release */
|
|
|
|
status = BSP_ERROR_FEATURE_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Configure gesture on TS.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param GestureConfig Pointer to gesture configuration structure.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_GestureConfig(const uint32_t Instance,
|
|
|
|
TS_Gesture_Config_t *GestureConfig) {
|
|
|
|
int32_t status;
|
|
|
|
|
|
|
|
if ((Instance >= TS_INSTANCES_NBR) || (GestureConfig == NULL)) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Feature not supported */
|
|
|
|
status = BSP_ERROR_FEATURE_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get gesture.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param GestureId Pointer to gesture.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_GetGestureId(const uint32_t Instance, uint32_t *GestureId) {
|
|
|
|
int32_t status;
|
|
|
|
|
|
|
|
if ((Instance >= TS_INSTANCES_NBR) || (GestureId == NULL)) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Feature not supported */
|
|
|
|
status = BSP_ERROR_FEATURE_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get the TS capabilities.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @param Capabilities Pointer to TS capabilities structure.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
int32_t BSP_TS_GetCapabilities(uint32_t Instance,
|
|
|
|
TS_Capabilities_t *Capabilities) {
|
|
|
|
int32_t status = BSP_ERROR_NONE;
|
|
|
|
|
|
|
|
if ((Instance >= TS_INSTANCES_NBR) || (Capabilities == NULL)) {
|
|
|
|
status = BSP_ERROR_WRONG_PARAM;
|
|
|
|
} else {
|
|
|
|
/* Get the TS driver capabilities */
|
|
|
|
if (Ts_Drv[Instance]->GetCapabilities(Ts_CompObj[Instance], Capabilities) <
|
|
|
|
0) {
|
|
|
|
status = BSP_ERROR_COMPONENT_FAILURE;
|
|
|
|
} else {
|
|
|
|
/* Update maximum X and Y according orientation */
|
|
|
|
if ((Ts_Ctx[Instance].Orientation == TS_ORIENTATION_LANDSCAPE) ||
|
|
|
|
(Ts_Ctx[Instance].Orientation == TS_ORIENTATION_LANDSCAPE_ROT180)) {
|
|
|
|
uint32_t tmp;
|
|
|
|
tmp = Capabilities->MaxXl;
|
|
|
|
Capabilities->MaxXl = Capabilities->MaxYl;
|
|
|
|
Capabilities->MaxYl = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief TS Callback.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @retval None.
|
|
|
|
*/
|
|
|
|
__weak void BSP_TS_Callback(uint32_t Instance) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
UNUSED(Instance);
|
|
|
|
|
|
|
|
/* This function should be implemented by the user application.
|
|
|
|
It is called into this driver when an event on TS touch detection */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief BSP TS interrupt handler.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @retval None.
|
|
|
|
*/
|
|
|
|
void BSP_TS_IRQHandler(uint32_t Instance) {
|
|
|
|
/* Prevent unused argument(s) compilation warning */
|
|
|
|
UNUSED(Instance);
|
|
|
|
|
|
|
|
/* To be implemented */
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @defgroup STM32U5x9J_DISCOVERY_TS_Private_Functions TS Private Functions
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @brief Probe the SITRONIX TS driver.
|
|
|
|
* @param Instance TS Instance.
|
|
|
|
* @retval BSP status.
|
|
|
|
*/
|
|
|
|
static int32_t SITRONIX_Probe(uint32_t Instance) {
|
|
|
|
int32_t status;
|
|
|
|
static SITRONIX_Object_t SITRONIXObj;
|
|
|
|
|
|
|
|
Ts_CompObj[Instance] = &SITRONIXObj;
|
|
|
|
Ts_Drv[Instance] = (TS_Drv_t *)&SITRONIX_TS_Driver;
|
|
|
|
if (Ts_Drv[Instance]->Init(Ts_CompObj[Instance]) < 0) {
|
|
|
|
status = BSP_ERROR_COMPONENT_FAILURE;
|
|
|
|
} else {
|
|
|
|
status = BSP_ERROR_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include "touch.h"
|
|
|
|
|
|
|
|
void touch_init(void) {
|
|
|
|
TS_Init_t TsInit;
|
|
|
|
|
|
|
|
/* Initialize the TouchScreen */
|
|
|
|
TsInit.Width = 480;
|
|
|
|
TsInit.Height = 480;
|
|
|
|
TsInit.Orientation = 0;
|
|
|
|
TsInit.Accuracy = 10;
|
|
|
|
|
|
|
|
BSP_TS_Init(0, &TsInit);
|
|
|
|
}
|
|
|
|
void touch_power_on(void) {}
|
|
|
|
void touch_power_off(void) {}
|
|
|
|
void touch_sensitivity(uint8_t value) {}
|
|
|
|
|
|
|
|
uint32_t touch_is_detected(void) { return sitronix_touching != 0; }
|
|
|
|
|
|
|
|
uint32_t touch_read(void) {
|
|
|
|
TS_State_t state = {0};
|
|
|
|
static uint32_t xy = 0;
|
|
|
|
static TS_State_t state_last = {0};
|
|
|
|
// static uint16_t first = 1;
|
|
|
|
static uint16_t touching = 0;
|
|
|
|
|
|
|
|
BSP_TS_GetState(0, &state);
|
|
|
|
|
|
|
|
state.TouchDetected = touch_is_detected();
|
|
|
|
state.TouchY = state.TouchY > 120 ? state.TouchY - 120 : 0;
|
|
|
|
state.TouchX = state.TouchX > 120 ? state.TouchX - 120 : 0;
|
|
|
|
|
|
|
|
if (!touch_is_detected()) {
|
|
|
|
// if (state.TouchDetected == 0) {
|
|
|
|
if (touching) {
|
|
|
|
// touch end
|
|
|
|
memcpy(&state_last, &state, sizeof(state));
|
|
|
|
touching = 0;
|
|
|
|
return TOUCH_END | xy;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (state.TouchDetected == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if (first != 0) {
|
|
|
|
// memcpy(&state_last, &state, sizeof(state));
|
|
|
|
// first = 0;
|
|
|
|
// return 0;
|
|
|
|
// }
|
|
|
|
|
|
|
|
if ((state.TouchDetected == 0 && state_last.TouchDetected == 0) ||
|
|
|
|
memcmp(&state, &state_last, sizeof(state)) == 0) {
|
|
|
|
// no change detected
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
xy = touch_pack_xy(state.TouchX, state.TouchY);
|
|
|
|
|
|
|
|
if (state.TouchDetected && !state_last.TouchDetected) {
|
|
|
|
// touch start
|
|
|
|
memcpy(&state_last, &state, sizeof(state));
|
|
|
|
touching = 1;
|
|
|
|
return TOUCH_START | xy;
|
|
|
|
} else if (!state.TouchDetected && state_last.TouchDetected) {
|
|
|
|
// touch end
|
|
|
|
memcpy(&state_last, &state, sizeof(state));
|
|
|
|
touching = 0;
|
|
|
|
return TOUCH_END | xy;
|
|
|
|
} else {
|
|
|
|
// touch move
|
|
|
|
memcpy(&state_last, &state, sizeof(state));
|
|
|
|
return TOUCH_MOVE | xy;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|