xmclib/XMCLib/examples/XMC4500_series/LEDTS/LEDTS_TOUCH/main.c
2024-10-17 17:09:59 +02:00

290 lines
12 KiB
C

/*******************************************************************************
Copyright (c) 2014, Infineon Technologies AG **
All rights reserved. **
**
Redistribution and use in source and binary forms, with or without **
modification,are permitted provided that the following conditions are met: **
**
*Redistributions of source code must retain the above copyright notice, **
this list of conditions and the following disclaimer. **
*Redistributions in binary form must reproduce the above copyright notice, **
this list of conditions and the following disclaimer in the documentation **
and/or other materials provided with the distribution. **
*Neither the name of the copyright holders nor the names of its contributors **
may be used to endorse or promote products derived from this software without**
specific prior written permission. **
**
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" **
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE **
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE **
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE **
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR **
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF **
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS **
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN **
CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) **
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE **
POSSIBILITY OF SUCH DAMAGE. **
**
To improve the quality of the software, users are encouraged to share **
modifications, enhancements or bug fixes with Infineon Technologies AG **
dave@infineon.com). **
**
********************************************************************************
** **
** PLATFORM : Infineon XMC1200 Series **
** **
** AUTHOR : Application Engineering Team **
** **
** version 1.0.0 (Initial version) **
** **
********************************************************************************/
/*******************************************************************************
** Revision History: **
** Date version Details **
** 03-Dec-2014 1.0.0 Initial version of Example project **
*******************************************************************************/
#include <XMC4500.h> //SFR declarations of the selected device
#include <xmc_gpio.h>
#include <xmc_ledts.h>
/*******************************************************************************
** GLOBAL VARIABLE DEFINITIONS:
*******************************************************************************/
/* Touch-Sense Library Variables/Parameters */
uint8_t LPFilterGain = 8U;
uint16_t SubM[8] = {0, 0, 0x4F, 0, 0, 0, 0, 0x4F};
uint16_t ShortCnt = 0xFFFCU;
uint16_t ErrorCnt = 0xFFEFU;
uint8_t PADFLAG[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t PADRESULT[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t PADERROR[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint32_t LEDTS_Average[8];
uint32_t LEDTS_LowTripVal[8];
uint32_t LEDTS_PadDownCounter[8];
uint8_t CurrentPadTurn = 0;
/* LED status tracker */
uint8_t ledstatus = 0;
/*******************************************************************************
** FUNCTION DECLARATIONS:
*******************************************************************************/
void FindTouchedPad(void);
/*******************************************************************************
** LEDTS CONFIGURATION HANDLES:
*******************************************************************************/
const XMC_LEDTS_GLOBAL_CONFIG_t global_config_data =
{
.suspend_response = XMC_LEDTS_SUSPEND_ENABLE,
.clock_generation = XMC_LEDTS_CLOCK_TYPE_MASTER,
.autoscan_synchronization = XMC_LEDTS_TP_SYNC_DISABLE
};
const XMC_LEDTS_LED_CONFIG_t led_config_data =
{
.column_active_level = XMC_LEDTS_ACTIVE_LEVEL_LED_COL_LOW,
.no_of_led_columns = XMC_LEDTS_NUMBER_LED_COLUMNS_2,
};
const XMC_LEDTS_TS_CONFIG_BASIC_t ts_basic_config_data =
{
.common_compare = XMC_LEDTS_COMMON_COMPARE_ENABLE,
.counter_auto_reset = XMC_LEDTS_TS_COUNTER_AUTO_RESET_ENABLE,
.counter_saturation = XMC_LEDTS_TS_COUNTER_SATURATION_ENABLE,
.no_of_accumulation = XMC_LEDTS_ACCUMULATION_COUNT_2_TIMES,
};
const XMC_LEDTS_TS_CONFIG_ADVANCED_t ts_adv_config_data =
{
.first_pad_turn = XMC_LEDTS_PAD_TURN_2,
.pad_turn_control = XMC_LEDTS_SW_CONTROL_ENABLE,
};
/*******************************************************************************
** MAIN CODE:
*******************************************************************************/
int main(void)
{
/* Initialize LEDTS features */
XMC_LEDTS_InitGlobal(XMC_LEDTS0, &global_config_data);
XMC_LEDTS_InitLED(XMC_LEDTS0, &led_config_data);
XMC_LEDTS_InitTSBasic(XMC_LEDTS0, &ts_basic_config_data);
XMC_LEDTS_InitTSAdvanced(XMC_LEDTS0, &ts_adv_config_data);
/* Configure all LED columns for max brightness */
XMC_LEDTS_SetColumnBrightness(XMC_LEDTS0, XMC_LEDTS_LED_COLUMN_1, 0xFF);
/* LEDs are off at start */
XMC_LEDTS_SetLEDLinePattern(XMC_LEDTS0, XMC_LEDTS_LED_COLUMN_1, 0x00);
/* Configure common oscillation window size for touch pads */
XMC_LEDTS_SetCommonOscillationWindow(XMC_LEDTS0, 0xF0);
/* Initialize PORT Pins */
XMC_GPIO_SetMode(XMC_GPIO_PORT5, 10, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4); /* LINE7 */
XMC_GPIO_SetMode(XMC_GPIO_PORT2, 4, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4); /* LINE2 */
XMC_GPIO_SetMode(XMC_GPIO_PORT0, 10, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT4); /* COL1 */
/* Initialize PORT Pins for Touch Sense Inputs */
XMC_GPIO_SetHardwareControl(XMC_GPIO_PORT5, 10, XMC_GPIO_HWCTRL_PERIPHERAL1); /* TSIN7 HW Control Config */
XMC_GPIO_SetHardwareControl(XMC_GPIO_PORT2, 4, XMC_GPIO_HWCTRL_PERIPHERAL1); /* TSIN2 HW Control Config */
/* Configure LEDTS Interrupt */
XMC_LEDTS_EnableInterrupt(XMC_LEDTS0, XMC_LEDTS_INTERRUPT_TIMEFRAME); /* Enable LEDTS Kernel 0 Time Frame Interrupt */
NVIC_SetPriority(LEDTS0_0_IRQn, 0); /* Set Interrupt Priority for NVIC 30 Node App Instance 0 */
NVIC_EnableIRQ(LEDTS0_0_IRQn); /* Enable LEDTS Kernel 1 Interrupt Request */
/* Start LEDTS timer */
XMC_LEDTS_StartCounter(XMC_LEDTS0, 0x01D5); /* time slice duration = 1ms */
while(1)
{
}
}
/*******************************************************************************
** INTERRUPT HANDLERS:
*******************************************************************************/
void LEDTS0_0_IRQHandler()
{
if((XMC_LEDTS_ReadInterruptFlag(XMC_LEDTS0) & XMC_LEDTS_INTERRUPT_FLAG_TIMEFRAME) == XMC_LEDTS_INTERRUPT_FLAG_TIMEFRAME)
{
/* Time Frame Interrupt has occured */
/* Clear flag */
XMC_LEDTS_ClearInterruptFlag(XMC_LEDTS0, XMC_LEDTS_INTERRUPT_FLAG_TIMEFRAME);
CurrentPadTurn = RD_REG(LEDTS0->FNCTL, LEDTS_FNCTL_PADT_Msk, LEDTS_FNCTL_PADT_Pos);
/* Call Find Touch Pad */
FindTouchedPad();
if(PADRESULT[2]) /* T1 touched */
{
if(ledstatus & 0x04) ledstatus &= ~(0x04);
else ledstatus |= 0x04;
PADRESULT[2] = 0;
}
if(PADRESULT[7]) /* T2 touched */
{
if(ledstatus & 0x80) ledstatus &= ~(0x80);
else ledstatus |= 0x80;
PADRESULT[7] = 0;
}
XMC_LEDTS_SetLEDLinePattern(XMC_LEDTS0, XMC_LEDTS_LED_COLUMN_1, ledstatus); /* update LEDs */
if(PADERROR[2])
{
PADERROR[2] = 0; /* ignore long touch */
}
if(PADERROR[7])
{
PADERROR[7] = 0; /* ignore long touch */
}
}
}
/*******************************************************************************
** TOUCH SENSE LIBRARY FUNCTION:
*******************************************************************************/
/* This function utilizes the TSVAL.TSCTRVALR value and calculates
* average values. The average values are used to determine if any
* of the touch pads are touched.
*/
void FindTouchedPad(void)
{
uint8_t PadIndex = 0U;
uint16_t TotalTSCnt = 0U;
uint32_t CrrntComprsnVal = 0U;
/* Get current PadTurnIndex */
PadIndex = (uint8_t)RD_REG(LEDTS0->FNCTL, LEDTS_FNCTL_PADT_Msk, LEDTS_FNCTL_PADT_Pos);
/* Take the accumulated TSCounter value */
TotalTSCnt = XMC_LEDTS_ReadTSVAL(XMC_LEDTS0);
if (0U == PADFLAG[PadIndex])
{
/* Calculate New Average */
LEDTS_Average[PadIndex] = (LEDTS_Average[PadIndex] + \
TotalTSCnt) - (LEDTS_Average[PadIndex] / (uint32_t)LPFilterGain);
if(LEDTS_Average[PadIndex] > SubM[PadIndex])
/* check to avoid error if tscount sum is 0x0000 for 1st iteration */
{
LEDTS_LowTripVal[PadIndex] = LEDTS_Average[PadIndex] -\
(uint32_t)SubM[PadIndex];
}
}
else
{
/* Do nothing - Only if PadFlag for the pad is 0,
Calculate Average and LowTrip,else proceed to analyzing condition for Touch */
}
CrrntComprsnVal = (uint32_t)TotalTSCnt * (uint32_t)LPFilterGain;
if(CrrntComprsnVal < LEDTS_LowTripVal[PadIndex])
{
if(0U == PADERROR[PadIndex])
{
if(0U == PADRESULT[PadIndex])
{
if(0U == PADFLAG[PadIndex])
{
PADFLAG[PadIndex] = 1;
LEDTS_PadDownCounter[PadIndex] = 0xFFFFU;
}
else
{
if(0U == LEDTS_PadDownCounter[PadIndex])
{
PADERROR[PadIndex] = 1;
PADFLAG[PadIndex] = 0;
}
else if(--LEDTS_PadDownCounter[PadIndex] == ErrorCnt)
{
LEDTS_PadDownCounter[PadIndex] = 0U;
}
}
}
}
}
else
{
if(0 != PADFLAG[PadIndex]) // finger is released
{
if(LEDTS_PadDownCounter[PadIndex] < ShortCnt) PADRESULT[PadIndex] = 1;
PADFLAG[PadIndex] = 0;
LEDTS_PadDownCounter[PadIndex] = 0;
}
}
/* For SW padturn next pad to be analyzed is to be set by SW
Set this PADT value.....You can change the below portion
of code to set the sequence of active pad turn........ */
if(1 == RD_REG(LEDTS0->FNCTL,LEDTS_FNCTL_PADTSW_Msk, LEDTS_FNCTL_PADTSW_Pos))
{
if(CurrentPadTurn == 2)
{
CurrentPadTurn = 7;
}
else if(CurrentPadTurn == 7)
{
CurrentPadTurn = 2;
}
/* End of code portion where modification can be done for setting
the sequence of active pad turn in SW pad turn control */
/* write next padt for SW pad turn */
WR_REG(LEDTS0->FNCTL, LEDTS_FNCTL_PADT_Msk, LEDTS_FNCTL_PADT_Pos, CurrentPadTurn);
}
else
{
/* Do Nothing - For HW pad turn HW automatically scans in Round Robin */
}
}