MCUXpresso_LPC804/boards/lpcxpresso804/touch_examples/capt_key/touch.c
Yilin Sun e468131146
Initial commit v2.13.0
Signed-off-by: Yilin Sun <imi415@imi.moe>
2023-05-25 15:51:41 +08:00

184 lines
4.7 KiB
C

/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdint.h>
#include "touch.h"
#include "app_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
int16_t touchWindowsBuff[TOUCH_X_CHANNEL_COUNT][TOUCH_WINDOW_LENGTH];
uint8_t touchWindowsIndex;
/* Baseline after calibration. */
int32_t touchDataBaseline[TOUCH_X_CHANNEL_COUNT];
/* Touch data removed baseline. */
int32_t touchData[TOUCH_X_CHANNEL_COUNT];
/*******************************************************************************
* Code
******************************************************************************/
void TOUCH_WINDOWS_Init(void)
{
touchWindowsIndex = 0u;
}
/*
* Push the raw data into the calculation window array,
* the window array is actually FIFO.
*/
void TOUCH_WINDOWS_Puth(int16_t *input)
{
for (uint8_t i = 0u; i < TOUCH_X_CHANNEL_COUNT; i++)
{
touchWindowsBuff[i][touchWindowsIndex] = input[i];
}
touchWindowsIndex = (touchWindowsIndex + 1u) % TOUCH_WINDOW_LENGTH;
}
/*
* Calculate the sum of one channel's sample data in the window.
* Input is one channel's sample data in the window.
* Return the sum.
*/
static int32_t TOUCH_WINDOW_CalcSum(int16_t *input)
{
int32_t sum = 0;
for (uint8_t i = 0u; i < TOUCH_WINDOW_LENGTH; i++)
{
sum += input[i];
}
return sum;
}
/* Calculate the sum of each channel's sample data separately. */
void TOUCH_WINDOWS_CalcSum(int32_t *output)
{
for (uint8_t i = 0u; i < TOUCH_X_CHANNEL_COUNT; i++)
{
output[i] = TOUCH_WINDOW_CalcSum(touchWindowsBuff[i]);
}
}
/*
* Calculate the average value of one channel's sample data in the window.
* Input is one channel's sample data in the window.
* Return the average value.
*/
static int16_t TOUCH_WINDOW_CalcAverage(int16_t *input)
{
return (int16_t)(TOUCH_WINDOW_CalcSum(input) / TOUCH_WINDOW_LENGTH);
}
/* Calculate the average value of each channel's sample data separately. */
void TOUCH_WINDOWS_CalcAverage(int32_t *output)
{
for (uint8_t i = 0u; i < TOUCH_X_CHANNEL_COUNT; i++)
{
output[i] = TOUCH_WINDOW_CalcAverage(touchWindowsBuff[i]);
}
}
/*
* Calculate the variance of one channel's sample data in the window.
* Input is one channel's average value and sample data in the window.
* Return the variance value.
*/
static int32_t TOUCH_WINDOW_CalcVariance(int16_t average, int16_t *input)
{
int32_t sum2 = 0;
int32_t diff;
for (uint8_t i = 0u; i < TOUCH_WINDOW_LENGTH; i++)
{
diff = input[i] - average;
sum2 += (diff * diff);
}
return sum2 / TOUCH_WINDOW_LENGTH;
}
/* Calculate the variance value of each channel's sample data separately. */
void TOUCH_WINDOWS_CalcVariance(int32_t *average, int32_t *output)
{
for (uint8_t i = 0u; i < TOUCH_X_CHANNEL_COUNT; i++)
{
output[i] = TOUCH_WINDOW_CalcVariance(average[i], touchWindowsBuff[i]);
}
}
void TOUCH_WINDOWS_SetBaseline(int32_t *input)
{
for (uint8_t i = 0u; i < TOUCH_X_CHANNEL_COUNT; i++)
{
touchDataBaseline[i] = input[i];
}
}
int32_t TOUCH_GetPressedKeyIndex(int32_t *input)
{
for (int i = 0; i < TOUCH_X_CHANNEL_COUNT; i++)
{
#if TOUCH_PRESSED_KEY_COUNT_DECREASE
touchData[i] = touchDataBaseline[i] - input[i];
#else
touchData[i] = input[i] - touchDataBaseline[i];
#endif
}
#if (TOUCH_X_CHANNEL_COUNT > 1)
uint8_t touchValMaxIdx = 0;
uint8_t touchValMinIdx = 0;
for (int i = 1; i < TOUCH_X_CHANNEL_COUNT; i++)
{
if (touchData[i] > touchData[touchValMaxIdx])
{
touchValMaxIdx = i;
}
if (touchData[i] < touchData[touchValMinIdx])
{
touchValMinIdx = i;
}
}
/* No significant difference, no touch happend. */
if ((touchData[touchValMaxIdx] - touchData[touchValMinIdx]) < TOUCH_YES_TOUCH_THRESHOLD_LOW)
{
return TOUCH_X_CHANNEL_COUNT;
}
else
{
/* Touch happened. */
return touchValMaxIdx;
}
#else
if (touchData[0] < TOUCH_YES_TOUCH_THRESHOLD_LOW)
{
/* Touch not happened. */
return TOUCH_X_CHANNEL_COUNT;
}
else
{
/* Touch happened. */
return 0;
}
#endif
}