summaryrefslogtreecommitdiff
path: root/third_party/TouchSense
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/TouchSense')
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl.h52
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq.h118
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f0xx.h199
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f3xx.h210
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_hw.h287
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_sw.h293
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_hw.h234
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_sw.h275
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8tl5x.h270
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config.h451
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f0xx.h245
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f3xx.h227
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32l1xx.h401
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8l.h211
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8tl5x.h270
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f0xx.h_TOADAPT629
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f3xx.h_TOADAPT628
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32l1xx.h_TOADAPT527
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8l.h_TOADAPT533
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8tl5x.h_TOADAPT598
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_dxs.h43
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_ecs.h45
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_filter.h41
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_globals.h87
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_linrot.h226
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_object.h89
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_time.h88
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f0xx.h51
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f3xx.h51
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32l1xx.h43
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8l.h51
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8tl5x.h43
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_touchkey.h139
-rw-r--r--third_party/TouchSense/STMTouch_Driver/inc/tsl_types.h217
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl.c61
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq.c373
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f0xx.c1012
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f3xx.c1148
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c862
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_sw.c996
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_hw.c888
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_sw.c1426
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c906
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_dxs.c181
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_ecs.c332
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_filter.c137
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_globals.c33
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_linrot.c2103
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_object.c258
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_time.c174
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f0xx.c107
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f3xx.c55
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32l1xx.c55
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8l.c108
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8tl5x.c104
-rw-r--r--third_party/TouchSense/STMTouch_Driver/src/tsl_touchkey.c1089
-rw-r--r--third_party/TouchSense/stmCriticalSection.c59
-rw-r--r--third_party/TouchSense/stmCriticalSection.h32
-rw-r--r--third_party/TouchSense/tsl_conf_stm32f0xx.h630
-rw-r--r--third_party/TouchSense/tsl_user.c292
-rw-r--r--third_party/TouchSense/tsl_user.h102
61 files changed, 21395 insertions, 0 deletions
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl.h
new file mode 100644
index 0000000..6141ae1
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl.h
@@ -0,0 +1,52 @@
+/**
+ ******************************************************************************
+ * @file tsl.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_H
+#define __TSL_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq.h"
+#include "tsl_time.h"
+#include "tsl_touchkey.h"
+#include "tsl_linrot.h"
+#include "tsl_object.h"
+#include "tsl_dxs.h"
+#include "tsl_ecs.h"
+#include "tsl_filter.h"
+#include "tsl_globals.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported variables --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+
+/* Exported functions ------------------------------------------------------- */
+TSL_Status_enum_T TSL_Init(CONST TSL_Bank_T *bank);
+
+#endif /* __TSL_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq.h
new file mode 100644
index 0000000..eec8d83
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq.h
@@ -0,0 +1,118 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_acq.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_H
+#define __TSL_ACQ_H
+
+/* Includes ------------------------------------------------------------------*/
+
+// Check the device selection.
+// It must be defined in the toolchain compiler preprocessor.
+// The same name as in the Standard Peripheral Library is used.
+#if !defined(STM8L10X) &&\
+ !defined(STM8L15X_LD) && !defined(STM8L15X_MD) && !defined(STM8L15X_MDP) && !defined(STM8L15X_HD) &&\
+ !defined(STM8TL5X) &&\
+ !defined(STM32L1XX_MD) && !defined(STM32L1XX_MDP) && !defined(STM32L1XX_HD) && !defined(STM32L1XX_XL) &&\
+ !defined(STM32F0XX) && !defined(STM32F0XX_MD) && !defined(STM32F0XX_HD) &&\
+ !defined(STM32F051) && !defined(STM32F072) && !defined(STM32F042) &&\
+ !defined(STM32F303xC) && !defined(STM32F334x8) && !defined(STM32F303x8) && !defined(STM32F301x8) && !defined(STM32F302x8) &&\
+ !defined(STM32F37X)
+#error "Device family not declared in the toolchain compiler preprocessor."
+#endif
+
+#if defined(STM8L10X) || defined(STM8L15X_MD) || defined(STM8L15X_MDP) || defined(STM8L15X_HD)
+#include "tsl_acq_stm8l_sw.h" // Software acquisition only
+#endif
+
+#if defined(STM8L15X_LD)
+#if defined(TSLPRM_STM8L1XX_SW_ACQ)
+#include "tsl_acq_stm8l_sw.h" // Software acquisition
+#else
+#include "tsl_acq_stm8l_hw.h" // Hardware acquisition with Timers (default)
+#endif
+#endif
+
+#if defined(STM8TL5X)
+#include "tsl_acq_stm8tl5x.h"
+#endif
+
+#if defined(STM32L1XX_MD)
+#include "tsl_acq_stm32l1xx_sw.h" // Software acquisition only
+#endif
+
+#if defined(STM32L1XX_MDP) || defined(STM32L1XX_HD) || defined(STM32L1XX_XL)
+#if defined(TSLPRM_STM32L1XX_SW_ACQ)
+#include "tsl_acq_stm32l1xx_sw.h" // Software acquisition
+#else
+#include "tsl_acq_stm32l1xx_hw.h" // Hardware acquisition with Timers (default)
+#endif
+#endif
+
+#if defined(STM32F0XX) || defined(STM32F0XX_MD) || defined(STM32F0XX_HD) ||\
+ defined(STM32F051) || defined(STM32F072) || defined(STM32F042)
+#include "tsl_acq_stm32f0xx.h"
+#endif
+
+#if defined(STM32F303xC) || defined(STM32F334x8) || defined(STM32F303x8) || defined(STM32F301x8) || defined(STM32F302x8) ||\
+ defined(STM32F37X)
+#include "tsl_acq_stm32f3xx.h"
+#endif
+
+/* Defines -------------------------------------------------------------------*/
+
+/* Exported types ------------------------------------------------------------*/
+
+// Filter functions
+typedef TSL_tMeas_T(* TSL_pFuncMeasFilter_T)(TSL_tMeas_T, TSL_tMeas_T); /**< Pointer to the Measure filter function */
+typedef TSL_tDelta_T(* TSL_pFuncDeltaFilter_T)(TSL_tDelta_T); /**< Pointer to the Delta filter function */
+
+/** Structure containing all data of a Zone.
+ * A Zone is a set of Banks.
+ * Variables of this structure type can be placed in RAM or ROM.
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ TSL_tIndex_T *BankIndex; /**< Pointer to an array of bank indexes */
+ TSL_pFuncDeltaFilter_T *dFilter; /**< Pointer to a Delta filter function */
+ TSL_tNb_T NbBanks; /**< Number of banks in the zone */
+} TSL_Zone_T;
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Exported macros -----------------------------------------------------------*/
+
+/* Exported functions ------------------------------------------------------- */
+TSL_Status_enum_T TSL_acq_ZoneConfig(CONST TSL_Zone_T *zone, TSL_tIndex_T idx_bk);
+TSL_Status_enum_T TSL_acq_BankGetResult(TSL_tIndex_T idx_bk, TSL_pFuncMeasFilter_T mfilter, TSL_pFuncDeltaFilter_T dfilter);
+TSL_Status_enum_T TSL_acq_BankCalibrate(TSL_tIndex_T bank);
+void TSL_acq_BankClearData(TSL_tIndex_T bank);
+
+#endif /* __TSL_ACQ_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f0xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f0xx.h
new file mode 100644
index 0000000..80fc192
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f0xx.h
@@ -0,0 +1,199 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32f0xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions prototypes that manage the TSC
+ * acquisition on STM32F0x products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM32F0XX_H
+#define __TSL_ACQ_STM32F0XX_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f0xx.h"
+#include "tsl_conf_stm32f0xx.h"
+#include "tsl_types.h"
+
+/* Defines -------------------------------------------------------------------*/
+
+#ifndef CONST
+#define CONST const
+#endif
+
+// SysTick enable/disable interrupt macros
+#define enableInterrupts() {SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;}
+#define disableInterrupts() {SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;}
+
+#define TSL_NB_GROUPS (8)
+
+#define TSL_GROUP1 (0x01)
+#define TSL_GROUP2 (0x02)
+#define TSL_GROUP3 (0x04)
+#define TSL_GROUP4 (0x08)
+#define TSL_GROUP5 (0x10)
+#define TSL_GROUP6 (0x20)
+#define TSL_GROUP7 (0x40)
+#define TSL_GROUP8 (0x80)
+
+// GxIOy masks
+#define TSL_GROUP1_IO1 (0x00000001)
+#define TSL_GROUP1_IO2 (0x00000002)
+#define TSL_GROUP1_IO3 (0x00000004)
+#define TSL_GROUP1_IO4 (0x00000008)
+#define TSL_GROUP2_IO1 (0x00000010)
+#define TSL_GROUP2_IO2 (0x00000020)
+#define TSL_GROUP2_IO3 (0x00000040)
+#define TSL_GROUP2_IO4 (0x00000080)
+#define TSL_GROUP3_IO1 (0x00000100)
+#define TSL_GROUP3_IO2 (0x00000200)
+#define TSL_GROUP3_IO3 (0x00000400)
+#define TSL_GROUP3_IO4 (0x00000800)
+#define TSL_GROUP4_IO1 (0x00001000)
+#define TSL_GROUP4_IO2 (0x00002000)
+#define TSL_GROUP4_IO3 (0x00004000)
+#define TSL_GROUP4_IO4 (0x00008000)
+#define TSL_GROUP5_IO1 (0x00010000)
+#define TSL_GROUP5_IO2 (0x00020000)
+#define TSL_GROUP5_IO3 (0x00040000)
+#define TSL_GROUP5_IO4 (0x00080000)
+#define TSL_GROUP6_IO1 (0x00100000)
+#define TSL_GROUP6_IO2 (0x00200000)
+#define TSL_GROUP6_IO3 (0x00400000)
+#define TSL_GROUP6_IO4 (0x00800000)
+#define TSL_GROUP7_IO1 (0x01000000)
+#define TSL_GROUP7_IO2 (0x02000000)
+#define TSL_GROUP7_IO3 (0x04000000)
+#define TSL_GROUP7_IO4 (0x08000000)
+#define TSL_GROUP8_IO1 (0x10000000)
+#define TSL_GROUP8_IO2 (0x20000000)
+#define TSL_GROUP8_IO3 (0x40000000)
+#define TSL_GROUP8_IO4 (0x80000000)
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint16_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint8_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndexDest_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndexSrc_T IdxSrc; /**< Index of TSC->IOGXCR[] registers */
+ // For stm32f0x TSC acquisition only
+ uint32_t msk_IOCCR_channel; /**< Mask of the Channel IO (electrodes ONLY) */
+ uint32_t msk_IOGCSR_group; /**< Mask of the Group used (electrodes ONLY) */
+} TSL_ChannelSrc_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+ unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+ unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+ unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For STM32F0x TSC acquisition only
+ uint32_t msk_IOCCR_channels; /**< Mask of all channel IOs (electrodes AND shields) */
+ uint32_t msk_IOGCSR_groups; /**< Mask of all groups used (electrodes ONLY) */
+} TSL_Bank_T;
+
+/* Exported variables --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+TSL_Status_enum_T TSL_acq_Init(void);
+void TSL_acq_InitGPIOs(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndexSrc_T index);
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas);
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta);
+
+#endif /* __TSL_ACQ_STM32F0XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f3xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f3xx.h
new file mode 100644
index 0000000..945ec4e
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32f3xx.h
@@ -0,0 +1,210 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32f3xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions prototypes that manage the TSC
+ * acquisition on STM32F3xx products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM32F3XX_H
+#define __TSL_ACQ_STM32F3XX_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#if defined(STM32F303xC) || defined(STM32F334x8) || defined(STM32F303x8) || defined(STM32F301x8) || defined(STM32F302x8)
+#include "stm32f30x.h"
+#ifndef STM32F30X
+#define STM32F30X (1)
+#endif
+#endif
+
+#if defined(STM32F37X)
+#include "stm32f37x.h"
+#endif
+
+#include "tsl_conf_stm32f3xx.h"
+#include "tsl_types.h"
+
+/* Defines -------------------------------------------------------------------*/
+
+#ifndef CONST
+#define CONST const
+#endif
+
+// SysTick enable/disable interrupt macros
+#define enableInterrupts() {SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;}
+#define disableInterrupts() {SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;}
+
+#define TSL_NB_GROUPS (8) // Number of groups available on STM32F3xx devices
+
+#define TSL_GROUP1 (0x01)
+#define TSL_GROUP2 (0x02)
+#define TSL_GROUP3 (0x04)
+#define TSL_GROUP4 (0x08)
+#define TSL_GROUP5 (0x10)
+#define TSL_GROUP6 (0x20)
+#define TSL_GROUP7 (0x40)
+#define TSL_GROUP8 (0x80)
+
+// GxIOy masks
+#define TSL_GROUP1_IO1 (0x00000001)
+#define TSL_GROUP1_IO2 (0x00000002)
+#define TSL_GROUP1_IO3 (0x00000004)
+#define TSL_GROUP1_IO4 (0x00000008)
+#define TSL_GROUP2_IO1 (0x00000010)
+#define TSL_GROUP2_IO2 (0x00000020)
+#define TSL_GROUP2_IO3 (0x00000040)
+#define TSL_GROUP2_IO4 (0x00000080)
+#define TSL_GROUP3_IO1 (0x00000100)
+#define TSL_GROUP3_IO2 (0x00000200)
+#define TSL_GROUP3_IO3 (0x00000400)
+#define TSL_GROUP3_IO4 (0x00000800)
+#define TSL_GROUP4_IO1 (0x00001000)
+#define TSL_GROUP4_IO2 (0x00002000)
+#define TSL_GROUP4_IO3 (0x00004000)
+#define TSL_GROUP4_IO4 (0x00008000)
+#define TSL_GROUP5_IO1 (0x00010000)
+#define TSL_GROUP5_IO2 (0x00020000)
+#define TSL_GROUP5_IO3 (0x00040000)
+#define TSL_GROUP5_IO4 (0x00080000)
+#define TSL_GROUP6_IO1 (0x00100000)
+#define TSL_GROUP6_IO2 (0x00200000)
+#define TSL_GROUP6_IO3 (0x00400000)
+#define TSL_GROUP6_IO4 (0x00800000)
+#define TSL_GROUP7_IO1 (0x01000000)
+#define TSL_GROUP7_IO2 (0x02000000)
+#define TSL_GROUP7_IO3 (0x04000000)
+#define TSL_GROUP7_IO4 (0x08000000)
+#define TSL_GROUP8_IO1 (0x10000000)
+#define TSL_GROUP8_IO2 (0x20000000)
+#define TSL_GROUP8_IO3 (0x40000000)
+#define TSL_GROUP8_IO4 (0x80000000)
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint16_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint8_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndexDest_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndexSrc_T IdxSrc; /**< Index of TSC->IOGXCR[] registers */
+ // For STM32F3xx TSC acquisition only
+ uint32_t msk_IOCCR_channel; /**< Mask of the Channel IO (electrodes ONLY) */
+ uint32_t msk_IOGCSR_group; /**< Mask of the Group used (electrodes ONLY) */
+} TSL_ChannelSrc_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+ unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+ unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+ unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For STM32F3xx TSC acquisition only
+ uint32_t msk_IOCCR_channels; /**< Mask of all channel IOs (electrodes AND shields) */
+ uint32_t msk_IOGCSR_groups; /**< Mask of all groups used (electrodes ONLY) */
+} TSL_Bank_T;
+
+/* Exported variables --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+TSL_Status_enum_T TSL_acq_Init(void);
+void TSL_acq_InitGPIOs(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndexSrc_T index);
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas);
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta);
+
+#endif /* __TSL_ACQ_STM32F3XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_hw.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_hw.h
new file mode 100644
index 0000000..f13a943
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_hw.h
@@ -0,0 +1,287 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32l1xx_hw.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_acq_stm32l1xx_hw.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM32L1XX_HW_H
+#define __TSL_ACQ_STM32L1XX_HW_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l1xx.h"
+#include "tsl_conf_stm32l1xx.h"
+#include "tsl_types.h"
+
+/* Defines -------------------------------------------------------------------*/
+
+#ifndef CONST
+#define CONST const
+#endif
+
+// SysTick enable/disable interrupt macros
+#define enableInterrupts() {SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;}
+#define disableInterrupts() {SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;}
+
+/** Groups list
+ */
+enum
+{
+ GR1,
+ GR2,
+ GR3,
+ GR4,
+ GR5,
+ GR6,
+ GR7,
+ GR8,
+ GR9,
+ GR10,
+ GR11
+};
+
+/** GPIOs list
+ High significant nibble for the IO port (GPIOA:0,...,GPIOG:6)
+ Low significant nibble for the IO number (pin0:0,...,pin15:F)
+ */
+enum
+{
+ PA0 = 0x00, /**< TSL_GROUP1_IO1 */
+ PA1 = 0x01,
+ PA2 = 0x02,
+ PA3 = 0x03,
+ PA6 = 0x06, /**< TSL_GROUP2_IO1 */
+ PA7 = 0x07,
+ PA8 = 0x08,
+ PA9 = 0x09,
+ PA10 = 0x0A,
+ PA13 = 0x0D, /**< TSL_GROUP5_IO1 */
+ PA14 = 0x0E,
+ PA15 = 0x0F,
+ PB0 = 0x10, /**< TSL_GROUP3_IO1 */
+ PB1 = 0x11,
+ PB2 = 0x12,
+ PB4 = 0x14, /**< TSL_GROUP6_IO1 */
+ PB5 = 0x15,
+ PB6 = 0x16,
+ PB7 = 0x17,
+ PB12 = 0x1C, /**< TSL_GROUP7_IO1 */
+ PB13 = 0x1D,
+ PB14 = 0x1E,
+ PB15 = 0x1F,
+ PC0 = 0x20, /**< TSL_GROUP8_IO1 */
+ PC1 = 0x21,
+ PC2 = 0x22,
+ PC3 = 0x23,
+ PC4 = 0x24,
+ PC5 = 0x25,
+ PC6 = 0x26,
+ PC7 = 0x27,
+ PC8 = 0x28,
+ PC9 = 0x29,
+ PF6 = 0x56, /**< TSL_GROUP11_IO1 */
+ PF7 = 0x57,
+ PF8 = 0x58,
+ PF9 = 0x59,
+ PF10 = 0x5A,
+ PF11 = 0x5B,
+ PF12 = 0x5C,
+ PF13 = 0x5D,
+ PF14 = 0x5E,
+ PF15 = 0x5F,
+ PG0 = 0x60, /**< TSL_GROUP2_IO4 */
+ PG1 = 0x61,
+ PG2 = 0x62,
+ PG3 = 0x63,
+ PG4 = 0x64
+};
+
+/** GPIOs list:
+ High significant nibble for the IO port (GPIOA:0,...,GPIOG:6)
+ Low significant nibble for the IO number (pin0:0,...,pin15:F)
+ */
+enum
+{
+ TSL_GROUP1_IO1 = 0x00, /**< PA0 */
+ TSL_GROUP1_IO2 = 0x01,
+ TSL_GROUP1_IO3 = 0x02,
+ TSL_GROUP1_IO4 = 0x03,
+ TSL_GROUP2_IO1 = 0x06, /**< PA6 */
+ TSL_GROUP2_IO2 = 0x07,
+ TSL_GROUP4_IO1 = 0x08,
+ TSL_GROUP4_IO2 = 0x09,
+ TSL_GROUP4_IO3 = 0x0A,
+ TSL_GROUP5_IO1 = 0x0D, /**< PA13 */
+ TSL_GROUP5_IO2 = 0x0E,
+ TSL_GROUP5_IO3 = 0x0F,
+ TSL_GROUP3_IO1 = 0x10, /**< PB0 */
+ TSL_GROUP3_IO2 = 0x11,
+ TSL_GROUP3_IO3 = 0x12,
+ TSL_GROUP6_IO1 = 0x14, /**< PB4 */
+ TSL_GROUP6_IO2 = 0x15,
+ TSL_GROUP6_IO3 = 0x16,
+ TSL_GROUP6_IO4 = 0x17,
+ TSL_GROUP7_IO1 = 0x1C, /**< PB12 */
+ TSL_GROUP7_IO2 = 0x1D,
+ TSL_GROUP7_IO3 = 0x1E,
+ TSL_GROUP7_IO4 = 0x1F,
+ TSL_GROUP8_IO1 = 0x20, /**< PC0 */
+ TSL_GROUP8_IO2 = 0x21,
+ TSL_GROUP8_IO3 = 0x22,
+ TSL_GROUP8_IO4 = 0x23,
+ TSL_GROUP9_IO1 = 0x24,
+ TSL_GROUP9_IO2 = 0x25,
+ TSL_GROUP10_IO1 = 0x26,
+ TSL_GROUP10_IO2 = 0x27,
+ TSL_GROUP10_IO3 = 0x28,
+ TSL_GROUP10_IO4 = 0x29,
+ TSL_GROUP11_IO1 = 0x56, /**< PF6 */
+ TSL_GROUP11_IO2 = 0x57,
+ TSL_GROUP11_IO3 = 0x58,
+ TSL_GROUP11_IO4 = 0x59,
+ TSL_GROUP11_IO5 = 0x5A,
+ TSL_GROUP3_IO4 = 0x5B,
+ TSL_GROUP3_IO5 = 0x5C,
+ TSL_GROUP9_IO3 = 0x5D,
+ TSL_GROUP9_IO4 = 0x5E,
+ TSL_GROUP2_IO3 = 0x5F,
+ TSL_GROUP2_IO4 = 0x60, /**< PG0 */
+ TSL_GROUP2_IO5 = 0x61,
+ TSL_GROUP7_IO5 = 0x62,
+ TSL_GROUP7_IO6 = 0x63,
+ TSL_GROUP7_IO7 = 0x64
+};
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint16_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint8_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+typedef uint8_t TSL_Conf_t;
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndex_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndex_T IdxSrc; /**< Index of source value */
+ // For stm32l1x acquisition only
+ TSL_Conf_t t_sample; /**< Indicates which GPIO.n is used for the sample */
+ TSL_Conf_t t_channel; /**< Indicates which GPIO.n is used for the channel */
+} TSL_ChannelSrc_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+ unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+ unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+ unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For stm32l1x acquisition only
+ TSL_Conf_t shield_sample; /**< Indicates which GPIO.n is used for the shield sample */
+ TSL_Conf_t shield_channel; /**< Indicates which GPIO.n is used for the shield channel */
+} TSL_Bank_T;
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Exported macros -----------------------------------------------------------*/
+
+
+/* Exported functions ------------------------------------------------------- */
+
+TSL_Status_enum_T TSL_acq_Init(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+void TSL_acq_ProcessIT(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas);
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+
+#endif // __TSL_ACQ_STM32L1XX_HW_H
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_sw.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_sw.h
new file mode 100644
index 0000000..a410aca
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm32l1xx_sw.h
@@ -0,0 +1,293 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32l1xx_sw.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_acq_stm32l1xx_sw.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM32L1XX_SW_H
+#define __TSL_ACQ_STM32L1XX_SW_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l1xx.h"
+#include "tsl_conf_stm32l1xx.h"
+#include "tsl_types.h"
+
+/* Defines -------------------------------------------------------------------*/
+
+#ifndef CONST
+#define CONST const
+#endif
+
+// SysTick enable/disable interrupt macros
+#define enableInterrupts() {SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;}
+#define disableInterrupts() {SysTick->CTRL &= ~SysTick_CTRL_TICKINT_Msk;}
+
+enum
+{
+ GR1,
+ GR2,
+ GR3,
+ GR4,
+ GR5,
+ GR6,
+ GR7,
+ GR8,
+ GR9,
+ GR10,
+ GR11
+};
+
+enum
+{
+ TSL_BANK_GPIOA = 0,
+ TSL_BANK_GPIOB = 1,
+ TSL_BANK_GPIOC = 2,
+ TSL_BANK_GPIOE = 4,
+ TSL_BANK_GPIOF = 5,
+ TSL_BANK_GPIOG = 6
+};
+
+/** GPIOs list
+ High significant nibble for the IO port (GPIOA:0,...,GPIOG:6)
+ Low significant nibble for the IO number (pin0:0,...,pin15:F)
+ */
+enum
+{
+ PA0 = 0x00, /**< TSL_GROUP1_IO1 */
+ PA1 = 0x01,
+ PA2 = 0x02,
+ PA3 = 0x03,
+ PA6 = 0x06, /**< TSL_GROUP2_IO1 */
+ PA7 = 0x07,
+ PA8 = 0x08,
+ PA9 = 0x09,
+ PA10 = 0x0A,
+ PA13 = 0x0D, /**< TSL_GROUP5_IO1 */
+ PA14 = 0x0E,
+ PA15 = 0x0F,
+ PB0 = 0x10, /**< TSL_GROUP3_IO1 */
+ PB1 = 0x11,
+ PB2 = 0x12,
+ PB4 = 0x14, /**< TSL_GROUP6_IO1 */
+ PB5 = 0x15,
+ PB6 = 0x16,
+ PB7 = 0x17,
+ PB12 = 0x1C, /**< TSL_GROUP7_IO1 */
+ PB13 = 0x1D,
+ PB14 = 0x1E,
+ PB15 = 0x1F,
+ PC0 = 0x20, /**< TSL_GROUP8_IO1 */
+ PC1 = 0x21,
+ PC2 = 0x22,
+ PC3 = 0x23,
+ PC4 = 0x24,
+ PC5 = 0x25,
+ PC6 = 0x26,
+ PC7 = 0x27,
+ PC8 = 0x28,
+ PC9 = 0x29,
+ PF6 = 0x56, /**< TSL_GROUP11_IO1 */
+ PF7 = 0x57,
+ PF8 = 0x58,
+ PF9 = 0x59,
+ PF10 = 0x5A,
+ PF11 = 0x5B,
+ PF12 = 0x5C,
+ PF13 = 0x5D,
+ PF14 = 0x5E,
+ PF15 = 0x5F,
+ PG0 = 0x60, /**< TSL_GROUP2_IO4 */
+ PG1 = 0x61,
+ PG2 = 0x62,
+ PG3 = 0x63,
+ PG4 = 0x64
+};
+
+/** GPIOs list:
+ - High significant nibble for the IO port (GPIOA:0,...,GPIOG:6)
+ - Low significant nibble for the IO number (pin0:0,...,pin15:F)
+ */
+enum
+{
+ TSL_GROUP1_IO1 = 0x00, /**< PA0 */
+ TSL_GROUP1_IO2 = 0x01,
+ TSL_GROUP1_IO3 = 0x02,
+ TSL_GROUP1_IO4 = 0x03,
+ TSL_GROUP2_IO1 = 0x06, /**< PA6 */
+ TSL_GROUP2_IO2 = 0x07,
+ TSL_GROUP4_IO1 = 0x08,
+ TSL_GROUP4_IO2 = 0x09,
+ TSL_GROUP4_IO3 = 0x0A,
+ TSL_GROUP5_IO1 = 0x0D, /**< PA13 */
+ TSL_GROUP5_IO2 = 0x0E,
+ TSL_GROUP5_IO3 = 0x0F,
+ TSL_GROUP3_IO1 = 0x10, /**< PB0 */
+ TSL_GROUP3_IO2 = 0x11,
+ TSL_GROUP3_IO3 = 0x12,
+ TSL_GROUP6_IO1 = 0x14, /**< PB4 */
+ TSL_GROUP6_IO2 = 0x15,
+ TSL_GROUP6_IO3 = 0x16,
+ TSL_GROUP6_IO4 = 0x17,
+ TSL_GROUP7_IO1 = 0x1C, /**< PB12 */
+ TSL_GROUP7_IO2 = 0x1D,
+ TSL_GROUP7_IO3 = 0x1E,
+ TSL_GROUP7_IO4 = 0x1F,
+ TSL_GROUP8_IO1 = 0x20, /**< PC0 */
+ TSL_GROUP8_IO2 = 0x21,
+ TSL_GROUP8_IO3 = 0x22,
+ TSL_GROUP8_IO4 = 0x23,
+ TSL_GROUP9_IO1 = 0x24,
+ TSL_GROUP9_IO2 = 0x25,
+ TSL_GROUP10_IO1 = 0x26,
+ TSL_GROUP10_IO2 = 0x27,
+ TSL_GROUP10_IO3 = 0x28,
+ TSL_GROUP10_IO4 = 0x29,
+ TSL_GROUP11_IO1 = 0x56, /**< PF6 */
+ TSL_GROUP11_IO2 = 0x57,
+ TSL_GROUP11_IO3 = 0x58,
+ TSL_GROUP11_IO4 = 0x59,
+ TSL_GROUP11_IO5 = 0x5A,
+ TSL_GROUP3_IO4 = 0x5B,
+ TSL_GROUP3_IO5 = 0x5C,
+ TSL_GROUP9_IO3 = 0x5D,
+ TSL_GROUP9_IO4 = 0x5E,
+ TSL_GROUP2_IO3 = 0x5F,
+ TSL_GROUP2_IO4 = 0x60, /**< PG0 */
+ TSL_GROUP2_IO5 = 0x61,
+ TSL_GROUP7_IO5 = 0x62,
+ TSL_GROUP7_IO6 = 0x63,
+ TSL_GROUP7_IO7 = 0x64
+};
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint16_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint8_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+typedef uint8_t TSL_Conf_t;
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndex_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndex_T IdxSrc; /**< Index of source value */
+ // For stm32l1x acquisition only
+ TSL_Conf_t t_sample; /**< Indicates which GPIO.n is used for the sample */
+ TSL_Conf_t t_channel; /**< Indicates which GPIO.n is used for the channel */
+} TSL_ChannelSrc_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+ unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+ unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+ unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For stm32l1x acquisition only
+ TSL_Conf_t shield_sample; /**< Indicates which GPIO.n is used for the shield sample */
+ TSL_Conf_t shield_channel; /**< Indicates which GPIO.n is used for the shield channel */
+} TSL_Bank_T;
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+TSL_Status_enum_T TSL_acq_Init(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+void TSL_acq_ProcessIT(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas);
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+
+#endif /* __TSL_ACQ_STM32L1XX_SW_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_hw.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_hw.h
new file mode 100644
index 0000000..b77d867
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_hw.h
@@ -0,0 +1,234 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm8l_hw.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_acq_stm8l_hw.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM8L_HW_H
+#define __TSL_ACQ_STM8L_HW_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm8l15x.h"
+#include "tsl_conf_stm8l.h"
+#include "tsl_types.h"
+
+/* Defines -------------------------------------------------------------------*/
+
+#ifndef CONST
+#define CONST const
+#endif
+
+enum
+{
+ GR1 = 0,
+ GR2,
+ GR3,
+ GR4,
+ GR5,
+ GR6,
+ GR7,
+ GR8
+};
+
+enum
+{
+ TSL_BANK_GPIOA = 0,
+ TSL_BANK_GPIOB,
+ TSL_BANK_GPIOC,
+ TSL_BANK_GPIOD,
+ TSL_BANK_GPIOE
+};
+
+/** GPIOs list:
+ - bits 7:3 GPIO number (0=GPIOA, 1=GPIOB, 2=GPIOC, 3=GPIOD, 4=GPIOE)
+ - bits 2:0 IO number (0=pin0, ..., 7=pin7)
+ */
+
+// GROUP1
+#define PA4 (0x00|0x04) // CH1
+#define PA5 (0x00|0x05) // CH2
+#define PA6 (0x00|0x06) // CH3
+#define PA7 (0x00|0x07) // CH4
+// GROUP2
+#define PC7 (0x10|0x07) // CH1
+#define PC4 (0x10|0x04) // CH2
+#define PC3 (0x10|0x03) // CH3
+#define PE7 (0x20|0x07) // CH4
+// GROUP3
+#define PC2 (0x10|0x02) // CH1
+#define PD7 (0x18|0x07) // CH2
+#define PD6 (0x18|0x06) // CH3
+// GROUP4
+#define PD5 (0x18|0x05) // CH1
+#define PD4 (0x18|0x04) // CH2
+#define PB7 (0x08|0x07) // CH3
+// GROUP5
+#define PB6 (0x08|0x06) // CH1
+#define PB5 (0x08|0x05) // CH2
+#define PB4 (0x08|0x04) // CH3
+// GROUP6
+#define PB3 (0x08|0x03) // CH1
+#define PB2 (0x08|0x02) // CH2
+#define PB1 (0x08|0x01) // CH3
+// GROUP7
+#define PB0 (0x08|0x00) // CH1
+#define PD3 (0x18|0x03) // CH2
+#define PD2 (0x18|0x02) // CH3
+#define PE3 (0x20|0x03) // CH4
+// GROUP8
+#define PD1 (0x18|0x01) // CH1
+#define PD0 (0x18|0x00) // CH2
+#define PE5 (0x20|0x05) // CH3
+#define PE4 (0x20|0x04) // CH4
+
+// Acquisition pulses period
+/** Master timer reload value for HW acquisition only (range=4..65534, even number)
+ --> Period for Charge/Transfer cycle = ((TSLPRM_TIM_RELOAD*2)/FTimer)
+*/
+#define TIM_RELOAD ((TSLPRM_CT_PERIOD * TSLPRM_TIMER_FREQ) / 2)
+#define TIM2_PWM_CH1_WIDTH ((TIM_RELOAD / 2) - 1) // Configure channel 1 Pulse Width
+#define TIM2_PWM_CH2_WIDTH ((TIM_RELOAD / 2) + 1) // Configure channel 2 Pulse Width
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint8_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint16_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+typedef uint8_t TSL_Conf_T;
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndexDest_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndex_T IdxSrc; /**< Index of source value */
+ // For stm8l acquisition only
+ TSL_Conf_T sampling; /**< Indicates which GPIO.n is used for the sample */
+ TSL_Conf_T channel; /**< Indicates which GPIO.n is used for the channel */
+} TSL_ChannelSrc_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For stm8l acquisition only
+ TSL_Conf_T shield_sampling; /**< Indicates which GPIO.n is used for the shield sample */
+ TSL_Conf_T shield_channel; /**< Indicates which GPIO.n is used for the shield channel */
+} TSL_Bank_T;
+
+/** Bank Config Mask
+ */
+typedef struct
+{
+ uint8_t ch1; /**< Contains the mask for all first channel of group */
+ uint8_t ch2; /**< Contains the mask for all second channel of group */
+ uint8_t ch3; /**< Contains the mask for all third channel of group */
+ uint8_t ch4; /**< Contains the mask for all fourth channel of group (if LD device)*/
+} TSL_Bank_Config_Mask_T;
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+TSL_Status_enum_T TSL_acq_Init(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+void TSL_CT_HWacq_TIM3(void);
+void TSL_CT_HWacq_RI(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas);
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+
+#endif /* __TSL_ACQ_STM8L_HW_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_sw.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_sw.h
new file mode 100644
index 0000000..7ac57de
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8l_sw.h
@@ -0,0 +1,275 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm8l_sw.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_acq_stm8l_sw.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM8L_SW_H
+#define __TSL_ACQ_STM8L_SW_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#if defined(STM8L15X_LD) || defined(STM8L15X_MD) || defined(STM8L15X_MDP) || defined(STM8L15X_HD)
+#include "stm8l15x.h"
+#endif
+
+#if defined(STM8L10X)
+#include "stm8l10x.h"
+#endif
+
+#include "tsl_conf_stm8l.h"
+#include "tsl_types.h"
+
+/* Defines -------------------------------------------------------------------*/
+
+#ifndef CONST
+#define CONST const
+#endif
+
+#if !defined(STM8L10X)
+
+enum
+{
+ GR1 = 0,
+ GR2,
+ GR3,
+ GR4,
+ GR5,
+ GR6,
+ GR7,
+ GR8
+};
+
+/** GPIOs list:
+ - bits 7:3 GPIO number (0=GPIOA, 1=GPIOB, 2=GPIOC, 3=GPIOD, 4=GPIOE)
+ - bits 2:0 IO number (0=pin0, ..., 7=pin7)
+ */
+
+// GROUP1
+#define PA4 (0x00|0x04) // CH1
+#define PA5 (0x00|0x05) // CH2
+#define PA6 (0x00|0x06) // CH3
+#ifdef STM8L15X_LD
+#define PA7 (0x00|0x07) // CH4
+#endif
+// GROUP2
+#define PC7 (0x10|0x07) // CH1
+#define PC4 (0x10|0x04) // CH2
+#define PC3 (0x10|0x03) // CH3
+#ifdef STM8L15X_LD
+#define PE7 (0x20|0x07) // CH4
+#endif
+// GROUP3
+#define PC2 (0x10|0x02) // CH1
+#define PD7 (0x18|0x07) // CH2
+#define PD6 (0x18|0x06) // CH3
+// GROUP4
+#define PD5 (0x18|0x05) // CH1
+#define PD4 (0x18|0x04) // CH2
+#define PB7 (0x08|0x07) // CH3
+// GROUP5
+#define PB6 (0x08|0x06) // CH1
+#define PB5 (0x08|0x05) // CH2
+#define PB4 (0x08|0x04) // CH3
+// GROUP6
+#define PB3 (0x08|0x03) // CH1
+#define PB2 (0x08|0x02) // CH2
+#define PB1 (0x08|0x01) // CH3
+// GROUP7
+#define PB0 (0x08|0x00) // CH1
+#define PD3 (0x18|0x03) // CH2
+#define PD2 (0x18|0x02) // CH3
+#ifdef STM8L15X_LD
+#define PE3 (0x20|0x03) // CH4
+#endif
+// GROUP8
+#define PD1 (0x18|0x01) // CH1
+#define PD0 (0x18|0x00) // CH2
+#define PE5 (0x20|0x05) // CH3
+#ifdef STM8L15X_LD
+#define PE4 (0x20|0x04) // CH4
+#endif
+
+#else // STM8L10X
+
+enum
+{
+ GR1 = 0,
+ GR2
+};
+
+/** GPIOs list:
+ - bits 7:2 GPIO number (0=GPIOB, 1=GPIOD)
+ - bits 1:0 IO number (0=pin0, ..., 3=pin3)
+ */
+// GROUP1
+#define PB0 (0x00|0x00) // CH1
+#define PB1 (0x00|0x01) // CH2
+#define PD0 (0x04|0x00) // CH3
+#define PD1 (0x04|0x01) // CH4
+// GROUP2
+#define PB2 (0x00|0x02) // CH1
+#define PB3 (0x00|0x03) // CH2
+#define PD2 (0x04|0x02) // CH3
+#define PD3 (0x04|0x03) // CH4
+
+#endif // !defined(STM8L10X)
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint8_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint16_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+typedef uint8_t TSL_Conf_T;
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndexDest_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndex_T IdxSrc; /**< Index of source value */
+ // For stm8l acquisition only
+ TSL_Conf_T sampling; /**< Indicates which GPIO.n is used for the sample */
+ TSL_Conf_T channel; /**< Indicates which GPIO.n is used for the channel */
+} TSL_ChannelSrc_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For stm8l acquisition only
+ TSL_Conf_T shield_sampling; /**< Indicates which GPIO.n is used for the shield sample */
+ TSL_Conf_T shield_channel; /**< Indicates which GPIO.n is used for the shield channel */
+} TSL_Bank_T;
+
+#if !defined(STM8L10X)
+
+/** Bank Config Mask
+ */
+typedef struct
+{
+ uint8_t ch1; /**< Contains the mask for all first channel of group */
+ uint8_t ch2; /**< Contains the mask for all second channel of group */
+ uint8_t ch3; /**< Contains the mask for all third channel of group */
+ uint8_t ch4; /**< Contains the mask for all fourth channel of group (if LD device)*/
+} TSL_Bank_Config_Mask_T;
+
+#else // STM8L10X
+
+/** Bank Config Mask
+ */
+typedef struct
+{
+ uint8_t GPIOB_IO; /**< Contains the mask for all first channel of group */
+ uint8_t GPIOB_Samp; /**< Contains the mask for all second channel of group */
+ uint8_t GPIOD_IO; /**< Contains the mask for all third channel of group */
+ uint8_t GPIOD_Samp; /**< Contains the mask for all fourth channel of group (if LD device)*/
+} TSL_Bank_Config_Mask_T;
+
+#endif // !defined(STM8L10X)
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Exported macros -----------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+TSL_Status_enum_T TSL_acq_Init(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+void TSL_acq_ProcessIT(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas);
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+
+#endif /* __TSL_ACQ_STM8L_SW_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8tl5x.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8tl5x.h
new file mode 100644
index 0000000..31318b3
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_acq_stm8tl5x.h
@@ -0,0 +1,270 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm8tl5x.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions prototypes that manage the TSC
+ * acquisition on STM8TL5x products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ACQ_STM8TL5X_H
+#define __TSL_ACQ_STM8TL5X_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm8tl5x.h"
+#include "tsl_conf_stm8tl5x.h"
+#include "tsl_types.h"
+
+/*==============================================================================
+
+ *** RECEIVERS AND TRANSMITTERS DESCRIPTION ***
+
+ ProxSense receiver and transmitter description for STM8TL5x
+ For more details please refer to the Proxsense
+ section in the reference manual
+
+
+ Txi
+ Group Ai Rx0a __/____ |
+ Rx1a __/____ |
+ Rx2a __/____ |
+ Rx3a __/____ |
+ Rx4a __/____ |
+ Rx5a __/____ |
+ Rx6a __/____ |
+ Rx7a __/____ |
+ Rx8a __/____ |
+ Rx9a __/____ |
+
+ Group Bi Rx0b __/____ |
+ Rx1b __/____ |
+ Rx2b __/____ |
+ Rx3b __/____ |
+ Rx4b __/____ |
+ Rx5b __/____ |
+ Rx6b __/____ |
+ Rx7b __/____ |
+ Rx8b __/____ |
+ Rx9b __/____ |
+
+==============================================================================*/
+
+/* Defines -------------------------------------------------------------------*/
+
+// Receivers
+#define RX0 (0+0x8000)
+#define RX1 (1+0x8000)
+#define RX2 (2+0x8000)
+#define RX3 (3+0x8000)
+#define RX4 (4+0x8000)
+#define RX5 (5+0x8000)
+#define RX6 (6+0x8000)
+#define RX7 (7+0x8000)
+#define RX8 (8+0x8000)
+#define RX9 (9+0x8000)
+
+// Transmitters
+#define TX0 (0)
+#define TX1 (1)
+#define TX2 (2)
+#define TX3 (3)
+#define TX4 (4)
+#define TX5 (5)
+#define TX6 (6)
+#define TX7 (7)
+#define TX8 (8)
+#define TX9 (9)
+#define TX10 (10)
+#define TX11 (11)
+#define TX12 (12)
+#define TX13 (13)
+#define TX14 (14)
+
+#define BIT_MASK_RX(N) ((uint16_t)1<<(uint8_t)(N & 0xFF))
+#define BIT_MASK_TX(N) ((uint16_t)1<< N)
+
+// Acquisition Bank
+#define BANK01 1
+#define BANK02 2
+#define BANK03 3
+#define BANK04 4
+#define BANK05 5
+#define BANK06 6
+#define BANK07 7
+#define BANK08 8
+#define BANK09 9
+#define BANK10 10
+#define BANK11 11
+#define BANK12 12
+#define BANK13 13
+#define BANK14 14
+#define BANK15 15
+#define BANK16 16
+#define BANK17 17
+#define BANK18 18
+#define BANK19 19
+#define BANK20 20
+#define BANK21 21
+#define BANK22 22
+#define BANK23 23
+#define BANK24 24
+#define BANK25 25
+#define BANK26 26
+#define BANK27 27
+#define BANK28 28
+#define BANK29 29
+#define BANK30 30
+
+/* Exported types ------------------------------------------------------------*/
+
+// For all devices/acquisitions
+
+typedef uint16_t TSL_tMeas_T; /**< Measurement */
+typedef uint16_t TSL_tRef_T; /**< Reference */
+typedef int16_t TSL_tDelta_T; /**< Delta */
+
+typedef uint8_t TSL_tIndexSrc_T; /**< Channel source index */
+typedef uint16_t TSL_tIndexDest_T; /**< Channel destination index */
+
+typedef uint8_t TSL_tRefRest_T; /**< Reference Rest (ECS) */
+typedef uint16_t TSL_tKCoeff_T; /**< K coefficient (ECS) */
+
+typedef uint8_t TSL_tIndex_T; /**< Generic index */
+typedef uint16_t TSL_tNb_T; /**< Generic number */
+typedef uint8_t TSL_tCounter_T; /**< Generic counter used for debounce */
+
+typedef uint8_t TSL_tThreshold_T; /**< Delta threshold */
+
+typedef int16_t TSL_tsignPosition_T; /**< Linear and Rotary sensors position */
+typedef uint8_t TSL_tPosition_T; /**< Linear and Rotary sensors position */
+
+typedef uint16_t TSL_tTick_ms_T; /**< Time in ms */
+typedef uint8_t TSL_tTick_sec_T; /**< Time in sec */
+
+// For STM8TL5X only
+
+typedef uint16_t TSL_tMaskRX; /**< Receiver mask */
+typedef uint16_t TSL_tMaskTX; /**< Transmitter mask */
+
+//------------------------------------------------------------------------------
+// Channel
+//------------------------------------------------------------------------------
+
+/** Channel destination index
+ */
+typedef struct
+{
+ TSL_tIndexDest_T IdxDest; /**< Index in the Channel data array */
+} TSL_ChannelDest_T;
+
+/** Channel Source and Configuration
+ */
+typedef struct
+{
+ TSL_tIndexSrc_T IdxSrc; /**< Index of the receivers (between 0 and 9) */
+} TSL_ChannelSrc_T;
+
+#define TSL_EPCC_CHANGE_MASK (0x04) /**< EPCC change mask */
+
+/** EPCC status
+ */
+typedef enum
+{
+ TSL_EPCC_STATUS_UNLOCKED = 0, /**< EPCC is unlocked */
+ TSL_EPCC_STATUS_LOCKED = 1, /**< EPCC is locked */
+ TSL_EPCC_STATUS_DECREASE = 4, /**< EPCC must decreased */
+ TSL_EPCC_STATUS_INCREASE = 6 /**< EPCC must be increased */
+} TSL_EPCCStatus_enum_T;
+
+/** Channel flags
+ */
+typedef struct
+{
+ unsigned int DataReady : 1; /**< To identify a new measurement (TSL_DataReady_enum_T) */
+ unsigned int AcqStatus : 2; /**< Acquisition status (TSL_AcqStatus_enum_T) */
+ unsigned int EPCCStatus : 3; /**< Acquisition status (TSL_EPCCStatus_enum_T) */
+ unsigned int ObjStatus : 2; /**< Object status (TSL_ObjStatus_enum_T) */
+} TSL_ChannelFlags_T;
+
+/** Channel Data
+ */
+typedef struct
+{
+ TSL_ChannelFlags_T Flags; /**< Flags */
+ TSL_tRef_T Ref; /**< Reference */
+ TSL_tRefRest_T RefRest; /**< Reference rest for ECS */
+ TSL_tDelta_T Delta; /**< Delta */
+#if TSLPRM_USE_MEAS > 0
+ TSL_tMeas_T Meas; /**< Hold the last acquisition measure */
+#endif
+} TSL_ChannelData_T;
+
+//------------------------------------------------------------------------------
+// Bank
+//------------------------------------------------------------------------------
+
+/** Bank
+ */
+typedef struct
+{
+ // Common to all acquisitions
+ CONST TSL_ChannelSrc_T *p_chSrc; /**< Pointer to the Channel Source and Configuration */
+ CONST TSL_ChannelDest_T *p_chDest; /**< Pointer to the Channel Destination */
+ TSL_ChannelData_T *p_chData; /**< Pointer to the Channel Data */
+ TSL_tNb_T NbChannels; /**< Number of channels in the bank */
+ // For stm8tl5x PXS acquisition only
+ TSL_tMaskRX msk_channels; /**< Mask of all receivers */
+ TSL_tMaskTX msk_TX; /**< Mask of Tx */
+ uint8_t msk_group; /**< Mask of group used (RX_GROUPA or RX_GROUPB) */
+ TSL_tMaskRX msk_RXEN; /**< Mask of all RX (receivers and transmitters) */
+} TSL_Bank_T;
+
+/** Bank Configuration
+ */
+typedef struct
+{
+ uint8_t CSSEL[TSLPRM_HIGH_CHANNEL_NB+1]; /**< Array of CS values */
+ uint8_t EPCCSEL[TSLPRM_HIGH_CHANNEL_NB+1]; /**< Array of EPCC values */
+} TSL_BankConfig_T;
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Exported macros -----------------------------------------------------------*/
+#define TSL_acq_ComputeDelta(Reference,Measure) (TSL_tDelta_T)(Measure - Reference) /**< Calculate the Delta */
+#define TSL_acq_ComputeMeas(Reference,Delta) (TSL_tMeas_T)(Delta + Reference) /**< Calculate the Measure */
+
+/* Exported functions ------------------------------------------------------- */
+TSL_Status_enum_T TSL_acq_Init(void);
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk);
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh);
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas);
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh);
+void TSL_acq_BankStartAcq(void);
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void);
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void);
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndexSrc_T index);
+void TSL_acq_UpdateCS(uint8_t *pCSSEL, TSL_EPCCStatus_enum_T change);
+
+#endif /* __TSL_ACQ_STM8TL5X_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config.h
new file mode 100644
index 0000000..836c3e6
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config.h
@@ -0,0 +1,451 @@
+/**
+ ******************************************************************************
+ * @file tsl_check_config.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the check of all parameters defined in the
+ * common configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CHECK_CONFIG_H
+#define __TSL_CHECK_CONFIG_H
+
+//==============================================================================
+// Common parameters check
+//==============================================================================
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TOTAL_CHANNELS
+#error "TSLPRM_TOTAL_CHANNELS is not defined."
+#endif
+
+#ifndef TSLPRM_TOTAL_BANKS
+#error "TSLPRM_TOTAL_BANKS is not defined."
+#endif
+
+#ifndef TSLPRM_TOTAL_TOUCHKEYS
+#error "TSLPRM_TOTAL_TOUCHKEYS is not defined."
+#endif
+
+#ifndef TSLPRM_TOTAL_TOUCHKEYS_B
+#error "TSLPRM_TOTAL_TOUCHKEYS_B is not defined."
+#endif
+
+#ifndef TSLPRM_TOTAL_LINROTS
+#error "TSLPRM_TOTAL_LINROTS is not defined."
+#endif
+
+#ifndef TSLPRM_TOTAL_LINROTS_B
+#error "TSLPRM_TOTAL_LINROTS_B is not defined."
+#endif
+
+#ifndef TSLPRM_TOTAL_OBJECTS
+#error "TSLPRM_TOTAL_OBJECTS is not defined."
+#endif
+
+#define TSLPRM_TOTAL_TKEYS (TSLPRM_TOTAL_TOUCHKEYS + TSLPRM_TOTAL_TOUCHKEYS_B)
+#define TSLPRM_TOTAL_LNRTS (TSLPRM_TOTAL_LINROTS + TSLPRM_TOTAL_LINROTS_B)
+
+#if ((TSLPRM_TOTAL_TKEYS == 0) && (TSLPRM_TOTAL_LNRTS == 0))
+#error "No TouchKey and No Linear/Rotary sensors are defined."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_CALIB_SAMPLES
+#error "TSLPRM_CALIB_SAMPLES is not defined."
+#endif
+
+#if ((TSLPRM_CALIB_SAMPLES != 4) && (TSLPRM_CALIB_SAMPLES != 8) && (TSLPRM_CALIB_SAMPLES != 16))
+#error "TSLPRM_CALIB_SAMPLES is out of range (4, 8, 16)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_CALIB_DELAY
+#error "TSLPRM_CALIB_DELAY is not defined."
+#endif
+
+#if ((TSLPRM_CALIB_DELAY < 0) || (TSLPRM_CALIB_DELAY > 40))
+#error "TSLPRM_CALIB_DELAY is out of range (0..40)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_ACQ_MIN
+#error "TSLPRM_ACQ_MIN is not defined."
+#endif
+
+#ifndef TSLPRM_ACQ_MAX
+#error "TSLPRM_ACQ_MAX is not defined."
+#endif
+
+#if ((TSLPRM_ACQ_MIN < 1) || (TSLPRM_ACQ_MIN > (TSLPRM_ACQ_MAX-1)))
+#error "TSLPRM_ACQ_MIN is out of range (1 .. ACQ_MAX-1)."
+#endif
+
+#if ((TSLPRM_ACQ_MAX < (TSLPRM_ACQ_MIN+1)) || (TSLPRM_ACQ_MAX > 50000))
+#error "TSLPRM_ACQ_MAX is out of range (ACQ_MIN+1 .. 50000)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TKEY_PROX_IN_TH
+#error "TSLPRM_TKEY_PROX_IN_TH is not defined."
+#endif
+
+#ifndef TSLPRM_TKEY_PROX_OUT_TH
+#error "TSLPRM_TKEY_PROX_OUT_TH is not defined."
+#endif
+
+#if ((TSLPRM_TKEY_PROX_OUT_TH < 0) || (TSLPRM_TKEY_PROX_OUT_TH > (TSLPRM_TKEY_PROX_IN_TH-1)))
+#error "TSLPRM_TKEY_PROX_OUT_TH is out of range (0 .. TSLPRM_TKEY_PROX_IN_TH-1)."
+#endif
+
+#if TSLPRM_COEFF_TH == 0
+#if ((TSLPRM_TKEY_PROX_IN_TH < (TSLPRM_TKEY_PROX_OUT_TH+1)) || (TSLPRM_TKEY_PROX_IN_TH > (TSLPRM_TKEY_DETECT_OUT_TH-1)))
+#error "TSLPRM_TKEY_PROX_IN_TH is out of range (TSLPRM_TKEY_PROX_OUT_TH+1 .. TSLPRM_TKEY_DETECT_OUT_TH-1)."
+#endif
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_PROX_IN_TH
+#error "TSLPRM_LINROT_PROX_IN_TH is not defined."
+#endif
+
+#ifndef TSLPRM_LINROT_PROX_OUT_TH
+#error "TSLPRM_LINROT_PROX_OUT_TH is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_PROX_OUT_TH < 0) || (TSLPRM_LINROT_PROX_OUT_TH > (TSLPRM_LINROT_PROX_IN_TH-1)))
+#error "TSLPRM_LINROT_PROX_OUT_TH is out of range (0 .. TSLPRM_LINROT_PROX_IN_TH-1)."
+#endif
+
+#if TSLPRM_COEFF_TH == 0
+#if ((TSLPRM_LINROT_PROX_IN_TH < (TSLPRM_LINROT_PROX_OUT_TH+1)) || (TSLPRM_LINROT_PROX_IN_TH > (TSLPRM_LINROT_DETECT_OUT_TH-1)))
+#error "TSLPRM_LINROT_PROX_IN_TH is out of range (TSLPRM_LINROT_PROX_OUT_TH+1 .. TSLPRM_LINROT_DETECT_OUT_TH-1)."
+#endif
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TKEY_DETECT_IN_TH
+#error "TSLPRM_TKEY_DETECT_IN_TH is not defined."
+#endif
+
+#ifndef TSLPRM_TKEY_DETECT_OUT_TH
+#error "TSLPRM_TKEY_DETECT_OUT_TH is not defined."
+#endif
+
+#if TSLPRM_COEFF_TH == 0
+#if ((TSLPRM_TKEY_DETECT_OUT_TH < (TSLPRM_TKEY_PROX_IN_TH+1)) || (TSLPRM_TKEY_DETECT_OUT_TH > (TSLPRM_TKEY_DETECT_IN_TH-1)))
+#error "TSLPRM_TKEY_DETECT_OUT_TH is out of range (TSLPRM_TKEY_PROX_IN_TH+1 .. TSLPRM_TKEY_DETECT_IN_TH-1)."
+#endif
+#endif
+
+#if ((TSLPRM_TKEY_DETECT_IN_TH < (TSLPRM_TKEY_DETECT_OUT_TH+1)) || (TSLPRM_TKEY_DETECT_IN_TH > 255))
+#error "TSLPRM_TKEY_DETECT_IN_TH is out of range (TSLPRM_TKEY_DETECT_OUT_TH+1 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_DETECT_IN_TH
+#error "TSLPRM_LINROT_DETECT_IN_TH is not defined."
+#endif
+
+#ifndef TSLPRM_LINROT_DETECT_OUT_TH
+#error "TSLPRM_LINROT_DETECT_OUT_TH is not defined."
+#endif
+
+#if TSLPRM_COEFF_TH == 0
+#if ((TSLPRM_LINROT_DETECT_OUT_TH < (TSLPRM_LINROT_PROX_IN_TH+1)) || (TSLPRM_LINROT_DETECT_OUT_TH > (TSLPRM_LINROT_DETECT_IN_TH-1)))
+#error "TSLPRM_LINROT_DETECT_OUT_TH is out of range (TSLPRM_LINROT_PROX_IN_TH+1 .. TSLPRM_LINROT_DETECT_IN_TH-1)."
+#endif
+#endif
+
+#if ((TSLPRM_LINROT_DETECT_IN_TH < (TSLPRM_LINROT_DETECT_OUT_TH+1)) || (TSLPRM_LINROT_DETECT_IN_TH > 255))
+#error "TSLPRM_LINROT_DETECT_IN_TH is out of range (TSLPRM_LINROT_DETECT_OUT_TH+1 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TKEY_CALIB_TH
+#error "TSLPRM_TKEY_CALIB_TH is not defined."
+#endif
+
+#if ((TSLPRM_TKEY_CALIB_TH < 0) || (TSLPRM_TKEY_CALIB_TH > 255))
+#error "TSLPRM_TKEY_CALIB_TH is out of range (0 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_CALIB_TH
+#error "TSLPRM_LINROT_CALIB_TH is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_CALIB_TH < 0) || (TSLPRM_LINROT_CALIB_TH > 255))
+#error "TSLPRM_LINROT_CALIB_TH is out of range (0 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_USE_NORMDELTA
+#error "TSLPRM_LINROT_USE_NORMDELTA is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_USE_NORMDELTA < 0) || (TSLPRM_LINROT_USE_NORMDELTA > 1))
+#error "TSLPRM_LINROT_USE_NORMDELTA is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_COEFF_TH
+#error "TSLPRM_COEFF_TH is not defined."
+#endif
+
+#if ((TSLPRM_COEFF_TH < 0) || (TSLPRM_COEFF_TH > 4))
+#error "TSLPRM_COEFF_TH is out of range (0 .. 4)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_DIR_CHG_POS
+#error "TSLPRM_LINROT_DIR_CHG_POS is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_DIR_CHG_POS < 0) || (TSLPRM_LINROT_DIR_CHG_POS > 255))
+#error "TSLPRM_LINROT_DIR_CHG_POS is out of range (0 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_RESOLUTION
+#error "TSLPRM_LINROT_RESOLUTION is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_RESOLUTION < 1) || (TSLPRM_LINROT_RESOLUTION > 8))
+#error "TSLPRM_LINROT_RESOLUTION is out of range (1 .. 8)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DEBOUNCE_PROX
+#error "TSLPRM_DEBOUNCE_PROX is not defined."
+#endif
+
+#if ((TSLPRM_DEBOUNCE_PROX < 0) || (TSLPRM_DEBOUNCE_PROX > 63))
+#error "TSLPRM_DEBOUNCE_PROX is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DEBOUNCE_DETECT
+#error "TSLPRM_DEBOUNCE_DETECT is not defined."
+#endif
+
+#if ((TSLPRM_DEBOUNCE_DETECT < 0) || (TSLPRM_DEBOUNCE_DETECT > 63))
+#error "TSLPRM_DEBOUNCE_DETECT is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DEBOUNCE_RELEASE
+#error "TSLPRM_DEBOUNCE_RELEASE is not defined."
+#endif
+
+#if ((TSLPRM_DEBOUNCE_RELEASE < 0) || (TSLPRM_DEBOUNCE_RELEASE > 63))
+#error "TSLPRM_DEBOUNCE_RELEASE is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DEBOUNCE_CALIB
+#error "TSLPRM_DEBOUNCE_CALIB is not defined."
+#endif
+
+#if ((TSLPRM_DEBOUNCE_CALIB < 0) || (TSLPRM_DEBOUNCE_CALIB > 63))
+#error "TSLPRM_DEBOUNCE_CALIB is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DEBOUNCE_ERROR
+#error "TSLPRM_DEBOUNCE_ERROR is not defined."
+#endif
+
+#if ((TSLPRM_DEBOUNCE_ERROR < 0) || (TSLPRM_DEBOUNCE_ERROR > 63))
+#error "TSLPRM_DEBOUNCE_ERROR is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_DIR_CHG_DEB
+#error "TSLPRM_LINROT_DIR_CHG_DEB is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_DIR_CHG_DEB < 0) || (TSLPRM_LINROT_DIR_CHG_DEB > 63))
+#error "TSLPRM_LINROT_DIR_CHG_DEB is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_ECS_K_SLOW
+#error "TSLPRM_ECS_K_SLOW is not defined."
+#endif
+
+#if ((TSLPRM_ECS_K_SLOW < 0) || (TSLPRM_ECS_K_SLOW > 255))
+#error "TSLPRM_ECS_K_SLOW is out of range (0 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_ECS_K_FAST
+#error "TSLPRM_ECS_K_FAST is not defined."
+#endif
+
+#if ((TSLPRM_ECS_K_FAST < 0) || (TSLPRM_ECS_K_FAST > 255))
+#error "TSLPRM_ECS_K_FAST is out of range (0 .. 255)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_ECS_DELAY
+#error "TSLPRM_ECS_DELAY is not defined."
+#endif
+
+#if ((TSLPRM_ECS_DELAY < 0) || (TSLPRM_ECS_DELAY > 5000))
+#error "TSLPRM_ECS_DELAY is out of range (0 .. 5000)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_MEAS
+#error "TSLPRM_USE_MEAS is not defined."
+#endif
+
+#if ((TSLPRM_USE_MEAS != 0) && (TSLPRM_USE_MEAS != 1))
+#error "TSLPRM_USE_MEAS is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_PROX
+#error "TSLPRM_USE_PROX is not defined."
+#endif
+
+#if ((TSLPRM_USE_PROX != 0) && (TSLPRM_USE_PROX != 1))
+#error "TSLPRM_USE_PROX is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_ZONE
+#error "TSLPRM_USE_ZONE is not defined."
+#endif
+
+#if ((TSLPRM_USE_ZONE != 0) && (TSLPRM_USE_ZONE != 1))
+#error "TSLPRM_USE_ZONE is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_ACQ_INTERRUPT
+#error "TSLPRM_USE_ACQ_INTERRUPT is not defined."
+#endif
+
+#if ((TSLPRM_USE_ACQ_INTERRUPT != 0) && (TSLPRM_USE_ACQ_INTERRUPT != 1))
+#error "TSLPRM_USE_ACQ_INTERRUPT is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DTO
+#error "TSLPRM_DTO is not defined."
+#endif
+
+#if ((TSLPRM_DTO < 0) || (TSLPRM_DTO > 63))
+#error "TSLPRM_DTO is out of range (0 .. 63)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TICK_FREQ
+#error "TSLPRM_TICK_FREQ is not defined."
+#endif
+
+#if ((TSLPRM_TICK_FREQ != 125) && (TSLPRM_TICK_FREQ != 250) && (TSLPRM_TICK_FREQ != 500) &&\
+ (TSLPRM_TICK_FREQ != 1000) && (TSLPRM_TICK_FREQ != 2000))
+#error "TSLPRM_TICK_FREQ is out of range (125, 250, 500, 1000, 2000)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_DXS
+#error "TSLPRM_USE_DXS is not defined."
+#endif
+
+#if ((TSLPRM_USE_DXS < 0) || (TSLPRM_USE_DXS > 1))
+#error "TSLPRM_USE_DXS is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_TIMER_CALLBACK
+#error "TSLPRM_USE_TIMER_CALLBACK is not defined."
+#endif
+
+#if ((TSLPRM_USE_TIMER_CALLBACK != 0) && (TSLPRM_USE_TIMER_CALLBACK != 1))
+#error "TSLPRM_USE_TIMER_CALLBACK is out of range (0 .. 1)."
+#endif
+
+//==============================================================================
+// Specific parameters check
+//==============================================================================
+
+#if defined(STM8L10X) || defined(STM8L15X_LD) || defined(STM8L15X_MD) || defined(STM8L15X_MDP) || defined(STM8L15X_HD)
+#include "tsl_check_config_stm8l.h"
+#endif
+
+#if defined(STM8TL5X)
+#include "tsl_check_config_stm8tl5x.h"
+#endif
+
+#if defined(STM32L1XX_MD) || defined(STM32L1XX_MDP) || defined(STM32L1XX_HD) || defined(STM32L1XX_XL)
+#include "tsl_check_config_stm32l1xx.h"
+#endif
+
+#if defined(STM32F0XX) || defined(STM32F0XX_MD) || defined(STM32F0XX_HD) ||\
+ defined(STM32F051) || defined(STM32F072) || defined(STM32F042)
+#include "tsl_check_config_stm32f0xx.h"
+#endif
+
+#if defined(STM32F303xC) || defined(STM32F334x8) || defined(STM32F303x8) || defined(STM32F301x8) || defined(STM32F302x8) ||\
+ defined(STM32F37X)
+#include "tsl_check_config_stm32f3xx.h"
+#endif
+
+#endif /* __TSL_CHECK_CONFIG_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f0xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f0xx.h
new file mode 100644
index 0000000..661f41f
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f0xx.h
@@ -0,0 +1,245 @@
+/**
+ ******************************************************************************
+ * @file tsl_check_config_stm32f0xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the check of all parameters defined in the
+ * STM32F0XX configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CHECK_CONFIG_STM32F0XX_H
+#define __TSL_CHECK_CONFIG_STM32F0XX_H
+
+//------------------------------------------------------------------------------
+
+#if ((TSLPRM_TOTAL_CHANNELS < 1) || (TSLPRM_TOTAL_CHANNELS > 24))
+#error "TSLPRM_TOTAL_CHANNELS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_BANKS < 1) || (TSLPRM_TOTAL_BANKS > 8))
+#error "TSLPRM_TOTAL_BANKS is out of range (1 .. 8)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS < 0) || (TSLPRM_TOTAL_TOUCHKEYS > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS_B < 0) || (TSLPRM_TOTAL_TOUCHKEYS_B > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS < 0) || (TSLPRM_TOTAL_LINROTS > 24))
+#error "TSLPRM_TOTAL_LINROTS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS_B < 0) || (TSLPRM_TOTAL_LINROTS_B > 24))
+#error "TSLPRM_TOTAL_LINROTS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_OBJECTS < 1) || (TSLPRM_TOTAL_OBJECTS > 24))
+#error "TSLPRM_TOTAL_OBJECTS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TKEYS + TSLPRM_TOTAL_LNRTS) > 24)
+#error "The Sum of TouchKeys and Linear/Rotary sensors exceeds 24."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_GPIO_CONFIG
+#error "TSLPRM_TSC_GPIO_CONFIG is not defined."
+#endif
+
+#if ((TSLPRM_TSC_GPIO_CONFIG < 0) || (TSLPRM_TSC_GPIO_CONFIG > 1))
+#error "TSLPRM_TSC_GPIO_CONFIG is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_CTPH
+#error "TSLPRM_TSC_CTPH is not defined."
+#endif
+
+#if ((TSLPRM_TSC_CTPH < 0) || (TSLPRM_TSC_CTPH > 15))
+#error "TSLPRM_TSC_CTPH is out of range (0 .. 15)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_CTPL
+#error "TSLPRM_TSC_CTPL is not defined."
+#endif
+
+#if ((TSLPRM_TSC_CTPL < 0) || (TSLPRM_TSC_CTPL > 15))
+#error "TSLPRM_TSC_CTPL is out of range (0 .. 15)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_PGPSC
+#error "TSLPRM_TSC_PGPSC is not defined."
+#endif
+
+#if ((TSLPRM_TSC_PGPSC < 0) || (TSLPRM_TSC_PGPSC > 7))
+#error "TSLPRM_TSC_PGPSC is out of range (0 .. 7)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (TSLPRM_ACQ_MAX > 0) && (TSLPRM_ACQ_MAX < 256)
+#define TSLPRM_TSC_MCV 0 // 255
+#endif
+
+#if (TSLPRM_ACQ_MAX > 255) && (TSLPRM_ACQ_MAX < 512)
+#define TSLPRM_TSC_MCV 1 // 511
+#endif
+
+#if (TSLPRM_ACQ_MAX > 511) && (TSLPRM_ACQ_MAX < 1024)
+#define TSLPRM_TSC_MCV 2 // 1023
+#endif
+
+#if (TSLPRM_ACQ_MAX > 1023) && (TSLPRM_ACQ_MAX < 2048)
+#define TSLPRM_TSC_MCV 3 // 2047
+#endif
+
+#if (TSLPRM_ACQ_MAX > 2047) && (TSLPRM_ACQ_MAX < 4096)
+#define TSLPRM_TSC_MCV 4 // 4095
+#endif
+
+#if (TSLPRM_ACQ_MAX > 4095) && (TSLPRM_ACQ_MAX < 8192)
+#define TSLPRM_TSC_MCV 5 // 8191
+#endif
+
+#if (TSLPRM_ACQ_MAX > 8191)
+#define TSLPRM_TSC_MCV 6 // 16383
+#endif
+
+#ifndef TSLPRM_TSC_MCV
+#error "TSLPRM_TSC_MCV is not defined."
+#endif
+
+#if ((TSLPRM_TSC_MCV < 0) || (TSLPRM_TSC_MCV > 6))
+#error "TSLPRM_TSC_MCV is out of range (0 .. 6)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_IODEF
+#error "TSLPRM_TSC_IODEF is not defined."
+#endif
+
+#if ((TSLPRM_TSC_IODEF < 0) || (TSLPRM_TSC_IODEF > 1))
+#error "TSLPRM_TSC_IODEF is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_AM
+#error "TSLPRM_TSC_AM is not defined."
+#endif
+
+#if ((TSLPRM_TSC_AM < 0) || (TSLPRM_TSC_AM > 1))
+#error "TSLPRM_TSC_AM is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SYNC_PIN
+#error "TSLPRM_TSC_SYNC_PIN is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SYNC_PIN < 0) || (TSLPRM_TSC_SYNC_PIN > 1))
+#error "TSLPRM_TSC_SYNC_PIN is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SYNC_POL
+#error "TSLPRM_TSC_SYNC_POL is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SYNC_POL < 0) || (TSLPRM_TSC_SYNC_POL > 1))
+#error "TSLPRM_TSC_SYNC_POL is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_USE_SS
+#error "TSLPRM_TSC_USE_SS is not defined."
+#endif
+
+#if ((TSLPRM_TSC_USE_SS < 0) || (TSLPRM_TSC_USE_SS > 1))
+#error "TSLPRM_TSC_USE_SS is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SSD
+#error "TSLPRM_TSC_SSD is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SSD < 0) || (TSLPRM_TSC_SSD > 127))
+#error "TSLPRM_TSC_SSD is out of range (0 .. 127)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SSPSC
+#error "TSLPRM_TSC_SSPSC is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SSPSC < 0) || (TSLPRM_TSC_SSPSC > 1))
+#error "TSLPRM_TSC_SSPSC is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef TSC_GROUP7_ENABLED
+#undef TSC_GROUP7_ENABLED
+#endif
+
+#if (TSLPRM_TSC_GROUP7_IO1 != NU) || (TSLPRM_TSC_GROUP7_IO2 != NU) || (TSLPRM_TSC_GROUP7_IO3 != NU) || (TSLPRM_TSC_GROUP7_IO4 != NU)
+#define TSC_GROUP7_ENABLED (1)
+#endif
+
+#ifdef TSC_GROUP8_ENABLED
+#undef TSC_GROUP8_ENABLED
+#endif
+
+#if (TSLPRM_TSC_GROUP8_IO1 != NU) || (TSLPRM_TSC_GROUP8_IO2 != NU) || (TSLPRM_TSC_GROUP8_IO3 != NU) || (TSLPRM_TSC_GROUP8_IO4 != NU)
+#define TSC_GROUP8_ENABLED (1)
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DELAY_DISCHARGE_ALL
+#error "TSLPRM_DELAY_DISCHARGE_ALL is not defined."
+#endif
+
+#if ((TSLPRM_DELAY_DISCHARGE_ALL < 0) || (TSLPRM_DELAY_DISCHARGE_ALL > 65535))
+#error "TSLPRM_DELAY_DISCHARGE_ALL is out of range (0 .. 65535)."
+#endif
+
+#endif /* __TSL_CHECK_CONFIG_STM32F0XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f3xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f3xx.h
new file mode 100644
index 0000000..d0e5813
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32f3xx.h
@@ -0,0 +1,227 @@
+/**
+ ******************************************************************************
+ * @file tsl_check_config_stm32f3xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the check of all parameters defined in the
+ * STM32F3XX configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CHECK_CONFIG_STM32F3XX_H
+#define __TSL_CHECK_CONFIG_STM32F3XX_H
+
+//------------------------------------------------------------------------------
+
+#if ((TSLPRM_TOTAL_CHANNELS < 1) || (TSLPRM_TOTAL_CHANNELS > 24))
+#error "TSLPRM_TOTAL_CHANNELS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_BANKS < 1) || (TSLPRM_TOTAL_BANKS > 8))
+#error "TSLPRM_TOTAL_BANKS is out of range (1 .. 8)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS < 0) || (TSLPRM_TOTAL_TOUCHKEYS > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS_B < 0) || (TSLPRM_TOTAL_TOUCHKEYS_B > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS < 0) || (TSLPRM_TOTAL_LINROTS > 24))
+#error "TSLPRM_TOTAL_LINROTS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS_B < 0) || (TSLPRM_TOTAL_LINROTS_B > 24))
+#error "TSLPRM_TOTAL_LINROTS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_OBJECTS < 1) || (TSLPRM_TOTAL_OBJECTS > 24))
+#error "TSLPRM_TOTAL_OBJECTS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TKEYS + TSLPRM_TOTAL_LNRTS) > 24)
+#error "The Sum of TouchKeys and Linear/Rotary sensors exceeds 24."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_GPIO_CONFIG
+#error "TSLPRM_TSC_GPIO_CONFIG is not defined."
+#endif
+
+#if ((TSLPRM_TSC_GPIO_CONFIG < 0) || (TSLPRM_TSC_GPIO_CONFIG > 1))
+#error "TSLPRM_TSC_GPIO_CONFIG is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_CTPH
+#error "TSLPRM_TSC_CTPH is not defined."
+#endif
+
+#if ((TSLPRM_TSC_CTPH < 0) || (TSLPRM_TSC_CTPH > 15))
+#error "TSLPRM_TSC_CTPH is out of range (0 .. 15)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_CTPL
+#error "TSLPRM_TSC_CTPL is not defined."
+#endif
+
+#if ((TSLPRM_TSC_CTPL < 0) || (TSLPRM_TSC_CTPL > 15))
+#error "TSLPRM_TSC_CTPL is out of range (0 .. 15)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_PGPSC
+#error "TSLPRM_TSC_PGPSC is not defined."
+#endif
+
+#if ((TSLPRM_TSC_PGPSC < 0) || (TSLPRM_TSC_PGPSC > 7))
+#error "TSLPRM_TSC_PGPSC is out of range (0 .. 7)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (TSLPRM_ACQ_MAX > 0) && (TSLPRM_ACQ_MAX < 256)
+#define TSLPRM_TSC_MCV 0 // 255
+#endif
+
+#if (TSLPRM_ACQ_MAX > 255) && (TSLPRM_ACQ_MAX < 512)
+#define TSLPRM_TSC_MCV 1 // 511
+#endif
+
+#if (TSLPRM_ACQ_MAX > 511) && (TSLPRM_ACQ_MAX < 1024)
+#define TSLPRM_TSC_MCV 2 // 1023
+#endif
+
+#if (TSLPRM_ACQ_MAX > 1023) && (TSLPRM_ACQ_MAX < 2048)
+#define TSLPRM_TSC_MCV 3 // 2047
+#endif
+
+#if (TSLPRM_ACQ_MAX > 2047) && (TSLPRM_ACQ_MAX < 4096)
+#define TSLPRM_TSC_MCV 4 // 4095
+#endif
+
+#if (TSLPRM_ACQ_MAX > 4095) && (TSLPRM_ACQ_MAX < 8192)
+#define TSLPRM_TSC_MCV 5 // 8191
+#endif
+
+#if (TSLPRM_ACQ_MAX > 8191)
+#define TSLPRM_TSC_MCV 6 // 16383
+#endif
+
+#ifndef TSLPRM_TSC_MCV
+#error "TSLPRM_TSC_MCV is not defined."
+#endif
+
+#if ((TSLPRM_TSC_MCV < 0) || (TSLPRM_TSC_MCV > 6))
+#error "TSLPRM_TSC_MCV is out of range (0 .. 6)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_IODEF
+#error "TSLPRM_TSC_IODEF is not defined."
+#endif
+
+#if ((TSLPRM_TSC_IODEF < 0) || (TSLPRM_TSC_IODEF > 1))
+#error "TSLPRM_TSC_IODEF is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_AM
+#error "TSLPRM_TSC_AM is not defined."
+#endif
+
+#if ((TSLPRM_TSC_AM < 0) || (TSLPRM_TSC_AM > 1))
+#error "TSLPRM_TSC_AM is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SYNC_PIN
+#error "TSLPRM_TSC_SYNC_PIN is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SYNC_PIN < 0) || (TSLPRM_TSC_SYNC_PIN > 2))
+#error "TSLPRM_TSC_SYNC_PIN is out of range (0 .. 2)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SYNC_POL
+#error "TSLPRM_TSC_SYNC_POL is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SYNC_POL < 0) || (TSLPRM_TSC_SYNC_POL > 1))
+#error "TSLPRM_TSC_SYNC_POL is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_USE_SS
+#error "TSLPRM_TSC_USE_SS is not defined."
+#endif
+
+#if ((TSLPRM_TSC_USE_SS < 0) || (TSLPRM_TSC_USE_SS > 1))
+#error "TSLPRM_TSC_USE_SS is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SSD
+#error "TSLPRM_TSC_SSD is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SSD < 0) || (TSLPRM_TSC_SSD > 127))
+#error "TSLPRM_TSC_SSD is out of range (0 .. 127)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TSC_SSPSC
+#error "TSLPRM_TSC_SSPSC is not defined."
+#endif
+
+#if ((TSLPRM_TSC_SSPSC < 0) || (TSLPRM_TSC_SSPSC > 1))
+#error "TSLPRM_TSC_SSPSC is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DELAY_DISCHARGE_ALL
+#error "TSLPRM_DELAY_DISCHARGE_ALL is not defined."
+#endif
+
+#if ((TSLPRM_DELAY_DISCHARGE_ALL < 0) || (TSLPRM_DELAY_DISCHARGE_ALL > 65535))
+#error "TSLPRM_DELAY_DISCHARGE_ALL is out of range (0 .. 65535)."
+#endif
+
+#endif /* __TSL_CHECK_CONFIG_STM32F3XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32l1xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32l1xx.h
new file mode 100644
index 0000000..e948768
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm32l1xx.h
@@ -0,0 +1,401 @@
+/**
+ ******************************************************************************
+ * @file tsl_check_config_stm32l1xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the check of all parameters defined in the
+ * STM32L1XX configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CHECK_CONFIG_STM32L1XX_H
+#define __TSL_CHECK_CONFIG_STM32L1XX_H
+
+//------------------------------------------------------------------------------
+
+#if ((TSLPRM_TOTAL_CHANNELS < 1) || (TSLPRM_TOTAL_CHANNELS > 24))
+#error "TSLPRM_TOTAL_CHANNELS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_BANKS < 1) || (TSLPRM_TOTAL_BANKS > 8))
+#error "TSLPRM_TOTAL_BANKS is out of range (1 .. 8)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS < 0) || (TSLPRM_TOTAL_TOUCHKEYS > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS_B < 0) || (TSLPRM_TOTAL_TOUCHKEYS_B > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS < 0) || (TSLPRM_TOTAL_LINROTS > 24))
+#error "TSLPRM_TOTAL_LINROTS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS_B < 0) || (TSLPRM_TOTAL_LINROTS_B > 24))
+#error "TSLPRM_TOTAL_LINROTS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_OBJECTS < 1) || (TSLPRM_TOTAL_OBJECTS > 24))
+#error "TSLPRM_TOTAL_OBJECTS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TKEYS + TSLPRM_TOTAL_LNRTS) > 24)
+#error "The Sum of TouchKeys and Linear/Rotary sensors exceeds 24."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_SHIELD
+#error "TSLPRM_USE_SHIELD is not defined."
+#endif
+
+#if ((TSLPRM_USE_SHIELD < 0) || (TSLPRM_USE_SHIELD > 1))
+#error "TSLPRM_USE_SHIELD is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_IODEF
+#error "TSLPRM_IODEF is not defined."
+#endif
+
+#if ((TSLPRM_IODEF < 0) || (TSLPRM_IODEF > 1))
+#error "TSLPRM_IODEF is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MD) || defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_DELAY_TRANSFER
+#error "TSLPRM_DELAY_TRANSFER is not defined."
+#endif
+
+#if ((TSLPRM_DELAY_TRANSFER < 0) || (TSLPRM_DELAY_TRANSFER > 65535))
+#error "TSLPRM_DELAY_TRANSFER is out of range (0 .. 65535)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MD) || defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_USE_SPREAD_SPECTRUM
+#error "TSLPRM_USE_SPREAD_SPECTRUM is not defined."
+#endif
+
+#if ((TSLPRM_USE_SPREAD_SPECTRUM < 0) || (TSLPRM_USE_SPREAD_SPECTRUM > 1))
+#error "TSLPRM_USE_SPREAD_SPECTRUM is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MD) || defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_SPREAD_MIN
+#error "TSLPRM_SPREAD_MIN is not defined."
+#endif
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM == 1)
+#if ((TSLPRM_SPREAD_MIN < 1) || (TSLPRM_SPREAD_MIN >= TSLPRM_SPREAD_MAX))
+#error "TSLPRM_SPREAD_MIN is out of range (1 .. TSLPRM_SPREAD_MAX-1)."
+#endif
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MD) || defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_SPREAD_MAX
+#error "TSLPRM_SPREAD_MAX is not defined."
+#endif
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM == 1)
+#if ((TSLPRM_SPREAD_MAX > 255) || (TSLPRM_SPREAD_MAX <= TSLPRM_SPREAD_MIN))
+#error "TSLPRM_SPREAD_MAX is out of range (TSLPRM_SPREAD_MIN+1 .. 255)."
+#endif
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && !defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_CT_PERIOD
+#error "TSLPRM_CT_PERIOD is not defined."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && !defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_TIMER_FREQ
+#error "TSLPRM_TIMER_FREQ is not defined."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && !defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#define TMP_RELOAD ((TSLPRM_CT_PERIOD * TSLPRM_TIMER_FREQ)/2)
+
+#if ((TMP_RELOAD < 4) || (TMP_RELOAD > 16534))
+#error "The calculated Timer RELOAD value is out of range (4 .. 65534)."
+#endif
+
+#if ((TMP_RELOAD % 2) != (0))
+#error "The calculated Timer RELOAD value is odd and must be even."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_PROTECT_IO_ACCESS
+#error "TSLPRM_PROTECT_IO_ACCESS is not defined."
+#endif
+
+#if ((TSLPRM_PROTECT_IO_ACCESS < 0) || (TSLPRM_PROTECT_IO_ACCESS > 1))
+#error "TSLPRM_PROTECT_IO_ACCESS is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_USE_GPIOA
+#error "TSLPRM_USE_GPIOA is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOA < 0) || (TSLPRM_USE_GPIOA > 1))
+#error "TSLPRM_USE_GPIOA is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOB
+#error "TSLPRM_USE_GPIOB is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOB < 0) || (TSLPRM_USE_GPIOB > 1))
+#error "TSLPRM_USE_GPIOB is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOC
+#error "TSLPRM_USE_GPIOC is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOC < 0) || (TSLPRM_USE_GPIOC > 1))
+#error "TSLPRM_USE_GPIOC is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOF
+#error "TSLPRM_USE_GPIOA is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOF < 0) || (TSLPRM_USE_GPIOF > 1))
+#error "TSLPRM_USE_GPIOF is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOG
+#error "TSLPRM_USE_GPIOG is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOG < 0) || (TSLPRM_USE_GPIOG > 1))
+#error "TSLPRM_USE_GPIOG is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MD)
+
+#ifndef TSLPRM_PROTECT_IO_ACCESS
+#error "TSLPRM_PROTECT_IO_ACCESS is not defined."
+#endif
+
+#if ((TSLPRM_PROTECT_IO_ACCESS < 0) || (TSLPRM_PROTECT_IO_ACCESS > 1))
+#error "TSLPRM_PROTECT_IO_ACCESS is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MD)
+
+#ifndef TSLPRM_USE_GPIOA
+#error "TSLPRM_USE_GPIOA is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOA < 0) || (TSLPRM_USE_GPIOA > 1))
+#error "TSLPRM_USE_GPIOA is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOB
+#error "TSLPRM_USE_GPIOB is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOB < 0) || (TSLPRM_USE_GPIOB > 1))
+#error "TSLPRM_USE_GPIOB is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOC
+#error "TSLPRM_USE_GPIOC is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOC < 0) || (TSLPRM_USE_GPIOC > 1))
+#error "TSLPRM_USE_GPIOC is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOF
+#error "TSLPRM_USE_GPIOA is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOF < 0) || (TSLPRM_USE_GPIOF > 1))
+#error "TSLPRM_USE_GPIOF is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOG
+#error "TSLPRM_USE_GPIOG is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOG < 0) || (TSLPRM_USE_GPIOG > 1))
+#error "TSLPRM_USE_GPIOG is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && !defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_CT_PERIOD
+#error "TSLPRM_CT_PERIOD is not defined."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && !defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_TIMER_FREQ
+#error "TSLPRM_TIMER_FREQ is not defined."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if (defined(STM32L1XX_HD) || defined(STM32L1XX_XL)) && !defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#define TMP_RELOAD ((TSLPRM_CT_PERIOD * TSLPRM_TIMER_FREQ)/2)
+
+#if ((TMP_RELOAD < 4) || (TMP_RELOAD > 16534))
+#error "The calculated Timer RELOAD value is out of range (4 .. 65534)."
+#endif
+
+#if ((TMP_RELOAD % 2) != (0))
+#error "The calculated Timer RELOAD value is odd and must be even."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MDP) && defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_PROTECT_IO_ACCESS
+#error "TSLPRM_PROTECT_IO_ACCESS is not defined."
+#endif
+
+#if ((TSLPRM_PROTECT_IO_ACCESS < 0) || (TSLPRM_PROTECT_IO_ACCESS > 1))
+#error "TSLPRM_PROTECT_IO_ACCESS is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#if defined(STM32L1XX_MDP) && defined(TSLPRM_STM32L1XX_SW_ACQ)
+
+#ifndef TSLPRM_USE_GPIOA
+#error "TSLPRM_USE_GPIOA is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOA < 0) || (TSLPRM_USE_GPIOA > 1))
+#error "TSLPRM_USE_GPIOA is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOB
+#error "TSLPRM_USE_GPIOB is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOB < 0) || (TSLPRM_USE_GPIOB > 1))
+#error "TSLPRM_USE_GPIOB is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOC
+#error "TSLPRM_USE_GPIOC is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOC < 0) || (TSLPRM_USE_GPIOC > 1))
+#error "TSLPRM_USE_GPIOC is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOF
+#error "TSLPRM_USE_GPIOA is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOF < 0) || (TSLPRM_USE_GPIOF > 1))
+#error "TSLPRM_USE_GPIOF is out of range (0 .. 1)."
+#endif
+
+#ifndef TSLPRM_USE_GPIOG
+#error "TSLPRM_USE_GPIOG is not defined."
+#endif
+
+#if ((TSLPRM_USE_GPIOG < 0) || (TSLPRM_USE_GPIOG > 1))
+#error "TSLPRM_USE_GPIOG is out of range (0 .. 1)."
+#endif
+
+#endif
+
+#endif /* __TSL_CHECK_CONFIG_STM32L1XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8l.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8l.h
new file mode 100644
index 0000000..ecfb3a8
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8l.h
@@ -0,0 +1,211 @@
+/**
+ ******************************************************************************
+ * @file tsl_check_config_stm8l.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the check of all parameters defined in the
+ * STM8L configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CHECK_CONFIG_STM8L_H
+#define __TSL_CHECK_CONFIG_STM8L_H
+
+//------------------------------------------------------------------------------
+
+#if ((TSLPRM_TOTAL_CHANNELS < 1) || (TSLPRM_TOTAL_CHANNELS > 24))
+#error "TSLPRM_TOTAL_CHANNELS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_BANKS < 1) || (TSLPRM_TOTAL_BANKS > 8))
+#error "TSLPRM_TOTAL_BANKS is out of range (1 .. 8)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS < 0) || (TSLPRM_TOTAL_TOUCHKEYS > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS_B < 0) || (TSLPRM_TOTAL_TOUCHKEYS_B > 24))
+#error "TSLPRM_TOTAL_TOUCHKEYS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS < 0) || (TSLPRM_TOTAL_LINROTS > 24))
+#error "TSLPRM_TOTAL_LINROTS is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS_B < 0) || (TSLPRM_TOTAL_LINROTS_B > 24))
+#error "TSLPRM_TOTAL_LINROTS_B is out of range (0 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_OBJECTS < 1) || (TSLPRM_TOTAL_OBJECTS > 24))
+#error "TSLPRM_TOTAL_OBJECTS is out of range (1 .. 24)."
+#endif
+
+#if ((TSLPRM_TOTAL_TKEYS + TSLPRM_TOTAL_LNRTS) > 24)
+#error "The Sum of TouchKeys and Linear/Rotary sensors exceeds 24."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_SHIELD
+#error "TSLPRM_USE_SHIELD is not defined."
+#endif
+
+#if ((TSLPRM_USE_SHIELD < 0) || (TSLPRM_USE_SHIELD > 1))
+#error "TSLPRM_USE_SHIELD is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_IODEF
+#error "TSLPRM_IODEF is not defined."
+#endif
+
+#if ((TSLPRM_IODEF < 0) || (TSLPRM_IODEF > 1))
+#error "TSLPRM_IODEF is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_DELAY_DISCHARGE_ALL
+#error "TSLPRM_DELAY_DISCHARGE_ALL is not defined."
+#endif
+
+#if ((TSLPRM_DELAY_DISCHARGE_ALL < 0) || (TSLPRM_DELAY_DISCHARGE_ALL > 65535))
+#error "TSLPRM_DELAY_DISCHARGE_ALL is out of range (0 .. 65535)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef TSLPRM_STM8L1XX_SW_ACQ // Software acquisition
+
+#ifndef TSLPRM_PROTECT_IO_ACCESS
+#error "TSLPRM_PROTECT_IO_ACCESS is not defined."
+#endif
+
+#if ((TSLPRM_PROTECT_IO_ACCESS < 0) || (TSLPRM_PROTECT_IO_ACCESS > 1))
+#error "TSLPRM_PROTECT_IO_ACCESS is out of range (0 .. 1)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef TSLPRM_STM8L1XX_SW_ACQ // Software acquisition
+
+#ifndef TSLPRM_DELAY_CHARGE
+#error "TSLPRM_DELAY_CHARGE is not defined."
+#endif
+
+#if ((TSLPRM_DELAY_CHARGE < 0) || (TSLPRM_DELAY_CHARGE > 32))
+#error "TSLPRM_DELAY_CHARGE is out of range (0 .. 32)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifdef TSLPRM_STM8L1XX_SW_ACQ // Software acquisition
+
+#ifndef TSLPRM_DELAY_TRANSFER
+#error "TSLPRM_DELAY_TRANSFER is not defined."
+#endif
+
+#if ((TSLPRM_DELAY_TRANSFER < 0) || (TSLPRM_DELAY_TRANSFER > 32))
+#error "TSLPRM_DELAY_TRANSFER is out of range (0 .. 32)."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_USE_SPREAD_SPECTRUM
+#error "TSLPRM_USE_SPREAD_SPECTRUM is not defined."
+#endif
+
+#if ((TSLPRM_USE_SPREAD_SPECTRUM < 0) || (TSLPRM_USE_SPREAD_SPECTRUM > 1))
+#error "TSLPRM_USE_SPREAD_SPECTRUM is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_SPREAD_MIN
+#error "TSLPRM_SPREAD_MIN is not defined."
+#endif
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM == 1)
+#if ((TSLPRM_SPREAD_MIN < 1) || (TSLPRM_SPREAD_MIN >= TSLPRM_SPREAD_MAX))
+#error "TSLPRM_SPREAD_MIN is out of range (1 .. TSLPRM_SPREAD_MAX-1)."
+#endif
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_SPREAD_MAX
+#error "TSLPRM_SPREAD_MAX is not defined."
+#endif
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM == 1)
+#if ((TSLPRM_SPREAD_MAX > 255) || (TSLPRM_SPREAD_MAX <= TSLPRM_SPREAD_MIN))
+#error "TSLPRM_SPREAD_MAX is out of range (TSLPRM_SPREAD_MIN+1 .. 255)."
+#endif
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_STM8L1XX_SW_ACQ // Hardware acquisition
+
+#ifndef TSLPRM_CT_PERIOD
+#error "TSLPRM_CT_PERIOD is not defined."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_STM8L1XX_SW_ACQ // Hardware acquisition
+
+#ifndef TSLPRM_TIMER_FREQ
+#error "TSLPRM_TIMER_FREQ is not defined."
+#endif
+
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_STM8L1XX_SW_ACQ // Hardware acquisition
+
+#define TMP_RELOAD ((TSLPRM_CT_PERIOD * TSLPRM_TIMER_FREQ) / 2)
+
+#if ((TMP_RELOAD < 4) || (TMP_RELOAD > 65534))
+#error "The calculated Timer RELOAD value is out of range (4 .. 65534)."
+#endif
+
+#if ((TMP_RELOAD % 2) != (0))
+#error "The calculated Timer RELOAD value is odd and must be even."
+#endif
+
+#endif
+
+#endif /* __TSL_CHECK_CONFIG_STM8L_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8tl5x.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8tl5x.h
new file mode 100644
index 0000000..cb9514f
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_check_config_stm8tl5x.h
@@ -0,0 +1,270 @@
+/**
+ ******************************************************************************
+ * @file tsl_check_config_stm8tl5x.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the check of all parameters defined in the
+ * STM8TL5X configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CHECK_CONFIG_STM8TL5X_H
+#define __TSL_CHECK_CONFIG_STM8TL5X_H
+
+//------------------------------------------------------------------------------
+
+#if ((TSLPRM_MCU < 0) && (TSLPRM_MCU > 4))
+#error "The MCU selected is not in the STM8TL5x MCU list !"
+#endif
+
+#if (TSLPRM_MCU > 0)
+#define __MAX_RX 7
+#else
+#define __MAX_RX 9
+#endif
+
+//------------------------------------------------------------------------------
+
+#if ((TSLPRM_TOTAL_CHANNELS < 1) || (TSLPRM_TOTAL_CHANNELS > 300))
+#error "TSLPRM_TOTAL_CHANNELS is out of range (1 .. 300)."
+#endif
+
+#if ((TSLPRM_TOTAL_BANKS < 1) || (TSLPRM_TOTAL_BANKS > 15))
+#error "TSLPRM_TOTAL_BANKS is out of range (1 .. 15)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS < 0) || (TSLPRM_TOTAL_TOUCHKEYS > 256))
+#error "TSLPRM_TOTAL_TOUCHKEYS is out of range (0 .. 256)."
+#endif
+
+#if ((TSLPRM_TOTAL_TOUCHKEYS_B < 0) || (TSLPRM_TOTAL_TOUCHKEYS_B > 256))
+#error "TSLPRM_TOTAL_TOUCHKEYS_B is out of range (0 .. 256)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS < 0) || (TSLPRM_TOTAL_LINROTS > 256))
+#error "TSLPRM_TOTAL_LINROTS is out of range (0 .. 256)."
+#endif
+
+#if ((TSLPRM_TOTAL_LINROTS_B < 0) || (TSLPRM_TOTAL_LINROTS_B > 256))
+#error "TSLPRM_TOTAL_LINROTS_B is out of range (0 .. 256)."
+#endif
+
+#if ((TSLPRM_TOTAL_OBJECTS < 1) || (TSLPRM_TOTAL_OBJECTS > 256))
+#error "TSLPRM_TOTAL_OBJECTS is out of range (1 .. 256)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_KEY_TARGET_REFERENCE
+#error "TSLPRM_KEY_TARGET_REFERENCE is not defined."
+#endif
+
+#if ((TSLPRM_KEY_TARGET_REFERENCE < 100) || (TSLPRM_KEY_TARGET_REFERENCE > 2000))
+#error "TSLPRM_KEY_TARGET_REFERENCE is out of range (100 .. 2000)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_KEY_TARGET_REFERENCE_ERROR
+#error "TSLPRM_KEY_TARGET_REFERENCE_ERROR is not defined."
+#endif
+
+#if ((TSLPRM_KEY_TARGET_REFERENCE_ERROR < 1) || (TSLPRM_KEY_TARGET_REFERENCE_ERROR > TSLPRM_KEY_TARGET_REFERENCE))
+#error "TSLPRM_KEY_TARGET_REFERENCE_ERROR is out of range (1 .. TSLPRM_KEY_TARGET_REFERENCE)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION
+#error "TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION is not defined."
+#endif
+
+#if ((TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION < 3) || (TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION > 5))
+#error "TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION is out of range (3 .. 5)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_KEY_TARGET_ATTENUATION
+#error "TSLPRM_KEY_TARGET_ATTENUATION is not defined."
+#endif
+
+#if ((TSLPRM_KEY_TARGET_ATTENUATION != 1) && (TSLPRM_KEY_TARGET_ATTENUATION != 2) &&\
+ (TSLPRM_KEY_TARGET_ATTENUATION != 4) && (TSLPRM_KEY_TARGET_ATTENUATION != 8))
+#error "TSLPRM_KEY_TARGET_ATTENUATION is out of range (1,2,4,8)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_TOUCHKEY_REFERENCE_RANGE
+#error "TSLPRM_TOUCHKEY_REFERENCE_RANGE is not defined."
+#endif
+
+#if ((TSLPRM_TOUCHKEY_REFERENCE_RANGE < 1) || (TSLPRM_TOUCHKEY_REFERENCE_RANGE > TSLPRM_KEY_TARGET_REFERENCE))
+#error "TSLPRM_TOUCHKEY_REFERENCE_RANGE is out of range (1 .. TSLPRM_KEY_TARGET_REFERENCE)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_LINROT_REFERENCE_RANGE
+#error "TSLPRM_LINROT_REFERENCE_RANGE is not defined."
+#endif
+
+#if ((TSLPRM_LINROT_REFERENCE_RANGE < 1) || (TSLPRM_LINROT_REFERENCE_RANGE > TSLPRM_KEY_TARGET_REFERENCE))
+#error "TSLPRM_LINROT_REFERENCE_RANGE is out of range (1 .. TSLPRM_KEY_TARGET_REFERENCE)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_HSI
+#error "TSLPRM_PXS_HSI is not defined."
+#endif
+
+#if ((TSLPRM_PXS_HSI != 16000) && (TSLPRM_PXS_HSI != 8000) && (TSLPRM_PXS_HSI != 4000) && \
+ (TSLPRM_PXS_HSI != 2000) && (TSLPRM_PXS_HSI != 1000) && (TSLPRM_PXS_HSI != 500) && \
+ (TSLPRM_PXS_HSI != 250) && (TSLPRM_PXS_HSI != 125))
+#error "TSLPRM_PXS_HSI is out of range (16000, 8000, 4000, 2000, 1000, 500, 250, 125)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_UP_LENGTH
+#error "TSLPRM_PXS_UP_LENGTH is not defined."
+#endif
+
+#if ((TSLPRM_PXS_UP_LENGTH < 1) || (TSLPRM_PXS_UP_LENGTH > 7))
+#error "TSLPRM_PXS_UP_LENGTH is out of range (1 .. 7)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_PASS_LENGTH
+#error "TSLPRM_PXS_PASS_LENGTH is not defined."
+#endif
+
+#if ((TSLPRM_PXS_PASS_LENGTH < 1) || (TSLPRM_PXS_PASS_LENGTH > 7))
+#error "TSLPRM_PXS_PASS_LENGTH is out of range (1 .. 7)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_LOW_POWER_MODE
+#error "TSLPRM_PXS_LOW_POWER_MODE is not defined."
+#endif
+
+#if ((TSLPRM_PXS_LOW_POWER_MODE != 0) && (TSLPRM_PXS_LOW_POWER_MODE != 1))
+#error "TSLPRM_PXS_LOW_POWER_MODE is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_RF_DETECTION
+#error "TSLPRM_PXS_RF_DETECTION is not defined."
+#endif
+
+#if ((TSLPRM_PXS_RF_DETECTION != 0) && (TSLPRM_PXS_RF_DETECTION != 1))
+#error "TSLPRM_PXS_RF_DETECTION is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_SYNCHRONIZE
+#error "TSLPRM_PXS_SYNCHRONIZE is not defined."
+#endif
+
+#if ((TSLPRM_PXS_SYNCHRONIZE != 0) && (TSLPRM_PXS_SYNCHRONIZE != 1))
+#error "TSLPRM_PXS_SYNCHRONIZE is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_SYNCHRO_EDGE
+#error "TSLPRM_PXS_SYNCHRO_EDGE is not defined."
+#endif
+
+#if ((TSLPRM_PXS_SYNCHRO_EDGE != 0) && (TSLPRM_PXS_SYNCHRO_EDGE != 1))
+#error "TSLPRM_PXS_SYNCHRO_EDGE is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_INACTIVE_TX
+#error "TSLPRM_PXS_INACTIVE_TX is not defined."
+#endif
+
+#if ((TSLPRM_PXS_INACTIVE_TX != 0) && (TSLPRM_PXS_INACTIVE_TX != 1))
+#error "TSLPRM_PXS_INACTIVE_TX is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_INACTIVE_RX
+#error "TSLPRM_PXS_INACTIVE_RX is not defined."
+#endif
+
+#if ((TSLPRM_PXS_INACTIVE_RX != 0) && (TSLPRM_PXS_INACTIVE_RX != 1))
+#error "TSLPRM_PXS_INACTIVE_RX is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_RX_COUPLING
+#error "TSLPRM_PXS_RX_COUPLING is not defined."
+#endif
+
+#if ((TSLPRM_PXS_RX_COUPLING != 0) && (TSLPRM_PXS_RX_COUPLING != 1))
+#error "TSLPRM_PXS_RX_COUPLING is out of range (0 .. 1)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_STAB
+#error "TSLPRM_PXS_STAB is not defined."
+#endif
+
+#if ((TSLPRM_PXS_STAB != LONG_STAB) && (TSLPRM_PXS_STAB != MEDIUM_STAB) && (TSLPRM_PXS_STAB != SHORT_STAB))
+#error "TSLPRM_PXS_STAB is out of range (LONG_STAB, MEDIUM_STAB, SHORT_STAB)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_PXS_BIAS
+#error "TSLPRM_PXS_BIAS is not defined."
+#endif
+
+#if ((TSLPRM_PXS_BIAS != HIGH_BIAS) && (TSLPRM_PXS_BIAS != MEDIUM_BIAS) && (TSLPRM_PXS_BIAS != LOW_BIAS) && (TSLPRM_PXS_BIAS != VERY_LOW_BIAS))
+#error "TSLPRM_PXS_BIAS is out of range (HIGH_BIAS, MEDIUM_BIAS, LOW_BIAS, VERY_LOW_BIAS)."
+#endif
+
+//------------------------------------------------------------------------------
+
+#ifndef TSLPRM_HIGH_CHANNEL_NB
+#error "TSLPRM_HIGH_CHANNEL_NB is not defined."
+#endif
+
+#if ((TSLPRM_HIGH_CHANNEL_NB < 0) || (TSLPRM_HIGH_CHANNEL_NB > __MAX_RX))
+#error "TSLPRM_HIGH_CHANNEL_NB is out of range (0..9 for STM8TL53C4, 0..7 for STM8TL53G4)."
+#endif
+
+#endif /* __TSL_CHECK_CONFIG_STM8TL5X_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f0xx.h_TOADAPT b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f0xx.h_TOADAPT
new file mode 100644
index 0000000..2dc3877
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f0xx.h_TOADAPT
@@ -0,0 +1,629 @@
+/**
+ ******************************************************************************
+ * @file tsl_conf_stm32f0xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief Acquisition parameters for STM32F0xx products.
+ * @note This file must be copied in the application project and values
+ * changed for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CONF_STM32F0XX_H
+#define __TSL_CONF_STM32F0XX_H
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++ COMMON PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup Common_Parameters Common Parameters
+ * @{ */
+
+//==============================================================================
+// Number of elements
+//==============================================================================
+
+/** @defgroup Common_Parameters_Number_Of_Elements 01 - Number of elements
+ * @{ */
+
+/** Total number of channels in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_CHANNELS (1)
+
+/** Total number of banks in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_BANKS (1)
+
+/** Total number of "Extended" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS (1)
+
+/** Total number of "Basic" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS_B (1)
+
+/** Total number of "Extended" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS (1)
+
+/** Total number of "Basic" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS_B (1)
+
+/** Total number of sensors/objects in application (range=1..255)
+ - Count all TouchKeys, Linear and Rotary sensors
+*/
+#define TSLPRM_TOTAL_OBJECTS (1)
+
+/** @} Common_Parameters_Number_Of_Elements */
+
+//==============================================================================
+// Optional features
+//==============================================================================
+
+/** @defgroup Common_Parameters_Options 02 - Optional features
+ * @{ */
+
+/** Record the last measure (0=No, 1=Yes)
+ - If No the measure is recalculated using the Reference and Delta
+*/
+#define TSLPRM_USE_MEAS (1)
+
+/** Zone management usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_ZONE (1)
+
+/** Proximity detection usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_PROX (1)
+
+/** Use the Timer tick callback (0=No, 1=Yes)
+ - When equal to 1, the function TSL_CallBack_TimerTick must be defined in
+ the application code. It is called for each timer interruption.
+*/
+#define TSLPRM_USE_TIMER_CALLBACK (1)
+
+/** Acquisition interrupt mode (0=No, 1=Yes)
+ - If No the TS interrupt is not used.
+ - If Yes the TS interrupt is used.
+*/
+#define TSLPRM_USE_ACQ_INTERRUPT (1)
+
+/** @} Common_Parameters_Options */
+
+//==============================================================================
+// Acquisition limits
+//==============================================================================
+
+/** @defgroup Common_Parameters_Acquisition_Limits 03 - Acquisition limits
+ * @{ */
+
+/** Minimum acquisition measurement (range=0..65535)
+ - This is the minimum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is below this value.
+*/
+#define TSLPRM_ACQ_MIN (10)
+
+/** Maximum acquisition measurement (range=255, 511, 1023, 2047, 8191, 16383)
+ - This is the maximum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is above this value.
+*/
+#define TSLPRM_ACQ_MAX (8191)
+
+/** @} Common_Parameters_Acquisition_Limits */
+
+//==============================================================================
+// Calibration
+//==============================================================================
+
+/** @defgroup Common_Parameters_Calibration 04 - Calibration
+ * @{ */
+
+/** Number of calibration samples (range=4, 8, 16)
+ - Low value = faster calibration but less precision.
+ - High value = slower calibration but more precision.
+*/
+#define TSLPRM_CALIB_SAMPLES (8)
+
+/** Delay in measurement samples before starting the calibration (range=0..40)
+ - This is useful if a noise filter is used.
+ - Write 0 to disable the delay.
+*/
+#define TSLPRM_CALIB_DELAY (10)
+
+/** @} Common_Parameters_Calibration */
+
+//==============================================================================
+// Thresholds for TouchKey sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_TouchKey_Thresholds 05 - Thresholds for TouchKey sensors
+ * @{ */
+
+/** TouchKeys Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_TKEY_PROX_IN_TH (10)
+
+/** TouchKeys Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_TKEY_PROX_OUT_TH (5)
+
+/** TouchKeys Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_TKEY_DETECT_IN_TH (20)
+
+/** TouchKeys Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_TKEY_DETECT_OUT_TH (15)
+
+/** TouchKeys re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+*/
+#define TSLPRM_TKEY_CALIB_TH (20)
+
+/** TouchKey, Linear and Rotary sensors thresholds coefficient (range=0..4)
+ This multiplier coefficient is applied on Detect and Re-Calibration thresholds only.
+ - 0: feature disabled
+ - 1: thresholds x 2
+ - 2: thresholds x 4
+ - 3: thresholds x 8
+ - 4: thresholds x 16
+*/
+#define TSLPRM_COEFF_TH (1)
+
+/** @} Common_Parameters_TouchKey_Thresholds */
+
+//==============================================================================
+// Thresholds for Linear and Rotary sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Thresholds 06 - Thresholds for Linear and Rotary sensors
+ * @{ */
+
+/** Linear/Rotary Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_LINROT_PROX_IN_TH (10)
+
+/** Linear/Rotary Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_LINROT_PROX_OUT_TH (5)
+
+/** Linear/Rotary Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_LINROT_DETECT_IN_TH (20)
+
+/** Linear/Rotary Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_LINROT_DETECT_OUT_TH (15)
+
+/** Linear/Rotary re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+ - A low absolute value will result in a higher sensitivity and thus some spurious
+ recalibration may be issued.
+*/
+#define TSLPRM_LINROT_CALIB_TH (20)
+
+/** Linear/Rotary Delta normalization (0=No, 1=Yes)
+ - When this parameter is set, a coefficient is applied on all Delta of all sensors
+ in order to normalize them and to improve the position calculation.
+ - These coefficients must be defined in a constant table in the application (see Library examples).
+ - The MSB is the coefficient integer part, the LSB is the coefficient real part.
+ - Examples:
+ - To apply a factor 1.10:
+ 0x01 to the MSB
+ 0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
+ - To apply a factor 0.90:
+ 0x00 to the MSB
+ 0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
+ - To apply no factor:
+ 0x01 to the MSB
+ 0x00 to the LSB
+*/
+#define TSLPRM_LINROT_USE_NORMDELTA (1)
+
+/** @} Common_Parameters_LinRot_Thresholds */
+
+//==============================================================================
+// Linear/Rotary sensors used
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Used 07 - Linear/Rotary sensors used
+ * @{ */
+
+/** Select which Linear and Rotary sensors you use in your application.
+ - 0 = Not Used
+ - 1 = Used
+
+ LIN = Linear sensor
+ ROT = Rotary sensor
+ M1 = Mono electrodes design with 0/255 position at extremities of the sensor
+ M2 = Mono electrodes design
+ H = Half-ended electrodes design
+ D = Dual electrodes design
+*/
+#define TSLPRM_USE_3CH_LIN_M1 (1)
+#define TSLPRM_USE_3CH_LIN_M2 (1)
+#define TSLPRM_USE_3CH_LIN_H (1)
+#define TSLPRM_USE_3CH_ROT_M (1)
+
+#define TSLPRM_USE_4CH_LIN_M1 (1)
+#define TSLPRM_USE_4CH_LIN_M2 (1)
+#define TSLPRM_USE_4CH_LIN_H (1)
+#define TSLPRM_USE_4CH_ROT_M (1)
+
+#define TSLPRM_USE_5CH_LIN_M1 (1)
+#define TSLPRM_USE_5CH_LIN_M2 (1)
+#define TSLPRM_USE_5CH_LIN_H (1)
+#define TSLPRM_USE_5CH_ROT_M (1)
+#define TSLPRM_USE_5CH_ROT_D (1)
+
+#define TSLPRM_USE_6CH_LIN_M1 (1)
+#define TSLPRM_USE_6CH_LIN_M2 (1)
+#define TSLPRM_USE_6CH_LIN_H (1)
+#define TSLPRM_USE_6CH_ROT_M (1)
+
+/** @} Common_Parameters_LinRot_used */
+
+//==============================================================================
+// Linear/Rotary sensors position
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Position 08 - Linear/Rotary sensors position
+ * @{ */
+
+/** Position resolution in number of bits (range=1..8)
+ - A Low value will result in a low resolution and will be less subject to noise.
+ - A High value will result in a high resolution and will be more subject to noise.
+*/
+#define TSLPRM_LINROT_RESOLUTION (7)
+
+/** Direction change threshold in position unit (range=0..255)
+ - Defines the default threshold used during the change direction process.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_POS (10)
+
+/** Direction change debounce (range=0..63)
+ - Defines the default integrator counter used during the change direction process.
+ - This counter is decremented when the same change in the position is detected and the direction will
+ change after this counter reaches zero.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_DEB (1)
+
+/** @} Common_Parameters_LinRot_Position */
+
+//==============================================================================
+// Debounce counters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Debounce 09 - Debounce counters
+ * @{ */
+
+/** Proximity state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the Proximity detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_PROX (3)
+
+/** Detect state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_DETECT (3)
+
+/** Release state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the end-detection but with less noise filtering.
+ - A High value will result in a lower sensitivity during the end-detection but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_RELEASE (3)
+
+/** Re-calibration state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the recalibration but with less noise filtering.
+ - A High value will result in a lower sensitivity during the recalibration but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_CALIB (3)
+
+/** Error state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity to enter in error state.
+ - A High value will result in a lower sensitivity to enter in error state.
+*/
+#define TSLPRM_DEBOUNCE_ERROR (3)
+
+/** @} Common_Parameters_Debounce */
+
+//==============================================================================
+// Environment Change System (ECS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_ECS 10 - ECS
+ * @{ */
+
+/** Environment Change System Slow K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_SLOW (10)
+
+/** Environment Change System Fast K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_FAST (20)
+
+/** Environment Change System delay in msec (range=0..5000)
+ - The ECS will be started after this delay and when all sensors are in Release state.
+*/
+#define TSLPRM_ECS_DELAY (500)
+
+/** @} Common_Parameters_ECS */
+
+//==============================================================================
+// Detection Time Out (DTO)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DTO 11 - DTO
+ * @{ */
+
+/** Detection Time Out delay in seconds (range=0..63)
+ - Value 0: DTO processing not compiled in the code (to gain size if not used).
+ - Value 1: Default time out infinite.
+ - Value between 2 and 63: Default time out between value n-1 and n.
+ - Examples:
+ - With a DTO equal to 2, the time out is between 1s and 2s.
+ - With a DTO equal to 63, the time out is between 62s and 63s.
+
+@note The DTO can be changed in run-time by the application only if the
+ default value is between 1 and 63.
+*/
+#define TSLPRM_DTO (5)
+
+/** @} Common_Parameters_DTO */
+
+//==============================================================================
+// Detection Exclusion System (DXS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DXS 12 - DXS
+ * @{ */
+
+/** Detection Exclusion System (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_DXS (1)
+
+/** @} Common_Parameters_DXS */
+
+//==============================================================================
+// Miscellaneous parameters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Misc 13 - Miscellaneous
+ * @{ */
+
+/** Timing tick frequency in Hz (range=125, 250, 500, 1000, 2000)
+ - Result to a timing interrupt respectively every 8ms, 4ms, 2ms, 1ms, 0.5ms
+*/
+#define TSLPRM_TICK_FREQ (1000)
+
+/** Delay for discharging Cx and Cs capacitors (range=0..65535)
+ - The value corresponds to the Softdelay function parameter.
+ - 500 gives around 53 µs delay whatever HCLK
+ - 1000 gives around 106 µs delay whatever HCLK
+ - 2000 gives around 210 µs delay whatever HCLK
+*/
+#define TSLPRM_DELAY_DISCHARGE_ALL (1000)
+
+/** @} Common_Parameters_Misc */
+
+/** @} Common_Parameters */
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++ MCU PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup STM32F0xx_Parameters STM32F0xx Parameters
+ * @{ */
+
+//==============================================================================
+// GPIO configuration
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_GPIO_Config 01 - TSC GPIOs Configuration
+ * @{ */
+
+/** TSC GPIOs Configuration selection (range=0..1)
+ - 0: Manual. The TSC GPIOs configuration must be done by the application code.
+ - 1: Automatic. The TSLPRM_TSC_GROUPx_IOy parameters below must be filled up.
+ The TSC GPIOs configuration is automatically done by the STMTouch driver.
+*/
+#define TSLPRM_TSC_GPIO_CONFIG (1)
+
+//+++ DO NOT CHANGE THESE VALUES +++++++++++++++++++++++++++++++++
+// These defines must be applied to the TSLPRM_TSC_GROUPx_IOy parameters below.
+#define NU (0) // Not Used IO
+#define CHANNEL (1) // Channel IO
+#define SHIELD (2) // Shield IO (= Channel IO but not acquired)
+#define SAMPCAP (3) // Sampling Capacitor IO
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// If TSLPRM_TSC_GPIO_CONFIG=1 assign each TSLPRM_TSC_GROUPx_IOy parameters below.
+// If TSLPRM_TSC_GPIO_CONFIG=0 these parameters are ignored.
+
+#define TSLPRM_TSC_GROUP1_IO1 NU // PA0
+#define TSLPRM_TSC_GROUP1_IO2 NU // PA1
+#define TSLPRM_TSC_GROUP1_IO3 NU // PA2
+#define TSLPRM_TSC_GROUP1_IO4 NU // PA3
+
+#define TSLPRM_TSC_GROUP2_IO1 NU // PA4
+#define TSLPRM_TSC_GROUP2_IO2 NU // PA5
+#define TSLPRM_TSC_GROUP2_IO3 NU // PA6
+#define TSLPRM_TSC_GROUP2_IO4 NU // PA7
+
+#define TSLPRM_TSC_GROUP3_IO1 NU // PC5
+#define TSLPRM_TSC_GROUP3_IO2 NU // PB0
+#define TSLPRM_TSC_GROUP3_IO3 NU // PB1
+#define TSLPRM_TSC_GROUP3_IO4 NU // PB2
+
+#define TSLPRM_TSC_GROUP4_IO1 NU // PA9
+#define TSLPRM_TSC_GROUP4_IO2 NU // PA10
+#define TSLPRM_TSC_GROUP4_IO3 NU // PA11
+#define TSLPRM_TSC_GROUP4_IO4 NU // PA12
+
+#define TSLPRM_TSC_GROUP5_IO1 NU // PB3
+#define TSLPRM_TSC_GROUP5_IO2 NU // PB4
+#define TSLPRM_TSC_GROUP5_IO3 NU // PB6
+#define TSLPRM_TSC_GROUP5_IO4 NU // PB7
+
+#define TSLPRM_TSC_GROUP6_IO1 NU // PB11
+#define TSLPRM_TSC_GROUP6_IO2 NU // PB12
+#define TSLPRM_TSC_GROUP6_IO3 NU // PB13
+#define TSLPRM_TSC_GROUP6_IO4 NU // PB14
+
+// Warning: this group is available on some devices only.
+#define TSLPRM_TSC_GROUP7_IO1 NU // PE2
+#define TSLPRM_TSC_GROUP7_IO2 NU // PE3
+#define TSLPRM_TSC_GROUP7_IO3 NU // PE4
+#define TSLPRM_TSC_GROUP7_IO4 NU // PE5
+
+// Warning: this group is available on some devices only.
+#define TSLPRM_TSC_GROUP8_IO1 NU // PD12
+#define TSLPRM_TSC_GROUP8_IO2 NU // PD13
+#define TSLPRM_TSC_GROUP8_IO3 NU // PD14
+#define TSLPRM_TSC_GROUP8_IO4 NU // PD15
+
+/** @} STM32F0xx_Parameters_GPIO_Config */
+
+//==============================================================================
+// Charge Transfer Pulses
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_CT_Pulses 02 - Charge Transfer Pulses
+ * @{ */
+
+/** Charge Transfer Pulse High (range=0..15)
+ - 0: 1 x tPGCLK
+ - 1: 2 x tPGCLK
+ - ...
+ - 15: 16 x tPGCLK
+*/
+#define TSLPRM_TSC_CTPH (1)
+
+/** Charge Transfer Pulse Low (range=0..15)
+ - 0: 1 x tPGCLK
+ - 1: 2 x tPGCLK
+ - ...
+ - 15: 16 x tPGCLK
+*/
+#define TSLPRM_TSC_CTPL (1)
+
+/** Pulse Generator Prescaler (range=0..7)
+ - 0: fPGCLK = fHCLK
+ - 1: fPGCLK = fHCLK/2
+ - ...
+ - 7: fPGCLK = fHCLK/128
+*/
+#define TSLPRM_TSC_PGPSC (5)
+
+/** @} STM32F0xx_Parameters_CT_Pulses */
+
+//==============================================================================
+// IOs
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_IOs 03 - I/Os
+ * @{ */
+
+/** TSC IOs default mode when no on-going acquisition (range=0..1)
+ - 0: Output push-pull low
+ - 1: Input floating
+@note To ensure a correct operation in noisy environment, this parameter should
+be configured to output push-pull low.
+*/
+#define TSLPRM_TSC_IODEF (0)
+
+/** Acquisition Mode (range=0..1)
+ - 0: Normal acquisition mode
+ - 1: Synchronized acquisition mode
+*/
+#define TSLPRM_TSC_AM (0)
+
+/** Synchronization Pin (range=0..1)
+ - 0: PB08
+ - 1: PB10
+*/
+#define TSLPRM_TSC_SYNC_PIN (0)
+
+/** Synchronization Polarity (range=0..1)
+ - 0: Falling edge only
+ - 1: Rising edge and high level
+*/
+#define TSLPRM_TSC_SYNC_POL (0)
+
+/** @} STM32F0xx_Parameters_Misc */
+
+//==============================================================================
+// Spread Spectrum
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_SpreadSpectrum 04 - Spread Spectrum
+ * @{ */
+
+/** Use Spread Spectrum (0=No, 1=Yes)
+*/
+#define TSLPRM_TSC_USE_SS (0)
+
+/** Spread Spectrum Deviation (range=0..127)
+ - 0: 1 x tSSCLK
+ - 1: 2 x tSSCLK
+ - ...
+ - 127: 128 x tSSCLK
+*/
+#define TSLPRM_TSC_SSD (0)
+
+/** Spread Spectrum Prescaler (range=0..1)
+ - 0: fSSCLK = fHCLK
+ - 1: fSSCLK = fHCLK/2
+*/
+#define TSLPRM_TSC_SSPSC (0)
+
+/** @} STM32F0xx_Parameters_SpreadSpectrum */
+
+/** @} STM32F0xx_Parameters */
+
+// DO NOT REMOVE !!!
+#include "tsl_check_config.h"
+
+#endif /* __TSL_CONF_STM32F0XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f3xx.h_TOADAPT b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f3xx.h_TOADAPT
new file mode 100644
index 0000000..547555e
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32f3xx.h_TOADAPT
@@ -0,0 +1,628 @@
+/**
+ ******************************************************************************
+ * @file tsl_conf_stm32f3xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief Acquisition parameters for STM32F3xx products.
+ * @note This file must be copied in the application project and values
+ * changed for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CONF_STM32F3XX_H
+#define __TSL_CONF_STM32F3XX_H
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++ COMMON PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup Common_Parameters Common Parameters
+ * @{ */
+
+//==============================================================================
+// Number of elements
+//==============================================================================
+
+/** @defgroup Common_Parameters_Number_Of_Elements 01 - Number of elements
+ * @{ */
+
+/** Total number of channels in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_CHANNELS (1)
+
+/** Total number of banks in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_BANKS (1)
+
+/** Total number of "Extended" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS (1)
+
+/** Total number of "Basic" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS_B (1)
+
+/** Total number of "Extended" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS (1)
+
+/** Total number of "Basic" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS_B (1)
+
+/** Total number of sensors/objects in application (range=1..255)
+ - Count all TouchKeys, Linear and Rotary sensors
+*/
+#define TSLPRM_TOTAL_OBJECTS (1)
+
+/** @} Common_Parameters_Number_Of_Elements */
+
+//==============================================================================
+// Optional features
+//==============================================================================
+
+/** @defgroup Common_Parameters_Options 02 - Optional features
+ * @{ */
+
+/** Record the last measure (0=No, 1=Yes)
+ - If No the measure is recalculated using the Reference and Delta
+*/
+#define TSLPRM_USE_MEAS (1)
+
+/** Zone management usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_ZONE (1)
+
+/** Proximity detection usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_PROX (1)
+
+/** Use the Timer tick callback (0=No, 1=Yes)
+ - When equal to 1, the function TSL_CallBack_TimerTick must be defined in
+ the application code. It is called for each timer interruption.
+*/
+#define TSLPRM_USE_TIMER_CALLBACK (1)
+
+/** Acquisition interrupt mode (0=No, 1=Yes)
+ - If No the TS interrupt is not used.
+ - If Yes the TS interrupt is used.
+*/
+#define TSLPRM_USE_ACQ_INTERRUPT (1)
+
+/** @} Common_Parameters_Options */
+
+//==============================================================================
+// Acquisition limits
+//==============================================================================
+
+/** @defgroup Common_Parameters_Acquisition_Limits 03 - Acquisition limits
+ * @{ */
+
+/** Minimum acquisition measurement (range=0..65535)
+ - This is the minimum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is below this value.
+*/
+#define TSLPRM_ACQ_MIN (10)
+
+/** Maximum acquisition measurement (range=255, 511, 1023, 2047, 8191, 16383)
+ - This is the maximum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is above this value.
+*/
+#define TSLPRM_ACQ_MAX (8191)
+
+/** @} Common_Parameters_Acquisition_Limits */
+
+//==============================================================================
+// Calibration
+//==============================================================================
+
+/** @defgroup Common_Parameters_Calibration 04 - Calibration
+ * @{ */
+
+/** Number of calibration samples (range=4, 8, 16)
+ - Low value = faster calibration but less precision.
+ - High value = slower calibration but more precision.
+*/
+#define TSLPRM_CALIB_SAMPLES (8)
+
+/** Delay in measurement samples before starting the calibration (range=0..40)
+ - This is useful if a noise filter is used.
+ - Write 0 to disable the delay.
+*/
+#define TSLPRM_CALIB_DELAY (10)
+
+/** @} Common_Parameters_Calibration */
+
+//==============================================================================
+// Thresholds for TouchKey sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_TouchKey_Thresholds 05 - Thresholds for TouchKey sensors
+ * @{ */
+
+/** TouchKeys Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_TKEY_PROX_IN_TH (10)
+
+/** TouchKeys Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_TKEY_PROX_OUT_TH (5)
+
+/** TouchKeys Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_TKEY_DETECT_IN_TH (20)
+
+/** TouchKeys Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_TKEY_DETECT_OUT_TH (15)
+
+/** TouchKeys re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+*/
+#define TSLPRM_TKEY_CALIB_TH (20)
+
+/** TouchKey, Linear and Rotary sensors thresholds coefficient (range=0..4)
+ This multiplier coefficient is applied on Detect and Re-Calibration thresholds only.
+ - 0: feature disabled
+ - 1: thresholds x 2
+ - 2: thresholds x 4
+ - 3: thresholds x 8
+ - 4: thresholds x 16
+*/
+#define TSLPRM_COEFF_TH (1)
+
+/** @} Common_Parameters_TouchKey_Thresholds */
+
+//==============================================================================
+// Thresholds for Linear and Rotary sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Thresholds 06 - Thresholds for Linear and Rotary sensors
+ * @{ */
+
+/** Linear/Rotary Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_LINROT_PROX_IN_TH (10)
+
+/** Linear/Rotary Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_LINROT_PROX_OUT_TH (5)
+
+/** Linear/Rotary Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_LINROT_DETECT_IN_TH (20)
+
+/** Linear/Rotary Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_LINROT_DETECT_OUT_TH (15)
+
+/** Linear/Rotary re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+ - A low absolute value will result in a higher sensitivity and thus some spurious
+ recalibration may be issued.
+*/
+#define TSLPRM_LINROT_CALIB_TH (20)
+
+/** Linear/Rotary Delta normalization (0=No, 1=Yes)
+ - When this parameter is set, a coefficient is applied on all Delta of all sensors
+ in order to normalize them and to improve the position calculation.
+ - These coefficients must be defined in a constant table in the application (see Library examples).
+ - The MSB is the coefficient integer part, the LSB is the coefficient real part.
+ - Examples:
+ - To apply a factor 1.10:
+ 0x01 to the MSB
+ 0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
+ - To apply a factor 0.90:
+ 0x00 to the MSB
+ 0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
+ - To apply no factor:
+ 0x01 to the MSB
+ 0x00 to the LSB
+*/
+#define TSLPRM_LINROT_USE_NORMDELTA (1)
+
+/** @} Common_Parameters_LinRot_Thresholds */
+
+//==============================================================================
+// Linear/Rotary sensors used
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Used 07 - Linear/Rotary sensors used
+ * @{ */
+
+/** Select which Linear and Rotary sensors you use in your application.
+ - 0 = Not Used
+ - 1 = Used
+
+ LIN = Linear sensor
+ ROT = Rotary sensor
+ M1 = Mono electrodes design with 0/255 position at extremities of the sensor
+ M2 = Mono electrodes design
+ H = Half-ended electrodes design
+ D = Dual electrodes design
+*/
+#define TSLPRM_USE_3CH_LIN_M1 (1)
+#define TSLPRM_USE_3CH_LIN_M2 (1)
+#define TSLPRM_USE_3CH_LIN_H (1)
+#define TSLPRM_USE_3CH_ROT_M (1)
+
+#define TSLPRM_USE_4CH_LIN_M1 (1)
+#define TSLPRM_USE_4CH_LIN_M2 (1)
+#define TSLPRM_USE_4CH_LIN_H (1)
+#define TSLPRM_USE_4CH_ROT_M (1)
+
+#define TSLPRM_USE_5CH_LIN_M1 (1)
+#define TSLPRM_USE_5CH_LIN_M2 (1)
+#define TSLPRM_USE_5CH_LIN_H (1)
+#define TSLPRM_USE_5CH_ROT_M (1)
+#define TSLPRM_USE_5CH_ROT_D (1)
+
+#define TSLPRM_USE_6CH_LIN_M1 (1)
+#define TSLPRM_USE_6CH_LIN_M2 (1)
+#define TSLPRM_USE_6CH_LIN_H (1)
+#define TSLPRM_USE_6CH_ROT_M (1)
+
+/** @} Common_Parameters_LinRot_used */
+
+//==============================================================================
+// Linear/Rotary sensors position
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Position 08 - Linear/Rotary sensors position
+ * @{ */
+
+/** Position resolution in number of bits (range=1..8)
+ - A Low value will result in a low resolution and will be less subject to noise.
+ - A High value will result in a high resolution and will be more subject to noise.
+*/
+#define TSLPRM_LINROT_RESOLUTION (7)
+
+/** Direction change threshold in position unit (range=0..255)
+ - Defines the default threshold used during the change direction process.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_POS (10)
+
+/** Direction change debounce (range=0..63)
+ - Defines the default integrator counter used during the change direction process.
+ - This counter is decremented when the same change in the position is detected and the direction will
+ change after this counter reaches zero.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_DEB (1)
+
+/** @} Common_Parameters_LinRot_Position */
+
+//==============================================================================
+// Debounce counters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Debounce 09 - Debounce counters
+ * @{ */
+
+/** Proximity state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the Proximity detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_PROX (3)
+
+/** Detect state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_DETECT (3)
+
+/** Release state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the end-detection but with less noise filtering.
+ - A High value will result in a lower sensitivity during the end-detection but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_RELEASE (3)
+
+/** Re-calibration state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the recalibration but with less noise filtering.
+ - A High value will result in a lower sensitivity during the recalibration but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_CALIB (3)
+
+/** Error state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity to enter in error state.
+ - A High value will result in a lower sensitivity to enter in error state.
+*/
+#define TSLPRM_DEBOUNCE_ERROR (3)
+
+/** @} Common_Parameters_Debounce */
+
+//==============================================================================
+// Environment Change System (ECS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_ECS 10 - ECS
+ * @{ */
+
+/** Environment Change System Slow K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_SLOW (10)
+
+/** Environment Change System Fast K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_FAST (20)
+
+/** Environment Change System delay in msec (range=0..5000)
+ - The ECS will be started after this delay and when all sensors are in Release state.
+*/
+#define TSLPRM_ECS_DELAY (500)
+
+/** @} Common_Parameters_ECS */
+
+//==============================================================================
+// Detection Time Out (DTO)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DTO 11 - DTO
+ * @{ */
+
+/** Detection Time Out delay in seconds (range=0..63)
+ - Value 0: DTO processing not compiled in the code (to gain size if not used).
+ - Value 1: Default time out infinite.
+ - Value between 2 and 63: Default time out between value n-1 and n.
+ - Examples:
+ - With a DTO equal to 2, the time out is between 1s and 2s.
+ - With a DTO equal to 63, the time out is between 62s and 63s.
+
+@note The DTO can be changed in run-time by the application only if the
+ default value is between 1 and 63.
+*/
+#define TSLPRM_DTO (5)
+
+/** @} Common_Parameters_DTO */
+
+//==============================================================================
+// Detection Exclusion System (DXS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DXS 12 - DXS
+ * @{ */
+
+/** Detection Exclusion System (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_DXS (1)
+
+/** @} Common_Parameters_DXS */
+
+//==============================================================================
+// Miscellaneous parameters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Misc 13 - Miscellaneous
+ * @{ */
+
+/** Timing tick frequency in Hz (range=125, 250, 500, 1000, 2000)
+ - Result to a timing interrupt respectively every 8ms, 4ms, 2ms, 1ms, 0.5ms
+*/
+#define TSLPRM_TICK_FREQ (1000)
+
+/** Delay for discharging Cx and Cs capacitors (range=0..65535)
+ - The value corresponds to the Softdelay function parameter.
+ - 500 gives around 63 µs delay whatever HCLK
+ - 1000 gives around 126 µs delay whatever HCLK
+ - 2000 gives around 251 µs delay whatever HCLK
+*/
+#define TSLPRM_DELAY_DISCHARGE_ALL (1000)
+
+/** @} Common_Parameters_Misc */
+
+/** @} Common_Parameters */
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++ MCU PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup STM32F3xx_Parameters STM32F3xx Parameters
+ * @{ */
+
+//==============================================================================
+// GPIO configuration
+//==============================================================================
+
+/** @defgroup STM32F3xx_Parameters_GPIO_Config 01 - TSC GPIOs Configuration
+ * @{ */
+
+/** TSC GPIOs Configuration selection (range=0..1)
+ - 0: Manual. The TSC GPIOs configuration must be done by the application code.
+ - 1: Automatic. The TSLPRM_TSC_GROUPx_IOy parameters below must be filled up.
+ The TSC GPIOs configuration is automatically done by the STMTouch driver.
+*/
+#define TSLPRM_TSC_GPIO_CONFIG (1)
+
+//+++ DO NOT CHANGE THESE VALUES +++++++++++++++++++++++++++++++++
+// These defines must be applied to the TSLPRM_TSC_GROUPx_IOy parameters below.
+#define NU (0) // Not Used IO
+#define CHANNEL (1) // Channel IO
+#define SHIELD (2) // Shield IO (= Channel IO but not acquired)
+#define SAMPCAP (3) // Sampling Capacitor IO
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// If TSLPRM_TSC_GPIO_CONFIG=1 assign each TSLPRM_TSC_GROUPx_IOy parameters below.
+// If TSLPRM_TSC_GPIO_CONFIG=0 these parameters are ignored.
+// STM32F30X STM32F37X
+#define TSLPRM_TSC_GROUP1_IO1 NU // PA0 PA0
+#define TSLPRM_TSC_GROUP1_IO2 NU // PA1 PA1
+#define TSLPRM_TSC_GROUP1_IO3 NU // PA2 PA2
+#define TSLPRM_TSC_GROUP1_IO4 NU // PA3 PA3
+
+#define TSLPRM_TSC_GROUP2_IO1 NU // PA4 PA4
+#define TSLPRM_TSC_GROUP2_IO2 NU // PA5 PA5
+#define TSLPRM_TSC_GROUP2_IO3 NU // PA6 PA6
+#define TSLPRM_TSC_GROUP2_IO4 NU // PA7 PA7
+
+#define TSLPRM_TSC_GROUP3_IO1 NU // PC5 PC4 << diff
+#define TSLPRM_TSC_GROUP3_IO2 NU // PB0 PC5 << diff
+#define TSLPRM_TSC_GROUP3_IO3 NU // PB1 PB0 << diff
+#define TSLPRM_TSC_GROUP3_IO4 NU // PB2 PB1 << diff
+
+#define TSLPRM_TSC_GROUP4_IO1 NU // PA9 PA9
+#define TSLPRM_TSC_GROUP4_IO2 NU // PA10 PA10
+#define TSLPRM_TSC_GROUP4_IO3 NU // PA13 PA13
+#define TSLPRM_TSC_GROUP4_IO4 NU // PA14 PA14
+
+#define TSLPRM_TSC_GROUP5_IO1 NU // PB3 PB3
+#define TSLPRM_TSC_GROUP5_IO2 NU // PB4 PB4
+#define TSLPRM_TSC_GROUP5_IO3 NU // PB6 PB6
+#define TSLPRM_TSC_GROUP5_IO4 NU // PB7 PB7
+
+#define TSLPRM_TSC_GROUP6_IO1 NU // PB11 PB14 << diff
+#define TSLPRM_TSC_GROUP6_IO2 NU // PB12 PB15 << diff
+#define TSLPRM_TSC_GROUP6_IO3 NU // PB13 PD8 << diff
+#define TSLPRM_TSC_GROUP6_IO4 NU // PB14 PD9 << diff
+
+#define TSLPRM_TSC_GROUP7_IO1 NU // PE2 PE2
+#define TSLPRM_TSC_GROUP7_IO2 NU // PE3 PE3
+#define TSLPRM_TSC_GROUP7_IO3 NU // PE4 PE4
+#define TSLPRM_TSC_GROUP7_IO4 NU // PE5 PE5
+
+#define TSLPRM_TSC_GROUP8_IO1 NU // PD12 PD12
+#define TSLPRM_TSC_GROUP8_IO2 NU // PD13 PD13
+#define TSLPRM_TSC_GROUP8_IO3 NU // PD14 PD14
+#define TSLPRM_TSC_GROUP8_IO4 NU // PD15 PD15
+
+/** @} STM32F3xx_Parameters_GPIO_Config */
+
+//==============================================================================
+// Charge Transfer Pulses
+//==============================================================================
+
+/** @defgroup STM32F3xx_Parameters_CT_Pulses 02 - Charge Transfer Pulses
+ * @{ */
+
+/** Charge Transfer Pulse High (range=0..15)
+ - 0: 1 x tPGCLK
+ - 1: 2 x tPGCLK
+ - ...
+ - 15: 16 x tPGCLK
+*/
+#define TSLPRM_TSC_CTPH (1)
+
+/** Charge Transfer Pulse Low (range=0..15)
+ - 0: 1 x tPGCLK
+ - 1: 2 x tPGCLK
+ - ...
+ - 15: 16 x tPGCLK
+*/
+#define TSLPRM_TSC_CTPL (1)
+
+/** Pulse Generator Prescaler (range=0..7)
+ - 0: fPGCLK = fHCLK
+ - 1: fPGCLK = fHCLK/2
+ - ...
+ - 7: fPGCLK = fHCLK/128
+*/
+#define TSLPRM_TSC_PGPSC (5)
+
+/** @} STM32F3xx_Parameters_CT_Pulses */
+
+//==============================================================================
+// IOs
+//==============================================================================
+
+/** @defgroup STM32F3xx_Parameters_IOs 03 - I/Os
+ * @{ */
+
+/** TSC IOs default mode when no on-going acquisition (range=0..1)
+ - 0: Output push-pull low
+ - 1: Input floating
+@note To ensure a correct operation in noisy environment, this parameter should
+be configured to output push-pull low.
+*/
+#define TSLPRM_TSC_IODEF (0)
+
+/** Acquisition Mode (range=0..1)
+ - 0: Normal acquisition mode
+ - 1: Synchronized acquisition mode
+*/
+#define TSLPRM_TSC_AM (0)
+
+/** Synchronization Pin (range=0..2)
+ - 0: PB08
+ - 1: PB10
+ - 2: PA15 (on some devices only)
+*/
+#define TSLPRM_TSC_SYNC_PIN (0)
+
+/** Synchronization Polarity (range=0..1)
+ - 0: Falling edge only
+ - 1: Rising edge and high level
+*/
+#define TSLPRM_TSC_SYNC_POL (0)
+
+/** @} STM32F3xx_Parameters_Misc */
+
+//==============================================================================
+// Spread Spectrum
+//==============================================================================
+
+/** @defgroup STM32F3xx_Parameters_SpreadSpectrum 04 - Spread Spectrum
+ * @{ */
+
+/** Use Spread Spectrum (0=No, 1=Yes)
+*/
+#define TSLPRM_TSC_USE_SS (0)
+
+/** Spread Spectrum Deviation (range=0..127)
+ - 0: 1 x tSSCLK
+ - 1: 2 x tSSCLK
+ - ...
+ - 127: 128 x tSSCLK
+*/
+#define TSLPRM_TSC_SSD (0)
+
+/** Spread Spectrum Prescaler (range=0..1)
+ - 0: fSSCLK = fHCLK
+ - 1: fSSCLK = fHCLK/2
+*/
+#define TSLPRM_TSC_SSPSC (0)
+
+/** @} STM32F3xx_Parameters_SpreadSpectrum */
+
+/** @} STM32F3xx_Parameters */
+
+// DO NOT REMOVE !!!
+#include "tsl_check_config.h"
+
+#endif /* __TSL_CONF_STM32F3XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32l1xx.h_TOADAPT b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32l1xx.h_TOADAPT
new file mode 100644
index 0000000..6dad088
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm32l1xx.h_TOADAPT
@@ -0,0 +1,527 @@
+/**
+ ******************************************************************************
+ * @file tsl_conf_stm32l1xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief Acquisition parameters for STM32L1xx products.
+ * @note This file must be copied in the application project and values
+ * changed for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CONF_STM32L1xx_H
+#define __TSL_CONF_STM32L1xx_H
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++ COMMON PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup Common_Parameters Common Parameters
+ * @{ */
+
+//==============================================================================
+// Number of elements
+//==============================================================================
+
+/** @defgroup Common_Parameters_Number_Of_Elements 01 - Number of elements
+ * @{ */
+
+/** Total number of channels in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_CHANNELS (1)
+
+/** Total number of banks in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_BANKS (1)
+
+/** Total number of "Extended" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS (1)
+
+/** Total number of "Basic" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS_B (1)
+
+/** Total number of "Extended" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS (1)
+
+/** Total number of "Basic" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS_B (1)
+
+/** Total number of sensors/objects in application (range=1..255)
+ - Count all TouchKeys, Linear and Rotary sensors
+*/
+#define TSLPRM_TOTAL_OBJECTS (1)
+
+/** @} Common_Parameters_Number_Of_Elements */
+
+//==============================================================================
+// Optional features
+//==============================================================================
+
+/** @defgroup Common_Parameters_Options 02 - Optional features
+ * @{ */
+
+/** Record the last measure (0=No, 1=Yes)
+ - If No the measure is recalculated using the Reference and Delta
+*/
+#define TSLPRM_USE_MEAS (1)
+
+/** Zone management usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_ZONE (1)
+
+/** Proximity detection usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_PROX (1)
+
+/** Use the Timer tick callback (0=No, 1=Yes)
+ - When equal to 1, the function TSL_CallBack_TimerTick must be defined in
+ the application code. It is called for each timer interruption.
+*/
+#define TSLPRM_USE_TIMER_CALLBACK (1)
+
+/** Acquisition interrupt mode (0=No, 1=Yes)
+ - If No the TS interrupt is not used.
+ - If Yes the TS interrupt is used.
+*/
+#define TSLPRM_USE_ACQ_INTERRUPT (1)
+
+/** @} Common_Parameters_Options */
+
+//==============================================================================
+// Acquisition limits
+//==============================================================================
+
+/** @defgroup Common_Parameters_Acquisition_Limits 03 - Acquisition limits
+ * @{ */
+
+/** Minimum acquisition measurement (range=0..65535)
+ - This is the minimum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is below this value.
+*/
+#define TSLPRM_ACQ_MIN (10)
+
+/** Maximum acquisition measurement (range=0..65535)
+ - This is the maximum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is above this value.
+*/
+#define TSLPRM_ACQ_MAX (4000)
+
+/** @} Common_Parameters_Acquisition_Limits */
+
+//==============================================================================
+// Calibration
+//==============================================================================
+
+/** @defgroup Common_Parameters_Calibration 04 - Calibration
+ * @{ */
+
+/** Number of calibration samples (range=4, 8, 16)
+ - Low value = faster calibration but less precision.
+ - High value = slower calibration but more precision.
+*/
+#define TSLPRM_CALIB_SAMPLES (8)
+
+/** Delay in measurement samples before starting the calibration (range=0..40)
+ - This is useful if a noise filter is used.
+ - Write 0 to disable the delay.
+*/
+#define TSLPRM_CALIB_DELAY (10)
+
+/** @} Common_Parameters_Calibration */
+
+//==============================================================================
+// Thresholds for TouchKey sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_TouchKey_Thresholds 05 - Thresholds for TouchKey sensors
+ * @{ */
+
+/** TouchKeys Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_TKEY_PROX_IN_TH (10)
+
+/** TouchKeys Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_TKEY_PROX_OUT_TH (5)
+
+/** TouchKeys Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_TKEY_DETECT_IN_TH (20)
+
+/** TouchKeys Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_TKEY_DETECT_OUT_TH (15)
+
+/** TouchKeys re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+*/
+#define TSLPRM_TKEY_CALIB_TH (20)
+
+/** TouchKey, Linear and Rotary sensors thresholds coefficient (range=0..4)
+ This multiplier coefficient is applied on Detect and Re-Calibration thresholds only.
+ - 0: feature disabled
+ - 1: thresholds x 2
+ - 2: thresholds x 4
+ - 3: thresholds x 8
+ - 4: thresholds x 16
+*/
+#define TSLPRM_COEFF_TH (1)
+
+/** @} Common_Parameters_TouchKey_Thresholds */
+
+//==============================================================================
+// Thresholds for Linear and Rotary sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Thresholds 06 - Thresholds for Linear and Rotary sensors
+ * @{ */
+
+/** Linear/Rotary Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_LINROT_PROX_IN_TH (10)
+
+/** Linear/Rotary Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_LINROT_PROX_OUT_TH (5)
+
+/** Linear/Rotary Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_LINROT_DETECT_IN_TH (20)
+
+/** Linear/Rotary Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_LINROT_DETECT_OUT_TH (15)
+
+/** Linear/Rotary re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+ - A low absolute value will result in a higher sensitivity and thus some spurious
+ recalibration may be issued.
+*/
+#define TSLPRM_LINROT_CALIB_TH (20)
+
+/** Linear/Rotary Delta normalization (0=No, 1=Yes)
+ - When this parameter is set, a coefficient is applied on all Delta of all sensors
+ in order to normalize them and to improve the position calculation.
+ - These coefficients must be defined in a constant table in the application (see Library examples).
+ - The MSB is the coefficient integer part, the LSB is the coefficient real part.
+ - Examples:
+ - To apply a factor 1.10:
+ 0x01 to the MSB
+ 0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
+ - To apply a factor 0.90:
+ 0x00 to the MSB
+ 0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
+ - To apply no factor:
+ 0x01 to the MSB
+ 0x00 to the LSB
+*/
+#define TSLPRM_LINROT_USE_NORMDELTA (1)
+
+/** @} Common_Parameters_LinRot_Thresholds */
+
+//==============================================================================
+// Linear/Rotary sensors used
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Used 07 - Linear/Rotary sensors used
+ * @{ */
+
+/** Select which Linear and Rotary sensors you use in your application.
+ - 0 = Not Used
+ - 1 = Used
+
+ LIN = Linear sensor
+ ROT = Rotary sensor
+ M1 = Mono electrodes design with 0/255 position at extremities of the sensor
+ M2 = Mono electrodes design
+ H = Half-ended electrodes design
+ D = Dual electrodes design
+*/
+#define TSLPRM_USE_3CH_LIN_M1 (1)
+#define TSLPRM_USE_3CH_LIN_M2 (1)
+#define TSLPRM_USE_3CH_LIN_H (1)
+#define TSLPRM_USE_3CH_ROT_M (1)
+
+#define TSLPRM_USE_4CH_LIN_M1 (1)
+#define TSLPRM_USE_4CH_LIN_M2 (1)
+#define TSLPRM_USE_4CH_LIN_H (1)
+#define TSLPRM_USE_4CH_ROT_M (1)
+
+#define TSLPRM_USE_5CH_LIN_M1 (1)
+#define TSLPRM_USE_5CH_LIN_M2 (1)
+#define TSLPRM_USE_5CH_LIN_H (1)
+#define TSLPRM_USE_5CH_ROT_M (1)
+#define TSLPRM_USE_5CH_ROT_D (1)
+
+#define TSLPRM_USE_6CH_LIN_M1 (1)
+#define TSLPRM_USE_6CH_LIN_M2 (1)
+#define TSLPRM_USE_6CH_LIN_H (1)
+#define TSLPRM_USE_6CH_ROT_M (1)
+
+/** @} Common_Parameters_LinRot_used */
+
+//==============================================================================
+// Linear/Rotary sensors position
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Position 08 - Linear/Rotary sensors position
+ * @{ */
+
+/** Position resolution in number of bits (range=1..8)
+ - A Low value will result in a low resolution and will be less subject to noise.
+ - A High value will result in a high resolution and will be more subject to noise.
+*/
+#define TSLPRM_LINROT_RESOLUTION (7)
+
+/** Direction change threshold in position unit (range=0..255)
+ - Defines the default threshold used during the change direction process.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_POS (10)
+
+/** Direction change debounce (range=0..63)
+ - Defines the default integrator counter used during the change direction process.
+ - This counter is decremented when the same change in the position is detected and the direction will
+ change after this counter reaches zero.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_DEB (1)
+
+/** @} Common_Parameters_LinRot_Position */
+
+//==============================================================================
+// Debounce counters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Debounce 09 - Debounce counters
+ * @{ */
+
+/** Proximity state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the Proximity detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_PROX (3)
+
+/** Detect state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_DETECT (3)
+
+/** Release state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the end-detection but with less noise filtering.
+ - A High value will result in a lower sensitivity during the end-detection but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_RELEASE (3)
+
+/** Re-calibration state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the recalibration but with less noise filtering.
+ - A High value will result in a lower sensitivity during the recalibration but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_CALIB (3)
+
+/** Error state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity to enter in error state.
+ - A High value will result in a lower sensitivity to enter in error state.
+*/
+#define TSLPRM_DEBOUNCE_ERROR (3)
+
+/** @} Common_Parameters_Debounce */
+
+//==============================================================================
+// Environment Change System (ECS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_ECS 10 - ECS
+ * @{ */
+
+/** Environment Change System Slow K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_SLOW (10)
+
+/** Environment Change System Fast K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_FAST (20)
+
+/** Environment Change System delay in msec (range=0..5000)
+ - The ECS will be started after this delay and when all sensors are in Release state.
+*/
+#define TSLPRM_ECS_DELAY (500)
+
+/** @} Common_Parameters_ECS */
+
+//==============================================================================
+// Detection Time Out (DTO)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DTO 11 - DTO
+ * @{ */
+
+/** Detection Time Out delay in seconds (range=0..63)
+ - Value 0: DTO processing not compiled in the code (to gain size if not used).
+ - Value 1: Default time out infinite.
+ - Value between 2 and 63: Default time out between value n-1 and n.
+ - Examples:
+ - With a DTO equal to 2, the time out is between 1s and 2s.
+ - With a DTO equal to 63, the time out is between 62s and 63s.
+
+@note The DTO can be changed in run-time by the application only if the
+ default value is between 1 and 63.
+*/
+#define TSLPRM_DTO (5)
+
+/** @} Common_Parameters_DTO */
+
+//==============================================================================
+// Detection Exclusion System (DXS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DXS 12 - DXS
+ * @{ */
+
+/** Detection Exclusion System (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_DXS (1)
+
+/** @} Common_Parameters_DXS */
+
+//==============================================================================
+// Miscellaneous parameters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Misc 13 - Miscellaneous
+ * @{ */
+
+/** Timing tick frequency in Hz (range=125, 250, 500, 1000, 2000)
+ - Result to a timing interrupt respectively every 8ms, 4ms, 2ms, 1ms, 0.5ms
+*/
+#define TSLPRM_TICK_FREQ (1000)
+
+/** @} Common_Parameters_Misc */
+
+/** @} Common_Parameters */
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++ MCU PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup STM32L1xx_Parameters STM32L1xx Parameters
+ * @{ */
+
+/** @defgroup STM32L1xx_Parameters_Misc 01 - Miscellaneous
+ * @{ */
+
+/** Shield with a channel (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_SHIELD (1)
+
+/** IOs default mode when no on-going acquisition (range=0..1)
+ - 0: Output push-pull low
+ - 1: Input floating
+@note To ensure a correct operation in noisy environment, this parameter should
+be configured to output push-pull low.
+*/
+#define TSLPRM_IODEF (1)
+
+/** Charge/transfer Period (in µs) (= high pulse + low pulse)
+ - This is used to calculate the Timer reload value.
+@note For HW acquisition only
+ */
+#define TSLPRM_CT_PERIOD (2)
+
+/** Timer frequency (in MHz)
+ - This is used to calculate the Timer reload value.
+@note For HW acquisition only
+ */
+#define TSLPRM_TIMER_FREQ (32)
+
+/** Delay for transfering charges from Cx to Cs capacitor and then discharge Cx
+ (range=0..65535)
+ - 0: no delay (it takes about 2.8µs for a CT cycle)
+ - (1..65535): delay (in µs) = 0.75 * TSLPRM_DELAY_TRANSFER + 1
+@note for SW acquisition only
+*/
+#define TSLPRM_DELAY_TRANSFER (1)
+
+/**Use Spread Spectrum (0=No, 1=Yes)
+@note for SW acquisition only
+*/
+#define TSLPRM_USE_SPREAD_SPECTRUM (1)
+
+/** Spread min value (range=0..(TSLPRM_SPREAD_MAX-1))
+@note for SW acquisition only
+*/
+#define TSLPRM_SPREAD_MIN (1)
+
+/** Spread max value (range=2..255)
+@note for SW acquisition only
+*/
+#define TSLPRM_SPREAD_MAX (20)
+
+/** IT disabling for IO protection (range=0..1)
+ - 0: IO not protected
+ - 1: IO protected
+@note for SW acquisition only
+*/
+#define TSLPRM_PROTECT_IO_ACCESS (0)
+
+/** Which GPIO will be used (range=0..1)
+ - 0: Not used
+ - 1: Used
+@note for SW acquisition only
+*/
+#define TSLPRM_USE_GPIOA (1)
+#define TSLPRM_USE_GPIOB (1)
+#define TSLPRM_USE_GPIOC (1)
+#define TSLPRM_USE_GPIOF (0)
+#define TSLPRM_USE_GPIOG (0)
+
+/** @} STM32L1xx_Parameters_Misc */
+
+/** @} STM32L1xx_Parameters */
+
+// DO NOT REMOVE !!!
+#include "tsl_check_config.h"
+
+#endif /* __TSL_CONF_STM32L1xx_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8l.h_TOADAPT b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8l.h_TOADAPT
new file mode 100644
index 0000000..511f0f6
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8l.h_TOADAPT
@@ -0,0 +1,533 @@
+/**
+ ******************************************************************************
+ * @file tsl_conf_stm8l.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief Acquisition parameters for STM8L products.
+ * @note This file must be copied in the application project and values
+ * changed for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CONF_STM8L_H
+#define __TSL_CONF_STM8L_H
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++ COMMON PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup Common_Parameters Common Parameters
+ * @{ */
+
+//==============================================================================
+// Number of elements
+//==============================================================================
+
+/** @defgroup Common_Parameters_Number_Of_Elements 01 - Number of elements
+ * @{ */
+
+/** Total number of channels in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_CHANNELS (1)
+
+/** Total number of banks in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_BANKS (1)
+
+/** Total number of "Extended" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS (1)
+
+/** Total number of "Basic" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS_B (1)
+
+/** Total number of "Extended" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS (1)
+
+/** Total number of "Basic" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS_B (1)
+
+/** Total number of sensors/objects in application (range=1..255)
+ - Count all TouchKeys, Linear and Rotary sensors
+*/
+#define TSLPRM_TOTAL_OBJECTS (1)
+
+/** @} Common_Parameters_Number_Of_Elements */
+
+//==============================================================================
+// Optional features
+//==============================================================================
+
+/** @defgroup Common_Parameters_Options 02 - Optional features
+ * @{ */
+
+/** Record the last measure (0=No, 1=Yes)
+ - If No the measure is recalculated using the Reference and Delta
+*/
+#define TSLPRM_USE_MEAS (1)
+
+/** Zone management usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_ZONE (1)
+
+/** Proximity detection usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_PROX (1)
+
+/** Use the Timer tick callback (0=No, 1=Yes)
+ - When equal to 1, the function TSL_CallBack_TimerTick must be defined in
+ the application code. It is called for each timer interruption.
+*/
+#define TSLPRM_USE_TIMER_CALLBACK (1)
+
+/** Acquisition interrupt mode (0=No, 1=Yes)
+ - If No the acquisition is managed in the main routine using polling mode.
+ - If Yes the acquisition is managed in the interrupt routines.
+*/
+#define TSLPRM_USE_ACQ_INTERRUPT (1)
+
+/** @} Common_Parameters_Options */
+
+//==============================================================================
+// Acquisition limits
+//==============================================================================
+
+/** @defgroup Common_Parameters_Acquisition_Limits 03 - Acquisition limits
+ * @{ */
+
+/** Minimum acquisition measurement (range=0..65535)
+ - This is the minimum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is below this value.
+*/
+#define TSLPRM_ACQ_MIN (50)
+
+/** Maximum acquisition measurement (range=0..65535)
+ - This is the maximum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is above this value.
+*/
+#define TSLPRM_ACQ_MAX (4000)
+
+/** @} Common_Parameters_Acquisition_Limits */
+
+//==============================================================================
+// Calibration
+//==============================================================================
+
+/** @defgroup Common_Parameters_Calibration 04 - Calibration
+ * @{ */
+
+/** Number of calibration samples (range=4, 8, 16)
+ - Low value = faster calibration but less precision.
+ - High value = slower calibration but more precision.
+*/
+#define TSLPRM_CALIB_SAMPLES (8)
+
+/** Delay in measurement samples before starting the calibration (range=0..40)
+ - This is useful if a noise filter is used.
+ - Write 0 to disable the delay.
+*/
+#define TSLPRM_CALIB_DELAY (10)
+
+/** @} Common_Parameters_Calibration */
+
+//==============================================================================
+// Thresholds for TouchKey sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_TouchKey_Thresholds 05 - Thresholds for TouchKey sensors
+ * @{ */
+
+/** TouchKeys Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_TKEY_PROX_IN_TH (20)
+
+/** TouchKeys Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_TKEY_PROX_OUT_TH (15)
+
+/** TouchKeys Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_TKEY_DETECT_IN_TH (30)
+
+/** TouchKeys Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_TKEY_DETECT_OUT_TH (25)
+
+/** TouchKeys re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+*/
+#define TSLPRM_TKEY_CALIB_TH (30)
+
+/** TouchKey, Linear and Rotary sensors thresholds coefficient (range=0..4)
+ This multiplier coefficient is applied on Detect and Re-Calibration thresholds only.
+ - 0: feature disabled
+ - 1: thresholds x 2
+ - 2: thresholds x 4
+ - 3: thresholds x 8
+ - 4: thresholds x 16
+*/
+#define TSLPRM_COEFF_TH (1)
+
+/** @} Common_Parameters_TouchKey_Thresholds */
+
+//==============================================================================
+// Thresholds for Linear and Rotary sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Thresholds 06 - Thresholds for Linear and Rotary sensors
+ * @{ */
+
+/** Linear/Rotary Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_LINROT_PROX_IN_TH (10)
+
+/** Linear/Rotary Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_LINROT_PROX_OUT_TH (5)
+
+/** Linear/Rotary Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_LINROT_DETECT_IN_TH (20)
+
+/** Linear/Rotary Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_LINROT_DETECT_OUT_TH (15)
+
+/** Linear/Rotary re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+ - A low absolute value will result in a higher sensitivity and thus some spurious
+ recalibration may be issued.
+*/
+#define TSLPRM_LINROT_CALIB_TH (20)
+
+/** Linear/Rotary Delta normalization (0=No, 1=Yes)
+ - When this parameter is set, a coefficient is applied on all Delta of all sensors
+ in order to normalize them and to improve the position calculation.
+ - These coefficients must be defined in a constant table in the application (see Library examples).
+ - The MSB is the coefficient integer part, the LSB is the coefficient real part.
+ - Examples:
+ - To apply a factor 1.10:
+ 0x01 to the MSB
+ 0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
+ - To apply a factor 0.90:
+ 0x00 to the MSB
+ 0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
+ - To apply no factor:
+ 0x01 to the MSB
+ 0x00 to the LSB
+*/
+#define TSLPRM_LINROT_USE_NORMDELTA (1)
+
+/** @} Common_Parameters_LinRot_Thresholds */
+
+//==============================================================================
+// Linear/Rotary sensors used
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Used 07 - Linear/Rotary sensors used
+ * @{ */
+
+/** Select which Linear and Rotary sensors you use in your application.
+ - 0 = Not Used
+ - 1 = Used
+
+ LIN = Linear sensor
+ ROT = Rotary sensor
+ M1 = Mono electrodes design with 0/255 position at extremities of the sensor
+ M2 = Mono electrodes design
+ H = Half-ended electrodes design
+ D = Dual electrodes design
+*/
+#define TSLPRM_USE_3CH_LIN_M1 (1)
+#define TSLPRM_USE_3CH_LIN_M2 (1)
+#define TSLPRM_USE_3CH_LIN_H (1)
+#define TSLPRM_USE_3CH_ROT_M (1)
+
+#define TSLPRM_USE_4CH_LIN_M1 (1)
+#define TSLPRM_USE_4CH_LIN_M2 (1)
+#define TSLPRM_USE_4CH_LIN_H (1)
+#define TSLPRM_USE_4CH_ROT_M (1)
+
+#define TSLPRM_USE_5CH_LIN_M1 (1)
+#define TSLPRM_USE_5CH_LIN_M2 (1)
+#define TSLPRM_USE_5CH_LIN_H (1)
+#define TSLPRM_USE_5CH_ROT_M (1)
+#define TSLPRM_USE_5CH_ROT_D (1)
+
+#define TSLPRM_USE_6CH_LIN_M1 (1)
+#define TSLPRM_USE_6CH_LIN_M2 (1)
+#define TSLPRM_USE_6CH_LIN_H (1)
+#define TSLPRM_USE_6CH_ROT_M (1)
+
+/** @} Common_Parameters_LinRot_used */
+
+//==============================================================================
+// Linear/Rotary sensors position
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Position 08 - Linear/Rotary sensors position
+ * @{ */
+
+/** Position resolution in number of bits (range=1..8)
+ - A Low value will result in a low resolution and will be less subject to noise.
+ - A High value will result in a high resolution and will be more subject to noise.
+*/
+#define TSLPRM_LINROT_RESOLUTION (7)
+
+/** Direction change threshold in position unit (range=0..255)
+ - Defines the default threshold used during the change direction process.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_POS (10)
+
+/** Direction change debounce (range=0..63)
+ - Defines the default integrator counter used during the change direction process.
+ - This counter is decremented when the same change in the position is detected and the direction will
+ change after this counter reaches zero.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_DEB (1)
+
+/** @} Common_Parameters_LinRot_Position */
+
+//==============================================================================
+// Debounce counters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Debounce 09 - Debounce counters
+ * @{ */
+
+/** Proximity state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the Proximity detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_PROX (3)
+
+/** Detect state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_DETECT (3)
+
+/** Release state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the end-detection but with less noise filtering.
+ - A High value will result in a lower sensitivity during the end-detection but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_RELEASE (3)
+
+/** Re-calibration state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the recalibration but with less noise filtering.
+ - A High value will result in a lower sensitivity during the recalibration but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_CALIB (3)
+
+/** Error state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity to enter in error state.
+ - A High value will result in a lower sensitivity to enter in error state.
+*/
+#define TSLPRM_DEBOUNCE_ERROR (3)
+
+/** @} Common_Parameters_Debounce */
+
+//==============================================================================
+// Environment Change System (ECS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_ECS 10 - ECS
+ * @{ */
+
+/** Environment Change System Slow K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_SLOW (10)
+
+/** Environment Change System Fast K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_FAST (20)
+
+/** Environment Change System delay in msec (range=0..5000)
+ - The ECS will be started after this delay and when all sensors are in Release state.
+*/
+#define TSLPRM_ECS_DELAY (100)
+
+/** @} Common_Parameters_ECS */
+
+//==============================================================================
+// Detection Time Out (DTO)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DTO 11 - DTO
+ * @{ */
+
+/** Detection Time Out delay in seconds (range=0..63)
+ - Value 0: DTO processing not compiled in the code (to gain size if not used).
+ - Value 1: Default time out infinite.
+ - Value between 2 and 63: Default time out between value n-1 and n.
+ - Examples:
+ - With a DTO equal to 2, the time out is between 1s and 2s.
+ - With a DTO equal to 63, the time out is between 62s and 63s.
+
+@note The DTO can be changed in run-time by the application only if the
+ default value is between 1 and 63.
+*/
+#define TSLPRM_DTO (5)
+
+/** @} Common_Parameters_DTO */
+
+//==============================================================================
+// Detection Exclusion System (DXS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DXS 12 - DXS
+ * @{ */
+
+/** Detection Exclusion System (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_DXS (1)
+
+/** @} Common_Parameters_DXS */
+
+//==============================================================================
+// Miscellaneous parameters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Misc 13 - Miscellaneous
+ * @{ */
+
+/** Timing tick frequency in Hz (range=125, 250, 500, 1000, 2000)
+ - Result to a timing interrupt respectively every 8ms, 4ms, 2ms, 1ms, 0.5ms
+*/
+#define TSLPRM_TICK_FREQ (500)
+
+/** @} Common_Parameters_Misc */
+
+/** @} Common_Parameters */
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++ MCU PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup STM8L_Parameters STM8L Parameters
+ * @{ */
+
+/** @defgroup STM8L_Parameters_Common 01 - Common
+ * @{ */
+
+/** Shield with a channel (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_SHIELD (1)
+
+/** IOs default mode when no on-going acquisition (range=0..1)
+ - 0: Output push-pull low
+ - 1: Input floating
+@note To ensure a correct operation in noisy environment, this parameter must
+be set to output push-pull low.
+*/
+#define TSLPRM_IODEF (1)
+
+/** Delay for discharging Cx and Cs capacitors (range=0..65535)
+ - The value corresponds to the Softdelay function parameter.
+*/
+#define TSLPRM_DELAY_DISCHARGE_ALL (3)
+
+/** @} STM8L_Parameters_Common */
+
+/** @defgroup STM8L_Parameters_Sw 02 - Software acquisition
+ * @{ */
+
+/** IT disabling for IO protection (range=0..1)
+ - 0: IO not protected
+ - 1: IO protected
+@note For software acquisition only
+*/
+#define TSLPRM_PROTECT_IO_ACCESS (1)
+
+/** Delay for charging Cx capacitor (range=0..32)
+ - The value corresponds to a number of NOPs.
+@note For software acquisition only
+*/
+#define TSLPRM_DELAY_CHARGE (3)
+
+/** Delay for transfering charges from Cx to Cs capacitor (range=0..32)
+ - The value corresponds to a number of NOPs.
+@note For software acquisition only
+*/
+#define TSLPRM_DELAY_TRANSFER (3)
+
+/** Use Spread Spectrum (0=No, 1=Yes)
+@note For software acquisition only
+*/
+#define TSLPRM_USE_SPREAD_SPECTRUM (1)
+
+/** Spread min value (range=1..TSLPRM_SPREAD_MAX-1)
+@note For software acquisition only
+*/
+#define TSLPRM_SPREAD_MIN (1)
+
+/** Spread max value (range=TSLPRM_SPREAD_MIN+1..255)
+@note For software acquisition only
+*/
+#define TSLPRM_SPREAD_MAX (20)
+
+/** @} STM8L_Parameters_Sw */
+
+/** @defgroup STM8L_Parameters_Hw 03 - Hardware acquisition
+ * @{ */
+
+/** Charge/transfer Period (in µs)
+ - This is used to calculate the Timer reload value.
+ */
+#define TSLPRM_CT_PERIOD (2)
+
+/** Timer frequency (in MHz)
+ - This is used to calculate the Timer reload value.
+ */
+#define TSLPRM_TIMER_FREQ (16)
+
+/** @} STM8L_Parameters_Hw */
+
+/** @} STM8L_Parameters */
+
+// DO NOT REMOVE !!!
+#include "tsl_check_config.h"
+
+#endif /* __TSL_CONF_STM8L_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8tl5x.h_TOADAPT b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8tl5x.h_TOADAPT
new file mode 100644
index 0000000..adc7da4
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_conf_stm8tl5x.h_TOADAPT
@@ -0,0 +1,598 @@
+/**
+ ******************************************************************************
+ * @file tsl_conf_stm8tl5x.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief Acquisition parameters for STM8TL5x products.
+ * @note This file must be copied in the application project and values
+ * changed for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CONF_STM8TL5X_H
+#define __TSL_CONF_STM8TL5X_H
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++ COMMON PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup Common_Parameters Common Parameters
+ * @{ */
+
+//==============================================================================
+// Number of elements
+//==============================================================================
+
+/** @defgroup Common_Parameters_Number_Of_Elements 01 - Number of elements
+ * @{ */
+
+/** Total number of channels in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_CHANNELS (1)
+
+/** Total number of banks in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_BANKS (1)
+
+/** Total number of "Extended" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS (1)
+
+/** Total number of "Basic" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS_B (1)
+
+/** Total number of "Extended" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS (1)
+
+/** Total number of "Basic" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS_B (1)
+
+/** Total number of sensors/objects in application (range=1..255)
+ - Count all TouchKeys, Linear and Rotary sensors
+*/
+#define TSLPRM_TOTAL_OBJECTS (1)
+
+/** @} Common_Parameters_Number_Of_Elements */
+
+//==============================================================================
+// Optional features
+//==============================================================================
+
+/** @defgroup Common_Parameters_Options 02 - Optional features
+ * @{ */
+
+/** Record the last measure (0=No, 1=Yes)
+ - If No the measure is recalculated using the Reference and Delta
+*/
+#define TSLPRM_USE_MEAS (1)
+
+/** Zone management usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_ZONE (1)
+
+/** Proximity detection usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_PROX (1)
+
+/** Use the Timer tick callback (0=No, 1=Yes)
+ - When equal to 1, the function TSL_CallBack_TimerTick must be defined in
+ the application code. It is called for each timer interruption.
+*/
+#define TSLPRM_USE_TIMER_CALLBACK (1)
+
+/** Acquisition interrupt mode (0=No, 1=Yes)
+ - If No the acquisition is managed in the main routine using polling mode.
+ - If Yes the acquisition is managed in the interrupt routines.
+*/
+#define TSLPRM_USE_ACQ_INTERRUPT (1)
+
+/** @} Common_Parameters_Options */
+
+//==============================================================================
+// Acquisition limits
+//==============================================================================
+
+/** @defgroup Common_Parameters_Acquisition_Limits 03 - Acquisition limits
+ * @{ */
+
+/** Minimum acquisition measurement (range=0..65535)
+ - This is the minimum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is below this value.
+*/
+#define TSLPRM_ACQ_MIN (50)
+
+/** Maximum acquisition measurement (range=0..65535)
+ - This is the maximum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is above this value.
+*/
+#define TSLPRM_ACQ_MAX (4000)
+
+/** @} Common_Parameters_Acquisition_Limits */
+
+//==============================================================================
+// Calibration
+//==============================================================================
+
+/** @defgroup Common_Parameters_Calibration 04 - Calibration
+ * @{ */
+
+/** Number of calibration samples (range=4, 8, 16)
+ - Low value = faster calibration but less precision.
+ - High value = slower calibration but more precision.
+*/
+#define TSLPRM_CALIB_SAMPLES (8)
+
+/** Delay in measurement samples before starting the calibration (range=0..40)
+ - This is useful if a noise filter is used.
+ - Write 0 to disable the delay.
+*/
+#define TSLPRM_CALIB_DELAY (10)
+
+/** @} Common_Parameters_Calibration */
+
+//==============================================================================
+// Thresholds for TouchKey sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_TouchKey_Thresholds 05 - Thresholds for TouchKey sensors
+ * @{ */
+
+/** TouchKeys Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_TKEY_PROX_IN_TH (15)
+
+/** TouchKeys Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_TKEY_PROX_OUT_TH (5)
+
+/** TouchKeys Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_TKEY_DETECT_IN_TH (50)
+
+/** TouchKeys Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_TKEY_DETECT_OUT_TH (40)
+
+/** TouchKeys re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+*/
+#define TSLPRM_TKEY_CALIB_TH (20)
+
+/** TouchKey, Linear and Rotary sensors thresholds coefficient (range=0..4)
+ This multiplier coefficient is applied on Detect and Re-Calibration thresholds only.
+ - 0: feature disabled
+ - 1: thresholds x 2
+ - 2: thresholds x 4
+ - 3: thresholds x 8
+ - 4: thresholds x 16
+*/
+#define TSLPRM_COEFF_TH (1)
+
+/** @} Common_Parameters_TouchKey_Thresholds */
+
+//==============================================================================
+// Thresholds for Linear and Rotary sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Thresholds 06 - Thresholds for Linear and Rotary sensors
+ * @{ */
+
+/** Linear/Rotary Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_LINROT_PROX_IN_TH (15)
+
+/** Linear/Rotary Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_LINROT_PROX_OUT_TH (5)
+
+/** Linear/Rotary Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_LINROT_DETECT_IN_TH (50)
+
+/** Linear/Rotary Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_LINROT_DETECT_OUT_TH (30)
+
+/** Linear/Rotary re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+ - A low absolute value will result in a higher sensitivity and thus some spurious
+ recalibration may be issued.
+*/
+#define TSLPRM_LINROT_CALIB_TH (20)
+
+/** Linear/Rotary Delta normalization (0=No, 1=Yes)
+ - When this parameter is set, a coefficient is applied on all Delta of all sensors
+ in order to normalize them and to improve the position calculation.
+ - These coefficients must be defined in a constant table in the application (see Library examples).
+ - The MSB is the coefficient integer part, the LSB is the coefficient real part.
+ - Examples:
+ - To apply a factor 1.10:
+ 0x01 to the MSB
+ 0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
+ - To apply a factor 0.90:
+ 0x00 to the MSB
+ 0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
+ - To apply no factor:
+ 0x01 to the MSB
+ 0x00 to the LSB
+*/
+#define TSLPRM_LINROT_USE_NORMDELTA (1)
+
+/** @} Common_Parameters_LinRot_Thresholds */
+
+//==============================================================================
+// Linear/Rotary sensors used
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Used 07 - Linear/Rotary sensors used
+ * @{ */
+
+/** Select which Linear and Rotary sensors you use in your application.
+ - 0 = Not Used
+ - 1 = Used
+
+ LIN = Linear sensor
+ ROT = Rotary sensor
+ M1 = Mono electrodes design with 0/255 position at extremities of the sensor
+ M2 = Mono electrodes design
+ H = Half-ended electrodes design
+ D = Dual electrodes design
+*/
+#define TSLPRM_USE_3CH_LIN_M1 (1)
+#define TSLPRM_USE_3CH_LIN_M2 (1)
+#define TSLPRM_USE_3CH_LIN_H (1)
+#define TSLPRM_USE_3CH_ROT_M (1)
+
+#define TSLPRM_USE_4CH_LIN_M1 (1)
+#define TSLPRM_USE_4CH_LIN_M2 (1)
+#define TSLPRM_USE_4CH_LIN_H (1)
+#define TSLPRM_USE_4CH_ROT_M (1)
+
+#define TSLPRM_USE_5CH_LIN_M1 (1)
+#define TSLPRM_USE_5CH_LIN_M2 (1)
+#define TSLPRM_USE_5CH_LIN_H (1)
+#define TSLPRM_USE_5CH_ROT_M (1)
+#define TSLPRM_USE_5CH_ROT_D (1)
+
+#define TSLPRM_USE_6CH_LIN_M1 (1)
+#define TSLPRM_USE_6CH_LIN_M2 (1)
+#define TSLPRM_USE_6CH_LIN_H (1)
+#define TSLPRM_USE_6CH_ROT_M (1)
+
+/** @} Common_Parameters_LinRot_used */
+
+//==============================================================================
+// Linear/Rotary sensors position
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Position 08 - Linear/Rotary sensors position
+ * @{ */
+
+/** Position resolution in number of bits (range=1..8)
+ - A Low value will result in a low resolution and will be less subject to noise.
+ - A High value will result in a high resolution and will be more subject to noise.
+*/
+#define TSLPRM_LINROT_RESOLUTION (7)
+
+/** Direction change threshold in position unit (range=0..255)
+ - Defines the default threshold used during the change direction process.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_POS (10)
+
+/** Direction change debounce (range=0..63)
+ - Defines the default integrator counter used during the change direction process.
+ - This counter is decremented when the same change in the position is detected and the direction will
+ change after this counter reaches zero.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_DEB (1)
+
+/** @} Common_Parameters_LinRot_Position */
+
+//==============================================================================
+// Debounce counters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Debounce 09 - Debounce counters
+ * @{ */
+
+/** Proximity state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the Proximity detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_PROX (3)
+
+/** Detect state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_DETECT (3)
+
+/** Release state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the end-detection but with less noise filtering.
+ - A High value will result in a lower sensitivity during the end-detection but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_RELEASE (3)
+
+/** Re-calibration state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the recalibration but with less noise filtering.
+ - A High value will result in a lower sensitivity during the recalibration but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_CALIB (3)
+
+/** Error state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity to enter in error state.
+ - A High value will result in a lower sensitivity to enter in error state.
+*/
+#define TSLPRM_DEBOUNCE_ERROR (3)
+
+/** @} Common_Parameters_Debounce */
+
+//==============================================================================
+// Environment Change System (ECS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_ECS 10 - ECS
+ * @{ */
+
+/** Environment Change System Slow K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_SLOW (5)
+
+/** Environment Change System Fast K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_FAST (40)
+
+/** Environment Change System delay in msec (range=0..5000)
+ - The ECS will be started after this delay and when all sensors are in Release state.
+*/
+#define TSLPRM_ECS_DELAY (500)
+
+/** @} Common_Parameters_ECS */
+
+//==============================================================================
+// Detection Time Out (DTO)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DTO 11 - DTO
+ * @{ */
+
+/** Detection Time Out delay in seconds (range=0..63)
+ - Value 0: DTO processing not compiled in the code (to gain size if not used).
+ - Value 1: Default time out infinite.
+ - Value between 2 and 63: Default time out between value n-1 and n.
+ - Examples:
+ - With a DTO equal to 2, the time out is between 1s and 2s.
+ - With a DTO equal to 63, the time out is between 62s and 63s.
+
+@note The DTO can be changed in run-time by the application only if the
+ default value is between 1 and 63.
+*/
+#define TSLPRM_DTO (5)
+
+/** @} Common_Parameters_DTO */
+
+//==============================================================================
+// Detection Exclusion System (DXS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DXS 12 - DXS
+ * @{ */
+
+/** Detection Exclusion System (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_DXS (1)
+
+/** @} Common_Parameters_DXS */
+
+//==============================================================================
+// Miscellaneous parameters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Misc 13 - Miscellaneous
+ * @{ */
+
+/** Timing tick frequency in Hz (range=125, 250, 500, 1000, 2000)
+ - Result to a timing interrupt respectively every 8ms, 4ms, 2ms, 1ms, 0.5ms
+*/
+#define TSLPRM_TICK_FREQ (1000)
+
+/** @} Common_Parameters_Misc */
+
+/** @} Common_Parameters */
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++ MCU PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// DO NOT MODIFY THE LINES BELOW!!!
+#define STM8TL53C4 (0)
+#define STM8TL53G4 (1)
+#define STM8TL53F4 (2)
+#define STM8TL52G4 (3)
+#define STM8TL52F4 (4)
+
+/** @defgroup STM8TL5x_Parameters STM8TL5x Parameters
+ * @{ */
+
+//==============================================================================
+// Device selection
+//==============================================================================
+
+/** @defgroup STM8TL5x_Parameters_Device_Selection 01 - Device Selection
+ * @{ */
+
+/** STM8TL5x device selection (range=0..4)
+ - Select a MCU in the above list
+*/
+#define TSLPRM_MCU STM8TL53C4
+
+/** @} STM8TL5x_Parameters_Device_Selection */
+
+//==============================================================================
+// Reference adjustment
+//==============================================================================
+
+/** @defgroup STM8TL5x_Parameters_Reference_Adjustment 02 - Reference adjustment
+ * @{ */
+
+/** Used to calibrate the EPCC to get the Reference closed to this value (range=100..2000)
+ - The range values are recommended values.
+ - The higher the Reference, the higher the sensitivity
+*/
+#define TSLPRM_KEY_TARGET_REFERENCE (500)
+
+/** Used to calibrate the EPCC (range=1..TSLPRM_KEY_TARGET_REFERENCE)
+*/
+#define TSLPRM_KEY_TARGET_REFERENCE_ERROR (25)
+
+/** Number of iteration after the dichotomy to fine tune the EPCC value (range=3..5)
+*/
+#define TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION (3)
+
+/** Used to calibrate the CS (range=1,2,4,8)
+*/
+#define TSLPRM_KEY_TARGET_ATTENUATION (4)
+
+/** Below (TSLPRM_KEY_TARGET_REFERENCE - TSLPRM_TOUCHKEY_REFERENCE_RANGE) the EPCC is updated for the TKeys (range=1..TSLPRM_KEY_TARGET_REFERENCE)
+*/
+#define TSLPRM_TOUCHKEY_REFERENCE_RANGE (75)
+
+/** Below (TSLPRM_KEY_TARGET_REFERENCE - TSLPRM_LINROT_REFERENCE_RANGE) the EPCC is updated for the Linear/Rotary (range=1..TSLPRM_KEY_TARGET_REFERENCE)
+*/
+#define TSLPRM_LINROT_REFERENCE_RANGE (75)
+
+/** @} STM8TL5x_Parameters_Reference_Adjustment */
+
+//==============================================================================
+// PXS Clock
+//==============================================================================
+
+/** @defgroup STM8TL5x_Parameters_PXS_Clock 03 - PXS Clock
+ - These parameters define the acquisition clock settings.
+ * @{ */
+
+/** Acquisition frequency (values are 16000, 8000, 4000, 2000, 1000, 500, 250 or 125)
+*/
+#define TSLPRM_PXS_HSI (16000)
+
+/** Up phase length (range=1..7)
+*/
+#define TSLPRM_PXS_UP_LENGTH (1)
+
+/** Pass phase length (range=1..7)
+*/
+#define TSLPRM_PXS_PASS_LENGTH (1)
+
+/** @} STM8TL5x_Parameters_PXS_Clock */
+
+//==============================================================================
+// PXS Synchro
+//==============================================================================
+
+/** @defgroup STM8TL5x_Parameters_PXS_Synchro 04 - PXS Synchro
+ * @{ */
+
+/** Acquisition synchronized with SYNCHRO pin (0=No, 1=Yes)
+*/
+#define TSLPRM_PXS_SYNCHRONIZE (1)
+
+/** Synchronization edge (0=Fall, 1=Rise)
+*/
+#define TSLPRM_PXS_SYNCHRO_EDGE (1)
+
+/** @} STM8TL5x_Parameters_PXS_Synchro */
+
+//==============================================================================
+// PXS Miscellaneous
+//==============================================================================
+
+/** @defgroup STM8TL5x_Parameters_PXS_Miscellaneous 05 - PXS Miscellaneous
+ * @{ */
+
+/** Low power mode between acquisition (0=No, 1=Yes)
+*/
+#define TSLPRM_PXS_LOW_POWER_MODE (1)
+
+/** RF detection (0=No, 1=Yes)
+*/
+#define TSLPRM_PXS_RF_DETECTION (1)
+
+/** Transmitter inactive state (0=Grounded, 1=Floating)
+@note To ensure a correct operation in noisy environment, this parameter should
+be configured to Grounded state.
+*/
+#define TSLPRM_PXS_INACTIVE_TX (1)
+
+/** Receiver inactive state (0=Grounded, 1=Floating)
+@note To ensure a correct operation in noisy environment, this parameter should
+be configured to Grounded state.
+*/
+#define TSLPRM_PXS_INACTIVE_RX (1)
+
+/** Charge/Discharge cycle behaviour after VTHR is reached (0=stop, 1=continue)
+*/
+#define TSLPRM_PXS_RX_COUPLING (1)
+
+/** Stabilization time (values are LONG_STAB, MEDIUM_STAB, SHORT_STAB)
+*/
+#define TSLPRM_PXS_STAB LONG_STAB
+
+/** Bias (values are HIGH_BIAS, MEDIUM_BIAS, LOW_BIAS, VERY_LOW_BIAS)
+*/
+#define TSLPRM_PXS_BIAS HIGH_BIAS
+
+/** Index maximum of Rx channels ("N" of RxN)
+ - This value must not exceed 9 with STM8TL53C4 and 7 with STM8TL53G4
+*/
+#define TSLPRM_HIGH_CHANNEL_NB (9)
+
+/** @} STM8TL5x_Parameters_PXS_Miscellaneous */
+
+/** @} STM8TL5x_Parameters */
+
+// DO NOT REMOVE !!!
+#include "tsl_check_config.h"
+
+#endif /* __TSL_CONF_STM8TL5X_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_dxs.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_dxs.h
new file mode 100644
index 0000000..1d4f36b
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_dxs.h
@@ -0,0 +1,43 @@
+/**
+ ******************************************************************************
+ * @file tsl_dxs.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_dxs.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_DXS_H
+#define __TSL_DXS_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_object.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+void TSL_dxs_FirstObj(CONST TSL_ObjectGroup_T *objgrp);
+
+#endif /* __TSL_DXS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_ecs.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_ecs.h
new file mode 100644
index 0000000..36482fa
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_ecs.h
@@ -0,0 +1,45 @@
+/**
+ ******************************************************************************
+ * @file tsl_ecs.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_ecs.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_ECS_H
+#define __TSL_ECS_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_object.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+TSL_tKCoeff_T TSL_ecs_CalcK(TSL_ObjectGroup_T *objgrp, TSL_tKCoeff_T k_slow, TSL_tKCoeff_T k_fast);
+void TSL_ecs_ProcessK(TSL_ObjectGroup_T *objgrp, TSL_tKCoeff_T Kcoeff);
+TSL_Status_enum_T TSL_ecs_Process(TSL_ObjectGroup_T *objgrp);
+
+#endif /* __TSL_ECS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_filter.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_filter.h
new file mode 100644
index 0000000..ed3ce0a
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_filter.h
@@ -0,0 +1,41 @@
+/**
+ ******************************************************************************
+ * @file tsl_filter.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_filter.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_FILTER_H
+#define __TSL_FILTER_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq.h"
+
+/* Exported types ------------------------------------------------------------*/
+TSL_tMeas_T TSL_filt_MeasFilter(TSL_tMeas_T measn1, TSL_tMeas_T measn);
+TSL_tDelta_T TSL_filt_DeltaFilter(TSL_tDelta_T delta);
+
+#endif /* __TSL_FILTER_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_globals.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_globals.h
new file mode 100644
index 0000000..43e610f
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_globals.h
@@ -0,0 +1,87 @@
+/**
+ ******************************************************************************
+ * @file tsl_globals.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_globals.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_GLOBALS_H
+#define __TSL_GLOBALS_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq.h"
+#include "tsl_object.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+/** Store all global variables shared between the STMTouch Driver and the Application.
+ */
+typedef struct
+{
+ TSL_tTick_ms_T Tick_ms; /**< Incremented each 0.5ms by timing interrupt routine */
+ TSL_tTick_sec_T Tick_sec; /**< Incremented each second by timing interrupt routine */
+ CONST TSL_Bank_T *Bank_Array; /**< Pointer to the array containing all Banks */
+ TSL_tIndex_T This_Bank; /**< Pointer to the current Bank */
+ CONST TSL_Object_T *This_Obj; /**< Pointer to the current Object */
+#if TSLPRM_USE_ZONE > 0
+ CONST TSL_Zone_T *This_Zone; /**< Pointer to the current Zone */
+ TSL_tIndex_T Index_In_This_Zone; /**< Index in the current Zone */
+#endif
+#if TSLPRM_TOTAL_TKEYS > 0
+ CONST TSL_TouchKey_T *This_TKey; /**< Pointer to the current TKey */
+#endif
+#if TSLPRM_TOTAL_LNRTS > 0
+ CONST TSL_LinRot_T *This_LinRot; /**< Pointer to the current Linear or Rotary sensor */
+#endif
+}
+TSL_Globals_T;
+
+/** Store all global parametersshared between the STMTouch Driver and the Application .
+ @warning Only one variable of this structure type must be created and be placed
+ in RAM only.
+ */
+typedef struct
+{
+ TSL_tMeas_T AcqMin; /**< Acquisition minimum limit */
+ TSL_tMeas_T AcqMax; /**< Acquisition maximum limit */
+ TSL_tNb_T NbCalibSamples; /**< Number of Calibration samples */
+ TSL_tTick_sec_T DTO; /**< Detection Time Out */
+#if TSLPRM_TOTAL_TKEYS > 0
+ CONST TSL_State_T *p_TKeySM; /**< Default state machine for TouchKey sensors */
+ CONST TSL_TouchKeyMethods_T *p_TKeyMT; /**< Default methods for TouchKey sensors */
+#endif
+#if TSLPRM_TOTAL_LNRTS > 0
+ CONST TSL_State_T *p_LinRotSM; /**< Default state machine for Linear/Rotary sensors */
+ CONST TSL_LinRotMethods_T *p_LinRotMT; /**< Default methods for Linear/Rotary sensors */
+#endif
+}
+TSL_Params_T;
+
+/* Exported variables --------------------------------------------------------*/
+extern TSL_Globals_T TSL_Globals;
+extern TSL_Params_T TSL_Params;
+
+#endif /* __TSL_GLOBALS_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_linrot.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_linrot.h
new file mode 100644
index 0000000..e0571b7
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_linrot.h
@@ -0,0 +1,226 @@
+/**
+ ******************************************************************************
+ * @file tsl_linrot.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_linrot.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_LINROT_H
+#define __TSL_LINROT_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq.h"
+#include "tsl_time.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+/** Contains all data related to Linear and Rotary sensor.
+ * Variables of this structure type must be placed in RAM only.
+ */
+typedef struct
+{
+ TSL_StateId_enum_T StateId; /**< Current state identifier */
+ TSL_tPosition_T RawPosition; /**< Raw position */
+ TSL_tPosition_T Position; /**< Scaled position */
+ TSL_tCounter_T CounterDebounce; /**< Counter for debounce and calibration management */
+ unsigned int CounterDTO : 6; /**< Counter for DTO management (TSL_tCounter_T) */
+ unsigned int Change : 1; /**< The State is different from the previous one (TSL_StateChange_enum_T) */
+ unsigned int PosChange : 1; /**< The RawPosition/Position is different from the previous one (TSL_StateChange_enum_T) */
+ unsigned int CounterDirection : 6; /**< Counter for direction debounce management (TSL_tCounter_T) */
+ unsigned int DxSLock : 1; /**< The State is locked by the DxS (TSL_Bool_enum_T) */
+ unsigned int Direction : 1; /**< Movement direction (TSL_Bool_enum_T) */
+}
+TSL_LinRotData_T;
+
+/** Contains all parameters related to Linear and Rotary sensor.
+ * Variables of this structure type can be placed in RAM or ROM.
+ */
+typedef struct
+{
+ // Thresholds
+#if TSLPRM_USE_PROX > 0
+ TSL_tThreshold_T ProxInTh; /**< Proximity state in threshold */
+ TSL_tThreshold_T ProxOutTh; /**< Proximity state out threshold */
+#endif
+ TSL_tThreshold_T DetectInTh; /**< Detection state in threshold */
+ TSL_tThreshold_T DetectOutTh; /**< Detection state out threshold */
+ TSL_tThreshold_T CalibTh; /**< Calibration state threshold */
+ // Debounce counters
+ TSL_tCounter_T CounterDebCalib; /**< Debounce counter to enter in Calibration state */
+#if TSLPRM_USE_PROX > 0
+ TSL_tCounter_T CounterDebProx; /**< Debounce counter to enter in Proximity state */
+#endif
+ TSL_tCounter_T CounterDebDetect; /**< Debounce counter to enter in Detect state */
+ TSL_tCounter_T CounterDebRelease; /**< Debounce counter to enter in Release state */
+ TSL_tCounter_T CounterDebError; /**< Debounce counter to enter in Error state */
+ TSL_tCounter_T CounterDebDirection; /**< Debounce counter for the direction change */
+ // Other parameters
+ TSL_tCounter_T Resolution; /**< Position resolution */
+ TSL_tPosition_T DirChangePos; /**< Direction change position threshold */
+}
+TSL_LinRotParam_T;
+
+/** Contains definition of a Linear and Rotary sensor.
+ * Variables of this structure type can be placed in RAM or ROM.
+ */
+typedef struct
+{
+ TSL_LinRotData_T *p_Data; /**< Data (state id, counter, flags, ...) */
+ TSL_LinRotParam_T *p_Param; /**< Parameters (thresholds, debounce, ...) */
+ TSL_ChannelData_T *p_ChD; /**< First Channel Data (Meas, Ref, Delta, ...) */
+ TSL_tNb_T NbChannels; /**< Number of channels */
+ CONST uint16_t *p_DeltaCoeff; /**< Coefficient to apply on Delta */
+ CONST TSL_tsignPosition_T *p_PosOff; /**< Position offset table */
+ TSL_tNb_T SctComp; /**< Sector Computation */
+ TSL_tNb_T PosCorr; /**< Position Correction */
+ CONST TSL_State_T *p_SM; /**< State Machine */
+ CONST TSL_LinRotMethods_T *p_Methods; /**< Methods */
+}
+TSL_LinRot_T;
+
+/** Contains definition of a Basic Linear and Rotary sensor.
+ * Variables of this structure type can be placed in RAM or ROM.
+ * Basic sensor does not contain its own state machine and methods. It used
+ * default ones instead to gain memory space.
+ */
+typedef struct
+{
+ TSL_LinRotData_T *p_Data; /**< Data (state id, counter, flags, ...) */
+ TSL_LinRotParam_T *p_Param; /**< Parameters (thresholds, debounce, ...) */
+ TSL_ChannelData_T *p_ChD; /**< First Channel Data (Meas, Ref, Delta, ...) */
+ TSL_tNb_T NbChannels; /**< Number of channels */
+ CONST uint16_t *p_DeltaCoeff; /**< Coefficient to apply on Delta */
+ CONST TSL_tsignPosition_T *p_PosOff; /**< Position offset table */
+ TSL_tNb_T SctComp; /**< Sector Computation */
+ TSL_tNb_T PosCorr; /**< Position Correction */
+}
+TSL_LinRotB_T;
+
+/* Exported variables --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+// "Object methods" functions
+void TSL_linrot_Init(void);
+void TSL_linrot_Process(void);
+TSL_Status_enum_T TSL_linrot_CalcPos(void);
+
+// Utility functions
+void TSL_linrot_SetStateCalibration(TSL_tCounter_T delay);
+void TSL_linrot_SetStateOff(void);
+#if !defined(TSLPRM_STM8TL5X) && !defined(STM8TL5X)
+void TSL_linrot_SetStateBurstOnly(void);
+#endif
+TSL_StateId_enum_T TSL_linrot_GetStateId(void);
+TSL_StateMask_enum_T TSL_linrot_GetStateMask(void);
+TSL_tNb_T TSL_linrot_IsChanged(void);
+
+// State machine functions
+void TSL_linrot_CalibrationStateProcess(void);
+void TSL_linrot_DebCalibrationStateProcess(void);
+void TSL_linrot_ReleaseStateProcess(void);
+void TSL_linrot_DebReleaseProxStateProcess(void);
+void TSL_linrot_DebReleaseDetectStateProcess(void);
+void TSL_linrot_DebReleaseTouchStateProcess(void);
+void TSL_linrot_ProxStateProcess(void);
+void TSL_linrot_DebProxStateProcess(void);
+void TSL_linrot_DebProxDetectStateProcess(void);
+void TSL_linrot_DebProxTouchStateProcess(void);
+void TSL_linrot_DetectStateProcess(void);
+void TSL_linrot_DebDetectStateProcess(void);
+void TSL_linrot_TouchStateProcess(void);
+void TSL_linrot_DebTouchStateProcess(void);
+void TSL_linrot_ErrorStateProcess(void);
+void TSL_linrot_DebErrorStateProcess(void);
+void TSL_linrot_OffStateProcess(void);
+
+// Position offset constant tables and corrections
+
+extern CONST TSL_tsignPosition_T TSL_POSOFF_3CH_LIN_M1[3][3];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_3CH_LIN_M2[3][3];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_3CH_LIN_H[3][3];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_3CH_ROT_M[3][3];
+
+extern CONST TSL_tsignPosition_T TSL_POSOFF_4CH_LIN_M1[4][4];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_4CH_LIN_M2[4][4];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_4CH_LIN_H[4][4];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_4CH_ROT_M[4][4];
+
+extern CONST TSL_tsignPosition_T TSL_POSOFF_5CH_LIN_M1[5][5];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_5CH_LIN_M2[5][5];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_5CH_LIN_H[5][5];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_5CH_ROT_M[5][5];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_5CH_ROT_D[5][5];
+
+extern CONST TSL_tsignPosition_T TSL_POSOFF_6CH_LIN_M1[6][6];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_6CH_LIN_M2[6][6];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_6CH_LIN_H[6][6];
+extern CONST TSL_tsignPosition_T TSL_POSOFF_6CH_ROT_M[6][6];
+
+#define TSL_SCTCOMP_3CH_LIN_M1 ((TSL_tNb_T)(128))
+#define TSL_POSCORR_3CH_LIN_M1 ((TSL_tNb_T)( 64))
+#define TSL_SCTCOMP_3CH_LIN_M2 ((TSL_tNb_T)(256))
+#define TSL_POSCORR_3CH_LIN_M2 ((TSL_tNb_T)(256))
+
+#define TSL_SCTCOMP_3CH_LIN_H ((TSL_tNb_T)(128))
+#define TSL_POSCORR_3CH_LIN_H ((TSL_tNb_T)(128))
+
+#define TSL_SCTCOMP_3CH_ROT_M ((TSL_tNb_T)( 85))
+
+#define TSL_SCTCOMP_4CH_LIN_M1 ((TSL_tNb_T)( 85))
+#define TSL_POSCORR_4CH_LIN_M1 ((TSL_tNb_T)( 43))
+#define TSL_SCTCOMP_4CH_LIN_M2 ((TSL_tNb_T)(128))
+#define TSL_POSCORR_4CH_LIN_M2 ((TSL_tNb_T)(128))
+
+#define TSL_SCTCOMP_4CH_LIN_H ((TSL_tNb_T)( 85))
+#define TSL_POSCORR_4CH_LIN_H ((TSL_tNb_T)( 85))
+
+#define TSL_SCTCOMP_4CH_ROT_M ((TSL_tNb_T)( 64))
+
+#define TSL_SCTCOMP_5CH_LIN_M1 ((TSL_tNb_T)( 64))
+#define TSL_POSCORR_5CH_LIN_M1 ((TSL_tNb_T)( 32))
+#define TSL_SCTCOMP_5CH_LIN_M2 ((TSL_tNb_T)( 85))
+#define TSL_POSCORR_5CH_LIN_M2 ((TSL_tNb_T)( 85))
+
+#define TSL_SCTCOMP_5CH_LIN_H ((TSL_tNb_T)( 64))
+#define TSL_POSCORR_5CH_LIN_H ((TSL_tNb_T)( 64))
+
+#define TSL_SCTCOMP_5CH_ROT_M ((TSL_tNb_T)( 51))
+
+#define TSL_SCTCOMP_5CH_ROT_D ((TSL_tNb_T)( 26))
+
+#define TSL_SCTCOMP_6CH_LIN_M1 ((TSL_tNb_T)( 51))
+#define TSL_POSCORR_6CH_LIN_M1 ((TSL_tNb_T)( 25))
+#define TSL_SCTCOMP_6CH_LIN_M2 ((TSL_tNb_T)( 64))
+#define TSL_POSCORR_6CH_LIN_M2 ((TSL_tNb_T)( 64))
+
+#define TSL_SCTCOMP_6CH_LIN_H ((TSL_tNb_T)( 51))
+#define TSL_POSCORR_6CH_LIN_H ((TSL_tNb_T)( 51))
+
+#define TSL_SCTCOMP_6CH_ROT_M ((TSL_tNb_T)( 43))
+
+#endif /* __TSL_LINROT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_object.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_object.h
new file mode 100644
index 0000000..64b4d01
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_object.h
@@ -0,0 +1,89 @@
+/**
+ ******************************************************************************
+ * @file tsl_object.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_object.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_OBJECT_H
+#define __TSL_OBJECT_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_touchkey.h"
+#include "tsl_linrot.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+#define TSL_OBJ_TYPE_TKEY_MASK (0x10) /**< TouchKey object mask */
+#define TSL_OBJ_TYPE_LINROT_MASK (0x20) /**< Linear and Rotary objects mask */
+#define TSL_OBJ_TYPE_TRACKNAV_MASK (0x40) /**< TrackPad and NaviPad objects mask */
+
+/** Contains all different kinds of sensors.
+ */
+typedef enum
+{
+ TSL_OBJ_TOUCHKEY = (TSL_OBJ_TYPE_TKEY_MASK + 0), /**< Normal TouchKey */
+ TSL_OBJ_TOUCHKEYB = (TSL_OBJ_TYPE_TKEY_MASK + 1), /**< Basic TouchKey */
+ TSL_OBJ_LINEAR = (TSL_OBJ_TYPE_LINROT_MASK + 0), /**< Normal Linear sensor */
+ TSL_OBJ_LINEARB = (TSL_OBJ_TYPE_LINROT_MASK + 1), /**< Basic Linear sensor */
+ TSL_OBJ_ROTARY = (TSL_OBJ_TYPE_LINROT_MASK + 2), /**< Normal Rotary sensor */
+ TSL_OBJ_ROTARYB = (TSL_OBJ_TYPE_LINROT_MASK + 3), /**< Basic Rotary sensor */
+ TSL_OBJ_TRACKPAD = (TSL_OBJ_TYPE_TRACKNAV_MASK + 0), /**< TrackPad sensor */
+ TSL_OBJ_NAVIPAD = (TSL_OBJ_TYPE_TRACKNAV_MASK + 1) /**< NaviPad sensor */
+} TSL_ObjectType_enum_T;
+
+/** Contains the definition of an Object.
+ * Variables of this structure type can be placed in RAM or ROM.
+ */
+typedef struct
+{
+ TSL_ObjectType_enum_T Type; /**< Object type */
+ void *Elmt; /**< Pointer to the object */
+} TSL_Object_T;
+
+/** Contains the definition of a Group of Objects.
+ * Variables of this structure type must be placed in RAM only.
+ */
+typedef struct
+{
+ CONST TSL_Object_T *p_Obj; /**< Pointer to the first object */
+ TSL_tNb_T NbObjects; /**< Number of objects in the group */
+ TSL_tNb_T StateMask; /**< "OR" of all objects state mask */
+ TSL_StateChange_enum_T Change; /**< The State is different from the previous one */
+ TSL_tIndex_T ECS_exec; /**< Flag for the ECS execution */
+#if TSLPRM_ECS_DELAY > 0
+ TSL_tIndex_T ECS_wait; /**< Flag for the ECS delay */
+ TSL_tTick_ms_T ECS_start_time; /**< Keep the time for the ECS delay */
+#endif
+} TSL_ObjectGroup_T;
+
+/* Exported functions --------------------------------------------------------*/
+
+void TSL_obj_GroupInit(TSL_ObjectGroup_T *objgrp);
+void TSL_obj_GroupProcess(TSL_ObjectGroup_T *objgrp);
+void TSL_obj_SetGlobalObj(CONST TSL_Object_T *pobj);
+
+#endif /* __TSL_OBJECT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_time.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time.h
new file mode 100644
index 0000000..00875e4
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time.h
@@ -0,0 +1,88 @@
+/**
+ ******************************************************************************
+ * @file tsl_time.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_time.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TIME_H
+#define __TSL_TIME_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#if defined(STM8L10X) || defined(STM8L15X_MD) || defined(STM8L15X_MDP) || defined(STM8L15X_HD)
+#include "tsl_acq_stm8l_sw.h" // Software acquisition
+#include "tsl_time_stm8l.h"
+#endif
+
+#if defined(STM8L15X_LD)
+#if defined(TSLPRM_STM8L1XX_SW_ACQ)
+#include "tsl_acq_stm8l_sw.h" // Software acquisition
+#else
+#include "tsl_acq_stm8l_hw.h" // Hardware acquisition with Timers (default)
+#endif
+#include "tsl_time_stm8l.h"
+#endif
+
+#if defined(STM8TL5X)
+#include "tsl_acq_stm8tl5x.h"
+#include "tsl_time_stm8tl5x.h"
+#endif
+
+#if defined(STM32L1XX_MD)
+#include "tsl_acq_stm32l1xx_sw.h" // Software acquisition only
+#include "tsl_time_stm32l1xx.h"
+#endif
+
+#if defined(STM32L1XX_MDP) || defined(STM32L1XX_HD) || defined(STM32L1XX_XL)
+#if defined(TSLPRM_STM32L1XX_SW_ACQ)
+#include "tsl_acq_stm32l1xx_sw.h" // Software acquisition
+#else
+#include "tsl_acq_stm32l1xx_hw.h" // Hardware acquisition with Timers (default)
+#endif
+#include "tsl_time_stm32l1xx.h"
+#endif
+
+#if defined(STM32F0XX) || defined(STM32F0XX_MD) || defined(STM32F0XX_HD) ||\
+ defined(STM32F051) || defined(STM32F072) || defined(STM32F042)
+#include "tsl_acq_stm32f0xx.h"
+#include "tsl_time_stm32f0xx.h"
+#endif
+
+#if defined(STM32F303xC) || defined(STM32F334x8) || defined(STM32F303x8) || defined(STM32F301x8) || defined(STM32F302x8) ||\
+ defined(STM32F37X)
+#include "tsl_acq_stm32f3xx.h"
+#include "tsl_time_stm32f3xx.h"
+#endif
+
+/* Exported functions ------------------------------------------------------- */
+
+void TSL_tim_ProcessIT(void);
+TSL_Status_enum_T TSL_tim_CheckDelay_ms(TSL_tTick_ms_T delay_ms, __IO TSL_tTick_ms_T *last_tick);
+TSL_Status_enum_T TSL_tim_CheckDelay_sec(TSL_tTick_sec_T delay_sec, __IO TSL_tTick_sec_T *last_tick);
+void TSL_CallBack_TimerTick(void);
+
+#endif /* __TSL_TIME_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f0xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f0xx.h
new file mode 100644
index 0000000..6216974
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f0xx.h
@@ -0,0 +1,51 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm32f0xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_time_stm32f0xx.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TIME_STM32F0XX_H
+#define __TSL_TIME_STM32F0XX_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f0xx.h"
+#include "stm32f0xx_rcc.h"
+#include "tsl_conf_stm32f0xx.h"
+#include "tsl_types.h"
+
+// Îïðåäåëåíèÿ äëÿ òàéìåðà TouchSense --------------------------------------- //
+#define TS_TIM_IRQHandler TIM15_IRQHandler
+#define TS_TIMx TIM15
+#define TS_TIM_RCC RCC_APB2Periph_TIM15
+#define TS_TIM_IRQx TIM15_IRQn
+#define TS_RCC_APBxPeriphClockCmd RCC_APB2PeriphClockCmd
+
+/* Exported types ------------------------------------------------------------*/
+
+TSL_Status_enum_T TSL_tim_Init(void);
+
+#endif /* __TSL_TIME_STM32F0XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f3xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f3xx.h
new file mode 100644
index 0000000..c121e22
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32f3xx.h
@@ -0,0 +1,51 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm32f3xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_time_stm32f3xx.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TIME_STM32F3XX_H
+#define __TSL_TIME_STM32F3XX_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#if defined(STM32F303xC) || defined(STM32F334x8) || defined(STM32F303x8) || defined(STM32F301x8) || defined(STM32F302x8)
+#include "stm32f30x.h"
+#endif
+
+#if defined(STM32F37X)
+#include "stm32f37x.h"
+#endif
+
+#include "tsl_conf_stm32f3xx.h"
+#include "tsl_types.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+TSL_Status_enum_T TSL_tim_Init(void);
+
+#endif /* __TSL_TIME_STM32F3XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32l1xx.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32l1xx.h
new file mode 100644
index 0000000..a693dc4
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm32l1xx.h
@@ -0,0 +1,43 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm32l1xx.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_time_stm32l1xx.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TIME_STM32L1XX_H
+#define __TSL_TIME_STM32L1XX_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32l1xx.h"
+#include "tsl_conf_stm32l1xx.h"
+#include "tsl_types.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+TSL_Status_enum_T TSL_tim_Init(void);
+
+#endif /* __TSL_TIME_STM32L1XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8l.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8l.h
new file mode 100644
index 0000000..94d549f
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8l.h
@@ -0,0 +1,51 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm8l.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_time_stm8l.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TIME_STM8L_H
+#define __TSL_TIME_STM8L_H
+
+/* Includes ------------------------------------------------------------------*/
+
+#if defined(STM8L15X_LD) || defined(STM8L15X_MD) || defined(STM8L15X_MDP) || defined(STM8L15X_HD)
+#include "stm8l15x.h"
+#endif
+
+#if defined(STM8L10X)
+#include "stm8l10x.h"
+#endif
+
+#include "tsl_conf_stm8l.h"
+#include "tsl_types.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+TSL_Status_enum_T TSL_tim_Init(void);
+
+#endif /* __TSL_TIME_STM8L_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8tl5x.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8tl5x.h
new file mode 100644
index 0000000..70c0121
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_time_stm8tl5x.h
@@ -0,0 +1,43 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm8tl5x.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_time_stm8tl5x.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TIME_STM8TL5X_H
+#define __TSL_TIME_STM8TL5X_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm8tl5x.h"
+#include "tsl_conf_stm8tl5x.h"
+#include "tsl_types.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+TSL_Status_enum_T TSL_tim_Init(void);
+
+#endif /* __TSL_TIME_STM8TL5X_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_touchkey.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_touchkey.h
new file mode 100644
index 0000000..04b4d73
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_touchkey.h
@@ -0,0 +1,139 @@
+/**
+ ******************************************************************************
+ * @file tsl_touchkey.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains external declarations of the tsl_touchkey.c file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TOUCHKEY_H
+#define __TSL_TOUCHKEY_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq.h"
+#include "tsl_time.h"
+
+/* Exported types ------------------------------------------------------------*/
+
+/** Contains all data related to TouchKey sensor.
+ * Variables of this structure type must be placed in RAM only.
+ */
+typedef struct
+{
+ TSL_StateId_enum_T StateId; /**< Current state identifier */
+ TSL_tCounter_T CounterDebounce; /**< Counter for debounce and calibration management */
+ unsigned int CounterDTO : 6; /**< Counter for DTO management (TSL_tCounter_T) */
+ unsigned int Change : 1; /**< The State is different from the previous one (TSL_StateChange_enum_T) */
+ unsigned int DxSLock : 1; /**< The State is locked by the DxS (TSL_Bool_enum_T) */
+}
+TSL_TouchKeyData_T;
+
+/** Contains all parameters related to TouchKey sensor.
+ * Variables of this structure type can be placed in RAM or ROM.
+ */
+typedef struct
+{
+#if TSLPRM_USE_PROX > 0
+ TSL_tThreshold_T ProxInTh; /**< Proximity in threshold */
+ TSL_tThreshold_T ProxOutTh; /**< Proximity out threshold */
+#endif
+ TSL_tThreshold_T DetectInTh; /**< Detection in threshold */
+ TSL_tThreshold_T DetectOutTh; /**< Detection out threshold */
+ TSL_tThreshold_T CalibTh; /**< Calibration threshold */
+ TSL_tCounter_T CounterDebCalib; /**< Debounce counter to enter in Calibration state */
+#if TSLPRM_USE_PROX > 0
+ TSL_tCounter_T CounterDebProx; /**< Debounce counter to enter in Proximity state */
+#endif
+ TSL_tCounter_T CounterDebDetect; /**< Debounce counter to enter in Detect state */
+ TSL_tCounter_T CounterDebRelease; /**< Debounce counter to enter in Release state */
+ TSL_tCounter_T CounterDebError; /**< Debounce counter to enter in Error state */
+}
+TSL_TouchKeyParam_T;
+
+/** Contains definition of a TouchKey sensor.
+ * Variables of this structure type can be placed in RAM or ROM.
+ */
+typedef struct
+{
+ TSL_TouchKeyData_T *p_Data; /**< Data (state id, counter, flags, ...) */
+ TSL_TouchKeyParam_T *p_Param; /**< Parameters (thresholds, debounce, ...) */
+ TSL_ChannelData_T *p_ChD; /**< Channel Data (Meas, Ref, Delta, ...) */
+ CONST TSL_State_T *p_SM; /**< State Machine */
+ CONST TSL_TouchKeyMethods_T *p_Methods; /**< Methods */
+}
+TSL_TouchKey_T;
+
+/** Contains definition of a Basic TouchKey sensor.
+ * Variables of this structure type can be placed in RAM or ROM.
+ * Basic sensor does not contain its own state machine and methods. It used
+ * default ones instead to gain memory space.
+ */
+typedef struct
+{
+ TSL_TouchKeyData_T *p_Data; /**< Data (state id, counters, flags, ...) */
+ TSL_TouchKeyParam_T *p_Param; /**< Parameters (thresholds, debounce, ...) */
+ TSL_ChannelData_T *p_ChD; /**< Channel Data (Meas, Ref, Delta, ...) */
+}
+TSL_TouchKeyB_T;
+
+/* Exported variables --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+// "Object methods" functions
+void TSL_tkey_Init(void);
+void TSL_tkey_Process(void);
+
+// Utility functions
+void TSL_tkey_SetStateCalibration(TSL_tCounter_T delay);
+void TSL_tkey_SetStateOff(void);
+#if !defined(TSLPRM_STM8TL5X) && !defined(STM8TL5X)
+void TSL_tkey_SetStateBurstOnly(void);
+#endif
+TSL_StateId_enum_T TSL_tkey_GetStateId(void);
+TSL_StateMask_enum_T TSL_tkey_GetStateMask(void);
+TSL_tNb_T TSL_tkey_IsChanged(void);
+
+// State machine functions
+void TSL_tkey_CalibrationStateProcess(void);
+void TSL_tkey_DebCalibrationStateProcess(void);
+void TSL_tkey_ReleaseStateProcess(void);
+void TSL_tkey_DebReleaseProxStateProcess(void);
+void TSL_tkey_DebReleaseDetectStateProcess(void);
+void TSL_tkey_DebReleaseTouchStateProcess(void);
+void TSL_tkey_ProxStateProcess(void);
+void TSL_tkey_DebProxStateProcess(void);
+void TSL_tkey_DebProxDetectStateProcess(void);
+void TSL_tkey_DebProxTouchStateProcess(void);
+void TSL_tkey_DetectStateProcess(void);
+void TSL_tkey_DebDetectStateProcess(void);
+void TSL_tkey_TouchStateProcess(void);
+void TSL_tkey_DebTouchStateProcess(void);
+void TSL_tkey_ErrorStateProcess(void);
+void TSL_tkey_DebErrorStateProcess(void);
+void TSL_tkey_OffStateProcess(void);
+
+#endif /* __TSL_TOUCHKEY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/inc/tsl_types.h b/third_party/TouchSense/STMTouch_Driver/inc/tsl_types.h
new file mode 100644
index 0000000..4284493
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/inc/tsl_types.h
@@ -0,0 +1,217 @@
+/**
+ ******************************************************************************
+ * @file tsl_types.h
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all general structures definition.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_TYPES_H
+#define __TSL_TYPES_H
+
+/* Exported types ------------------------------------------------------------*/
+
+/** Generic Boolean status
+*/
+typedef enum
+{
+ TSL_FALSE = 0, /**< A False value */
+ TSL_TRUE = 1 /**< A True value */
+}
+TSL_Bool_enum_T;
+
+/** Generic status returned by functions
+*/
+typedef enum
+{
+ TSL_STATUS_OK = 0, /**< The function has been executed correctly */
+ TSL_STATUS_BUSY = 1, /**< The function is in a Busy state */
+ TSL_STATUS_ERROR = 2 /**< The function has been executed not correctly */
+} TSL_Status_enum_T;
+
+/** DataReady status : 1 bit
+ - Used by acquisition to indicate if a new measurement is ready or not.
+*/
+typedef enum
+{
+ TSL_DATA_NOT_READY = 0, /**< No new measurement or measurement treated */
+ TSL_DATA_READY = 1 /**< A new measurement is ready */
+} TSL_DataReady_enum_T;
+
+/** State change status
+*/
+typedef enum
+{
+ TSL_STATE_NOT_CHANGED = 0, /**< The object has the same state */
+ TSL_STATE_CHANGED = 1 /**< The object has changed of state */
+} TSL_StateChange_enum_T;
+
+#define TSL_ACQ_STATUS_ERROR_MASK (0x02) /**< Associated to TSL_AcqStatus_enum_T */
+
+/** Acquisition status
+*/
+typedef enum
+{
+ TSL_ACQ_STATUS_OK = 0, /**< The acquisition is correct */
+ TSL_ACQ_STATUS_NOISE = 1, /**< Noise detected during the acquisition */
+ TSL_ACQ_STATUS_ERROR_MIN = TSL_ACQ_STATUS_ERROR_MASK, /**< The measure is below the minimum threshold */
+ TSL_ACQ_STATUS_ERROR_MAX = (TSL_ACQ_STATUS_ERROR_MASK | 0x01) /**< The measure is above the maximum threshold */
+} TSL_AcqStatus_enum_T;
+
+/** Bank status
+*/
+typedef enum
+{
+ TSL_BANK_STATUS_DISABLED = 0, /**< The bank is disabled */
+ TSL_BANK_STATUS_ENABLED = 1 /**< The bank is enabled */
+} TSL_BankStatus_enum_T;
+
+/** Zone status
+*/
+typedef enum
+{
+ TSL_ZONE_STATUS_DISABLED = 0, /**< The zone is disabled */
+ TSL_ZONE_STATUS_ENABLED = 1 /**< The zone is enabled */
+}TSL_ZoneStatus_enum_T;
+
+#define TSL_OBJ_STATUS_ACQ_MASK (0x01) /**< Associated to TSL_ObjStatus_enum_T */
+#define TSL_OBJ_STATUS_BURST_MASK (0x02) /**< Associated to TSL_ObjStatus_enum_T */
+
+/** Object status
+*/
+typedef enum
+{
+ TSL_OBJ_STATUS_OFF = 0, /**< No burst and no acquisition */
+ TSL_OBJ_STATUS_BURST_ONLY = TSL_OBJ_STATUS_BURST_MASK, /**< Burst only */
+ TSL_OBJ_STATUS_ON = (TSL_OBJ_STATUS_BURST_MASK | TSL_OBJ_STATUS_ACQ_MASK) /**< Burst and acquisition */
+} TSL_ObjStatus_enum_T;
+
+#define TSL_STATE_ERROR_BIT_MASK (0x80) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_OFF_BIT_MASK (0x40) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_DEBOUNCE_BIT_MASK (0x20) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_CALIB_BIT_MASK (0x10) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_TOUCH_BIT_MASK (0x08) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_DETECT_BIT_MASK (0x04) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_PROX_BIT_MASK (0x02) /**< Associated to TSL_StateMask_enum_T */
+#define TSL_STATE_RELEASE_BIT_MASK (0x01) /**< Associated to TSL_StateMask_enum_T */
+
+/** Object state masks
+*/
+typedef enum
+{
+ // Calibration states
+ TSL_STATEMASK_CALIB = TSL_STATE_CALIB_BIT_MASK, /**< 0x10 */
+ TSL_STATEMASK_DEB_CALIB = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_CALIB_BIT_MASK), /**< 0x30 */
+ // Release states
+ TSL_STATEMASK_RELEASE = TSL_STATE_RELEASE_BIT_MASK, /**< 0x01 */
+ TSL_STATEMASK_DEB_RELEASE_PROX = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_RELEASE_BIT_MASK | TSL_STATE_PROX_BIT_MASK), /**< 0x23 */
+ TSL_STATEMASK_DEB_RELEASE_DETECT = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_RELEASE_BIT_MASK | TSL_STATE_DETECT_BIT_MASK), /**< 0x25 */
+ TSL_STATEMASK_DEB_RELEASE_TOUCH = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_RELEASE_BIT_MASK | TSL_STATE_TOUCH_BIT_MASK), /**< 0x29 */
+ // Proximity states
+ TSL_STATEMASK_PROX = TSL_STATE_PROX_BIT_MASK, /**< 0x02 */
+ TSL_STATEMASK_DEB_PROX = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_PROX_BIT_MASK), /**< 0x22 */
+ TSL_STATEMASK_DEB_PROX_DETECT = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_PROX_BIT_MASK | TSL_STATE_DETECT_BIT_MASK), /**< 0x26 */
+ TSL_STATEMASK_DEB_PROX_TOUCH = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_PROX_BIT_MASK | TSL_STATE_TOUCH_BIT_MASK), /**< 0x2A */
+ // Detect states
+ TSL_STATEMASK_DETECT = TSL_STATE_DETECT_BIT_MASK, /**< 0x04 */
+ TSL_STATEMASK_DEB_DETECT = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_DETECT_BIT_MASK), /**< 0x24 */
+ // Touch state
+ TSL_STATEMASK_TOUCH = TSL_STATE_TOUCH_BIT_MASK, /**< 0x08 */
+ // Error states
+ TSL_STATEMASK_ERROR = TSL_STATE_ERROR_BIT_MASK, /**< 0x80 */
+ TSL_STATEMASK_DEB_ERROR_CALIB = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK | TSL_STATE_CALIB_BIT_MASK), /**< 0xB0 */
+ TSL_STATEMASK_DEB_ERROR_RELEASE = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK | TSL_STATE_RELEASE_BIT_MASK), /**< 0xA1 */
+ TSL_STATEMASK_DEB_ERROR_PROX = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK | TSL_STATE_PROX_BIT_MASK), /**< 0xA2 */
+ TSL_STATEMASK_DEB_ERROR_DETECT = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK | TSL_STATE_DETECT_BIT_MASK), /**< 0xA4 */
+ TSL_STATEMASK_DEB_ERROR_TOUCH = (TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK | TSL_STATE_TOUCH_BIT_MASK), /**< 0xA8 */
+ // OFF state
+ TSL_STATEMASK_OFF = TSL_STATE_OFF_BIT_MASK, /**< 0x40 */
+ // Other states not associated to a state id
+ TSL_STATEMASK_ACTIVE = (TSL_STATE_PROX_BIT_MASK | TSL_STATE_DETECT_BIT_MASK | TSL_STATE_TOUCH_BIT_MASK | TSL_STATE_CALIB_BIT_MASK | TSL_STATE_DEBOUNCE_BIT_MASK), /**< 0x3E */
+ TSL_STATEMASK_UNKNOWN = 0 /**< 0x00 */
+} TSL_StateMask_enum_T;
+
+/** Object state identifiers
+*/
+typedef enum
+{
+ // Calibration states
+ TSL_STATEID_CALIB = 0, /**< 0 - Object is in Calibration */
+ TSL_STATEID_DEB_CALIB = 1, /**< 1 - Object is in Debounce Calibration */
+ // Release states
+ TSL_STATEID_RELEASE = 2, /**< 2 - Object is released */
+ TSL_STATEID_DEB_RELEASE_PROX = 3, /**< 3 - Object is in Debounce Release from Proximity state */
+ TSL_STATEID_DEB_RELEASE_DETECT = 4, /**< 4 - Object is in Debounce Release from Detect state */
+ TSL_STATEID_DEB_RELEASE_TOUCH = 5, /**< 5 - Object is in Debounce Release from Touch state */
+ // Proximity states
+ TSL_STATEID_PROX = 6, /**< 6 - Object is in Proximity */
+ TSL_STATEID_DEB_PROX = 7, /**< 7 - Object is in Debounce Proximity from Release state */
+ TSL_STATEID_DEB_PROX_DETECT = 8, /**< 8 - Object is in Debounce Proximity from Detect state */
+ TSL_STATEID_DEB_PROX_TOUCH = 9, /**< 9 - Object is in Debounce Proximity from Detect state */
+ // Detect states
+ TSL_STATEID_DETECT = 10, /**< 10 - Object is in Detect */
+ TSL_STATEID_DEB_DETECT = 11, /**< 11 - Object is in Debounce Detect */
+ // Touch state
+ TSL_STATEID_TOUCH = 12, /**< 12 - Object is in Touch */
+ // Error states
+ TSL_STATEID_ERROR = 13, /**< 13 - Object is in Error */
+ TSL_STATEID_DEB_ERROR_CALIB = 14, /**< 14 - Object is in Debounce Error from Calibration */
+ TSL_STATEID_DEB_ERROR_RELEASE = 15, /**< 15 - Object is in Debounce Error from Release */
+ TSL_STATEID_DEB_ERROR_PROX = 16, /**< 16 - Object is in Debounce Error from Proximity */
+ TSL_STATEID_DEB_ERROR_DETECT = 17, /**< 17 - Object is in Debounce Error from Detect */
+ TSL_STATEID_DEB_ERROR_TOUCH = 18, /**< 18 - Object is in Debounce Error from Touch */
+ // Other states
+ TSL_STATEID_OFF = 19 /**< 19 - Object is OFF (no burst, no acquisition) */
+} TSL_StateId_enum_T;
+
+/** Object state
+*/
+typedef struct
+{
+ TSL_StateMask_enum_T StateMask; /**< Current state mask */
+ void(* StateFunc)(void); /**< Function executed in the state */
+}
+TSL_State_T;
+
+/** Touchkey methods
+*/
+typedef struct
+{
+ void(* Init)(void); /**< Used to initialize the TouchKey sensor */
+ void(* Process)(void); /**< Used to execute the TouchKey sensor state machine */
+}
+TSL_TouchKeyMethods_T;
+
+/** Linear/Rotary methods
+*/
+typedef struct
+{
+ void(* Init)(void); /**< Used to initialize the Linear/Rotary sensor */
+ void(* Process)(void); /**< Used to execute the Linear/Rotary sensor state machine */
+ TSL_Status_enum_T(* CalcPosition)(void); /**< Used to calculate the Linear/Rotary sensor position */
+}
+TSL_LinRotMethods_T;
+
+#endif /* __TSL_TYPES_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl.c b/third_party/TouchSense/STMTouch_Driver/src/tsl.c
new file mode 100644
index 0000000..45ab841
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl.c
@@ -0,0 +1,61 @@
+/**
+ ******************************************************************************
+ * @file tsl.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains the STMTouch Driver main functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Initializes the TS interface.
+ * @param bank Array holding all the banks
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_Init(CONST TSL_Bank_T *bank)
+{
+ TSL_Status_enum_T retval;
+
+ // Get banks array
+ TSL_Globals.Bank_Array = bank;
+
+ // Initialization of the timing module
+ retval = TSL_tim_Init();
+
+ if (retval == TSL_STATUS_OK)
+ {
+ // Initialization of the acquisition module
+ retval = TSL_acq_Init();
+ }
+
+ return retval;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq.c
new file mode 100644
index 0000000..85156ec
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq.c
@@ -0,0 +1,373 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the acquisition in general.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq.h"
+#include "tsl_globals.h"
+#include "stm32f0xx_conf.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
+
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Read all channels measurement of a Bank, calculate Delta
+ * @param[in] idx_bk Index of the Bank to access
+ * @param[in] mfilter Pointer to the Measure filter function
+ * @param[in] dfilter Pointer to the Delta filter function
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankGetResult(TSL_tIndex_T idx_bk, TSL_pFuncMeasFilter_T mfilter, TSL_pFuncDeltaFilter_T dfilter)
+{
+ TSL_Status_enum_T retval = TSL_STATUS_OK;
+ TSL_tIndex_T idx_ch;
+ TSL_tIndexDest_T idx_dest;
+ TSL_tMeas_T old_meas, new_meas;
+ TSL_tDelta_T new_delta;
+ CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
+ CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ // For all channels in the bank copy the measure + calculate delta and store them.
+ for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
+ {
+
+ // Get the Destination Index of the current channel
+ idx_dest = pchDest->IdxDest;
+
+ if (bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_ON)
+ {
+
+ // Initialize flag to inform the Object of that a new data is ready
+ bank->p_chData[idx_dest].Flags.DataReady = TSL_DATA_READY;
+
+ // Get the new measure (the access is different between acquisitions)
+ new_meas = TSL_acq_GetMeas(pchSrc->IdxSrc);
+
+ // Store last measure for the filter below
+#if TSLPRM_USE_MEAS > 0
+ old_meas = bank->p_chData[idx_dest].Meas;
+#else
+ old_meas = new_meas;
+#endif
+
+ // Store the new measure
+#if TSLPRM_USE_MEAS > 0
+ bank->p_chData[idx_dest].Meas = new_meas;
+#endif
+
+ // Check acquisition value min/max and set acquisition status flag
+ if (new_meas < TSL_Params.AcqMin)
+ {
+ bank->p_chData[idx_dest].Flags.AcqStatus = TSL_ACQ_STATUS_ERROR_MIN;
+ bank->p_chData[idx_dest].Delta = 0;
+ retval = TSL_STATUS_ERROR;
+ }
+ else
+ {
+ if (new_meas > TSL_Params.AcqMax)
+ {
+ bank->p_chData[idx_dest].Flags.AcqStatus = TSL_ACQ_STATUS_ERROR_MAX;
+ bank->p_chData[idx_dest].Delta = 0;
+ retval = TSL_STATUS_ERROR;
+ }
+ else // The measure is OK
+ {
+ if (TSL_acq_UseFilter(&bank->p_chData[idx_dest]))
+ {
+ // Apply Measure filter if it exists
+ if (mfilter)
+ {
+ new_meas = mfilter(old_meas, new_meas);
+ // Store the measure (optional - used for debug purpose)
+#if TSLPRM_USE_MEAS > 0
+ bank->p_chData[idx_dest].Meas = new_meas;
+#endif
+ }
+
+ // Calculate the new Delta
+ new_delta = TSL_acq_ComputeDelta(bank->p_chData[idx_dest].Ref, new_meas);
+
+ // Check Noise (TSL_ACQ_STATUS_OK if no Noise or if Noise detection is not supported)
+ bank->p_chData[idx_dest].Flags.AcqStatus = TSL_acq_CheckNoise();
+
+ // Apply Delta filter if it exists
+ if (dfilter)
+ {
+ bank->p_chData[idx_dest].Delta = dfilter(new_delta);
+ }
+ else
+ {
+ bank->p_chData[idx_dest].Delta = new_delta;
+ }
+ }
+ else
+ {
+ // Calculate the new Delta
+ bank->p_chData[idx_dest].Delta = TSL_acq_ComputeDelta(bank->p_chData[idx_dest].Ref, new_meas);
+
+ // Check Noise (TSL_ACQ_STATUS_OK if no Noise or if Noise detection is not supported)
+ bank->p_chData[idx_dest].Flags.AcqStatus = TSL_acq_CheckNoise();
+ }
+ }
+ }
+ }
+
+ // Next channel
+ pchDest++;
+ pchSrc++;
+
+ }
+
+ return retval;
+}
+
+
+/**
+ * @brief Calibrate a Bank
+ * @param[in] idx_bk Index of the Bank to access
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankCalibrate(TSL_tIndex_T idx_bk)
+{
+ TSL_Status_enum_T retval;
+ TSL_Status_enum_T acq_status;
+ TSL_tIndex_T idx_ch;
+ TSL_tIndexDest_T idx_dest;
+ TSL_tMeas_T new_meas;
+ static TSL_tIndex_T calibration_ongoing = 0;
+ static TSL_tNb_T calibration_done = 0;
+ static TSL_tNb_T div;
+ CONST TSL_Bank_T *bank;
+ CONST TSL_ChannelDest_T *pchDest; // Pointer to the current channel
+ CONST TSL_ChannelSrc_T *pchSrc; // Pointer to the current channel
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ bank = &(TSL_Globals.Bank_Array[idx_bk]);
+
+ if (calibration_ongoing == 0)
+ {
+ switch (TSL_Params.NbCalibSamples)
+ {
+ case 4:
+ div = 2;
+ break;
+ case 16:
+ div = 4;
+ break;
+ default:
+ TSL_Params.NbCalibSamples = 8;
+ div = 3;
+ break;
+ }
+ // Clear data for all channels of the bank
+ TSL_acq_BankClearData(idx_bk);
+ // Configure bank
+ if (TSL_acq_BankConfig(idx_bk) == TSL_STATUS_OK)
+ {
+ // Start acquisition
+ TSL_acq_BankStartAcq();
+ calibration_ongoing = 1; // Calibration started
+ calibration_done = TSL_Params.NbCalibSamples;
+ retval = TSL_STATUS_BUSY;
+ }
+ else
+ {
+ // Stop calibration
+ // Clear data for all channels of the bank
+ TSL_acq_BankClearData(idx_bk);
+ calibration_ongoing = 0;
+ retval = TSL_STATUS_ERROR;
+ }
+
+ }
+ else // Calibration is on-going
+ {
+ // Check End of Acquisition
+ acq_status = TSL_acq_BankWaitEOC();
+ if (acq_status == TSL_STATUS_OK)
+ {
+
+ // Get the first channel of the bank
+ pchDest = bank->p_chDest;
+ pchSrc = bank->p_chSrc;
+
+ // Get new measurement for all channels of the bank
+ for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
+ {
+
+ // Get index of the current channel
+ idx_dest = pchDest->IdxDest;
+
+ // Get the new measure (the access is different between acquisitions)
+ new_meas = TSL_acq_GetMeas(pchSrc->IdxSrc);
+
+ // Check min/max and set status flag
+ if ((new_meas < TSL_Params.AcqMin) || (new_meas > TSL_Params.AcqMax))
+ {
+ // Stop calibration
+ // Clear data for all channels of the bank
+ TSL_acq_BankClearData(idx_bk);
+ calibration_ongoing = 0;
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ // Add the measure
+ bank->p_chData[idx_dest].Ref += new_meas;
+ }
+
+ // Next channel
+ pchDest++;
+ pchSrc++;
+ }
+
+ // Check that we have all the needed measurements
+ calibration_done--;
+ if (calibration_done == 0)
+ {
+
+ // Get the first channel of the bank
+ pchDest = bank->p_chDest;
+
+ // Calculate the Reference for all channels of the bank
+ for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
+ {
+ // Get index of the current channel
+ idx_dest = pchDest->IdxDest;
+ // Divide the Reference by the number of samples
+ bank->p_chData[idx_dest].Ref >>= div;
+ // Next channel
+ pchDest++;
+ }
+
+ // End
+ calibration_ongoing = 0;
+ retval = TSL_STATUS_OK;
+ }
+ else // Restart a new measurement on the bank
+ {
+ TSL_acq_BankStartAcq();
+ retval = TSL_STATUS_BUSY;
+ }
+ }
+ else
+ if (acq_status == TSL_STATUS_ERROR)
+ {
+ // Stop calibration
+ // Clear data for all channels of the bank
+ TSL_acq_BankClearData(idx_bk);
+ calibration_ongoing = 0;
+ retval = TSL_STATUS_ERROR;
+ }
+ else
+ {
+ retval = TSL_STATUS_BUSY;
+ }
+ }
+
+ return retval;
+}
+
+
+/**
+ * @brief Clear Reference and Delta on all channels of a Bank
+ * @param[in] idx_bk Index of the Bank to access
+ * @retval None
+ */
+void TSL_acq_BankClearData(TSL_tIndex_T idx_bk)
+{
+ TSL_tIndex_T idx_ch;
+ TSL_tIndexDest_T idx_Dest;
+ CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ // For all channels of the bank
+ for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
+ {
+ idx_Dest = pchDest->IdxDest;
+ bank->p_chData[idx_Dest].Ref = 0;
+ bank->p_chData[idx_Dest].Delta = 0;
+ pchDest++; // Next channel
+ }
+}
+
+
+#if TSLPRM_USE_ZONE > 0
+
+/**
+ * @brief Configures a Zone.
+ * @param[in] zone Zone to configure
+ * @param[in] idx_bk Bank index in the zone to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_ZoneConfig(CONST TSL_Zone_T *zone, TSL_tIndex_T idx_bk)
+{
+ TSL_Status_enum_T retval;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ TSL_Globals.This_Zone = zone;
+
+ do
+ {
+ retval = TSL_acq_BankConfig(zone->BankIndex[idx_bk]);
+ TSL_Globals.This_Bank = zone->BankIndex[idx_bk];
+ idx_bk++;
+ }
+ while ((idx_bk < zone->NbBanks) && (retval == TSL_STATUS_ERROR));
+
+ TSL_Globals.Index_In_This_Zone = idx_bk;
+
+#if TSLPRM_PXS_LOW_POWER_MODE > 0
+ if (idx_bk < zone->NbBanks)
+ {
+ resetPXSLowPower();
+ }
+#endif
+
+ return(retval);
+
+}
+
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f0xx.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f0xx.c
new file mode 100644
index 0000000..24271de
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f0xx.c
@@ -0,0 +1,1012 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32f0xx.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the TSC acquisition
+ * on STM32F0xx products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm32f0xx.h"
+#include "tsl_globals.h"
+#include "stm32f0xx_it.h"
+#include "stm32f0xx_gpio.h"
+#include "stm32f0xx_conf.h"
+#include "stm32f0xx_misc.h"
+#include "stm32f0xx_rtc.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+#define NU (0) // Not Used IO
+#define CHANNEL (1) // Channel IO
+#define SHIELD (2) // Shield IO (= Channel IO but not acquired)
+#define SAMPCAP (3) // Sampling Capacitor IO
+
+/* Private macros ------------------------------------------------------------*/
+
+// Used by assert
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
+#define IS_SRC_INDEX_0_5_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < 6)))
+#define IS_SRC_INDEX_0_7_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < 8)))
+
+/* Private variables ---------------------------------------------------------*/
+uint32_t DelayDischarge;
+
+/* Private functions prototype -----------------------------------------------*/
+void SoftDelay(uint32_t val);
+
+/**
+ * @brief Initializes the TouchSensing GPIOs.
+ * @param None
+ * @retval None
+ */
+void TSL_acq_InitGPIOs(void)
+{
+
+ GPIO_InitTypeDef GPIO_InitStructure;
+ uint32_t tmp_value_0;
+ uint32_t tmp_value_1;
+
+ //====================
+ // GPIOs configuration
+ //====================
+
+ // Enable GPIOs clocks
+ RCC->AHBENR |= (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN
+#if (TSC_GROUP7_ENABLED > 0) || (TSC_GROUP8_ENABLED > 0)
+ | RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOEEN
+#endif
+ );
+
+ // Alternate function Output Open-Drain for Sampling Capacitor IOs
+ //----------------------------------------------------------------
+
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+
+ // GPIOA
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP1_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_9;
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_10;
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ // GPIOB
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP3_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ // GPIOC
+#if TSLPRM_TSC_GROUP3_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif
+
+#if (TSC_GROUP8_ENABLED > 0)
+ // GPIOD
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP8_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
+#endif
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+#endif // TSC_GROUP8_ENABLED
+
+#if (TSC_GROUP7_ENABLED > 0)
+// GPIOE
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP7_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
+#endif // TSC_GROUP7_ENABLED
+
+ // Alternate function Output Push-Pull for Channel and Shield IOs
+ //---------------------------------------------------------------
+
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+
+ // GPIOA
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP1_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if (TSLPRM_TSC_GROUP1_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if (TSLPRM_TSC_GROUP1_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if (TSLPRM_TSC_GROUP1_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_9;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_10;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ // GPIOB
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP3_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if (TSLPRM_TSC_GROUP3_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if (TSLPRM_TSC_GROUP3_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ // GPIOC
+#if (TSLPRM_TSC_GROUP3_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif
+
+#if (TSC_GROUP8_ENABLED > 0)
+ // GPIOD
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP8_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if (TSLPRM_TSC_GROUP8_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if (TSLPRM_TSC_GROUP8_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#if (TSLPRM_TSC_GROUP8_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
+#endif
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+#endif // TSC_GROUP8_ENABLED
+
+#if (TSC_GROUP7_ENABLED > 0)
+ // GPIOE
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP7_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if (TSLPRM_TSC_GROUP7_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP7_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP7_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
+#endif // TSC_GROUP7_ENABLED
+
+ // Set Alternate-Function AF3 for GPIOA and GPIOB
+ //-----------------------------------------------
+
+ // GPIOA
+ tmp_value_0 = 0;
+ tmp_value_1 = 0;
+#if TSLPRM_TSC_GROUP1_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (0 * 4));
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+ GPIOA->AFR[0] |= tmp_value_0;
+ GPIOA->AFR[1] |= tmp_value_1;
+
+ // GPIOB
+ tmp_value_0 = 0;
+ tmp_value_1 = 0;
+#if TSLPRM_TSC_GROUP3_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (0 * 4));
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+ GPIOB->AFR[0] |= tmp_value_0;
+ GPIOB->AFR[1] |= tmp_value_1;
+
+ // Set Alternate-Function AF1 for GPIOD and GPIOE
+ //-----------------------------------------------
+
+#if (TSC_GROUP8_ENABLED > 0)
+ // GPIOD
+ tmp_value_1 = 0;
+#if TSLPRM_TSC_GROUP8_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)1 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)1 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)1 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)1 << (7 * 4));
+#endif
+ GPIOD->AFR[1] |= tmp_value_1;
+#endif // TSC_GROUP8_ENABLED
+
+#if (TSC_GROUP7_ENABLED > 0)
+ // GPIOE
+ tmp_value_0 = 0;
+#if TSLPRM_TSC_GROUP7_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << (5 * 4));
+#endif
+ GPIOE->AFR[0] |= tmp_value_0;
+#endif // TSC_GROUP7_ENABLED
+
+ //==================
+ // TSC configuration
+ //==================
+
+ // Enable TSC clock
+ RCC->AHBENR |= RCC_AHBENR_TSEN;
+
+ // Disable Schmitt trigger hysteresis on all used TS IOs (Channel, Shield and Sampling IOs)
+ //-----------------------------------------------------------------------------------------
+
+ tmp_value_0 = 0xFFFFFFFF;
+#if TSLPRM_TSC_GROUP1_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 0);
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 1);
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 2);
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 3);
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 4);
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 5);
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 6);
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 7);
+#endif
+#if TSLPRM_TSC_GROUP3_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 8);
+#endif
+#if TSLPRM_TSC_GROUP3_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 9);
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 10);
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 11);
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 12);
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 13);
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 14);
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 15);
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 16);
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 17);
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 18);
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 19);
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 20);
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 21);
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 22);
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 23);
+#endif
+
+#if (TSC_GROUP7_ENABLED > 0)
+#if TSLPRM_TSC_GROUP7_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 24);
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 25);
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 26);
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 27);
+#endif
+#endif // TSC_GROUP7_ENABLED
+
+#if (TSC_GROUP8_ENABLED > 0)
+#if TSLPRM_TSC_GROUP8_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 28);
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 29);
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 30);
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 31);
+#endif
+#endif // TSC_GROUP8_ENABLED
+
+ TSC->IOHCR &= tmp_value_0;
+
+ // Set Sampling Capacitor IOs
+ //---------------------------
+
+ tmp_value_0 = 0;
+#if TSLPRM_TSC_GROUP1_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 0);
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 1);
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 2);
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 3);
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 4);
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 5);
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 6);
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 7);
+#endif
+#if TSLPRM_TSC_GROUP3_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 8);
+#endif
+#if TSLPRM_TSC_GROUP3_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 9);
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 10);
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 11);
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 12);
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 13);
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 14);
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 15);
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 16);
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 17);
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 18);
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 19);
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 20);
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 21);
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 22);
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 23);
+#endif
+
+#if (TSC_GROUP7_ENABLED > 0)
+#if TSLPRM_TSC_GROUP7_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 24);
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 25);
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 26);
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 27);
+#endif
+#endif // TSC_GROUP7_ENABLED
+
+#if (TSC_GROUP8_ENABLED > 0)
+#if TSLPRM_TSC_GROUP8_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 28);
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 29);
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 30);
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 31);
+#endif
+#endif // TSC_GROUP8_ENABLED
+
+ TSC->IOSCR |= tmp_value_0;
+
+}
+
+
+/**
+ * @brief Initializes the acquisition module.
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+
+#if TSLPRM_TSC_GPIO_CONFIG > 0
+ TSL_acq_InitGPIOs();
+#endif
+
+ // Enable TSC clock
+ RCC->AHBENR |= RCC_AHBENR_TSEN;
+
+ // TSC enabled
+ TSC->CR = 0x01;
+
+ // Set CTPH
+#if TSLPRM_TSC_CTPH > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_CTPH << 28) & 0xF0000000;
+#endif
+
+ // Set CTPL
+#if TSLPRM_TSC_CTPL > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_CTPL << 24) & 0x0F000000;
+#endif
+
+ // Set SpreadSpectrum
+#if TSLPRM_TSC_USE_SS > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_USE_SS << 16) & 0x00010000;
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_SSD << 17) & 0x00FE0000;
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_SSPSC << 15) & 0x00008000;
+#endif
+
+ // Set Prescaler
+#if TSLPRM_TSC_PGPSC > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_PGPSC << 12) & 0x00007000;
+#endif
+
+ // Set Max Count
+#if TSLPRM_TSC_MCV > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_MCV << 5) & 0x000000E0;
+#endif
+
+ // Set IO default in Output PP Low to discharge all capacitors
+ TSC->CR &= (uint32_t)(~(1 << 4));
+
+ // Set Synchronization Mode
+#if TSLPRM_TSC_AM > 0
+
+ // Set Synchronization Pin in Alternate-Function mode
+ RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // Set GPIOB clock
+
+#if TSLPRM_TSC_SYNC_PIN == 0 // PB08
+ GPIOB->MODER &= 0xFFFCFFFF;
+ GPIOB->MODER |= 0x00020000;
+ GPIOB->AFR[1] |= 0x00000003;
+#else // PB10
+ GPIOB->MODER &= 0xFFCFFFFF;
+ GPIOB->MODER |= 0x00200000;
+ GPIOB->AFR[1] |= 0x00000300;
+#endif
+
+ // Set Synchronization Polarity
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_SYNC_POL << 3) & 0x00000008;
+
+ // Set acquisition mode
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_AM << 2) & 0x00000004;
+
+#endif
+
+#if TSLPRM_USE_ACQ_INTERRUPT > 0
+
+ // Set both EOA and MCE interrupts
+ TSC->IER |= 0x03;
+
+ // Configure NVIC
+ NVIC_SetPriority(TSC_IRQn, 0);
+ NVIC_EnableIRQ(TSC_IRQn);
+
+#endif
+
+ // Initialize the delay that will be used to discharge the capacitors
+ DelayDischarge = (uint32_t)((TSLPRM_DELAY_DISCHARGE_ALL * (uint32_t)(SystemCoreClock/1000000)) / 48);
+
+ return TSL_STATUS_OK;
+
+}
+
+
+/**
+ * @brief Configures a Bank.
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ uint32_t idx_ch;
+ uint32_t objs; /* bit field of TSL_ObjStatus_enum_T type */
+ uint32_t gx;
+ uint32_t ioy;
+ CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;
+ CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ // Mark the current bank processed
+ TSL_Globals.This_Bank = idx_bk;
+
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // Enable the Gx_IOy used as channels (channels + shield)
+ TSC->IOCCR = bank->msk_IOCCR_channels;
+ // Enable acquisition on selected Groups
+ TSC->IOGCSR = bank->msk_IOGCSR_groups;
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ // For all channels of the bank check if they are OFF or BURST_ONLY
+ // and set acquisition status flag
+ for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
+ {
+
+ // Check Object status flag
+ objs = bank->p_chData[pchDest->IdxDest].Flags.ObjStatus;
+
+ if (objs != TSL_OBJ_STATUS_ON)
+ {
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // Get the Channel Group mask
+ gx = pchSrc->msk_IOGCSR_group;
+ // Stop acquisition of the Group
+ TSC->IOGCSR &= (uint32_t)~gx;
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ if (objs == TSL_OBJ_STATUS_OFF)
+ {
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // Get the Channel IO mask
+ ioy = pchSrc->msk_IOCCR_channel;
+ // Stop Burst of the Channel
+ TSC->IOCCR &= (uint32_t)~ioy;
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ }
+ }
+
+ // Next channel
+ pchSrc++;
+ pchDest++;
+ }
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Start acquisition on a previously configured bank
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+ // Clear both EOAIC and MCEIC flags
+ TSC->ICR |= 0x03;
+
+ // Wait capacitors discharge
+ SoftDelay(DelayDischarge);
+
+#if TSLPRM_TSC_IODEF > 0 // Default = Input Floating
+ // Set IO default in Input Floating
+ TSC->CR |= (1 << 4);
+#endif
+
+ // Start acquisition
+ TSC->CR |= 0x02;
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ TSL_Status_enum_T retval = TSL_STATUS_BUSY;
+
+ // Check EOAF flag
+ if (TSC->ISR & 0x01)
+ {
+
+#if TSLPRM_TSC_IODEF > 0 // Default = Input Floating
+ // Set IO default in Output PP Low to discharge all capacitors
+ TSC->CR &= (uint32_t)(~(1 << 4));
+#endif
+
+ // Check MCEF flag
+ if (TSC->ISR & 0x02)
+ {
+ retval = TSL_STATUS_ERROR;
+ }
+ else
+ {
+ retval = TSL_STATUS_OK;
+ }
+ }
+
+ return retval;
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index)
+{
+ // Check parameters (if USE_FULL_ASSERT is defined)
+#if (TSC_GROUP7_ENABLED > 0) || (TSC_GROUP8_ENABLED > 0)
+ assert_param(IS_SRC_INDEX_0_7_OK(idx_bk));
+#else
+ assert_param(IS_SRC_INDEX_0_5_OK(idx_bk));
+#endif
+ return((TSL_tMeas_T)(TSC->IOGXCR[index]));
+}
+
+
+/**
+ * @brief Compute the Delta value
+ * @param[in] ref Reference value
+ * @param[in] meas Last Measurement value
+ * @retval Delta value
+ */
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas)
+{
+ return((TSL_tDelta_T)(ref - meas));
+}
+
+
+/**
+ * @brief Compute the Measurement value
+ * @param[in] ref Reference value
+ * @param[in] delta Delta value
+ * @retval Measurement value
+ */
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta)
+{
+ return((TSL_tMeas_T)(ref - delta));
+}
+
+
+/**
+ * @brief Check noise (not used)
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ return TSL_ACQ_STATUS_OK;
+}
+
+
+/**
+ * @brief Check if a filter must be used on the current channel (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if a filter can be applied
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ return TSL_TRUE;
+}
+
+
+/**
+ * @brief Test if the Reference is incorrect (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if the Reference is out of range
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ return TSL_FALSE;
+}
+
+
+/**
+ * @brief Test if the measure has crossed the reference target (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result TRUE if the Reference is valid
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ return TSL_TRUE;
+}
+
+
+#if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM
+#pragma optimize=low
+#elif defined(__CC_ARM) // Keil/MDK-ARM
+#pragma O1
+#pragma Ospace
+#elif defined(__TASKING__) // Altium/Tasking
+#pragma optimize O0
+#elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * @retval None
+ * @note Measurements done with HCLK=48MHz and Keil/MDK-ARM compiler
+ * val = 500: ~ 53µs
+ * val = 1000: ~106µs
+ * val = 2000: ~210µs
+ */
+void SoftDelay(uint32_t val)
+{
+ uint32_t idx;
+ for (idx = val; idx > 0; idx--)
+ {}
+}
+#if defined(__TASKING__)
+#pragma endoptimize
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f3xx.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f3xx.c
new file mode 100644
index 0000000..c75a791
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32f3xx.c
@@ -0,0 +1,1148 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32f3xx.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the TSC acquisition
+ * on STM32F3xx products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm32f3xx.h"
+#include "tsl_globals.h"
+#if defined(STM32F30X)
+#include "stm32f30x_it.h"
+#endif
+#if defined(STM32F37X)
+#include "stm32f37x_it.h"
+#endif
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+#define NU (0) // Not Used IO
+#define CHANNEL (1) // Channel IO
+#define SHIELD (2) // Shield IO (= Channel IO but not acquired)
+#define SAMPCAP (3) // Sampling Capacitor IO
+
+/* Private macros ------------------------------------------------------------*/
+
+// Used by assert
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
+#define IS_SRC_INDEX_0_7_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < 8)))
+
+/* Private variables ---------------------------------------------------------*/
+uint32_t DelayDischarge;
+
+/* Private functions prototype -----------------------------------------------*/
+void SoftDelay(uint32_t val);
+
+/**
+ * @brief Initializes the TouchSensing GPIOs.
+ * @param None
+ * @retval None
+ */
+void TSL_acq_InitGPIOs(void)
+{
+
+ GPIO_InitTypeDef GPIO_InitStructure;
+ uint32_t tmp_value_0;
+ uint32_t tmp_value_1;
+
+ //====================
+ // GPIOs configuration
+ //====================
+
+ // Enable GPIOs clocks
+ RCC->AHBENR |= (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN |
+ RCC_AHBENR_GPIODEN | RCC_AHBENR_GPIOEEN);
+
+ // Alternate function Output Open-Drain for Sampling Capacitor IOs
+ //----------------------------------------------------------------
+
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
+ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+
+ // GPIOA
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP1_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_9;
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_10;
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ // GPIOB
+ GPIO_InitStructure.GPIO_Pin = 0;
+
+#if defined(STM32F30X)
+#if TSLPRM_TSC_GROUP3_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#endif // STM32F30X
+
+#if defined(STM32F37X)
+#if TSLPRM_TSC_GROUP3_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
+#endif
+#endif // STM32F37X
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ // GPIOC
+#if defined(STM32F30X)
+#if TSLPRM_TSC_GROUP3_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif
+#endif // STM32F30X
+
+#if defined(STM32F37X)
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP3_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP3_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif // STM32F37X
+
+ // GPIOD
+ GPIO_InitStructure.GPIO_Pin = 0;
+
+#if defined(STM32F37X)
+#if TSLPRM_TSC_GROUP6_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
+#endif
+#endif // STM32F37X
+
+#if TSLPRM_TSC_GROUP8_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
+#endif
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ // GPIOE
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if TSLPRM_TSC_GROUP7_IO1 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 == SAMPCAP
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+#endif
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+ // Alternate function Output Push-Pull for Channel and Shield IOs
+ //---------------------------------------------------------------
+
+ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+
+ // GPIOA
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP1_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if (TSLPRM_TSC_GROUP1_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if (TSLPRM_TSC_GROUP1_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if (TSLPRM_TSC_GROUP1_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP1_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if (TSLPRM_TSC_GROUP2_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP2_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_9;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_10;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if (TSLPRM_TSC_GROUP4_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP4_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+ GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+ // GPIOB
+ GPIO_InitStructure.GPIO_Pin = 0;
+
+#if defined(STM32F30X)
+#if (TSLPRM_TSC_GROUP3_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if (TSLPRM_TSC_GROUP3_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if (TSLPRM_TSC_GROUP3_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_11;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#endif // STM32F30X
+
+#if defined(STM32F37X)
+#if (TSLPRM_TSC_GROUP3_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_0;
+#endif
+#if (TSLPRM_TSC_GROUP3_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_1;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_6;
+#endif
+#if (TSLPRM_TSC_GROUP5_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP5_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_7;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
+#endif
+#endif // STM32F37X
+
+ GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+ // GPIOC
+
+#if defined(STM32F30X)
+#if (TSLPRM_TSC_GROUP3_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif
+#endif // STM32F30X
+
+#if defined(STM32F37X)
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP3_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP3_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP3_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+ GPIO_Init(GPIOC, &GPIO_InitStructure);
+#endif // STM32F37X
+
+ // GPIOD
+ GPIO_InitStructure.GPIO_Pin = 0;
+
+#if defined(STM32F37X)
+#if (TSLPRM_TSC_GROUP6_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_8;
+#endif
+#if (TSLPRM_TSC_GROUP6_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP6_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_9;
+#endif
+#endif // STM32F37X
+
+#if (TSLPRM_TSC_GROUP8_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_12;
+#endif
+#if (TSLPRM_TSC_GROUP8_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;
+#endif
+#if (TSLPRM_TSC_GROUP8_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;
+#endif
+#if (TSLPRM_TSC_GROUP8_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP8_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;
+#endif
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ // GPIOE
+ GPIO_InitStructure.GPIO_Pin = 0;
+#if (TSLPRM_TSC_GROUP7_IO1 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO1 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_2;
+#endif
+#if (TSLPRM_TSC_GROUP7_IO2 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO2 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_3;
+#endif
+#if (TSLPRM_TSC_GROUP7_IO3 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO3 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_4;
+#endif
+#if (TSLPRM_TSC_GROUP7_IO4 == CHANNEL) || (TSLPRM_TSC_GROUP7_IO4 == SHIELD)
+ GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_5;
+#endif
+ GPIO_Init(GPIOE, &GPIO_InitStructure);
+
+ // Set Alternate-Function AF3 on used TSC IOs
+ //-------------------------------------------
+
+ // GPIOA
+ tmp_value_0 = 0;
+ tmp_value_1 = 0;
+#if TSLPRM_TSC_GROUP1_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (0 * 4));
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+ GPIOA->AFR[0] |= tmp_value_0;
+ GPIOA->AFR[1] |= tmp_value_1;
+
+ // GPIOB
+ tmp_value_0 = 0;
+ tmp_value_1 = 0;
+
+#if defined(STM32F30X)
+#if TSLPRM_TSC_GROUP3_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (0 * 4));
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#endif // STM32F30X
+
+#if defined(STM32F37X)
+#if TSLPRM_TSC_GROUP3_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (0 * 4));
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+#endif // STM32F37X
+
+ GPIOB->AFR[0] |= tmp_value_0;
+ GPIOB->AFR[1] |= tmp_value_1;
+
+ // GPIOC
+#if defined(STM32F30X)
+#if TSLPRM_TSC_GROUP3_IO1 != NU
+ GPIOC->AFR[0] |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#endif // STM32F30X
+
+#if defined(STM32F37X)
+#if TSLPRM_TSC_GROUP3_IO1 != NU
+ GPIOC->AFR[0] |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP3_IO2 != NU
+ GPIOC->AFR[0] |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#endif // STM32F37X
+
+ // GPIOD
+ tmp_value_1 = 0;
+
+#if defined(STM32F37X)
+#if TSLPRM_TSC_GROUP6_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (0 * 4));
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (1 * 4));
+#endif
+#endif // STM32F37X
+
+#if TSLPRM_TSC_GROUP8_IO1 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (6 * 4));
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 != NU
+ tmp_value_1 |= (uint32_t)((uint32_t)3 << (7 * 4));
+#endif
+ GPIOD->AFR[1] |= tmp_value_1;
+
+ // GPIOE
+ tmp_value_0 = 0;
+#if TSLPRM_TSC_GROUP7_IO1 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (2 * 4));
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (3 * 4));
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (4 * 4));
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 != NU
+ tmp_value_0 |= (uint32_t)((uint32_t)3 << (5 * 4));
+#endif
+ GPIOE->AFR[0] |= tmp_value_0;
+
+ //==================
+ // TSC configuration
+ //==================
+
+ // Enable TSC clock
+ RCC->AHBENR |= RCC_AHBENR_TSEN;
+
+ // Disable Schmitt trigger hysteresis on all used TS IOs (Channel, Shield and Sampling IOs)
+ //-----------------------------------------------------------------------------------------
+
+ tmp_value_0 = 0xFFFFFFFF;
+#if TSLPRM_TSC_GROUP1_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 0);
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 1);
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 2);
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 3);
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 4);
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 5);
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 6);
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 7);
+#endif
+#if TSLPRM_TSC_GROUP3_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 8);
+#endif
+#if TSLPRM_TSC_GROUP3_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 9);
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 10);
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 11);
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 12);
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 13);
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 14);
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 15);
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 16);
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 17);
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 18);
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 19);
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 20);
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 21);
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 22);
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 23);
+#endif
+#if TSLPRM_TSC_GROUP7_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 24);
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 25);
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 26);
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 27);
+#endif
+#if TSLPRM_TSC_GROUP8_IO1 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 28);
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 29);
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 30);
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 != NU
+ tmp_value_0 &= (uint32_t)~((uint32_t)1 << 31);
+#endif
+ TSC->IOHCR &= tmp_value_0;
+
+ // Set Sampling Capacitor IOs
+ //---------------------------
+
+ tmp_value_0 = 0;
+#if TSLPRM_TSC_GROUP1_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 0);
+#endif
+#if TSLPRM_TSC_GROUP1_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 1);
+#endif
+#if TSLPRM_TSC_GROUP1_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 2);
+#endif
+#if TSLPRM_TSC_GROUP1_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 3);
+#endif
+#if TSLPRM_TSC_GROUP2_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 4);
+#endif
+#if TSLPRM_TSC_GROUP2_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 5);
+#endif
+#if TSLPRM_TSC_GROUP2_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 6);
+#endif
+#if TSLPRM_TSC_GROUP2_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 7);
+#endif
+#if TSLPRM_TSC_GROUP3_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 8);
+#endif
+#if TSLPRM_TSC_GROUP3_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 9);
+#endif
+#if TSLPRM_TSC_GROUP3_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 10);
+#endif
+#if TSLPRM_TSC_GROUP3_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 11);
+#endif
+#if TSLPRM_TSC_GROUP4_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 12);
+#endif
+#if TSLPRM_TSC_GROUP4_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 13);
+#endif
+#if TSLPRM_TSC_GROUP4_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 14);
+#endif
+#if TSLPRM_TSC_GROUP4_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 15);
+#endif
+#if TSLPRM_TSC_GROUP5_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 16);
+#endif
+#if TSLPRM_TSC_GROUP5_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 17);
+#endif
+#if TSLPRM_TSC_GROUP5_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 18);
+#endif
+#if TSLPRM_TSC_GROUP5_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 19);
+#endif
+#if TSLPRM_TSC_GROUP6_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 20);
+#endif
+#if TSLPRM_TSC_GROUP6_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 21);
+#endif
+#if TSLPRM_TSC_GROUP6_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 22);
+#endif
+#if TSLPRM_TSC_GROUP6_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 23);
+#endif
+#if TSLPRM_TSC_GROUP7_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 24);
+#endif
+#if TSLPRM_TSC_GROUP7_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 25);
+#endif
+#if TSLPRM_TSC_GROUP7_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 26);
+#endif
+#if TSLPRM_TSC_GROUP7_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 27);
+#endif
+#if TSLPRM_TSC_GROUP8_IO1 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 28);
+#endif
+#if TSLPRM_TSC_GROUP8_IO2 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 29);
+#endif
+#if TSLPRM_TSC_GROUP8_IO3 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 30);
+#endif
+#if TSLPRM_TSC_GROUP8_IO4 == SAMPCAP
+ tmp_value_0 |= (uint32_t)((uint32_t)1 << 31);
+#endif
+ TSC->IOSCR |= tmp_value_0;
+
+}
+
+
+/**
+ * @brief Initializes the acquisition module.
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+
+#if TSLPRM_TSC_GPIO_CONFIG > 0
+ TSL_acq_InitGPIOs();
+#endif
+
+ // Enable TSC clock
+ RCC->AHBENR |= RCC_AHBENR_TSEN;
+
+ // TSC enabled
+ TSC->CR = 0x01;
+
+ // Set CTPH
+#if TSLPRM_TSC_CTPH > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_CTPH << 28) & 0xF0000000;
+#endif
+
+ // Set CTPL
+#if TSLPRM_TSC_CTPL > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_CTPL << 24) & 0x0F000000;
+#endif
+
+ // Set SpreadSpectrum
+#if TSLPRM_TSC_USE_SS > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_USE_SS << 16) & 0x00010000;
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_SSD << 17) & 0x00FE0000;
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_SSPSC << 15) & 0x00008000;
+#endif
+
+ // Set Prescaler
+#if TSLPRM_TSC_PGPSC > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_PGPSC << 12) & 0x00007000;
+#endif
+
+ // Set Max Count
+#if TSLPRM_TSC_MCV > 0
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_MCV << 5) & 0x000000E0;
+#endif
+
+ // Set IO default in Output PP Low to discharge all capacitors
+ TSC->CR &= (uint32_t)(~(1 << 4));
+
+ // Set Synchronization Mode
+#if TSLPRM_TSC_AM > 0
+
+ // Set Synchronization Pin in Alternate-Function mode
+#if TSLPRM_TSC_SYNC_PIN == 0 // PB08
+ RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // Set GPIOB clock
+ GPIOB->MODER &= 0xFFFCFFFF;
+ GPIOB->MODER |= 0x00020000;
+ GPIOB->AFR[1] |= 0x00000003;
+#endif
+#if TSLPRM_TSC_SYNC_PIN == 1 // PB10
+ RCC->AHBENR |= RCC_AHBENR_GPIOBEN; // Set GPIOB clock
+ GPIOB->MODER &= 0xFFCFFFFF;
+ GPIOB->MODER |= 0x00200000;
+ GPIOB->AFR[1] |= 0x00000300;
+#endif
+#if TSLPRM_TSC_SYNC_PIN == 2 // PA15
+ RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // Set GPIOA clock
+ GPIOA->MODER &= 0x3FFFFFFF;
+ GPIOA->MODER |= 0x80000000;
+ GPIOA->AFR[1] |= 0x30000000;
+#endif
+
+ // Set Synchronization Polarity
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_SYNC_POL << 3) & 0x00000008;
+
+ // Set acquisition mode
+ TSC->CR |= (uint32_t)((uint32_t)TSLPRM_TSC_AM << 2) & 0x00000004;
+
+#endif
+
+#if TSLPRM_USE_ACQ_INTERRUPT > 0
+
+ // Set both EOA and MCE interrupts
+ TSC->IER |= 0x03;
+
+ // Configure NVIC
+ NVIC_SetPriority(EXTI2_TS_IRQn, 0);
+ NVIC_EnableIRQ(EXTI2_TS_IRQn);
+
+#endif
+
+ // Initialize the delay that will be used to discharge the capacitors
+ DelayDischarge = (uint32_t)((TSLPRM_DELAY_DISCHARGE_ALL * (uint32_t)(SystemCoreClock/1000000)) / 72);
+
+ return TSL_STATUS_OK;
+
+}
+
+
+/**
+ * @brief Configures a Bank.
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ uint32_t idx_ch;
+ uint32_t objs; /* bit field of TSL_ObjStatus_enum_T type */
+ uint32_t gx;
+ uint32_t ioy;
+ CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;
+ CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ // Mark the current bank processed
+ TSL_Globals.This_Bank = idx_bk;
+
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // Enable the Gx_IOy used as channels (channels + shield)
+ TSC->IOCCR = bank->msk_IOCCR_channels;
+ // Enable acquisition on selected Groups
+ TSC->IOGCSR = bank->msk_IOGCSR_groups;
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ // For all channels of the bank check if they are OFF or BURST_ONLY
+ // and set acquisition status flag
+ for (idx_ch = 0; idx_ch < bank->NbChannels; idx_ch++)
+ {
+
+ // Check Object status flag
+ objs = bank->p_chData[pchDest->IdxDest].Flags.ObjStatus;
+
+ if (objs != TSL_OBJ_STATUS_ON)
+ {
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // Get the Channel Group mask
+ gx = pchSrc->msk_IOGCSR_group;
+ // Stop acquisition of the Group
+ TSC->IOGCSR &= (uint32_t)~gx;
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ if (objs == TSL_OBJ_STATUS_OFF)
+ {
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ // Get the Channel IO mask
+ ioy = pchSrc->msk_IOCCR_channel;
+ // Stop Burst of the Channel
+ TSC->IOCCR &= (uint32_t)~ioy;
+ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ }
+ }
+
+ // Next channel
+ pchSrc++;
+ pchDest++;
+ }
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Start acquisition on a previously configured bank
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+ // Clear both EOAIC and MCEIC flags
+ TSC->ICR |= 0x03;
+
+ // Wait capacitors discharge
+ SoftDelay(DelayDischarge);
+
+#if TSLPRM_TSC_IODEF > 0 // Default = Input Floating
+ // Set IO default in Input Floating
+ TSC->CR |= (1 << 4);
+#endif
+
+ // Start acquisition
+ TSC->CR |= 0x02;
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ TSL_Status_enum_T retval = TSL_STATUS_BUSY;
+
+ // Check EOAF flag
+ if (TSC->ISR & 0x01)
+ {
+
+#if TSLPRM_TSC_IODEF > 0 // Default = Input Floating
+ // Set IO default in Output PP Low to discharge all capacitors
+ TSC->CR &= (uint32_t)(~(1 << 4));
+#endif
+
+ // Check MCEF flag
+ if (TSC->ISR & 0x02)
+ {
+ retval = TSL_STATUS_ERROR;
+ }
+ else
+ {
+ retval = TSL_STATUS_OK;
+ }
+ }
+
+ return retval;
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index)
+{
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_SRC_INDEX_0_7_OK(idx_bk));
+ return((TSL_tMeas_T)(TSC->IOGXCR[index]));
+}
+
+
+/**
+ * @brief Compute the Delta value
+ * @param[in] ref Reference value
+ * @param[in] meas Last Measurement value
+ * @retval Delta value
+ */
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas)
+{
+ return((TSL_tDelta_T)(ref - meas));
+}
+
+
+/**
+ * @brief Compute the Measurement value
+ * @param[in] ref Reference value
+ * @param[in] delta Delta value
+ * @retval Measurement value
+ */
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta)
+{
+ return((TSL_tMeas_T)(ref - delta));
+}
+
+
+/**
+ * @brief Check noise (not used)
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ return TSL_ACQ_STATUS_OK;
+}
+
+
+/**
+ * @brief Check if a filter must be used on the current channel (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if a filter can be applied
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ return TSL_TRUE;
+}
+
+
+/**
+ * @brief Test if the Reference is incorrect (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if the Reference is out of range
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ return TSL_FALSE;
+}
+
+
+/**
+ * @brief Test if the measure has crossed the reference target (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result TRUE if the Reference is valid
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ return TSL_TRUE;
+}
+
+
+#if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM
+#pragma optimize=low
+#elif defined(__CC_ARM) // Keil/MDK-ARM
+#pragma O1
+#pragma Ospace
+#elif defined(__TASKING__) // Altium/Tasking
+#pragma optimize O0
+#elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * @retval None
+ * @note Measurements done with HCLK=72MHz and Keil/MDK-ARM compiler
+ * val = 500: ~ 63µs
+ * val = 1000: ~126µs
+ * val = 2000: ~251µs
+ */
+void SoftDelay(uint32_t val)
+{
+ uint32_t idx;
+ for (idx = val; idx > 0; idx--)
+ {}
+}
+#if defined(__TASKING__)
+#pragma endoptimize
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c
new file mode 100644
index 0000000..dd7048f
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_hw.c
@@ -0,0 +1,862 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32l1xx_hw.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the acquisition
+ * on STM32l1xx products using the Hardware mode (with Timers).
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm32l1xx_hw.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+
+// Register configuration
+typedef struct
+{
+ unsigned int RI_ASCR : 3;
+ unsigned int RI_ASCR_bit : 5;
+} TSL_RIConf_t;
+
+/* Private defines -----------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
+
+// Acquisition pulses period
+/** Master timer reload value for HW acquisition only (range=4..65534, even number)
+ --> Period for Charge/Transfer cycle = ((TSLPRM_TIM_RELOAD*2)/FTimer)
+*/
+#define TIM_RELOAD ((TSLPRM_CT_PERIOD * TSLPRM_TIMER_FREQ) / 2)
+#define TIM9_PWM_CH1_WIDTH ((TIM_RELOAD >> 1) + 1) // Configure channel 1 Pulse Width
+#define TIM9_PWM_CH2_WIDTH ((TIM_RELOAD >> 1) - 1) // Configure channel 2 Pulse Width
+
+#define TSL_CHANNEL_PORT(channel) (channel >> 4)
+#define TSL_CHANNEL_IO(channel) (channel & 0x0F)
+
+#define TSL_GPIO_AFR(channel) ((TSL_CHANNEL_IO(channel) < 8) ? 0 : 1)
+#define TSL_GPIO_AFR_Shift(channel) ((TSL_CHANNEL_IO(channel) < 8) ? (4 * TSL_CHANNEL_IO(channel)) : (4 * (TSL_CHANNEL_IO(channel) - 8)))
+
+#define TSL_RI_HYSCR_MASK(channel) (1 << TSL_CHANNEL_IO(channel))
+#define TSL_RI_ASMR_MASK(channel) (1 << TSL_CHANNEL_IO(channel))
+#define TSL_RI_CMR_MASK(channel) (1 << TSL_CHANNEL_IO(channel))
+#define TSL_RI_CICR_MASK(channel) (1 << TSL_CHANNEL_IO(channel))
+
+#define TSL_RCC_AHBENR_Config(channel) (RCC->AHBENR |= TSL_GPIO_Clock_LookUpTable[TSL_CHANNEL_PORT(channel)])
+
+#define TSL_RI_ASCR_Config(channel) (*TSL_RI_ASCR_LookUpTable[TSL_RI_Conf_LookUpTable[channel].RI_ASCR] |= (1 << (TSL_RI_Conf_LookUpTable[channel].RI_ASCR_bit)))
+#define TSL_RI_HYSCR_Config(channel) (*TSL_RI_HYSCR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_HYSCR_MASK(channel))
+#define TSL_RI_ASMR_Config(channel) (*TSL_RI_ASMR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_ASMR_MASK(channel))
+#define TSL_RI_ASMR_Config_Clear(channel) (*TSL_RI_ASMR_LookUpTable[TSL_CHANNEL_PORT(channel)] &= (uint32_t)(~TSL_RI_ASMR_MASK(channel)))
+#define TSL_RI_CMR_Config(channel) (*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_CMR_MASK(channel))
+#define TSL_RI_CMR_Config_Clear(channel) (*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)] &= (uint32_t)(~TSL_RI_CMR_MASK(channel)))
+#define TSL_RI_CICR_Config(channel) (*TSL_RI_CICR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_CICR_MASK(channel))
+#define TSL_RI_CICR_Config_Clear(channel) (*TSL_RI_CICR_LookUpTable[TSL_CHANNEL_PORT(channel)] &= (uint32_t)(~TSL_RI_CICR_MASK(channel)))
+
+#define TSL_GPIO_MODER_IN_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER &= (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel)))))
+#define TSL_GPIO_MODER_AF_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER = (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER & (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel))))) | (2 << (2 * TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_MODER_OUT_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER = (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER & (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel))))) | (1 << (2 * TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_PUPDR_NO_PUPD_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->PUPDR &= (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel)))))
+#define TSL_GPIO_OTYPER_PP_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->OTYPER &= (uint32_t)(~(1 << TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_OSPEEDR_VL_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->OSPEEDR &= (uint32_t)~(3 << (2 * TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_AFR_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->AFR[TSL_GPIO_AFR(channel)] |= (0x0E << (TSL_GPIO_AFR_Shift(channel))))
+#define TSL_GPIO_BS_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->BSRRL = (uint16_t)(1 << (TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_BR_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->BSRRH = (uint16_t)(1 << (TSL_CHANNEL_IO(channel))))
+
+#define TSL_GPIO_AFR_NOAF_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->AFR[TSL_GPIO_AFR(channel)] &= (uint32_t)(~(0x0F << (TSL_GPIO_AFR_Shift(channel)))))
+
+#define TSL_GPIO_IDR_XOR_RI_CMR(channel) ((TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->IDR)^(*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)]))
+#define TSL_GPIO_IDR_AND_RI_CMR(channel) ((TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->IDR)&(*TSL_RI_CMR_LookUpTable[TSL_CHANNEL_PORT(channel)]))
+
+/* Private variables ---------------------------------------------------------*/
+CONST TSL_Bank_T *bank;
+TSL_tIndex_T NumberOfChannelOn = 0;
+TSL_tNb_T NumberOfChannels = 0;
+uint32_t tab_MeasurementCounter[11];
+TSL_Status_enum_T TSL_Acq_Status = TSL_STATUS_BUSY;
+static uint16_t GroupToCheck = 0;
+static TSL_tIndex_T NumberOfChannelChecked = 0;
+
+uint32_t TSL_GPIO_Clock_LookUpTable[] = {RCC_AHBPeriph_GPIOA, RCC_AHBPeriph_GPIOB, RCC_AHBPeriph_GPIOC, RCC_AHBPeriph_GPIOD, RCC_AHBPeriph_GPIOE, RCC_AHBPeriph_GPIOF, RCC_AHBPeriph_GPIOG, RCC_AHBPeriph_GPIOH};
+GPIO_TypeDef *TSL_GPIO_LookUpTable[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH};
+
+uint32_t *TSL_RI_ASCR_LookUpTable[] = {(uint32_t *)&RI->ASCR1, (uint32_t *)&RI->ASCR2};
+
+uint16_t *TSL_RI_HYSCR_LookUpTable[] =
+{
+ (uint16_t *)&RI->HYSCR1, (uint16_t *)&RI->HYSCR1 + 1,
+ (uint16_t *)&RI->HYSCR2, (uint16_t *)&RI->HYSCR2 + 1,
+ (uint16_t *)&RI->HYSCR3, (uint16_t *)&RI->HYSCR3 + 1,
+ (uint16_t *)&RI->HYSCR4, (uint16_t *)&RI->HYSCR4 + 1
+};
+
+uint32_t *TSL_RI_ASMR_LookUpTable[] = {(uint32_t *)&RI->ASMR1, (uint32_t *)&RI->ASMR2, (uint32_t *)&RI->ASMR3, 0, 0, (uint32_t *)&RI->ASMR4, (uint32_t *)&RI->ASMR5};
+uint32_t *TSL_RI_CMR_LookUpTable[] = {(uint32_t *)&RI->CMR1, (uint32_t *)&RI->CMR2, (uint32_t *)&RI->CMR3, 0, 0, (uint32_t *)&RI->CMR4, (uint32_t *)&RI->CMR5};
+uint32_t *TSL_RI_CICR_LookUpTable[] = {(uint32_t *)&RI->CICR1, (uint32_t *)&RI->CICR2, (uint32_t *)&RI->CICR3, 0, 0, (uint32_t *)&RI->CICR4, (uint32_t *)&RI->CICR5};
+
+CONST TSL_RIConf_t TSL_RI_Conf_LookUpTable[101] =
+{
+ {0, 0},
+ {0, 1},
+ {0, 2},
+ {0, 3},
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 6},
+ {0, 7},
+ {1, 9},
+ {1, 10},
+ {1, 11},
+ {1, 15},
+ {0, 0},//padding
+ {1, 6},
+ {1, 7},
+ {1, 8},
+
+ {0, 8},
+ {0, 9},
+ {1, 16},
+ {0, 0},//padding
+ {1, 4},
+ {1, 5},
+ {1, 27},
+ {1, 28},
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 18},
+ {0, 19},
+ {0, 20},
+ {0, 21},
+
+ {0, 10},
+ {0, 11},
+ {0, 12},
+ {0, 13},
+ {0, 14},
+ {0, 15},
+ {1, 0},
+ {1, 1},
+ {1, 2},
+ {1, 3},
+ {1, 29},
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 27},
+ {0, 28},
+ {0, 29},
+ {0, 30},
+ {0, 16},
+ {1, 17},
+ {1, 18},
+ {1, 19},
+ {1, 20},
+ {1, 21},
+
+ {1, 22},
+ {1, 23},
+ {1, 24},
+ {1, 25},
+ {1, 26}
+};
+
+/* Private functions prototype -----------------------------------------------*/
+void TSL_Init_GPIOs(void);
+void TSL_Init_TIMs(void);
+void TSL_Init_RI(void);
+uint8_t TSL_Check_GPIO_IDR(uint8_t sample);
+void SoftDelay(uint16_t val);
+
+
+/**
+ * @brief Initializes the TouchSensing GPIOs.
+ * @param None
+ * @retval None
+ */
+void TSL_Init_GPIOs(void)
+{
+ CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]);
+ TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS;
+ TSL_tNb_T LocalNumberOfChannels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+ CONST TSL_ChannelSrc_T *p_chSrc = LocalBank->p_chSrc; // Pointer to the current channel
+
+ for (idx_bk = 0; idx_bk < NumberOfBanks; idx_bk++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = LocalBank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Enables GPIOs clock
+ TSL_RCC_AHBENR_Config(LocalBank->shield_sample);
+
+ // Bank shield configuration
+ TSL_GPIO_OTYPER_PP_Config(LocalBank->shield_channel);
+ TSL_GPIO_OSPEEDR_VL_Config(LocalBank->shield_channel);
+ TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_channel);
+ TSL_GPIO_AFR_Config(LocalBank->shield_channel);
+
+ TSL_GPIO_OSPEEDR_VL_Config(LocalBank->shield_sample);
+ TSL_GPIO_BR_Config(LocalBank->shield_sample);
+ TSL_GPIO_OTYPER_PP_Config(LocalBank->shield_sample);
+ TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_sample);
+
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_sample);
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_channel);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < LocalNumberOfChannels;
+ idx_ch++)
+ {
+ TSL_RCC_AHBENR_Config(p_chSrc->t_sample);
+ TSL_RCC_AHBENR_Config(p_chSrc->t_channel);
+
+ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_channel);
+ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_channel);
+ TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_channel);
+ TSL_GPIO_AFR_Config(p_chSrc->t_channel);
+
+ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_sample);
+ TSL_GPIO_BR_Config(p_chSrc->t_sample);
+ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_sample);
+ TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_sample);
+
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel);
+
+ p_chSrc++;
+ }
+ }
+}
+
+/**
+ * @brief Initializes the TouchSensing timers.
+ * @param None
+ * @retval None
+ */
+// Acquisition pulses period
+/** Master timer reload value for HW acquisition only (range=4..65534, even number)
+ --> Period for Charge/Transfer cycle = ((TSLPRM_TIM_RELOAD*2)/FTimer)
+*/
+void TSL_Init_TIMs(void)
+{
+ // Enable Timers clocks
+ RCC->APB2ENR |= ((1 << 4) | (1 << 2)); // TIM11, TIM9
+
+ //==============================
+ // TIMER 9 configuration: Master
+ //==============================
+ // Set the option register to redirect RI_tim9_itr_O to TIM9_itr
+ TIM9->OR |= 4;
+ // Set the Autoreload value (signal frequency)
+ //TIM9->ARR = 64; // freq = (64*2)*31.25ns = 1us
+ TIM9->ARR = TIM_RELOAD; // freq = (64*2)*31.25ns = 1us
+ // Set the Prescaler value
+ //TIM9->PSC = 0; // fCK_CNT = 32MHz/(0+1) = 32MHz --> T=31.25ns
+ //TIM9->PSC = TSLPRM_TIM_PRESCALER; // fCK_CNT = 32MHz/(1+1) = 32MHz --> T=31.25ns
+ TIM9->PSC = 0; // fCK_CNT = 32MHz/(1+1) = 32MHz --> T=31.25ns
+ // Set UP counter, Center-Aligned mode 1
+ TIM9->CR1 = 0x20;
+ // OC1REF used as TRGO
+ TIM9->CR2 |= 0x40; // MMS=100
+ // Select Master mode
+ TIM9->SMCR = 0x95;
+ // Set Update generation
+ TIM9->EGR |= 0x01;
+
+ // Channel 1 PWM configuration
+ // Set the Output Compare Mode, PWM2
+ TIM9->CCMR1 |= 0x0070;
+ // Set the Pulse value
+ //TIM9->CCR1 = 34; // duty cycle
+ TIM9->CCR1 = TIM9_PWM_CH1_WIDTH; // duty cycle
+ // Compare output enable, active high
+ TIM9->CCER |= 0x01;
+
+ // Channel 2 PWM configuration
+ // Set the Output Compare Mode, PWM2
+ TIM9->CCMR1 |= 0x6000;
+ // Set the Pulse value
+ //TIM9->CCR2 = 30;
+ TIM9->CCR2 = TIM9_PWM_CH2_WIDTH;
+ // Compare output enable, active high
+ TIM9->CCER |= 0x10;
+
+ //==============================
+ // TIMER 11 configuration: slave
+ //==============================
+ // Set the option register to redirect TIM11_ic_o to TIM11_ti
+ TIM11->OR |= 8;
+ // Set the option register to redirect TIM9_tgo_cktim to TIM11_etri
+ TIM11->OR |= 4;
+ // Set the Prescaler value
+ TIM11->PSC = 0;
+ // Set UP counter, edge-aligned mode
+ TIM11->CR1 = 0;
+ // Select Slave mode, Internal Trigger 2 (ITR2 = TIM9), External clock mode 1
+ TIM11->SMCR = 0x4000; // ECE bit
+ // Channel 1 configured in Input capture mode
+ TIM11->CCMR1 = 0x01; // No prescaler, no filter
+ // Channel 1 capture enable (CCE1 = 1)
+ TIM11->CCER = 0x01;
+ // Set auto reload regarding the max count
+#if (TSLPRM_ACQ_MAX < 16534)
+ TIM11->ARR = TSLPRM_ACQ_MAX+1;
+#endif
+ // Interrupt Enable, active high, Enable interrupt when counter reaches max count (ARR)
+ TIM11->DIER |= 0x03;
+ // Start slave timer
+ TIM11->CR1 |= 0x01;
+}
+
+
+/**
+ * @brief Init TS routing interface.
+ * @param None
+ * @retval None
+ */
+void TSL_Init_RI(void)
+{
+ CONST TSL_Bank_T *LocalBank;
+ TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS;
+ TSL_tNb_T LocalNumberOfChannels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+ CONST TSL_ChannelSrc_T *p_chSrc; // Pointer to the current channel
+
+ RCC->APB1ENR |= (uint32_t)((uint32_t)1 << 31); // COMP enable
+
+ for (idx_bk = 0; idx_bk < NumberOfBanks; idx_bk++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[idx_bk]);
+
+#if (TSLPRM_USE_SHIELD > 0)
+ TSL_RI_HYSCR_Config(LocalBank->shield_sample);
+ TSL_RI_CICR_Config(LocalBank->shield_sample);
+ TSL_RI_CICR_Config_Clear(LocalBank->shield_channel);
+
+ TSL_RI_ASCR_Config(LocalBank->shield_sample);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ p_chSrc = LocalBank->p_chSrc;
+ for (idx_ch = 0; idx_ch < LocalNumberOfChannels; idx_ch++)
+ {
+ TSL_RI_HYSCR_Config(p_chSrc->t_sample);
+ TSL_RI_CICR_Config(p_chSrc->t_sample);
+ TSL_RI_CICR_Config_Clear(p_chSrc->t_channel);
+ TSL_RI_ASCR_Config(p_chSrc->t_sample);
+ p_chSrc++;
+ }
+ }
+
+ // Reset TSUSP bit, TIM9 ITR enabled to suspend OC TIM9 generation
+ COMP->CSR &= (uint32_t)(~0x80000000);
+
+}
+
+
+/**
+ * @brief Initializes the acquisition module.
+ * @param None
+ * @retval retval
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+ NVIC_InitTypeDef NVIC_InitStructure;
+
+ NVIC_InitStructure.NVIC_IRQChannel = TIM11_IRQn;
+ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init(&NVIC_InitStructure);
+
+ TSL_Init_GPIOs();
+ TSL_Init_TIMs();
+ TSL_Init_RI();
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Configures a Bank.
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ TSL_tIndex_T idx_dest;
+ TSL_tIndex_T idx_ch;
+ CONST TSL_ChannelDest_T *p_chDest; // Pointer to the current channel
+ CONST TSL_ChannelSrc_T *p_chSrc; // Pointer to the current channel
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ bank = &(TSL_Globals.Bank_Array[idx_bk]);
+
+ NumberOfChannels = bank->NbChannels;
+
+ GroupToCheck = 0;//init group to check
+ NumberOfChannelOn = 0;//init number of channel on
+
+ // init RI ASMR
+ RI->ASMR1 = 0;
+ RI->ASMR2 = 0;
+ RI->ASMR3 = 0;
+ RI->ASMR4 = 0;
+ RI->ASMR5 = 0;
+
+ p_chDest = bank->p_chDest;
+ p_chSrc = bank->p_chSrc;
+ for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++)
+ {
+ // Get index in the result array associated to the current channel
+ idx_dest = p_chDest->IdxDest;
+ if (bank->p_chData[idx_dest].Flags.ObjStatus != TSL_OBJ_STATUS_OFF)
+ {
+ TSL_RI_CMR_Config(p_chSrc->t_sample);
+ TSL_RI_ASMR_Config(p_chSrc->t_channel);
+ GroupToCheck |= (1 << (p_chSrc->IdxSrc));
+ NumberOfChannelOn++;
+ }
+ p_chDest++;
+ p_chSrc++;
+ }
+
+ return TSL_STATUS_OK;
+
+}
+
+
+/**
+ * @brief Start acquisition on a previously configured bank
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+#if (TSLPRM_IODEF > 0)
+ CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]);
+ TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS;
+ TSL_tNb_T LocalNumberOfChannels = 0;
+ TSL_tIndex_T BankIndex;
+#endif
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ CONST TSL_ChannelDest_T *p_chDest;
+ TSL_tIndex_T idx_dest;
+ TSL_tIndex_T idx_ch;
+
+ if (NumberOfChannelOn)
+ {
+#if (TSLPRM_IODEF > 0)
+ //============================
+ // All GPIOs in Input floating
+ //============================
+ for (BankIndex = 0; BankIndex < NumberOfBanks; BankIndex++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[BankIndex]);
+ p_chSrc = LocalBank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ TSL_GPIO_MODER_IN_Config(LocalBank->shield_sample);
+ TSL_GPIO_MODER_IN_Config(LocalBank->shield_channel);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < LocalNumberOfChannels;
+ idx_ch++)
+ {
+ TSL_GPIO_MODER_IN_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_IN_Config(p_chSrc->t_channel);
+
+ p_chSrc++;
+ }
+ }
+#endif
+
+
+ // Reset count
+ TIM11->CNT = 0;
+
+ // Discharge sample capacitors
+ p_chDest = bank->p_chDest;
+ p_chSrc = bank->p_chSrc;
+ for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++)
+ {
+ // Get index in the result array associated to the current channel
+ idx_dest = p_chDest->IdxDest;
+ if (bank->p_chData[idx_dest].Flags.ObjStatus != TSL_OBJ_STATUS_OFF)
+ {
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample);
+ }
+ p_chDest++;
+ p_chSrc++;
+ }
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Discharge shield sample capacitor
+ TSL_GPIO_MODER_OUT_Config(bank->shield_sample);
+#endif
+
+ // Wait for capa discharge
+ SoftDelay(0x80);
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Init sample shield in floating input
+ TSL_GPIO_MODER_IN_Config(bank->shield_sample);
+ TSL_GPIO_MODER_AF_Config(bank->shield_channel);
+
+ TSL_RI_ASMR_Config(bank->shield_channel);
+#endif
+
+ // Init samples in floating input and channels in alternate
+ p_chDest = bank->p_chDest;
+ p_chSrc = bank->p_chSrc;
+ for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++)
+ {
+ // Get index in the result array associated to the current channel
+ idx_dest = p_chDest->IdxDest;
+
+ if (bank->p_chData[idx_dest].Flags.ObjStatus != TSL_OBJ_STATUS_OFF)
+ {
+ TSL_GPIO_MODER_IN_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_AF_Config(p_chSrc->t_channel);
+ }
+
+ p_chDest++;
+ p_chSrc++;
+ }
+
+ /* Start acquisition */
+ TSL_Acq_Status = TSL_STATUS_BUSY;
+ TIM9 ->CR1 |= 0x01; // Master
+ }
+ else
+ {
+ TSL_Acq_Status = TSL_STATUS_OK;
+ }
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ return TSL_Acq_Status;
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index)
+{
+ return(tab_MeasurementCounter[index]);
+}
+
+
+/**
+ * @brief Check noise (not used)
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ return TSL_ACQ_STATUS_OK;
+}
+
+
+/**
+ * @brief Check GPIO IDR for the sample
+ * @param[in] sample
+ * @retval Status
+ */
+uint8_t TSL_Check_GPIO_IDR(uint8_t sample)
+{
+ GPIO_TypeDef *GPIO;
+ uint32_t GPIO_IDR_Mask = 0;
+
+ GPIO = TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(sample)];
+
+ GPIO_IDR_Mask = (1 << (sample & 0x0F));
+
+ if (((GPIO->IDR) & GPIO_IDR_Mask) == GPIO_IDR_Mask)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+/**
+ * @brief Process the TS Interrupt routine
+ * @param None
+ * @retval None
+ */
+void TSL_acq_ProcessIT(void)
+{
+ CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]);
+ TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS;
+ TSL_tNb_T LocalNumberOfChannels = 0;
+ TSL_tIndex_T BankIndex;
+
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ CONST TSL_ChannelDest_T *p_chDest;
+ TSL_tIndex_T idx_dest;
+ TSL_tIndex_T idx_ch;
+ TSL_tNb_T CounterOverflowFlag = 0;
+
+ CounterOverflowFlag = TIM11->SR & TIM_SR_UIF;
+
+ // Reset flags
+ TIM11->SR = 0;
+ idx_ch = 0;
+
+ p_chDest = bank->p_chDest;
+ p_chSrc = bank->p_chSrc;
+ do
+ {
+ // Get index in the result array associated to the current channel
+ idx_dest = p_chDest->IdxDest;
+
+ if (bank->p_chData[idx_dest].Flags.ObjStatus != TSL_OBJ_STATUS_OFF)
+ {
+ if ((TSL_Check_GPIO_IDR(p_chSrc->t_sample)) &&
+ ((GroupToCheck & (1 << (p_chSrc->IdxSrc))) == (1 << (p_chSrc->IdxSrc))))
+ {
+ tab_MeasurementCounter[p_chSrc->IdxSrc] = TIM11->CCR1;
+ NumberOfChannelChecked++;
+ GroupToCheck &= (uint32_t)(~(1 << (p_chSrc->IdxSrc)));
+
+ // Reset CMR register to restart the timer
+ TSL_RI_CMR_Config_Clear(p_chSrc->t_sample);
+ }
+ // Manage Overflow
+ else if((CounterOverflowFlag) &&
+ ((GroupToCheck & (1 << (p_chSrc->IdxSrc))) == (1 << (p_chSrc->IdxSrc))))
+ {
+ tab_MeasurementCounter[p_chSrc->IdxSrc] = TSLPRM_ACQ_MAX + 1;
+ GroupToCheck &= (uint32_t)(~(1 << (p_chSrc->IdxSrc)));
+
+ // Reset CMR register to restart the timer
+ TSL_RI_CMR_Config_Clear(p_chSrc->t_sample);
+ }
+ }
+ p_chDest++;
+ p_chSrc++;
+ idx_ch++;
+ }
+ while (idx_ch < NumberOfChannels);
+
+ if (NumberOfChannelChecked >= NumberOfChannelOn)
+ {
+ NumberOfChannelOn = 0;
+ NumberOfChannelChecked = 0;
+
+ // Disable master counter
+ TIM9->CR1 &= (uint16_t)(~0x01);
+
+ //====================
+ // All GPIOs in PP Low
+ //====================
+ for (BankIndex = 0; BankIndex < NumberOfBanks; BankIndex++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[BankIndex]);
+ p_chSrc = LocalBank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ TSL_GPIO_BR_Config(LocalBank->shield_sample);
+ TSL_GPIO_BR_Config(LocalBank->shield_channel);
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_sample);
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_channel);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < LocalNumberOfChannels;
+ idx_ch++)
+ {
+ TSL_GPIO_BR_Config(p_chSrc->t_sample);
+ TSL_GPIO_BR_Config(p_chSrc->t_channel);
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel);
+
+ p_chSrc++;
+ }
+ }
+ TSL_Acq_Status = TSL_STATUS_OK;
+ }
+}
+
+
+/**
+ * @brief Check if a filter must be used on the current channel (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if a filter can be applied
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ return TSL_TRUE;
+}
+
+
+/**
+ * @brief Compute the Delta value
+ * @param[in] ref Reference value
+ * @param[in] meas Last Measurement value
+ * @retval Delta value
+ */
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas)
+{
+ return((TSL_tDelta_T)(ref - meas));
+}
+
+
+/**
+ * @brief Compute the Measurement value
+ * @param[in] ref Reference value
+ * @param[in] delta Delta value
+ * @retval Measurement value
+ */
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta)
+{
+ return((TSL_tMeas_T)(ref - delta));
+}
+
+
+/**
+ * @brief Test if the Reference is incorrect (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if the Reference is out of range
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ return TSL_FALSE;
+}
+
+
+/**
+ * @brief Test if the measure has crossed the reference target (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result TRUE if the Reference is valid
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ return TSL_TRUE;
+}
+
+
+#if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM
+#pragma optimize=medium
+#elif defined(__CC_ARM) // Keil/MDK-ARM
+#pragma O1
+#pragma Ospace
+#elif defined(__TASKING__) // Altium/Tasking
+#pragma optimize O0
+#elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * With fHCLK = 32MHz: 1 = ~1µs, 50 = ~14µs, 100 = ~25µs, 200 = ~50µs
+ * @retval None
+ */
+void SoftDelay(uint16_t val)
+{
+ __IO uint16_t idx;
+ for (idx = val; idx > 0; idx--)
+ {}
+}
+#if defined(__TASKING__)
+#pragma endoptimize
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_sw.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_sw.c
new file mode 100644
index 0000000..98e6792
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm32l1xx_sw.c
@@ -0,0 +1,996 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm32l1xx_sw.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the acquisition
+ * on STM32l1xx products using the software mode.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm32l1xx_sw.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+
+// Register configuration
+typedef struct
+{
+ unsigned int RI_ASCR : 3;
+ unsigned int RI_ASCR_bit : 5;
+} TSL_RIConf_t;
+
+/* Private defines -----------------------------------------------------------*/
+#define SIZEOFBANKCONF (17) //2 mask RIRs + 5 ports x 3 mask registers(MODER input, output, ODR) => 17 registers
+
+/* Private macros ------------------------------------------------------------*/
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
+
+#define TSL_CHANNEL_PORT(channel) (channel >> 4)
+#define TSL_CHANNEL_IO(channel) (channel & 0x0F)
+
+
+#define TSL_RI_HYSCR_MASK(channel) (1 << TSL_CHANNEL_IO(channel))
+
+#define TSL_RCC_AHBENR_Config(channel) (RCC->AHBENR |= TSL_GPIO_Clock_LookUpTable[TSL_CHANNEL_PORT(channel)])
+
+#define TSL_RI_HYSCR_Config(channel) (*TSL_RI_HYSCR_LookUpTable[TSL_CHANNEL_PORT(channel)] |= TSL_RI_HYSCR_MASK(channel))
+
+#define TSL_GPIO_MODER_IN_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER &= (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel)))))
+#define TSL_GPIO_MODER_OUT_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER = (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->MODER & (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel))))) | (1 << (2 * TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_PUPDR_NO_PUPD_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->PUPDR &= (uint32_t)(~(3 << (2 * TSL_CHANNEL_IO(channel)))))
+#define TSL_GPIO_OTYPER_PP_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->OTYPER &= (uint32_t)(~(1 << TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_OSPEEDR_VL_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->OSPEEDR &= (uint32_t)~(3 << (2 * TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_BS_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->BSRRL = (uint16_t)(1 << (TSL_CHANNEL_IO(channel))))
+#define TSL_GPIO_BR_Config(channel) (TSL_GPIO_LookUpTable[TSL_CHANNEL_PORT(channel)]->BSRRH = (uint16_t)(1 << (TSL_CHANNEL_IO(channel))))
+
+
+/* Private variables ---------------------------------------------------------*/
+uint32_t TSL_BankSampleConf[SIZEOFBANKCONF];
+uint32_t TSL_BankChannelConf[SIZEOFBANKCONF];
+uint32_t tab_MeasurementCounter[11];
+extern TSL_Params_T TSL_Params;
+
+CONST TSL_Bank_T *bank;
+TSL_tIndex_T NumberOfChannelOn = 0;
+TSL_tNb_T NumberOfChannels = 0;
+TSL_Status_enum_T TSL_Acq_Status = TSL_STATUS_BUSY;
+uint16_t GroupToCheck = 0;
+
+uint32_t TSL_GPIO_Clock_LookUpTable[] = {RCC_AHBPeriph_GPIOA, RCC_AHBPeriph_GPIOB, RCC_AHBPeriph_GPIOC, RCC_AHBPeriph_GPIOD, RCC_AHBPeriph_GPIOE, RCC_AHBPeriph_GPIOF, RCC_AHBPeriph_GPIOG, RCC_AHBPeriph_GPIOH};
+GPIO_TypeDef *TSL_GPIO_LookUpTable[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH};
+
+uint16_t *TSL_RI_HYSCR_LookUpTable[] =
+{
+ (uint16_t *)&RI->HYSCR1, (uint16_t *)&RI->HYSCR1 + 1,
+ (uint16_t *)&RI->HYSCR2, (uint16_t *)&RI->HYSCR2 + 1,
+ (uint16_t *)&RI->HYSCR3, (uint16_t *)&RI->HYSCR3 + 1,
+ (uint16_t *)&RI->HYSCR4, (uint16_t *)&RI->HYSCR4 + 1
+};
+
+CONST TSL_RIConf_t TSL_RI_Conf_LookUpTable[101] =
+{
+ {0, 0},
+ {0, 1},
+ {0, 2},
+ {0, 3},
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 6},
+ {0, 7},
+ {1, 9},
+ {1, 10},
+ {1, 11},
+ {1, 15},
+ {0, 0},//padding
+ {1, 6},
+ {1, 7},
+ {1, 8},
+
+ {0, 8},
+ {0, 9},
+ {1, 16},
+ {0, 0},//padding
+ {1, 4},
+ {1, 5},
+ {1, 27},
+ {1, 28},
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 18},
+ {0, 19},
+ {0, 20},
+ {0, 21},
+
+ {0, 10},
+ {0, 11},
+ {0, 12},
+ {0, 13},
+ {0, 14},
+ {0, 15},
+ {1, 0},
+ {1, 1},
+ {1, 2},
+ {1, 3},
+ {1, 29},
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 0},//padding
+ {0, 27},
+ {0, 28},
+ {0, 29},
+ {0, 30},
+ {0, 16},
+ {1, 17},
+ {1, 18},
+ {1, 19},
+ {1, 20},
+ {1, 21},
+
+ {1, 22},
+ {1, 23},
+ {1, 24},
+ {1, 25},
+ {1, 26}
+};
+
+#if (TSLPRM_USE_GPIOA)
+uint32_t GPIOA_IDR_Mask = 0;
+#endif
+#if (TSLPRM_USE_GPIOB)
+uint32_t GPIOB_IDR_Mask = 0;
+#endif
+#if (TSLPRM_USE_GPIOC)
+uint32_t GPIOC_IDR_Mask = 0;
+#endif
+#if (TSLPRM_USE_GPIOF)
+uint32_t GPIOF_IDR_Mask = 0;
+#endif
+#if (TSLPRM_USE_GPIOG)
+uint32_t GPIOG_IDR_Mask = 0;
+#endif
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+uint8_t SpreadCounter = TSLPRM_SPREAD_MIN;
+#endif
+
+/* Private functions prototype -----------------------------------------------*/
+void SoftDelay(uint16_t val);
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+__INLINE void SwSpreadSpectrum(void);
+#endif
+void TSL_BankConf(uint32_t * BankConf, TSL_Conf_t Conf);
+void TSL_acq_GroupDone(uint16_t EndedGroup);
+
+/**
+ * @brief Configures the acquisition module.
+ * @param[in] BankConf Pointer to the bank to configure
+ * @param[in] Conf Configuration
+ * @retval None
+ */
+void TSL_BankConf(uint32_t *BankConf, TSL_Conf_t Conf)
+{
+ BankConf[TSL_RI_Conf_LookUpTable[Conf].RI_ASCR] |= (1 << (TSL_RI_Conf_LookUpTable[Conf].RI_ASCR_bit));
+
+ switch (TSL_CHANNEL_PORT(Conf))
+ {
+ case TSL_BANK_GPIOA: BankConf[2] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input
+ BankConf[3] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output
+ BankConf[4] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR
+ break;
+ case TSL_BANK_GPIOB: BankConf[5] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input
+ BankConf[6] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output
+ BankConf[7] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR
+ break;
+ case TSL_BANK_GPIOC: BankConf[8] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input
+ BankConf[9] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output
+ BankConf[10] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR
+ break;
+ case TSL_BANK_GPIOF: BankConf[11] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input
+ BankConf[12] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output
+ BankConf[13] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR
+ break;
+ case TSL_BANK_GPIOG: BankConf[14] |= (3 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER input
+ BankConf[15] |= (1 << (2 * (TSL_CHANNEL_IO(Conf)))); //MODER output
+ BankConf[16] |= (1 << (TSL_CHANNEL_IO(Conf))); //ODR
+ break;
+ default: break;
+ }
+}
+
+
+/**
+ * @brief Initializes the acquisition module.
+ * @param None
+ * @retval None
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+ CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]);
+ TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS;
+ TSL_tNb_T LocalNumberOfChannels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+ CONST TSL_ChannelSrc_T *p_chSrc = LocalBank->p_chSrc; // Pointer to the current channel
+
+ /* Enables the comparator interface clock */
+ RCC->APB1ENR |= RCC_APB1Periph_COMP;
+
+ //====================
+ // GPIOs configuration
+ //====================
+ for (idx_bk = 0; idx_bk < NumberOfBanks; idx_bk++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = LocalBank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Enables GPIOs clock
+ TSL_RCC_AHBENR_Config(LocalBank->shield_sample);
+
+ // Bank shield configuration
+ /* Disables Hysteresis Register */
+ TSL_RI_HYSCR_Config(LocalBank->shield_sample);
+
+ /* Output PP config */
+ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_sample);
+ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_channel);
+ /* 400kHz config */
+ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_sample);
+ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_channel);
+ /* No pull up/pull down config */
+ TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_sample);
+ TSL_GPIO_PUPDR_NO_PUPD_Config(LocalBank->shield_channel);
+ /* Set ODR */
+ TSL_GPIO_BR_Config(LocalBank->shield_sample);
+ TSL_GPIO_BR_Config(LocalBank->shield_channel);
+ /* Output mode */
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_sample);
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_channel);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < LocalNumberOfChannels;
+ idx_ch++)
+ {
+ /* Enables GPIOs clock */
+ TSL_RCC_AHBENR_Config(p_chSrc->t_sample);
+ TSL_RCC_AHBENR_Config(p_chSrc->t_channel);
+
+ // Bank/channel configuration
+ /* Disables Hysteresis Register */
+ TSL_RI_HYSCR_Config(p_chSrc->t_sample);
+ /* Output PP config */
+ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_sample);
+ TSL_GPIO_OTYPER_PP_Config(p_chSrc->t_channel);
+ /* 400kHz config */
+ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_sample);
+ TSL_GPIO_OSPEEDR_VL_Config(p_chSrc->t_channel);
+ /* No pull up/pull down config */
+ TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_sample);
+ TSL_GPIO_PUPDR_NO_PUPD_Config(p_chSrc->t_channel);
+ /* Set ODR */
+ TSL_GPIO_BR_Config(p_chSrc->t_sample);
+ TSL_GPIO_BR_Config(p_chSrc->t_channel);
+ /* Output mode */
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel);
+
+ p_chSrc++;
+ }
+ }
+
+ /* Enable RI Switch */
+ RI->ASCR1 &= (uint32_t)(~0x80000000); // ADC analog switches open !!!
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Configures a Bank.
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ TSL_tIndex_T index;
+ TSL_tIndex_T idx_dest;
+ TSL_tIndex_T idx_ch;
+ CONST TSL_ChannelDest_T *p_chDest; // Pointer to the current channel
+ CONST TSL_ChannelSrc_T *p_chSrc; // Pointer to the current channel
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ bank = &(TSL_Globals.Bank_Array[idx_bk]);
+
+ for (index = 0;index < SIZEOFBANKCONF;index++)
+ {
+ TSL_BankSampleConf[index] = 0x00000000;
+ TSL_BankChannelConf[index] = 0x00000000;
+ }
+
+ NumberOfChannels = bank->NbChannels;
+ NumberOfChannelOn = 0;
+ GroupToCheck = 0;//init group to check
+
+ p_chDest = bank->p_chDest;
+ p_chSrc = bank->p_chSrc;
+ for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++)
+ {
+ // Get index in the result array associated to the current channel
+ idx_dest = p_chDest->IdxDest;
+
+ if (bank->p_chData[idx_dest].Flags.ObjStatus != TSL_OBJ_STATUS_OFF)
+ {
+ TSL_BankConf(TSL_BankSampleConf, p_chSrc->t_sample);
+ TSL_BankConf(TSL_BankChannelConf, p_chSrc->t_channel);
+ GroupToCheck |= (1 << (p_chSrc->IdxSrc));
+ NumberOfChannelOn++;
+ }
+
+ p_chSrc++;
+ p_chDest++;
+ }
+
+#if (TSLPRM_USE_GPIOA)
+ GPIOA_IDR_Mask = TSL_BankSampleConf[4];
+#endif
+
+#if (TSLPRM_USE_GPIOB)
+ GPIOB_IDR_Mask = TSL_BankSampleConf[7];
+#endif
+
+#if (TSLPRM_USE_GPIOC)
+ GPIOC_IDR_Mask = TSL_BankSampleConf[10];
+#endif
+
+#if (TSLPRM_USE_GPIOF)
+ GPIOF_IDR_Mask = TSL_BankSampleConf[13];
+#endif
+
+#if (TSLPRM_USE_GPIOG)
+ GPIOG_IDR_Mask = TSL_BankSampleConf[16];
+#endif
+
+
+#if (TSLPRM_USE_SHIELD > 0)
+ if (NumberOfChannelOn != 0)
+ {
+ TSL_BankConf(TSL_BankSampleConf, bank->shield_sample);
+ TSL_BankConf(TSL_BankChannelConf, bank->shield_channel);
+ }
+#endif
+
+ return TSL_STATUS_OK;
+
+}
+
+
+/**
+ * @brief Check which group is not over
+ * @param[in] EndedGroup
+ * @retval None
+ */
+void TSL_acq_GroupDone(uint16_t EndedGroup)
+{
+ uint16_t i;
+
+ for (i = 0;i < 11;i++)
+ {
+ if ((EndedGroup & (1 << i)) != (1 << i))
+ {
+ tab_MeasurementCounter[i] = TSL_Params.AcqMax + 1;
+ }
+ }
+
+}
+
+
+/**
+ * @brief Start acquisition on a previously configured bank
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+ CONST TSL_Bank_T *LocalBank = &(TSL_Globals.Bank_Array[0]);
+ TSL_tNb_T NumberOfBanks = TSLPRM_TOTAL_BANKS;
+ TSL_tNb_T LocalNumberOfChannels = 0;
+ TSL_tIndex_T BankIndex;
+
+ uint16_t MeasurementCounter = 0;
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ TSL_tIndex_T idx_ch;
+ uint16_t GroupToCheckMask = 0;
+ uint32_t GPIO_IDR_Mask = 0;
+ uint8_t Check_Input = 0;
+
+#if (TSLPRM_USE_GPIOA)
+ uint16_t TSL_GPIOA_IDR = 0;
+#endif
+#if (TSLPRM_USE_GPIOB)
+ uint16_t TSL_GPIOB_IDR = 0;
+#endif
+#if (TSLPRM_USE_GPIOC)
+ uint16_t TSL_GPIOC_IDR = 0;
+#endif
+#if (TSLPRM_USE_GPIOF)
+ uint16_t TSL_GPIOF_IDR = 0;
+#endif
+#if (TSLPRM_USE_GPIOG)
+ uint16_t TSL_GPIOG_IDR = 0;
+#endif
+ uint16_t GPIO_IDR = 0;
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __disable_irq();
+#endif
+#if (TSLPRM_IODEF > 0)
+ //============================
+ // All GPIOs in Input floating
+ //============================
+ for (BankIndex = 0; BankIndex < NumberOfBanks; BankIndex++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[BankIndex]);
+ p_chSrc = LocalBank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ TSL_GPIO_MODER_IN_Config(LocalBank->shield_sample);
+ TSL_GPIO_MODER_IN_Config(LocalBank->shield_channel);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < LocalNumberOfChannels;
+ idx_ch++)
+ {
+ TSL_GPIO_MODER_IN_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_IN_Config(p_chSrc->t_channel);
+
+ p_chSrc++;
+ }
+ }
+#endif
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __enable_irq();
+#endif
+
+ /* Open the analog switches */
+ RI->ASCR1 &= (uint32_t)(~(TSL_BankSampleConf[0] | TSL_BankChannelConf[0]));
+ RI->ASCR2 &= (uint32_t)(~(TSL_BankSampleConf[1] | TSL_BankChannelConf[1]));
+
+ /* All IO to pushpull LOW for discharging all capacitors (Ctouch and Csense) */
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __disable_irq();
+#endif
+ /* Discharging sampling capacitor and CTouch */
+#if (TSLPRM_USE_GPIOA)
+ GPIOA->ODR &= (uint32_t)(~(TSL_BankSampleConf[4] | TSL_BankChannelConf[4]));
+ GPIOA->MODER = (GPIOA->MODER & (uint32_t)(~(TSL_BankSampleConf[2] | TSL_BankChannelConf[2]))) | (TSL_BankSampleConf[3] | TSL_BankChannelConf[3]);
+#endif
+#if (TSLPRM_USE_GPIOB)
+ GPIOB->ODR &= (uint32_t)(~(TSL_BankSampleConf[7] | TSL_BankChannelConf[7]));
+ GPIOB->MODER = (GPIOB->MODER & (uint32_t)(~(TSL_BankSampleConf[5] | TSL_BankChannelConf[5]))) | (TSL_BankSampleConf[6] | TSL_BankChannelConf[6]);
+#endif
+#if (TSLPRM_USE_GPIOC)
+ GPIOC->ODR &= (uint32_t)(~(TSL_BankSampleConf[10] | TSL_BankChannelConf[10]));
+ GPIOC->MODER = (GPIOC->MODER & (uint32_t)(~(TSL_BankSampleConf[8] | TSL_BankChannelConf[8]))) | (TSL_BankSampleConf[9] | TSL_BankChannelConf[9]);
+#endif
+#if (TSLPRM_USE_GPIOF)
+ GPIOF->ODR &= (uint32_t)(~(TSL_BankSampleConf[13] | TSL_BankChannelConf[13]));
+ GPIOF->MODER = (GPIOF->MODER & (uint32_t)(~(TSL_BankSampleConf[11] | TSL_BankChannelConf[11]))) | (TSL_BankSampleConf[12] | TSL_BankChannelConf[12]);
+#endif
+#if (TSLPRM_USE_GPIOG)
+ GPIOG->ODR &= (uint32_t)(~(TSL_BankSampleConf[16] | TSL_BankChannelConf[16]));
+ GPIOG->MODER = (GPIOG->MODER & (uint32_t)(~(TSL_BankSampleConf[14] | TSL_BankChannelConf[14]))) | (TSL_BankSampleConf[15] | TSL_BankChannelConf[15]);
+#endif
+
+
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __enable_irq();
+#endif
+
+ /* Wait a while for a good discharging of all capacitors */
+ SoftDelay(50); // ~14µs with fHCLK = 32MHz
+ //this time depends of the size of the sampling capacitor
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __disable_irq();
+#endif
+ /* All IO in input floating */
+#if (TSLPRM_USE_GPIOA)
+ GPIOA->MODER &= (uint32_t)(~(TSL_BankSampleConf[2] | TSL_BankChannelConf[2]));
+#endif
+#if (TSLPRM_USE_GPIOB)
+ GPIOB->MODER &= (uint32_t)(~(TSL_BankSampleConf[5] | TSL_BankChannelConf[5]));
+#endif
+#if (TSLPRM_USE_GPIOC)
+ GPIOC->MODER &= (uint32_t)(~(TSL_BankSampleConf[8] | TSL_BankChannelConf[8]));
+#endif
+#if (TSLPRM_USE_GPIOF)
+ GPIOF->MODER &= (uint32_t)(~(TSL_BankSampleConf[11] | TSL_BankChannelConf[11]));
+#endif
+#if (TSLPRM_USE_GPIOG)
+ GPIOG->MODER &= (uint32_t)(~(TSL_BankSampleConf[14] | TSL_BankChannelConf[14]));
+#endif
+
+ /* set the IO to Vdd (io in push-pull HIGH when in output mode) */
+#if (TSLPRM_USE_GPIOA)
+ GPIOA->ODR |= (TSL_BankSampleConf[4] | TSL_BankChannelConf[4]); /* HIGH level */
+#endif
+#if (TSLPRM_USE_GPIOB)
+ GPIOB->ODR |= (TSL_BankSampleConf[7] | TSL_BankChannelConf[7]); /* HIGH level */
+#endif
+#if (TSLPRM_USE_GPIOC)
+ GPIOC->ODR |= (TSL_BankSampleConf[10] | TSL_BankChannelConf[10]); /* HIGH level */
+#endif
+#if (TSLPRM_USE_GPIOF)
+ GPIOF->ODR |= (TSL_BankSampleConf[13] | TSL_BankChannelConf[13]); /* HIGH level */
+#endif
+#if (TSLPRM_USE_GPIOG)
+ GPIOG->ODR |= (TSL_BankSampleConf[16] | TSL_BankChannelConf[16]); /* HIGH level */
+#endif
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __enable_irq();
+#endif
+
+ /* Close the sampling capacitor analog switch */
+ RI->ASCR1 |= (TSL_BankSampleConf[0]);
+ RI->ASCR2 |= (TSL_BankSampleConf[1]);
+
+
+ /* Loop while all the 1st channel of each group have not reach the VIH level */
+ do
+ {
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __disable_irq();
+#endif
+ /* Charging Ctouch by connecting the IO to Vdd (io in push-pull HIGH) */
+#if (TSLPRM_USE_GPIOA)
+ GPIOA->MODER |= (TSL_BankChannelConf[3]); /* Output push pull config */
+#endif
+#if (TSLPRM_USE_GPIOB)
+ GPIOB->MODER |= (TSL_BankChannelConf[6]); /* Output push pull config */
+#endif
+#if (TSLPRM_USE_GPIOC)
+ GPIOC->MODER |= (TSL_BankChannelConf[9]); /* Output push pull config */
+#endif
+#if (TSLPRM_USE_GPIOF)
+ GPIOF->MODER |= (TSL_BankChannelConf[12]); /* Output push pull config */
+#endif
+#if (TSLPRM_USE_GPIOG)
+ GPIOG->MODER |= (TSL_BankChannelConf[15]); /* Output push pull config */
+#endif
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __enable_irq();
+#endif
+
+ /* Wait a while for a good charging (programmable delay) */
+#if ( TSLPRM_DELAY_TRANSFER > 0 )
+ SoftDelay(TSLPRM_DELAY_TRANSFER);
+#endif
+
+ /* Spread Spectrum */
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+ SwSpreadSpectrum();
+#endif
+
+ /* test GPIOx->IDR bit + group configuration for each channel */
+
+#if (TSLPRM_USE_GPIOA)
+ TSL_GPIOA_IDR = GPIOA->IDR;
+ if ((TSL_GPIOA_IDR & GPIOA_IDR_Mask) != 0)
+ {
+ Check_Input = 1;
+ GPIOA_IDR_Mask &= (uint32_t)(~TSL_GPIOA_IDR);
+ }
+#endif
+
+#if (TSLPRM_USE_GPIOB)
+ TSL_GPIOB_IDR = GPIOB->IDR;
+ if ((TSL_GPIOB_IDR & GPIOB_IDR_Mask) != 0)
+ {
+ Check_Input = (1 << 1);
+ GPIOB_IDR_Mask &= (uint32_t)(~TSL_GPIOB_IDR);
+ }
+#endif
+
+#if (TSLPRM_USE_GPIOC)
+ TSL_GPIOC_IDR = GPIOC->IDR;
+ if ((TSL_GPIOC_IDR & GPIOC_IDR_Mask) != 0)
+ {
+ Check_Input = (1 << 2);
+ GPIOC_IDR_Mask &= (uint32_t)(~TSL_GPIOC_IDR);
+ }
+#endif
+
+#if (TSLPRM_USE_GPIOF)
+ TSL_GPIOF_IDR = GPIOF->IDR;
+ if ((TSL_GPIOF_IDR & GPIOF_IDR_Mask) != 0)
+ {
+ Check_Input = (1 << 5);
+ GPIOF_IDR_Mask &= (uint32_t)(~TSL_GPIOF_IDR);
+ }
+#endif
+
+#if (TSLPRM_USE_GPIOG)
+ TSL_GPIOG_IDR = GPIOG->IDR;
+ if ((TSL_GPIOG_IDR & GPIOG_IDR_Mask) != 0)
+ {
+ Check_Input = (1 << 6);
+ GPIOG_IDR_Mask &= (uint32_t)(~TSL_GPIOG_IDR);
+ }
+#endif
+
+
+ if (Check_Input)
+ {
+ p_chSrc = bank->p_chSrc;
+ for (idx_ch = 0; idx_ch < NumberOfChannels; idx_ch++)
+ {
+ GroupToCheckMask = (1 << (p_chSrc->IdxSrc));
+ if ((GroupToCheck & GroupToCheckMask) == (GroupToCheckMask))
+ {
+ GPIO_IDR_Mask = (1 << TSL_CHANNEL_IO(p_chSrc->t_sample));
+
+ switch (TSL_CHANNEL_PORT(p_chSrc->t_sample))
+ {
+#if (TSLPRM_USE_GPIOA)
+ case 0: GPIO_IDR = TSL_GPIOA_IDR; break;
+#endif
+#if (TSLPRM_USE_GPIOB)
+ case 1: GPIO_IDR = TSL_GPIOB_IDR; break;
+#endif
+#if (TSLPRM_USE_GPIOC)
+ case 2: GPIO_IDR = TSL_GPIOC_IDR; break;
+#endif
+#if (TSLPRM_USE_GPIOF)
+ case 5: GPIO_IDR = TSL_GPIOF_IDR; break;
+#endif
+#if (TSLPRM_USE_GPIOG)
+ case 6: GPIO_IDR = TSL_GPIOG_IDR; break;
+#endif
+ default: break;
+ }
+
+ if ((GPIO_IDR & GPIO_IDR_Mask) == GPIO_IDR_Mask)
+ {
+ tab_MeasurementCounter[p_chSrc->IdxSrc] = MeasurementCounter;
+ GroupToCheck &= (uint32_t)(~(1 << (p_chSrc->IdxSrc)));
+ Check_Input &= (uint32_t)(~(1 << TSL_CHANNEL_PORT(p_chSrc->t_sample)));
+ }
+ }
+ p_chSrc++;
+ }
+ }
+
+ MeasurementCounter++;
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __disable_irq();
+#endif
+ /* Configure All channels in input floating */
+#if (TSLPRM_USE_GPIOA)
+ GPIOA->MODER &= (uint32_t)(~(TSL_BankChannelConf[2]));
+#endif
+#if (TSLPRM_USE_GPIOB)
+ GPIOB->MODER &= (uint32_t)(~(TSL_BankChannelConf[5]));
+#endif
+#if (TSLPRM_USE_GPIOC)
+ GPIOC->MODER &= (uint32_t)(~(TSL_BankChannelConf[8]));
+#endif
+#if (TSLPRM_USE_GPIOF)
+ GPIOF->MODER &= (uint32_t)(~(TSL_BankChannelConf[11]));
+#endif
+#if (TSLPRM_USE_GPIOG)
+ GPIOG->MODER &= (uint32_t)(~(TSL_BankChannelConf[14]));
+#endif
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __enable_irq();
+#endif
+
+ /* Charging the Csense cap with connecting it to Ctouch by closing the analog switch */
+ RI->ASCR1 |= (TSL_BankChannelConf[0]);
+ RI->ASCR2 |= (TSL_BankChannelConf[1]);
+
+ /* Wait a while for a good charge transfering (programmable delay) */
+#if ( TSLPRM_DELAY_TRANSFER > 0 )
+ SoftDelay(TSLPRM_DELAY_TRANSFER);
+#endif
+
+ RI->ASCR1 &= (uint32_t)(~(TSL_BankChannelConf[0]));
+ RI->ASCR2 &= (uint32_t)(~(TSL_BankChannelConf[1]));
+
+ /*it's better to implement this like that because it's much more faster than to put this test in the "while test" below */
+ if (MeasurementCounter > TSL_Params.AcqMax)
+ {
+ TSL_acq_GroupDone(GroupToCheck);
+ __NOP();
+ break;
+ }
+
+ }
+ while (GroupToCheck != 0);
+
+
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __disable_irq();
+#endif
+ //====================
+ // All GPIOs in PP Low
+ //====================
+ for (BankIndex = 0; BankIndex < NumberOfBanks; BankIndex++)
+ {
+ LocalBank = &(TSL_Globals.Bank_Array[BankIndex]);
+ p_chSrc = LocalBank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ TSL_GPIO_BR_Config(LocalBank->shield_sample);
+ TSL_GPIO_BR_Config(LocalBank->shield_channel);
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_sample);
+ TSL_GPIO_MODER_OUT_Config(LocalBank->shield_channel);
+#endif
+
+ LocalNumberOfChannels = LocalBank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < LocalNumberOfChannels;
+ idx_ch++)
+ {
+ TSL_GPIO_BR_Config(p_chSrc->t_sample);
+ TSL_GPIO_BR_Config(p_chSrc->t_channel);
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_sample);
+ TSL_GPIO_MODER_OUT_Config(p_chSrc->t_channel);
+
+ p_chSrc++;
+ }
+ }
+#if (TSLPRM_PROTECT_IO_ACCESS > 0)
+ __enable_irq();
+#endif
+
+
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ TSL_Status_enum_T retval = TSL_STATUS_BUSY;
+ retval = TSL_STATUS_OK;
+ return retval;
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index)
+{
+ return(tab_MeasurementCounter[index]);
+}
+
+
+/**
+ * @brief Check noise (not used)
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ return TSL_ACQ_STATUS_OK;
+}
+
+
+/**
+ * @brief Process the TS Interrupt routine
+ * @param None
+ * @retval None
+ */
+void TSL_acq_ProcessIT(void)
+{
+}
+
+/**
+ * @brief Check if a filter must be used on the current channel (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if a filter can be applied
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ return TSL_TRUE;
+}
+
+
+/**
+ * @brief Compute the Delta value
+ * @param[in] ref Reference value
+ * @param[in] meas Last Measurement value
+ * @retval Delta value
+ */
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas)
+{
+ return((TSL_tDelta_T)(ref - meas));
+}
+
+
+/**
+ * @brief Compute the Measurement value
+ * @param[in] ref Reference value
+ * @param[in] delta Delta value
+ * @retval Measurement value
+ */
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta)
+{
+ return((TSL_tMeas_T)(ref - delta));
+}
+
+
+/**
+ * @brief Test if the Reference is incorrect (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if the Reference is out of range
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ return TSL_FALSE;
+}
+
+
+/**
+ * @brief Test if the measure has crossed the reference target (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result TRUE if the Reference is valid
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ return TSL_TRUE;
+}
+
+
+#if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM
+#pragma optimize=medium
+#elif defined(__CC_ARM) // Keil/MDK-ARM
+#pragma O1
+#pragma Ospace
+#elif defined(__TASKING__) // Altium/Tasking
+#pragma optimize O0
+#elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * With fHCLK = 32MHz: 1 = ~1µs, 50 = ~14µs, 100 = ~25µs, 200 = ~50µs
+ * @retval None
+ */
+void SoftDelay(uint16_t val)
+{
+ __IO uint16_t idx;
+ for (idx = val; idx > 0; idx--)
+ {}
+}
+#if defined(__TASKING__)
+#pragma endoptimize
+#endif
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+#if defined(__IAR_SYSTEMS_ICC__) // IAR/EWARM
+#pragma optimize=medium
+#elif defined(__CC_ARM) // Keil/MDK-ARM
+#pragma O1
+#pragma Ospace
+#elif defined(__TASKING__) // Altium/Tasking
+#pragma optimize O0
+#elif defined(__GNUC__) // Atollic/True Studio + Raisonance/RKit
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+#endif
+/**
+ * @brief Spread Spectrum using a variable software delay.
+ * @param None
+ * @retval None
+ */
+__INLINE void SwSpreadSpectrum(void)
+{
+ uint8_t idx;
+
+ SpreadCounter++;
+
+ if (SpreadCounter == TSLPRM_SPREAD_MAX)
+ {
+ SpreadCounter = TSLPRM_SPREAD_MIN;
+ }
+
+ idx = SpreadCounter;
+
+ while (--idx) {}
+}
+#if defined(__TASKING__)
+#pragma endoptimize
+#endif
+#endif
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_hw.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_hw.c
new file mode 100644
index 0000000..007efa2
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_hw.c
@@ -0,0 +1,888 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm8l_hw.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the acquisition
+ * on STM8L products using the hardware acquisition mode (with Timers).
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm8l_hw.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+
+/** Structure containing RI IO informations according to GPIO.
+ */
+typedef struct
+{
+ unsigned int IO_Channel : 4; /**< Channel number from 1 to 4 in the Routing interface group */
+ unsigned int IO_Group : 4; /**< Group number in the Routing interface */
+} TSL_IOConf_T;
+
+/* Private defines -----------------------------------------------------------*/
+
+#define MAX_CHANNEL_NUMBER_BY_GROUP (4)
+
+/* Private macros ------------------------------------------------------------*/
+
+#define GPIO_PORT(GPIO) (GPIO >> 3) /**< Get the GPIO port*/
+#define GPIO_BIT(GPIO) (GPIO & 0x07) /**< Get the GPIO pin number*/
+
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS))) /**< Check if the index have a good range*/
+
+#define GPIO_ODR_HIGH(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->ODR |= (uint8_t)(1 << GPIO_BIT(GPIO)))
+#define GPIO_ODR_LOW(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->ODR &= (uint8_t)(~(1 << GPIO_BIT(GPIO))))
+#define GPIO_DDR_IN(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->DDR &= (uint8_t)(~(1 << GPIO_BIT(GPIO))))
+#define GPIO_DDR_OUT(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->DDR |= (uint8_t)(1 << GPIO_BIT(GPIO)))
+#define GPIO_CR1_PP(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->CR1 |= (uint8_t)(1 << GPIO_BIT(GPIO)))
+#define GPIO_CR1_FLOATING(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->CR1 &= (uint8_t)(~(1 << GPIO_BIT(GPIO))))
+
+#define DISABLE_MASK(GPIO) (DisableMask[(GPIO_to_SW_Conf[GPIO].IO_Channel)-1] |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group)) /**< Create disable mask array to modify initial bank mask before acquisition (only for STATUS_OFF)*/
+#define DISABLE_SAMPLING(GPIO) (DisableSampling |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group)) /**< Create disable sampling mask to don't take sampling measurement of corresponding channels(for STATUS_BURST_ONLY and shield) */
+
+/* Private variables ---------------------------------------------------------*/
+
+__IO uint8_t *p_IOIRx; // Pointer to the IOIRx register (x from 1 to 4)
+__IO uint8_t *p_IOMRx; // Pointer to the IOMRx register (x from 1 to 4)
+uint8_t OldStatus; // Mask used to memorize the IOIRx bits processed during the acquisition
+uint8_t BankDone; // Control if all activate sampling reach the VIH level
+uint8_t CurrentSampling; // Mask to control IOGCR register
+uint8_t CurrentChannel; // Mask to control IOGCR register
+uint8_t ChannelSampling; // Contain the channel number where all sampling are connected
+uint8_t DisableSampling; // Disable sampling mask when the Burst Only mode is activated for one channel of the current bank(not get the measure)
+
+TSL_Bank_Config_Mask_T BankMask[TSLPRM_TOTAL_BANKS]; // Complete masks (channel and sampling) to configure IOCMRx and IOSRx registers for all banks
+uint8_t SamplingMask[TSLPRM_TOTAL_BANKS]; // Sampling mask to configure IOGCR register for all banks
+uint8_t ChannelMask[TSLPRM_TOTAL_BANKS]; // Channel mask to configure IOGCR register for all banks
+uint8_t DisableMask[MAX_CHANNEL_NUMBER_BY_GROUP]; // Complete disable mask(channel and sampling) when the Channel OFF mode is activated for one channel of the current bank(to modifie the Current_Bank)
+uint8_t CurrentBank[MAX_CHANNEL_NUMBER_BY_GROUP]; // Complete mask for the current bank
+uint16_t tab_MeasurementCounter[8] = {0}; // Measurement of each sampling of the current bank
+
+TSL_Status_enum_T TSL_Acq_Status = TSL_STATUS_BUSY;
+
+GPIO_TypeDef *p_GPIOx[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF};
+
+__IO uint8_t *RI_IOIRx_Register[MAX_CHANNEL_NUMBER_BY_GROUP] = {&(RI->IOIR1), &(RI->IOIR2), &(RI->IOIR3), &(RI->IOIR4)};
+__IO uint8_t *RI_IOMRx_Register[MAX_CHANNEL_NUMBER_BY_GROUP] = {&(RI->IOMR1), &(RI->IOMR2), &(RI->IOMR3), &(RI->IOMR4)};
+
+
+/* Table which do the link between GPIO and switch configuation:{x,y}
+ x = channel number
+ y = group number - 1
+ Note: {0,0} = not connect to IO switch
+*/
+CONST TSL_IOConf_T GPIO_to_SW_Conf[40] =
+{
+ // Port A definitions
+ {0, 0}, // PA0
+ {0, 0}, // PA1
+ {0, 0}, // PA2
+ {0, 0}, // PA3
+ {3, 0}, // PA4 is channel 3 of Group 1
+ {2, 0}, // PA5 is channel 2 of Group 1
+ {1, 0}, // PA6 is channel 1 of Group 1
+ {4, 0}, // PA7 is channel 4 of Group 1
+ // Port B definitions
+ {1, 6}, // PB0
+ {3, 5},
+ {2, 5},
+ {1, 5},
+ {3, 4},
+ {2, 4},
+ {1, 4},
+ {3, 3}, // PB7
+ // Port C definitions
+ {0, 0}, // PC0
+ {0, 0},
+ {1, 2},
+ {3, 1},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}, // PC7
+ // Port D definitions
+ {2, 7}, // PD0
+ {1, 7},
+ {3, 6},
+ {2, 6},
+ {2, 3},
+ {1, 3},
+ {3, 2},
+ {2, 2}, // PD7
+ // Port E definitions
+ {0, 0}, // PE0
+ {0, 0},
+ {0, 0},
+ {4, 6},
+ {4, 7},
+ {3, 7},
+ {0, 0},
+ {4, 1} // PE7
+};
+
+/* Private functions prototype -----------------------------------------------*/
+void SoftDelay(uint16_t val);
+void CreateMask(uint16_t idx_bk, uint8_t GPIO);
+void TSL_Init_GPIOs(void);
+void TSL_Init_TIMs(void);
+TSL_Status_enum_T TSL_Init_RI(void);
+
+
+/**
+ * @brief Initializes the touch sensing GPIOs.
+ * @param None
+ * @retval None
+ */
+void TSL_Init_GPIOs(void)
+{
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]); // Pointer to the first bank
+ CONST TSL_ChannelSrc_T *p_chSrc = p_bank->p_chSrc; // Pointer to the source channel of the current bank
+ uint16_t number_of_channels = 0;
+ uint16_t idx_bk;
+ uint16_t idx_ch;
+
+ // Initializes each bank and configures the used GPIO
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+ number_of_channels = p_bank->NbChannels;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // GPIO in Output
+ GPIO_DDR_OUT(p_bank->shield_sampling);
+ GPIO_DDR_OUT(p_bank->shield_channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_bank->shield_sampling);
+ GPIO_CR1_PP(p_bank->shield_channel);
+ // Output in Low level
+ GPIO_ODR_LOW(p_bank->shield_sampling);
+ GPIO_ODR_LOW(p_bank->shield_channel);
+#endif
+
+ // Initialize the mask for channel and sampling
+ for (idx_ch = 0; idx_ch < number_of_channels; idx_ch++)
+ {
+ // GPIO are configured in PP Low mode when inactive
+ // GPIO in Output
+ GPIO_DDR_OUT(p_chSrc->sampling);
+ GPIO_DDR_OUT(p_chSrc->channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_chSrc->sampling);
+ GPIO_CR1_PP(p_chSrc->channel);
+ // Output in Low level
+ GPIO_ODR_LOW(p_chSrc->sampling);
+ GPIO_ODR_LOW(p_chSrc->channel);
+ // Next channel
+ p_chSrc++;
+ }
+ }
+}
+
+
+/**
+ * @brief Initializes the timers used for touch sensing hardware acquisition.
+ * @param None
+ * @retval None
+ */
+void TSL_Init_TIMs(void)
+{
+ CLK->PCKENR1 |= 0x03; // Enable TIM2 and TIM3 clocks
+
+ //==============================
+ // TIMER 2 configuration: Master
+ //==============================
+ // Channel 1 as output, set PWM mode 1
+ TIM2->CCMR1 = 0x60;
+ TIM2->CCMR2 = 0x60;
+ // Main Output Enable
+ TIM2->BKR |= 0x80; // MOE=1
+ // Center-Aligned mode 3
+ TIM2->CR1 |= 0x60; // CMS=11
+ // OC2 polarity = active low
+ TIM2->CCER1 |= 0x20; // CC2P=1
+ // Enable OC2
+ TIM2->CCER1 |= 0x10; // CC2E=1
+ // Set the Prescaler value
+ TIM2->PSCR = 0; // fCK_CNT = 16MHz/(0+1) = 16MHz --> T=62.5ns
+ // Set the Autoreload value (signal frequency)
+ TIM2->ARRH = (uint8_t)(TIM_RELOAD >> 8);
+ TIM2->ARRL = (uint8_t)(TIM_RELOAD);
+ // Set PWM1 duty cycle
+ TIM2->CCR1H = (uint8_t)(TIM2_PWM_CH1_WIDTH >> 8);
+ TIM2->CCR1L = (uint8_t)(TIM2_PWM_CH1_WIDTH);
+ // Set PWM2 duty cycle
+ TIM2->CCR2H = (uint8_t)(TIM2_PWM_CH2_WIDTH >> 8);
+ TIM2->CCR2L = (uint8_t)(TIM2_PWM_CH2_WIDTH);
+ // Select Master mode, Internal Trigger selection, Gated mode
+ TIM2->SMCR = 0x35; // TS=011=ITR3(TIM2), SMS=101=Gated mode enabled
+ // Map OC1REF to TRGO
+ TIM2->CR2 = 0x40; // MMS=100
+ // Enable OC1
+ TIM2->CCER1 |= 0x01; // CC1E=1
+ // Set Update generation
+ TIM2->EGR |= 0x01; // UG=1
+ // Set Break interrupt flag
+ TIM2->SR1 |= 0x80;
+
+ //==============================
+ // TIMER 3 configuration: slave
+ //==============================
+ // Enable External Clock mode 2, external trigger filter, trigger on high level or rising edge
+ TIM3->ETR = 0x42; // ETP=0, ECE=1, ETF=0010
+ // Capture/Compare 1 configured as Input: h/w detection mapped on TI2FP1
+ TIM3->CCMR1 = 0x02; // CC1S=10
+ // Capture/Compare 2 configured as Output: MaxCount
+ TIM3->CCMR2 = 0; // CC2S=00
+ // Enable CC1 channel as Input for Capture function
+ TIM3->CCER1 = 0x01; // CC1E=1
+ // Enable counter (slave must be enabled first)
+ TIM3->CR1 |= 0x01; // CEN=1
+}
+
+
+/**
+ * @brief Init routing interface.
+ * @param None
+ * @retval None
+ */
+TSL_Status_enum_T TSL_Init_RI(void)
+{
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]); // Pointer to the first bank
+ CONST TSL_ChannelSrc_T *p_chSrc = p_bank->p_chSrc; // Pointer to the source channel of the current bank
+ uint16_t number_of_channels = 0;
+ uint16_t idx_bk;
+ uint16_t idx_ch;
+
+ // Enable comparator clock to activate the RI block
+ CLK->PCKENR2 |= CLK_PCKENR2_COMP;
+
+ // Enable H/W acquisition sequence
+ RI->CR |= 0x04; // AM=1
+
+ // Enable Channel Acquisition interrupt
+ RI->CR |= 0x01; // TIE=1
+
+ // Suspend Timer2 on h/w detection
+ RI->CR |= 0x08; // THALT=1
+
+ // Enable schmitt trigger required for H/W acq mode.
+ COMP->CSR1 |= 0x04; // STE=1
+
+ // Initializes each bank and configures the used GPIO
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+ number_of_channels = p_bank->NbChannels;
+
+ // Masks initialisation
+ BankMask[idx_bk].ch1 = 0;
+ BankMask[idx_bk].ch2 = 0;
+ BankMask[idx_bk].ch3 = 0;
+ BankMask[idx_bk].ch4 = 0;
+
+ // Get which channel is used for sampling only one time because it's the same for each couple
+ SamplingMask[idx_bk] = (uint8_t)GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Create Mask per bank
+ CreateMask(idx_bk,p_bank->shield_sampling);
+ CreateMask(idx_bk,p_bank->shield_channel);
+ ChannelMask[idx_bk] |= (uint8_t)(3 << (2 * ((GPIO_to_SW_Conf[p_bank->shield_channel].IO_Channel) - 1)));
+ if ((SamplingMask[idx_bk] != (uint8_t)GPIO_to_SW_Conf[p_bank->shield_sampling].IO_Channel))
+ {
+ return TSL_STATUS_ERROR;
+ }
+#endif
+
+ // Initializes the mask for channel and sampling
+ for (idx_ch = 0; idx_ch < number_of_channels; idx_ch++)
+ {
+ // Create Mask per bank
+ CreateMask(idx_bk,p_chSrc->channel);
+ CreateMask(idx_bk,p_chSrc->sampling);
+ ChannelMask[idx_bk] |= (uint8_t)(3 << (2 * ((GPIO_to_SW_Conf[p_chSrc->channel].IO_Channel) - 1)));
+ if ((SamplingMask[idx_bk] != (uint8_t)GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel))
+ {
+ return TSL_STATUS_ERROR;
+ }
+ // Next channel
+ p_chSrc++;
+ }
+
+ // Unlock IO to RI register : IO controlled by GPIO
+ RI->IOCMR1 &= (uint8_t)(~BankMask[idx_bk].ch1);
+ RI->IOCMR2 &= (uint8_t)(~BankMask[idx_bk].ch2);
+ RI->IOCMR3 &= (uint8_t)(~BankMask[idx_bk].ch3);
+ RI->IOCMR4 &= (uint8_t)(~BankMask[idx_bk].ch4);
+ }
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Create Mask for all banks
+ * @param[in] idx_bk Index of the Bank to configure
+ * @param[in] GPIO Pin number
+ * @retval None
+ */
+void CreateMask(uint16_t idx_bk, uint8_t GPIO)
+{
+ switch(GPIO_to_SW_Conf[GPIO].IO_Channel)
+ {
+ case 1:
+ BankMask[idx_bk].ch1 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask for all first channel
+ break;
+ case 2:
+ BankMask[idx_bk].ch2 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask for all second channel
+ break;
+ case 3:
+ BankMask[idx_bk].ch3 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask fo all third channel
+ break;
+ case 4:
+ BankMask[idx_bk].ch4 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask for all fourth channel
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**
+ * @brief Initializes the acquisition module.
+ * @param None
+ * @retval retval
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+ TSL_Init_GPIOs();
+ TSL_Init_TIMs();
+ TSL_Init_RI();
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Configures a Bank.
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ uint8_t idx;
+ uint16_t idx_dest;
+ uint16_t idx_ch;
+ uint16_t number_of_channels = 0;
+ CONST TSL_Bank_T *p_bank; // Pointer to the current bank
+ CONST TSL_ChannelDest_T *p_chDest; // Pointer to the first destination channel of the current bank
+ CONST TSL_ChannelSrc_T *p_chSrc; // Pointer to the fisrt source channel of the current bank
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ OldStatus = 0;
+
+ TSL_Globals.This_Bank = idx_bk;
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ number_of_channels = p_bank->NbChannels;
+ p_chDest = p_bank->p_chDest;
+ p_chSrc = p_bank->p_chSrc;
+
+ // Reset the disable mask
+ DisableSampling = 0;
+ for (idx = 0; idx < MAX_CHANNEL_NUMBER_BY_GROUP; idx++)
+ {
+ DisableMask[idx] = 0;
+ }
+
+#if (TSLPRM_USE_SHIELD > 0)
+ DISABLE_SAMPLING(p_bank->shield_sampling);
+#endif
+
+ // Loop for each channel of this bank
+ for (idx_ch = 0; idx_ch < number_of_channels; idx_ch++)
+ {
+
+ idx_dest = p_chDest->IdxDest;
+
+ // Mode Status OFF
+ if (p_bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_OFF)
+ {
+ // Update Mask if channels are disabled
+ DISABLE_MASK(p_chSrc->channel);
+ DISABLE_MASK(p_chSrc->sampling);
+ }
+
+ // Mode Status BURST ONLY
+ if (p_bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_BURST_ONLY)
+ {
+ DISABLE_SAMPLING(p_chSrc->sampling);
+ }
+
+ tab_MeasurementCounter[GPIO_to_SW_Conf[p_chSrc->sampling].IO_Group] = 0;
+
+ // Next channel
+ p_chSrc++;
+ p_chDest++;
+ }
+
+ // Get Mask for the current bank
+ CurrentBank[0] = (uint8_t)(BankMask[idx_bk].ch1 & (~DisableMask[0])); // Mask for all 1st channel are used by channels and sampling for this bank
+ CurrentBank[1] = (uint8_t)(BankMask[idx_bk].ch2 & (~DisableMask[1])); // Mask for all 2nd channel are used by channels and sampling for this bank
+ CurrentBank[2] = (uint8_t)(BankMask[idx_bk].ch3 & (~DisableMask[2])); // Mask for all 3rd channel are used by channels and sampling for this bank
+ CurrentBank[3] = (uint8_t)(BankMask[idx_bk].ch4 & (~DisableMask[3])); // Mask for all 4th channel are used by channels and sampling for this bank
+
+ CurrentChannel = ChannelMask[idx_bk]; // Mask for channels
+ CurrentSampling = (uint8_t)(3 << (2 * (SamplingMask[idx_bk] - 1))); // Mask for sampling
+ ChannelSampling = SamplingMask[idx_bk]; // Mask for the channel used by sampling
+
+ // Channel's state of the current bank
+ BankDone = (uint8_t)(CurrentBank[ChannelSampling - 1] & (~DisableSampling));
+
+ // Select the IO Input register corresponding to the channel sampling (to optimize the measurement)
+ p_IOIRx = RI_IOIRx_Register[ChannelSampling - 1];
+
+ // Select the IO Mask register corresponding to the channel sampling (to optimize the measurement)
+ p_IOMRx = RI_IOMRx_Register[ChannelSampling - 1];
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Start acquisition on a previously configured bank
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+#if (TSLPRM_IODEF > 0)
+
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]);
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ TSL_tNb_T number_of_channels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+
+ //============================
+ // All GPIOs in Input floating
+ //============================
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // GPIO in Input
+ GPIO_DDR_IN(p_bank->shield_sampling);
+ GPIO_DDR_IN(p_bank->shield_channel);
+ // GPIO in floating mode
+ GPIO_CR1_FLOATING(p_bank->shield_sampling);
+ GPIO_CR1_FLOATING(p_bank->shield_channel);
+#endif // TSLPRM_USE_SHIELD
+
+ number_of_channels = p_bank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < number_of_channels;
+ idx_ch++)
+ {
+ // GPIO in Input
+ GPIO_DDR_IN(p_chSrc->sampling);
+ GPIO_DDR_IN(p_chSrc->channel);
+ // GPIO in floating mode
+ GPIO_CR1_FLOATING(p_chSrc->sampling);
+ GPIO_CR1_FLOATING(p_chSrc->channel);
+ p_chSrc++;
+ }
+ }
+#endif // TSLPRM_IODEF
+
+ // Test if this bank is not empty
+ if (BankDone != 0)
+ {
+
+ // Set the AL bit to exit from WFI mode only on PXS interrupt
+ CFG->GCR |= (uint8_t)CFG_GCR_AL;
+
+ //--------------------------------------------
+ // Configure Timer3 for the MaxCount detection
+ //--------------------------------------------
+
+ // Clear the Slave timer counter
+ TIM3->CNTRH = 0;
+ TIM3->CNTRL = 0;
+
+ // Timer3 interruption routine to detect MaxCount
+ // Warning: the high byte must be written before the low byte
+ TIM3->CCR2H = (uint8_t)((TSL_Params.AcqMax+1) >> 8);
+ TIM3->CCR2L = (uint8_t)(TSL_Params.AcqMax+1);
+
+ // Clear all Timer3 flags...
+ TIM3->SR1 = 0;
+ TIM3->SR2 = 0;
+
+ // Enable Capture/Compare 2 interrupt: MaxCount
+ TIM3->IER |= 0x04; // CC2IE=1
+
+ //--------------------------------------------
+
+ // Enable necessary IOs
+ RI->IOCMR1 |= (uint8_t)CurrentBank[0];
+ RI->IOCMR2 |= (uint8_t)CurrentBank[1];
+ RI->IOCMR3 |= (uint8_t)CurrentBank[2];
+ RI->IOCMR4 |= (uint8_t)CurrentBank[3];
+
+ // Discharge all capacitors
+ RI->IOSR1 &= (uint8_t)(~CurrentBank[0]);
+ RI->IOSR2 &= (uint8_t)(~CurrentBank[1]);
+ RI->IOSR3 &= (uint8_t)(~CurrentBank[2]);
+ RI->IOSR4 &= (uint8_t)(~CurrentBank[3]);
+
+ // Wait a complete discharge
+ SoftDelay(TSLPRM_DELAY_DISCHARGE_ALL);
+
+ // Configure channel capacitors and sampling capacitors
+ RI->IOGCR = (uint8_t)(0x55 & (~CurrentSampling));
+
+ RI->IOSR1 |= (uint8_t)CurrentBank[0];
+ RI->IOSR2 |= (uint8_t)CurrentBank[1];
+ RI->IOSR3 |= (uint8_t)CurrentBank[2];
+ RI->IOSR4 |= (uint8_t)CurrentBank[3];
+
+ // Start acquisition
+ TSL_Acq_Status = TSL_STATUS_BUSY;
+
+ // Start the Master timer counter
+ TIM2->CR1 |= 0x01; // CEN=1
+ }
+ else
+ {
+ TSL_Acq_Status = TSL_STATUS_OK;
+ }
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ return TSL_Acq_Status;
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index)
+{
+ return(tab_MeasurementCounter[index]);
+}
+
+
+/**
+ * @brief Check noise (not used)
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ return TSL_ACQ_STATUS_OK;
+}
+
+
+/**
+ * @brief Used during HW acquisition mode.
+ * @param None
+ * @retval None
+ * @note Must be called by the TIM3 Capture/Compare interrupt routine.
+ */
+void TSL_CT_HWacq_TIM3(void)
+{
+ uint8_t new_status;
+ uint8_t idx = 0;
+ uint16_t timer_count;
+
+ TIM2->CR1 &= (uint8_t)(~0x01); // Stop master counter
+
+ RI->IOMR1 = 0;
+ RI->IOMR2 = 0;
+ RI->IOMR3 = 0;
+ RI->IOMR4 = 0;
+
+ // Discharge all capacitors (electrode and sampling capacitor IOs)
+ RI->IOSR1 &= (uint8_t)(~(CurrentBank[0]));
+ RI->IOSR2 &= (uint8_t)(~(CurrentBank[1]));
+ RI->IOSR3 &= (uint8_t)(~(CurrentBank[2]));
+ RI->IOSR4 &= (uint8_t)(~(CurrentBank[3]));
+
+ TSL_Acq_Status = TSL_STATUS_OK;
+
+ // Clear all Timer3 flags...
+ TIM3->SR1 = 0;
+ TIM3->SR2 = 0;
+
+ // Read capture counter
+ timer_count = (uint16_t)(TIM3->CCR1H << 8);
+ timer_count += TIM3->CCR1L;
+
+ new_status = (uint8_t)(BankDone & (~(OldStatus)));
+
+ while ((new_status != 0) && (idx < 8))
+ {
+ if ((new_status & (1 << idx)) != 0)
+ {
+ tab_MeasurementCounter[idx] = timer_count;
+ new_status &= (uint8_t)(~(1 << idx));
+ OldStatus |= (uint8_t)(1 << idx);
+ *p_IOMRx |= (uint8_t)(1 << idx); // Mask IO which reach VIH
+ }
+ idx++;
+ }
+}
+
+
+/**
+ * @brief Used during HW acquisition mode.
+ * @param None
+ * @retval None
+ * @note Must be called by the RI interrupt routine.
+ * Timer 2 and 3 are halted during this interrupt but counter is not reset.
+ */
+void TSL_CT_HWacq_RI(void)
+{
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]);
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ TSL_tNb_T number_of_channels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+
+ __IO uint8_t IOIRx;
+ uint8_t new_status;
+ uint8_t idx = 0;
+ uint16_t timer_count;
+
+ IOIRx = *p_IOIRx;
+
+ // Test RI Input register corresponding to sampling capacitors
+ if ((IOIRx & BankDone) != OldStatus)
+ {
+ // Read capture counter
+ timer_count = (uint16_t)(TIM3->CCR1H << 8);
+ timer_count += TIM3->CCR1L;
+
+ new_status = (uint8_t)((BankDone & IOIRx) & (~(OldStatus)));
+
+ while ((new_status != 0) && (idx < 8))
+ {
+ if ((new_status & (1 << idx)) != 0)
+ {
+ tab_MeasurementCounter[idx] = timer_count;
+ new_status &= (uint8_t)(~(1 << idx));
+ OldStatus |= (uint8_t)(1 << idx);
+ *p_IOMRx |= (uint8_t)(1 << idx); // Mask IO which reach VIH
+ }
+ idx++;
+ }
+
+ // When Current bank is completed
+ if ((OldStatus == BankDone))
+ {
+
+ // Disable master counter
+ TIM2->CR1 &= (uint8_t)(~0x01); // Stop master counter
+
+ // Reset IO Mask
+ RI->IOMR1 = 0;
+ RI->IOMR2 = 0;
+ RI->IOMR3 = 0;
+ RI->IOMR4 = 0;
+
+ // Disable necessary IOs
+ RI->IOSR1 &= (uint8_t)(~(CurrentBank[0]));
+ RI->IOSR2 &= (uint8_t)(~(CurrentBank[1]));
+ RI->IOSR3 &= (uint8_t)(~(CurrentBank[2]));
+ RI->IOSR4 &= (uint8_t)(~(CurrentBank[3]));
+
+ RI->IOCMR1 &= (uint8_t)(~(CurrentBank[0]));
+ RI->IOCMR2 &= (uint8_t)(~(CurrentBank[1]));
+ RI->IOCMR3 &= (uint8_t)(~(CurrentBank[2]));
+ RI->IOCMR4 &= (uint8_t)(~(CurrentBank[3]));
+
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+ number_of_channels = p_bank->NbChannels;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // GPIO in Output
+ GPIO_DDR_OUT(p_bank->shield_sampling);
+ GPIO_DDR_OUT(p_bank->shield_channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_bank->shield_sampling);
+ GPIO_CR1_PP(p_bank->shield_channel);
+ // Output in Low level
+ GPIO_ODR_LOW(p_bank->shield_sampling);
+ GPIO_ODR_LOW(p_bank->shield_channel);
+#endif
+ // Initialize the mask for channel and sampling
+ for (idx_ch = 0; idx_ch < number_of_channels; idx_ch++)
+ {
+ // GPIO are configured in PP Low mode when inactive
+ // GPIO in Output
+ GPIO_DDR_OUT(p_chSrc->sampling);
+ GPIO_DDR_OUT(p_chSrc->channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_chSrc->sampling);
+ GPIO_CR1_PP(p_chSrc->channel);
+ // Output in Low level
+ GPIO_ODR_LOW(p_chSrc->sampling);
+ GPIO_ODR_LOW(p_chSrc->channel);
+ // Next channel
+ p_chSrc++;
+ }
+ }
+
+#if TSLPRM_USE_ZONE > 0
+
+ TSL_acq_BankGetResult(TSL_Globals.This_Bank, 0, 0); // Get Bank Result
+
+ if ((TSL_Globals.This_Zone == 0) || (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks))
+ {
+ CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing
+ TSL_Globals.This_Bank = 0;
+ }
+ else
+ {
+ if (TSL_acq_ZoneConfig(TSL_Globals.This_Zone, TSL_Globals.Index_In_This_Zone) != TSL_STATUS_ERROR)
+ {
+ // Start Bank acquisition
+ TSL_acq_BankStartAcq();
+ }
+ else
+ {
+ CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing
+ TSL_Globals.This_Bank = 0;
+ }
+ }
+#else
+ CFG->GCR &= (uint8_t)(~CFG_GCR_AL);
+#endif
+ }
+ }
+
+ // Reset Interrupt flag
+ RI->CR |= 0x02; // CAIF=1
+ TSL_Acq_Status = TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Check if a filter must be used on the current channel (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if a filter can be applied
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ return TSL_TRUE;
+}
+
+
+/**
+ * @brief Compute the Delta value
+ * @param[in] ref Reference value
+ * @param[in] meas Last Measurement value
+ * @retval Delta value
+ */
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas)
+{
+ return((TSL_tDelta_T)(ref - meas));
+}
+
+
+/**
+ * @brief Compute the Measurement value
+ * @param[in] ref Reference value
+ * @param[in] delta Delta value
+ * @retval Measurement value
+ */
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta)
+{
+ return((TSL_tMeas_T)(ref - delta));
+}
+
+
+/**
+ * @brief Test if the Reference is incorrect (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if the Reference is out of range
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ return TSL_FALSE;
+}
+
+
+/**
+ * @brief Test if the measure has crossed the reference target (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result TRUE if the Reference is valid
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ return TSL_TRUE;
+}
+
+
+#if defined(__ICCSTM8__)
+#pragma optimize=low
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * @retval None
+ */
+void SoftDelay(uint16_t val)
+{
+ uint16_t idx;
+ for (idx = val; idx > 0; idx--)
+ {
+ nop();
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_sw.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_sw.c
new file mode 100644
index 0000000..0334c22
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8l_sw.c
@@ -0,0 +1,1426 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm8l_sw.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the acquisition
+ * on STM8L products using the software acquisition mode.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm8l_sw.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+
+/** Structure containing RI IO informations according to GPIO.
+ */
+typedef struct
+{
+ unsigned int IO_Channel : 4; /**< Channel number from 1 to 4 in the Routing interface group */
+ unsigned int IO_Group : 4; /**< Group number in the Routing interface */
+} TSL_IOConf_T;
+
+/* Private defines -----------------------------------------------------------*/
+
+/** Define if maximum channel number is 3 or 4 according to the Device Density
+ */
+#if defined(STM8L15X_LD) || defined(STM8L10X)
+#define MAX_CHANNEL_NUMBER_BY_GROUP (4)
+#else
+#define MAX_CHANNEL_NUMBER_BY_GROUP (3)
+#endif // defined(STM8L15X_LD) || defined(STM8L10X)
+
+#if defined(_COSMIC_)
+#define INLINE @inline
+#elif defined(_RAISONANCE_)
+#define INLINE inline
+#elif defined(_IAR_)
+#define INLINE
+#else
+#error "Compiler not Supported"
+#endif
+
+/* Private macros ------------------------------------------------------------*/
+
+#if !defined(STM8L10X)
+#define GPIO_PORT(GPIO) (GPIO >> 3) /**< Get the GPIO port*/
+#define GPIO_BIT(GPIO) (GPIO & 0x07) /**< Get the GPIO pin number*/
+#else
+#define GPIO_PORT(GPIO) (GPIO >> 2) /**< Get the GPIO port*/
+#define GPIO_BIT(GPIO) (GPIO & 0x03) /**< Get the GPIO pin number*/
+#endif // !defined(STM8L10X)
+
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS))) /**< Check if the index have a good range*/
+
+#define GPIO_ODR_HIGH(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->ODR |= (uint8_t)(1 << GPIO_BIT(GPIO)))
+#define GPIO_ODR_LOW(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->ODR &= (uint8_t)(~(1 << GPIO_BIT(GPIO))))
+#define GPIO_DDR_IN(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->DDR &= (uint8_t)(~(1 << GPIO_BIT(GPIO))))
+#define GPIO_DDR_OUT(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->DDR |= (uint8_t)(1 << GPIO_BIT(GPIO)))
+#define GPIO_CR1_PP(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->CR1 |= (uint8_t)(1 << GPIO_BIT(GPIO)))
+#define GPIO_CR1_FLOATING(GPIO) (p_GPIOx[GPIO_PORT(GPIO)]->CR1 &= (uint8_t)(~(1 << GPIO_BIT(GPIO))))
+
+#define DISABLE_MASK(GPIO) (DisableMask[(GPIO_to_SW_Conf[GPIO].IO_Channel)-1] |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group)) /**< Create disable mask array to modify initial bank mask before acquisition (only for STATUS_OFF)*/
+#define DISABLE_SAMPLING(GPIO) (DisableSampling |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group)) /**< Create disable sampling mask to don't take sampling measurement of corresponding channels(for STATUS_BURST_ONLY and shield) */
+
+/* Private variables ---------------------------------------------------------*/
+
+uint8_t SpreadCounter = TSLPRM_SPREAD_MIN;
+
+uint16_t ChargeTransferCounter; // This variable count the charge transfer number in the acquisition loop
+uint8_t BankDone; // Control if all activate sampling reach the VIH level
+uint8_t CurrentSampling; // Mask to control IOGCR register
+uint8_t CurrentChannel; // Mask to control IOGCR register
+uint8_t ChannelSampling; // Contain the channel number where all sampling are connected
+uint8_t DisableSampling; // Disable sampling mask when the Burst Only mode is activated for one channel of the current bank(not get the measure)
+
+TSL_Bank_Config_Mask_T BankMask[TSLPRM_TOTAL_BANKS]; // Complete masks (channel and sampling) to configure IOCMRx and IOSRx registers for all banks
+uint8_t SamplingMask[TSLPRM_TOTAL_BANKS]; // Sampling mask to configure IOGCR register for all banks
+uint8_t DisableMask[MAX_CHANNEL_NUMBER_BY_GROUP]; // Complete disable mask(channel and sampling) when the Channel OFF mode is activated for one channel of the current bank(to modifie the CurrentBank)
+uint8_t CurrentBank[MAX_CHANNEL_NUMBER_BY_GROUP]; // Complete mask for the current bank
+
+#if !defined(STM8L10X)
+
+#if defined(STM8L15X_LD)
+__IO uint8_t *RI_IOIRx_Register[MAX_CHANNEL_NUMBER_BY_GROUP] = {&(RI->IOIR1), &(RI->IOIR2), &(RI->IOIR3), &(RI->IOIR4)};
+#else
+__IO uint8_t *RI_IOIRx_Register[MAX_CHANNEL_NUMBER_BY_GROUP] = {&(RI->IOIR1), &(RI->IOIR2), &(RI->IOIR3)};
+#endif // STM8L15X_LD
+
+__IO uint8_t *p_IOIRx; // Pointer to the IOIRx register (x from 1 to 4)
+GPIO_TypeDef *p_GPIOx[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF};
+
+uint16_t tab_MeasurementCounter[8] = {0}; // Measurement of each sampling of the current bank
+uint8_t ChannelMask[TSLPRM_TOTAL_BANKS]; // Channel mask to configure IOGCR register for all banks
+
+/* Table which do the link between GPIO and switch configuation:{x,y}
+ x = channel number
+ y = group number - 1
+ Note: {0,0} = not connect to IO switch
+*/
+CONST TSL_IOConf_T GPIO_to_SW_Conf[40] =
+{
+ // Port A definitions
+ {0, 0}, // PA0
+ {0, 0}, // PA1
+ {0, 0}, // PA2
+ {0, 0}, // PA3
+ {3, 0}, // PA4 is channel 3 of Group 1
+ {2, 0}, // PA5 is channel 2 of Group 1
+ {1, 0}, // PA6 is channel 1 of Group 1
+ {4, 0}, // PA7 is channel 4 of Group 1
+ // Port B definitions
+ {1, 6}, // PB0
+ {3, 5},
+ {2, 5},
+ {1, 5},
+ {3, 4},
+ {2, 4},
+ {1, 4},
+ {3, 3}, // PB7
+ // Port C definitions
+ {0, 0}, // PC0
+ {0, 0},
+ {1, 2},
+ {3, 1},
+ {2, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1}, // PC7
+ // Port D definitions
+ {2, 7}, // PD0
+ {1, 7},
+ {3, 6},
+ {2, 6},
+ {2, 3},
+ {1, 3},
+ {3, 2},
+ {2, 2}, // PD7
+ // Port E definitions
+ {0, 0}, // PE0
+ {0, 0},
+ {0, 0},
+ {4, 6},
+ {4, 7},
+ {3, 7},
+ {0, 0},
+ {4, 1} // PE7
+};
+
+#else // STM8L10X
+
+__IO uint8_t *p_GPIOx_IDR;
+__IO uint8_t *GPIOx_IDR[2] = {&(GPIOB->IDR), &(GPIOD->IDR)};
+
+GPIO_TypeDef *p_GPIOx[] = {GPIOB, GPIOD};
+
+uint16_t tab_MeasurementCounter[2] = {0}; // Measurement of each sampling of the current bank
+uint8_t Bank_IO_CompMask[TSLPRM_TOTAL_BANKS]; // IO Mask for Comparator register to control SW
+uint8_t BankSamplingCompMask[TSLPRM_TOTAL_BANKS]; // Sampling Mask for Comparator register to control SW
+uint8_t Bank_IOShield_CompMask[TSLPRM_TOTAL_BANKS];
+uint8_t BankSamplingShieldCompMask[TSLPRM_TOTAL_BANKS];
+
+/* Table which do the link between GPIO and switch configuation:{x,y}
+ x = channel number
+ y = group number - 1
+ Note: {0,0} = not connect to IO switch
+*/
+CONST TSL_IOConf_T GPIO_to_SW_Conf[8] =
+{
+ // Port B definitions
+ {1, 0}, // PB0 is channel 1 of Group 1
+ {2, 0}, // PB1 is channel 2 of Group 1
+ {1, 1}, // PB2 is channel 1 of Group 2
+ {2, 1}, // PB3 is channel 2 of Group 2
+ // Port D definitions
+ {3, 0}, // PD0 is channel 3 of Group 1
+ {4, 0}, // PD1 is channel 4 of Group 1
+ {3, 1}, // PD2 is channel 3 of Group 2
+ {4, 1} // PD3 is channel 4 of Group 2
+};
+
+#endif // !defined(STM8L10X)
+
+/* Private functions prototype -----------------------------------------------*/
+void SoftDelay(uint16_t val);
+void CreateMask(TSL_tIndex_T idx_bk, uint8_t GPIO);
+void GetCounter(__IO uint8_t *p_reg, uint8_t *p_old_status);
+INLINE void __Delay_Charge(void);
+void CreateIOMask(TSL_tIndex_T idx_bk, uint8_t GPIO);
+void CreateSamplingMask(TSL_tIndex_T idx_bk, uint8_t GPIO);
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+INLINE void SwSpreadSpectrum(void);
+#endif
+
+
+/**
+ * @brief Delay in NOPs to apply during charging time.
+ * @param None
+ * @retval None
+ */
+INLINE void __Delay_Charge(void)
+{
+#if TSLPRM_DELAY_CHARGE > 0
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 1
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 2
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 3
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 4
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 5
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 6
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 7
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 8
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 9
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 10
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 11
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 12
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 13
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 14
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 15
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 16
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 17
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 18
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 19
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 20
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 21
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 22
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 23
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 24
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 25
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 26
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 27
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 28
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 29
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 30
+ nop();
+#endif
+#if TSLPRM_DELAY_CHARGE > 31
+ nop();
+#endif
+}
+
+
+/**
+ * @brief Delay in NOPs to apply during transfering time.
+ * @param None
+ * @retval None
+ */
+INLINE void __Delay_Transfer(void)
+{
+#if TSLPRM_DELAY_TRANSFER > 0
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 1
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 2
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 3
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 4
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 5
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 6
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 7
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 8
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 9
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 10
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 11
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 12
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 13
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 14
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 15
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 16
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 17
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 18
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 19
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 20
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 21
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 22
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 23
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 24
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 25
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 26
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 27
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 28
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 29
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 30
+ nop();
+#endif
+#if TSLPRM_DELAY_TRANSFER > 31
+ nop();
+#endif
+}
+
+
+/**
+ * @brief Initialize the acquisition module.
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]); // Pointer to the first bank
+ CONST TSL_ChannelSrc_T *p_chSrc = p_bank->p_chSrc; // Pointer to the source channel of the current bank
+ TSL_tNb_T number_of_channels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+
+#if !defined(STM8L10X)
+ // Enable comparator clock to activate the RI block
+ CLK->PCKENR2 |= CLK_PCKENR2_COMP;
+#endif // !defined(STM8L10X)
+
+ // Enable mode software (bit AM)
+#if defined(STM8L15X_LD)
+ RI->CR &= (uint8_t)(~0x04); // Mode SW
+#endif // STM8L15X_LD
+
+ // Initializes each bank and configures the used GPIO
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+ number_of_channels = p_bank->NbChannels;
+
+#if !defined(STM8L10X)
+ // Mask Initialization
+ BankMask[idx_bk].ch1 = 0;
+ BankMask[idx_bk].ch2 = 0;
+ BankMask[idx_bk].ch3 = 0;
+ BankMask[idx_bk].ch4 = 0;
+#else
+ // Mask Initialization
+ BankMask[idx_bk].GPIOB_IO = 0;
+ BankMask[idx_bk].GPIOB_Samp = 0;
+ BankMask[idx_bk].GPIOD_IO = 0;
+ BankMask[idx_bk].GPIOD_Samp = 0;
+#endif // !defined(STM8L10X)
+
+ // Get which channel is used for sampling only one time because it's the same for each couple
+ SamplingMask[idx_bk] = (uint8_t)GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel;
+
+#if (TSLPRM_USE_SHIELD > 0)
+
+ // Create Mask per bank for shield
+#if !defined(STM8L10X)
+ CreateMask(idx_bk, p_bank->shield_sampling);
+ CreateMask(idx_bk, p_bank->shield_channel);
+ ChannelMask[idx_bk] |= (uint8_t)(3 << (2 * ((GPIO_to_SW_Conf[p_bank->shield_channel].IO_Channel) - 1)));
+#else
+ CreateIOMask(idx_bk, p_bank->shield_channel);
+ CreateSamplingMask(idx_bk, p_bank->shield_sampling);
+#endif // !defined(STM8L10X)
+
+ // Check if shield sampling capacitors are in the same number of channel for each group
+ if ((SamplingMask[idx_bk] != (uint8_t)GPIO_to_SW_Conf[p_bank->shield_sampling].IO_Channel))
+ {
+ return TSL_STATUS_ERROR;
+ }
+
+ // GPIO in Output
+ GPIO_DDR_OUT(p_bank->shield_sampling);
+ GPIO_DDR_OUT(p_bank->shield_channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_bank->shield_sampling);
+ GPIO_CR1_PP(p_bank->shield_channel);
+ // Output in Low level
+ GPIO_ODR_LOW(p_bank->shield_sampling);
+ GPIO_ODR_LOW(p_bank->shield_channel);
+
+ // Activate Comparator 1
+ if (GPIO_to_SW_Conf[p_bank->shield_sampling].IO_Group == 0)
+ {
+ COMP->CR |= 0x02;
+ }
+ // Activate Comparator 2
+ if (GPIO_to_SW_Conf[p_bank->shield_sampling].IO_Group == 1)
+ {
+ COMP->CR |= 0x04;
+ }
+
+#endif // TSLPRM_USE_SHIELD
+
+ // Initialize the mask for channel and sampling
+ for (idx_ch = 0; idx_ch < number_of_channels; idx_ch++)
+ {
+#if !defined(STM8L10X)
+ // Create Mask per bank for channel and sampling
+ CreateMask(idx_bk, p_chSrc->channel);
+ CreateMask(idx_bk, p_chSrc->sampling);
+ ChannelMask[idx_bk] |= (uint8_t)(3 << (2 * ((GPIO_to_SW_Conf[p_chSrc->channel].IO_Channel) - 1)));
+ // Check if sampling capacitors are in the same number of channel for each group
+ if ((SamplingMask[idx_bk] != (uint8_t)GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel))
+ {
+ return TSL_STATUS_ERROR;
+ }
+#else
+ // Activate Comparator 1
+ if (p_chSrc->IdxSrc == 0)
+ {
+ COMP->CR |= 0x02;
+ }
+ // Activate Comparator 2
+ if (p_chSrc->IdxSrc == 1)
+ {
+ COMP->CR |= 0x04;
+ }
+ // Create Mask per bank for channel and sampling
+ CreateIOMask(idx_bk,p_chSrc->channel);
+ Bank_IO_CompMask[idx_bk] |= (uint8_t)(1 << (GPIO_to_SW_Conf[p_chSrc->channel].IO_Channel - 1));
+ Bank_IO_CompMask[idx_bk] = (uint8_t)(Bank_IO_CompMask[idx_bk] << (4 * GPIO_to_SW_Conf[p_chSrc->channel].IO_Group));
+ CreateSamplingMask(idx_bk,p_chSrc->sampling);
+ BankSamplingCompMask[idx_bk] |= (uint8_t)(1 << (GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel - 1));
+ BankSamplingCompMask[idx_bk] = (uint8_t)(BankSamplingCompMask[idx_bk] << (4 * GPIO_to_SW_Conf[p_chSrc->sampling].IO_Group));
+ if ((SamplingMask[idx_bk] != (uint8_t)GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel))
+ {
+ return TSL_STATUS_ERROR;
+ }
+#if (TSLPRM_USE_SHIELD > 0)
+ Bank_IOShield_CompMask[idx_bk] |= (uint8_t)(1 << (GPIO_to_SW_Conf[p_bank->shield_channel].IO_Channel - 1));
+ Bank_IOShield_CompMask[idx_bk] = (uint8_t)(Bank_IOShield_CompMask[idx_bk] << (4 * GPIO_to_SW_Conf[p_bank->shield_channel].IO_Group));
+ BankSamplingShieldCompMask[idx_bk] |= (uint8_t)(1 << (GPIO_to_SW_Conf[p_bank->shield_sampling].IO_Channel - 1));
+ BankSamplingShieldCompMask[idx_bk] = (uint8_t)(BankSamplingShieldCompMask[idx_bk] << (4 * GPIO_to_SW_Conf[p_bank->shield_sampling].IO_Group));
+ Bank_IO_CompMask[idx_bk] = (uint8_t)(Bank_IO_CompMask[idx_bk] | Bank_IOShield_CompMask[idx_bk]);
+ BankSamplingCompMask[idx_bk] = (uint8_t)(BankSamplingCompMask[idx_bk] | BankSamplingShieldCompMask[idx_bk]);
+#endif
+#endif // !defined(STM8L10X)
+
+ // GPIO are configured in PP Low mode when inactive
+ // GPIO in Output
+ GPIO_DDR_OUT(p_chSrc->sampling);
+ GPIO_DDR_OUT(p_chSrc->channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_chSrc->sampling);
+ GPIO_CR1_PP(p_chSrc->channel);
+ // Output in Low level
+ GPIO_ODR_LOW(p_chSrc->sampling);
+ GPIO_ODR_LOW(p_chSrc->channel);
+
+ p_chSrc++; // Next channel
+ }
+
+#if !defined(STM8L10X)
+ // Unlock IO to RI register: IO controlled by GPIO
+ RI->IOCMR1 &= (uint8_t)(~BankMask[idx_bk].ch1);
+ RI->IOCMR2 &= (uint8_t)(~BankMask[idx_bk].ch2);
+ RI->IOCMR3 &= (uint8_t)(~BankMask[idx_bk].ch3);
+#if defined(STM8L15X_LD)
+ RI->IOCMR4 &= (uint8_t)(~BankMask[idx_bk].ch4);
+#endif // STM8L15X_LD || STM8L10X
+#endif // !defined(STM8L10X)
+ }
+
+ return TSL_STATUS_OK;
+}
+
+
+#if !defined(STM8L10X)
+/**
+ * @brief Create Mask for all banks
+ * @param[in] idx_bk Index of the Bank to configure
+ * @param[in] GPIO Pin number
+ * @retval None
+ */
+void CreateMask(TSL_tIndex_T idx_bk, uint8_t GPIO)
+{
+ switch (GPIO_to_SW_Conf[GPIO].IO_Channel)
+ {
+ case 1:
+ BankMask[idx_bk].ch1 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask for all first channel
+ break;
+ case 2:
+ BankMask[idx_bk].ch2 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask for all second channel
+ break;
+ case 3:
+ BankMask[idx_bk].ch3 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask fo all third channel
+ break;
+#if defined(STM8L15X_LD) || defined(STM8L10X)
+ case 4:
+ BankMask[idx_bk].ch4 |= (uint8_t)(1 << GPIO_to_SW_Conf[GPIO].IO_Group); // Mask for all fourth channel
+ break;
+#endif // STM8L15X_LD || STM8L10X
+ default:
+ break;
+ }
+}
+
+#else
+
+/**
+ * @brief Create IO Mask for all banks
+ * @param[in] idx_bk Index of the Bank to configure
+ * @param[in] GPIO Pin number
+ * @retval None
+ */
+void CreateIOMask(TSL_tIndex_T idx_bk, uint8_t GPIO)
+{
+ switch (GPIO_PORT(GPIO))
+ {
+ case 0:
+ BankMask[idx_bk].GPIOB_IO |= (uint8_t)(1 << GPIO_BIT(GPIO));
+ break;
+ case 1:
+ BankMask[idx_bk].GPIOD_IO |= (uint8_t)(1 << GPIO_BIT(GPIO));
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**
+ * @brief Create Sampling Mask for all banks
+ * @param[in] idx_bk Index of the Bank to configure
+ * @param[in] GPIO Pin number
+ * @retval None
+ */
+void CreateSamplingMask(TSL_tIndex_T idx_bk, uint8_t GPIO)
+{
+ switch (GPIO_PORT(GPIO))
+ {
+ case 0:
+ BankMask[idx_bk].GPIOB_Samp |= (uint8_t)(1 << GPIO_BIT(GPIO));
+ break;
+ case 1:
+ BankMask[idx_bk].GPIOD_Samp |= (uint8_t)(1 << GPIO_BIT(GPIO));
+ break;
+ default:
+ break;
+ }
+}
+
+#endif // !defined(STM8L10X)
+
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+/**
+ * @brief Spread Spectrum using a variable software delay.
+ * @param None
+ * @retval None
+ */
+INLINE void SwSpreadSpectrum(void)
+{
+ uint8_t idx;
+
+ SpreadCounter++;
+
+ if (SpreadCounter == TSLPRM_SPREAD_MAX)
+ {
+ SpreadCounter = TSLPRM_SPREAD_MIN;
+ }
+
+ idx = SpreadCounter;
+
+ while (--idx) {}
+}
+#endif
+
+
+/**
+ * @brief Bank configuration
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ uint8_t idx_i;
+#if defined(STM8L10X)
+ uint8_t GroupUsed = 0;
+#endif
+ TSL_tIndex_T idx_dest;
+ TSL_tIndex_T idx_ch;
+ TSL_tNb_T number_of_channels = 0;
+ CONST TSL_Bank_T *p_bank; // Pointer to the current bank
+ CONST TSL_ChannelDest_T *p_chDest; // Pointer to the first destination channel of the current bank
+ CONST TSL_ChannelSrc_T *p_chSrc; // Pointer to the fisrt source channel of the current bank
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ number_of_channels = p_bank->NbChannels;
+ p_chDest = p_bank->p_chDest;
+ p_chSrc = p_bank->p_chSrc;
+
+ // Reset the disable mask
+ DisableSampling = 0;
+ for (idx_i = 0; idx_i < MAX_CHANNEL_NUMBER_BY_GROUP; idx_i++)
+ {
+ DisableMask[idx_i] = 0;
+ }
+
+ BankDone = 0;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ DISABLE_SAMPLING(p_bank->shield_sampling);
+#endif // TSLPRM_USE_SHIELD
+
+ ChannelSampling = SamplingMask[idx_bk]; // Mask for the channel used by sampling
+
+ // Loop for each channel of this bank
+ for (idx_ch = 0; idx_ch < number_of_channels; idx_ch++)
+ {
+ idx_dest = p_chDest->IdxDest;
+#if defined(STM8L10X)
+ if (p_chSrc->IdxSrc == 0)
+ {
+ GroupUsed |= 0x01;
+ }
+ if (p_chSrc->IdxSrc == 1)
+ {
+ GroupUsed |= 0x02;
+ }
+#endif // defined(STM8L10X)
+
+ // Mode Status OFF
+ if (p_bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_OFF)
+ {
+#if !defined(STM8L10X)
+ // Update Mask if channels are disabled
+ DISABLE_MASK(p_chSrc->channel);
+ DISABLE_MASK(p_chSrc->sampling);
+#else
+ // Update Mask if channels are disabled
+ if (GPIO_to_SW_Conf[p_chSrc->channel].IO_Channel > 2)
+ {
+ DisableMask[2] |= (uint8_t)(1 << ((2 * GPIO_to_SW_Conf[p_chSrc->channel].IO_Group) + (GPIO_to_SW_Conf[p_chSrc->channel].IO_Channel - 3)));
+ }
+ else
+ {
+ DisableMask[0] |= (uint8_t)(1 << ((2 * GPIO_to_SW_Conf[p_chSrc->channel].IO_Group) + (GPIO_to_SW_Conf[p_chSrc->channel].IO_Channel - 1)));
+ }
+ if (GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel > 2)
+ {
+ DisableMask[3] |= (uint8_t)(1 << ((2 * GPIO_to_SW_Conf[p_chSrc->sampling].IO_Group) + (GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel - 3)));
+ }
+ else
+ {
+ DisableMask[1] |= (uint8_t)(1<<((2 * GPIO_to_SW_Conf[p_chSrc->sampling].IO_Group) + (GPIO_to_SW_Conf[p_chSrc->sampling].IO_Channel - 1)));
+ }
+#endif // !defined(STM8L10X)
+ }
+
+ // Mode Status BURST ONLY
+ if (p_bank->p_chData[idx_dest].Flags.ObjStatus == TSL_OBJ_STATUS_BURST_ONLY)
+ {
+#if !defined(STM8L10X)
+ DISABLE_SAMPLING(p_chSrc->sampling);
+#else
+ if (p_chSrc->IdxSrc == 0)
+ {
+ GroupUsed &= (uint8_t)(~0x01);
+ }
+ if (p_chSrc->IdxSrc == 1)
+ {
+ GroupUsed &= (uint8_t)(~0x02);
+ }
+#endif // !defined(STM8L10X)
+ }
+
+ tab_MeasurementCounter[GPIO_to_SW_Conf[p_chSrc->sampling].IO_Group] = 0;
+
+ // Next channel
+ p_chSrc++;
+ p_chDest++;
+ }
+
+#if !defined(STM8L10X)
+ //Get Mask for the current bank
+ CurrentBank[0] = (uint8_t)(BankMask[idx_bk].ch1 & (~DisableMask[0])); // Mask for all 1st channel are used by channels and sampling for this bank
+ CurrentBank[1] = (uint8_t)(BankMask[idx_bk].ch2 & (~DisableMask[1])); // Mask for all 2nd channel are used by channels and sampling for this bank
+ CurrentBank[2] = (uint8_t)(BankMask[idx_bk].ch3 & (~DisableMask[2])); // Mask for all 3rd channel are used by channels and sampling for this bank
+#if defined(STM8L15X_LD)
+ CurrentBank[3] = (uint8_t)(BankMask[idx_bk].ch4 & (~DisableMask[3])); // Mask for all 4th channel are used by channels and sampling for this bank
+#endif // STM8L15X_LD
+ CurrentChannel = ChannelMask[idx_bk]; // Mask for channels
+ CurrentSampling = (uint8_t)(3 << (2 * (SamplingMask[idx_bk] - 1))); // Mask for sampling
+
+ // Channel's state of the current bank
+ BankDone = (uint8_t)(CurrentBank[ChannelSampling - 1] & (~DisableSampling));
+
+ // Select the Input register corresponding to the channel sampling (to optimize the measurement)
+ p_IOIRx = RI_IOIRx_Register[ChannelSampling - 1];
+
+#else
+ //Get Mask for the current bank
+ CurrentBank[0] = (uint8_t)(BankMask[idx_bk].GPIOB_IO & (~DisableMask[0]));
+ CurrentBank[1] = (uint8_t)(BankMask[idx_bk].GPIOB_Samp & (~DisableMask[1]));
+ CurrentBank[2] = (uint8_t)(BankMask[idx_bk].GPIOD_IO & (~DisableMask[2]));
+ CurrentBank[3] = (uint8_t)(BankMask[idx_bk].GPIOD_Samp & (~DisableMask[3]));
+
+ CurrentChannel = (uint8_t)(Bank_IO_CompMask[idx_bk]); // Mask for channels
+ CurrentSampling = (uint8_t)(BankSamplingCompMask[idx_bk]); // Mask for sampling
+
+ // Select the Input register corresponding to the channel sampling (to optimize the measurement) and update BankDone, which is the mask where there are sampling capacitors
+ if (ChannelSampling > 2) // GPIOD
+ {
+ p_GPIOx_IDR = GPIOx_IDR[1];
+ if ((GroupUsed & 0x01) == 1)
+ {
+ BankDone |= (uint8_t)(1 << (ChannelSampling - 3));
+ }
+ if((GroupUsed & 0x02) == 2)
+ {
+ BankDone |= (uint8_t)(1 << (2 + (ChannelSampling - 3)));
+ }
+
+ }
+ else // GPIOB
+ {
+ p_GPIOx_IDR = GPIOx_IDR[0];
+ if ((GroupUsed & 0x01) == 1)
+ {
+ BankDone |= (uint8_t)(1 << (ChannelSampling - 1));
+ }
+ if ((GroupUsed & 0x02) == 2)
+ {
+ BankDone |= (uint8_t)(1 << (2 + (ChannelSampling - 1)));
+ }
+ }
+
+#endif // !defined(STM8L10X)
+
+ return TSL_STATUS_OK;
+}
+
+
+#if !defined(STM8L10X)
+
+/**
+ * @brief Start acquisition
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]);
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ TSL_tNb_T number_of_channels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+ uint8_t step3, step5, deadtime1, deadtime2; //intermediate variables to speed-up the acquisition loop
+
+ uint8_t old_status = 0;
+
+ ChargeTransferCounter = 0;
+
+#if (TSLPRM_IODEF > 0)
+ //============================
+ // All GPIOs in Input floating
+ //============================
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // GPIO in floating mode
+ GPIO_CR1_FLOATING(p_bank->shield_sampling);
+ GPIO_CR1_FLOATING(p_bank->shield_channel);
+ // GPIO in Input
+ GPIO_DDR_IN(p_bank->shield_sampling);
+ GPIO_DDR_IN(p_bank->shield_channel);
+#endif // TSLPRM_USE_SHIELD
+
+ number_of_channels = p_bank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < number_of_channels;
+ idx_ch++)
+ {
+ // GPIO in floating mode
+ GPIO_CR1_FLOATING(p_chSrc->sampling);
+ GPIO_CR1_FLOATING(p_chSrc->channel);
+ // GPIO in Input
+ GPIO_DDR_IN(p_chSrc->sampling);
+ GPIO_DDR_IN(p_chSrc->channel);
+ p_chSrc++;
+ }
+ }
+#endif // TSLPRM_IODEF
+
+ // Test if this bank is not empty
+ if (BankDone != 0)
+ {
+ // Enable necessary IOs
+ RI->IOCMR1 |= (uint8_t)CurrentBank[0];
+ RI->IOCMR2 |= (uint8_t)CurrentBank[1];
+ RI->IOCMR3 |= (uint8_t)CurrentBank[2];
+#if defined(STM8L15X_LD)
+ RI->IOCMR4 |= (uint8_t)CurrentBank[3];
+#endif // STM8L15X_LD
+
+ RI->IOSR1 |= (uint8_t)CurrentBank[0];
+ RI->IOSR2 |= (uint8_t)CurrentBank[1];
+ RI->IOSR3 |= (uint8_t)CurrentBank[2];
+#if defined(STM8L15X_LD)
+ RI->IOSR4 |= (uint8_t)CurrentBank[3];
+#endif // STM8L15X_LD
+
+ /* STEP1 : Discharging all capacitors
+ ==> all IOs in Push-Pull LOW */
+ RI->IOGCR &= (uint8_t)(~(CurrentChannel | CurrentSampling));
+
+ /* STEP2: Waiting for complete discharge */
+ SoftDelay(TSLPRM_DELAY_DISCHARGE_ALL);
+ // Dead Time
+ RI->IOGCR |= (uint8_t)(0xAA & (CurrentChannel | CurrentSampling));
+
+ // Close switch sampling
+ RI->IOGCR |= CurrentSampling;
+
+ /* Copmpute RI->IOGCR for each step */
+ /* STEP3: Charging C-Touch
+ ==> Channels in Push-Pull HIGH
+ ==> Sampling kept open */
+ step3 = (uint8_t)(RI->IOGCR ^ CurrentChannel);
+ /* Deadtime */
+ deadtime1 = RI->IOGCR ; // equivalent to step3 ^ (uint8_t)CurrentChannel;
+ /* STEP5: Transfering C-Touch charge in C-Sampling
+ ==> Close IOs Switchs */
+ step5 = (uint8_t)(RI->IOGCR | CurrentChannel);
+ /* Deadtime */
+ deadtime2 = (uint8_t)(step5 & (0xAA | (~CurrentChannel)));
+
+ // Loop while all sampling have not reach the VIH level
+ do
+ {
+ /* STEP3: Charging C-Touch */
+ RI->IOGCR = step3;
+ // Get the measurement of counter if the value of Input register change
+ if ((*p_IOIRx & BankDone) != old_status)
+ {
+ GetCounter(p_IOIRx, &old_status);
+ }
+
+ /* STEP4 : Waiting for good chargement */
+ __Delay_Charge();
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+ SwSpreadSpectrum();
+#endif
+
+ /* Dead Time */
+ RI->IOGCR = deadtime1;
+ /* STEP5: Transfering C-Touch charge in C-Sampling */
+ RI->IOGCR = step5;
+
+ ChargeTransferCounter++;
+
+ /* STEP6: Waiting for good transfer */
+ __Delay_Transfer();
+
+ /* Dead Time */
+ RI->IOGCR = deadtime1;
+ } while ((old_status != BankDone) && (ChargeTransferCounter <= TSL_Params.AcqMax));
+
+ // Get the value of counter if he reach the Max count
+ if(ChargeTransferCounter > TSL_Params.AcqMax)
+ {
+ GetCounter(&BankDone, &old_status);
+ }
+
+ // Disable necessary IOs
+ RI->IOSR1 &= (uint8_t)(~(CurrentBank[0]));
+ RI->IOSR2 &= (uint8_t)(~(CurrentBank[1]));
+ RI->IOSR3 &= (uint8_t)(~(CurrentBank[2]));
+#if defined(STM8L15X_LD)
+ RI->IOSR4 &= (uint8_t)(~(CurrentBank[3]));
+#endif
+
+ RI->IOCMR1 &= (uint8_t)(~(CurrentBank[0]));
+ RI->IOCMR2 &= (uint8_t)(~(CurrentBank[1]));
+ RI->IOCMR3 &= (uint8_t)(~(CurrentBank[2]));
+#if defined(STM8L15X_LD)
+ RI->IOCMR4 &= (uint8_t)(~(CurrentBank[3]));
+#endif
+
+ //====================
+ // All GPIOs in PP Low
+ //====================
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Output in Low level
+ GPIO_ODR_LOW(p_bank->shield_sampling);
+ GPIO_ODR_LOW(p_bank->shield_channel);
+ // GPIO in Output
+ GPIO_DDR_OUT(p_bank->shield_sampling);
+ GPIO_DDR_OUT(p_bank->shield_channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_bank->shield_sampling);
+ GPIO_CR1_PP(p_bank->shield_channel);
+#endif // TSLPRM_USE_SHIELD
+
+ number_of_channels = p_bank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < number_of_channels;
+ idx_ch++)
+ {
+ // Output in Low level
+ GPIO_ODR_LOW(p_chSrc->sampling);
+ GPIO_ODR_LOW(p_chSrc->channel);
+ // GPIO in Output
+ GPIO_DDR_OUT(p_chSrc->sampling);
+ GPIO_DDR_OUT(p_chSrc->channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_chSrc->sampling);
+ GPIO_CR1_PP(p_chSrc->channel);
+ p_chSrc++;
+ }
+ }
+
+ }
+}
+
+#else // STM8L10X
+
+/**
+ * @brief Start acquisition
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+ CONST TSL_Bank_T *p_bank = &(TSL_Globals.Bank_Array[0]);
+ CONST TSL_ChannelSrc_T *p_chSrc;
+ TSL_tNb_T number_of_channels = 0;
+ TSL_tIndex_T idx_bk;
+ TSL_tIndex_T idx_ch;
+
+ uint8_t old_status = 0;
+
+ ChargeTransferCounter = 0;
+
+#if (TSLPRM_IODEF > 0)
+ //============================
+ // All GPIOs in Input floating
+ //============================
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS; idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // GPIO in floating mode
+ GPIO_CR1_FLOATING(p_bank->shield_sampling);
+ GPIO_CR1_FLOATING(p_bank->shield_channel);
+ // GPIO in Input
+ GPIO_DDR_IN(p_bank->shield_sampling);
+ GPIO_DDR_IN(p_bank->shield_channel);
+#endif
+
+ number_of_channels = p_bank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < number_of_channels;
+ idx_ch++)
+ {
+ // GPIO in floating mode
+ GPIO_CR1_FLOATING(p_chSrc->sampling);
+ GPIO_CR1_FLOATING(p_chSrc->channel);
+ // GPIO in Input
+ GPIO_DDR_IN(p_chSrc->sampling);
+ GPIO_DDR_IN(p_chSrc->channel);
+
+ p_chSrc++;
+ }
+ }
+#endif // TSLPRM_IODEF
+
+ // Test if this bank is not empty
+ if (BankDone != 0)
+ {
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ disableInterrupts();
+#endif //TSLPRM_PROTECT_IO_ACCESS
+
+ /* STEP1 : Discharging all capacitors
+ ==> all IOs in open-drain LOW */
+ GPIOB->ODR &= (uint8_t)(~(CurrentBank[0] | CurrentBank[1]));
+ GPIOB->CR1 &= (uint8_t)(~(CurrentBank[0] | CurrentBank[1]));
+ GPIOB->DDR |= (uint8_t)(CurrentBank[0] | CurrentBank[1]);
+ GPIOD->ODR &= (uint8_t)(~(CurrentBank[2] | CurrentBank[3]));
+ GPIOD->CR1 &= (uint8_t)(~(CurrentBank[2] | CurrentBank[3]));
+ GPIOD->DDR |= (uint8_t)(CurrentBank[2] | CurrentBank[3]);
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ enableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ COMP->CCS &= (uint8_t)(~(CurrentSampling |CurrentChannel));
+
+ /* STEP2: Waiting for complete discharge */
+ SoftDelay(TSLPRM_DELAY_DISCHARGE_ALL);
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ disableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ // Dead Time
+ GPIOB->DDR &= (uint8_t)(~(CurrentBank[0] | CurrentBank[1]));
+ GPIOD->DDR &= (uint8_t)(~(CurrentBank[2] | CurrentBank[3]));
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ enableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ GPIOB->ODR |= (uint8_t)(CurrentBank[0]);
+ GPIOD->ODR |= (uint8_t)(CurrentBank[2]);
+
+ // Loop while all sampling have not reach the VIH level
+ do
+ {
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ disableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ /* STEP3: Charging C-Touch
+ ==> Channels in Push-Pull HIGH
+ ==> Sampling kept open */
+ GPIOB->DDR |= (uint8_t)(CurrentBank[0]);
+ GPIOB->CR1 |= (uint8_t)(CurrentBank[0]);
+ GPIOD->DDR |= (uint8_t)(CurrentBank[2]);
+ GPIOD->CR1 |= (uint8_t)(CurrentBank[2]);
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ enableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ /* STEP4 : Waiting for good chargement */
+ __Delay_Charge();
+
+#if (TSLPRM_USE_SPREAD_SPECTRUM > 0)
+ SwSpreadSpectrum();
+#endif
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ disableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ // Dead Time
+ GPIOB->CR1 &= (uint8_t)(~(CurrentBank[0]));
+ GPIOB->DDR &= (uint8_t)(~(CurrentBank[0]));
+ GPIOD->CR1 &= (uint8_t)(~(CurrentBank[2]));
+ GPIOD->DDR &= (uint8_t)(~(CurrentBank[2]));
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ enableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ /* STEP5: Transfering C-Touch charge in C-Sampling
+ ==> Close IOs Switchs */
+
+ // Close switch sampling
+ COMP->CCS |= (uint8_t)CurrentSampling;
+ COMP->CCS |= (uint8_t)CurrentChannel;
+
+ /* STEP6: Waiting for good transfer */
+ __Delay_Transfer();
+
+ //Dead Time
+ COMP->CCS &= (uint8_t)(~(CurrentChannel | CurrentSampling));
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ disableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ // Get the measurement of counter if the value of Input register change
+ if ((*p_GPIOx_IDR & BankDone) != old_status)
+ {
+ GetCounter(p_GPIOx_IDR, &old_status);
+ }
+
+#ifdef TSLPRM_PROTECT_IO_ACCESS
+ enableInterrupts();
+#endif // TSLPRM_PROTECT_IO_ACCESS
+
+ ChargeTransferCounter++;
+
+ } while ((old_status != BankDone) && (ChargeTransferCounter != (TSL_Params.AcqMax+1)));
+
+ // Get the value of counter if he reach the Max count
+ if(ChargeTransferCounter == (TSL_Params.AcqMax+1))
+ {
+ GetCounter(&BankDone, &old_status);
+ }
+
+ //====================
+ // All GPIOs in PP Low
+ //====================
+ for (idx_bk = 0; idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++)
+ {
+ p_bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ p_chSrc = p_bank->p_chSrc;
+
+#if (TSLPRM_USE_SHIELD > 0)
+ // Output in Low level
+ GPIO_ODR_LOW(p_bank->shield_sampling);
+ GPIO_ODR_LOW(p_bank->shield_channel);
+ // GPIO in Output
+ GPIO_DDR_OUT(p_bank->shield_sampling);
+ GPIO_DDR_OUT(p_bank->shield_channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_bank->shield_sampling);
+ GPIO_CR1_PP(p_bank->shield_channel);
+#endif // TSLPRM_USE_SHIELD
+
+ number_of_channels = p_bank->NbChannels;
+
+ for (idx_ch = 0;
+ idx_ch < number_of_channels;
+ idx_ch++)
+ {
+ // Output in Low level
+ GPIO_ODR_LOW(p_chSrc->sampling);
+ GPIO_ODR_LOW(p_chSrc->channel);
+ // GPIO in Output
+ GPIO_DDR_OUT(p_chSrc->sampling);
+ GPIO_DDR_OUT(p_chSrc->channel);
+ // GPIO in PP
+ GPIO_CR1_PP(p_chSrc->sampling);
+ GPIO_CR1_PP(p_chSrc->channel);
+ p_chSrc++;
+ }
+ }
+
+ }
+}
+
+#endif
+
+
+/**
+ * @brief Do the measurement
+ * @param *p_reg Pointer to the Input register
+ * @param *p_old_status Pointer to the previous status value
+ * @retval None
+ */
+
+void GetCounter(__IO uint8_t *p_reg, uint8_t *p_old_status)
+{
+
+ uint8_t new_status = 0;
+ uint8_t idx_i = 0;
+ uint8_t mask_i = 1;
+#if defined(STM8L10X)
+ uint8_t idx_j = 4;
+ uint8_t idx_group = 0;
+#else
+ uint8_t idx_j = 8;
+#endif // defined(STM8L10X)
+
+ new_status = *p_reg;
+ new_status = (uint8_t)(new_status & BankDone & (~(*p_old_status)));
+
+ while ((new_status != 0) && (idx_i < idx_j))
+ {
+ if ((new_status & mask_i) != 0)
+ {
+#if defined(STM8L10X)
+ tab_MeasurementCounter[idx_group]= ChargeTransferCounter;
+#else
+ tab_MeasurementCounter[idx_i] = ChargeTransferCounter;
+#endif // defined(STM8L10X)
+ *p_old_status |= mask_i;
+ new_status &= (uint8_t)(~mask_i);
+ }
+ idx_i++;
+ mask_i <<= 1;
+#if defined(STM8L10X)
+ if (idx_i > 1)
+ {
+ idx_group = 1;
+ }
+#endif // defined(STM8L10X)
+ }
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndex_T index)
+{
+ return(tab_MeasurementCounter[index]);
+}
+
+
+/**
+ * @brief Check noise (not used)
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ return TSL_ACQ_STATUS_OK;
+}
+
+
+/**
+ * @brief Check if a filter must be used on the current channel (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if a filter can be applied
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ return TSL_TRUE;
+}
+
+
+/**
+ * @brief Compute the Delta value
+ * @param[in] ref Reference value
+ * @param[in] meas Last Measurement value
+ * @retval Delta value
+ */
+TSL_tDelta_T TSL_acq_ComputeDelta(TSL_tRef_T ref, TSL_tMeas_T meas)
+{
+ return((TSL_tDelta_T)(ref - meas));
+}
+
+
+/**
+ * @brief Compute the Measurement value
+ * @param[in] ref Reference value
+ * @param[in] delta Delta value
+ * @retval Measurement value
+ */
+TSL_tMeas_T TSL_acq_ComputeMeas(TSL_tRef_T ref, TSL_tDelta_T delta)
+{
+ return((TSL_tMeas_T)(ref - delta));
+}
+
+
+/**
+ * @brief Test if the Reference is incorrect (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @retval Result TRUE if the Reference is out of range
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ return TSL_FALSE;
+}
+
+
+/**
+ * @brief Test if the measure has crossed the reference target (not used)
+ * @param[in] pCh Pointer on the channel data information
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result TRUE if the Reference is valid
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ return TSL_TRUE;
+}
+
+
+#if defined(__ICCSTM8__)
+#pragma optimize=low
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * @retval None
+ */
+void SoftDelay(uint16_t val)
+{
+ uint16_t idx;
+ for (idx = val; idx > 0; idx--)
+ {
+ nop();
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c
new file mode 100644
index 0000000..9298122
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_acq_stm8tl5x.c
@@ -0,0 +1,906 @@
+/**
+ ******************************************************************************
+ * @file tsl_acq_stm8tl5x.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the PXS acquisition
+ * on STM8TL5x products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_acq_stm8tl5x.h"
+#include "tsl_globals.h"
+#include "stm8tl5x_it.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+
+/* Private defines -----------------------------------------------------------*/
+#define EPCC_INIT_VALUE (0x80)
+#define CS_MIDDLE_VALUE (17)
+#define CS_MAX_VALUE (32)
+#define MAX_MEASURE (0xFFFF)
+
+/* Private macros ------------------------------------------------------------*/
+#define IS_BANK_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_BANKS)))
+#define IS_SOURCE_INDEX_OK(INDEX) (((INDEX) == 0) || (((INDEX) > 0) && ((INDEX) < TSLPRM_TOTAL_CHANNELS)))
+#define IS_EPCC_STATUS_OK(STATUS) ((STATUS & TSL_EPCC_CHANGE_MASK) != 0)
+#define IS_CSSEL_OK(CSSEL) (((CSSEL) == 0) || (((CSSEL) > 0) && ((CSSEL) < CS_MAX_VALUE)))
+
+/* Private variables ---------------------------------------------------------*/
+TSL_BankConfig_T PXS_BankConfig[TSLPRM_TOTAL_BANKS];
+CONST uint8_t PXS_CSsorting[] = {0, 1, 2, 8, 3, 4, 5, 9, 6, 10, 16, 11, 7, 12, 17, 13, 18, 19, 14, 24, 15, 20, 25, 21, 26, 22, 27, 23, 28, 29, 30, 31};
+
+/* Private functions prototype -----------------------------------------------*/
+void TSL_PXS_CS_CalibrateBank(TSL_tIndex_T idx_bk);
+int8_t TSL_PXS_EPCC_CalibrateBank(TSL_tIndex_T bank);
+TSL_Status_enum_T TSL_PXS_EPCC_CalibrateZone(CONST TSL_Zone_T *);
+void SoftDelay(uint16_t val);
+
+/**
+ * @brief Initializes the acquisition module.
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_Init(void)
+{
+
+ TSL_Status_enum_T retval = TSL_STATUS_OK;
+
+ TSL_tIndex_T i;
+ TSL_tIndex_T j;
+ TSL_tIndex_T idx_bk; // Bank index
+ uint16_t TxInUseMask = 0;
+ uint16_t RxInUseMask = 0;
+ CONST TSL_Bank_T *bank;
+ uint8_t *CSArray;
+
+ // Enable the PXS IP clock
+ CLK->PCKENR1 |= CLK_PCKENR1_PXS;
+
+ // Initialization of PXS IP
+ PXS->CKCR1 &= (uint8_t)~PXS_CKCR1_PRESC;
+
+#if (TSLPRM_PXS_HSI == 16000)
+ PXS->CKCR1 |= PXS_CKCR1_16MHZ;
+#elif (TSLPRM_PXS_HSI == 8000)
+ PXS->CKCR1 |= PXS_CKCR1_8MHZ;
+#elif (TSLPRM_PXS_HSI == 4000)
+ PXS->CKCR1 |= PXS_CKCR1_4MHZ;
+#elif (TSLPRM_PXS_HSI == 2000)
+ PXS->CKCR1 |= PXS_CKCR1_2MHZ;
+#elif (TSLPRM_PXS_HSI == 1000)
+ PXS->CKCR1 |= PXS_CKCR1_1MHZ;
+#elif (TSLPRM_PXS_HSI == 500)
+ PXS->CKCR1 |= PXS_CKCR1_500KHZ;
+#elif (TSLPRM_PXS_HSI == 250)
+ PXS->CKCR1 |= PXS_CKCR1_250KHZ;
+#elif (TSLPRM_PXS_HSI == 125)
+ PXS->CKCR1 |= PXS_CKCR1_125KHZ;
+#else
+ PXS->CKCR1 |= PXS_CKCR1_16MHZ; // Default
+#endif
+
+ PXS->CKCR2 = (uint8_t)(((uint8_t)TSLPRM_PXS_UP_LENGTH & 0x07) << 4) | ((uint8_t)TSLPRM_PXS_PASS_LENGTH & 0x07);
+
+#if TSLPRM_PXS_RF_DETECTION > 0
+ enablePXSNoiseDetection();
+#endif
+
+ setPXSStab(TSLPRM_PXS_STAB);
+ setPXSBias(TSLPRM_PXS_BIAS);
+
+ // Initialization of the GPIO shared with the used TX
+ for (i = 0; i < TSLPRM_TOTAL_BANKS; i++)
+ {
+ bank = &(TSL_Globals.Bank_Array[i]);
+ CSArray = PXS_BankConfig[i].CSSEL;
+ TxInUseMask |= bank->msk_TX;
+ // Set the mask with the receivers use as receiver or as transmitter
+ RxInUseMask |= bank->msk_RXEN;
+ // Set the CS to 0
+ for (j = 0; j <= TSLPRM_HIGH_CHANNEL_NB; j++)
+ {
+ *CSArray = 0;
+ CSArray++;
+ }
+ }
+
+ GPIOD->ODR &= (uint8_t)(~(TxInUseMask & 0x00FF));
+ // Set the port as output
+ GPIOD->DDR |= (uint8_t)(TxInUseMask & 0x00FF);
+ // Configure the port as open-drain
+ GPIOD->CR1 &= (uint8_t)(~(TxInUseMask & 0x00FF));
+#if TSLPRM_PXS_INACTIVE_TX > 0
+ // Configure as floating
+ GPIOD->ODR |= (uint8_t)(TxInUseMask & 0x00FF);
+#else
+ // Drive them to VSS
+ GPIOD->ODR &= (uint8_t)(~(TxInUseMask & 0x00FF));
+#endif
+ GPIOB->ODR &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8));
+ // Set the port as output
+ GPIOB->DDR |= (uint8_t)((TxInUseMask & 0xFF00) >> 8);
+ // Configure the port as open-drain
+ GPIOB->CR1 &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8));
+#if TSLPRM_PXS_INACTIVE_TX > 0
+ // Configure as floating
+ GPIOB->ODR |= (uint8_t)((TxInUseMask & 0xFF00) >> 8);
+#else
+ // Drive it to VSS
+ GPIOB->ODR &= (uint8_t)(~((TxInUseMask & 0xFF00) >> 8));
+#endif
+
+ enablePXS();
+
+#if TSLPRM_PXS_INACTIVE_RX > 0
+ PXS->RXINSR = 0x3FF;
+#else
+ PXS->RXINSR = 0x0000;
+#endif
+
+#if TSLPRM_PXS_RX_COUPLING > 0
+ enablePXSCoupling();
+#else
+ disablePXSCoupling()
+#endif
+
+#if TSLPRM_PXS_SYNCHRONIZE > 0
+ enablePXSSync();
+#if TSLPRM_PXS_SYNCHRO_EDGE > 0
+ selectPXSSyncRisingEdge();
+#else
+ selectPXSSyncFallingEdge();
+#endif
+#else
+ disablePXSSync();
+#endif
+
+#if TSLPRM_USE_ACQ_INTERRUPT > 0
+ enablePXSInterrupts(PXS_CR2_EOCITEN);
+#endif
+ // Configure the acquisition mode
+ PXS->RXCR3 = (uint16_t)RxInUseMask;
+ PXS->RXCR2 = (uint16_t)RxInUseMask;
+
+#if TSLPRM_ACQ_MAX > 0
+ PXS->MAXR = TSLPRM_ACQ_MAX;
+ PXS->MAXENR = 0x03FF;
+#else
+ PXS->MAXENR = 0;
+#endif
+
+ // Calibrate the CS for all banks
+ for (idx_bk = 0;idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++)
+ {
+ TSL_PXS_CS_CalibrateBank(idx_bk);
+ }
+
+
+ // Calibrate the EPCC for all banks
+ for (idx_bk = 0;idx_bk < TSLPRM_TOTAL_BANKS;idx_bk++)
+ {
+ if (TSL_PXS_EPCC_CalibrateBank(idx_bk) > 0)
+ {
+ retval = TSL_STATUS_ERROR;
+ }
+ }
+#if TSLPRM_PXS_LOW_POWER_MODE > 0
+ setPXSLowPower();
+#else
+ resetPXSLowPower();
+#endif
+
+ return retval;
+
+}
+
+/**
+ * @brief Calibrate the CS for a selected acquisition bank
+ * @param[in] idx_bk Index of the bank
+ * @retval Number of Receivers not correctly calibrated
+ */
+void TSL_PXS_CS_CalibrateBank(TSL_tIndex_T idx_bk)
+{
+ TSL_tIndex_T idx_ch;
+ uint8_t currentCS = 24;
+ uint8_t CS_delta = 4; // Value to add/substract to/from the current CS
+ CONST TSL_Bank_T *bank;
+ CONST uint16_t targetCount = TSLPRM_KEY_TARGET_REFERENCE / TSLPRM_KEY_TARGET_ATTENUATION;
+ CONST uint16_t targetCountError = targetCount >> 3;
+ bool CalibrationDone = FALSE;
+ uint16_t measSup[TSLPRM_HIGH_CHANNEL_NB+1];
+ uint16_t measInf[TSLPRM_HIGH_CHANNEL_NB+1];
+ uint8_t CSsup[TSLPRM_HIGH_CHANNEL_NB+1];
+ uint8_t CSinf[TSLPRM_HIGH_CHANNEL_NB+1];
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+#if TSLPRM_USE_ACQ_INTERRUPT == 0
+ enablePXSInterrupts(PXS_CR2_EOCITEN);
+#endif
+
+ bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ resetPXSLowPower();
+ TSL_acq_BankConfig(idx_bk);
+
+ PXS->MAXR = TSLPRM_KEY_TARGET_REFERENCE;
+
+ WFE->CR1 |= WFE_CR1_PXS_EV;
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ PXS->RXEPCCSELR[idx_ch] = 0;
+ PXS->RXCSSELR[idx_ch] = currentCS;
+ CSsup[idx_ch] = 0;
+ CSinf[idx_ch] = 0;
+ measInf[idx_ch] = 0;
+ measSup[idx_ch] = 0xFFFF;
+
+ }
+ do
+ {
+ startPXSAcquisition();
+ wfe();
+ clearPXS_ISR_EOCF;
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
+ {
+ if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > targetCount - targetCountError))
+ {
+ PXS->RXCSSELR[idx_ch] -= 8;
+ }
+ }
+ }
+ currentCS -= 8;
+ }
+ while (currentCS);
+
+
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ PXS->RXCSSELR[idx_ch] += CS_delta;
+ }
+
+ do
+ {
+ CS_delta >>= 1;
+ if ((CS_delta == 0) && (CalibrationDone == FALSE))
+ {
+ CalibrationDone = TRUE;
+ CS_delta = 1;
+ }
+
+ startPXSAcquisition();
+ wfe();
+ clearPXS_ISR_EOCF;
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
+ {
+ if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > targetCount))
+ {
+ measSup[idx_ch] = PXS->RXCNTR[idx_ch];
+ CSsup[idx_ch] = PXS->RXCSSELR[idx_ch];
+ PXS->RXCSSELR[idx_ch] -= CS_delta;
+ }
+ else //if (PXS->RXCNTR[idx_ch] < targetCount )
+ {
+ measInf[idx_ch] = PXS->RXCNTR[idx_ch];
+ CSinf[idx_ch] = PXS->RXCSSELR[idx_ch];
+ PXS->RXCSSELR[idx_ch] += CS_delta;
+ }
+// else
+// {
+ // Do nothing (MISRA requirement)
+// }
+ }
+ }
+ }
+ while ((CalibrationDone == FALSE) || (CS_delta != 0));
+
+
+ // Restore configuration
+#if TSLPRM_ACQ_MAX > 0
+ PXS->MAXR = TSLPRM_ACQ_MAX;
+#else
+ PXS->MAXENR = 0;
+#endif
+
+ WFE->CR1 &= (uint8_t)~WFE_CR1_PXS_EV;
+#if TSLPRM_USE_ACQ_INTERRUPT == 0
+ disablePXSInterrupts(PXS_CR2_EOCITEN);
+#endif
+
+ // Store the CS
+ for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
+ {
+ if ((measSup[idx_ch] == 0) || ((measSup[idx_ch] - targetCount) > (targetCount - measInf[idx_ch])))
+ {
+ PXS_BankConfig[idx_bk].CSSEL[idx_ch] = CSinf[idx_ch];
+ }
+ else
+ {
+ PXS_BankConfig[idx_bk].CSSEL[idx_ch] = CSsup[idx_ch];
+ }
+ }
+}
+
+
+/**
+ * @brief Calibrate the EPCC for a selected acquisition bank
+ * @param[in] idx_bk Index of the bank
+ * @retval Number Number of Receivers not correctly calibrated
+ */
+int8_t TSL_PXS_EPCC_CalibrateBank(TSL_tIndex_T idx_bk)
+{
+ TSL_tIndex_T idx_ch;
+ uint8_t currentEPCC, trial, goodEPCC = 0;
+ uint8_t EPCCtoCompute = 0; // Used to define if all the EPCC have their final value
+ uint8_t EPCC_delta = EPCC_INIT_VALUE; // Value to add/substract to/from the current EPCC
+ CONST TSL_Bank_T *bank;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+#if TSLPRM_USE_ACQ_INTERRUPT == 0
+ enablePXSInterrupts(PXS_CR2_EOCITEN);
+#endif
+
+ bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ resetPXSLowPower();
+ TSL_acq_BankConfig(idx_bk);
+
+ PXS->MAXR = 2 * TSLPRM_KEY_TARGET_REFERENCE;
+
+ WFE->CR1 |= WFE_CR1_PXS_EV;
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ PXS->RXEPCCSELR[idx_ch] = EPCC_delta;
+ if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
+ {
+ EPCCtoCompute++;
+ }
+ }
+ do
+ {
+ EPCC_delta >>= 1;
+ startPXSAcquisition();
+ wfe();
+ clearPXS_ISR_EOCF;
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
+ {
+ if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > TSLPRM_KEY_TARGET_REFERENCE))
+ {
+ PXS->RXEPCCSELR[idx_ch] -= EPCC_delta;
+ }
+ else if (PXS->RXCNTR[idx_ch] < TSLPRM_KEY_TARGET_REFERENCE)
+ {
+ PXS->RXEPCCSELR[idx_ch] += EPCC_delta;
+ }
+ else
+ {
+ // Do nothing (MISRA requirement)
+ }
+ }
+ }
+ }
+ while (EPCC_delta >= 1);
+ // Second pass to fine-tune
+ trial = TSLPRM_PXS_EPCC_FINE_TUNING_ITERATION;
+ do
+ {
+ startPXSAcquisition();
+ goodEPCC = 0; // Reset the goodEPCC variable
+ wfe();
+ clearPXS_ISR_EOCF;
+ for (idx_ch = 0; idx_ch <= TSLPRM_HIGH_CHANNEL_NB; idx_ch++)
+ {
+ if (bank->msk_channels & (uint16_t)((uint16_t)1 << idx_ch))
+ {
+ currentEPCC = PXS->RXEPCCSELR[idx_ch]; //this affectation allow to avoid computation of the structure address
+ if (!(PXS->RXSR & (uint16_t)((uint16_t)1 << idx_ch)) || (PXS->RXCNTR[idx_ch] > (TSLPRM_KEY_TARGET_REFERENCE + TSLPRM_KEY_TARGET_REFERENCE_ERROR)))
+ {
+ if (currentEPCC > 0)
+ {
+ if ((currentEPCC & 0x07) != 0)
+ {
+ currentEPCC--;
+ }
+ else
+ {
+ currentEPCC -= 3; // This is due to the non linearity of the EPCC
+ }
+ }
+ }
+ else if (PXS->RXCNTR[idx_ch] < (TSLPRM_KEY_TARGET_REFERENCE - TSLPRM_KEY_TARGET_REFERENCE_ERROR))
+ {
+ if (currentEPCC < 0xFF)
+ {
+ if ((currentEPCC & 0x07) != 0x07)
+ {
+ currentEPCC++;
+ }
+ else
+ {
+ currentEPCC += 2; // This is due to the non linearity of the EPCC
+ }
+ }
+ else // Invert the change in case the sorting is not reliable
+ {
+ currentEPCC--;
+ }
+ }
+ else
+ {
+ goodEPCC++;
+ }
+ PXS->RXEPCCSELR[idx_ch] = currentEPCC;
+ }
+ }
+ trial--;
+ }
+ while ((goodEPCC < EPCCtoCompute) && (trial));
+
+ // Restore configuration
+#if TSLPRM_ACQ_MAX > 0
+ PXS->MAXR = TSLPRM_ACQ_MAX;
+#else
+ PXS->MAXENR = 0;
+#endif
+
+ WFE->CR1 &= (uint8_t)~WFE_CR1_PXS_EV;
+#if TSLPRM_USE_ACQ_INTERRUPT == 0
+ disablePXSInterrupts(PXS_CR2_EOCITEN);
+#endif
+
+ // Store the EPCC
+ for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
+ {
+ PXS_BankConfig[idx_bk].EPCCSEL[idx_ch] = PXS->RXEPCCSELR[idx_ch];
+ }
+
+ return((int8_t)(EPCCtoCompute - goodEPCC));
+}
+
+
+#if TSLPRM_USE_ZONE > 0
+/**
+ * @brief Calibrate the EPCC for a set of acquisition banks.
+ * @param[in] zone Set of banks to calibrate the EPCC
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_PXS_EPCC_CalibrateZone(CONST TSL_Zone_T *zone)
+{
+ uint16_t idx_bk;
+ TSL_Status_enum_T retval = TSL_STATUS_OK;
+ for (idx_bk = 0; idx_bk < zone->NbBanks; idx_bk++)
+ {
+ if (TSL_PXS_EPCC_CalibrateBank(zone->BankIndex[idx_bk]) > 0)
+ {
+ retval = TSL_STATUS_ERROR;
+ }
+ }
+ return(retval);
+}
+#endif
+
+
+/**
+ * @brief Test the reference and update the EPCC/CS if needed
+ * @param[in] pCh pointer on the channel data information
+ * @retval Result
+ */
+TSL_Bool_enum_T TSL_acq_TestReferenceOutOfRange(TSL_ChannelData_T *pCh)
+{
+ uint16_t reference, target_error = 0;
+ TSL_Bool_enum_T result = TSL_FALSE;
+
+ if (pCh->Flags.EPCCStatus != TSL_EPCC_STATUS_LOCKED)
+ {
+ reference = pCh->Ref;
+#if TSLPRM_TOTAL_TKEYS > 0
+ if (TSL_Globals.This_Obj->Type & TSL_OBJ_TYPE_TKEY_MASK)
+ {
+ target_error = TSLPRM_TOUCHKEY_REFERENCE_RANGE;
+ }
+#endif
+
+#if TSLPRM_TOTAL_LNRTS > 0
+ if (TSL_Globals.This_Obj->Type & TSL_OBJ_TYPE_LINROT_MASK)
+ {
+ target_error = TSLPRM_LINROT_REFERENCE_RANGE;
+ }
+#endif
+ if ((reference != 0) && ((reference > (TSLPRM_KEY_TARGET_REFERENCE + target_error)) || (reference < (TSLPRM_KEY_TARGET_REFERENCE - target_error))))
+ {
+ if (reference < (TSLPRM_KEY_TARGET_REFERENCE - target_error))
+ {
+ pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_INCREASE;
+ }
+ else if (reference > (TSLPRM_KEY_TARGET_REFERENCE + target_error))
+ {
+ pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_DECREASE;
+ }
+ else
+ {
+ // Do nothing (MISRA requirement)
+ }
+ result = TSL_TRUE;
+ }
+ }
+ return(result);
+}
+
+/**
+ * @brief Test if the measure has crossed the reference target
+ * @param[in] pCh Pointer to the channel Data under test
+ * @param[in] new_meas Measure of the last acquisition on this channel
+ * @retval Result Result of the test
+ */
+TSL_Bool_enum_T TSL_acq_TestFirstReferenceIsValid(TSL_ChannelData_T *pCh, TSL_tMeas_T new_meas)
+{
+ TSL_Bool_enum_T result = TSL_TRUE;
+ TSL_EPCCStatus_enum_T EPCCStatus;
+
+ EPCCStatus = pCh->Flags.EPCCStatus;
+ if (EPCCStatus & TSL_EPCC_CHANGE_MASK)
+ {
+ // If the previous reference and the new one are on each side of the reference target
+ // the EPCC is no more tested and the calibration continues.
+ if (((EPCCStatus == TSL_EPCC_STATUS_INCREASE) && (new_meas >= TSLPRM_KEY_TARGET_REFERENCE))
+ || ((EPCCStatus == TSL_EPCC_STATUS_DECREASE) && (new_meas <= TSLPRM_KEY_TARGET_REFERENCE)))
+ {
+ pCh->Flags.EPCCStatus = TSL_EPCC_STATUS_UNLOCKED;
+ }
+ else
+ {
+ result = TSL_FALSE;
+ }
+ }
+
+ return(result);
+}
+
+
+/**
+ * @brief Increase or decrease the CS value
+ * @param[in] pCSSEL Address of the CS to be modified
+ * @param[in] change Define if the Cs must be increased or decreased
+ * @retval None
+ */
+void TSL_acq_UpdateCS(uint8_t *pCSSEL, TSL_EPCCStatus_enum_T change)
+{
+ uint16_t indexCS;
+
+ assert_param(IS_EPCC_STATUS_OK(change));
+ assert_param(IS_CSSEL_OK(*pCSSEL));
+
+ if (*pCSSEL > CS_MIDDLE_VALUE)
+ {
+ indexCS = (CS_MIDDLE_VALUE - 1);
+ }
+ else
+ {
+ indexCS = 0;
+ }
+ while ((PXS_CSsorting[indexCS] != *pCSSEL) && (indexCS < CS_MAX_VALUE))
+ {
+ indexCS++;
+ }
+ if (change == TSL_EPCC_STATUS_INCREASE)
+ {
+ *pCSSEL = PXS_CSsorting[indexCS + 1];
+ }
+ else
+ {
+ *pCSSEL = PXS_CSsorting[indexCS - 1];
+ }
+}
+
+
+/**
+ * @brief Configures a Bank.
+ * @param[in] idx_bk Index of the Bank to configure
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankConfig(TSL_tIndex_T idx_bk)
+{
+ TSL_Status_enum_T retval = TSL_STATUS_OK;
+ uint16_t idx_ch;
+ TSL_ChannelFlags_T flags;
+ CONST TSL_Bank_T *bank = &(TSL_Globals.Bank_Array[idx_bk]);
+ CONST TSL_ChannelSrc_T *pchSrc = bank->p_chSrc;
+ CONST TSL_ChannelDest_T *pchDest = bank->p_chDest;
+ TSL_tMaskRX enabledRX = 0;
+ uint8_t *pEPCCSEL, *pCSSEL;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_BANK_INDEX_OK(idx_bk));
+
+ TSL_Globals.This_Bank = idx_bk;
+
+ selectPXSRxGroup(bank->msk_group);
+ for (idx_ch = 0;idx_ch < bank->NbChannels;idx_ch++)
+ {
+ flags = bank->p_chData[pchDest->IdxDest].Flags;
+ if (flags.ObjStatus == TSL_OBJ_STATUS_ON)
+ {
+ enabledRX |= (1 << pchSrc->IdxSrc);
+ if (flags.EPCCStatus & TSL_EPCC_CHANGE_MASK)
+ {
+ pEPCCSEL = &PXS_BankConfig[idx_bk].EPCCSEL[pchSrc->IdxSrc];
+ if (flags.EPCCStatus == TSL_EPCC_STATUS_INCREASE)
+ {
+ if ((*pEPCCSEL) < 0xFF)
+ {
+ if (((*pEPCCSEL) & 0x07) != 0x07)
+ {
+ (*pEPCCSEL)++;
+ }
+ else
+ {
+ if ((*pEPCCSEL) < 0xFE)
+ {
+ (*pEPCCSEL) += 2; // This is due to the non linearity of the PCC
+ }
+ else
+ {
+ (*pEPCCSEL)++;
+ }
+ }
+
+ }
+ else
+ {
+ pCSSEL = &PXS_BankConfig[idx_bk].CSSEL[pchSrc->IdxSrc];
+ if (*pCSSEL < 0x1F)
+ {
+ TSL_acq_UpdateCS(pCSSEL, TSL_EPCC_STATUS_INCREASE);
+ }
+ else
+ {}
+ }
+ }
+ else
+ {
+ if ((*pEPCCSEL) > 0)
+ {
+ if (((*pEPCCSEL) & 0x07) != 0)
+ {
+ (*pEPCCSEL)--;
+ }
+ else
+ {
+ if ((*pEPCCSEL) > 3)
+ {
+ (*pEPCCSEL) -= 3; // This is due to the non linearity of the PCC
+ }
+ else
+ {
+ (*pEPCCSEL)--;
+ }
+ }
+ }
+ else
+ {
+ pCSSEL = &PXS_BankConfig[idx_bk].CSSEL[pchSrc->IdxSrc];
+ if (*pCSSEL > 0)
+ {
+ TSL_acq_UpdateCS(pCSSEL, TSL_EPCC_STATUS_DECREASE);
+ }
+ else
+ {}
+ }
+ }
+ }
+ }
+
+ // Next channel
+ pchSrc++;
+ pchDest++;
+ }
+
+ // The two following loops are more efficient than the two instructions in the same loop
+ for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
+ {
+ PXS->RXCSSELR[idx_ch] = PXS_BankConfig[idx_bk].CSSEL[idx_ch];
+ }
+ for (idx_ch = 0;idx_ch <= TSLPRM_HIGH_CHANNEL_NB;idx_ch++)
+ {
+ PXS->RXEPCCSELR[idx_ch] = PXS_BankConfig[idx_bk].EPCCSEL[idx_ch];
+ }
+
+ PXS->TXENR = bank->msk_TX; // Enable the Tx selected (if any)
+ PXS->RXCR1 = bank->msk_channels; // Configure the Rx and the Tx function modes
+
+ // Enable the Rx which are not disabled including the potential Rx configured as Tx
+ PXS->RXENR = bank->msk_RXEN & ((uint16_t)(~bank->msk_channels) | enabledRX);
+
+ if (enabledRX == 0)
+ {
+ retval = TSL_STATUS_ERROR;
+ }
+
+ return(retval);
+
+}
+
+
+/**
+ * @brief Test if EPCC are changing
+ * @param[in] pCh Channel to be processed
+ * @retval bool Test result
+ */
+TSL_Bool_enum_T TSL_acq_UseFilter(TSL_ChannelData_T *pCh)
+{
+ if (pCh->Flags.EPCCStatus & TSL_EPCC_CHANGE_MASK)
+ {
+ return (TSL_FALSE);
+ }
+ else
+ {
+ return(TSL_TRUE);
+ }
+}
+
+
+/**
+ * @brief Start acquisition on a previously configured bank
+ * @param None
+ * @retval None
+ */
+void TSL_acq_BankStartAcq(void)
+{
+ // Start acquisition
+ startPXSAcquisition();
+}
+
+
+/**
+ * @brief Wait end of acquisition
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_acq_BankWaitEOC(void)
+{
+ TSL_Status_enum_T retval = TSL_STATUS_BUSY;
+
+ if (checkPXSInterruptStatusFlag(PXS_ISR_EOCF)) // Check EOC flag
+ {
+ if (PXS->RXSR != TSL_Globals.Bank_Array[TSL_Globals.This_Bank].msk_channels) // Check MCE flag
+ {
+ retval = TSL_STATUS_ERROR;
+ }
+ else
+ {
+ retval = TSL_STATUS_OK;
+ }
+ }
+
+ return retval;
+}
+
+
+/**
+ * @brief Check noise detection
+ * @param None
+ * @retval Status
+ */
+TSL_AcqStatus_enum_T TSL_acq_CheckNoise(void)
+{
+ TSL_AcqStatus_enum_T retval = TSL_ACQ_STATUS_OK;
+#if TSLPRM_PXS_RF_DETECTION > 0
+ if (checkPXSInterruptStatusFlag(PXS_ISR_NOISEDETF) == PXS_ISR_NOISEDETF)
+ {
+ retval = TSL_ACQ_STATUS_NOISE;
+ }
+#endif
+ return(retval);
+}
+
+
+/**
+ * @brief Return the current measure
+ * @param[in] index Index of the measure source
+ * @retval Measure
+ */
+TSL_tMeas_T TSL_acq_GetMeas(TSL_tIndexSrc_T index)
+{
+ uint16_t CurrentReceiver;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_SOURCE_INDEX_OK(index));
+
+ CurrentReceiver = (uint16_t)(((uint16_t)1) << index);
+
+ if (PXS->RXSR & CurrentReceiver)
+ {
+ return(PXS->RXCNTR[index]);
+ }
+ else
+ {
+ return(MAX_MEASURE);
+ }
+}
+
+
+/**
+ * @brief Process the PXS Interrupt routine
+ * @param None
+ * @retval None
+ */
+INTERRUPT_HANDLER(TSL_acq_ProcessIT, 2)
+{
+ clearPXS_ISR_EOCF;
+
+ TSL_acq_BankGetResult(TSL_Globals.This_Bank, 0, 0); // No noise filter
+
+#if TSLPRM_USE_ZONE > 0
+ if ((TSL_Globals.This_Zone == 0) || (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks))
+ {
+ CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing
+ PXS->RXENR = 0; // To reduce consumption
+ PXS->TXENR = 0; // To reduce consumption
+ TSL_Globals.This_Bank = 0;
+ }
+ else
+ {
+ if (TSL_acq_ZoneConfig(TSL_Globals.This_Zone, TSL_Globals.Index_In_This_Zone) != TSL_STATUS_ERROR)
+ {
+ // Start Bank acquisition
+ TSL_acq_BankStartAcq();
+#if TSLPRM_PXS_LOW_POWER_MODE > 0
+ if (TSL_Globals.Index_In_This_Zone >= TSL_Globals.This_Zone->NbBanks)
+ {
+ setPXSLowPower();
+ }
+#endif
+ }
+
+ }
+#else
+ CFG->GCR &= (uint8_t)(~CFG_GCR_AL); // Reset Activation level to resume main processing
+ PXS->RXENR = 0; // To reduce consumption
+ PXS->TXENR = 0; // To reduce consumption
+#endif
+}
+
+
+#if defined(__ICCSTM8__)
+#pragma optimize=low
+#endif
+/**
+ * @brief Software delay (private routine)
+ * @param val Wait delay
+ * @retval None
+ */
+void SoftDelay(uint16_t val)
+{
+ __IO uint16_t idx;
+ for (idx = val; idx > 0; idx--)
+ {
+ nop();
+ }
+}
+
+/******************* (C) COPYRIGHT 2014 STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_dxs.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_dxs.c
new file mode 100644
index 0000000..c721b80
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_dxs.c
@@ -0,0 +1,181 @@
+/**
+ ******************************************************************************
+ * @file tsl_dxs.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the
+ * Detection Exclusion System (DxS) algorithm.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_dxs.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+#define THIS_OBJ_TYPE TSL_Globals.This_Obj->Type
+
+#define THIS_TKEY TSL_Globals.This_TKey
+#define THIS_TKEY_STATEID TSL_Globals.This_TKey->p_Data->StateId
+#define THIS_TKEY_DXSLOCK TSL_Globals.This_TKey->p_Data->DxSLock
+#define THIS_TKEY_CHANGE TSL_Globals.This_TKey->p_Data->Change
+
+#define THIS_LINROT TSL_Globals.This_LinRot
+#define THIS_LINROT_STATEID TSL_Globals.This_LinRot->p_Data->StateId
+#define THIS_LINROT_DXSLOCK TSL_Globals.This_LinRot->p_Data->DxSLock
+#define THIS_LINROT_CHANGE TSL_Globals.This_LinRot->p_Data->Change
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Detection Exclusion System on the first object in detect state
+ * @param[in] objgrp Pointer to the objects group to process
+ * @retval None
+ */
+void TSL_dxs_FirstObj(CONST TSL_ObjectGroup_T *objgrp)
+{
+#if TSLPRM_USE_DXS > 0
+
+ TSL_tIndex_T idx_obj;
+ CONST TSL_Object_T *pobj;
+ CONST TSL_Object_T *pobj_candidate = 0; // Candidate object for being in Detect state + DxSLock flag
+ TSL_tIndex_T obj_locked = 0; // Object with Lock flag
+
+ // Exit if no object are in DETECT state.
+ if ((objgrp->StateMask & TSL_STATE_DETECT_BIT_MASK) == 0)
+ {
+ return;
+ }
+
+ pobj = objgrp->p_Obj; // First object in the group
+
+ // Process all objects
+ for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++)
+ {
+
+ // Assign global object
+ TSL_obj_SetGlobalObj(pobj);
+
+ //--------------------------------------------------------------------------
+#if TSLPRM_TOTAL_TKEYS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB))
+ {
+ if (THIS_TKEY_STATEID == TSL_STATEID_DETECT)
+ {
+ if (THIS_TKEY_DXSLOCK == TSL_TRUE)
+ {
+ if (!obj_locked)
+ {
+ obj_locked = 1;
+ pobj_candidate = 0;
+ }
+ else
+ {
+ THIS_TKEY_STATEID = TSL_STATEID_TOUCH;
+ THIS_TKEY_CHANGE = TSL_STATE_CHANGED;
+ }
+ }
+ else
+ {
+ THIS_TKEY_STATEID = TSL_STATEID_TOUCH;
+ THIS_TKEY_CHANGE = TSL_STATE_CHANGED;
+ if ((!pobj_candidate) && (!obj_locked))
+ {
+ pobj_candidate = pobj;
+ }
+ }
+ }
+ }
+#endif // TSLPRM_TOTAL_TKEYS > 0
+
+ //--------------------------------------------------------------------------
+#if TSLPRM_TOTAL_LNRTS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) ||
+ (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB))
+ {
+ if (THIS_LINROT_STATEID == TSL_STATEID_DETECT)
+ {
+ if (THIS_LINROT_DXSLOCK == TSL_TRUE)
+ {
+ if (!obj_locked)
+ {
+ obj_locked = 1;
+ pobj_candidate = 0;
+ }
+ else
+ {
+ THIS_LINROT_STATEID = TSL_STATEID_TOUCH;
+ THIS_LINROT_CHANGE = TSL_STATE_CHANGED;
+ }
+ }
+ else
+ {
+ THIS_LINROT_STATEID = TSL_STATEID_TOUCH;
+ THIS_LINROT_CHANGE = TSL_STATE_CHANGED;
+ if ((!pobj_candidate) && (!obj_locked))
+ {
+ pobj_candidate = pobj;
+ }
+ }
+ }
+ }
+#endif // TSLPRM_TOTAL_LNRTS > 0
+
+ pobj++; // Next object
+
+ } // // for all objects
+
+ // Change state from TOUCH to DETECT + DxSLock flag on the candidate object only
+ if (pobj_candidate)
+ {
+
+ // Assign global object
+ TSL_obj_SetGlobalObj(pobj_candidate);
+
+#if TSLPRM_TOTAL_TKEYS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB))
+ {
+ THIS_TKEY_STATEID = TSL_STATEID_DETECT;
+ THIS_TKEY_CHANGE = TSL_STATE_CHANGED;
+ THIS_TKEY_DXSLOCK = TSL_TRUE;
+ }
+#endif // TSLPRM_TOTAL_TKEYS > 0
+
+#if TSLPRM_TOTAL_LNRTS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) ||
+ (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB))
+ {
+ THIS_LINROT_STATEID = TSL_STATEID_DETECT;
+ THIS_LINROT_CHANGE = TSL_STATE_CHANGED;
+ THIS_LINROT_DXSLOCK = TSL_TRUE;
+ }
+#endif // TSLPRM_TOTAL_LNRTS > 0
+
+ }
+
+#endif // TSLPRM_USE_DXS > 0
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_ecs.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_ecs.c
new file mode 100644
index 0000000..39052fd
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_ecs.c
@@ -0,0 +1,332 @@
+/**
+ ******************************************************************************
+ * @file tsl_ecs.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the ECS.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_ecs.h"
+#include "tsl_globals.h"
+#include "stm32f0xx_conf.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+#define THIS_OBJ_TYPE TSL_Globals.This_Obj->Type
+#define THIS_TKEY_REF TSL_Globals.This_TKey->p_ChD->Ref
+#define THIS_TKEY_REFREST TSL_Globals.This_TKey->p_ChD->RefRest
+#define THIS_TKEY_DELTA TSL_Globals.This_TKey->p_ChD->Delta
+#define THIS_TKEY_STATEID TSL_Globals.This_TKey->p_Data->StateId
+
+#define THIS_LINROT_STATEID TSL_Globals.This_LinRot->p_Data->StateId
+#define THIS_LINROT_NB_CHANNELS TSL_Globals.This_LinRot->NbChannels
+
+/* Private macros ------------------------------------------------------------*/
+#define IS_K_COEFF_OK(COEFF) (((COEFF) == 0) || (((COEFF) > 0) && ((COEFF) < 256)))
+#define IS_POINTER_INITIALIZED(POINTER) ((POINTER) != 0)
+
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Calculate the K coefficient
+ * @param[in] objgrp Pointer to the objects group to process
+ * @param[in] k_slow K coefficient when objects have different delta variation
+ * @param[in] k_fast K coefficient when objects have the same delta variation
+ * @retval K coefficient (slow or fast)
+ */
+TSL_tKCoeff_T TSL_ecs_CalcK(TSL_ObjectGroup_T *objgrp, TSL_tKCoeff_T k_slow, TSL_tKCoeff_T k_fast)
+{
+ TSL_tIndex_T idx_obj; // Index of current object
+ TSL_tIndex_T idx_ch; // Index of current channel
+ TSL_tDelta_T ldelta = 0; // Temporary delta
+ TSL_tDelta_T ECS_Fast_Enable = 1;
+ TSL_tDelta_T ECS_Fast_Direction = 0;
+ CONST TSL_Object_T *pobj;
+ TSL_tKCoeff_T retval = k_slow;
+ TSL_tNb_T nb_channels = 0; // Number of channels inside current object
+ TSL_ChannelData_T *p_Ch = 0;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_K_COEFF_OK(k_slow));
+ assert_param(IS_K_COEFF_OK(k_fast));
+
+ pobj = objgrp->p_Obj; // First object in the group
+
+ // Process all objects
+ for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++)
+ {
+
+ // Assign global object
+ TSL_obj_SetGlobalObj(pobj);
+
+#if TSLPRM_TOTAL_TKEYS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB))
+ {
+ // Ignore object if not in Release state (OFF or Error in this case)
+ if (THIS_TKEY_STATEID != TSL_STATEID_RELEASE)
+ {
+ pobj++; // Next object
+ continue; // Stop processing of current object
+ }
+ nb_channels = 1;
+ p_Ch = TSL_Globals.This_TKey->p_ChD;
+ }
+#endif
+
+#if TSLPRM_TOTAL_LNRTS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) ||
+ (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB))
+ {
+ // Ignore object if not in Release state (OFF or Error in this case)
+ if (THIS_LINROT_STATEID != TSL_STATEID_RELEASE)
+ {
+ pobj++; // Next object
+ continue; // Stop processing of current object
+ }
+ nb_channels = THIS_LINROT_NB_CHANNELS;
+ p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ }
+#endif
+
+ // Check channel pointer variable (if USE_FULL_ASSERT is defined)
+ assert_param(IS_POINTER_INITIALIZED(p_Ch));
+
+ // Check all channels of current object
+ for (idx_ch = 0; idx_ch < nb_channels; idx_ch++)
+ {
+
+ ldelta = p_Ch->Delta;
+
+ // Check delta
+ if (ldelta == 0) // No Fast ECS !
+ {
+ ECS_Fast_Enable = 0;
+ }
+ else
+ {
+ if (ldelta < 0)
+ {
+ if (ECS_Fast_Direction > 0) // No Fast ECS !
+ {
+ ECS_Fast_Enable = 0;
+ }
+ else
+ {
+ ECS_Fast_Direction = -1;
+ }
+ }
+ else
+ {
+ if (ECS_Fast_Direction < 0) // No Fast ECS !
+ {
+ ECS_Fast_Enable = 0;
+ }
+ else
+ {
+ ECS_Fast_Direction = 1;
+ }
+ }
+ }
+
+ p_Ch++; // Next channel
+
+ } // for all channels of current object
+
+ pobj++; // Next object
+
+ } // for all objects
+
+ // Assign K fast following Delta variations
+ if (ECS_Fast_Enable)
+ {
+ retval = k_fast;
+ }
+
+ return retval;
+}
+
+
+/**
+ * @brief Calculate the new Reference on a group of objects
+ * @param[in] objgrp Pointer to the objects group to process
+ * @param[in] Kcoeff K coefficient to apply
+ * @retval None
+ */
+void TSL_ecs_ProcessK(TSL_ObjectGroup_T *objgrp, TSL_tKCoeff_T Kcoeff)
+{
+ TSL_tIndex_T idx_obj; // Index of current object
+ TSL_tIndex_T idx_ch; // Index of current channel
+ CONST TSL_Object_T *pobj;
+ TSL_tKCoeff_T Kcoeff_comp;
+ uint32_t ECS_meas;
+ uint32_t ECS_ref;
+ TSL_tNb_T nb_channels = 0; // Number of channels inside current object
+ TSL_ChannelData_T *p_Ch = 0;
+ void(*pFunc_SetStateCalibration)(TSL_tCounter_T delay) = 0;
+
+ // Check parameters (if USE_FULL_ASSERT is defined)
+ assert_param(IS_K_COEFF_OK(Kcoeff));
+
+ pobj = objgrp->p_Obj; // First object in the group
+
+ // Calculate the K coefficient complement
+ Kcoeff_comp = (0xFF ^ Kcoeff) + 1;
+
+ // Process all objects
+ for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++)
+ {
+
+ // Assign global object
+ TSL_obj_SetGlobalObj(pobj);
+
+#if TSLPRM_TOTAL_TKEYS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEY) || (THIS_OBJ_TYPE == TSL_OBJ_TOUCHKEYB))
+ {
+ // Ignore object if not in Release state (OFF or Error in this case)
+ if (THIS_TKEY_STATEID != TSL_STATEID_RELEASE)
+ {
+ pobj++; // Next object
+ continue; // Stop processing of current object
+ }
+ nb_channels = 1;
+ p_Ch = TSL_Globals.This_TKey->p_ChD;
+ pFunc_SetStateCalibration = &TSL_tkey_SetStateCalibration;
+ }
+#endif
+
+#if TSLPRM_TOTAL_LNRTS > 0
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB) ||
+ (THIS_OBJ_TYPE == TSL_OBJ_ROTARY) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARYB))
+ {
+ // Ignore object if not in Release state (OFF or Error in this case)
+ if (THIS_LINROT_STATEID != TSL_STATEID_RELEASE)
+ {
+ pobj++; // Next object
+ continue; // Stop processing of current object
+ }
+ nb_channels = THIS_LINROT_NB_CHANNELS;
+ p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ pFunc_SetStateCalibration = &TSL_linrot_SetStateCalibration;
+ }
+#endif
+
+ // Check channel pointer variable (if USE_FULL_ASSERT is defined)
+ assert_param(IS_POINTER_INITIALIZED(p_Ch));
+
+ // Calculate the new reference + rest for all channels
+ for (idx_ch = 0; idx_ch < nb_channels; idx_ch++)
+ {
+ ECS_meas = TSL_acq_ComputeMeas(p_Ch->Ref, p_Ch->Delta);
+ ECS_meas <<= 8;
+
+ ECS_ref = (uint32_t)(p_Ch->Ref);
+ ECS_ref <<= 8;
+ ECS_ref += p_Ch->RefRest;
+ ECS_ref *= Kcoeff_comp;
+ ECS_ref += (Kcoeff * ECS_meas);
+
+ p_Ch->RefRest = (TSL_tRefRest_T)((ECS_ref >> 8) & 0xFF);
+ p_Ch->Ref = (TSL_tRef_T)(ECS_ref >> 16);
+
+ // Go in Calibration state in the Reference is out of Range
+ if (TSL_acq_TestReferenceOutOfRange(p_Ch) == TSL_TRUE)
+ {
+ pFunc_SetStateCalibration(0);
+ }
+
+ p_Ch++; // Next channel
+ }
+
+ pobj++; // Next object
+
+ } // for all objects
+
+}
+
+
+/**
+ * @brief ECS algorithm on a group of objects
+ * The ECS is only performed if at least an object is in Release state and
+ * if no objects are in active states (Prox, Detect or Touch)
+ * An optional delay is added after the ECS condition (all sensors in Release state) is reached.
+ * @param[in] objgrp Pointer to the objects group to process
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_ecs_Process(TSL_ObjectGroup_T *objgrp)
+{
+ TSL_tKCoeff_T MyKcoeff;
+ TSL_Status_enum_T retval;
+
+ if ((objgrp->StateMask & TSL_STATE_RELEASE_BIT_MASK) && !(objgrp->StateMask & TSL_STATEMASK_ACTIVE))
+ {
+#if TSLPRM_ECS_DELAY > 0
+ if (!objgrp->ECS_wait)
+ {
+ disableInterrupts();
+ objgrp->ECS_start_time = TSL_Globals.Tick_ms; // Save the current time
+ enableInterrupts();
+ objgrp->ECS_wait = 1;
+ objgrp->ECS_exec = 0;
+ }
+#else
+ objgrp->ECS_exec = 1;
+#endif
+ }
+ else
+ {
+#if TSLPRM_ECS_DELAY > 0
+ objgrp->ECS_wait = 0;
+#endif
+ objgrp->ECS_exec = 0;
+ }
+
+#if TSLPRM_ECS_DELAY > 0
+ if (objgrp->ECS_wait && (!objgrp->ECS_exec))
+ {
+ // Execute the ECS only when the delay has elapsed
+ if (TSL_tim_CheckDelay_ms(TSLPRM_ECS_DELAY, &objgrp->ECS_start_time) == TSL_STATUS_OK)
+ {
+ objgrp->ECS_exec = 1;
+ }
+ }
+#endif
+
+ if (objgrp->ECS_exec)
+ {
+ // Calculate the K coefficient
+ MyKcoeff = TSL_ecs_CalcK(objgrp, TSLPRM_ECS_K_SLOW, TSLPRM_ECS_K_FAST);
+ // Process the objects
+ TSL_ecs_ProcessK(objgrp, MyKcoeff);
+ retval = TSL_STATUS_OK;
+ }
+ else
+ {
+ retval = TSL_STATUS_BUSY;
+ }
+
+ return retval;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_filter.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_filter.c
new file mode 100644
index 0000000..8357154
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_filter.c
@@ -0,0 +1,137 @@
+/**
+ ******************************************************************************
+ * @file tsl_filter.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the signal or delta filters.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_filter.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/* Noise Filter description
+ ------------------------
+
+The noise filter is a first order IRR digital filter based on the following formula:
+
+S(n) = (1-k).S(n-1)+ k.N(n)
+
+S(n) : sample number n of the filtered signal
+N(n) : sample number n of the raw signal
+k : filter coefficient parameter in [0..1]
+
+The filter sampling rate is the acquisition rate.
+
+In order to optimize the implementation in the firmware, the above formula is
+modified in order to have only one multiply operation:
+
+S(n) = S(n-1) + k.(N(n) - S(n-1))
+
+Additionally, we use k = K/256 with K an unsigned 8-bit integer.
+
+The K is given by the ACQ_FILTER_COEFF constant.
+
+S(n) = S(n-1) + K.(N(n) - S(n-1))/(2^8)
+
+and the division can be done easily with bit shifting.
+
+As we are in the digital world, this formula presents a drawback:
+if the difference between S(n-1) and N(n) is less than 1/k, there will be no
+difference between S(n-1) and S(n).
+
+As a consequence, there will be a static error of up to 1/k.
+
+In the STMTouch Driver, the S(n) is stored in the Meas element of the data
+structure after each acquisition:
+
+Meas(n) = S(n) = N(n)
+
+The formula is then:
+
+Meas(n) = Meas(n-1) + K.(Meas(n) - Meas(n-1))/(2^8)
+
+In order to reduce the static error, we can use "Meas(n) = S(n).2^P".
+
+The P is given by the ACQ_FILTER_RANGE constant.
+
+This would shift the signal value left and provides a few additional low
+significant bits useful to reduce the static error.
+
+Warning: all thresholds must be shifted accordingly if the parameter P is
+different from 0.
+
+If we report this into the filter formula we obtain:
+
+Meas(n) = Meas(n-1) + K.[ Meas(n)*2^P - Meas(n-1)]/2^8
+
+In this case the static error is reduced to 1/(k.2^P)
+*/
+
+#define ACQ_FILTER_RANGE (0) /* Range[0..5] - Warning: all thresholds must be shifted if different from 0 */
+
+#define ACQ_FILTER_COEFF (128) /* Range[1..255] - First order filter coefficient (k = ACQ_FILTER_COEFF/256) */
+
+/**
+ * @brief Example of measure value filter
+ * @param[in] measn1 Previous measure value
+ * @param[in] measn Current measure value
+ * @retval Filtered measure
+ */
+TSL_tMeas_T TSL_filt_MeasFilter(TSL_tMeas_T measn1, TSL_tMeas_T measn)
+{
+ TSL_tMeas_T val;
+
+ val = (TSL_tMeas_T)(measn << ACQ_FILTER_RANGE);
+
+ if (measn1 != 0)
+ {
+ if (val > measn1)
+ {
+ val = measn1 + ((ACQ_FILTER_COEFF * (val - measn1)) >> 8);
+ }
+ else
+ {
+ val = measn1 - ((ACQ_FILTER_COEFF * (measn1 - val)) >> 8);
+ }
+ }
+
+ return(val);
+}
+
+
+/**
+ * @brief Example of delta value filter
+ * @param[in] delta Delta value to modify
+ * @retval Filtered delta
+ */
+TSL_tDelta_T TSL_filt_DeltaFilter(TSL_tDelta_T delta)
+{
+ return(delta);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_globals.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_globals.c
new file mode 100644
index 0000000..4aa0d94
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_globals.c
@@ -0,0 +1,33 @@
+/**
+ ******************************************************************************
+ * @file tsl_globals.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains global variables.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_globals.h"
+
+TSL_Globals_T TSL_Globals; /**< Global variables used by main() and TSL modules */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_linrot.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_linrot.c
new file mode 100644
index 0000000..561e15c
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_linrot.c
@@ -0,0 +1,2103 @@
+/**
+ ******************************************************************************
+ * @file tsl_linrot.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage Linear and Rotary sensors.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_linrot.h"
+#include "tsl_globals.h"
+
+#if TSLPRM_TOTAL_LNRTS > 0
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+
+#define THIS_OBJ_TYPE TSL_Globals.This_Obj->Type
+
+#define THIS_STATEID TSL_Globals.This_LinRot->p_Data->StateId
+#define THIS_RAW_POSITION TSL_Globals.This_LinRot->p_Data->RawPosition
+#define THIS_POSITION TSL_Globals.This_LinRot->p_Data->Position
+#define THIS_CHANGE TSL_Globals.This_LinRot->p_Data->Change
+#define THIS_POSCHANGE TSL_Globals.This_LinRot->p_Data->PosChange
+#define THIS_COUNTER_DEB TSL_Globals.This_LinRot->p_Data->CounterDebounce
+#define THIS_COUNTER_DIR TSL_Globals.This_LinRot->p_Data->CounterDirection
+#define THIS_COUNTER_DTO TSL_Globals.This_LinRot->p_Data->CounterDTO
+#define THIS_DXSLOCK TSL_Globals.This_LinRot->p_Data->DxSLock
+#define THIS_DIRECTION TSL_Globals.This_LinRot->p_Data->Direction
+
+#define THIS_PROXIN_TH TSL_Globals.This_LinRot->p_Param->ProxInTh
+#define THIS_PROXOUT_TH TSL_Globals.This_LinRot->p_Param->ProxOutTh
+#define THIS_DETECTIN_TH TSL_Globals.This_LinRot->p_Param->DetectInTh
+#define THIS_DETECTOUT_TH TSL_Globals.This_LinRot->p_Param->DetectOutTh
+#define THIS_CALIB_TH TSL_Globals.This_LinRot->p_Param->CalibTh
+
+#define THIS_RESOLUTION TSL_Globals.This_LinRot->p_Param->Resolution
+#define THIS_DIR_CHG_POS TSL_Globals.This_LinRot->p_Param->DirChangePos
+
+#define THIS_COUNTER_DEB_CALIB TSL_Globals.This_LinRot->p_Param->CounterDebCalib
+#define THIS_COUNTER_DEB_PROX TSL_Globals.This_LinRot->p_Param->CounterDebProx
+#define THIS_COUNTER_DEB_DETECT TSL_Globals.This_LinRot->p_Param->CounterDebDetect
+#define THIS_COUNTER_DEB_RELEASE TSL_Globals.This_LinRot->p_Param->CounterDebRelease
+#define THIS_COUNTER_DEB_ERROR TSL_Globals.This_LinRot->p_Param->CounterDebError
+#define THIS_COUNTER_DEB_DIRECTION TSL_Globals.This_LinRot->p_Param->CounterDebDirection
+
+#define THIS_NB_CHANNELS TSL_Globals.This_LinRot->NbChannels
+#define THIS_SCT_COMP TSL_Globals.This_LinRot->SctComp
+#define THIS_POS_CORR TSL_Globals.This_LinRot->PosCorr
+
+#if TSLPRM_DTO > 0
+#define DTO_GET_TIME {TSL_linrot_DTOGetTime();}
+#else
+#define DTO_GET_TIME
+#endif
+
+/* Private variables ---------------------------------------------------------*/
+
+//================================================================
+// See AN2869 for more details on Linear and Rotary sensors design
+//================================================================
+
+//==============================================================================
+// 3 CHANNELS - LINEAR - MONO - 0/255 at extremities
+// i.e. CH1 CH2 CH3
+//==============================================================================
+#if TSLPRM_USE_3CH_LIN_M1 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_3CH_LIN_M1[3][3] =
+{
+// sec = 1 2 3
+// j = 0 1 2
+ { 0, -96, 0 }, // maj = 1; i = 0
+ { 32, 0, -160 }, // maj = 2; i = 1
+ { 0, 96, 0 } // maj = 3; i = 2
+};
+#endif
+
+//==============================================================================
+// 3 CHANNELS - LINEAR - MONO
+// i.e. CH1 CH2 CH3
+//==============================================================================
+#if TSLPRM_USE_3CH_LIN_M2 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_3CH_LIN_M2[3][3] =
+{
+// sec = 1 2 3
+// j = 0 1 2
+ { 0, -192, 0 }, // maj = 1; i = 0
+ { 64, 0, -320 }, // maj = 2; i = 1
+ { 0, 192, 0 } // maj = 3; i = 2
+};
+#endif
+
+//==============================================================================
+// 3 CHANNELS - LINEAR - HALF-ENDED
+// i.e. CH1 CH2 CH3 CH1
+//==============================================================================
+#if TSLPRM_USE_3CH_LIN_H > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_3CH_LIN_H[3][3] =
+{
+// sec = 1 2 3
+// j = 0 1 2
+ { 0, -96, 160 }, // maj = 1; i = 0
+ { 32, 0, -160 }, // maj = 2; i = 1
+ { -224, 96, 0 } // maj = 3; i = 2
+};
+#endif
+
+//==============================================================================
+// 3 CHANNELS - ROTARY - MONO
+// i.e. CH1 CH2 CH3
+//==============================================================================
+#if TSLPRM_USE_3CH_ROT_M > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_3CH_ROT_M[3][3] =
+{
+// sec = 1 2 3
+// j = 0 1 2
+ { 0, -64, 107 }, // maj = 1; i = 0
+ { 21, 0, -107 }, // maj = 2; i = 1
+ { -149, 64, 0 } // maj = 3; i = 2
+};
+#endif
+
+//==============================================================================
+// 4 CHANNELS - LINEAR - MONO - 0/255 at extremities
+// i.e. CH1 CH2 CH3 CH4
+//==============================================================================
+#if TSLPRM_USE_4CH_LIN_M1 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_4CH_LIN_M1[4][4] =
+{
+// sec = 1 2 3 4
+// j = 0 1 2 3
+ { 0, -64, 0, 0 }, // maj = 1; i = 0
+ { 21, 0, -107, 0 }, // maj = 2; i = 1
+ { 0, 64, 0, -149 }, // maj = 3; i = 2
+ { 0, 0, 107, 0 } // maj = 4; i = 3
+};
+#endif
+
+//==============================================================================
+// 4 CHANNELS - LINEAR - MONO
+// i.e. CH1 CH2 CH3 CH4
+//==============================================================================
+#if TSLPRM_USE_4CH_LIN_M2 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_4CH_LIN_M2[4][4] =
+{
+// sec = 1 2 3 4
+// j = 0 1 2 3
+ { 0, -96, 0, 0 }, // maj = 1; i = 0
+ { 32, 0, -160, 0 }, // maj = 2; i = 1
+ { 0, 96, 0, -224 }, // maj = 3; i = 2
+ { 0, 0, 160, 0 } // maj = 4; i = 3
+};
+#endif
+
+//==============================================================================
+// 4 CHANNELS - LINEAR - HALF-ENDED
+// i.e. CH1 CH2 CH3 CH4 CH1
+//==============================================================================
+#if TSLPRM_USE_4CH_LIN_H > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_4CH_LIN_H[4][4] =
+{
+// sec = 1 2 3 4
+// j = 0 1 2 3
+ { 0, -64, 0, 149 }, // maj = 1; i = 0
+ { 21, 0, -107, 0 }, // maj = 2; i = 1
+ { 0, 64, 0, -149 }, // maj = 3; i = 2
+ { -192, 0, 107, 0 } // maj = 4; i = 3
+};
+#endif
+
+//==============================================================================
+// 4 CHANNELS - ROTARY - MONO
+// i.e. CH1 CH2 CH3 CH4
+//==============================================================================
+#if TSLPRM_USE_4CH_ROT_M > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_4CH_ROT_M[4][4] =
+{
+// sec = 1 2 3 4
+// j = 0 1 2 3
+ { 0, -48, 0, 112 }, // maj = 1; i = 0
+ { 16, 0, -80, 0 }, // maj = 2; i = 1
+ { 0, 48, 0, -112 }, // maj = 3; i = 2
+ { -144, 0, 80, 0 } // maj = 4; i = 3
+};
+#endif
+
+//==============================================================================
+// 5 CHANNELS - LINEAR - MONO - 0/255 at extremities
+// i.e. CH1 CH2 CH3 CH4 CH5
+//==============================================================================
+#if TSLPRM_USE_5CH_LIN_M1 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_5CH_LIN_M1[5][5] =
+{
+// sec = 1 2 3 4 5
+// j = 0 1 2 3 4
+ { 0, -48, 0, 0, 0 }, // maj = 1; i = 0
+ { 16, 0, -80, 0, 0 }, // maj = 2; i = 1
+ { 0, 48, 0, -112, 0 }, // maj = 3; i = 2
+ { 0, 0, 80, 0, -144 }, // maj = 4; i = 3
+ { 0, 0, 0, 112, 0 } // maj = 5; i = 4
+};
+#endif
+
+//==============================================================================
+// 5 CHANNELS - LINEAR - MONO
+// i.e. CH1 CH2 CH3 CH4 CH5
+//==============================================================================
+#if TSLPRM_USE_5CH_LIN_M2 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_5CH_LIN_M2[5][5] =
+{
+// sec = 1 2 3 4 5
+// j = 0 1 2 3 4
+ { 0, -64, 0, 0, 0 }, // maj = 1; i = 0
+ { 21, 0, -107, 0, 0 }, // maj = 2; i = 1
+ { 0, 64, 0, -149, 0 }, // maj = 3; i = 2
+ { 0, 0, 107, 0, -192 }, // maj = 4; i = 3
+ { 0, 0, 0, 149, 0 } // maj = 5; i = 4
+};
+#endif
+
+//==============================================================================
+// 5 CHANNELS - LINEAR - HALF-ENDED
+// i.e. CH1 CH2 CH3 CH4 CH5 CH1
+//==============================================================================
+#if TSLPRM_USE_5CH_LIN_H > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_5CH_LIN_H[5][5] =
+{
+// sec = 1 2 3 4 5
+// j = 0 1 2 3 4
+ { 0, -48, 0, 0, 144 }, // maj = 1; i = 0
+ { 16, 0, -80, 0, 0 }, // maj = 2; i = 1
+ { 0, 48, 0, -112, 0 }, // maj = 3; i = 2
+ { 0, 0, 80, 0, -144 }, // maj = 4; i = 3
+ { -176, 0, 0, 112, 0 } // maj = 5; i = 4
+};
+#endif
+
+//==============================================================================
+// 5 CHANNELS - ROTARY - MONO
+// i.e. CH1 CH2 CH3 CH4 CH5
+//==============================================================================
+#if TSLPRM_USE_5CH_ROT_M > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_5CH_ROT_M[5][5] =
+{
+// sec = 1 2 3 4 5
+// j = 0 1 2 3 4
+ { 0, -38, 0, 0, 115 }, // maj = 1; i = 0
+ { 13, 0, -64, 0, 0 }, // maj = 2; i = 1
+ { 0, 38, 0, -90, 0 }, // maj = 3; i = 2
+ { 0, 0, 64, 0, -115 }, // maj = 4; i = 3
+ {-141, 0, 0, 90, 0 } // maj = 5; i = 4
+};
+#endif
+
+//==============================================================================
+// 5 CHANNELS - ROTARY - DUAL
+// i.e. CH1 CH2 CH3 CH4 CH5 CH1 CH3 CH5 CH2 CH4
+//==============================================================================
+#if TSLPRM_USE_5CH_ROT_D > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_5CH_ROT_D[5][5] =
+{
+// sec = 1 2 3 4 5
+// j = 0 1 2 3 4
+ { 0, -19, -83, 122, 58 }, // maj = 1; i = 0
+ { 6, 0, -32, -122, 96 }, // maj = 2; i = 1
+ { 70, 19, 0, -45, -96 }, // maj = 3; i = 2
+ {-134, 109, 32, 0, -58 }, // maj = 4; i = 3
+ { -70, -109, 83, 45, 0 } // maj = 5; i = 4
+};
+#endif
+
+//==============================================================================
+// 6 CHANNELS - LINEAR - MONO - 0/255 at extremities
+// i.e. CH1 CH2 CH3 CH4 CH5 CH6
+//==============================================================================
+#if TSLPRM_USE_6CH_LIN_M1 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_6CH_LIN_M1[6][6] =
+{
+// sec = 1 2 3 4 5 6
+// j = 0 1 2 3 4 5
+ { 0, -38, 0, 0, 0, 0 }, // maj = 1; i = 0
+ { 13, 0, -64, 0, 0, 0 }, // maj = 2; i = 1
+ { 0, 38, 0, -90, 0, 0 }, // maj = 3; i = 2
+ { 0, 0, 64, 0, -115, 0 }, // maj = 4; i = 3
+ { 0, 0, 0, 90, 0, -141 }, // maj = 5; i = 4
+ { 0, 0, 0, 0, 115, 0 } // maj = 6; i = 5
+};
+#endif
+
+//==============================================================================
+// 6 CHANNELS - LINEAR - MONO
+// i.e. CH1 CH2 CH3 CH4 CH5 CH6
+//==============================================================================
+#if TSLPRM_USE_6CH_LIN_M2 > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_6CH_LIN_M2[6][6] =
+{
+// sec = 1 2 3 4 5 6
+// j = 0 1 2 3 4 5
+ { 0, -48, 0, 0, 0, 0 }, // maj = 1; i = 0
+ { 16, 0, -80, 0, 0, 0 }, // maj = 2; i = 1
+ { 0, 48, 0, -112, 0, 0 }, // maj = 3; i = 2
+ { 0, 0, 80, 0, -144, 0 }, // maj = 4; i = 3
+ { 0, 0, 0, 112, 0, -176 }, // maj = 5; i = 4
+ { 0, 0, 0, 0, 144, 0 } // maj = 6; i = 5
+};
+#endif
+
+//==============================================================================
+// 6 CHANNELS - LINEAR - HALF-ENDED
+// i.e. CH1 CH2 CH3 CH4 CH5 CH6 CH1
+//==============================================================================
+#if TSLPRM_USE_6CH_LIN_H > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_6CH_LIN_H[6][6] =
+{
+// sec = 1 2 3 4 5 6
+// j = 0 1 2 3 4 5
+ { 0, -38, 0, 0, 0, 141 }, // maj = 1; i = 0
+ { 13, 0, -64, 0, 0, 0 }, // maj = 2; i = 1
+ { 0, 38, 0, -90, 0, 0 }, // maj = 3; i = 2
+ { 0, 0, 64, 0, -115, 0 }, // maj = 4; i = 3
+ { 0, 0, 0, 90, 0, -141 }, // maj = 5; i = 4
+ {-166, 0, 0, 0, 115, 0 } // maj = 6; i = 5
+};
+#endif
+
+//==============================================================================
+// 6 CHANNELS - ROTARY - MONO
+// i.e. CH1 CH2 CH3 CH4 CH5 CH6
+//==============================================================================
+#if TSLPRM_USE_6CH_ROT_M > 0
+CONST TSL_tsignPosition_T TSL_POSOFF_6CH_ROT_M[6][6] =
+{
+// sec = 1 2 3 4 5 6
+// j = 0 1 2 3 4 5
+ { 0, -32, 0, 0, 0, 117 }, // maj = 1; i = 0
+ { 11, 0, -53, 0, 0, 0 }, // maj = 2; i = 1
+ { 0, 32, 0, -75, 0, 0 }, // maj = 3; i = 2
+ { 0, 0, 53, 0, -96, 0 }, // maj = 4; i = 3
+ { 0, 0, 0, 75, 0, -117 }, // maj = 5; i = 4
+ {-139, 0, 0, 0, 96, 0 } // maj = 6; i = 5
+};
+#endif
+
+//------------------
+// Common parameters
+//------------------
+
+#define DIRECTION_CHANGE_MAX_DISPLACEMENT (255)
+#define DIRECTION_CHANGE_TOTAL_STEPS (256)
+#define RESOLUTION_CALCULATION (8)
+
+static TSL_tNb_T CalibDiv;
+
+/* Private functions prototype -----------------------------------------------*/
+
+void TSL_linrot_DTOGetTime(void);
+void TSL_linrot_ProcessCh_All_SetStatus(TSL_ObjStatus_enum_T sts);
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DataReady(void);
+TSL_Status_enum_T TSL_linrot_ProcessCh_All_AcqStatus(TSL_AcqStatus_enum_T sts);
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_AcqStatusError(void);
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DeltaBelowEquMinus(TSL_tThreshold_T th, TSL_tIndex_T coeff);
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DeltaAboveEqu(TSL_tThreshold_T th, TSL_tIndex_T coeff);
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DeltaAbove(TSL_tThreshold_T th, TSL_tIndex_T coeff);
+TSL_Status_enum_T TSL_linrot_ProcessCh_All_DeltaBelowEqu(TSL_tThreshold_T th, TSL_tIndex_T coeff);
+void TSL_linrot_ProcessCh_All_ClearRef(void);
+TSL_tDelta_T TSL_linrot_NormDelta(TSL_ChannelData_T *ch, TSL_tIndex_T idx);
+
+
+//==============================================================================
+// "Object methods" functions
+//==============================================================================
+
+/**
+ * @brief Init parameters with default values from configuration file
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_Init(void)
+{
+ // Thresholds
+#if TSLPRM_USE_PROX > 0
+ THIS_PROXIN_TH = TSLPRM_LINROT_PROX_IN_TH;
+ THIS_PROXOUT_TH = TSLPRM_LINROT_PROX_OUT_TH;
+#endif
+ THIS_DETECTIN_TH = TSLPRM_LINROT_DETECT_IN_TH;
+ THIS_DETECTOUT_TH = TSLPRM_LINROT_DETECT_OUT_TH;
+ THIS_CALIB_TH = TSLPRM_LINROT_CALIB_TH;
+
+ // Debounce counters
+ THIS_COUNTER_DEB_CALIB = TSLPRM_DEBOUNCE_CALIB;
+#if TSLPRM_USE_PROX > 0
+ THIS_COUNTER_DEB_PROX = TSLPRM_DEBOUNCE_PROX;
+#endif
+ THIS_COUNTER_DEB_DETECT = TSLPRM_DEBOUNCE_DETECT;
+ THIS_COUNTER_DEB_RELEASE = TSLPRM_DEBOUNCE_RELEASE;
+ THIS_COUNTER_DEB_ERROR = TSLPRM_DEBOUNCE_ERROR;
+
+ // Other parameters for linear/rotary only
+ THIS_RESOLUTION = TSLPRM_LINROT_RESOLUTION;
+ THIS_DIR_CHG_POS = TSLPRM_LINROT_DIR_CHG_POS;
+ THIS_COUNTER_DEB_DIRECTION = TSLPRM_LINROT_DIR_CHG_DEB;
+
+ // Initial state
+ TSL_linrot_SetStateCalibration(TSLPRM_CALIB_DELAY);
+}
+
+
+/**
+ * @brief Process the State Machine
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_Process(void)
+{
+ TSL_StateId_enum_T prev_state_id;
+
+ // Check if at least one channel has a data ready
+ if ((TSL_linrot_ProcessCh_One_DataReady() == TSL_STATUS_OK) || (THIS_STATEID == TSL_STATEID_OFF))
+ {
+
+ prev_state_id = THIS_STATEID;
+
+#if TSLPRM_TOTAL_LINROTS > 0
+ if ((TSL_Globals.This_Obj->Type == TSL_OBJ_LINEAR) ||
+ (TSL_Globals.This_Obj->Type == TSL_OBJ_ROTARY))
+ {
+ // Launch the object state function
+ TSL_Globals.This_LinRot->p_SM[THIS_STATEID].StateFunc();
+ }
+#endif
+
+#if TSLPRM_TOTAL_LINROTS_B > 0
+ if ((TSL_Globals.This_Obj->Type == TSL_OBJ_LINEARB) ||
+ (TSL_Globals.This_Obj->Type == TSL_OBJ_ROTARYB))
+ {
+ // Launch the TSL_Params state function
+ TSL_Params.p_LinRotSM[THIS_STATEID].StateFunc();
+ }
+#endif
+
+ // Check if the new state has changed
+ if (THIS_STATEID == prev_state_id)
+ {
+ THIS_CHANGE = TSL_STATE_NOT_CHANGED;
+ }
+ else
+ {
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ }
+
+#if TSLPRM_USE_DXS > 0
+ if (THIS_STATEID != TSL_STATEID_DETECT)
+ {
+ THIS_DXSLOCK = TSL_FALSE;
+ }
+ if (THIS_STATEID == TSL_STATEID_TOUCH)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ }
+#endif
+
+ }
+}
+
+
+/**
+ * @brief Calculate the position
+ * @param None
+ * @retval Status Return OK if position calculation is correct
+ * @note The position is calculated only if the number of channels is greater than 2
+ */
+TSL_Status_enum_T TSL_linrot_CalcPos(void)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ TSL_tDelta_T norm_delta;
+ static TSL_tDelta_T delta1;
+ static TSL_tDelta_T delta2;
+ static TSL_tDelta_T delta3;
+ static TSL_tIndex_T index1;
+ static TSL_tIndex_T index2;
+ TSL_tNb_T minor;
+ TSL_tNb_T major;
+ TSL_tNb_T sector_computation = 0;
+ TSL_tNb_T position_correction = 0;
+ TSL_tsignPosition_T new_position = 0;
+ TSL_tPosition_T u_new_position = 0;
+
+ delta1 = 0;
+ delta2 = 0;
+ delta3 = 0;
+
+ index1 = 0;
+ index2 = 0;
+
+ // The position change flag will be set only if a new position is detected.
+ THIS_POSCHANGE = TSL_STATE_NOT_CHANGED;
+
+ // The position is calculated only if the number of channels is greater than 2
+ if (THIS_NB_CHANNELS < 3)
+ {
+ return TSL_STATUS_ERROR;
+ }
+
+ //--------------------------------------------------------------------------
+ // Sort the channels' delta
+ // - delta1 and index1 = biggest
+ // - delta2 and index2 = middle
+ // - delta3 and index3 = lowest
+ //--------------------------------------------------------------------------
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+
+#if TSLPRM_LINROT_USE_NORMDELTA > 0
+ norm_delta = TSL_linrot_NormDelta(p_Ch, idx); // Normalize the Delta
+#else
+ norm_delta = p_Ch->Delta; // Take only the Delta
+#endif
+
+ // The Delta must be positive only otherwise it is noise
+ if (norm_delta < 0) {norm_delta = 0;}
+
+ if (norm_delta > delta1)
+ {
+ delta3 = delta2;
+ delta2 = delta1;
+ delta1 = norm_delta;
+ index2 = index1;
+ index1 = idx;
+ }
+ else
+ {
+ if (norm_delta > delta2)
+ {
+ delta3 = delta2;
+ delta2 = norm_delta;
+ index2 = idx;
+ }
+ else
+ {
+ if (norm_delta > delta3)
+ {
+ delta3 = norm_delta;
+ }
+ }
+ }
+
+ p_Ch++; // Next channel
+
+ } // for all channels
+
+ // Noise filter: we need at least two significant Delta measurements
+ if (delta2 < ((TSL_tThreshold_T)(THIS_DETECTOUT_TH >> 1) - 1))
+ {
+ return TSL_STATUS_ERROR;
+ }
+
+ //----------------------------------------------------------------------------
+ // Position calculation...
+ //----------------------------------------------------------------------------
+
+ /*----------------------------------------------------------------------------
+ B = Biggest signal measured (Delta1/Index1)
+ M = Middle signal measured (Delta2/Index2)
+ S = Smallest signal measured (Delta3/Index3)
+
+ - The equation to find the position is:
+ Position = Offset +/- [ Sector_Size x ( Major / (Major + Minor) ) ]
+
+ - The Offset is the position of the middle of the Middle signal segment.
+ All the Offset values are stored in the ROM table Table_POSITION_OFFSET.
+
+ - Major = Biggest - Smallest signals
+ Minor = Middle - Smallest signals
+
+ - The Sector_Size depends of the number of channels used
+ ----------------------------------------------------------------------------*/
+
+ // Calculates the Major and Minor parameters
+ minor = (TSL_tNb_T)(delta2 - delta3); // Middle - Smallest signals
+ major = (TSL_tNb_T)(delta1 - delta3); // Biggest - Smallest signals
+
+ // Select the offset position in the position offset constant table
+ // Equal to: new_position = TABLE_POSITION_OFFSET_xCH_xxx[index1][index2];
+ new_position = *(TSL_Globals.This_LinRot->p_PosOff + (index1 * THIS_NB_CHANNELS) + index2);
+ sector_computation = THIS_SCT_COMP;
+ position_correction = THIS_POS_CORR;
+
+ // Calculates: [ Sector_Size x ( Major / (Major + Minor) ) ]
+ sector_computation = major * sector_computation;
+ sector_computation = sector_computation / (major + minor);
+
+ // Use the sign bit from position table to define the interpretation direction.
+ // The NewPosition is multiplied by 2 because the Offset stored in the ROM
+ // table is divided by 2...
+ if (new_position > 0) // Means Offset is > 0 in the position table
+ {
+ new_position = (TSL_tsignPosition_T)(new_position << 1);
+ new_position += sector_computation;
+ }
+ else // means Offset is <= 0 in the ROM table
+ {
+ new_position = (TSL_tsignPosition_T)((-new_position) << 1);
+ new_position -= sector_computation;
+ }
+
+ // Position is calculated differently if LINEAR or ROTARY sensor
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_LINEARB))
+ {
+
+ // First adjustment used to shift all the values to obtain the "zero"
+ if (new_position > 0)
+ {
+ new_position -= position_correction;
+ }
+ else
+ {
+ new_position = new_position + (256 - position_correction);
+ }
+
+ // Second adjustment used to clamp the values at both ends of sensor
+ if (new_position < 0)
+ {
+ new_position = 0;
+ }
+
+ if (new_position > 255)
+ {
+ new_position = 255;
+ }
+
+ }
+ else // ROTARY sensor: keep only the low byte
+ {
+ new_position = (TSL_tPosition_T)new_position;
+ }
+
+ //----------------------------------------------------------------------------
+ // Direction Change Process
+ //----------------------------------------------------------------------------
+
+ if (THIS_DIRECTION == TSL_TRUE) // Anticlockwise direction ...
+ {
+
+ // Check Direction changed and Position overflow from 0x00 to 0xFF not realized !
+ if (((TSL_tPosition_T)new_position > THIS_RAW_POSITION) && (((TSL_tPosition_T)new_position - THIS_RAW_POSITION) < DIRECTION_CHANGE_MAX_DISPLACEMENT))
+ {
+ if (new_position < (uint16_t)(THIS_RAW_POSITION + THIS_DIR_CHG_POS))
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ THIS_COUNTER_DIR--;
+ if (!THIS_COUNTER_DIR)
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ THIS_DIRECTION = TSL_FALSE; // New direction accepted: clockwise.
+ }
+ else
+ {
+ return TSL_STATUS_ERROR;
+ }
+ }
+ }
+
+ // Check position overflow from 0xFF to 0x00 to be filtered !
+ if ((new_position + DIRECTION_CHANGE_MAX_DISPLACEMENT) < THIS_RAW_POSITION)
+ {
+ if ((new_position + DIRECTION_CHANGE_TOTAL_STEPS) < (uint16_t)(THIS_RAW_POSITION + THIS_DIR_CHG_POS))
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ THIS_COUNTER_DIR--;
+ if (!THIS_COUNTER_DIR)
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ THIS_DIRECTION = TSL_FALSE; // New direction accepted: clockwise.
+ }
+ else
+ {
+ return TSL_STATUS_ERROR;
+ }
+ }
+ }
+
+ }
+ else // Clockwise direction... DEFAULT SETTING !
+ {
+
+ // Check Direction changed and Position overflow from 0xFF to 0x00 not realized !
+ if (((TSL_tPosition_T)new_position < THIS_RAW_POSITION) && ((THIS_RAW_POSITION - (TSL_tPosition_T)new_position) < DIRECTION_CHANGE_MAX_DISPLACEMENT))
+ {
+ if ((new_position + THIS_DIR_CHG_POS) > THIS_RAW_POSITION)
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ THIS_COUNTER_DIR--;
+ if (!THIS_COUNTER_DIR)
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ THIS_DIRECTION = TSL_TRUE; // New direction accepted: anticlockwise.
+ }
+ else
+ {
+ return TSL_STATUS_ERROR;
+ }
+ }
+ }
+
+ // Check position overflow from 0x00 to 0xFF to be filtered !
+ if (new_position > (uint16_t)(THIS_RAW_POSITION + DIRECTION_CHANGE_MAX_DISPLACEMENT))
+ {
+ if ((new_position + THIS_DIR_CHG_POS) > (uint16_t)(THIS_RAW_POSITION + DIRECTION_CHANGE_TOTAL_STEPS))
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ THIS_COUNTER_DIR--;
+ if (!THIS_COUNTER_DIR)
+ {
+ THIS_COUNTER_DIR = THIS_COUNTER_DEB_DIRECTION;
+ THIS_DIRECTION = TSL_TRUE; // New direction accepted: anticlockwise.
+ }
+ else
+ {
+ return TSL_STATUS_ERROR;
+ }
+ }
+ }
+
+ }
+
+ //----------------------------------------------------------------------------
+ // Final result...
+ //----------------------------------------------------------------------------
+
+ // The Raw Position is always updated
+ // The Position is updated only if different from the previous one
+
+ THIS_RAW_POSITION = (TSL_tPosition_T)new_position;
+
+ u_new_position = (TSL_tPosition_T)((TSL_tPosition_T)new_position >> (RESOLUTION_CALCULATION - THIS_RESOLUTION));
+
+ if (THIS_POSITION == u_new_position)
+ {
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ THIS_POSITION = u_new_position;
+ THIS_POSCHANGE = TSL_STATE_CHANGED;
+ return TSL_STATUS_OK;
+ }
+
+}
+
+
+//==============================================================================
+// Utility functions
+//==============================================================================
+
+/**
+ * @brief Go in Calibration state
+ * @param[in] delay Delay before calibration starts (stabilization of noise filter)
+ * @retval None
+ */
+void TSL_linrot_SetStateCalibration(TSL_tCounter_T delay)
+{
+ THIS_STATEID = TSL_STATEID_CALIB;
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ TSL_linrot_ProcessCh_All_SetStatus(TSL_OBJ_STATUS_ON);
+
+ switch (TSL_Params.NbCalibSamples)
+ {
+ case 4:
+ CalibDiv = 2;
+ break;
+ case 16:
+ CalibDiv = 4;
+ break;
+ default:
+ TSL_Params.NbCalibSamples = 8;
+ CalibDiv = 3;
+ break;
+ }
+
+ // If a noise filter is used, the counter must be initialized to a value
+ // different from 0 in order to stabilize the filter.
+ THIS_COUNTER_DEB = (TSL_tCounter_T)(delay + (TSL_tCounter_T)TSL_Params.NbCalibSamples);
+ TSL_linrot_ProcessCh_All_ClearRef();
+}
+
+
+/**
+ * @brief Go in Off state with sensor "off"
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_SetStateOff(void)
+{
+ THIS_STATEID = TSL_STATEID_OFF;
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ TSL_linrot_ProcessCh_All_SetStatus(TSL_OBJ_STATUS_OFF);
+}
+
+
+#if !defined(TSLPRM_STM8TL5X) && !defined(STM8TL5X)
+/**
+ * @brief Go in Off state with sensor in "Burst mode only"
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_SetStateBurstOnly(void)
+{
+ THIS_STATEID = TSL_STATEID_OFF;
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ TSL_linrot_ProcessCh_All_SetStatus(TSL_OBJ_STATUS_BURST_ONLY);
+}
+#endif
+
+
+/**
+ * @brief Return the current state identifier
+ * @param None
+ * @retval State id
+ */
+TSL_StateId_enum_T TSL_linrot_GetStateId(void)
+{
+ return(THIS_STATEID);
+}
+
+
+/**
+ * @brief Return the current state mask
+ * @param None
+ * @retval State mask
+ */
+TSL_StateMask_enum_T TSL_linrot_GetStateMask(void)
+{
+ TSL_StateMask_enum_T state_mask = TSL_STATEMASK_UNKNOWN;
+
+#if TSLPRM_TOTAL_LINROTS > 0
+ if ((TSL_Globals.This_Obj->Type == TSL_OBJ_LINEAR) ||
+ (TSL_Globals.This_Obj->Type == TSL_OBJ_ROTARY))
+ {
+ state_mask = TSL_Globals.This_LinRot->p_SM[THIS_STATEID].StateMask;
+ }
+#endif
+
+#if TSLPRM_TOTAL_LINROTS_B > 0
+ if ((TSL_Globals.This_Obj->Type == TSL_OBJ_LINEARB) ||
+ (TSL_Globals.This_Obj->Type == TSL_OBJ_ROTARYB))
+ {
+ state_mask = TSL_Params.p_LinRotSM[THIS_STATEID].StateMask;
+ }
+#endif
+
+ return state_mask;
+}
+
+
+/**
+ * @brief Return the Change flag
+ * @param None
+ * @retval Change flag status
+ */
+TSL_tNb_T TSL_linrot_IsChanged(void)
+{
+ return(THIS_CHANGE);
+}
+
+
+//==============================================================================
+// State machine functions
+//==============================================================================
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Release processing (previous state = Proximity)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebReleaseProxStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_PROX; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_PROX; // Go back to the previous state
+ }
+ else
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ // else stay in Debounce Release
+ }
+ }
+}
+#endif // if TSLPRM_USE_PROX > 0
+
+
+/**
+ * @brief Debounce Release processing (previous state = Detect)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebReleaseDetectStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_DETECTOUT_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ }
+ else
+ {
+#if TSLPRM_USE_PROX > 0
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ return;
+ }
+#endif
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ // else stay in Debounce Release
+ }
+ }
+}
+
+
+/**
+ * @brief Debounce Release processing (previous state = Touch)
+ * Same as Debounce Release Detect processing
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebReleaseTouchStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_TOUCH; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_DETECTOUT_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ }
+ else
+ {
+#if TSLPRM_USE_PROX > 0
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ return;
+ }
+#endif
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ // else stay in Debounce Release
+ }
+ }
+}
+
+
+/**
+ * @brief Release state processing
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_ReleaseStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_RELEASE;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_DETECTIN_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_DETECT;
+ }
+ return;
+ }
+
+#if TSLPRM_USE_PROX > 0
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_PROXIN_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX;
+ }
+ return;
+ }
+#endif
+
+ // Check delta for re-calibration
+ if (TSL_linrot_ProcessCh_One_DeltaBelowEquMinus(THIS_CALIB_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_CALIB;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ TSL_linrot_SetStateCalibration(0);
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_CALIB;
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Debounce Calibration processing (previous state = Release)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebCalibrationStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaBelowEquMinus(THIS_CALIB_TH, 1) == TSL_STATUS_OK) // Still below recalibration threshold
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ TSL_linrot_SetStateCalibration(0);
+ }
+ // else stay in Debounce Calibration
+ }
+ else // Go back to previous state
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ }
+}
+
+
+/**
+ * @brief Calibration state processing
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_CalibrationStateProcess(void)
+{
+ TSL_tMeas_T new_meas;
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch;
+
+#if TSLPRM_CALIB_DELAY > 0
+ // Noise filter stabilization time
+ if (THIS_COUNTER_DEB > (TSL_tCounter_T)TSL_Params.NbCalibSamples)
+ {
+ THIS_COUNTER_DEB--;
+ return; // Skip the sample
+ }
+#endif
+
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_CALIB;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ // Process all channels
+ p_Ch = TSL_Globals.This_LinRot->p_ChD;
+
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+
+ // Get the new measure or Calculate it
+#if TSLPRM_USE_MEAS > 0
+ new_meas = p_Ch->Meas;
+#else // Calculate it
+ new_meas = TSL_acq_ComputeMeas(p_Ch->Ref, p_Ch->Delta);
+#endif
+
+ // Verify the first Reference value
+ if (THIS_COUNTER_DEB == (TSL_tCounter_T)TSL_Params.NbCalibSamples)
+ {
+ if (TSL_acq_TestFirstReferenceIsValid(p_Ch, new_meas))
+ {
+ p_Ch->Ref = new_meas;
+ }
+ else
+ {
+ p_Ch->Ref = 0;
+ return;
+ }
+ }
+ else
+ {
+ // Add the measure in temporary Reference
+ p_Ch->Ref += new_meas;
+
+ // Check reference overflow
+ if (p_Ch->Ref < new_meas)
+ {
+ p_Ch->Ref = 0; // Suppress the bad reference
+ THIS_STATEID = TSL_STATEID_ERROR;
+ return;
+ }
+ }
+
+ p_Ch++; // Next channel
+ }
+
+ // Check that we have all the needed measurements
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ // Process all channels
+ p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+ // Divide temporary Reference by the number of samples
+ p_Ch->Ref >>= CalibDiv;
+ p_Ch->RefRest = 0;
+ p_Ch->Delta = 0;
+ p_Ch++; // Next channel
+ }
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ }
+}
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Proximity processing (previous state = Release)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebProxStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_DETECTIN_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_DETECT;
+ }
+ return;
+ }
+
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_PROXIN_TH, 0) == TSL_STATUS_OK)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Proximity
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ }
+}
+#endif
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Proximity processing (previous state = Detect)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebProxDetectStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_DETECTOUT_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ return;
+ }
+
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Proximity
+ }
+ else
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_DETECT;
+ }
+ }
+ }
+}
+#endif
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Proximity processing (previous state = Touch)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebProxTouchStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_DETECTOUT_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ return;
+ }
+
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Proximity
+ }
+ else
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_TOUCH;
+ }
+ }
+ }
+}
+#endif
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Proximity state processing
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_ProxStateProcess(void)
+{
+#if TSLPRM_DTO > 0
+ TSL_tTick_sec_T tick_detected;
+#endif
+
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_PROX;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_DETECTIN_TH, 1) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_DETECT;
+ }
+ return;
+ }
+
+ if (TSL_linrot_ProcessCh_All_DeltaBelowEqu(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_PROX;
+ }
+ return;
+ }
+
+ // Stay in Proximity state
+#if TSLPRM_DTO > 0
+ //------------------------------------
+ // Detection Time Out (DTO) processing
+ //------------------------------------
+ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64))
+ {
+ tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved
+ // Enter in calibration state if the DTO duration has elapsed
+ if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK)
+ {
+ TSL_linrot_SetStateCalibration(0);
+ }
+ }
+#endif
+
+ }
+}
+#endif
+
+
+/**
+ * @brief Debounce Detect processing (previous state = Release or Proximity)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebDetectStateProcess(void)
+{
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_DETECTIN_TH, 1) == TSL_STATUS_OK)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Detect
+ }
+ else
+ {
+#if TSLPRM_USE_PROX > 0
+ if (TSL_linrot_ProcessCh_One_DeltaAboveEqu(THIS_PROXIN_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX;
+ }
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+#else
+ THIS_STATEID = TSL_STATEID_RELEASE;
+#endif
+ }
+ }
+}
+
+
+/**
+ * @brief Detect state processing
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DetectStateProcess(void)
+{
+#if TSLPRM_DTO > 0
+ TSL_Status_enum_T pos_sts;
+ TSL_tTick_sec_T tick_detected;
+#endif
+
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_DETECT;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_DETECTOUT_TH, 1) == TSL_STATUS_OK)
+ {
+ //-------------------
+ // Calculate position
+ //-------------------
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARY))
+ {
+ // Call the specific method
+#if TSLPRM_DTO > 0
+ pos_sts = TSL_Globals.This_LinRot->p_Methods->CalcPosition();
+#else
+ TSL_Globals.This_LinRot->p_Methods->CalcPosition();
+#endif
+ }
+ else // TSL_OBJ_LINEARB or TSL_OBJ_ROTARYB
+ {
+ // Call the default method
+#if TSLPRM_DTO > 0
+ pos_sts = TSL_Params.p_LinRotMT->CalcPosition();
+#else
+ TSL_Params.p_LinRotMT->CalcPosition();
+#endif
+ }
+#if TSLPRM_DTO > 0
+ //------------------------------------
+ // Detection Time Out (DTO) processing
+ // Only if the Position has NOT changed
+ //-------------------------------------
+ if (pos_sts == TSL_STATUS_OK)
+ {
+ DTO_GET_TIME; // Take current time
+ }
+ else
+ {
+ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64))
+ {
+ tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved
+ // Enter in calibration state if the DTO duration has elapsed
+ if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK)
+ {
+ TSL_linrot_SetStateCalibration(0);
+ }
+ }
+ }
+#endif
+ return; // Normal operation, stay in Detect state
+ }
+
+#if TSLPRM_USE_PROX > 0
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX_DETECT;
+ }
+ return;
+ }
+#endif
+
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_DETECT;
+ }
+
+ }
+}
+
+
+/**
+ * @brief Touch state processing
+ * Same as Detect state
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_TouchStateProcess(void)
+{
+#if TSLPRM_DTO > 0
+ TSL_Status_enum_T pos_sts;
+ TSL_tTick_sec_T tick_detected;
+#endif
+
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_TOUCH;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_DETECTOUT_TH, 1) == TSL_STATUS_OK)
+ {
+ //-------------------
+ // Calculate position
+ //-------------------
+ if ((THIS_OBJ_TYPE == TSL_OBJ_LINEAR) || (THIS_OBJ_TYPE == TSL_OBJ_ROTARY))
+ {
+ // Call the specific method
+#if TSLPRM_DTO > 0
+ pos_sts = TSL_Globals.This_LinRot->p_Methods->CalcPosition();
+#else
+ TSL_Globals.This_LinRot->p_Methods->CalcPosition();
+#endif
+ }
+ else // TSL_OBJ_LINEARB or TSL_OBJ_ROTARYB
+ {
+ // Call the default method
+#if TSLPRM_DTO > 0
+ pos_sts = TSL_Params.p_LinRotMT->CalcPosition();
+#else
+ TSL_Params.p_LinRotMT->CalcPosition();
+#endif
+ }
+#if TSLPRM_DTO > 0
+ //------------------------------------
+ // Detection Time Out (DTO) processing
+ // Only if the Position has NOT changed
+ //-------------------------------------
+ if (pos_sts == TSL_STATUS_OK)
+ {
+ DTO_GET_TIME; // Take current time
+ }
+ else
+ {
+ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64))
+ {
+ tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved
+ // Enter in calibration state if the DTO duration has elapsed
+ if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK)
+ {
+ TSL_linrot_SetStateCalibration(0);
+ }
+ }
+ }
+#endif
+ return; // Normal operation, stay in Touch state
+ }
+
+#if TSLPRM_USE_PROX > 0
+ if (TSL_linrot_ProcessCh_One_DeltaAbove(THIS_PROXOUT_TH, 0) == TSL_STATUS_OK)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX_TOUCH;
+ }
+ return;
+ }
+#endif
+
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_TOUCH;
+ }
+
+ }
+}
+
+
+/**
+ * @brief Debounce error state processing
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DebErrorStateProcess(void)
+{
+ volatile TSL_StateMask_enum_T mask;
+
+ if (TSL_linrot_ProcessCh_One_AcqStatusError() == TSL_STATUS_OK) // Acquisition error (min or max)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ // Get state mask
+ mask = TSL_linrot_GetStateMask();
+ // Mask Error and Debounce bits
+#ifdef _RAISONANCE_
+ mask &= ~(TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK);
+#else
+ mask &= (TSL_StateMask_enum_T)(~(TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK));
+#endif
+ // Go back to the previous state
+ switch (mask)
+ {
+ case TSL_STATEMASK_RELEASE :
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ break;
+ case TSL_STATEMASK_PROX :
+ THIS_STATEID = TSL_STATEID_PROX;
+ break;
+ case TSL_STATEMASK_DETECT :
+ THIS_STATEID = TSL_STATEID_DETECT;
+ break;
+ case TSL_STATEMASK_TOUCH :
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ break;
+ default:
+ TSL_linrot_SetStateCalibration(0);
+ break;
+ }
+ }
+}
+
+
+//==============================================================================
+// Private functions
+//==============================================================================
+
+/**
+ * @brief Get the current time in second and affect it to the DTO counter (Private)
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_DTOGetTime(void)
+{
+ disableInterrupts();
+ THIS_COUNTER_DTO = (TSL_tCounter_T)TSL_Globals.Tick_sec;
+ enableInterrupts();
+}
+
+
+/**
+ * @brief Set all channels status to ON, OFF or BURST ONLY
+ * @param sts Channel status
+ * @retval None
+ */
+void TSL_linrot_ProcessCh_All_SetStatus(TSL_ObjStatus_enum_T sts)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ // Init channels status
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+ p_Ch->Flags.ObjStatus = sts;
+ p_Ch++;
+ }
+}
+
+
+/**
+ * @brief Check if at least one channel has a data ready
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DataReady(void)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ TSL_Status_enum_T retval = TSL_STATUS_ERROR;
+ // Return OK if at least one channel has a data ready
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+ if (p_Ch->Flags.DataReady == TSL_DATA_READY)
+ {
+ p_Ch->Flags.DataReady = TSL_DATA_NOT_READY; // The new data is processed
+ retval = TSL_STATUS_OK;
+ }
+ p_Ch++;
+ }
+ return retval;
+}
+
+
+/**
+ * @brief Check if all channels are equal to the status passed
+ * @param sts Status to be checked
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_All_AcqStatus(TSL_AcqStatus_enum_T sts)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ // Return OK if ALL channels have the correct acq status
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+ if (p_Ch->Flags.AcqStatus != sts)
+ {
+ return TSL_STATUS_ERROR;
+ }
+ p_Ch++;
+ }
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Check if at least one channel is in error
+ * @param None
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_AcqStatusError(void)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ // Return OK if at least one channel is in acquisition error min or max
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+ if (p_Ch->Flags.AcqStatus & TSL_ACQ_STATUS_ERROR_MASK)
+ {
+ return TSL_STATUS_OK;
+ }
+ p_Ch++;
+ }
+ return TSL_STATUS_ERROR;
+}
+
+
+/**
+ * @brief Check if at least one channel is below or equal a threshold (inverted)
+ * @param th Threshold
+ * @param coeff Enable or Disable the multiplier coefficient on threshold
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DeltaBelowEquMinus(TSL_tThreshold_T th, TSL_tIndex_T coeff)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ TSL_tDelta_T norm_delta;
+
+#if TSLPRM_COEFF_TH > 0
+ uint16_t lth;
+ if (coeff)
+ {
+ lth = (uint16_t)((uint16_t)th << TSLPRM_COEFF_TH);
+ }
+ else
+ {
+ lth = th;
+ }
+#endif
+
+ // Return OK if at least one channel is below or equal the threshold
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+
+#if TSLPRM_LINROT_USE_NORMDELTA > 0
+ norm_delta = TSL_linrot_NormDelta(p_Ch, idx); // Normalize the Delta
+#else
+ norm_delta = p_Ch->Delta; // Take only the Delta
+#endif
+
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta <= -lth) // Warning!!! The threshold is inverted
+#else
+ if (norm_delta <= -th) // Warning!!! The threshold is inverted
+#endif
+ {
+ return TSL_STATUS_OK;
+ }
+
+ p_Ch++;
+ }
+
+ return TSL_STATUS_ERROR;
+}
+
+
+/**
+ * @brief Check if at least one channel is above or equal a threshold
+ * @param th Threshold
+ * @param coeff Enable or Disable the multiplier coefficient on threshold
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DeltaAboveEqu(TSL_tThreshold_T th, TSL_tIndex_T coeff)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ TSL_tDelta_T norm_delta;
+
+#if TSLPRM_COEFF_TH > 0
+ uint16_t lth;
+ if (coeff)
+ {
+ lth = (uint16_t)((uint16_t)th << TSLPRM_COEFF_TH);
+ }
+ else
+ {
+ lth = th;
+ }
+#endif
+
+ // Return OK if at least one channel is above or equal the threshold
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+
+#if TSLPRM_LINROT_USE_NORMDELTA > 0
+ norm_delta = TSL_linrot_NormDelta(p_Ch, idx); // Normalize the Delta
+#else
+ norm_delta = p_Ch->Delta; // Take only the Delta
+#endif
+
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta >= lth)
+#else
+ if (norm_delta >= th)
+#endif
+ {
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta < 0)
+ {
+ p_Ch++;
+ continue;
+ }
+#endif
+ return TSL_STATUS_OK;
+ }
+ p_Ch++;
+ }
+ return TSL_STATUS_ERROR;
+}
+
+
+/**
+ * @brief Check if at least one channel is stricly above a threshold
+ * @param th Threshold
+ * @param coeff Enable or Disable the multiplier coefficient on threshold
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_One_DeltaAbove(TSL_tThreshold_T th, TSL_tIndex_T coeff)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ TSL_tDelta_T norm_delta;
+
+#if TSLPRM_COEFF_TH > 0
+ uint16_t lth;
+ if (coeff)
+ {
+ lth = (uint16_t)((uint16_t)th << TSLPRM_COEFF_TH);
+ }
+ else
+ {
+ lth = th;
+ }
+#endif
+
+ // Return OK if at least one channel is above the threshold
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+
+#if TSLPRM_LINROT_USE_NORMDELTA > 0
+ norm_delta = TSL_linrot_NormDelta(p_Ch, idx); // Normalize the Delta
+#else
+ norm_delta = p_Ch->Delta; // Take only the Delta
+#endif
+
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta > lth)
+#else
+ if (norm_delta > th)
+#endif
+ {
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta < 0)
+ {
+ p_Ch++;
+ continue;
+ }
+#endif
+ return TSL_STATUS_OK;
+ }
+ p_Ch++;
+ }
+ return TSL_STATUS_ERROR;
+}
+
+
+/**
+ * @brief Check if all channels are below or equal a threshold
+ * @param th Threshold
+ * @param coeff Enable or Disable the multiplier coefficient on threshold
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_linrot_ProcessCh_All_DeltaBelowEqu(TSL_tThreshold_T th, TSL_tIndex_T coeff)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ TSL_tDelta_T norm_delta;
+
+#if TSLPRM_COEFF_TH > 0
+ uint16_t lth;
+ if (coeff)
+ {
+ lth = (uint16_t)((uint16_t)th << TSLPRM_COEFF_TH);
+ }
+ else
+ {
+ lth = th;
+ }
+#endif
+
+ // Return OK if ALL channels are below or equal the threshold
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+
+#if TSLPRM_LINROT_USE_NORMDELTA > 0
+ norm_delta = TSL_linrot_NormDelta(p_Ch, idx); // Normalize the Delta
+#else
+ norm_delta = p_Ch->Delta; // Take only the Delta
+#endif
+
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta > lth)
+#else
+ if (norm_delta > th)
+#endif
+ {
+#if TSLPRM_COEFF_TH > 0
+ if (norm_delta < 0)
+ {
+ p_Ch++;
+ continue;
+ }
+#endif
+ return TSL_STATUS_ERROR;
+ }
+ p_Ch++;
+ }
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Clear the Reference and ReferenceRest for all channels
+ * @param None
+ * @retval None
+ */
+void TSL_linrot_ProcessCh_All_ClearRef(void)
+{
+ TSL_tIndex_T idx;
+ TSL_ChannelData_T *p_Ch = TSL_Globals.This_LinRot->p_ChD;
+ for (idx = 0; idx < THIS_NB_CHANNELS; idx++)
+ {
+ p_Ch->Ref = 0;
+ p_Ch->RefRest = 0;
+ p_Ch++;
+ }
+}
+
+
+/**
+ * @brief Normalize a Delta value
+ * @param ch Pointer to the current channel
+ * @param idx Index of the channel
+ * @retval Normalized Delta value
+ */
+TSL_tDelta_T TSL_linrot_NormDelta(TSL_ChannelData_T *ch, TSL_tIndex_T idx)
+{
+ uint32_t tmpdelta = ch->Delta;
+
+ // Apply coefficient
+ if (TSL_Globals.This_LinRot->p_DeltaCoeff[idx] != 0x0100)
+ {
+ tmpdelta = (uint32_t)(tmpdelta * TSL_Globals.This_LinRot->p_DeltaCoeff[idx]);
+ tmpdelta = tmpdelta >> (uint8_t)8;
+ }
+
+ return (TSL_tDelta_T)tmpdelta;
+}
+
+#endif
+// #if TSLPRM_TOTAL_LNRTS > 0
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_object.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_object.c
new file mode 100644
index 0000000..7c2e9bf
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_object.c
@@ -0,0 +1,258 @@
+/**
+ ******************************************************************************
+ * @file tsl_object.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the sensors in general.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_object.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Initialize a group of Objects
+ * @param[in] objgrp Pointer to the group of objects
+ * @retval None
+ */
+void TSL_obj_GroupInit(TSL_ObjectGroup_T *objgrp)
+{
+ TSL_tIndex_T idx_obj;
+ CONST TSL_Object_T *pobj;
+ TSL_tNb_T objgrp_state_mask = 0;
+
+ pobj = objgrp->p_Obj; // First object in the group
+
+ objgrp->Change = TSL_STATE_NOT_CHANGED;
+
+ // Process all objects
+ for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++)
+ {
+
+ // Assign global object
+ TSL_obj_SetGlobalObj(pobj);
+
+ switch (pobj->Type)
+ {
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_TOUCHKEYS > 0
+ case TSL_OBJ_TOUCHKEY:
+ // Call the specific method
+ TSL_Globals.This_TKey->p_Methods->Init();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_TKey->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Update object group state mask
+ objgrp_state_mask |= TSL_Globals.This_TKey->p_SM[TSL_Globals.This_TKey->p_Data->StateId].StateMask;
+ break;
+#endif
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_TOUCHKEYS_B > 0
+ case TSL_OBJ_TOUCHKEYB:
+ // Call the default method
+ TSL_Params.p_TKeyMT->Init();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_TKey->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Get object state mask from state machine in TSL_Params
+ objgrp_state_mask |= TSL_Params.p_TKeySM[TSL_Globals.This_TKey->p_Data->StateId].StateMask;
+ break;
+#endif
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_LINROTS > 0
+ case TSL_OBJ_LINEAR:
+ case TSL_OBJ_ROTARY:
+ // Call the specific method
+ TSL_Globals.This_LinRot->p_Methods->Init();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_LinRot->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Update object group state mask
+ objgrp_state_mask |= TSL_Globals.This_LinRot->p_SM[TSL_Globals.This_LinRot->p_Data->StateId].StateMask;
+ break;
+#endif
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_LINROTS_B > 0
+ case TSL_OBJ_LINEARB:
+ case TSL_OBJ_ROTARYB:
+ // Call the default method
+ TSL_Params.p_LinRotMT->Init();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_LinRot->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Get object state mask from state machine in TSL_Params
+ objgrp_state_mask |= TSL_Params.p_LinRotSM[TSL_Globals.This_LinRot->p_Data->StateId].StateMask;
+ break;
+#endif
+ default:
+ break;
+ }
+
+ pobj++; // Next object
+ }
+
+ // Update the object group state mask
+ objgrp->StateMask = objgrp_state_mask;
+}
+
+
+/**
+ * @brief Process the state machine on a group of Objects
+ * @param[in] objgrp Pointer to the group of objects to process
+ * @retval None
+ */
+void TSL_obj_GroupProcess(TSL_ObjectGroup_T *objgrp)
+{
+ TSL_tIndex_T idx_obj;
+ CONST TSL_Object_T *pobj;
+ TSL_tNb_T objgrp_state_mask = 0;
+
+ pobj = objgrp->p_Obj; // First object in the group
+
+ objgrp->Change = TSL_STATE_NOT_CHANGED;
+
+ // Process all objects
+ for (idx_obj = 0; idx_obj < objgrp->NbObjects; idx_obj++)
+ {
+
+ // Assign global object
+ TSL_obj_SetGlobalObj(pobj);
+
+ switch (pobj->Type)
+ {
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_TOUCHKEYS > 0
+ case TSL_OBJ_TOUCHKEY:
+ // Call the specific method
+ TSL_Globals.This_TKey->p_Methods->Process();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_TKey->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Update object group state mask
+ objgrp_state_mask |= TSL_Globals.This_TKey->p_SM[TSL_Globals.This_TKey->p_Data->StateId].StateMask;
+ break;
+#endif
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_TOUCHKEYS_B > 0
+ case TSL_OBJ_TOUCHKEYB:
+ // Call the default method
+ TSL_Params.p_TKeyMT->Process();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_TKey->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Get object state mask from state machine in TSL_Params
+ objgrp_state_mask |= TSL_Params.p_TKeySM[TSL_Globals.This_TKey->p_Data->StateId].StateMask;
+ break;
+#endif
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_LINROTS > 0
+ case TSL_OBJ_LINEAR:
+ case TSL_OBJ_ROTARY:
+ // Call the specific method
+ TSL_Globals.This_LinRot->p_Methods->Process();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_LinRot->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Update object group state mask
+ objgrp_state_mask |= TSL_Globals.This_LinRot->p_SM[TSL_Globals.This_LinRot->p_Data->StateId].StateMask;
+ break;
+#endif
+ //------------------------------------------------------------------------
+#if TSLPRM_TOTAL_LINROTS_B > 0
+ case TSL_OBJ_LINEARB:
+ case TSL_OBJ_ROTARYB:
+ // Call the default method
+ TSL_Params.p_LinRotMT->Process();
+ // Check if the object has changed of state
+ if (TSL_Globals.This_LinRot->p_Data->Change)
+ {
+ objgrp->Change = TSL_STATE_CHANGED;
+ }
+ // Get object state mask from state machine in TSL_Params
+ objgrp_state_mask |= TSL_Params.p_LinRotSM[TSL_Globals.This_LinRot->p_Data->StateId].StateMask;
+ break;
+#endif
+ default:
+ break;
+ }
+
+ pobj++; // Next object
+ }
+
+ // Update the object group state mask
+ objgrp->StateMask = objgrp_state_mask;
+}
+
+
+/**
+ * @brief Set the global object variable
+ * @param[in] pobj Pointer to the object to process
+ * @retval None
+ */
+void TSL_obj_SetGlobalObj(CONST TSL_Object_T *pobj)
+{
+
+ TSL_Globals.This_Obj = pobj;
+
+ switch (pobj->Type)
+ {
+#if TSLPRM_TOTAL_TKEYS > 0
+ case TSL_OBJ_TOUCHKEY:
+ case TSL_OBJ_TOUCHKEYB:
+ TSL_Globals.This_TKey = (TSL_TouchKey_T *)pobj->Elmt;
+ break;
+#endif
+#if TSLPRM_TOTAL_LNRTS > 0
+ case TSL_OBJ_LINEAR:
+ case TSL_OBJ_LINEARB:
+ case TSL_OBJ_ROTARY:
+ case TSL_OBJ_ROTARYB:
+ TSL_Globals.This_LinRot = (TSL_LinRot_T *)pobj->Elmt;
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_time.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_time.c
new file mode 100644
index 0000000..d274575
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_time.c
@@ -0,0 +1,174 @@
+/**
+ ******************************************************************************
+ * @file tsl_time.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the timings in general.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_time.h"
+#include "tsl_globals.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Management of the timing module interrupt service routine.
+ * @param None
+ * @retval None
+ */
+void TSL_tim_ProcessIT(void)
+{
+ static TSL_tTick_ms_T count_1s = 0;
+
+ // Count 1 global tick every xxx ms (defined by TSLPRM_TICK_FREQ parameter)
+ TSL_Globals.Tick_ms++;
+
+ // Check if 1 second has elapsed
+ count_1s++;
+ if (count_1s > (TSLPRM_TICK_FREQ - 1))
+ {
+ TSL_Globals.Tick_sec++; // 1 global tick every second
+ if (TSL_Globals.Tick_sec > 63) // Due to DTO counter on 6 bits...
+ {
+ TSL_Globals.Tick_sec = 0;
+ }
+ count_1s = 0;
+ }
+
+// Callback function
+#if TSLPRM_USE_TIMER_CALLBACK > 0
+ TSL_CallBack_TimerTick();
+#endif
+
+}
+
+
+/**
+ * @brief Check if a delay (in ms) has elapsed.
+ * This function must be called regularly due to counter Roll-over only managed one time.
+ * @param[in] delay_ms Delay in ms
+ * @param[in] last_tick Variable holding the last tick value
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_tim_CheckDelay_ms(TSL_tTick_ms_T delay_ms, __IO TSL_tTick_ms_T *last_tick)
+{
+ TSL_tTick_ms_T tick;
+ TSL_tTick_ms_T diff;
+
+ disableInterrupts();
+
+ tick = TSL_Globals.Tick_ms;
+
+ if (delay_ms == 0)
+ {
+ enableInterrupts();
+ return TSL_STATUS_ERROR;
+ }
+
+ // Counter Roll-over management
+ if (tick >= *last_tick)
+ {
+ diff = tick - *last_tick;
+ }
+ else
+ {
+ diff = (0xFFFF - *last_tick) + tick + 1;
+ }
+
+#if (TSLPRM_TICK_FREQ == 125)
+ if (diff >= (TSL_tTick_ms_T)(delay_ms >> 3)) // Divide by 8 for 8ms tick
+#endif
+#if (TSLPRM_TICK_FREQ == 250)
+ if (diff >= (TSL_tTick_ms_T)(delay_ms >> 2)) // Divide by 4 for 4ms tick
+#endif
+#if (TSLPRM_TICK_FREQ == 500)
+ if (diff >= (TSL_tTick_ms_T)(delay_ms >> 1)) // Divide by 2 for 2ms tick
+#endif
+#if (TSLPRM_TICK_FREQ == 1000)
+ if (diff >= (TSL_tTick_ms_T)delay_ms) // Direct value for 1ms tick
+#endif
+#if (TSLPRM_TICK_FREQ == 2000)
+ if (diff >= (TSL_tTick_ms_T)(delay_ms << 1)) // Multiply by 2 for 0.5ms tick
+#endif
+ {
+ // Save current time
+ *last_tick = tick;
+ enableInterrupts();
+ return TSL_STATUS_OK;
+ }
+
+ enableInterrupts();
+ return TSL_STATUS_BUSY;
+
+}
+
+
+/**
+ * @brief Check if a delay (in s) has elapsed.
+ * @param[in] delay_sec Delay in seconds
+ * @param[in] last_tick Variable holding the last tick value
+ * @retval Status
+ */
+TSL_Status_enum_T TSL_tim_CheckDelay_sec(TSL_tTick_sec_T delay_sec, __IO TSL_tTick_sec_T *last_tick)
+{
+ TSL_tTick_sec_T tick;
+ TSL_tTick_sec_T diff;
+
+ disableInterrupts();
+
+ tick = TSL_Globals.Tick_sec;
+
+ if (delay_sec == 0)
+ {
+ enableInterrupts();
+ return TSL_STATUS_ERROR;
+ }
+
+ // Counter Roll-over management
+ if (tick >= *last_tick)
+ {
+ diff = (TSL_tTick_sec_T)(tick - *last_tick);
+ }
+ else
+ {
+ diff = (TSL_tTick_sec_T)((63 - *last_tick) + tick + 1); // DTO counter is on 6 bits
+ }
+
+ if (diff >= delay_sec)
+ {
+ // Save current time
+ *last_tick = tick;
+ enableInterrupts();
+ return TSL_STATUS_OK;
+ }
+
+ enableInterrupts();
+ return TSL_STATUS_BUSY;
+
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f0xx.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f0xx.c
new file mode 100644
index 0000000..4db154a
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f0xx.c
@@ -0,0 +1,107 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm32f0xx.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the timing with STM32F0xx products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_time_stm32f0xx.h"
+#include "stm32f0xx_misc.h"
+#include "stm32f0xx_rtc.h"
+#include "stm32f0xx_tim.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Initialization of the timing module.
+ * @param None
+ * @retval Status Return TSL_STATUS_ERROR if the Systick configuration has failed.
+ */
+TSL_Status_enum_T TSL_tim_Init(void)
+{
+ // Program one systick interrupt every (1 / TSLPRM_TICK_FREQ) ms
+// if (SysTick_Config(SystemCoreClock / TSLPRM_TICK_FREQ))
+// {
+// return TSL_STATUS_ERROR;
+// }
+// else
+// {
+// return TSL_STATUS_OK;
+// }
+
+ NVIC_InitTypeDef NVIC_InitStructure;
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+
+ /* TouchSense_TIMx clock enable */
+ TS_RCC_APBxPeriphClockCmd ( TS_TIM_RCC, ENABLE );
+
+ /* Enable the TouchSense_TIMx gloabal Interrupt */
+ NVIC_InitStructure.NVIC_IRQChannel = TS_TIM_IRQx;
+ NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
+ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+ NVIC_Init ( &NVIC_InitStructure );
+
+ /* -----------------------------------------------------------------------
+ In this example TIM7 counter clock (TIM7CLK) is set to APB1 clock (PCLK1), since
+ APB1 prescaler is set to 1 and TIM7 prescaler is set to 0.
+
+ In this example TIM7 input clock (TIM7CLK) is set to APB1 clock (PCLK1),
+ since APB1 prescaler is set to 1.
+ TIM7CLK = PCLK1 = HCLK = SystemCoreClock
+
+ With Prescaler set to 479 and Period to 24999, the TIM7 counter is updated each 250 ms
+ (i.e. and interrupt is generated each 250 ms)
+ TIM7 counter clock = TIM7CLK /((Prescaler + 1)*(Period + 1))
+ = 48 MHz / ((25000)*(480))
+ = 4 Hz
+ ==> TIM7 counter period = 250 ms
+
+ Note:
+ SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file.
+ Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
+ function to update SystemCoreClock variable value. Otherwise, any configuration
+ based on this variable will be incorrect.
+ ----------------------------------------------------------------------- */
+
+ /* Time base configuration */
+ TIM_TimeBaseStructure.TIM_Period = 1000; // Ýòî ìèêñðîñåêóíäû //24999
+ TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock/1000000)-1; //479;
+ TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
+ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInit ( TS_TIMx, &TIM_TimeBaseStructure );
+
+ /* TouchSense_TIMx Interrupts enable */
+ TIM_ITConfig ( TS_TIMx, TIM_IT_Update, ENABLE );
+
+ /* TouchSense_TIMx enable counter */
+ TIM_Cmd ( TS_TIMx, ENABLE );
+
+ return TSL_STATUS_OK;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f3xx.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f3xx.c
new file mode 100644
index 0000000..15135e7
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32f3xx.c
@@ -0,0 +1,55 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm32f3xx.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the timing with STM32F3xx products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_time_stm32f3xx.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Initialization of the timing module.
+ * @param None
+ * @retval Status Return TSL_STATUS_ERROR if the Systick configuration has failed.
+ */
+TSL_Status_enum_T TSL_tim_Init(void)
+{
+ // Program one systick interrupt every (1 / TSLPRM_TICK_FREQ) ms
+ if (SysTick_Config(SystemCoreClock / TSLPRM_TICK_FREQ))
+ {
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ return TSL_STATUS_OK;
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32l1xx.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32l1xx.c
new file mode 100644
index 0000000..6dfe699
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm32l1xx.c
@@ -0,0 +1,55 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm32l1xx.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the timing with STM32L1xx products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_time_stm32l1xx.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Initialization of the timing module.
+ * @param None
+ * @retval Status Return TSL_STATUS_ERROR if the Systick configuration has failed.
+ */
+TSL_Status_enum_T TSL_tim_Init(void)
+{
+ // Program one systick interrupt every (1 / TSLPRM_TICK_FREQ) ms
+ if (SysTick_Config(SystemCoreClock / TSLPRM_TICK_FREQ))
+ {
+ return TSL_STATUS_ERROR;
+ }
+ else
+ {
+ return TSL_STATUS_OK;
+ }
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8l.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8l.c
new file mode 100644
index 0000000..06904eb
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8l.c
@@ -0,0 +1,108 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm8l.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the timing with STM8L products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_time_stm8l.h"
+#include "tsl_time.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+
+/**
+ * @brief Initialization of the timing module.
+ * @param None
+ * @retval Status Return TSL_STATUS_ERROR if the clock divider is wrong
+ */
+TSL_Status_enum_T TSL_tim_Init(void)
+{
+ // Enable TIM4 clock
+#if defined(STM8L10X)
+ CLK->PCKENR |= CLK_PCKENR_TIM4;
+#else // STM8L15X
+ CLK->PCKENR1 |= CLK_PCKENR1_TIM4;
+#endif
+
+ if (CLK->CKDIVR != 0x00) // Warning: The CPU frequency must be equal to 16 MHz
+ {
+ return TSL_STATUS_ERROR;
+ }
+
+ TIM4->SR1 = 0; // Clear overflow flag
+
+#if (TSLPRM_TICK_FREQ == 2000)
+ TIM4->PSCR = 6; // 16 MHz / 64 = 4 us clock
+ TIM4->ARR = 124; // 125 * 4 us = 0.5 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 1000)
+ TIM4->PSCR = 6; // 16 MHz / 64 = 4 us clock
+ TIM4->ARR = 249; // 250 * 4 us = 1 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 500)
+ TIM4->PSCR = 8; // 16 MHz / 256 = 16 us clock
+ TIM4->ARR = 124; // 125 * 16 us = 2 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 250)
+ TIM4->PSCR = 8; // 16 MHz / 256 = 16 us clock
+ TIM4->ARR = 249; // 250 * 16 us = 4 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 125)
+ TIM4->PSCR = 10; // 16 MHz / 1024 = 64 us clock
+ TIM4->ARR = 124; // 125 * 64 us = 8 ms
+#endif
+
+ TIM4->IER = 0x01; // Enable interrupt
+ TIM4->CR1 = 0x01; // Start timer
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Interrupt handler for TIM4 dedicated to ECS
+ * @param None
+ * @retval None
+ */
+#if defined(_COSMIC_)
+// 'svlreg option' is added to force the saving of the virtual long register
+@svlreg INTERRUPT_HANDLER(TSL_Timer_ISR, 25)
+#else
+INTERRUPT_HANDLER(TSL_Timer_ISR, 25)
+#endif
+{
+ TIM4->SR1 &= (uint8_t)(~TIM4_SR1_UIF);
+ TSL_tim_ProcessIT();
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8tl5x.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8tl5x.c
new file mode 100644
index 0000000..143ba5d
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_time_stm8tl5x.c
@@ -0,0 +1,104 @@
+/**
+ ******************************************************************************
+ * @file tsl_time_stm8tl5x.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage the timing with STM8TL5x products.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_time_stm8tl5x.h"
+#include "tsl_time.h"
+#include "stm8tl5x_it.h"
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private functions prototype -----------------------------------------------*/
+
+/**
+ * @brief Initialization of the timing module to generate periodic interruptions
+ * @warning The CPU frequency must be equal to 16 MHz
+ * @param None
+ * @retval Status Return TSL_STATUS_ERROR if the CPU freq in uncorrect.
+ */
+TSL_Status_enum_T TSL_tim_Init(void)
+{
+ CLK->PCKENR1 |= CLK_PCKENR1_TIM4; // The peripheral clock are not enable by default
+
+ if (CLK->CKDIVR != 0x00) // The CPU frequency must be equal to 16 MHz
+ {
+ return TSL_STATUS_ERROR;
+ }
+
+ TIM4->SR1 = 0; // Clear overflow flag
+
+#if (TSLPRM_TICK_FREQ == 2000)
+ TIM4->PSCR = 6; // 16 MHz / 64 = 4 us clock
+ TIM4->ARR = 124; // 125 * 4 us = 0.5 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 1000)
+ TIM4->PSCR = 6; // 16 MHz / 64 = 4 us clock
+ TIM4->ARR = 249; // 250 * 4 us = 1 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 500)
+ TIM4->PSCR = 8; // 16 MHz / 256 = 16 us clock
+ TIM4->ARR = 124; // 125 * 16 us = 2 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 250)
+ TIM4->PSCR = 8; // 16 MHz / 256 = 16 us clock
+ TIM4->ARR = 249; // 250 * 16 us = 4 ms
+#endif
+
+#if (TSLPRM_TICK_FREQ == 125)
+ TIM4->PSCR = 10; // 16 MHz / 1024 = 64 us clock
+ TIM4->ARR = 124; // 125 * 64 us = 8 ms
+#endif
+
+ TIM4->IER = 0x01; // Enable interrupt
+ TIM4->CR1 = 0x01; // Start timer
+
+ return TSL_STATUS_OK;
+}
+
+
+/**
+ * @brief Interrupt handler for TIM4 dedicated to ECS
+ * @param None
+ * @retval None
+ */
+#if defined(_COSMIC_)
+// 'svlreg option' is added to force the saving of the virtual long register
+@svlreg INTERRUPT_HANDLER(TSL_Timer_ISR, 25)
+#else
+INTERRUPT_HANDLER(TSL_Timer_ISR, 25)
+#endif
+{
+ TIM4->SR1 &= (uint8_t)(~TIM4_SR1_UIF);
+ TSL_tim_ProcessIT();
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/STMTouch_Driver/src/tsl_touchkey.c b/third_party/TouchSense/STMTouch_Driver/src/tsl_touchkey.c
new file mode 100644
index 0000000..c419e7c
--- /dev/null
+++ b/third_party/TouchSense/STMTouch_Driver/src/tsl_touchkey.c
@@ -0,0 +1,1089 @@
+/**
+ ******************************************************************************
+ * @file tsl_touchkey.c
+ * @author MCD Application Team
+ * @version V1.4.4
+ * @date 31-March-2014
+ * @brief This file contains all functions to manage TouchKey sensors.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "tsl_touchkey.h"
+#include "tsl_globals.h"
+
+#if TSLPRM_TOTAL_TKEYS > 0
+
+/* Private typedefs ----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+
+/* Private macros ------------------------------------------------------------*/
+
+#define THIS_MEAS TSL_Globals.This_TKey->p_ChD->Meas
+#define THIS_DELTA TSL_Globals.This_TKey->p_ChD->Delta
+#define THIS_REF TSL_Globals.This_TKey->p_ChD->Ref
+#define THIS_REFREST TSL_Globals.This_TKey->p_ChD->RefRest
+#define THIS_CHANNEL_DATA TSL_Globals.This_TKey->p_ChD
+#define THIS_ACQ_STATUS TSL_Globals.This_TKey->p_ChD->Flags.AcqStatus
+#define THIS_OBJ_STATUS TSL_Globals.This_TKey->p_ChD->Flags.ObjStatus
+#define THIS_DATA_READY TSL_Globals.This_TKey->p_ChD->Flags.DataReady
+
+#define THIS_STATEID TSL_Globals.This_TKey->p_Data->StateId
+#define THIS_CHANGE TSL_Globals.This_TKey->p_Data->Change
+#define THIS_COUNTER_DEB TSL_Globals.This_TKey->p_Data->CounterDebounce
+#define THIS_COUNTER_DTO TSL_Globals.This_TKey->p_Data->CounterDTO
+#define THIS_DXSLOCK TSL_Globals.This_TKey->p_Data->DxSLock
+
+#define THIS_PROXIN_TH TSL_Globals.This_TKey->p_Param->ProxInTh
+#define THIS_PROXOUT_TH TSL_Globals.This_TKey->p_Param->ProxOutTh
+#define THIS_DETECTIN_TH TSL_Globals.This_TKey->p_Param->DetectInTh
+#define THIS_DETECTOUT_TH TSL_Globals.This_TKey->p_Param->DetectOutTh
+#define THIS_CALIB_TH TSL_Globals.This_TKey->p_Param->CalibTh
+
+#define THIS_COUNTER_DEB_CALIB TSL_Globals.This_TKey->p_Param->CounterDebCalib
+#define THIS_COUNTER_DEB_PROX TSL_Globals.This_TKey->p_Param->CounterDebProx
+#define THIS_COUNTER_DEB_DETECT TSL_Globals.This_TKey->p_Param->CounterDebDetect
+#define THIS_COUNTER_DEB_RELEASE TSL_Globals.This_TKey->p_Param->CounterDebRelease
+#define THIS_COUNTER_DEB_ERROR TSL_Globals.This_TKey->p_Param->CounterDebError
+
+#if TSLPRM_DTO > 0
+#define DTO_GET_TIME {TSL_tkey_DTOGetTime();}
+#else
+#define DTO_GET_TIME
+#endif
+
+#if TSLPRM_COEFF_TH > 0
+#define TEST_DELTA(OPER,TH) (THIS_DELTA OPER (uint16_t)((uint16_t)TH << TSLPRM_COEFF_TH))
+#define TEST_DELTA_N(OPER,TH) (THIS_DELTA OPER -((uint16_t)((uint16_t)TH << TSLPRM_COEFF_TH)))
+#define TEST_DELTA_NEGATIVE {if (THIS_DELTA < 0) {return;}}
+#else
+#define TEST_DELTA(OPER,TH) (THIS_DELTA OPER TH)
+#define TEST_DELTA_N(OPER,TH) (THIS_DELTA OPER -(TH))
+#define TEST_DELTA_NEGATIVE
+#endif
+
+/* Private variables ---------------------------------------------------------*/
+
+static TSL_tNb_T CalibDiv;
+
+/* Private functions prototype -----------------------------------------------*/
+
+void TSL_tkey_DTOGetTime(void);
+
+
+//==============================================================================
+// "Object methods" functions
+//==============================================================================
+
+/**
+ * @brief Init parameters with default values from configuration file
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_Init(void)
+{
+ // Thresholds
+#if TSLPRM_USE_PROX > 0
+ THIS_PROXIN_TH = TSLPRM_TKEY_PROX_IN_TH;
+ THIS_PROXOUT_TH = TSLPRM_TKEY_PROX_OUT_TH;
+#endif
+ THIS_DETECTIN_TH = TSLPRM_TKEY_DETECT_IN_TH;
+ THIS_DETECTOUT_TH = TSLPRM_TKEY_DETECT_OUT_TH;
+ THIS_CALIB_TH = TSLPRM_TKEY_CALIB_TH;
+
+ // Debounce counters
+ THIS_COUNTER_DEB_CALIB = TSLPRM_DEBOUNCE_CALIB;
+#if TSLPRM_USE_PROX > 0
+ THIS_COUNTER_DEB_PROX = TSLPRM_DEBOUNCE_PROX;
+#endif
+ THIS_COUNTER_DEB_DETECT = TSLPRM_DEBOUNCE_DETECT;
+ THIS_COUNTER_DEB_RELEASE = TSLPRM_DEBOUNCE_RELEASE;
+ THIS_COUNTER_DEB_ERROR = TSLPRM_DEBOUNCE_ERROR;
+
+ // Initial state
+ TSL_tkey_SetStateCalibration(TSLPRM_CALIB_DELAY);
+}
+
+
+/**
+ * @brief Process the State Machine
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_Process(void)
+{
+ TSL_StateId_enum_T prev_state_id;
+
+ if ((THIS_DATA_READY != 0) || (THIS_STATEID == TSL_STATEID_OFF))
+ {
+
+ THIS_DATA_READY = TSL_DATA_NOT_READY; // The new data is processed
+
+ prev_state_id = THIS_STATEID;
+
+#if TSLPRM_TOTAL_TOUCHKEYS > 0
+ if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEY)
+ {
+ // Launch the TKey state function
+ TSL_Globals.This_TKey->p_SM[THIS_STATEID].StateFunc();
+ }
+#endif
+
+#if TSLPRM_TOTAL_TOUCHKEYS_B > 0
+ if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEYB)
+ {
+ // Launch the TSL_Params state function
+ TSL_Params.p_TKeySM[THIS_STATEID].StateFunc();
+ }
+#endif
+
+ // Check if the new state has changed
+ if (THIS_STATEID == prev_state_id)
+ {
+ THIS_CHANGE = TSL_STATE_NOT_CHANGED;
+ }
+ else
+ {
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ }
+
+#if TSLPRM_USE_DXS > 0
+ if (THIS_STATEID != TSL_STATEID_DETECT)
+ {
+ THIS_DXSLOCK = TSL_FALSE;
+ }
+ if (THIS_STATEID == TSL_STATEID_TOUCH)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ }
+#endif
+
+ }
+}
+
+
+//==============================================================================
+// Utility functions
+//==============================================================================
+
+/**
+ * @brief Go in Calibration state
+ * @param[in] delay Delay before calibration starts (stabilization of noise filter)
+ * @retval None
+ */
+void TSL_tkey_SetStateCalibration(TSL_tCounter_T delay)
+{
+ THIS_STATEID = TSL_STATEID_CALIB;
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ THIS_OBJ_STATUS = TSL_OBJ_STATUS_ON;
+
+ switch (TSL_Params.NbCalibSamples)
+ {
+ case 4:
+ CalibDiv = 2;
+ break;
+ case 16:
+ CalibDiv = 4;
+ break;
+ default:
+ TSL_Params.NbCalibSamples = 8;
+ CalibDiv = 3;
+ break;
+ }
+
+ // If a noise filter is used, the counter must be initialized to a value
+ // different from 0 in order to stabilize the filter.
+ THIS_COUNTER_DEB = (TSL_tCounter_T)(delay + (TSL_tCounter_T)TSL_Params.NbCalibSamples);
+ THIS_REF = 0;
+}
+
+
+/**
+ * @brief Go in Off state with sensor "off"
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_SetStateOff(void)
+{
+ THIS_STATEID = TSL_STATEID_OFF;
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ THIS_OBJ_STATUS = TSL_OBJ_STATUS_OFF;
+}
+
+
+#if !defined(TSLPRM_STM8TL5X) && !defined(STM8TL5X)
+/**
+ * @brief Go in Off state with sensor in "Burst mode only"
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_SetStateBurstOnly(void)
+{
+ THIS_STATEID = TSL_STATEID_OFF;
+ THIS_CHANGE = TSL_STATE_CHANGED;
+ THIS_OBJ_STATUS = TSL_OBJ_STATUS_BURST_ONLY;
+}
+#endif
+
+
+/**
+ * @brief Return the current state identifier
+ * @param None
+ * @retval State id
+ */
+TSL_StateId_enum_T TSL_tkey_GetStateId(void)
+{
+ return(THIS_STATEID);
+}
+
+
+/**
+ * @brief Return the current state mask
+ * @param None
+ * @retval State mask
+ */
+TSL_StateMask_enum_T TSL_tkey_GetStateMask(void)
+{
+ TSL_StateMask_enum_T state_mask = TSL_STATEMASK_UNKNOWN;
+
+#if TSLPRM_TOTAL_TOUCHKEYS > 0
+ if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEY)
+ {
+ state_mask = TSL_Globals.This_TKey->p_SM[THIS_STATEID].StateMask;
+ }
+#endif
+
+#if TSLPRM_TOTAL_TOUCHKEYS_B > 0
+ if (TSL_Globals.This_Obj->Type == TSL_OBJ_TOUCHKEYB)
+ {
+ state_mask = TSL_Params.p_TKeySM[THIS_STATEID].StateMask;
+ }
+#endif
+
+ return state_mask;
+}
+
+
+/**
+ * @brief Return the Change flag
+ * @param None
+ * @retval Change flag status
+ */
+TSL_tNb_T TSL_tkey_IsChanged(void)
+{
+ return(THIS_CHANGE);
+}
+
+
+//==============================================================================
+// State machine functions
+//==============================================================================
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Release processing (previous state = Proximity)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebReleaseProxStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_PROX; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ THIS_STATEID = TSL_STATEID_PROX; // Go back to the previous state
+ }
+ else
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ // else stay in Debounce Release
+ }
+ }
+}
+#endif // if TSLPRM_USE_PROX > 0
+
+
+/**
+ * @brief Debounce Release processing (previous state = Detect)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebReleaseDetectStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>, THIS_DETECTOUT_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_STATEID = TSL_STATEID_DETECT;
+ }
+ else
+ {
+#if TSLPRM_USE_PROX > 0
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ return;
+ }
+#endif
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ // else stay in Debounce Release
+ }
+ }
+}
+
+
+/**
+ * @brief Debounce Release processing (previous state = Touch)
+ * Same as Debounce Release Detect processing
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebReleaseTouchStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_TOUCH; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>, THIS_DETECTOUT_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ }
+ else
+ {
+#if TSLPRM_USE_PROX > 0
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ return;
+ }
+#endif
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ // else stay in Debounce Release
+ }
+ }
+}
+
+
+/**
+ * @brief Release state processing
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_ReleaseStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_RELEASE;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>=, THIS_DETECTIN_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_DETECT;
+ }
+ return;
+ }
+
+#if TSLPRM_USE_PROX > 0
+ if (THIS_DELTA >= THIS_PROXIN_TH)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX;
+ }
+ return;
+ }
+#endif
+
+ // Check delta for re-calibration
+ // Warning: the threshold value is inverted in the macro
+ if TEST_DELTA_N(<=, THIS_CALIB_TH)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_CALIB;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ TSL_tkey_SetStateCalibration(0);
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_CALIB;
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Debounce Calibration processing (previous state = Release)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebCalibrationStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE; // Go back to the previous state
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ // Still below recalibration threshold
+ // Warning: the threshold value is inverted in the macro
+ if TEST_DELTA_N(<=, THIS_CALIB_TH)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ TSL_tkey_SetStateCalibration(0);
+ }
+ // else stay in Debounce Calibration
+ }
+ else // Go back to previous state
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ }
+}
+
+
+/**
+ * @brief Calibration state processing
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_CalibrationStateProcess(void)
+{
+ TSL_tMeas_T new_meas;
+
+#if TSLPRM_CALIB_DELAY > 0
+ // Noise filter stabilization time
+ if (THIS_COUNTER_DEB > (TSL_tCounter_T)TSL_Params.NbCalibSamples)
+ {
+ THIS_COUNTER_DEB--;
+ return; // Skip the sample
+ }
+#endif
+
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_CALIB;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+
+ // Get the new measure or Calculate it
+#if TSLPRM_USE_MEAS > 0
+ new_meas = THIS_MEAS;
+#else // Calculate it
+ new_meas = TSL_acq_ComputeMeas(THIS_REF, THIS_DELTA);
+#endif
+
+ // Verify the first Reference value
+ if (THIS_COUNTER_DEB == (TSL_tCounter_T)TSL_Params.NbCalibSamples)
+ {
+ if (TSL_acq_TestFirstReferenceIsValid(THIS_CHANNEL_DATA, new_meas))
+ {
+ THIS_REF = new_meas;
+ }
+ else
+ {
+ THIS_REF = 0;
+ return;
+ }
+ }
+ else
+ {
+ // Add the measure in temporary Reference
+ THIS_REF += new_meas;
+
+ // Check reference overflow
+ if (THIS_REF < new_meas)
+ {
+ THIS_REF = 0; // Suppress the bad reference
+ THIS_STATEID = TSL_STATEID_ERROR;
+ return;
+ }
+ }
+
+ // Check that we have all the needed measurements
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ // Divide temporary Reference by the number of samples
+ THIS_REF >>= CalibDiv;
+ THIS_REFREST = 0;
+ THIS_DELTA = 0;
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ }
+}
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Proximity processing (previous state = Release)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebProxStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>=, THIS_DETECTIN_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_DETECT;
+ }
+ return;
+ }
+
+ if (THIS_DELTA >= THIS_PROXIN_TH)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Proximity
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ }
+}
+#endif
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Proximity processing (previous state = Detect)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebProxDetectStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>, THIS_DETECTOUT_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_STATEID = TSL_STATEID_DETECT;
+ return;
+ }
+
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Proximity
+ }
+ else
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_DETECT;
+ }
+ }
+ }
+}
+#endif
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Debounce Proximity processing (previous state = Touch)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebProxTouchStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>, THIS_DETECTOUT_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ return;
+ }
+
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Proximity
+ }
+ else
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_TOUCH;
+ }
+ }
+ }
+}
+#endif
+
+
+#if TSLPRM_USE_PROX > 0
+/**
+ * @brief Proximity state processing
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_ProxStateProcess(void)
+{
+#if TSLPRM_DTO > 0
+ TSL_tTick_sec_T tick_detected;
+#endif
+
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_PROX;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>=, THIS_DETECTIN_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_DETECT;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_DETECT;
+ }
+ return;
+ }
+
+ if (THIS_DELTA <= THIS_PROXOUT_TH)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_PROX;
+ }
+ return;
+ }
+
+ // Stay in Proximity state
+#if TSLPRM_DTO > 0
+ //------------------------------------
+ // Detection Time Out (DTO) processing
+ //------------------------------------
+ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64))
+ {
+ tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved
+ // Enter in calibration state if the DTO duration has elapsed
+ if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK)
+ {
+ TSL_tkey_SetStateCalibration(0);
+ }
+ }
+#endif
+
+ }
+}
+#endif
+
+
+/**
+ * @brief Debounce Detect processing (previous state = Release or Proximity)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebDetectStateProcess(void)
+{
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>=, THIS_DETECTIN_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_DETECT;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ // else stay in Debounce Detect
+ }
+ else
+ {
+#if TSLPRM_USE_PROX > 0
+ if (THIS_DELTA >= THIS_PROXIN_TH)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX;
+ }
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+#else
+ THIS_STATEID = TSL_STATEID_RELEASE;
+#endif
+ }
+ }
+}
+
+
+/**
+ * @brief Detect state processing
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DetectStateProcess(void)
+{
+#if TSLPRM_DTO > 0
+ TSL_tTick_sec_T tick_detected;
+#endif
+
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_DETECT;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>, THIS_DETECTOUT_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+#if TSLPRM_DTO > 0
+ //------------------------------------
+ // Detection Time Out (DTO) processing
+ //------------------------------------
+ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64))
+ {
+ tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved
+ // Enter in calibration state if the DTO duration has elapsed
+ if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK)
+ {
+ TSL_tkey_SetStateCalibration(0);
+ }
+ }
+#endif
+ return; // Normal operation, stay in Detect state
+ }
+
+#if TSLPRM_USE_PROX > 0
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX_DETECT;
+ }
+ return;
+ }
+#endif
+
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_DETECT;
+ }
+
+ }
+}
+
+
+/**
+ * @brief Touch state processing
+ * Same as Detect state
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_TouchStateProcess(void)
+{
+#if TSLPRM_DTO > 0
+ TSL_tTick_sec_T tick_detected;
+#endif
+
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_ERROR;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_ERROR_TOUCH;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ if TEST_DELTA(>, THIS_DETECTOUT_TH)
+ {
+ TEST_DELTA_NEGATIVE;
+#if TSLPRM_DTO > 0
+ //------------------------------------
+ // Detection Time Out (DTO) processing
+ //------------------------------------
+ if ((TSL_Params.DTO > 1) && (TSL_Params.DTO < 64))
+ {
+ tick_detected = THIS_COUNTER_DTO; // Get the detected time previously saved
+ // Enter in calibration state if the DTO duration has elapsed
+ if (TSL_tim_CheckDelay_sec(TSL_Params.DTO, &tick_detected) == TSL_STATUS_OK)
+ {
+ TSL_tkey_SetStateCalibration(0);
+ }
+ }
+#endif
+ return; // Normal operation, stay in Touch state
+ }
+
+#if TSLPRM_USE_PROX > 0
+ if (THIS_DELTA > THIS_PROXOUT_TH)
+ {
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_PROX;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_PROX;
+ DTO_GET_TIME; // Take current time for DTO processing
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_PROX_TOUCH;
+ }
+ return;
+ }
+#endif
+
+ THIS_COUNTER_DEB = THIS_COUNTER_DEB_RELEASE;
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ }
+ else
+ {
+ THIS_STATEID = TSL_STATEID_DEB_RELEASE_TOUCH;
+ }
+
+ }
+}
+
+
+/**
+ * @brief Debounce error state processing
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DebErrorStateProcess(void)
+{
+ volatile TSL_StateMask_enum_T mask;
+
+ if (THIS_ACQ_STATUS & TSL_ACQ_STATUS_ERROR_MASK) // Acquisition error (min or max)
+ {
+ if (THIS_COUNTER_DEB > 0) {THIS_COUNTER_DEB--;}
+ if (THIS_COUNTER_DEB == 0)
+ {
+ THIS_STATEID = TSL_STATEID_ERROR;
+ }
+ }
+ else // Acquisition is OK or has NOISE
+ {
+ // Get state mask
+ mask = TSL_tkey_GetStateMask();
+ // Mask Error and Debounce bits
+#ifdef _RAISONANCE_
+ mask &= ~(TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK);
+#else
+ mask &= (TSL_StateMask_enum_T)(~(TSL_STATE_DEBOUNCE_BIT_MASK | TSL_STATE_ERROR_BIT_MASK));
+#endif
+ // Go back to the previous state
+ switch (mask)
+ {
+ case TSL_STATEMASK_RELEASE :
+ THIS_STATEID = TSL_STATEID_RELEASE;
+ break;
+ case TSL_STATEMASK_PROX :
+ THIS_STATEID = TSL_STATEID_PROX;
+ break;
+ case TSL_STATEMASK_DETECT :
+ THIS_STATEID = TSL_STATEID_DETECT;
+ break;
+ case TSL_STATEMASK_TOUCH :
+ THIS_STATEID = TSL_STATEID_TOUCH;
+ break;
+ default:
+ TSL_tkey_SetStateCalibration(0);
+ break;
+ }
+ }
+}
+
+
+//==============================================================================
+// Private functions
+//==============================================================================
+
+/**
+ * @brief Get the current time in second and affect it to the DTO counter (Private)
+ * @param None
+ * @retval None
+ */
+void TSL_tkey_DTOGetTime(void)
+{
+ disableInterrupts();
+ THIS_COUNTER_DTO = (TSL_tCounter_T)TSL_Globals.Tick_sec;
+ enableInterrupts();
+}
+
+#endif
+// #if TSLPRM_TOTAL_TKEYS > 0
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/stmCriticalSection.c b/third_party/TouchSense/stmCriticalSection.c
new file mode 100644
index 0000000..9b763f4
--- /dev/null
+++ b/third_party/TouchSense/stmCriticalSection.c
@@ -0,0 +1,59 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : stmCriticalSection.c
+* Author : MCD Tools Development
+* Version : V1.0
+* Date : 21/02/2013
+* Description : This file provides a mechanism for STMStudio host/target
+* synchronization. Based on a critical section, using few
+* target resources (in term of code and RAM), but
+* potentially impacting the application runtime (possible
+* waiting loop when enterring the critical section).
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+/* Implementation of Peterson's algorithm for mutual exclusive access to
+ data, between the STMStudio host and the target processor.
+ The use of the critical section ensures the coherence of a set of data: it is
+ not possible for the STMStudio host to read data while the target is in the
+ critical section.
+ The target should enter the critical section (waiting loop possible, if the
+ STMStudio host is being reading) before modifying data that are identified as
+ critical ones. Then leave the critical section in order to allow the
+ STMStudio host to read them.
+ The host also enters the critical section before each reading, and leaves it
+ afterwards.
+ Note that it is not mandatory for the target to protect all spied variables
+ into the critical section; and that the synchronization might generate
+ relatively long waiting loops on the target side. As a result the critical
+ section should be used only for word-variables or group of variables for
+ which the coherence is important.
+*/
+
+#include "stmCriticalSection.h"
+
+#define TARGET_LOCK_ID 0 // Do not modify - shared with STMStudio host software
+#define HOST_LOCK_ID 1 // Do not modify - shared with STMStudio host software
+
+typedef struct petersons_t {
+ volatile unsigned char flag[2]; // Do not modify - shared with STMStudio host software
+ volatile unsigned char turn; // Do not modify - shared with STMStudio host software
+} petersons_t;
+
+// stm_studio_lock symbol used by the STMStudio host software for synchronization
+petersons_t stm_studio_lock = { { 0, 0 }, TARGET_LOCK_ID }; // Do not modify - shared with STMStudio host software
+
+void enterLock (void) {
+ stm_studio_lock.flag[TARGET_LOCK_ID] = 1;
+ stm_studio_lock.turn = HOST_LOCK_ID;
+ while (stm_studio_lock.flag[HOST_LOCK_ID] && (stm_studio_lock.turn == HOST_LOCK_ID)) {}
+}
+
+void exitLock (void) {
+ stm_studio_lock.flag[TARGET_LOCK_ID] = 0;
+}
diff --git a/third_party/TouchSense/stmCriticalSection.h b/third_party/TouchSense/stmCriticalSection.h
new file mode 100644
index 0000000..dc864f7
--- /dev/null
+++ b/third_party/TouchSense/stmCriticalSection.h
@@ -0,0 +1,32 @@
+/******************** (C) COPYRIGHT 2014 STMicroelectronics ********************
+* File Name : stmCriticalSection.h
+* Author : MCD Tools Development
+* Version : V1.0
+* Date : 21/02/2013
+* Description : This file provides a mechanism for STMStudio host/target
+* synchronization. Based on a critical section, using few
+* target resources (in term of code and RAM), but
+* potentially impacting the application runtime (possible
+* waiting loop when enterring the critical section).
+********************************************************************************
+* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
+* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
+* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
+* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
+* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+*******************************************************************************/
+
+#ifndef STM_CRITICAL_SECTION_H
+#define STM_CRITICAL_SECTION_H
+
+/* To call before modifying any critical data. In case the host is inside or
+asked for enterring the critical section, this routine will wait for the host to
+leave the critical section. */
+void enterLock(void);
+
+/* Leave the critical section. If the host is waiting, access will be granted
+to him. Otherwise the first next one asking will own the turn. */
+void exitLock(void);
+
+#endif /* STM_CRITICAL_SECTION_H */
diff --git a/third_party/TouchSense/tsl_conf_stm32f0xx.h b/third_party/TouchSense/tsl_conf_stm32f0xx.h
new file mode 100644
index 0000000..64d3cfa
--- /dev/null
+++ b/third_party/TouchSense/tsl_conf_stm32f0xx.h
@@ -0,0 +1,630 @@
+/**
+ ******************************************************************************
+ * @file STM32F072B_Ex01_2TKeys_EVAL\inc\tsl_conf_stm32f0xx.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 04-April-2014
+ * @brief Acquisition parameters for STM32F0xx products.
+ * @note This file must be copied in the application project and values
+ * changed for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_CONF_STM32F0XX_H
+#define __TSL_CONF_STM32F0XX_H
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//+++++++++++++++++++++++++++ COMMON PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup Common_Parameters Common Parameters
+ * @{ */
+
+//==============================================================================
+// Number of elements
+//==============================================================================
+
+/** @defgroup Common_Parameters_Number_Of_Elements 01 - Number of elements
+ * @{ */
+
+/** Total number of channels in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_CHANNELS (2)
+
+/** Total number of banks in application (range=1..255)
+*/
+#define TSLPRM_TOTAL_BANKS (2)
+
+/** Total number of "Extended" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS (2)
+
+/** Total number of "Basic" TouchKeys in application (range=0..255)
+*/
+#define TSLPRM_TOTAL_TOUCHKEYS_B (0)
+
+/** Total number of "Extended" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS (0)
+
+/** Total number of "Basic" Linear and Rotary sensors in application (range=0..255)
+ - Count also the 1-channel linear sensor used as TouchKey
+*/
+#define TSLPRM_TOTAL_LINROTS_B (0)
+
+/** Total number of sensors/objects in application (range=1..255)
+ - Count all TouchKeys, Linear and Rotary sensors
+*/
+#define TSLPRM_TOTAL_OBJECTS (2)
+
+/** @} Common_Parameters_Number_Of_Elements */
+
+//==============================================================================
+// Optional features
+//==============================================================================
+
+/** @defgroup Common_Parameters_Options 02 - Optional features
+ * @{ */
+
+/** Record the last measure (0=No, 1=Yes)
+ - If No the measure is recalculated using the Reference and Delta
+*/
+#define TSLPRM_USE_MEAS (1)
+
+/** Zone management usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_ZONE (0)
+
+/** Proximity detection usage (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_PROX (0)
+
+/** Use the Timer tick callback (0=No, 1=Yes)
+ - When equal to 1, the function TSL_CallBack_TimerTick must be defined in
+ the application code. It is called for each timer interruption.
+*/
+#define TSLPRM_USE_TIMER_CALLBACK (0)
+
+/** Acquisition interrupt mode (0=No, 1=Yes)
+ - If No the TS interrupt is not used.
+ - If Yes the TS interrupt is used.
+*/
+#define TSLPRM_USE_ACQ_INTERRUPT (0)
+
+/** @} Common_Parameters_Options */
+
+//==============================================================================
+// Acquisition limits
+//==============================================================================
+
+/** @defgroup Common_Parameters_Acquisition_Limits 03 - Acquisition limits
+ * @{ */
+
+/** Minimum acquisition measurement (range=0..65535)
+ - This is the minimum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is below this value.
+*/
+#define TSLPRM_ACQ_MIN (10)
+
+/** Maximum acquisition measurement (range=255, 511, 1023, 2047, 8191, 16383)
+ - This is the maximum acceptable value for the acquisition measure.
+ - The acquisition will be in error if the measure is above this value.
+*/
+#define TSLPRM_ACQ_MAX (8191)
+
+
+/** @} Common_Parameters_Acquisition_Limits */
+
+//==============================================================================
+// Calibration
+//==============================================================================
+
+/** @defgroup Common_Parameters_Calibration 04 - Calibration
+ * @{ */
+
+/** Number of calibration samples (range=4, 8, 16)
+ - Low value = faster calibration but less precision.
+ - High value = slower calibration but more precision.
+*/
+#define TSLPRM_CALIB_SAMPLES (4)
+
+/** Delay in measurement samples before starting the calibration (range=0..40)
+ - This is useful if a noise filter is used.
+ - Write 0 to disable the delay.
+*/
+#define TSLPRM_CALIB_DELAY (0)
+
+/** @} Common_Parameters_Calibration */
+
+//==============================================================================
+// Thresholds for TouchKey sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_TouchKey_Thresholds 05 - Thresholds for TouchKey sensors
+ * @{ */
+
+/** TouchKeys Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_TKEY_PROX_IN_TH (6)
+
+/** TouchKeys Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_TKEY_PROX_OUT_TH (5)
+
+/** TouchKeys Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_TKEY_DETECT_IN_TH (12)//(150)
+
+/** TouchKeys Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_TKEY_DETECT_OUT_TH (8)//(100)
+
+/** TouchKeys re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+*/
+#define TSLPRM_TKEY_CALIB_TH (15)
+
+/** TouchKey, Linear and Rotary sensors thresholds coefficient (range=0..4)
+ This multiplier coefficient is applied on Detect and Re-Calibration thresholds only.
+ - 0: feature disabled
+ - 1: thresholds x 2
+ - 2: thresholds x 4
+ - 3: thresholds x 8
+ - 4: thresholds x 16
+*/
+#define TSLPRM_COEFF_TH (0)
+
+/** @} Common_Parameters_TouchKey_Thresholds */
+
+//==============================================================================
+// Thresholds for Linear and Rotary sensors
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Thresholds 06 - Thresholds for Linear and Rotary sensors
+ * @{ */
+
+/** Linear/Rotary Proximity state input threshold (range=0..255)
+ - Enter Proximity state if delta is above
+*/
+#define TSLPRM_LINROT_PROX_IN_TH (10)
+
+/** Linear/Rotary Proximity state output threshold (range=0..255)
+ - Exit Proximity state if delta is below
+*/
+#define TSLPRM_LINROT_PROX_OUT_TH (5)
+
+/** Linear/Rotary Detect state input threshold (range=0..255)
+ - Enter Detect state if delta is above
+*/
+#define TSLPRM_LINROT_DETECT_IN_TH (20)
+
+/** Linear/Rotary Detect state output threshold (range=0..255)
+ - Exit Detect state if delta is below
+*/
+#define TSLPRM_LINROT_DETECT_OUT_TH (15)
+
+/** Linear/Rotary re-Calibration threshold (range=0..255)
+ - @warning The value is inverted in the sensor state machine
+ - Enter Calibration state if delta is below
+ - A low absolute value will result in a higher sensitivity and thus some spurious
+ recalibration may be issued.
+*/
+#define TSLPRM_LINROT_CALIB_TH (20)
+
+/** Linear/Rotary Delta normalization (0=No, 1=Yes)
+ - When this parameter is set, a coefficient is applied on all Delta of all sensors
+ in order to normalize them and to improve the position calculation.
+ - These coefficients must be defined in a constant table in the application (see Library examples).
+ - The MSB is the coefficient integer part, the LSB is the coefficient real part.
+ - Examples:
+ - To apply a factor 1.10:
+ 0x01 to the MSB
+ 0x1A to the LSB (0.10 x 256 = 25.6 -> rounded to 26 = 0x1A)
+ - To apply a factor 0.90:
+ 0x00 to the MSB
+ 0xE6 to the LSB (0.90 x 256 = 230.4 -> rounded to 230 = 0xE6)
+ - To apply no factor:
+ 0x01 to the MSB
+ 0x00 to the LSB
+*/
+#define TSLPRM_LINROT_USE_NORMDELTA (0)
+
+/** @} Common_Parameters_LinRot_Thresholds */
+
+//==============================================================================
+// Linear/Rotary sensors used
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Used 07 - Linear/Rotary sensors used
+ * @{ */
+
+/** Select which Linear and Rotary sensors you use in your application.
+ - 0 = Not Used
+ - 1 = Used
+
+ LIN = Linear sensor
+ ROT = Rotary sensor
+ M1 = Mono electrodes design with 0/255 position at extremities of the sensor
+ M2 = Mono electrodes design
+ H = Half-ended electrodes design
+ D = Dual electrodes design
+*/
+#define TSLPRM_USE_3CH_LIN_M1 (0)
+#define TSLPRM_USE_3CH_LIN_M2 (0)
+#define TSLPRM_USE_3CH_LIN_H (0)
+#define TSLPRM_USE_3CH_ROT_M (0)
+
+#define TSLPRM_USE_4CH_LIN_M1 (0)
+#define TSLPRM_USE_4CH_LIN_M2 (0)
+#define TSLPRM_USE_4CH_LIN_H (0)
+#define TSLPRM_USE_4CH_ROT_M (0)
+
+#define TSLPRM_USE_5CH_LIN_M1 (0)
+#define TSLPRM_USE_5CH_LIN_M2 (0)
+#define TSLPRM_USE_5CH_LIN_H (0)
+#define TSLPRM_USE_5CH_ROT_M (0)
+#define TSLPRM_USE_5CH_ROT_D (0)
+
+#define TSLPRM_USE_6CH_LIN_M1 (0)
+#define TSLPRM_USE_6CH_LIN_M2 (0)
+#define TSLPRM_USE_6CH_LIN_H (0)
+#define TSLPRM_USE_6CH_ROT_M (0)
+
+/** @} Common_Parameters_LinRot_used */
+
+//==============================================================================
+// Linear/Rotary sensors position
+//==============================================================================
+
+/** @defgroup Common_Parameters_LinRot_Position 08 - Linear/Rotary sensors position
+ * @{ */
+
+/** Position resolution in number of bits (range=1..8)
+ - A Low value will result in a low resolution and will be less subject to noise.
+ - A High value will result in a high resolution and will be more subject to noise.
+*/
+#define TSLPRM_LINROT_RESOLUTION (7)
+
+/** Direction change threshold in position unit (range=0..255)
+ - Defines the default threshold used during the change direction process.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_POS (10)
+
+/** Direction change debounce (range=0..63)
+ - Defines the default integrator counter used during the change direction process.
+ - This counter is decremented when the same change in the position is detected and the direction will
+ change after this counter reaches zero.
+ - A Low value will result in a faster direction change.
+ - A High value will result in a slower direction change.
+*/
+#define TSLPRM_LINROT_DIR_CHG_DEB (1)
+
+/** @} Common_Parameters_LinRot_Position */
+
+//==============================================================================
+// Debounce counters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Debounce 09 - Debounce counters
+ * @{ */
+
+/** Proximity state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the Proximity detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_PROX (50)//(3)
+
+/** Detect state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the detection but with less noise filtering.
+ - A High value will result in improving the system noise immunity but will increase the system response time.
+*/
+#define TSLPRM_DEBOUNCE_DETECT (63)//(7)//(3)
+
+/** Release state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the end-detection but with less noise filtering.
+ - A High value will result in a lower sensitivity during the end-detection but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_RELEASE (63)//(6)//(3)
+
+/** Re-calibration state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity during the recalibration but with less noise filtering.
+ - A High value will result in a lower sensitivity during the recalibration but with more noise filtering.
+*/
+#define TSLPRM_DEBOUNCE_CALIB (63)//(3)
+
+/** Error state debounce in samples unit (range=0..63)
+ - A Low value will result in a higher sensitivity to enter in error state.
+ - A High value will result in a lower sensitivity to enter in error state.
+*/
+#define TSLPRM_DEBOUNCE_ERROR (3)
+
+/** @} Common_Parameters_Debounce */
+
+//==============================================================================
+// Environment Change System (ECS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_ECS 10 - ECS
+ * @{ */
+
+/** Environment Change System Slow K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_SLOW (10)
+
+/** Environment Change System Fast K factor (range=0..255)
+ - The higher value is K, the faster is the response time.
+*/
+#define TSLPRM_ECS_K_FAST (20)
+
+/** Environment Change System delay in msec (range=0..5000)
+ - The ECS will be started after this delay and when all sensors are in Release state.
+*/
+#define TSLPRM_ECS_DELAY (500)
+
+/** @} Common_Parameters_ECS */
+
+//==============================================================================
+// Detection Time Out (DTO)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DTO 11 - DTO
+ * @{ */
+
+/** Detection Time Out delay in seconds (range=0..63)
+ - Value 0: DTO processing not compiled in the code (to gain size if not used).
+ - Value 1: Default time out infinite.
+ - Value between 2 and 63: Default time out between value n-1 and n.
+ - Examples:
+ - With a DTO equal to 2, the time out is between 1s and 2s.
+ - With a DTO equal to 63, the time out is between 62s and 63s.
+
+@note The DTO can be changed in run-time by the application only if the
+ default value is between 1 and 63.
+*/
+#define TSLPRM_DTO (0)
+
+/** @} Common_Parameters_DTO */
+
+//==============================================================================
+// Detection Exclusion System (DXS)
+//==============================================================================
+
+/** @defgroup Common_Parameters_DXS 12 - DXS
+ * @{ */
+
+/** Detection Exclusion System (0=No, 1=Yes)
+*/
+#define TSLPRM_USE_DXS (0)
+
+/** @} Common_Parameters_DXS */
+
+//==============================================================================
+// Miscellaneous parameters
+//==============================================================================
+
+/** @defgroup Common_Parameters_Misc 13 - Miscellaneous
+ * @{ */
+
+/** Timing tick frequency in Hz (range=125, 250, 500, 1000, 2000)
+ - Result to a timing interrupt respectively every 8ms, 4ms, 2ms, 1ms, 0.5ms
+*/
+#define TSLPRM_TICK_FREQ (1000)
+
+/** Delay for discharging Cx and Cs capacitors (range=0..65535)
+ - The value corresponds to the Softdelay function parameter.
+ - 500 gives around 53 µs delay whatever HCLK
+ - 1000 gives around 106 µs delay whatever HCLK
+ - 2000 gives around 210 µs delay whatever HCLK
+*/
+#define TSLPRM_DELAY_DISCHARGE_ALL (1000)
+
+/** @} Common_Parameters_Misc */
+
+/** @} Common_Parameters */
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++ MCU PARAMETERS ++++++++++++++++++++++++++++++++
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+/** @defgroup STM32F0xx_Parameters STM32F0xx Parameters
+ * @{ */
+
+//==============================================================================
+// GPIO configuration
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_GPIO_Config 01 - TSC GPIOs Configuration
+ * @{ */
+
+/** TSC GPIOs Configuration selection (range=0..1)
+ - 0: Manual. The TSC GPIOs configuration must be done by the application code.
+ - 1: Automatic. The TSLPRM_TSC_GROUPx_IOy parameters below must be filled up.
+ The TSC GPIOs configuration is automatically done by the STMTouch driver.
+*/
+#define TSLPRM_TSC_GPIO_CONFIG (1)
+
+//+++ DO NOT CHANGE THESE VALUES +++++++++++++++++++++++++++++++++
+// These defines must be applied to the TSLPRM_TSC_GROUPx_IOy parameters below.
+#define NU (0) // Not Used IO
+#define CHANNEL (1) // Channel IO
+#define SHIELD (2) // Shield IO (= Channel IO but not acquired)
+#define SAMPCAP (3) // Sampling Capacitor IO
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// If TSLPRM_TSC_GPIO_CONFIG=1 assign each TSLPRM_TSC_GROUPx_IOy parameters below.
+// If TSLPRM_TSC_GPIO_CONFIG=0 these parameters are ignored.
+
+#define TSLPRM_TSC_GROUP1_IO1 NU // PA0
+#define TSLPRM_TSC_GROUP1_IO2 NU // PA1
+#define TSLPRM_TSC_GROUP1_IO3 CHANNEL // PA2
+#define TSLPRM_TSC_GROUP1_IO4 SAMPCAP // PA3
+
+#define TSLPRM_TSC_GROUP2_IO1 NU//CHANNEL // PA4
+#define TSLPRM_TSC_GROUP2_IO2 NU//CHANNEL // PA5
+#define TSLPRM_TSC_GROUP2_IO3 NU//SAMPCAP // PA6
+#define TSLPRM_TSC_GROUP2_IO4 NU // PA7
+
+#define TSLPRM_TSC_GROUP3_IO1 NU // PC5
+#define TSLPRM_TSC_GROUP3_IO2 NU // PB0
+#define TSLPRM_TSC_GROUP3_IO3 NU // PB1
+#define TSLPRM_TSC_GROUP3_IO4 NU // PB2
+
+#define TSLPRM_TSC_GROUP4_IO1 NU//SHIELD // PA9
+#define TSLPRM_TSC_GROUP4_IO2 NU//SAMPCAP // PA10
+#define TSLPRM_TSC_GROUP4_IO3 NU // PA11
+#define TSLPRM_TSC_GROUP4_IO4 NU // PA12
+
+#define TSLPRM_TSC_GROUP5_IO1 CHANNEL // PB3
+#define TSLPRM_TSC_GROUP5_IO2 SAMPCAP // PB4
+#define TSLPRM_TSC_GROUP5_IO3 NU // PB6
+#define TSLPRM_TSC_GROUP5_IO4 NU // PB7
+
+#define TSLPRM_TSC_GROUP6_IO1 NU // PB11
+#define TSLPRM_TSC_GROUP6_IO2 NU // PB12
+#define TSLPRM_TSC_GROUP6_IO3 NU // PB13
+#define TSLPRM_TSC_GROUP6_IO4 NU // PB14
+
+// Warning: this group is available on some devices only.
+#define TSLPRM_TSC_GROUP7_IO1 NU // PE2
+#define TSLPRM_TSC_GROUP7_IO2 NU // PE3
+#define TSLPRM_TSC_GROUP7_IO3 NU // PE4
+#define TSLPRM_TSC_GROUP7_IO4 NU // PE5
+
+// Warning: this group is available on some devices only.
+#define TSLPRM_TSC_GROUP8_IO1 NU // PD12
+#define TSLPRM_TSC_GROUP8_IO2 NU // PD13
+#define TSLPRM_TSC_GROUP8_IO3 NU // PD14
+#define TSLPRM_TSC_GROUP8_IO4 NU // PD15
+
+/** @} STM32F0xx_Parameters_GPIO_Config */
+
+//==============================================================================
+// Charge Transfer Pulses
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_CT_Pulses 02 - Charge Transfer Pulses
+ * @{ */
+
+/** Charge Transfer Pulse High (range=0..15)
+ - 0: 1 x tPGCLK
+ - 1: 2 x tPGCLK
+ - ...
+ - 15: 16 x tPGCLK
+*/
+#define TSLPRM_TSC_CTPH (1)
+
+/** Charge Transfer Pulse Low (range=0..15)
+ - 0: 1 x tPGCLK
+ - 1: 2 x tPGCLK
+ - ...
+ - 15: 16 x tPGCLK
+*/
+#define TSLPRM_TSC_CTPL (1)
+
+/** Pulse Generator Prescaler (range=0..7)
+ - 0: fPGCLK = fHCLK
+ - 1: fPGCLK = fHCLK/2
+ - ...
+ - 7: fPGCLK = fHCLK/128
+*/
+#define TSLPRM_TSC_PGPSC (3)
+
+/** @} STM32F0xx_Parameters_CT_Pulses */
+
+//==============================================================================
+// IOs
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_IOs 03 - I/Os
+ * @{ */
+
+/** TSC IOs default mode when no on-going acquisition (range=0..1)
+ - 0: Output push-pull low
+ - 1: Input floating
+@note To ensure a correct operation in noisy environment, this parameter should
+be configured to output push-pull low.
+*/
+#define TSLPRM_TSC_IODEF (0)
+
+/** Acquisition Mode (range=0..1)
+ - 0: Normal acquisition mode
+ - 1: Synchronized acquisition mode
+*/
+#define TSLPRM_TSC_AM (0)
+
+/** Synchronization Pin (range=0..1)
+ - 0: PB08
+ - 1: PB10
+*/
+#define TSLPRM_TSC_SYNC_PIN (0)
+
+/** Synchronization Polarity (range=0..1)
+ - 0: Falling edge only
+ - 1: Rising edge and high level
+*/
+#define TSLPRM_TSC_SYNC_POL (0)
+
+/** @} STM32F0xx_Parameters_Misc */
+
+//==============================================================================
+// Spread Spectrum
+//==============================================================================
+
+/** @defgroup STM32F0xx_Parameters_SpreadSpectrum 04 - Spread Spectrum
+ * @{ */
+
+/** Use Spread Spectrum (0=No, 1=Yes)
+*/
+#define TSLPRM_TSC_USE_SS (0)
+
+/** Spread Spectrum Deviation (range=0..127)
+ - 0: 1 x tSSCLK
+ - 1: 2 x tSSCLK
+ - ...
+ - 127: 128 x tSSCLK
+*/
+#define TSLPRM_TSC_SSD (0)
+
+/** Spread Spectrum Prescaler (range=0..1)
+ - 0: fSSCLK = fHCLK
+ - 1: fSSCLK = fHCLK/2
+*/
+#define TSLPRM_TSC_SSPSC (0)
+
+/** @} STM32F0xx_Parameters_SpreadSpectrum */
+
+/** @} STM32F0xx_Parameters */
+
+// DO NOT REMOVE !!!
+#include "tsl_check_config.h"
+
+#endif /* __TSL_CONF_STM32F0XX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/tsl_user.c b/third_party/TouchSense/tsl_user.c
new file mode 100644
index 0000000..b7d50ef
--- /dev/null
+++ b/third_party/TouchSense/tsl_user.c
@@ -0,0 +1,292 @@
+/**
+ ******************************************************************************
+ * @file STM32F072B_Ex01_2TKeys_EVAL\src\tsl_user.c
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 04-April-2014
+ * @brief Touch-Sensing user configuration and api file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+#include "tsl_user.h"
+
+//==============================================================================
+// Channels
+//==============================================================================
+
+// Source and Configuration (ROM)
+CONST TSL_ChannelSrc_T MyChannels_Src[TSLPRM_TOTAL_CHANNELS] =
+{
+ { CHANNEL_0_SRC, CHANNEL_0_IO_MSK, CHANNEL_0_GRP_MSK },
+ { CHANNEL_1_SRC, CHANNEL_1_IO_MSK, CHANNEL_1_GRP_MSK }
+};
+
+// Destination (ROM)
+CONST TSL_ChannelDest_T MyChannels_Dest[TSLPRM_TOTAL_CHANNELS] =
+{
+ { CHANNEL_0_DEST },
+ { CHANNEL_1_DEST }
+};
+
+// Data (RAM)
+TSL_ChannelData_T MyChannels_Data[TSLPRM_TOTAL_CHANNELS];
+
+//==============================================================================
+// Banks
+//==============================================================================
+
+// List (ROM)
+CONST TSL_Bank_T MyBanks[TSLPRM_TOTAL_BANKS] = {
+ {&MyChannels_Src[0], &MyChannels_Dest[0], MyChannels_Data, BANK_0_NBCHANNELS, BANK_0_MSK_CHANNELS, BANK_0_MSK_GROUPS},
+ {&MyChannels_Src[1], &MyChannels_Dest[1], MyChannels_Data, BANK_1_NBCHANNELS, BANK_1_MSK_CHANNELS, BANK_1_MSK_GROUPS}
+};
+
+//==============================================================================
+// TouchKeys
+//==============================================================================
+
+// Data (RAM)
+TSL_TouchKeyData_T MyTKeys_Data[TSLPRM_TOTAL_TKEYS];
+
+// Parameters (RAM)
+TSL_TouchKeyParam_T MyTKeys_Param[TSLPRM_TOTAL_TKEYS];
+
+// State Machine (ROM)
+
+void MyTKeys_ErrorStateProcess(void);
+void MyTKeys_OffStateProcess(void);
+
+CONST TSL_State_T MyTKeys_StateMachine[] =
+{
+ // Calibration states
+ /* 0 */ { TSL_STATEMASK_CALIB, TSL_tkey_CalibrationStateProcess },
+ /* 1 */ { TSL_STATEMASK_DEB_CALIB, TSL_tkey_DebCalibrationStateProcess },
+ // Release states
+ /* 2 */ { TSL_STATEMASK_RELEASE, TSL_tkey_ReleaseStateProcess },
+#if TSLPRM_USE_PROX > 0
+ /* 3 */ { TSL_STATEMASK_DEB_RELEASE_PROX, TSL_tkey_DebReleaseProxStateProcess },
+#else
+ /* 3 */ { TSL_STATEMASK_DEB_RELEASE_PROX, 0 },
+#endif
+ /* 4 */ { TSL_STATEMASK_DEB_RELEASE_DETECT, TSL_tkey_DebReleaseDetectStateProcess },
+ /* 5 */ { TSL_STATEMASK_DEB_RELEASE_TOUCH, TSL_tkey_DebReleaseTouchStateProcess },
+#if TSLPRM_USE_PROX > 0
+ // Proximity states
+ /* 6 */ { TSL_STATEMASK_PROX, TSL_tkey_ProxStateProcess },
+ /* 7 */ { TSL_STATEMASK_DEB_PROX, TSL_tkey_DebProxStateProcess },
+ /* 8 */ { TSL_STATEMASK_DEB_PROX_DETECT, TSL_tkey_DebProxDetectStateProcess },
+ /* 9 */ { TSL_STATEMASK_DEB_PROX_TOUCH, TSL_tkey_DebProxTouchStateProcess },
+#else
+ /* 6 */ { TSL_STATEMASK_PROX, 0 },
+ /* 7 */ { TSL_STATEMASK_DEB_PROX, 0 },
+ /* 8 */ { TSL_STATEMASK_DEB_PROX_DETECT, 0 },
+ /* 9 */ { TSL_STATEMASK_DEB_PROX_TOUCH, 0 },
+#endif
+ // Detect states
+ /* 10 */ { TSL_STATEMASK_DETECT, TSL_tkey_DetectStateProcess },
+ /* 11 */ { TSL_STATEMASK_DEB_DETECT, TSL_tkey_DebDetectStateProcess },
+ // Touch state
+ /* 12 */ { TSL_STATEMASK_TOUCH, TSL_tkey_TouchStateProcess },
+ // Error states
+ /* 13 */ { TSL_STATEMASK_ERROR, MyTKeys_ErrorStateProcess },
+ /* 14 */ { TSL_STATEMASK_DEB_ERROR_CALIB, TSL_tkey_DebErrorStateProcess },
+ /* 15 */ { TSL_STATEMASK_DEB_ERROR_RELEASE, TSL_tkey_DebErrorStateProcess },
+ /* 16 */ { TSL_STATEMASK_DEB_ERROR_PROX, TSL_tkey_DebErrorStateProcess },
+ /* 17 */ { TSL_STATEMASK_DEB_ERROR_DETECT, TSL_tkey_DebErrorStateProcess },
+ /* 18 */ { TSL_STATEMASK_DEB_ERROR_TOUCH, TSL_tkey_DebErrorStateProcess },
+ // Other states
+ /* 19 */ { TSL_STATEMASK_OFF, MyTKeys_OffStateProcess }
+};
+
+// Methods for "extended" type (ROM)
+CONST TSL_TouchKeyMethods_T MyTKeys_Methods =
+{
+ TSL_tkey_Init,
+ TSL_tkey_Process
+};
+
+// TouchKeys list (ROM)
+CONST TSL_TouchKey_T MyTKeys[TSLPRM_TOTAL_TKEYS] =
+{
+ { &MyTKeys_Data[0], &MyTKeys_Param[0], &MyChannels_Data[CHANNEL_0_DEST], MyTKeys_StateMachine, &MyTKeys_Methods },
+ { &MyTKeys_Data[1], &MyTKeys_Param[1], &MyChannels_Data[CHANNEL_1_DEST], MyTKeys_StateMachine, &MyTKeys_Methods }
+};
+
+//==============================================================================
+// Generic Objects
+//==============================================================================
+
+// List (ROM)
+CONST TSL_Object_T MyObjects[TSLPRM_TOTAL_OBJECTS] =
+{
+ { TSL_OBJ_TOUCHKEY, (TSL_TouchKey_T *)&MyTKeys[0] },
+ { TSL_OBJ_TOUCHKEY, (TSL_TouchKey_T *)&MyTKeys[1] }
+};
+
+// Group (RAM)
+TSL_ObjectGroup_T MyObjGroup =
+{
+ &MyObjects[0], // First object
+ TSLPRM_TOTAL_OBJECTS, // Number of objects
+ 0x00, // State mask reset value
+ TSL_STATE_NOT_CHANGED,// Current state
+ 0, 0, 0 // ECS flags
+};
+
+//==============================================================================
+// TSL Common Parameters placed in RAM or ROM
+// --> external declaration in tsl_conf.h
+//==============================================================================
+
+TSL_Params_T TSL_Params =
+{
+ TSLPRM_ACQ_MIN,
+ TSLPRM_ACQ_MAX,
+ TSLPRM_CALIB_SAMPLES,
+ TSLPRM_DTO,
+#if TSLPRM_TOTAL_TKEYS > 0
+ MyTKeys_StateMachine, // Default state machine for TKeys
+ &MyTKeys_Methods, // Default methods for TKeys
+#endif
+#if TSLPRM_TOTAL_LNRTS > 0
+ MyLinRots_StateMachine, // Default state machine for LinRots
+ &MyLinRots_Methods // Default methods for LinRots
+#endif
+};
+
+/* Private functions prototype -----------------------------------------------*/
+
+/* Global variables ----------------------------------------------------------*/
+
+__IO TSL_tTick_ms_T Gv_ECS_last_tick; // Hold the last time value for ECS
+__IO uint32_t Gv_EOA; // Set by TS interrupt routine to indicate the End Of Acquisition
+
+
+/**
+ * @brief Initialize the STMTouch Driver
+ * @param None
+ * @retval None
+ */
+void TSL_user_Init(void)
+{
+#if TSLPRM_TSC_GPIO_CONFIG == 0
+ // Automatic GPIO configuration not selected:
+ // This function must be created by the user to initialize the Touch Sensing GPIOs.
+ TSL_user_InitGPIOs();
+#endif
+
+ TSL_obj_GroupInit(&MyObjGroup); // Init Objects
+
+ TSL_Init(MyBanks); // Init timing and acquisition modules
+
+ TSL_user_SetThresholds(); // Init thresholds for each object individually
+}
+
+
+/**
+ * @brief Execute STMTouch Driver main State machine
+ * @param None
+ * @retval status Return TSL_STATUS_OK if the acquisition is done
+ */
+TSL_Status_enum_T TSL_user_Action(void)
+{
+ static uint32_t idx_bank = 0;
+ static uint32_t config_done = 0;
+ TSL_Status_enum_T status;
+
+ // Configure bank
+ if (!config_done)
+ {
+ TSL_acq_BankConfig(idx_bank); // Configure Bank
+ TSL_acq_BankStartAcq(); // Start Bank acquisition
+ config_done = 1;
+#if TSLPRM_USE_ACQ_INTERRUPT > 0
+ Gv_EOA = 0; // Will be set by the TS interrupt routine
+#endif
+ }
+
+ // Check end of acquisition
+#if TSLPRM_USE_ACQ_INTERRUPT > 0
+ if (Gv_EOA) // Set by the TS interrupt routine
+#else
+ if (TSL_acq_BankWaitEOC() == TSL_STATUS_OK)
+#endif
+ {
+ STMSTUDIO_LOCK;
+ TSL_acq_BankGetResult(idx_bank, 0, 0); // Get Bank Result
+ STMSTUDIO_UNLOCK;
+ idx_bank++; // Next bank
+ config_done = 0;
+ }
+
+ // Process objects, DxS and ECS
+ // Check if all banks have been acquired
+ if (idx_bank > TSLPRM_TOTAL_BANKS-1)
+ {
+ // Reset flags for next banks acquisition
+ idx_bank = 0;
+ config_done = 0;
+
+ // Process Objects
+ TSL_obj_GroupProcess(&MyObjGroup);
+
+ // DxS processing (if TSLPRM_USE_DXS option is set)
+ TSL_dxs_FirstObj(&MyObjGroup);
+
+ // ECS every 100ms
+ if (TSL_tim_CheckDelay_ms(100, &Gv_ECS_last_tick) == TSL_STATUS_OK)
+ {
+ if (TSL_ecs_Process(&MyObjGroup) == TSL_STATUS_OK)
+ {
+ //LED4_TOGGLE;
+ //GPIOB->ODR ^= GPIO_Pin_2;
+ }
+ else
+ {
+ //LED4_OFF;
+ //GPIOB->ODR ^= GPIO_Pin_2;
+ }
+ }
+
+ status = TSL_STATUS_OK; // All banks have been acquired and sensors processed
+
+ }
+ else
+ {
+ status = TSL_STATUS_BUSY;
+ }
+
+ return status;
+}
+
+
+/**
+ * @brief Set thresholds for each object (optional).
+ * @param None
+ * @retval None
+ */
+void TSL_user_SetThresholds(void)
+{
+ // Example: Decrease the Detect thresholds for the TKEY 0
+ //MyTKeys_Param[0].DetectInTh -= 10;
+ //MyTKeys_Param[0].DetectOutTh -= 10;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/third_party/TouchSense/tsl_user.h b/third_party/TouchSense/tsl_user.h
new file mode 100644
index 0000000..cbf5d34
--- /dev/null
+++ b/third_party/TouchSense/tsl_user.h
@@ -0,0 +1,102 @@
+/**
+ ******************************************************************************
+ * @file STM32F072B_Ex01_2TKeys_EVAL\inc\tsl_user.h
+ * @author MCD Application Team
+ * @version V1.1.0
+ * @date 04-April-2014
+ * @brief Touch-Sensing user configuration and api file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __TSL_USER_H
+#define __TSL_USER_H
+
+#include "tsl.h"
+
+//==============================================================================
+// U S E R S E T T I N G S
+//==============================================================================
+
+// Select to use or not the LCD (0=No, 1=Yes)
+// Warning: the usage of LCD slows down the touch-sensing reactivity observed on the LEDs
+#define USE_LCD (0)
+
+// STMStudio software usage (0=No, 1=Yes)
+// Warning: The low-power mode must be disabled when STMStudio is used.
+#define USE_STMSTUDIO (0)
+
+//==============================================================================
+
+
+#if USE_STMSTUDIO > 0
+#include "stmCriticalSection.h"
+#define STMSTUDIO_LOCK {enterLock();}
+#define STMSTUDIO_UNLOCK {exitLock();}
+#else
+#define STMSTUDIO_LOCK
+#define STMSTUDIO_UNLOCK
+#endif
+
+//=======================
+// Channel IOs definition
+//=======================
+
+#define CHANNEL_0_IO_MSK (TSL_GROUP1_IO3)
+#define CHANNEL_0_GRP_MSK (TSL_GROUP1)
+#define CHANNEL_0_SRC (0) // Index in source register (TSC->IOGXCR[])
+#define CHANNEL_0_DEST (0) // Index in destination result array
+
+#define CHANNEL_1_IO_MSK (TSL_GROUP5_IO1)
+#define CHANNEL_1_GRP_MSK (TSL_GROUP5)
+#define CHANNEL_1_SRC (4) // Index in source register (TSC->IOGXCR[])
+#define CHANNEL_1_DEST (1) // Index in destination result array
+
+//======================
+// Shield IOs definition
+//======================
+
+//#define SHIELD_IO_MSK (TSL_GROUP4_IO1)
+
+//=================
+// Banks definition
+//=================
+
+#define BANK_0_NBCHANNELS (1)
+#define BANK_0_MSK_CHANNELS (CHANNEL_0_IO_MSK)
+#define BANK_0_MSK_GROUPS (CHANNEL_0_GRP_MSK) // Only these groups will be acquired
+
+#define BANK_1_NBCHANNELS (1)
+#define BANK_1_MSK_CHANNELS (CHANNEL_1_IO_MSK)
+#define BANK_1_MSK_GROUPS (CHANNEL_1_GRP_MSK) // Only these groups will be acquired
+
+// User Parameters
+extern CONST TSL_Bank_T MyBanks[];
+extern CONST TSL_TouchKey_T MyTKeys[];
+extern CONST TSL_Object_T MyObjects[];
+extern TSL_ObjectGroup_T MyObjGroup;
+
+void TSL_user_Init(void);
+TSL_Status_enum_T TSL_user_Action(void);
+void TSL_user_SetThresholds(void);
+
+#endif /* __TSL_USER_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/