[imxrt 1060] support touchpad
Signed-off-by: Ting Liu <ting.liu@nxp.com>
This commit is contained in:
parent
f92c26a60b
commit
880fc2f59a
|
@ -1,13 +1,246 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
* Copyright 2022 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-10-18 Meco Man The first version
|
||||
* 2022-05-17 Ting Liu Support touchpad
|
||||
*/
|
||||
|
||||
#define LOG_TAG "LVGL.port.indev"
|
||||
#include <drv_log.h>
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "board.h"
|
||||
#include "fsl_video_common.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
#include "fsl_gpio.h"
|
||||
#ifdef DEMO_PANEL_RK043FN66HS
|
||||
#include "fsl_gt911.h"
|
||||
#else
|
||||
#include "fsl_ft5406_rt.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
#include "src/gpu/lv_gpu_nxp_pxp.h"
|
||||
#include "src/gpu/lv_gpu_nxp_pxp_osa.h"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/* @Brief Board touch panel configuration */
|
||||
#define BOARD_TOUCH_I2C_BASEADDR LPI2C1
|
||||
#define BOARD_TOUCH_RST_GPIO GPIO1
|
||||
#define BOARD_TOUCH_RST_PIN 2
|
||||
#define BOARD_TOUCH_INT_GPIO GPIO1
|
||||
#define BOARD_TOUCH_INT_PIN 11
|
||||
|
||||
/* Macros for the touch touch controller. */
|
||||
#define TOUCH_I2C LPI2C1
|
||||
|
||||
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
|
||||
#define TOUCH_LPI2C_CLOCK_SOURCE_SELECT (0U)
|
||||
/* Clock divider for master lpi2c clock source */
|
||||
#define TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER (5U)
|
||||
|
||||
#define TOUCH_I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
|
||||
#define TOUCH_I2C_BAUDRATE 100000U
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
static void DEMO_InitTouch(void);
|
||||
|
||||
static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data);
|
||||
#ifdef DEMO_PANEL_RK043FN66HS
|
||||
static void BOARD_PullTouchResetPin(bool pullUp);
|
||||
|
||||
static void BOARD_ConfigTouchIntPin(gt911_int_pin_mode_t mode);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
#ifdef DEMO_PANEL_RK043FN66HS
|
||||
static gt911_handle_t s_touchHandle;
|
||||
static const gt911_config_t s_touchConfig = {
|
||||
.I2C_SendFunc = BOARD_Touch_I2C_Send,
|
||||
.I2C_ReceiveFunc = BOARD_Touch_I2C_Receive,
|
||||
.pullResetPinFunc = BOARD_PullTouchResetPin,
|
||||
.intPinFunc = BOARD_ConfigTouchIntPin,
|
||||
.timeDelayMsFunc = VIDEO_DelayMs,
|
||||
.touchPointNum = 1,
|
||||
.i2cAddrMode = kGT911_I2cAddrMode0,
|
||||
.intTrigMode = kGT911_IntRisingEdge,
|
||||
};
|
||||
static int s_touchResolutionX;
|
||||
static int s_touchResolutionY;
|
||||
#else
|
||||
static ft5406_rt_handle_t touchHandle;
|
||||
#endif
|
||||
|
||||
void lv_port_indev_init(void)
|
||||
{
|
||||
static lv_indev_drv_t indev_drv;
|
||||
|
||||
/*------------------
|
||||
* Touchpad
|
||||
* -----------------*/
|
||||
|
||||
/*Initialize your touchpad */
|
||||
DEMO_InitTouch();
|
||||
|
||||
/*Register a touchpad input device*/
|
||||
lv_indev_drv_init(&indev_drv);
|
||||
indev_drv.type = LV_INDEV_TYPE_POINTER;
|
||||
indev_drv.read_cb = DEMO_ReadTouch;
|
||||
lv_indev_drv_register(&indev_drv);
|
||||
}
|
||||
|
||||
#ifdef DEMO_PANEL_RK043FN66HS
|
||||
static void BOARD_PullTouchResetPin(bool pullUp)
|
||||
{
|
||||
if (pullUp)
|
||||
{
|
||||
GPIO_PinWrite(BOARD_TOUCH_RST_GPIO, BOARD_TOUCH_RST_PIN, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_PinWrite(BOARD_TOUCH_RST_GPIO, BOARD_TOUCH_RST_PIN, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void BOARD_ConfigTouchIntPin(gt911_int_pin_mode_t mode)
|
||||
{
|
||||
if (mode == kGT911_IntPinInput)
|
||||
{
|
||||
BOARD_TOUCH_INT_GPIO->GDIR &= ~(1UL << BOARD_TOUCH_INT_PIN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mode == kGT911_IntPinPullDown)
|
||||
{
|
||||
GPIO_PinWrite(BOARD_TOUCH_INT_GPIO, BOARD_TOUCH_INT_PIN, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIO_PinWrite(BOARD_TOUCH_INT_GPIO, BOARD_TOUCH_INT_PIN, 1);
|
||||
}
|
||||
|
||||
BOARD_TOUCH_INT_GPIO->GDIR |= (1UL << BOARD_TOUCH_INT_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
/*Initialize your touchpad*/
|
||||
static void DEMO_InitTouch(void)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
const gpio_pin_config_t resetPinConfig = {
|
||||
.direction = kGPIO_DigitalOutput, .outputLogic = 0, .interruptMode = kGPIO_NoIntmode};
|
||||
GPIO_PinInit(BOARD_TOUCH_INT_GPIO, BOARD_TOUCH_INT_PIN, &resetPinConfig);
|
||||
GPIO_PinInit(BOARD_TOUCH_RST_GPIO, BOARD_TOUCH_RST_PIN, &resetPinConfig);
|
||||
|
||||
/*Clock setting for LPI2C*/
|
||||
CLOCK_SetMux(kCLOCK_Lpi2cMux, TOUCH_LPI2C_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER);
|
||||
|
||||
BOARD_LPI2C_Init(TOUCH_I2C, TOUCH_I2C_CLOCK_FREQ);
|
||||
|
||||
status = GT911_Init(&s_touchHandle, &s_touchConfig);
|
||||
|
||||
if (kStatus_Success != status)
|
||||
{
|
||||
//PRINTF("Touch IC initialization failed\r\n");
|
||||
assert(false);
|
||||
}
|
||||
|
||||
GT911_GetResolution(&s_touchHandle, &s_touchResolutionX, &s_touchResolutionY);
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the touchpad */
|
||||
static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
||||
{
|
||||
static int touch_x = 0;
|
||||
static int touch_y = 0;
|
||||
|
||||
if (kStatus_Success == GT911_GetSingleTouch(&s_touchHandle, &touch_x, &touch_y))
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
}
|
||||
|
||||
/*Set the last pressed coordinates*/
|
||||
data->point.x = touch_x * LCD_WIDTH / s_touchResolutionX;
|
||||
data->point.y = touch_y * LCD_HEIGHT / s_touchResolutionY;
|
||||
}
|
||||
#else
|
||||
/*Initialize your touchpad*/
|
||||
static void DEMO_InitTouch(void)
|
||||
{
|
||||
status_t status;
|
||||
|
||||
lpi2c_master_config_t masterConfig = {0};
|
||||
|
||||
/*Clock setting for LPI2C*/
|
||||
CLOCK_SetMux(kCLOCK_Lpi2cMux, TOUCH_LPI2C_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_Lpi2cDiv, TOUCH_LPI2C_CLOCK_SOURCE_DIVIDER);
|
||||
|
||||
/*
|
||||
* masterConfig.debugEnable = false;
|
||||
* masterConfig.ignoreAck = false;
|
||||
* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
|
||||
* masterConfig.baudRate_Hz = 100000U;
|
||||
* masterConfig.busIdleTimeout_ns = 0;
|
||||
* masterConfig.pinLowTimeout_ns = 0;
|
||||
* masterConfig.sdaGlitchFilterWidth_ns = 0;
|
||||
* masterConfig.sclGlitchFilterWidth_ns = 0;
|
||||
*/
|
||||
LPI2C_MasterGetDefaultConfig(&masterConfig);
|
||||
|
||||
/* Change the default baudrate configuration */
|
||||
masterConfig.baudRate_Hz = TOUCH_I2C_BAUDRATE;
|
||||
|
||||
/* Initialize the LPI2C master peripheral */
|
||||
LPI2C_MasterInit(TOUCH_I2C, &masterConfig, TOUCH_I2C_CLOCK_FREQ);
|
||||
|
||||
/* Initialize touch panel controller */
|
||||
status = FT5406_RT_Init(&touchHandle, TOUCH_I2C);
|
||||
if (status != kStatus_Success)
|
||||
{
|
||||
//PRINTF("Touch panel init failed\n");
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Will be called by the library to read the touchpad */
|
||||
static void DEMO_ReadTouch(lv_indev_drv_t *drv, lv_indev_data_t *data)
|
||||
{
|
||||
touch_event_t touch_event;
|
||||
static int touch_x = 0;
|
||||
static int touch_y = 0;
|
||||
|
||||
data->state = LV_INDEV_STATE_REL;
|
||||
|
||||
if (kStatus_Success == FT5406_RT_GetSingleTouch(&touchHandle, &touch_event, &touch_x, &touch_y))
|
||||
{
|
||||
if ((touch_event == kTouch_Down) || (touch_event == kTouch_Contact))
|
||||
{
|
||||
data->state = LV_INDEV_STATE_PR;
|
||||
}
|
||||
}
|
||||
|
||||
/*Set the last pressed coordinates*/
|
||||
data->point.x = touch_y;
|
||||
data->point.y = touch_x;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -68,11 +68,32 @@ menu "Onboard Peripheral Drivers"
|
|||
default 2
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_TOUCHPAD
|
||||
bool "Enable TOUCHPAD"
|
||||
select BSP_USING_PXP
|
||||
select BSP_USING_CACHE
|
||||
select BSP_USING_I2C
|
||||
select BSP_USING_LCD
|
||||
default n
|
||||
if BSP_USING_TOUCHPAD
|
||||
choice
|
||||
prompt "Select panel"
|
||||
default DEMO_PANEL_RK043FN02H
|
||||
|
||||
config DEMO_PANEL_RK043FN02H
|
||||
bool "RK043FN02H-CT"
|
||||
|
||||
config DEMO_PANEL_RK043FN66HS
|
||||
bool "RK043FN66HS-CTG"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config BSP_USING_LVGL
|
||||
bool "Enable LVGL for LCD"
|
||||
select BSP_USING_PXP
|
||||
select BSP_USING_CACHE
|
||||
select BSP_USING_LCD
|
||||
select BSP_USING_TOUCHPAD
|
||||
select PKG_USING_LVGL
|
||||
default n
|
||||
|
||||
|
@ -100,6 +121,26 @@ menu "On-chip Peripheral Drivers"
|
|||
select RT_USING_PIN
|
||||
default y
|
||||
|
||||
menuconfig BSP_USING_I2C
|
||||
bool "Enable I2C"
|
||||
select RT_USING_I2C
|
||||
default y
|
||||
if BSP_USING_I2C
|
||||
config BSP_USING_I2C1
|
||||
bool
|
||||
default y
|
||||
choice
|
||||
prompt "Select I2C1 badurate"
|
||||
default HW_I2C1_BADURATE_100kHZ
|
||||
|
||||
config HW_I2C1_BADURATE_100kHZ
|
||||
bool "Badurate 100kHZ"
|
||||
|
||||
config HW_I2C1_BADURATE_400kHZ
|
||||
bool "Badurate 400kHZ"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_LPUART
|
||||
bool "Enable UART"
|
||||
select RT_USING_SERIAL
|
||||
|
|
|
@ -12,6 +12,9 @@ MCUX_Config/pin_mux.c
|
|||
MCUX_Config/dcd.c
|
||||
""")
|
||||
|
||||
if GetDepend(['BSP_USING_TOUCHPAD']):
|
||||
src += ['ports/touchpad.c']
|
||||
|
||||
CPPPATH = [cwd,cwd + '/MCUX_Config',cwd + '/ports']
|
||||
|
||||
CPPDEFINES = ['CPU_MIMXRT1062DVL6A', 'SKIP_SYSCLK_INIT', 'EVK_MCIMXRM', 'FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1','XIP_EXTERNAL_FLASH=1', 'XIP_BOOT_HEADER_ENABLE=1', 'FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1', 'XIP_BOOT_HEADER_DCD_ENABLE=1', 'DATA_SECTION_IS_CACHEABLE=1']
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2022 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "touchpad.h"
|
||||
|
||||
void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz)
|
||||
{
|
||||
lpi2c_master_config_t lpi2cConfig = {0};
|
||||
|
||||
/*
|
||||
* lpi2cConfig.debugEnable = false;
|
||||
* lpi2cConfig.ignoreAck = false;
|
||||
* lpi2cConfig.pinConfig = kLPI2C_2PinOpenDrain;
|
||||
* lpi2cConfig.baudRate_Hz = 100000U;
|
||||
* lpi2cConfig.busIdleTimeout_ns = 0;
|
||||
* lpi2cConfig.pinLowTimeout_ns = 0;
|
||||
* lpi2cConfig.sdaGlitchFilterWidth_ns = 0;
|
||||
* lpi2cConfig.sclGlitchFilterWidth_ns = 0;
|
||||
*/
|
||||
LPI2C_MasterGetDefaultConfig(&lpi2cConfig);
|
||||
LPI2C_MasterInit(base, &lpi2cConfig, clkSrc_Hz);
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_Send(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize)
|
||||
{
|
||||
lpi2c_master_transfer_t xfer;
|
||||
|
||||
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
xfer.slaveAddress = deviceAddress;
|
||||
xfer.direction = kLPI2C_Write;
|
||||
xfer.subaddress = subAddress;
|
||||
xfer.subaddressSize = subAddressSize;
|
||||
xfer.data = txBuff;
|
||||
xfer.dataSize = txBuffSize;
|
||||
|
||||
return LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_Receive(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize)
|
||||
{
|
||||
lpi2c_master_transfer_t xfer;
|
||||
|
||||
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
xfer.slaveAddress = deviceAddress;
|
||||
xfer.direction = kLPI2C_Read;
|
||||
xfer.subaddress = subAddress;
|
||||
xfer.subaddressSize = subAddressSize;
|
||||
xfer.data = rxBuff;
|
||||
xfer.dataSize = rxBuffSize;
|
||||
|
||||
return LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_SendSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize)
|
||||
{
|
||||
lpi2c_master_transfer_t xfer;
|
||||
|
||||
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
xfer.slaveAddress = deviceAddress;
|
||||
xfer.direction = kLPI2C_Write;
|
||||
xfer.subaddress = subAddress;
|
||||
xfer.subaddressSize = subAddressSize;
|
||||
xfer.data = txBuff;
|
||||
xfer.dataSize = txBuffSize;
|
||||
|
||||
return LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
}
|
||||
|
||||
status_t BOARD_LPI2C_ReceiveSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subAddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize)
|
||||
{
|
||||
status_t status;
|
||||
lpi2c_master_transfer_t xfer;
|
||||
|
||||
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
xfer.slaveAddress = deviceAddress;
|
||||
xfer.direction = kLPI2C_Write;
|
||||
xfer.subaddress = subAddress;
|
||||
xfer.subaddressSize = subAddressSize;
|
||||
xfer.data = NULL;
|
||||
xfer.dataSize = 0;
|
||||
|
||||
status = LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
|
||||
if (kStatus_Success == status)
|
||||
{
|
||||
xfer.subaddressSize = 0;
|
||||
xfer.direction = kLPI2C_Read;
|
||||
xfer.data = rxBuff;
|
||||
xfer.dataSize = rxBuffSize;
|
||||
|
||||
status = LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t BOARD_Touch_I2C_Send(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Send(BOARD_TOUCH_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, (uint8_t *)txBuff,
|
||||
txBuffSize);
|
||||
}
|
||||
|
||||
status_t BOARD_Touch_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize)
|
||||
{
|
||||
return BOARD_LPI2C_Receive(BOARD_TOUCH_I2C_BASEADDR, deviceAddress, subAddress, subAddressSize, rxBuff, rxBuffSize);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright 2022 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef __TOUCHPAD_PORT_H__
|
||||
#define __TOUCHPAD_PORT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "clock_config.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
#include "fsl_gpio.h"
|
||||
|
||||
/* @Brief Board touch panel configuration */
|
||||
#define BOARD_TOUCH_I2C_BASEADDR LPI2C1
|
||||
#define BOARD_TOUCH_RST_GPIO GPIO1
|
||||
#define BOARD_TOUCH_RST_PIN 2
|
||||
#define BOARD_TOUCH_INT_GPIO GPIO1
|
||||
#define BOARD_TOUCH_INT_PIN 11
|
||||
|
||||
void BOARD_LPI2C_Init(LPI2C_Type *base, uint32_t clkSrc_Hz);
|
||||
status_t BOARD_LPI2C_Send(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize);
|
||||
status_t BOARD_LPI2C_Receive(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize);
|
||||
status_t BOARD_LPI2C_SendSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *txBuff,
|
||||
uint8_t txBuffSize);
|
||||
status_t BOARD_LPI2C_ReceiveSCCB(LPI2C_Type *base,
|
||||
uint8_t deviceAddress,
|
||||
uint32_t subAddress,
|
||||
uint8_t subaddressSize,
|
||||
uint8_t *rxBuff,
|
||||
uint8_t rxBuffSize);
|
||||
status_t BOARD_Touch_I2C_Send(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
|
||||
status_t BOARD_Touch_I2C_Receive(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subAddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2019 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
#include "fsl_ft5406_rt.h"
|
||||
|
||||
typedef struct _ft5406_rt_touch_point
|
||||
{
|
||||
uint8_t XH;
|
||||
uint8_t XL;
|
||||
uint8_t YH;
|
||||
uint8_t YL;
|
||||
uint8_t RESERVED[2];
|
||||
} ft5406_rt_touch_point_t;
|
||||
|
||||
typedef struct _ft5406_rt_touch_data
|
||||
{
|
||||
uint8_t GEST_ID;
|
||||
uint8_t TD_STATUS;
|
||||
ft5406_rt_touch_point_t TOUCH[FT5406_RT_MAX_TOUCHES];
|
||||
} ft5406_rt_touch_data_t;
|
||||
|
||||
#define TOUCH_POINT_GET_EVENT(T) ((touch_event_t)((T).XH >> 6))
|
||||
#define TOUCH_POINT_GET_ID(T) ((T).YH >> 4)
|
||||
#define TOUCH_POINT_GET_X(T) ((((T).XH & 0x0f) << 8) | (T).XL)
|
||||
#define TOUCH_POINT_GET_Y(T) ((((T).YH & 0x0f) << 8) | (T).YL)
|
||||
|
||||
status_t FT5406_RT_Init(ft5406_rt_handle_t *handle, LPI2C_Type *base)
|
||||
{
|
||||
lpi2c_master_transfer_t *xfer = &(handle->xfer);
|
||||
status_t status;
|
||||
uint8_t mode;
|
||||
|
||||
assert(handle);
|
||||
assert(base);
|
||||
|
||||
if (!handle || !base)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
handle->base = base;
|
||||
|
||||
/* clear transfer structure and buffer */
|
||||
memset(xfer, 0, sizeof(*xfer));
|
||||
memset(handle->touch_buf, 0, FT5406_RT_TOUCH_DATA_LEN);
|
||||
|
||||
/* set device mode to normal operation */
|
||||
mode = 0;
|
||||
xfer->slaveAddress = FT5406_RT_I2C_ADDRESS;
|
||||
xfer->direction = kLPI2C_Write;
|
||||
xfer->subaddress = 0;
|
||||
xfer->subaddressSize = 1;
|
||||
xfer->data = &mode;
|
||||
xfer->dataSize = 1;
|
||||
xfer->flags = kLPI2C_TransferDefaultFlag;
|
||||
|
||||
status = LPI2C_MasterTransferBlocking(handle->base, &handle->xfer);
|
||||
|
||||
/* prepare transfer structure for reading touch data */
|
||||
xfer->slaveAddress = FT5406_RT_I2C_ADDRESS;
|
||||
xfer->direction = kLPI2C_Read;
|
||||
xfer->subaddress = 1;
|
||||
xfer->subaddressSize = 1;
|
||||
xfer->data = handle->touch_buf;
|
||||
xfer->dataSize = FT5406_RT_TOUCH_DATA_LEN;
|
||||
xfer->flags = kLPI2C_TransferDefaultFlag;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t FT5406_RT_Denit(ft5406_rt_handle_t *handle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
handle->base = NULL;
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t FT5406_RT_ReadTouchData(ft5406_rt_handle_t *handle)
|
||||
{
|
||||
assert(handle);
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
return kStatus_InvalidArgument;
|
||||
}
|
||||
|
||||
return LPI2C_MasterTransferBlocking(handle->base, &handle->xfer);
|
||||
}
|
||||
|
||||
status_t FT5406_RT_GetSingleTouch(ft5406_rt_handle_t *handle, touch_event_t *touch_event, int *touch_x, int *touch_y)
|
||||
{
|
||||
status_t status;
|
||||
touch_event_t touch_event_local;
|
||||
|
||||
status = FT5406_RT_ReadTouchData(handle);
|
||||
|
||||
if (status == kStatus_Success)
|
||||
{
|
||||
ft5406_rt_touch_data_t *touch_data = (ft5406_rt_touch_data_t *)(void *)(handle->touch_buf);
|
||||
|
||||
if (touch_event == NULL)
|
||||
{
|
||||
touch_event = &touch_event_local;
|
||||
}
|
||||
*touch_event = TOUCH_POINT_GET_EVENT(touch_data->TOUCH[0]);
|
||||
|
||||
/* Update coordinates only if there is touch detected */
|
||||
if ((*touch_event == kTouch_Down) || (*touch_event == kTouch_Contact))
|
||||
{
|
||||
if (touch_x)
|
||||
{
|
||||
*touch_x = TOUCH_POINT_GET_X(touch_data->TOUCH[0]);
|
||||
}
|
||||
if (touch_y)
|
||||
{
|
||||
*touch_y = TOUCH_POINT_GET_Y(touch_data->TOUCH[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t FT5406_RT_GetMultiTouch(ft5406_rt_handle_t *handle,
|
||||
int *touch_count,
|
||||
touch_point_t touch_array[FT5406_RT_MAX_TOUCHES])
|
||||
{
|
||||
status_t status;
|
||||
|
||||
status = FT5406_RT_ReadTouchData(handle);
|
||||
|
||||
if (status == kStatus_Success)
|
||||
{
|
||||
ft5406_rt_touch_data_t *touch_data = (ft5406_rt_touch_data_t *)(void *)(handle->touch_buf);
|
||||
int i;
|
||||
|
||||
/* Check for valid number of touches - otherwise ignore touch information */
|
||||
if (touch_data->TD_STATUS > FT5406_RT_MAX_TOUCHES)
|
||||
{
|
||||
touch_data->TD_STATUS = 0;
|
||||
}
|
||||
|
||||
/* Decode number of touches */
|
||||
if (touch_count)
|
||||
{
|
||||
*touch_count = touch_data->TD_STATUS;
|
||||
}
|
||||
|
||||
/* Decode valid touch points */
|
||||
for (i = 0; i < touch_data->TD_STATUS; i++)
|
||||
{
|
||||
touch_array[i].TOUCH_ID = TOUCH_POINT_GET_ID(touch_data->TOUCH[i]);
|
||||
touch_array[i].TOUCH_EVENT = TOUCH_POINT_GET_EVENT(touch_data->TOUCH[i]);
|
||||
touch_array[i].TOUCH_X = TOUCH_POINT_GET_X(touch_data->TOUCH[i]);
|
||||
touch_array[i].TOUCH_Y = TOUCH_POINT_GET_Y(touch_data->TOUCH[i]);
|
||||
}
|
||||
|
||||
/* Clear vacant elements of touch_array */
|
||||
for (; i < FT5406_RT_MAX_TOUCHES; i++)
|
||||
{
|
||||
touch_array[i].TOUCH_ID = 0;
|
||||
touch_array[i].TOUCH_EVENT = kTouch_Reserved;
|
||||
touch_array[i].TOUCH_X = 0;
|
||||
touch_array[i].TOUCH_Y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
||||
* Copyright 2016-2017 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_FT5406_RT_H_
|
||||
#define _FSL_FT5406_RT_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup ft5406_rt
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief FT5406_RT I2C address. */
|
||||
#define FT5406_RT_I2C_ADDRESS (0x38)
|
||||
|
||||
/*! @brief FT5406_RT maximum number of simultaneously detected touches. */
|
||||
#define FT5406_RT_MAX_TOUCHES (5U)
|
||||
|
||||
/*! @brief FT5406_RT register address where touch data begin. */
|
||||
#define FT5406_RT_TOUCH_DATA_SUBADDR (1)
|
||||
|
||||
/*! @brief FT5406_RT raw touch data length. */
|
||||
#define FT5406_RT_TOUCH_DATA_LEN (0x20)
|
||||
|
||||
typedef enum _touch_event
|
||||
{
|
||||
kTouch_Down = 0, /*!< The state changed to touched. */
|
||||
kTouch_Up = 1, /*!< The state changed to not touched. */
|
||||
kTouch_Contact = 2, /*!< There is a continuous touch being detected. */
|
||||
kTouch_Reserved = 3 /*!< No touch information available. */
|
||||
} touch_event_t;
|
||||
|
||||
typedef struct _touch_point
|
||||
{
|
||||
touch_event_t TOUCH_EVENT; /*!< Indicates the state or event of the touch point. */
|
||||
uint8_t TOUCH_ID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
|
||||
uint16_t TOUCH_X; /*!< X coordinate of the touch point */
|
||||
uint16_t TOUCH_Y; /*!< Y coordinate of the touch point */
|
||||
} touch_point_t;
|
||||
|
||||
typedef struct _ft5406_rt_handle
|
||||
{
|
||||
LPI2C_Type *base;
|
||||
lpi2c_master_transfer_t xfer;
|
||||
uint8_t touch_buf[FT5406_RT_TOUCH_DATA_LEN];
|
||||
} ft5406_rt_handle_t;
|
||||
|
||||
status_t FT5406_RT_Init(ft5406_rt_handle_t *handle, LPI2C_Type *base);
|
||||
|
||||
status_t FT5406_RT_Denit(ft5406_rt_handle_t *handle);
|
||||
|
||||
status_t FT5406_RT_GetSingleTouch(ft5406_rt_handle_t *handle, touch_event_t *touch_event, int *touch_x, int *touch_y);
|
||||
|
||||
status_t FT5406_RT_GetMultiTouch(ft5406_rt_handle_t *handle,
|
||||
int *touch_count,
|
||||
touch_point_t touch_array[FT5406_RT_MAX_TOUCHES]);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
* Copyright 2019-2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_gt911.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief GT911 I2C address. */
|
||||
#define GT911_I2C_ADDRESS0 (0x5D)
|
||||
#define GT911_I2C_ADDRESS1 (0x14)
|
||||
|
||||
#define GT911_REG_ADDR_SIZE 2
|
||||
|
||||
/*! @brief GT911 registers. */
|
||||
#define GT911_REG_ID 0x8140U
|
||||
#define GT911_CONFIG_ADDR 0x8047U
|
||||
#define GT911_REG_XL 0x8048U
|
||||
#define GT911_REG_XH 0x8049U
|
||||
#define GT911_REG_YL 0x804AU
|
||||
#define GT911_REG_YH 0x804BU
|
||||
#define GT911_REG_TOUCH_NUM 0x804CU
|
||||
#define GT911_REG_CONFIG_VERSION 0x8047U
|
||||
#define GT911_REG_MODULE_SWITCH1 0x804DU
|
||||
#define GT911_REG_STAT 0x814EU
|
||||
#define GT911_REG_FIRST_POINT 0x814FU
|
||||
|
||||
#define GT911_STAT_BUF_MASK (1U << 7U)
|
||||
#define GT911_STAT_POINT_NUMBER_MASK (0xFU << 0U)
|
||||
#define GT911_MODULE_SWITCH_X2Y_MASK (1U << 3U)
|
||||
#define GT911_MODULE_SWITCH_INT_MASK (3U << 0U)
|
||||
|
||||
#define GT911_CONFIG_SIZE (186U)
|
||||
|
||||
/*******************************************************************************
|
||||
* Prototypes
|
||||
******************************************************************************/
|
||||
/* Verify firmware, return true if pass. */
|
||||
static bool GT911_VerifyFirmware(const uint8_t *firmware);
|
||||
static uint8_t GT911_GetFirmwareCheckSum(const uint8_t *firmware);
|
||||
|
||||
/*******************************************************************************
|
||||
* Variables
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
static uint8_t GT911_GetFirmwareCheckSum(const uint8_t *firmware)
|
||||
{
|
||||
uint8_t sum = 0;
|
||||
uint16_t i = 0;
|
||||
|
||||
for (i = 0; i < GT911_CONFIG_SIZE - 2U; i++)
|
||||
{
|
||||
sum += (*firmware);
|
||||
firmware++;
|
||||
}
|
||||
|
||||
return (~sum + 1U);
|
||||
}
|
||||
|
||||
static bool GT911_VerifyFirmware(const uint8_t *firmware)
|
||||
{
|
||||
return ((firmware[GT911_REG_CONFIG_VERSION - GT911_CONFIG_ADDR] != 0U) &&
|
||||
(GT911_GetFirmwareCheckSum(firmware) == firmware[GT911_CONFIG_SIZE - 2U]));
|
||||
}
|
||||
|
||||
status_t GT911_Init(gt911_handle_t *handle, const gt911_config_t *config)
|
||||
{
|
||||
status_t status;
|
||||
uint32_t deviceID;
|
||||
uint8_t gt911Config[GT911_CONFIG_SIZE];
|
||||
|
||||
assert(NULL != handle);
|
||||
|
||||
(void)memset(handle, 0, sizeof(*handle));
|
||||
|
||||
handle->I2C_SendFunc = config->I2C_SendFunc;
|
||||
handle->I2C_ReceiveFunc = config->I2C_ReceiveFunc;
|
||||
handle->timeDelayMsFunc = config->timeDelayMsFunc;
|
||||
handle->pullResetPinFunc = config->pullResetPinFunc;
|
||||
|
||||
/* Reset the panel and set the I2C address mode. */
|
||||
config->intPinFunc(kGT911_IntPinPullDown);
|
||||
config->pullResetPinFunc(false);
|
||||
|
||||
/* >= 10ms. */
|
||||
handle->timeDelayMsFunc(20);
|
||||
|
||||
if (kGT911_I2cAddrAny == config->i2cAddrMode)
|
||||
{
|
||||
config->pullResetPinFunc(true);
|
||||
|
||||
/* >= 55ms */
|
||||
handle->timeDelayMsFunc(55);
|
||||
|
||||
config->intPinFunc(kGT911_IntPinInput);
|
||||
|
||||
/* Try address 0 */
|
||||
handle->i2cAddr = GT911_I2C_ADDRESS0;
|
||||
status = handle->I2C_ReceiveFunc(handle->i2cAddr, GT911_REG_ID, GT911_REG_ADDR_SIZE, (uint8_t *)&deviceID, 4);
|
||||
|
||||
if (kStatus_Success != status)
|
||||
{
|
||||
/* Try address 1 */
|
||||
handle->i2cAddr = GT911_I2C_ADDRESS1;
|
||||
status =
|
||||
handle->I2C_ReceiveFunc(handle->i2cAddr, GT911_REG_ID, GT911_REG_ADDR_SIZE, (uint8_t *)&deviceID, 4);
|
||||
|
||||
if (kStatus_Success != status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (kGT911_I2cAddrMode1 == config->i2cAddrMode)
|
||||
{
|
||||
config->intPinFunc(kGT911_IntPinPullUp);
|
||||
handle->i2cAddr = GT911_I2C_ADDRESS1;
|
||||
}
|
||||
else
|
||||
{
|
||||
handle->i2cAddr = GT911_I2C_ADDRESS0;
|
||||
}
|
||||
|
||||
/* >= 100us */
|
||||
handle->timeDelayMsFunc(1);
|
||||
|
||||
config->pullResetPinFunc(true);
|
||||
|
||||
/* >= 5ms */
|
||||
handle->timeDelayMsFunc(5);
|
||||
|
||||
config->intPinFunc(kGT911_IntPinPullDown);
|
||||
|
||||
/* >= 50ms */
|
||||
handle->timeDelayMsFunc(50);
|
||||
|
||||
config->intPinFunc(kGT911_IntPinInput);
|
||||
|
||||
status = handle->I2C_ReceiveFunc(handle->i2cAddr, GT911_REG_ID, GT911_REG_ADDR_SIZE, (uint8_t *)&deviceID, 4);
|
||||
if (kStatus_Success != status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify the device. */
|
||||
if (deviceID != 0x00313139U)
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
/* Initialize the IC. */
|
||||
status = handle->I2C_ReceiveFunc(handle->i2cAddr, GT911_CONFIG_ADDR, GT911_REG_ADDR_SIZE, gt911Config,
|
||||
GT911_CONFIG_SIZE);
|
||||
if (kStatus_Success != status)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* GT911 driver gets the original firmware from touch panel control IC, modify
|
||||
* the configuration, then set it to the IC again. The original firmware
|
||||
* read from the touch IC must be correct, otherwise setting wrong firmware
|
||||
* to the touch IC will break it.
|
||||
*/
|
||||
if (true != GT911_VerifyFirmware(gt911Config))
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
|
||||
handle->resolutionX = ((uint16_t)gt911Config[GT911_REG_XH - GT911_CONFIG_ADDR]) << 8U;
|
||||
handle->resolutionX += gt911Config[GT911_REG_XL - GT911_CONFIG_ADDR];
|
||||
handle->resolutionY = ((uint16_t)gt911Config[GT911_REG_YH - GT911_CONFIG_ADDR]) << 8U;
|
||||
handle->resolutionY += gt911Config[GT911_REG_YL - GT911_CONFIG_ADDR];
|
||||
|
||||
gt911Config[GT911_REG_TOUCH_NUM - GT911_CONFIG_ADDR] = (config->touchPointNum) & 0x0FU;
|
||||
|
||||
gt911Config[GT911_REG_MODULE_SWITCH1 - GT911_CONFIG_ADDR] &= (uint8_t)(~GT911_MODULE_SWITCH_INT_MASK);
|
||||
gt911Config[GT911_REG_MODULE_SWITCH1 - GT911_CONFIG_ADDR] |= (uint8_t)(config->intTrigMode);
|
||||
|
||||
gt911Config[GT911_CONFIG_SIZE - 2U] = GT911_GetFirmwareCheckSum(gt911Config);
|
||||
gt911Config[GT911_CONFIG_SIZE - 1U] = 1U; /* Mark the firmware as valid. */
|
||||
|
||||
return handle->I2C_SendFunc(handle->i2cAddr, GT911_CONFIG_ADDR, GT911_REG_ADDR_SIZE, gt911Config,
|
||||
GT911_CONFIG_SIZE);
|
||||
}
|
||||
|
||||
status_t GT911_Deinit(gt911_handle_t *handle)
|
||||
{
|
||||
handle->pullResetPinFunc(false);
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
static status_t GT911_ReadRawTouchData(gt911_handle_t *handle, uint8_t *touchPointNum)
|
||||
{
|
||||
status_t status;
|
||||
uint8_t gt911Stat;
|
||||
|
||||
status = handle->I2C_ReceiveFunc(handle->i2cAddr, GT911_REG_STAT, GT911_REG_ADDR_SIZE, >911Stat, 1);
|
||||
if (kStatus_Success != status)
|
||||
{
|
||||
*touchPointNum = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
*touchPointNum = gt911Stat & GT911_STAT_POINT_NUMBER_MASK;
|
||||
|
||||
if (0U != (gt911Stat & GT911_STAT_BUF_MASK))
|
||||
{
|
||||
if (*touchPointNum > 0U)
|
||||
{
|
||||
status = handle->I2C_ReceiveFunc(handle->i2cAddr, GT911_REG_FIRST_POINT, GT911_REG_ADDR_SIZE,
|
||||
(void *)handle->pointReg, (*touchPointNum) * sizeof(gt911_point_reg_t));
|
||||
}
|
||||
|
||||
/* Must set the status register to 0 after read. */
|
||||
gt911Stat = 0;
|
||||
status = handle->I2C_SendFunc(handle->i2cAddr, GT911_REG_STAT, GT911_REG_ADDR_SIZE, >911Stat, 1);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t GT911_GetSingleTouch(gt911_handle_t *handle, int *touch_x, int *touch_y)
|
||||
{
|
||||
status_t status;
|
||||
uint8_t touchPointNum;
|
||||
|
||||
status = GT911_ReadRawTouchData(handle, &touchPointNum);
|
||||
|
||||
if (kStatus_Success == status)
|
||||
{
|
||||
if (touchPointNum > 0U)
|
||||
{
|
||||
*touch_x =
|
||||
(int)(uint16_t)((uint16_t)handle->pointReg[0].lowX + (((uint16_t)handle->pointReg[0].highX) << 8U));
|
||||
*touch_y =
|
||||
(int)(uint16_t)((uint16_t)handle->pointReg[0].lowY + (((uint16_t)handle->pointReg[0].highY) << 8U));
|
||||
}
|
||||
else
|
||||
{
|
||||
status = (status_t)kStatus_TOUCHPANEL_NotTouched;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t GT911_GetMultiTouch(gt911_handle_t *handle, uint8_t *touch_count, touch_point_t touch_array[])
|
||||
{
|
||||
status_t status;
|
||||
uint32_t i;
|
||||
uint8_t desiredTouchPointNum;
|
||||
uint8_t actualTouchPointNum;
|
||||
|
||||
status = GT911_ReadRawTouchData(handle, &actualTouchPointNum);
|
||||
|
||||
if (kStatus_Success == status)
|
||||
{
|
||||
desiredTouchPointNum = *touch_count;
|
||||
|
||||
if (0U == actualTouchPointNum)
|
||||
{
|
||||
status = (status_t)kStatus_TOUCHPANEL_NotTouched;
|
||||
}
|
||||
else if (actualTouchPointNum > desiredTouchPointNum)
|
||||
{
|
||||
actualTouchPointNum = desiredTouchPointNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MISRA compatible. */
|
||||
}
|
||||
|
||||
for (i = 0; i < actualTouchPointNum; i++)
|
||||
{
|
||||
touch_array[i].valid = true;
|
||||
touch_array[i].touchID = handle->pointReg[i].id;
|
||||
touch_array[i].x = handle->pointReg[i].lowX + (((uint16_t)handle->pointReg[i].highX) << 8U);
|
||||
touch_array[i].y = handle->pointReg[i].lowY + (((uint16_t)handle->pointReg[i].highY) << 8U);
|
||||
}
|
||||
|
||||
for (; i < desiredTouchPointNum; i++)
|
||||
{
|
||||
touch_array[i].valid = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = kStatus_Fail;
|
||||
}
|
||||
|
||||
*touch_count = actualTouchPointNum;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status_t GT911_GetResolution(gt911_handle_t *handle, int *resolutionX, int *resolutionY)
|
||||
{
|
||||
*resolutionX = (int)handle->resolutionX;
|
||||
*resolutionY = (int)handle->resolutionY;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright 2019-2020 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_GT911_H_
|
||||
#define _FSL_GT911_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*
|
||||
* Change Log:
|
||||
*
|
||||
* 1.0.3:
|
||||
* - Fixed MISRA 2012 issues.
|
||||
*
|
||||
* 1.0.2:
|
||||
* - Fixed the issue that INT pin is output low when using kGT911_I2cAddrAny.
|
||||
*
|
||||
* 1.0.1:
|
||||
* - Update GT911_GetMultiTouch and GT911_GetSingleTouch to return
|
||||
* kStatus_TOUCHPANEL_NotTouched when no touch happens.
|
||||
*
|
||||
* 1.0.0:
|
||||
* - Initial version.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @addtogroup gt911
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
/*! @brief GT911 maximum number of simultaneously detected touches. */
|
||||
#define GT911_MAX_TOUCHES (10U)
|
||||
|
||||
/*! @brief Error code definition. */
|
||||
enum _touch_status
|
||||
{
|
||||
kStatus_TOUCHPANEL_NotTouched = MAKE_STATUS(kStatusGroup_TOUCH_PANEL, 0) /*!< No touch happen. */
|
||||
};
|
||||
|
||||
/*! @brief Touch point definition. */
|
||||
typedef struct
|
||||
{
|
||||
bool valid; /*!< Whether the touch point coordinate value is valid. */
|
||||
uint8_t touchID; /*!< Id of the touch point. This numeric value stays constant between down and up event. */
|
||||
uint16_t x; /*!< X coordinate of the touch point */
|
||||
uint16_t y; /*!< Y coordinate of the touch point */
|
||||
} touch_point_t;
|
||||
|
||||
/*! @brief gt911 I2C address mode.*/
|
||||
typedef enum _gt911_i2c_addr_mode
|
||||
{
|
||||
kGT911_I2cAddrMode0, /*!< 7-bit address 0x5D, or 8-bit 0xBA/0xBB */
|
||||
kGT911_I2cAddrMode1, /*!< 7-bit address 0x14, or 8-bit 0x28/0x29 */
|
||||
kGT911_I2cAddrAny, /*!< Use 0x5D or 0x14, driver selects the right one to use,
|
||||
this is used for the case that MCU could not pull
|
||||
the INT pin level.
|
||||
*/
|
||||
} gt911_i2c_addr_mode_t;
|
||||
|
||||
/*! @brief gt911 interrupt pin mode.*/
|
||||
typedef enum _gt911_int_pin_mode
|
||||
{
|
||||
kGT911_IntPinPullDown, /*!< Interrupt pin output pull down. */
|
||||
kGT911_IntPinPullUp, /*!< Interrupt pin output pull up. */
|
||||
kGT911_IntPinInput, /*!< Interrupt pin set to input mode. */
|
||||
} gt911_int_pin_mode_t;
|
||||
|
||||
/*! @brief gt911 interrupt trigger mode.*/
|
||||
typedef enum _gt911_int_trig_mode
|
||||
{
|
||||
kGT911_IntRisingEdge, /*!< Rising edge. */
|
||||
kGT911_IntFallingEdge, /*!< Falling edge. */
|
||||
kGT911_IntLowLevel, /*!< Low level. */
|
||||
kGT911_IntHighLevel, /*!< High edge. */
|
||||
} gt911_int_trig_mode_t;
|
||||
|
||||
typedef status_t (*gt911_i2c_send_func_t)(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, const uint8_t *txBuff, uint8_t txBuffSize);
|
||||
typedef status_t (*gt911_i2c_receive_func_t)(
|
||||
uint8_t deviceAddress, uint32_t subAddress, uint8_t subaddressSize, uint8_t *rxBuff, uint8_t rxBuffSize);
|
||||
typedef void (*gt911_int_pin_func_t)(gt911_int_pin_mode_t mode);
|
||||
typedef void (*gt911_reset_pin_func_t)(bool pullUp);
|
||||
|
||||
/*! @brief gt911 configure structure.*/
|
||||
typedef struct _gt911_point_reg
|
||||
{
|
||||
uint8_t id; /*!< Track ID. */
|
||||
uint8_t lowX; /*!< Low byte of x coordinate. */
|
||||
uint8_t highX; /*!< High byte of x coordinate. */
|
||||
uint8_t lowY; /*!< Low byte of y coordinate. */
|
||||
uint8_t highY; /*!< High byte of x coordinate. */
|
||||
uint8_t lowSize; /*!< Low byte of point size. */
|
||||
uint8_t highSize; /*!< High byte of point size. */
|
||||
uint8_t reserved; /*!< Reserved. */
|
||||
} gt911_point_reg_t;
|
||||
|
||||
/*! @brief gt911 configure structure.*/
|
||||
typedef struct _gt911_config
|
||||
{
|
||||
gt911_i2c_send_func_t I2C_SendFunc; /*!< Function to send I2C data. */
|
||||
gt911_i2c_receive_func_t I2C_ReceiveFunc; /*!< Function to receive I2C data. */
|
||||
void (*timeDelayMsFunc)(uint32_t delayMs); /*!< Function to delay some MS. */
|
||||
gt911_int_pin_func_t intPinFunc; /*!< Function to set interrupt pin to different mode. */
|
||||
gt911_reset_pin_func_t pullResetPinFunc; /*!< Function to pull reset pin high or low. */
|
||||
uint8_t touchPointNum; /*!< How many touch points to enable. */
|
||||
gt911_i2c_addr_mode_t i2cAddrMode; /*!< I2C address mode. */
|
||||
gt911_int_trig_mode_t intTrigMode; /*!< Interrupt trigger mode. */
|
||||
} gt911_config_t;
|
||||
|
||||
/*! @brief gt911 driver structure.*/
|
||||
typedef struct _gt911_handle
|
||||
{
|
||||
gt911_i2c_send_func_t I2C_SendFunc; /*!< Function to send I2C data. */
|
||||
gt911_i2c_receive_func_t I2C_ReceiveFunc; /*!< Function to receive I2C data. */
|
||||
void (*timeDelayMsFunc)(uint32_t delayMs); /*!< Function to delay some MS. */
|
||||
gt911_reset_pin_func_t pullResetPinFunc; /*!< Function to pull reset pin high or low. */
|
||||
gt911_point_reg_t pointReg[GT911_MAX_TOUCHES]; /*!< Buffer to receive touch point raw data. */
|
||||
uint8_t touchPointNum; /*!< How many touch points to enable. */
|
||||
uint8_t i2cAddr; /*!< I2C address. */
|
||||
uint16_t resolutionX; /*!< Resolution. */
|
||||
uint16_t resolutionY; /*!< Resolution. */
|
||||
} gt911_handle_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @brief Initialize the driver.
|
||||
*
|
||||
* @param[in] handle Pointer to the GT911 driver.
|
||||
* @param[in] config Pointer to the configuration.
|
||||
* @return Returns @ref kStatus_Success if succeeded, otherwise return error code.
|
||||
*/
|
||||
status_t GT911_Init(gt911_handle_t *handle, const gt911_config_t *config);
|
||||
|
||||
/*!
|
||||
* @brief De-initialize the driver.
|
||||
*
|
||||
* @param[in] handle Pointer to the GT911 driver.
|
||||
* @return Returns @ref kStatus_Success if succeeded, otherwise return error code.
|
||||
*/
|
||||
status_t GT911_Deinit(gt911_handle_t *handle);
|
||||
|
||||
/*!
|
||||
* @brief Get single touch point coordinate.
|
||||
*
|
||||
* @param[in] handle Pointer to the GT911 driver.
|
||||
* @param[out] touch_x X coordinate of the touch point.
|
||||
* @param[out] touch_y Y coordinate of the touch point.
|
||||
* @return Returns @ref kStatus_Success if succeeded, otherwise return error code.
|
||||
*/
|
||||
status_t GT911_GetSingleTouch(gt911_handle_t *handle, int *touch_x, int *touch_y);
|
||||
|
||||
/*!
|
||||
* @brief Get multiple touch points coordinate.
|
||||
*
|
||||
* When calling this function, parameter @ref touch_count means the array size
|
||||
* of @p touch_array. After the function returns, the @p touch_count means how
|
||||
* many valid touch points there are in the @p touch_array.
|
||||
*
|
||||
* @param[in] handle Pointer to the GT911 driver.
|
||||
* @param[in, out] touch_count The touch point number.
|
||||
* @param[out] touch_array Array of touch points coordinate.
|
||||
* @return Returns @ref kStatus_Success if succeeded, otherwise return error code.
|
||||
*/
|
||||
status_t GT911_GetMultiTouch(gt911_handle_t *handle, uint8_t *touch_count, touch_point_t touch_array[]);
|
||||
|
||||
/*!
|
||||
* @brief Get touch IC resolution.
|
||||
*
|
||||
* Note the touch resolution might be different with display resolution.
|
||||
*
|
||||
* @param handle Pointer to the driver.
|
||||
* @param touch_x X resolution.
|
||||
* @param touch_y Y resolution.
|
||||
* @return Returns @ref kStatus_Success if succeeded, otherwise return error code.
|
||||
*/
|
||||
status_t GT911_GetResolution(gt911_handle_t *handle, int *resolutionX, int *resolutionY);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! @} */
|
||||
|
||||
#endif /* _FSL_GT911_H_ */
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* Copyright 2017, 2020-2021 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "fsl_video_common.h"
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
bool VIDEO_IsYUV(video_pixel_format_t format)
|
||||
{
|
||||
if ((kVIDEO_PixelFormatYUYV == format) || (kVIDEO_PixelFormatYVYU == format) ||
|
||||
(kVIDEO_PixelFormatUYVY == format) || (kVIDEO_PixelFormatVYUY == format) ||
|
||||
(kVIDEO_PixelFormatXYVU == format) || (kVIDEO_PixelFormatXYUV == format))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void VIDEO_DelayMs(uint32_t ms)
|
||||
{
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
TickType_t tick;
|
||||
|
||||
tick = ms * configTICK_RATE_HZ / 1000U;
|
||||
|
||||
tick = (0U == tick) ? 1U : tick;
|
||||
|
||||
vTaskDelay(tick);
|
||||
#else
|
||||
while (0U != (ms--))
|
||||
{
|
||||
SDK_DelayAtLeastUs(1000U, SystemCoreClock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
switch (pixelFormat)
|
||||
{
|
||||
case kVIDEO_PixelFormatXRGB8888:
|
||||
case kVIDEO_PixelFormatRGBX8888:
|
||||
case kVIDEO_PixelFormatXBGR8888:
|
||||
case kVIDEO_PixelFormatBGRX8888:
|
||||
case kVIDEO_PixelFormatXYUV:
|
||||
case kVIDEO_PixelFormatXYVU:
|
||||
ret = 32;
|
||||
break;
|
||||
|
||||
case kVIDEO_PixelFormatRGB888:
|
||||
case kVIDEO_PixelFormatBGR888:
|
||||
ret = 24;
|
||||
break;
|
||||
|
||||
case kVIDEO_PixelFormatRGB565:
|
||||
case kVIDEO_PixelFormatBGR565:
|
||||
case kVIDEO_PixelFormatXRGB1555:
|
||||
case kVIDEO_PixelFormatRGBX5551:
|
||||
case kVIDEO_PixelFormatXBGR1555:
|
||||
case kVIDEO_PixelFormatBGRX5551:
|
||||
case kVIDEO_PixelFormatXRGB4444:
|
||||
case kVIDEO_PixelFormatRGBX4444:
|
||||
case kVIDEO_PixelFormatXBGR4444:
|
||||
case kVIDEO_PixelFormatBGRX4444:
|
||||
case kVIDEO_PixelFormatYUYV:
|
||||
case kVIDEO_PixelFormatYVYU:
|
||||
case kVIDEO_PixelFormatUYVY:
|
||||
case kVIDEO_PixelFormatVYUY:
|
||||
ret = 16;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
status_t VIDEO_RINGBUF_Init(video_ringbuf_t *ringbuf, void **buf, uint32_t size)
|
||||
{
|
||||
assert(ringbuf);
|
||||
|
||||
ringbuf->rear = 0;
|
||||
ringbuf->front = 0;
|
||||
ringbuf->size = size;
|
||||
ringbuf->buf = buf;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
status_t VIDEO_RINGBUF_Get(video_ringbuf_t *ringbuf, void **item)
|
||||
{
|
||||
uint32_t front_next;
|
||||
|
||||
/* To fix IAR Pa082 warning. */
|
||||
uint32_t rear = ringbuf->rear;
|
||||
uint32_t front = ringbuf->front;
|
||||
|
||||
if (rear != front)
|
||||
{
|
||||
*item = ringbuf->buf[ringbuf->front];
|
||||
|
||||
/*
|
||||
* Here don't use ringbuf->front = (ringbuf->front + 1) % ringbuf->size,
|
||||
* because mod operation might be slow.
|
||||
*/
|
||||
front_next = (ringbuf->front + 1U);
|
||||
|
||||
/* Use two steps to make sure ringbuf->front is always a valid value. */
|
||||
ringbuf->front = (front_next == ringbuf->size) ? 0UL : front_next;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
|
||||
status_t VIDEO_RINGBUF_Put(video_ringbuf_t *ringbuf, void *item)
|
||||
{
|
||||
/*
|
||||
* Here don't use ringbuf->rear = (ringbuf->rear + 1) % ringbuf->size,
|
||||
* because mod operation might be slow.
|
||||
*/
|
||||
uint32_t rear_next = ringbuf->rear + 1U;
|
||||
|
||||
rear_next = (rear_next == ringbuf->size) ? 0U : rear_next;
|
||||
|
||||
if (rear_next != ringbuf->front)
|
||||
{
|
||||
ringbuf->buf[ringbuf->rear] = item;
|
||||
ringbuf->rear = rear_next;
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
/* No room. */
|
||||
else
|
||||
{
|
||||
return kStatus_Fail;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t VIDEO_RINGBUF_GetLength(video_ringbuf_t *ringbuf)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
/* To fix IAR Pa082 warning. */
|
||||
uint32_t rear = ringbuf->rear;
|
||||
uint32_t front = ringbuf->front;
|
||||
|
||||
ret = (rear + ringbuf->size) - front;
|
||||
|
||||
if (ret >= ringbuf->size)
|
||||
{
|
||||
ret -= ringbuf->size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VIDEO_RINGBUF_IsEmpty(video_ringbuf_t *ringbuf)
|
||||
{
|
||||
/* To fix IAR Pa082 warning. */
|
||||
uint32_t rear = ringbuf->rear;
|
||||
uint32_t front = ringbuf->front;
|
||||
|
||||
if (rear == front)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool VIDEO_RINGBUF_IsFull(video_ringbuf_t *ringbuf)
|
||||
{
|
||||
uint32_t rear = ringbuf->rear;
|
||||
uint32_t front = ringbuf->front;
|
||||
|
||||
rear++;
|
||||
|
||||
if (rear >= ringbuf->size)
|
||||
{
|
||||
rear = 0;
|
||||
}
|
||||
|
||||
if (rear == front)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
status_t VIDEO_MEMPOOL_Init(video_mempool_t *mempool, void *initMem, uint32_t size, uint32_t count)
|
||||
{
|
||||
(void)memset(mempool, 0, sizeof(video_mempool_t));
|
||||
|
||||
while (0U != (count--))
|
||||
{
|
||||
VIDEO_MEMPOOL_Put(mempool, initMem);
|
||||
initMem = &((uint8_t *)initMem)[size];
|
||||
}
|
||||
|
||||
return kStatus_Success;
|
||||
}
|
||||
|
||||
void VIDEO_MEMPOOL_InitEmpty(video_mempool_t *mempool)
|
||||
{
|
||||
mempool->pool = NULL;
|
||||
mempool->cnt = 0;
|
||||
}
|
||||
|
||||
void VIDEO_MEMPOOL_Put(video_mempool_t *mempool, void *mem)
|
||||
{
|
||||
*(void **)mem = mempool->pool;
|
||||
mempool->pool = mem;
|
||||
mempool->cnt++;
|
||||
}
|
||||
|
||||
void *VIDEO_MEMPOOL_Get(video_mempool_t *mempool)
|
||||
{
|
||||
void *mem = mempool->pool;
|
||||
|
||||
if (NULL != mem)
|
||||
{
|
||||
mempool->cnt--;
|
||||
mempool->pool = *(void **)mem;
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
uint32_t VIDEO_MEMPOOL_GetCount(video_mempool_t *mempool)
|
||||
{
|
||||
return mempool->cnt;
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright 2017, 2020-2021 NXP
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _FSL_VIDEO_COMMON_H_
|
||||
#define _FSL_VIDEO_COMMON_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
|
||||
/*
|
||||
* Change log:
|
||||
*
|
||||
* 1.0.5
|
||||
* - Fix IAR Pa082 warning.
|
||||
*
|
||||
* 1.0.4
|
||||
* - Add LUT8 definition.
|
||||
*
|
||||
* 1.0.3
|
||||
* - Add RAW8 definition.
|
||||
*
|
||||
* 1.0.2
|
||||
* - Fixed MISRA-C 2012 issues.
|
||||
*
|
||||
* 1.0.1
|
||||
* - Update the VIDEO_DelayMs for bare metal.
|
||||
*
|
||||
* 1.0.0
|
||||
* - Initial version
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
/*! @brief Pixel format FOURCC. */
|
||||
#define FSL_VIDEO_FOURCC(a, b, c, d) \
|
||||
((uint32_t)(a) | ((uint32_t)(b) << 8U) | ((uint32_t)(c) << 16U) | ((uint32_t)(d) << 24U))
|
||||
|
||||
/*! @brief Macro to define resolution. */
|
||||
#define FSL_VIDEO_RESOLUTION(width, height) ((uint32_t)(width) | ((uint32_t)(height) << 16U))
|
||||
|
||||
#define FSL_VIDEO_EXTRACT_WIDTH(resolution) ((uint16_t)((resolution)&0xFFFFU))
|
||||
#define FSL_VIDEO_EXTRACT_HEIGHT(resolution) ((uint16_t)((resolution) >> 16U))
|
||||
|
||||
/*! @brief Pixel format definition. */
|
||||
typedef enum _video_pixel_format
|
||||
{
|
||||
/* RAW */
|
||||
kVIDEO_PixelFormatRAW8 = FSL_VIDEO_FOURCC('G', 'R', 'B', 'G'), /*!< RAW8, GRBG. */
|
||||
|
||||
/* LUT/palette */
|
||||
kVIDEO_PixelFormatLUT8 = FSL_VIDEO_FOURCC('L', 'U', 'T', '8'), /*!< 8-bit Indexed Color. */
|
||||
|
||||
/* RGB */
|
||||
kVIDEO_PixelFormatXRGB8888 = FSL_VIDEO_FOURCC('X', 'R', '2', '4'), /*!< 32-bit XRGB8888. */
|
||||
kVIDEO_PixelFormatRGBX8888 = FSL_VIDEO_FOURCC('R', 'X', '2', '4'), /*!< 32-bit RGBX8888. */
|
||||
kVIDEO_PixelFormatXBGR8888 = FSL_VIDEO_FOURCC('X', 'B', '2', '4'), /*!< 32-bit XBGR8888. */
|
||||
kVIDEO_PixelFormatBGRX8888 = FSL_VIDEO_FOURCC('B', 'X', '2', '4'), /*!< 32-bit BGRX8888. */
|
||||
|
||||
kVIDEO_PixelFormatRGB888 = FSL_VIDEO_FOURCC('R', 'G', '2', '4'), /*!< 24-bit RGB888. */
|
||||
kVIDEO_PixelFormatBGR888 = FSL_VIDEO_FOURCC('B', 'G', '2', '4'), /*!< 24-bit BGR888. */
|
||||
|
||||
kVIDEO_PixelFormatRGB565 = FSL_VIDEO_FOURCC('R', 'G', '1', '6'), /*!< 16-bit RGB565. */
|
||||
kVIDEO_PixelFormatBGR565 = FSL_VIDEO_FOURCC('B', 'G', '1', '6'), /*!< 16-bit BGR565. */
|
||||
|
||||
kVIDEO_PixelFormatXRGB1555 = FSL_VIDEO_FOURCC('X', 'R', '1', '5'), /*!< 16-bit XRGB1555. */
|
||||
kVIDEO_PixelFormatRGBX5551 = FSL_VIDEO_FOURCC('R', 'X', '1', '5'), /*!< 16-bit RGBX5551. */
|
||||
kVIDEO_PixelFormatXBGR1555 = FSL_VIDEO_FOURCC('X', 'B', '1', '5'), /*!< 16-bit XBGR1555. */
|
||||
kVIDEO_PixelFormatBGRX5551 = FSL_VIDEO_FOURCC('B', 'X', '1', '5'), /*!< 16-bit BGRX5551. */
|
||||
|
||||
kVIDEO_PixelFormatXRGB4444 = FSL_VIDEO_FOURCC('X', 'R', '1', '2'), /*!< 16-bit XRGB4444. */
|
||||
kVIDEO_PixelFormatRGBX4444 = FSL_VIDEO_FOURCC('R', 'X', '1', '2'), /*!< 16-bit RGBX4444. */
|
||||
kVIDEO_PixelFormatXBGR4444 = FSL_VIDEO_FOURCC('X', 'B', '1', '2'), /*!< 16-bit XBGR4444. */
|
||||
kVIDEO_PixelFormatBGRX4444 = FSL_VIDEO_FOURCC('B', 'X', '1', '2'), /*!< 16-bit BGRX4444. */
|
||||
|
||||
/* YUV. */
|
||||
kVIDEO_PixelFormatYUYV = FSL_VIDEO_FOURCC('Y', 'U', 'Y', 'V'), /*!< YUV422, Y-U-Y-V. */
|
||||
kVIDEO_PixelFormatYVYU = FSL_VIDEO_FOURCC('Y', 'V', 'Y', 'U'), /*!< YUV422, Y-V-Y-U. */
|
||||
kVIDEO_PixelFormatUYVY = FSL_VIDEO_FOURCC('U', 'Y', 'V', 'Y'), /*!< YUV422, U-Y-V-Y. */
|
||||
kVIDEO_PixelFormatVYUY = FSL_VIDEO_FOURCC('V', 'Y', 'U', 'Y'), /*!< YUV422, V-Y-U-Y. */
|
||||
|
||||
kVIDEO_PixelFormatXYUV = FSL_VIDEO_FOURCC('X', 'Y', 'U', 'V'), /*!< YUV444, X-Y-U-V. */
|
||||
kVIDEO_PixelFormatXYVU = FSL_VIDEO_FOURCC('X', 'Y', 'V', 'U'), /*!< YUV444, X-Y-V-U. */
|
||||
} video_pixel_format_t;
|
||||
|
||||
/*! @brief Resolution definition. */
|
||||
typedef enum _video_resolution
|
||||
{
|
||||
kVIDEO_ResolutionVGA = FSL_VIDEO_RESOLUTION(640, 480), /*!< VGA, 640 * 480 */
|
||||
kVIDEO_ResolutionQVGA = FSL_VIDEO_RESOLUTION(320, 240), /*!< QVGA, 320 * 240 */
|
||||
kVIDEO_ResolutionQQVGA = FSL_VIDEO_RESOLUTION(160, 120), /*!< QQVGA, 160 * 120 */
|
||||
kVIDEO_ResolutionCIF = FSL_VIDEO_RESOLUTION(352, 288), /*!< CIF, 352 * 288 */
|
||||
kVIDEO_ResolutionQCIF = FSL_VIDEO_RESOLUTION(176, 144), /*!< QCIF, 176 * 144 */
|
||||
kVIDEO_ResolutionQQCIF = FSL_VIDEO_RESOLUTION(88, 72), /*!< QQCIF, 88 * 72 */
|
||||
kVIDEO_Resolution720P = FSL_VIDEO_RESOLUTION(1280, 720), /*!< 720P, 1280 * 720 */
|
||||
kVIDEO_Resolution1080P = FSL_VIDEO_RESOLUTION(1920, 1080), /*!< 1080P, 1920 * 1280*/
|
||||
kVIDEO_ResolutionWXGA = FSL_VIDEO_RESOLUTION(1280, 800), /*!< WXGA, 1280 * 800 */
|
||||
} video_resolution_t;
|
||||
|
||||
/*!
|
||||
* @brief Ring buffer structure.
|
||||
*
|
||||
* There is one empty room reserved in the ring buffer, used to distinguish
|
||||
* whether the ring buffer is full or empty. When rear equals front, it is empty;
|
||||
* when rear+1 equals front, it is full.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
volatile uint32_t rear; /*!< Pointer to save the incoming item. */
|
||||
volatile uint32_t front; /*!< Pointer to read out the item. */
|
||||
void *volatile *buf; /*!< Memory to the ring buffer. */
|
||||
uint32_t size; /*!< Ring buffer total size. */
|
||||
} video_ringbuf_t;
|
||||
|
||||
/*!
|
||||
* @brief Memory pool structure.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
void *volatile pool; /*!< Pointer to the pool. */
|
||||
volatile uint32_t cnt; /*!< Count of memory blocks in the pool. */
|
||||
} video_mempool_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* API
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @name Common
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Check the pixel format is YUV or not.
|
||||
*
|
||||
* @param format Pixel format.
|
||||
*/
|
||||
bool VIDEO_IsYUV(video_pixel_format_t format);
|
||||
|
||||
/*!
|
||||
* @brief Delay the specific time.
|
||||
*
|
||||
* @param ms How many milli-second to delay.
|
||||
*/
|
||||
void VIDEO_DelayMs(uint32_t ms);
|
||||
|
||||
/*!
|
||||
* @brief Get the pixel size in bits.
|
||||
*
|
||||
* @param pixelFormat The pixel format.
|
||||
* @return Bits per pixel.
|
||||
*/
|
||||
uint8_t VIDEO_GetPixelSizeBits(video_pixel_format_t pixelFormat);
|
||||
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Ring buffer.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes ring buffer.
|
||||
*
|
||||
* @param ringbuf Pointer to the ring buffer handle.
|
||||
* @param buf Memory to save the items.
|
||||
* @param size Size of the @p buf.
|
||||
* @return Returns @ref kStatus_Success if initialize success, otherwise returns
|
||||
* error code.
|
||||
*/
|
||||
status_t VIDEO_RINGBUF_Init(video_ringbuf_t *ringbuf, void **buf, uint32_t size);
|
||||
|
||||
/*!
|
||||
* @brief Get one item from the ring buffer.
|
||||
*
|
||||
* @param ringbuf Pointer to the ring buffer handle.
|
||||
* @param item Memory to save the item.
|
||||
* @return Returns @ref kStatus_Success if get success, otherwise returns
|
||||
* error code.
|
||||
*/
|
||||
status_t VIDEO_RINGBUF_Get(video_ringbuf_t *ringbuf, void **item);
|
||||
|
||||
/*!
|
||||
* @brief Put one item to the ring buffer.
|
||||
*
|
||||
* @param ringbuf Pointer to the ring buffer handle.
|
||||
* @param item The new item to save.
|
||||
* @return Returns @ref kStatus_Success if put success, otherwise returns
|
||||
* error code.
|
||||
*/
|
||||
status_t VIDEO_RINGBUF_Put(video_ringbuf_t *ringbuf, void *item);
|
||||
|
||||
/*!
|
||||
* @brief Get current count of items in the ring buffer.
|
||||
*
|
||||
* @param ringbuf Pointer to the ring buffer handle.
|
||||
* @return Returns the item count.
|
||||
*/
|
||||
uint32_t VIDEO_RINGBUF_GetLength(video_ringbuf_t *ringbuf);
|
||||
|
||||
/*!
|
||||
* @brief Check whether the ring buffer is empty.
|
||||
*
|
||||
* @param ringbuf Pointer to the ring buffer handle.
|
||||
* @return Returns true if the ring buffer is empty, otherwise returns false.
|
||||
*/
|
||||
bool VIDEO_RINGBUF_IsEmpty(video_ringbuf_t *ringbuf);
|
||||
|
||||
/*!
|
||||
* @brief Check whether the ring buffer is full.
|
||||
*
|
||||
* @param ringbuf Pointer to the ring buffer handle.
|
||||
* @return Returns true if the ring buffer is full, otherwise returns false.
|
||||
*/
|
||||
bool VIDEO_RINGBUF_IsFull(video_ringbuf_t *ringbuf);
|
||||
/* @} */
|
||||
|
||||
/*!
|
||||
* @name Memory Pool
|
||||
*
|
||||
* User can put memory block to the pool, or get memory block from the pool.
|
||||
* There is no count limitation to put memory block in to the pool. The memory
|
||||
* content in the pool might be modified.
|
||||
*
|
||||
* The memory block should be 4-byte aligned, and the dividable by 4-byte.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @brief Initializes memory pool.
|
||||
*
|
||||
* Initializes memory pool. Initial memory blocks in the memory pool is optional.
|
||||
* If initial blocks are used, user should specify the initial block size and count.
|
||||
*
|
||||
* @param mempool Pointer to the memory pool handle.
|
||||
* @param initMem Initial memory blocks to saved in the pool.
|
||||
* @param size Every memory block's size (bytes) in the @p initMem.
|
||||
* @param count Number of memory blocks @p initMem.
|
||||
* @return Returns @ref kStatus_Success if initialize success, otherwise returns
|
||||
* error code.
|
||||
*/
|
||||
status_t VIDEO_MEMPOOL_Init(video_mempool_t *mempool, void *initMem, uint32_t size, uint32_t count);
|
||||
|
||||
/*!
|
||||
* @brief Create an empty memory pool.
|
||||
*
|
||||
* @param mempool Pointer to the memory pool handle.
|
||||
*/
|
||||
void VIDEO_MEMPOOL_InitEmpty(video_mempool_t *mempool);
|
||||
|
||||
/*!
|
||||
* @brief Put memory block in the pool.
|
||||
*
|
||||
* @param mempool Pointer to the memory pool handle.
|
||||
* @param mem Pointer to the memory block.
|
||||
*/
|
||||
void VIDEO_MEMPOOL_Put(video_mempool_t *mempool, void *mem);
|
||||
|
||||
/*!
|
||||
* @brief Get memory block in the pool.
|
||||
*
|
||||
* @param mempool Pointer to the memory pool handle.
|
||||
* @return The memory block get from pool. If the pool is empty, returns NULL.
|
||||
*/
|
||||
void *VIDEO_MEMPOOL_Get(video_mempool_t *mempool);
|
||||
|
||||
/*!
|
||||
* @brief How many memory blocks in the pool.
|
||||
*
|
||||
* @param mempool Pointer to the memory pool handle.
|
||||
* @return The memory block count in the pool
|
||||
*/
|
||||
uint32_t VIDEO_MEMPOOL_GetCount(video_mempool_t *mempool);
|
||||
|
||||
/* @} */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FSL_VIDEO_COMMON_H_ */
|
|
@ -6,6 +6,7 @@ path = [cwd + '/CMSIS/Include',cwd + '/MIMXRT1060', cwd + '/MIMXRT1060/drivers']
|
|||
src = Split('''
|
||||
MIMXRT1060/system_MIMXRT1062.c
|
||||
MIMXRT1060/drivers/fsl_common.c
|
||||
MIMXRT1060/drivers/fsl_common_arm.c
|
||||
MIMXRT1060/drivers/fsl_clock.c
|
||||
MIMXRT1060/drivers/fsl_cache.c
|
||||
''')
|
||||
|
@ -53,6 +54,12 @@ if GetDepend(['BSP_USING_SDRAM']):
|
|||
if GetDepend(['BSP_USING_LCD']):
|
||||
src += ['MIMXRT1060/drivers/fsl_elcdif.c']
|
||||
|
||||
if GetDepend(['DEMO_PANEL_RK043FN02H']):
|
||||
src += ['MIMXRT1060/drivers/fsl_ft5406_rt.c']
|
||||
|
||||
if GetDepend(['DEMO_PANEL_RK043FN66HS']):
|
||||
src += ['MIMXRT1060/drivers/fsl_video_common.c', 'MIMXRT1060/drivers/fsl_gt911.c']
|
||||
|
||||
if GetDepend(['BSP_USING_CACHE']):
|
||||
src += ['MIMXRT1060/drivers/fsl_cache.c']
|
||||
|
||||
|
|
Loading…
Reference in New Issue