1 /*!
2  * @file        tsc_linrot.c
3  *
4  * @brief       This file contains all functions to manage Linear and Rotary sensors.
5  *
6  * @version     V1.0.1
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be useful and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Includes */
27 #include "tsc.h"
28 #include "tsc_linrot.h"
29 
30 #if TOUCH_TOTAL_LNRTS > 0
31 
32 /** @addtogroup TSC_Driver_Library TSC Driver Library
33   @{
34 */
35 
36 /** @addtogroup TSC_Linrot_Driver TSC Linrot Driver
37   @{
38 */
39 
40 /** @defgroup TSC_Linrot_Macros Macros
41   @{
42 */
43 
44 #define FOR_OBJ_TYPE              TSC_Globals.For_Obj->Type
45 
46 #define FOR_STATEID               TSC_Globals.For_LinRot->p_Data->StateId
47 #define FOR_RAW_POSITION          TSC_Globals.For_LinRot->p_Data->RawPosition
48 #define FOR_POSITION              TSC_Globals.For_LinRot->p_Data->Position
49 #define FOR_CHANGE                TSC_Globals.For_LinRot->p_Data->Change
50 #define FOR_POSCHANGE             TSC_Globals.For_LinRot->p_Data->PosChange
51 #define FOR_COUNTER_DEB           TSC_Globals.For_LinRot->p_Data->CounterDebounce
52 #define FOR_COUNTER_DIR           TSC_Globals.For_LinRot->p_Data->CounterDirection
53 #define FOR_COUNTER_DTO           TSC_Globals.For_LinRot->p_Data->CounterDTO
54 #define FOR_DXSLOCK               TSC_Globals.For_LinRot->p_Data->DxsLock
55 #define FOR_DIRECTION             TSC_Globals.For_LinRot->p_Data->Direction
56 
57 #define FOR_PROXIN_TH             TSC_Globals.For_LinRot->p_Param->ProxInTh
58 #define FOR_PROXOUT_TH            TSC_Globals.For_LinRot->p_Param->ProxOutTh
59 #define FOR_DETECTIN_TH           TSC_Globals.For_LinRot->p_Param->DetectInTh
60 #define FOR_DETECTOUT_TH          TSC_Globals.For_LinRot->p_Param->DetectOutTh
61 #define FOR_CALIB_TH              TSC_Globals.For_LinRot->p_Param->CalibTh
62 
63 #define FOR_RESOLUTION            TSC_Globals.For_LinRot->p_Param->Resolution
64 #define FOR_DIR_CHG_POS           TSC_Globals.For_LinRot->p_Param->DirChangePos
65 
66 #define FOR_COUNTER_DEB_CALIB     TSC_Globals.For_LinRot->p_Param->CounterDebCalib
67 #define FOR_COUNTER_DEB_PROX      TSC_Globals.For_LinRot->p_Param->CounterDebProx
68 #define FOR_COUNTER_DEB_DETECT    TSC_Globals.For_LinRot->p_Param->CounterDebDetect
69 #define FOR_COUNTER_DEB_RELEASE   TSC_Globals.For_LinRot->p_Param->CounterDebRelease
70 #define FOR_COUNTER_DEB_ERROR     TSC_Globals.For_LinRot->p_Param->CounterDebError
71 #define FOR_COUNTER_DEB_DIRECTION TSC_Globals.For_LinRot->p_Param->CounterDebDirection
72 
73 #define FOR_NB_CHANNELS           TSC_Globals.For_LinRot->NumChannel
74 #define FOR_SCT_COMP              TSC_Globals.For_LinRot->SctComp
75 #define FOR_POS_CORR              TSC_Globals.For_LinRot->PosCorr
76 
77 #if TOUCH_DTO > 0
78     #define DTO_READ_TIME  {TSC_Linrot_ReadTimeForDTO();}
79 #else
80     #define DTO_READ_TIME
81 #endif
82 
83 #define DIRECTION_CHANGE_MAX_DISPLACEMENT (255)
84 #define DIRECTION_CHANGE_TOTAL_STEPS      (256)
85 #define RESOLUTION_CALCULATION            (8)
86 
87 /**@} end of group TSC_Linrot_Macros */
88 
89 /** @defgroup TSC_Linrot_Enumerations Enumerations
90   @{
91 */
92 
93 /**@} end of group TSC_Linrot_Enumerations */
94 
95 /** @defgroup TSC_Linrot_Structures Structures
96   @{
97 */
98 
99 /**@} end of group TSC_Linrot_Structures */
100 
101 /** @defgroup TSC_Linrot_Variables Variables
102   @{
103 */
104 
105 static TSC_tNum_T CalibDiv;
106 
107 /**
108  * @brief   3 CHANNELS - CH1 CH2 CH3
109  *            LINEAR - MONO - 0/255 at extremities
110  */
111 #if TOUCH_USE_3CH_LIN_M1 > 0
112 CONST TSC_tPosition_T TSC_POSOFF_3CH_LIN_M1[3][3] =
113 {
114     {    0,  -96,    0 },
115     {   32,    0, -160 },
116     {    0,   96,    0 }
117 };
118 #endif
119 
120 /**
121  * @brief   3 CHANNELS - CH1 CH2 CH3
122  *            LINEAR - MONO
123  */
124 #if TOUCH_USE_3CH_LIN_M2 > 0
125 CONST TSC_tPosition_T TSC_POSOFF_3CH_LIN_M2[3][3] =
126 {
127     {    0, -192,    0 },
128     {   64,    0, -320 },
129     {    0,  192,    0 }
130 };
131 #endif
132 
133 /**
134  * @brief   3 CHANNELS - CH1 CH2 CH3 CH1
135  *            LINEAR - HALF-ENDED
136  */
137 #if TOUCH_USE_3CH_LIN_H > 0
138 CONST TSC_tPosition_T TSC_POSOFF_3CH_LIN_H[3][3] =
139 {
140     {    0,  -96,  160 },
141     {   32,    0, -160 },
142     { -224,   96,    0 }
143 };
144 #endif
145 
146 /**
147  * @brief   3 CHANNELS - CH1 CH2 CH3
148  *            ROTARY - MONO
149  */
150 #if TOUCH_USE_3CH_ROT_M > 0
151 CONST TSC_tPosition_T TSC_POSOFF_3CH_ROT_M[3][3] =
152 {
153     {    0,  -64,  107 },
154     {   21,    0, -107 },
155     { -149,   64,    0 }
156 };
157 #endif
158 
159 /**
160  * @brief   4 CHANNELS - CH1 CH2 CH3 CH4
161  *            LINEAR - MONO - 0/255 at extremities
162  */
163 #if TOUCH_USE_4CH_LIN_M1 > 0
164 CONST TSC_tPosition_T TSC_POSOFF_4CH_LIN_M1[4][4] =
165 {
166     {    0,  -64,    0,    0 },
167     {   21,    0, -107,    0 },
168     {    0,   64,    0, -149 },
169     {    0,    0,  107,    0 }
170 };
171 #endif
172 
173 /**
174  * @brief   4 CHANNELS - CH1 CH2 CH3 CH4
175  *            LINEAR - MONO
176  */
177 #if TOUCH_USE_4CH_LIN_M2 > 0
178 CONST TSC_tPosition_T TSC_POSOFF_4CH_LIN_M2[4][4] =
179 {
180     {    0,  -96,    0,    0 },
181     {   32,    0, -160,    0 },
182     {    0,   96,    0, -224 },
183     {    0,    0,  160,    0 }
184 };
185 #endif
186 
187 /**
188  * @brief   4 CHANNELS - CH1 CH2 CH3 CH4 CH1
189  *            LINEAR - MONO - HALF-ENDED
190  */
191 #if TOUCH_USE_4CH_LIN_H > 0
192 CONST TSC_tPosition_T TSC_POSOFF_4CH_LIN_H[4][4] =
193 {
194     {    0,  -64,    0,  149 },
195     {   21,    0, -107,    0 },
196     {    0,   64,    0, -149 },
197     { -192,    0,  107,    0 }
198 };
199 #endif
200 
201 /**
202  * @brief   4 CHANNELS - CH1 CH2 CH3 CH4
203  *            ROTARY - MONO
204  */
205 #if TOUCH_USE_4CH_ROT_M > 0
206 CONST TSC_tPosition_T TSC_POSOFF_4CH_ROT_M[4][4] =
207 {
208     {    0,  -48,    0,  112 },
209     {   16,    0,  -80,    0 },
210     {    0,   48,    0, -112 },
211     { -144,    0,   80,    0 }
212 };
213 #endif
214 
215 /**
216  * @brief   5 CHANNELS - CH1 CH2 CH3 CH4 CH5
217  *            LINEAR - MONO - 0/255 at extremities
218  */
219 #if TOUCH_USE_5CH_LIN_M1 > 0
220 CONST TSC_tPosition_T TSC_POSOFF_5CH_LIN_M1[5][5] =
221 {
222     {    0,  -48,    0,    0,    0 },
223     {   16,    0,  -80,    0,    0 },
224     {    0,   48,    0, -112,    0 },
225     {    0,    0,   80,    0, -144 },
226     {    0,    0,    0,  112,    0 }
227 };
228 #endif
229 
230 /**
231  * @brief   5 CHANNELS - CH1 CH2 CH3 CH4 CH5
232  *            LINEAR - MONO
233  */
234 #if TOUCH_USE_5CH_LIN_M2 > 0
235 CONST TSC_tPosition_T TSC_POSOFF_5CH_LIN_M2[5][5] =
236 {
237     {    0,  -64,    0,    0,    0 },
238     {   21,    0, -107,    0,    0 },
239     {    0,   64,    0, -149,    0 },
240     {    0,    0,  107,    0, -192 },
241     {    0,    0,    0,  149,    0 }
242 };
243 #endif
244 
245 /**
246  * @brief   5 CHANNELS - CH1 CH2 CH3 CH4 CH5 CH1
247  *            LINEAR - HALF-ENDED
248  */
249 #if TOUCH_USE_5CH_LIN_H > 0
250 CONST TSC_tPosition_T TSC_POSOFF_5CH_LIN_H[5][5] =
251 {
252     {    0,  -48,    0,    0,  144 },
253     {   16,    0,  -80,    0,    0 },
254     {    0,   48,    0, -112,    0 },
255     {    0,    0,   80,    0, -144 },
256     { -176,    0,    0,  112,    0 }
257 };
258 #endif
259 
260 /**
261  * @brief   5 CHANNELS - CH1 CH2 CH3 CH4 CH5
262  *            ROTARY - MONO
263  */
264 #if TOUCH_USE_5CH_ROT_M > 0
265 CONST TSC_tPosition_T TSC_POSOFF_5CH_ROT_M[5][5] =
266 {
267     {   0,  -38,    0,    0,  115 },
268     {  13,    0,  -64,    0,    0 },
269     {   0,   38,    0,  -90,    0 },
270     {   0,    0,   64,    0, -115 },
271     {-141,    0,    0,   90,    0 }
272 };
273 #endif
274 
275 /**
276  * @brief   5 CHANNELS - CH1 CH2 CH3 CH4 CH5 CH1 CH3 CH5 CH2 CH4
277  *            ROTARY - DUAL
278  */
279 #if TOUCH_USE_5CH_ROT_D > 0
280 CONST TSC_tPosition_T TSC_POSOFF_5CH_ROT_D[5][5] =
281 {
282     {   0,  -19,  -83,  122,   58 },
283     {   6,    0,  -32, -122,   96 },
284     {  70,   19,    0,  -45,  -96 },
285     {-134,  109,   32,    0,  -58 },
286     { -70, -109,   83,   45,    0 }
287 };
288 #endif
289 
290 /**
291  * @brief   6 CHANNELS - CH1 CH2 CH3 CH4 CH5 CH6
292  *            LINEAR - MONO - 0/255 at extremities
293  */
294 #if TOUCH_USE_6CH_LIN_M1 > 0
295 CONST TSC_tPosition_T TSC_POSOFF_6CH_LIN_M1[6][6] =
296 {
297     {   0,  -38,    0,    0,    0,    0 },
298     {  13,    0,  -64,    0,    0,    0 },
299     {   0,   38,    0,  -90,    0,    0 },
300     {   0,    0,   64,    0, -115,    0 },
301     {   0,    0,    0,   90,    0, -141 },
302     {   0,    0,    0,    0,  115,    0 }
303 };
304 #endif
305 
306 /**
307  * @brief   6 CHANNELS - CH1 CH2 CH3 CH4 CH5 CH6
308  *            LINEAR - MONO
309  */
310 #if TOUCH_USE_6CH_LIN_M2 > 0
311 CONST TSC_tPosition_T TSC_POSOFF_6CH_LIN_M2[6][6] =
312 {
313     {   0,  -48,    0,    0,    0,    0 },
314     {  16,    0,  -80,    0,    0,    0 },
315     {   0,   48,    0, -112,    0,    0 },
316     {   0,    0,   80,    0, -144,    0 },
317     {   0,    0,    0,  112,    0, -176 },
318     {   0,    0,    0,    0,  144,    0 }
319 };
320 #endif
321 
322 /**
323  * @brief   6 CHANNELS - CH1 CH2 CH3 CH4 CH5 CH6 CH1
324  *            LINEAR - HALF-ENDED
325  */
326 #if TOUCH_USE_6CH_LIN_H > 0
327 CONST TSC_tPosition_T TSC_POSOFF_6CH_LIN_H[6][6] =
328 {
329     {   0,  -38,    0,    0,    0,  141 },
330     {  13,    0,  -64,    0,    0,    0 },
331     {   0,   38,    0,  -90,    0,    0 },
332     {   0,    0,   64,    0, -115,    0 },
333     {   0,    0,    0,   90,    0, -141 },
334     {-166,    0,    0,    0,  115,    0 }
335 };
336 #endif
337 
338 /**
339  * @brief   6 CHANNELS - CH1 CH2 CH3 CH4 CH5 CH6
340  *            ROTARY - MONO
341  */
342 #if TOUCH_USE_6CH_ROT_M > 0
343 CONST TSC_tPosition_T TSC_POSOFF_6CH_ROT_M[6][6] =
344 {
345     {   0,  -32,    0,    0,    0,  117 },
346     {  11,    0,  -53,    0,    0,    0 },
347     {   0,   32,    0,  -75,    0,    0 },
348     {   0,    0,   53,    0,  -96,    0 },
349     {   0,    0,    0,   75,    0, -117 },
350     {-139,    0,    0,    0,   96,    0 }
351 };
352 #endif
353 
354 /**@} end of group TSC_Linrot_Variables */
355 
356 /** @defgroup TSC_Linrot_Functions Functions
357   @{
358 */
359 
360 /** @defgroup "Object_methods" Functions
361   @{
362 */
363 
364 /*!
365  * @brief       The parameters with default values from configuration file
366  *
367  * @param       None
368  *
369  * @retval      None
370  */
TSC_Linrot_Config(void)371 void TSC_Linrot_Config(void)
372 {
373     /* Thresholds */
374 #if TOUCH_USE_PROX > 0
375     FOR_PROXIN_TH    = TOUCH_LINROT_PROX_IN_TH;
376     FOR_PROXOUT_TH   = TOUCH_LINROT_PROX_OUT_TH;
377 #endif
378     FOR_DETECTIN_TH  = TOUCH_LINROT_DETECT_IN_TH;
379     FOR_DETECTOUT_TH = TOUCH_LINROT_DETECT_OUT_TH;
380     FOR_CALIB_TH     = TOUCH_LINROT_CALIB_TH;
381 
382     /* Debounce counters */
383     FOR_COUNTER_DEB_CALIB   = TOUCH_DEBOUNCE_CALIB;
384 #if TOUCH_USE_PROX > 0
385     FOR_COUNTER_DEB_PROX    = TOUCH_DEBOUNCE_PROX;
386 #endif
387     FOR_COUNTER_DEB_DETECT  = TOUCH_DEBOUNCE_DETECT;
388     FOR_COUNTER_DEB_RELEASE = TOUCH_DEBOUNCE_RELEASE;
389     FOR_COUNTER_DEB_ERROR   = TOUCH_DEBOUNCE_ERROR;
390 
391     /* Other parameters for linear/rotary only */
392     FOR_RESOLUTION            = TOUCH_LINROT_RESOLUTION;
393     FOR_DIR_CHG_POS           = TOUCH_LINROT_DIR_CHG_POS;
394     FOR_COUNTER_DEB_DIRECTION = TOUCH_LINROT_DIR_CHG_DEB;
395 
396     /* Config state */
397     TSC_Linrot_ConfigCalibrationState(TOUCH_CALIB_DELAY);
398 }
399 
400 /*!
401  * @brief       Process the State Machine
402  *
403  * @param       None
404  *
405  * @retval      None
406  */
TSC_Linrot_Process(void)407 void TSC_Linrot_Process(void)
408 {
409     TSC_STATEID_T stateID;
410 
411     /* Check if at least one channel has a data ready */
412     if ((TSC_Linrot_Process_OneChannel_DataReady() == TSC_STATUS_OK) || (FOR_STATEID == TSC_STATEID_OFF))
413     {
414         stateID = FOR_STATEID;
415 
416 #if TOUCH_TOTAL_LINROTS > 0
417         if ((TSC_Globals.For_Obj->Type == TSC_OBJ_LINEAR) ||
418                 (TSC_Globals.For_Obj->Type == TSC_OBJ_ROTARY))
419         {
420             TSC_Globals.For_LinRot->p_SM[FOR_STATEID].StateFunc();
421         }
422 #endif
423 
424 #if TOUCH_TOTAL_LINROTS_B > 0
425         if ((TSC_Globals.For_Obj->Type == TSC_OBJ_LINEARB) ||
426                 (TSC_Globals.For_Obj->Type == TSC_OBJ_ROTARYB))
427         {
428             TSC_Params.p_LinRotSta[FOR_STATEID].StateFunc();
429         }
430 #endif
431 
432         if (FOR_STATEID != stateID)
433         {
434             FOR_CHANGE = TSC_STATE_CHANGED;
435         }
436         else
437         {
438             FOR_CHANGE = TSC_STATE_NOT_CHANGED;
439         }
440 
441 #if TOUCH_USE_DXS > 0
442         if (FOR_STATEID != TSC_STATEID_DETECT)
443         {
444             FOR_DXSLOCK = TSC_FALSE;
445         }
446         if (FOR_STATEID == TSC_STATEID_TOUCH)
447         {
448             FOR_STATEID = TSC_STATEID_DETECT;
449         }
450 #endif
451     }
452 }
453 
454 /*!
455  * @brief       Calculate the position
456  *
457  * @param       None
458  *
459  * @retval      Status Return OK if position calculation is correct
460  *
461  * @note        The position is calculated only if the number of channels is greater than 2
462  */
TSC_Linrot_CalcPos(void)463 TSC_STATUS_T TSC_Linrot_CalcPos(void)
464 {
465     TSC_tIndex_T     index;
466     TSC_tDelta_T     normDelta;
467     TSC_tNum_T       minor, major;
468     TSC_tNum_T       sector = 0;
469     TSC_tNum_T       prePosition = 0;
470     TSC_tPosition_T  curPosition = 0;
471     TSC_tsignPosition_T   updatePosition = 0;
472     static TSC_tIndex_T   index1, index2;
473     static TSC_tDelta_T   delta1, delta2, delta3;
474 
475     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
476 
477     index1 = 0;
478     index2 = 0;
479     delta1 = 0;
480     delta2 = 0;
481     delta3 = 0;
482 
483     FOR_POSCHANGE = TSC_STATE_NOT_CHANGED;
484 
485     if (FOR_NB_CHANNELS < 3)
486     {
487         return TSC_STATUS_ERROR;
488     }
489 
490     /**
491      *  Sort the channels' delta
492      *    - delta1 and index1 = biggest
493      *    - delta2 and index2 = middle
494      *    - delta3 and index3 = lowest
495      */
496     for (index = 0; index < FOR_NB_CHANNELS; index++)
497     {
498 #if TOUCH_LINROT_USE_NORMDELTA > 0
499         normDelta = TSC_Linrot_NormDelta(p_Ch, index);
500 #else
501         normDelta = p_Ch->Delta;
502 #endif
503 
504         if (normDelta < 0)
505         {
506             normDelta = 0;
507         }
508 
509         if (normDelta <= delta1)
510         {
511             if (normDelta <= delta2)
512             {
513                 if (normDelta > delta3)
514                 {
515                     delta3 = normDelta;
516                 }
517             }
518             else
519             {
520                 delta3 = delta2;
521                 delta2 = normDelta;
522                 index2 = index;
523             }
524         }
525         else
526         {
527             delta3 = delta2;
528             delta2 = delta1;
529             delta1 = normDelta;
530             index2 = index1;
531             index1 = index;
532         }
533         p_Ch++;
534     }
535 
536     if (delta2 < ((TSC_tThreshold_T)(FOR_DETECTOUT_TH >> 1) - 1))
537     {
538         return TSC_STATUS_ERROR;
539     }
540 
541     /******************** Position calculation **********************/
542 
543     /**
544      *   B = Biggest  signal measured (Delta1/Index1)
545      *   M = Middle   signal measured (Delta2/Index2)
546      *   S = Smallest signal measured (Delta3/Index3)
547      *
548      * - The equation to find the position is:
549      *   Position = Offset +/- [ Sector_Size x ( Major / (Major + Minor) ) ]
550      *
551      * - The Offset is the position of the middle of the Middle signal segment.
552      *   All the Offset values are stored in the ROM table Table_POSITION_OFFSET.
553      *
554      * - Major = Biggest - Smallest signals
555      *   Minor = Middle - Smallest signals
556      *
557      * - The Sector_Size depends of the number of channels used
558      */
559 
560     /* Calculates the Major and Minor parameters */
561     minor = (TSC_tNum_T)(delta2 - delta3); /*!<Middle - Smallest signals */
562     major = (TSC_tNum_T)(delta1 - delta3); /*!<Biggest - Smallest signals */
563 
564     /* Select the offset position in the position offset constant table */
565     curPosition = *(TSC_Globals.For_LinRot->p_PosOff + (index1 * FOR_NB_CHANNELS) + index2);
566     sector = FOR_SCT_COMP;
567     prePosition = FOR_POS_CORR;
568 
569     /* Calculates: [ Sector_Size x ( Major / (Major + Minor) ) ] */
570     sector = major * sector;
571     sector = sector / (major + minor);
572 
573     /* Use the sign bit from position table to define the interpretation direction.
574         The NewPosition is multiplied by 2 because the Offset stored in the ROM
575         table is divided by 2... */
576     if (curPosition <= 0) /*!<Means Offset is <= 0 in the ROM table */
577     {
578         curPosition = (TSC_tPosition_T)((-curPosition) << 1);
579         curPosition -= sector;
580     }
581     else /*!<Means Offset is > 0 in the position table */
582     {
583         curPosition = (TSC_tPosition_T)(curPosition << 1);
584         curPosition += sector;
585     }
586 
587     /* Position is calculated differently if LINEAR or ROTARY sensor */
588     if ((FOR_OBJ_TYPE == TSC_OBJ_LINEAR) || (FOR_OBJ_TYPE == TSC_OBJ_LINEARB))
589     {
590         /* First adjustment used to shift all the values to obtain the "zero" */
591         if (curPosition <= 0)
592         {
593             curPosition = curPosition + (256 - prePosition);
594         }
595         else
596         {
597             curPosition -= prePosition;
598         }
599         /*!<Second adjustment used to clamp the values at both ends of sensor */
600         if (curPosition > 255)
601         {
602             curPosition = 255;
603         }
604         if (curPosition < 0)
605         {
606             curPosition = 0;
607         }
608     }
609     else /*!<ROTARY sensor: keep only the low byte */
610     {
611         curPosition = (TSC_tsignPosition_T)curPosition;
612     }
613 
614     /******************** Direction Change Process **********************/
615 
616     if (FOR_DIRECTION != TSC_TRUE) /*!<Clockwise direction */
617     {
618         /* Check Direction changed and Position overflow from 0xFF to 0x00 not realized */
619         if (((TSC_tsignPosition_T)curPosition < FOR_RAW_POSITION) && ((FOR_RAW_POSITION - (TSC_tsignPosition_T)curPosition) < DIRECTION_CHANGE_MAX_DISPLACEMENT))
620         {
621             if ((curPosition + FOR_DIR_CHG_POS) <= FOR_RAW_POSITION)
622             {
623                 FOR_COUNTER_DIR--;
624                 if (FOR_COUNTER_DIR)
625                 {
626                     return TSC_STATUS_ERROR;
627                 }
628                 else
629                 {
630                     FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
631                     FOR_DIRECTION = TSC_TRUE;  /*!<Clockwise direction */
632                 }
633             }
634             else
635             {
636                 FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
637                 return TSC_STATUS_ERROR;
638             }
639         }
640         /* Check position overflow from 0x00 to 0xFF to be filtered */
641         if (curPosition > (uint16_t)(FOR_RAW_POSITION + DIRECTION_CHANGE_MAX_DISPLACEMENT))
642         {
643             if ((curPosition + FOR_DIR_CHG_POS) <= (uint16_t)(FOR_RAW_POSITION + DIRECTION_CHANGE_TOTAL_STEPS))
644             {
645                 FOR_COUNTER_DIR--;
646                 if (FOR_COUNTER_DIR)
647                 {
648                     return TSC_STATUS_ERROR;
649                 }
650                 else
651                 {
652                     FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
653                     FOR_DIRECTION = TSC_TRUE;  /*!<Clockwise direction */
654                 }
655             }
656             else
657             {
658                 FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
659                 return TSC_STATUS_ERROR;
660             }
661         }
662     }
663     else /*!<Anticlockwise direction */
664     {
665         /* Check Direction changed and Position overflow from 0x00 to 0xFF not realized */
666         if (((TSC_tsignPosition_T)curPosition > FOR_RAW_POSITION) && (((TSC_tsignPosition_T)curPosition - FOR_RAW_POSITION) < DIRECTION_CHANGE_MAX_DISPLACEMENT))
667         {
668             if (curPosition >= (uint16_t)(FOR_RAW_POSITION + FOR_DIR_CHG_POS))
669             {
670                 FOR_COUNTER_DIR--;
671                 if (FOR_COUNTER_DIR)
672                 {
673                     return TSC_STATUS_ERROR;
674                 }
675                 else
676                 {
677                     FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
678                     FOR_DIRECTION = TSC_FALSE;  /*!<Clockwise direction */
679                 }
680             }
681             else
682             {
683                 FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
684                 return TSC_STATUS_ERROR;
685             }
686         }
687         /* Check position overflow from 0xFF to 0x00 to be filtered */
688         if ((curPosition + DIRECTION_CHANGE_MAX_DISPLACEMENT) < FOR_RAW_POSITION)
689         {
690             if ((curPosition + DIRECTION_CHANGE_TOTAL_STEPS) >= (uint16_t)(FOR_RAW_POSITION + FOR_DIR_CHG_POS))
691             {
692                 FOR_COUNTER_DIR--;
693                 if (FOR_COUNTER_DIR)
694                 {
695                     return TSC_STATUS_ERROR;
696                 }
697                 else
698                 {
699                     FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
700                     FOR_DIRECTION = TSC_FALSE;  /*!<Clockwise direction */
701                 }
702             }
703             else
704             {
705                 FOR_COUNTER_DIR = FOR_COUNTER_DEB_DIRECTION;
706                 return TSC_STATUS_ERROR;
707             }
708         }
709     }
710 
711     /******************** Final result **********************/
712 
713     FOR_RAW_POSITION = (TSC_tsignPosition_T)curPosition;
714 
715     updatePosition = (TSC_tsignPosition_T)((TSC_tsignPosition_T)curPosition >> (RESOLUTION_CALCULATION - FOR_RESOLUTION));
716 
717     if (FOR_POSITION != updatePosition)
718     {
719         FOR_POSITION = updatePosition;
720         FOR_POSCHANGE = TSC_STATE_CHANGED;
721         return TSC_STATUS_OK;
722     }
723     else
724     {
725         return TSC_STATUS_ERROR;
726     }
727 }
728 
729 /**@} "Object_methods" Functions */
730 
731 /** @defgroup Utility Functions
732   @{
733 */
734 
735 /*!
736  * @brief     Go in Calibration state
737  *
738  * @param     delay Delay before calibration starts (stabilization of noise filter)
739  *
740  * @retval    None
741  */
TSC_Linrot_ConfigCalibrationState(TSC_tCounter_T delay)742 void TSC_Linrot_ConfigCalibrationState(TSC_tCounter_T delay)
743 {
744     FOR_STATEID = TSC_STATEID_CALIB;
745     FOR_CHANGE = TSC_STATE_CHANGED;
746     TSC_Linrot_Process_AllChannel_Status(TSC_OBJ_STATUS_ON);
747 
748     if (TSC_Params.NumCalibSample == 4)
749     {
750         CalibDiv = 2;
751     }
752     else if (TSC_Params.NumCalibSample == 16)
753     {
754         CalibDiv = 4;
755     }
756     else
757     {
758         TSC_Params.NumCalibSample =  8;
759         CalibDiv = 3;
760     }
761 
762     /* If a noise filter is used, the counter must be initialized to a value
763         different from 0 in order to stabilize the filter */
764     FOR_COUNTER_DEB = (TSC_tCounter_T)(delay + (TSC_tCounter_T)TSC_Params.NumCalibSample);
765     TSC_Linrot_Process_AllChannel_ClearRef();
766 }
767 
768 /*!
769  * @brief       Go in Off state with sensor "off"
770  *
771  * @param       None
772  *
773  * @retval      None
774  */
TSC_Linrot_ConfigOffState(void)775 void TSC_Linrot_ConfigOffState(void)
776 {
777     FOR_STATEID = TSC_STATEID_OFF;
778     FOR_CHANGE = TSC_STATE_CHANGED;
779     TSC_Linrot_Process_AllChannel_Status(TSC_OBJ_STATUS_OFF);
780 }
781 
782 /*!
783  * @brief       Go in Off state with sensor in "Burst mode only"
784  *
785  * @param       None
786  *
787  * @retval      None
788  */
TSC_Linrot_ConfigBurstOnlyState(void)789 void TSC_Linrot_ConfigBurstOnlyState(void)
790 {
791     FOR_STATEID = TSC_STATEID_OFF;
792     FOR_CHANGE = TSC_STATE_CHANGED;
793     TSC_Linrot_Process_AllChannel_Status(TSC_OBJ_STATUS_BURST_ONLY);
794 }
795 
796 /*!
797  * @brief       Return the current state identifier
798  *
799  * @param       None
800  *
801  * @retval      State id
802  */
TSC_Linrot_ReadStateId(void)803 TSC_STATEID_T TSC_Linrot_ReadStateId(void)
804 {
805     return (FOR_STATEID);
806 }
807 
808 /*!
809  * @brief       Return the current state mask
810  *
811  * @param       None
812  *
813  * @retval      State mask
814  */
TSC_Linrot_ReadStateMask(void)815 TSC_STATEMASK_T TSC_Linrot_ReadStateMask(void)
816 {
817     TSC_STATEMASK_T state_mask = TSC_STATEMASK_UNKNOWN;
818 
819     switch (TSC_Globals.For_Obj->Type)
820     {
821 #if TOUCH_TOTAL_LINROTS > 0
822         case TSC_OBJ_LINEAR:
823         case TSC_OBJ_ROTARY:
824             state_mask = TSC_Globals.For_LinRot->p_SM[FOR_STATEID].StateMask;
825             break;
826 #endif
827 
828 #if TOUCH_TOTAL_LINROTS_B > 0
829         case TSC_OBJ_LINEARB:
830         case TSC_OBJ_ROTARYB:
831             state_mask = TSC_Params.p_LinRotSta[FOR_STATEID].StateMask;
832             break;
833 #endif
834         default:
835             break;
836     }
837     return state_mask;
838 }
839 
840 /*!
841  * @brief       Return the Change flag
842  *
843  * @param       None
844  *
845  * @retval      Change flag status
846  */
TSC_Linrot_ReadChangeFlag(void)847 TSC_tNum_T TSC_Linrot_ReadChangeFlag(void)
848 {
849     return (FOR_CHANGE);
850 }
851 
852 /**@} Utility Functions */
853 
854 /** @defgroup State_machine Functions
855   @{
856 */
857 
858 #if TOUCH_USE_PROX > 0
859 /*!
860  * @brief       Debounce Release processing (previous state = Proximity)
861  *
862  * @param       None
863  *
864  * @retval      None
865  */
TSC_Linrot_ProcessDebReleaseProxState(void)866 void TSC_Linrot_ProcessDebReleaseProxState(void)
867 {
868     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
869     {
870         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0))
871         {
872             if (FOR_COUNTER_DEB > 0)
873             {
874                 FOR_COUNTER_DEB--;
875             }
876             if (FOR_COUNTER_DEB == 0)
877             {
878                 FOR_STATEID = TSC_STATEID_RELEASE;
879             }
880         }
881         else
882         {
883             FOR_STATEID = TSC_STATEID_PROX;
884         }
885     }
886     else
887     {
888         /* Go back to the previous state */
889         FOR_STATEID = TSC_STATEID_PROX;
890     }
891 }
892 #endif /*!<if TOUCH_USE_PROX > 0 */
893 
894 /*!
895  * @brief       Debounce Release processing (previous state = Detect)
896  *
897  * @param       None
898  *
899  * @retval      None
900  */
TSC_Linrot_ProcessDebReleaseDetectState(void)901 void TSC_Linrot_ProcessDebReleaseDetectState(void)
902 {
903     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
904     {
905         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_DETECTOUT_TH, 1))
906         {
907 #if TOUCH_USE_PROX > 0
908             if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0) == TSC_STATUS_OK)
909             {
910                 FOR_STATEID = TSC_STATEID_PROX;
911                 return;
912             }
913 #endif
914             if (FOR_COUNTER_DEB > 0)
915             {
916                 FOR_COUNTER_DEB--;
917             }
918             if (FOR_COUNTER_DEB == 0)
919             {
920                 FOR_STATEID = TSC_STATEID_RELEASE;
921             }
922         }
923         else
924         {
925             FOR_STATEID = TSC_STATEID_DETECT;
926         }
927     }
928     else
929     {
930         FOR_STATEID = TSC_STATEID_DETECT;
931     }
932 }
933 
934 /*!
935  * @brief       Debounce Release processing (previous state = Touch)
936  *              Same as Debounce Release Detect processing
937  *
938  * @param       None
939  *
940  * @retval      None
941  */
TSC_Linrot_ProcessDebReleaseTouchState(void)942 void TSC_Linrot_ProcessDebReleaseTouchState(void)
943 {
944     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
945     {
946         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_DETECTOUT_TH, 1))
947         {
948 #if TOUCH_USE_PROX > 0
949             if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0) == TSC_STATUS_OK)
950             {
951                 FOR_STATEID = TSC_STATEID_PROX;
952                 return;
953             }
954 #endif
955             if (FOR_COUNTER_DEB > 0)
956             {
957                 FOR_COUNTER_DEB--;
958             }
959             if (FOR_COUNTER_DEB == 0)
960             {
961                 FOR_STATEID = TSC_STATEID_RELEASE;
962             }
963         }
964         else
965         {
966             FOR_STATEID = TSC_STATEID_TOUCH;
967         }
968     }
969     else
970     {
971         FOR_STATEID = TSC_STATEID_TOUCH;
972     }
973 }
974 
975 /*!
976  * @brief       Release state processing
977  *
978  * @param       None
979  *
980  * @retval      None
981  */
TSC_Linrot_ProcessReleaseState(void)982 void TSC_Linrot_ProcessReleaseState(void)
983 {
984     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
985     {
986         if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_DETECTIN_TH, 1) == TSC_STATUS_OK)
987         {
988             FOR_COUNTER_DEB = FOR_COUNTER_DEB_DETECT;
989             if (FOR_COUNTER_DEB)
990             {
991                 FOR_STATEID = TSC_STATEID_DEB_DETECT;
992             }
993             else
994             {
995                 FOR_STATEID = TSC_STATEID_DETECT;
996                 DTO_READ_TIME;
997             }
998             return;
999         }
1000 
1001 #if TOUCH_USE_PROX > 0
1002         if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_PROXIN_TH, 0) == TSC_STATUS_OK)
1003         {
1004             FOR_COUNTER_DEB = FOR_COUNTER_DEB_PROX;
1005             if (FOR_COUNTER_DEB)
1006             {
1007                 FOR_STATEID = TSC_STATEID_DEB_PROX;
1008             }
1009             else
1010             {
1011                 FOR_STATEID = TSC_STATEID_PROX;
1012                 DTO_READ_TIME;
1013             }
1014             return;
1015         }
1016 #endif
1017 
1018         /* Check delta for re-calibration */
1019         if (TSC_Linrot_Process_OneChannel_DeltaBelowEquMinus(FOR_CALIB_TH, 1) == TSC_STATUS_OK)
1020         {
1021             FOR_COUNTER_DEB = FOR_COUNTER_DEB_CALIB;
1022             if (FOR_COUNTER_DEB)
1023             {
1024                 FOR_STATEID = TSC_STATEID_DEB_CALIB;
1025             }
1026             else
1027             {
1028                 TSC_Linrot_ConfigCalibrationState(0);
1029             }
1030         }
1031     }
1032     else
1033     {
1034         FOR_COUNTER_DEB = FOR_COUNTER_DEB_ERROR;
1035         if (FOR_COUNTER_DEB)
1036         {
1037             FOR_STATEID = TSC_STATEID_DEB_ERROR_RELEASE;
1038         }
1039         else
1040         {
1041             FOR_STATEID = TSC_STATEID_ERROR;
1042         }
1043     }
1044 }
1045 
1046 /*!
1047  * @brief       Debounce Calibration processing (previous state = Release)
1048  *
1049  * @param       None
1050  *
1051  * @retval      None
1052  */
TSC_Linrot_ProcessDebCalibrationState(void)1053 void TSC_Linrot_ProcessDebCalibrationState(void)
1054 {
1055     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1056     {
1057         if (TSC_Linrot_Process_OneChannel_DeltaBelowEquMinus(FOR_CALIB_TH, 1))
1058         {
1059             FOR_STATEID = TSC_STATEID_RELEASE;
1060         }
1061         else
1062         {
1063             if (FOR_COUNTER_DEB > 0)
1064             {
1065                 FOR_COUNTER_DEB--;
1066             }
1067             if (FOR_COUNTER_DEB == 0)
1068             {
1069                 TSC_Linrot_ConfigCalibrationState(0);
1070             }
1071         }
1072     }
1073     else
1074     {
1075         FOR_STATEID = TSC_STATEID_RELEASE;
1076     }
1077 }
1078 
1079 /*!
1080  * @brief       Calibration state processing
1081  *
1082  * @param       None
1083  *
1084  * @retval      None
1085  */
TSC_Linrot_ProcessCalibrationState(void)1086 void TSC_Linrot_ProcessCalibrationState(void)
1087 {
1088     TSC_tMeas_T   newMeas;
1089     TSC_tIndex_T  index;
1090     TSC_Channel_Data_T* p_Ch;
1091 
1092 #if TOUCH_CALIB_DELAY > 0
1093     /* Noise filter stabilization time */
1094     if (FOR_COUNTER_DEB > (TSC_tCounter_T)TSC_Params.NumCalibSample)
1095     {
1096         FOR_COUNTER_DEB--;
1097         return;
1098     }
1099 #endif
1100 
1101     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1102     {
1103         /* Process all channels */
1104         p_Ch = TSC_Globals.For_LinRot->p_ChD;
1105 
1106         for (index = 0; index < FOR_NB_CHANNELS; index++)
1107         {
1108             /* Read the new measure or Calculate it */
1109 #if TOUCH_USE_MEAS > 0
1110             newMeas = p_Ch->Meas;
1111 #else
1112             newMeas = TSC_Acq_ComputeMeas(p_Ch->Refer, p_Ch->Delta);
1113 #endif
1114 
1115             /* Verify the first Reference value */
1116             if (FOR_COUNTER_DEB != (TSC_tCounter_T)TSC_Params.NumCalibSample)
1117             {
1118                 p_Ch->Refer += newMeas;
1119 
1120                 if (p_Ch->Refer < newMeas)
1121                 {
1122                     p_Ch->Refer = 0;
1123                     FOR_STATEID = TSC_STATEID_ERROR;
1124                     return;
1125                 }
1126             }
1127             else
1128             {
1129                 if (TSC_Acq_TestFirstReference(p_Ch, newMeas))
1130                 {
1131                     p_Ch->Refer = newMeas;
1132                 }
1133                 else
1134                 {
1135                     p_Ch->Refer = 0;
1136                     return;
1137                 }
1138             }
1139             p_Ch++;
1140         }
1141 
1142         if (FOR_COUNTER_DEB > 0)
1143         {
1144             FOR_COUNTER_DEB--;
1145         }
1146         if (FOR_COUNTER_DEB == 0)
1147         {
1148             /* Process all channels */
1149             p_Ch = TSC_Globals.For_LinRot->p_ChD;
1150 
1151             for (index = 0; index < FOR_NB_CHANNELS; index++)
1152             {
1153                 p_Ch->Refer >>= CalibDiv;
1154                 p_Ch->RefRest = 0;
1155                 p_Ch->Delta = 0;
1156                 p_Ch++;
1157             }
1158             FOR_STATEID = TSC_STATEID_RELEASE;
1159         }
1160     }
1161     else
1162     {
1163         FOR_COUNTER_DEB = FOR_COUNTER_DEB_ERROR;
1164         if (FOR_COUNTER_DEB)
1165         {
1166             FOR_STATEID = TSC_STATEID_DEB_ERROR_CALIB;
1167         }
1168         else
1169         {
1170             FOR_STATEID = TSC_STATEID_ERROR;
1171         }
1172     }
1173 }
1174 
1175 #if TOUCH_USE_PROX > 0
1176 /*!
1177  * @brief       Debounce Proximity processing (previous state = Release)
1178  *
1179  * @param       None
1180  *
1181  * @retval      None
1182  */
TSC_Linrot_ProcessDebProxState(void)1183 void TSC_Linrot_ProcessDebProxState(void)
1184 {
1185     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1186     {
1187         if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_DETECTIN_TH, 1) == TSC_STATUS_OK)
1188         {
1189             FOR_COUNTER_DEB = FOR_COUNTER_DEB_DETECT;
1190             if (FOR_COUNTER_DEB)
1191             {
1192                 FOR_STATEID = TSC_STATEID_DEB_DETECT;
1193             }
1194             else
1195             {
1196                 FOR_STATEID = TSC_STATEID_DETECT;
1197                 DTO_READ_TIME;
1198             }
1199             return;
1200         }
1201 
1202         if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_PROXIN_TH, 0))
1203         {
1204             FOR_STATEID = TSC_STATEID_RELEASE;
1205         }
1206         else
1207         {
1208             if (FOR_COUNTER_DEB > 0)
1209             {
1210                 FOR_COUNTER_DEB--;
1211             }
1212             if (FOR_COUNTER_DEB == 0)
1213             {
1214                 FOR_STATEID = TSC_STATEID_PROX;
1215                 DTO_READ_TIME;
1216             }
1217         }
1218     }
1219     else
1220     {
1221         FOR_STATEID = TSC_STATEID_RELEASE;
1222     }
1223 }
1224 #endif
1225 
1226 
1227 #if TOUCH_USE_PROX > 0
1228 /*!
1229  * @brief       Debounce Proximity processing (previous state = Detect)
1230  *
1231  * @param       None
1232  *
1233  * @retval      None
1234  */
TSC_Linrot_ProcessDebProxDetectState(void)1235 void TSC_Linrot_ProcessDebProxDetectState(void)
1236 {
1237     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1238     {
1239         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_DETECTOUT_TH, 1) == TSC_STATUS_OK)
1240         {
1241             FOR_STATEID = TSC_STATEID_DETECT;
1242             return;
1243         }
1244 
1245         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0))
1246         {
1247             FOR_COUNTER_DEB = FOR_COUNTER_DEB_RELEASE;
1248             if (FOR_COUNTER_DEB)
1249             {
1250                 FOR_STATEID = TSC_STATEID_DEB_RELEASE_DETECT;
1251             }
1252             else
1253             {
1254                 FOR_STATEID = TSC_STATEID_RELEASE;
1255             }
1256         }
1257         else
1258         {
1259             if (FOR_COUNTER_DEB > 0)
1260             {
1261                 FOR_COUNTER_DEB--;
1262             }
1263             if (FOR_COUNTER_DEB == 0)
1264             {
1265                 FOR_STATEID = TSC_STATEID_PROX;
1266                 DTO_READ_TIME;
1267             }
1268         }
1269     }
1270     else
1271     {
1272         FOR_STATEID = TSC_STATEID_DETECT;
1273     }
1274 }
1275 #endif
1276 
1277 #if TOUCH_USE_PROX > 0
1278 /*!
1279  * @brief      Debounce Proximity processing (previous state = Touch)
1280  *
1281  * @param      None
1282  *
1283  * @retval     None
1284  */
TSC_Linrot_ProcessDebProxTouchState(void)1285 void TSC_Linrot_ProcessDebProxTouchState(void)
1286 {
1287     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1288     {
1289         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_DETECTOUT_TH, 1) == TSC_STATUS_OK)
1290         {
1291             FOR_STATEID = TSC_STATEID_TOUCH;
1292             return;
1293         }
1294 
1295         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0))
1296         {
1297             FOR_COUNTER_DEB = FOR_COUNTER_DEB_RELEASE;
1298             if (FOR_COUNTER_DEB)
1299             {
1300                 FOR_STATEID = TSC_STATEID_DEB_RELEASE_TOUCH;
1301             }
1302             else
1303             {
1304                 FOR_STATEID = TSC_STATEID_RELEASE;
1305             }
1306         }
1307         else
1308         {
1309             if (FOR_COUNTER_DEB > 0)
1310             {
1311                 FOR_COUNTER_DEB--;
1312             }
1313             if (FOR_COUNTER_DEB == 0)
1314             {
1315                 FOR_STATEID = TSC_STATEID_PROX;
1316                 DTO_READ_TIME;
1317             }
1318         }
1319     }
1320     else
1321     {
1322         FOR_STATEID = TSC_STATEID_TOUCH;
1323     }
1324 }
1325 #endif
1326 
1327 #if TOUCH_USE_PROX > 0
1328 /*!
1329  * @brief     roximity state processing
1330  *
1331  * @param      None
1332  *
1333  * @retval     None
1334  */
TSC_Linrot_ProcessProxState(void)1335 void TSC_Linrot_ProcessProxState(void)
1336 {
1337 #if TOUCH_DTO > 0
1338     TSC_tTick_sec_T tick_detected;
1339 #endif
1340 
1341     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1342     {
1343         if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_DETECTIN_TH, 1) == TSC_STATUS_OK)
1344         {
1345             FOR_COUNTER_DEB = FOR_COUNTER_DEB_DETECT;
1346             if (FOR_COUNTER_DEB)
1347             {
1348                 FOR_STATEID = TSC_STATEID_DEB_DETECT;
1349             }
1350             else
1351             {
1352                 FOR_STATEID = TSC_STATEID_DETECT;
1353                 DTO_READ_TIME;
1354             }
1355             return;
1356         }
1357 
1358         if (TSC_Linrot_Process_AllChannel_DeltaBelowEqu(FOR_PROXOUT_TH, 0) == TSC_STATUS_OK)
1359         {
1360             FOR_COUNTER_DEB = FOR_COUNTER_DEB_RELEASE;
1361             if (FOR_COUNTER_DEB)
1362             {
1363                 FOR_STATEID = TSC_STATEID_DEB_RELEASE_PROX;
1364             }
1365             else
1366             {
1367                 FOR_STATEID = TSC_STATEID_RELEASE;
1368             }
1369             return;
1370         }
1371 
1372         /* Stay in Proximity state */
1373 #if TOUCH_DTO > 0
1374         /* Detection Time Out (DTO) processing */
1375         if ((TSC_Params.DTO > 1) && (TSC_Params.DTO < 64))
1376         {
1377             tick_detected = FOR_COUNTER_DTO;
1378             /* Enter in calibration state if the DTO duration has elapsed */
1379             if (TSC_Time_Delay_sec(TSC_Params.DTO, &tick_detected) == TSC_STATUS_OK)
1380             {
1381                 TSC_Linrot_ConfigCalibrationState(0);
1382             }
1383         }
1384 #endif
1385     }
1386     else
1387     {
1388         FOR_COUNTER_DEB = FOR_COUNTER_DEB_ERROR;
1389         if (FOR_COUNTER_DEB)
1390         {
1391             FOR_STATEID = TSC_STATEID_DEB_ERROR_PROX;
1392         }
1393         else
1394         {
1395             FOR_STATEID = TSC_STATEID_ERROR;
1396         }
1397     }
1398 }
1399 #endif
1400 
1401 /*!
1402  * @brief      Debounce Detect processing (previous state = Release or Proximity)
1403  *
1404  * @param      None
1405  *
1406  * @retval     None
1407  */
TSC_Linrot_ProcessDebDetectState(void)1408 void TSC_Linrot_ProcessDebDetectState(void)
1409 {
1410     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1411     {
1412         if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_DETECTIN_TH, 1))
1413         {
1414 #if TOUCH_USE_PROX > 0
1415             if (TSC_Linrot_Process_OneChannel_DeltaAboveEqu(FOR_PROXIN_TH, 0))
1416             {
1417                 FOR_STATEID = TSC_STATEID_RELEASE;
1418             }
1419             else
1420             {
1421                 FOR_COUNTER_DEB = FOR_COUNTER_DEB_PROX;
1422                 if (FOR_COUNTER_DEB)
1423                 {
1424                     FOR_STATEID = TSC_STATEID_DEB_PROX;
1425                 }
1426                 else
1427                 {
1428                     FOR_STATEID = TSC_STATEID_PROX;
1429                     DTO_READ_TIME;
1430                 }
1431             }
1432 #else
1433             FOR_STATEID = TSC_STATEID_RELEASE;
1434 #endif
1435         }
1436         else
1437         {
1438             if (FOR_COUNTER_DEB > 0)
1439             {
1440                 FOR_COUNTER_DEB--;
1441             }
1442             if (FOR_COUNTER_DEB == 0)
1443             {
1444                 FOR_STATEID = TSC_STATEID_DETECT;
1445                 DTO_READ_TIME;
1446             }
1447         }
1448     }
1449     else
1450     {
1451         FOR_STATEID = TSC_STATEID_RELEASE;
1452     }
1453 }
1454 
1455 /*!
1456  * @brief      Detect state processing
1457  *
1458  * @param      None
1459  *
1460  * @retval     None
1461  */
TSC_Linrot_ProcessDetectState(void)1462 void TSC_Linrot_ProcessDetectState(void)
1463 {
1464 #if TOUCH_DTO > 0
1465     TSC_STATUS_T pos_sts;
1466     TSC_tTick_sec_T tick_detected;
1467 #endif
1468 
1469     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1470     {
1471         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_DETECTOUT_TH, 1) == TSC_STATUS_OK)
1472         {
1473             /* Calculate position */
1474             if ((FOR_OBJ_TYPE == TSC_OBJ_LINEAR) || (FOR_OBJ_TYPE == TSC_OBJ_ROTARY))
1475             {
1476 #if TOUCH_DTO > 0
1477                 pos_sts = TSC_Globals.For_LinRot->p_Methods->CalcPosition();
1478 #else
1479                 TSC_Globals.For_LinRot->p_Methods->CalcPosition();
1480 #endif
1481             }
1482             else /*!<TSC_OBJ_LINEARB or TSC_OBJ_ROTARYB */
1483             {
1484 #if TOUCH_DTO > 0
1485                 pos_sts = TSC_Params.p_LinRotMet->CalcPosition();
1486 #else
1487                 TSC_Params.p_LinRotMet->CalcPosition();
1488 #endif
1489             }
1490 #if TOUCH_DTO > 0
1491             /* Detection Time Out (DTO) processing, Only if the Position has NOT changed */
1492             if (pos_sts)
1493             {
1494                 if ((TSC_Params.DTO > 1) && (TSC_Params.DTO < 64))
1495                 {
1496                     tick_detected = FOR_COUNTER_DTO;
1497                     /* Enter in calibration state if the DTO duration has elapsed */
1498                     if (TSC_Time_Delay_sec(TSC_Params.DTO, &tick_detected) == TSC_STATUS_OK)
1499                     {
1500                         TSC_Linrot_ConfigCalibrationState(0);
1501                     }
1502                 }
1503             }
1504             else
1505             {
1506                 DTO_READ_TIME;
1507             }
1508 #endif
1509             return;
1510         }
1511 
1512 #if TOUCH_USE_PROX > 0
1513         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0) == TSC_STATUS_OK)
1514         {
1515             FOR_COUNTER_DEB = FOR_COUNTER_DEB_PROX;
1516             if (FOR_COUNTER_DEB)
1517             {
1518                 FOR_STATEID = TSC_STATEID_DEB_PROX_DETECT;
1519             }
1520             else
1521             {
1522                 FOR_STATEID = TSC_STATEID_PROX;
1523                 DTO_READ_TIME;
1524             }
1525             return;
1526         }
1527 #endif
1528 
1529         FOR_COUNTER_DEB = FOR_COUNTER_DEB_RELEASE;
1530         if (FOR_COUNTER_DEB)
1531         {
1532             FOR_STATEID = TSC_STATEID_DEB_RELEASE_DETECT;
1533         }
1534         else
1535         {
1536             FOR_STATEID = TSC_STATEID_RELEASE;
1537         }
1538     }
1539     else
1540     {
1541         FOR_COUNTER_DEB = FOR_COUNTER_DEB_ERROR;
1542         if (FOR_COUNTER_DEB)
1543         {
1544             FOR_STATEID = TSC_STATEID_DEB_ERROR_DETECT;
1545         }
1546         else
1547         {
1548             FOR_STATEID = TSC_STATEID_ERROR;
1549         }
1550     }
1551 }
1552 
1553 /*!
1554  * @brief      Touch state processing, Same as Detect state
1555  *
1556  * @param      None
1557  *
1558  * @retval     None
1559  */
TSC_Linrot_ProcessTouchState(void)1560 void TSC_Linrot_ProcessTouchState(void)
1561 {
1562 #if TOUCH_DTO > 0
1563     TSC_STATUS_T pos_sts;
1564     TSC_tTick_sec_T tick_detected;
1565 #endif
1566 
1567     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1568     {
1569         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_DETECTOUT_TH, 1) == TSC_STATUS_OK)
1570         {
1571             /* Calculate position */
1572             if ((FOR_OBJ_TYPE == TSC_OBJ_LINEAR) || (FOR_OBJ_TYPE == TSC_OBJ_ROTARY))
1573             {
1574 #if TOUCH_DTO > 0
1575                 pos_sts = TSC_Globals.For_LinRot->p_Methods->CalcPosition();
1576 #else
1577                 TSC_Globals.For_LinRot->p_Methods->CalcPosition();
1578 #endif
1579             }
1580             else /* TSC_OBJ_LINEARB or TSC_OBJ_ROTARYB */
1581             {
1582 #if TOUCH_DTO > 0
1583                 pos_sts = TSC_Params.p_LinRotMet->CalcPosition();
1584 #else
1585                 TSC_Params.p_LinRotMet->CalcPosition();
1586 #endif
1587             }
1588 #if TOUCH_DTO > 0
1589             /* Detection Time Out (DTO) processing, Only if the Position has NOT changed */
1590             if (pos_sts)
1591             {
1592                 if ((TSC_Params.DTO > 1) && (TSC_Params.DTO < 64))
1593                 {
1594                     tick_detected = FOR_COUNTER_DTO;
1595                     /* Enter in calibration state if the DTO duration has elapsed */
1596                     if (TSC_Time_Delay_sec(TSC_Params.DTO, &tick_detected) == TSC_STATUS_OK)
1597                     {
1598                         TSC_Linrot_ConfigCalibrationState(0);
1599                     }
1600                 }
1601             }
1602             else
1603             {
1604                 DTO_READ_TIME;
1605             }
1606 #endif
1607             return;
1608         }
1609 
1610 #if TOUCH_USE_PROX > 0
1611         if (TSC_Linrot_Process_OneChannel_DeltaAbove(FOR_PROXOUT_TH, 0) == TSC_STATUS_OK)
1612         {
1613             FOR_COUNTER_DEB = FOR_COUNTER_DEB_PROX;
1614             if (FOR_COUNTER_DEB)
1615             {
1616                 FOR_STATEID = TSC_STATEID_DEB_PROX_TOUCH;
1617             }
1618             else
1619             {
1620                 FOR_STATEID = TSC_STATEID_PROX;
1621                 DTO_READ_TIME;
1622             }
1623             return;
1624         }
1625 #endif
1626 
1627         FOR_COUNTER_DEB = FOR_COUNTER_DEB_RELEASE;
1628         if (FOR_COUNTER_DEB)
1629         {
1630             FOR_STATEID = TSC_STATEID_DEB_RELEASE_TOUCH;
1631         }
1632         else
1633         {
1634             FOR_STATEID = TSC_STATEID_RELEASE;
1635         }
1636     }
1637     else
1638     {
1639         FOR_COUNTER_DEB = FOR_COUNTER_DEB_ERROR;
1640         if (FOR_COUNTER_DEB)
1641         {
1642             FOR_STATEID = TSC_STATEID_DEB_ERROR_TOUCH;
1643         }
1644         else
1645         {
1646             FOR_STATEID = TSC_STATEID_ERROR;
1647         }
1648     }
1649 }
1650 
1651 /*!
1652  * @brief      Debounce error state processing
1653  *
1654  * @param      None
1655  *
1656  * @retval     None
1657  */
TSC_Linrot_ProcessDebErrorState(void)1658 void TSC_Linrot_ProcessDebErrorState(void)
1659 {
1660     volatile TSC_STATEMASK_T mask;
1661 
1662     if (TSC_Linrot_Process_OneChannel_AcqStatusError())
1663     {
1664         mask = TSC_Linrot_ReadStateMask();
1665         mask &= (TSC_STATEMASK_T)(~(TSC_STATE_DEBOUNCE_BIT_MASK | TSC_STATE_ERROR_BIT_MASK));
1666 
1667         if (mask == TSC_STATEMASK_RELEASE)
1668         {
1669             FOR_STATEID = TSC_STATEID_RELEASE;
1670         }
1671         else if (mask == TSC_STATEMASK_PROX)
1672         {
1673             FOR_STATEID = TSC_STATEID_PROX;
1674         }
1675         else if (mask == TSC_STATEMASK_DETECT)
1676         {
1677             FOR_STATEID = TSC_STATEID_DETECT;
1678         }
1679         else if (mask == TSC_STATEMASK_TOUCH)
1680         {
1681             FOR_STATEID = TSC_STATEID_TOUCH;
1682         }
1683         else
1684         {
1685             TSC_Linrot_ConfigCalibrationState(0);
1686         }
1687     }
1688     else
1689     {
1690         if (FOR_COUNTER_DEB > 0)
1691         {
1692             FOR_COUNTER_DEB--;
1693         }
1694         if (FOR_COUNTER_DEB == 0)
1695         {
1696             FOR_STATEID = TSC_STATEID_ERROR;
1697         }
1698     }
1699 }
1700 
1701 /**@} State_machine Functions */
1702 
1703 /** @defgroup Private Functions
1704   @{
1705 */
1706 
1707 /*!
1708  * @brief      Read the current time in second and affect it to the DTO counter (Private)
1709  *
1710  * @param      None
1711  *
1712  * @retval     None
1713  */
TSC_Linrot_ReadTimeForDTO(void)1714 void TSC_Linrot_ReadTimeForDTO(void)
1715 {
1716     disableInterrupts();
1717     FOR_COUNTER_DTO = (TSC_tCounter_T)TSC_Globals.Tick_sec;
1718     enableInterrupts();
1719 }
1720 
1721 /*!
1722  * @brief      Set all channels status to ON, OFF or BURST only
1723  *
1724  * @param      status: Channel status
1725  *
1726  * @retval     None
1727  */
TSC_Linrot_Process_AllChannel_Status(TSC_OBJ_STATUS_T status)1728 void TSC_Linrot_Process_AllChannel_Status(TSC_OBJ_STATUS_T status)
1729 {
1730     TSC_tIndex_T index;
1731     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1732     /* Config channels status */
1733     for (index = 0; index < FOR_NB_CHANNELS; index++)
1734     {
1735         p_Ch->Flag.ObjStatus = status;
1736         p_Ch++;
1737     }
1738 }
1739 
1740 /*!
1741  * @brief      Check if at least one channel has a data ready
1742  *
1743  * @param      None
1744  *
1745  * @retval     Status
1746  */
TSC_Linrot_Process_OneChannel_DataReady(void)1747 TSC_STATUS_T TSC_Linrot_Process_OneChannel_DataReady(void)
1748 {
1749     TSC_tIndex_T index;
1750     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1751     TSC_STATUS_T retval = TSC_STATUS_ERROR;
1752     /* Return OK if at least one channel has a data ready */
1753     for (index = 0; index < FOR_NB_CHANNELS; index++)
1754     {
1755         if (p_Ch->Flag.DataReady == TSC_DATA_READY)
1756         {
1757             p_Ch->Flag.DataReady = TSC_DATA_NOT_READY;
1758             retval = TSC_STATUS_OK;
1759         }
1760         p_Ch++;
1761     }
1762     return retval;
1763 }
1764 
1765 /*!
1766  * @brief      Check if all channels are equal to the status passed
1767  *
1768  * @param      status: Channel status
1769  *
1770  * @retval     Status
1771  */
TSC_Linrot_Process_AllChannel_AcqStatus(TSC_ACQ_STATUS_T status)1772 TSC_STATUS_T TSC_Linrot_Process_AllChannel_AcqStatus(TSC_ACQ_STATUS_T status)
1773 {
1774     TSC_tIndex_T index;
1775     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1776     /* Return OK if ALL channels have the correct acq status */
1777     for (index = 0; index < FOR_NB_CHANNELS; index++)
1778     {
1779         if (p_Ch->Flag.AcqStatus != status)
1780         {
1781             return TSC_STATUS_ERROR;
1782         }
1783         p_Ch++;
1784     }
1785     return TSC_STATUS_OK;
1786 }
1787 
1788 /*!
1789  * @brief      Check if at least one channel is in error
1790  *
1791  * @param      None
1792  *
1793  * @retval     Status
1794  */
TSC_Linrot_Process_OneChannel_AcqStatusError(void)1795 TSC_STATUS_T TSC_Linrot_Process_OneChannel_AcqStatusError(void)
1796 {
1797     TSC_tIndex_T index;
1798     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1799     /* Return OK if at least one channel is in acquisition error min or max */
1800     for (index = 0; index < FOR_NB_CHANNELS; index++)
1801     {
1802         if (p_Ch->Flag.AcqStatus & TSC_ACQ_STATUS_ERROR_MASK)
1803         {
1804             return TSC_STATUS_OK;
1805         }
1806         p_Ch++;
1807     }
1808     return TSC_STATUS_ERROR;
1809 }
1810 
1811 /*!
1812  * @brief      Check if at least one channel is below or equal a threshold (inverted)
1813  *
1814  * @param      threshold: Threshold
1815  *
1816  * @param      Cmd: Enable or Disable the multiplier coefficient on threshold
1817  *
1818  * @retval     Status
1819  */
TSC_Linrot_Process_OneChannel_DeltaBelowEquMinus(TSC_tThreshold_T threshold,TSC_tIndex_T Cmd)1820 TSC_STATUS_T TSC_Linrot_Process_OneChannel_DeltaBelowEquMinus(TSC_tThreshold_T threshold, TSC_tIndex_T Cmd)
1821 {
1822     TSC_tIndex_T index;
1823     TSC_tDelta_T normDelta;
1824     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1825 
1826 #if TOUCH_COEFF_TH > 0
1827     uint16_t nowThreshold;
1828     if (Cmd != ENABLE)
1829     {
1830         nowThreshold = threshold;
1831     }
1832     else
1833     {
1834         nowThreshold = (uint16_t)((uint16_t)threshold << TOUCH_COEFF_TH);
1835     }
1836 #endif
1837 
1838     /* Return OK if at least one channel is below or equal the threshold */
1839     for (index = 0; index < FOR_NB_CHANNELS; index++)
1840     {
1841 #if TOUCH_LINROT_USE_NORMDELTA > 0
1842         normDelta = TSC_Linrot_NormDelta(p_Ch, index);
1843 #else
1844         normDelta = p_Ch->Delta;
1845 #endif
1846 
1847 #if TOUCH_COEFF_TH > 0
1848         if (normDelta <= -nowThreshold)
1849 #else
1850         if (normDelta <= -threshold)
1851 #endif
1852         {
1853             return TSC_STATUS_OK;
1854         }
1855         p_Ch++;
1856     }
1857     return TSC_STATUS_ERROR;
1858 }
1859 
1860 /*!
1861  * @brief      Check if at least one channel is above or equal a threshold
1862  *
1863  * @param      threshold: Threshold
1864  *
1865  * @param      Cmd: Enable or Disable the multiplier coefficient on threshold
1866  *
1867  * @retval     Status
1868  */
TSC_Linrot_Process_OneChannel_DeltaAboveEqu(TSC_tThreshold_T threshold,TSC_tIndex_T Cmd)1869 TSC_STATUS_T TSC_Linrot_Process_OneChannel_DeltaAboveEqu(TSC_tThreshold_T threshold, TSC_tIndex_T Cmd)
1870 {
1871     TSC_tIndex_T index;
1872     TSC_tDelta_T normDelta;
1873     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1874 
1875 #if TOUCH_COEFF_TH > 0
1876     uint16_t nowThreshold;
1877     if (Cmd != ENABLE)
1878     {
1879         nowThreshold = threshold;
1880     }
1881     else
1882     {
1883         nowThreshold = (uint16_t)((uint16_t)threshold << TOUCH_COEFF_TH);
1884     }
1885 #endif
1886 
1887     /* Return OK if at least one channel is above or equal the threshold */
1888     for (index = 0; index < FOR_NB_CHANNELS; index++)
1889     {
1890 #if TOUCH_LINROT_USE_NORMDELTA > 0
1891         normDelta = TSC_Linrot_NormDelta(p_Ch, index);
1892 #else
1893         normDelta = p_Ch->Delta;
1894 #endif
1895 
1896 #if TOUCH_COEFF_TH > 0
1897         if (normDelta >= nowThreshold)
1898 #else
1899         if (normDelta >= threshold)
1900 #endif
1901         {
1902 #if TOUCH_COEFF_TH > 0
1903             if (normDelta < 0)
1904             {
1905                 p_Ch++;
1906                 continue;
1907             }
1908 #endif
1909             return TSC_STATUS_OK;
1910         }
1911         p_Ch++;
1912     }
1913     return TSC_STATUS_ERROR;
1914 }
1915 
1916 /*!
1917  * @brief      Check if at least one channel is stricly above a threshold
1918  *
1919  * @param      threshold: Threshold
1920  *
1921  * @param      Cmd: Enable or Disable the multiplier coefficient on threshold
1922  *
1923  * @retval     Status
1924  */
TSC_Linrot_Process_OneChannel_DeltaAbove(TSC_tThreshold_T threshold,TSC_tIndex_T Cmd)1925 TSC_STATUS_T TSC_Linrot_Process_OneChannel_DeltaAbove(TSC_tThreshold_T threshold, TSC_tIndex_T Cmd)
1926 {
1927     TSC_tIndex_T index;
1928     TSC_tDelta_T normDelta;
1929     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1930 
1931 #if TOUCH_COEFF_TH > 0
1932     uint16_t nowThreshold;
1933     if (Cmd != ENABLE)
1934     {
1935         nowThreshold = threshold;
1936     }
1937     else
1938     {
1939         nowThreshold = (uint16_t)((uint16_t)threshold << TOUCH_COEFF_TH);
1940     }
1941 #endif
1942 
1943     /* Return OK if at least one channel is above the threshold */
1944     for (index = 0; index < FOR_NB_CHANNELS; index++)
1945     {
1946 #if TOUCH_LINROT_USE_NORMDELTA > 0
1947         normDelta = TSC_Linrot_NormDelta(p_Ch, index);
1948 #else
1949         normDelta = p_Ch->Delta;
1950 #endif
1951 
1952 #if TOUCH_COEFF_TH > 0
1953         if (normDelta > nowThreshold)
1954 #else
1955         if (normDelta > threshold)
1956 #endif
1957         {
1958 #if TOUCH_COEFF_TH > 0
1959             if (normDelta < 0)
1960             {
1961                 p_Ch++;
1962                 continue;
1963             }
1964 #endif
1965             return TSC_STATUS_OK;
1966         }
1967         p_Ch++;
1968     }
1969     return TSC_STATUS_ERROR;
1970 }
1971 
1972 /*!
1973  * @brief      Check if all channels are below or equal a threshold
1974  *
1975  * @param      threshold: Threshold
1976  *
1977  * @param      Cmd: Enable or Disable the multiplier coefficient on threshold
1978  *
1979  * @retval     Status
1980  */
TSC_Linrot_Process_AllChannel_DeltaBelowEqu(TSC_tThreshold_T threshold,TSC_tIndex_T Cmd)1981 TSC_STATUS_T TSC_Linrot_Process_AllChannel_DeltaBelowEqu(TSC_tThreshold_T threshold, TSC_tIndex_T Cmd)
1982 {
1983     TSC_tIndex_T index;
1984     TSC_tDelta_T normDelta;
1985     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
1986 
1987 #if TOUCH_COEFF_TH > 0
1988     uint16_t nowThreshold;
1989     if (Cmd != ENABLE)
1990     {
1991         nowThreshold = threshold;
1992     }
1993     else
1994     {
1995         nowThreshold = (uint16_t)((uint16_t)threshold << TOUCH_COEFF_TH);
1996     }
1997 #endif
1998 
1999     /* Return OK if ALL channels are below or equal the threshold */
2000     for (index = 0; index < FOR_NB_CHANNELS; index++)
2001     {
2002 #if TOUCH_LINROT_USE_NORMDELTA > 0
2003         normDelta = TSC_Linrot_NormDelta(p_Ch, index);
2004 #else
2005         normDelta = p_Ch->Delta;
2006 #endif
2007 
2008 #if TOUCH_COEFF_TH > 0
2009         if (normDelta > nowThreshold)
2010 #else
2011         if (normDelta > threshold)
2012 #endif
2013         {
2014 #if TOUCH_COEFF_TH > 0
2015             if (normDelta < 0)
2016             {
2017                 p_Ch++;
2018                 continue;
2019             }
2020 #endif
2021             return TSC_STATUS_ERROR;
2022         }
2023         p_Ch++;
2024     }
2025     return TSC_STATUS_OK;
2026 }
2027 
2028 /*!
2029  * @brief      Clear the Reference and ReferenceRest for all channels
2030  *
2031  * @param      None
2032  *
2033  * @retval     None
2034  */
TSC_Linrot_Process_AllChannel_ClearRef(void)2035 void TSC_Linrot_Process_AllChannel_ClearRef(void)
2036 {
2037     TSC_tIndex_T index;
2038     TSC_Channel_Data_T* p_Ch = TSC_Globals.For_LinRot->p_ChD;
2039     for (index = 0; index < FOR_NB_CHANNELS; index++)
2040     {
2041         p_Ch->Refer = 0;
2042         p_Ch->RefRest = 0;
2043         p_Ch++;
2044     }
2045 }
2046 
2047 /*!
2048  * @brief      Normalize a Delta value
2049  *
2050  * @param      channel: Pointer to the current channel
2051  *
2052  * @param      index: Index of the channel
2053  *
2054  * @retval     Normalized Delta value
2055  */
TSC_Linrot_NormDelta(TSC_Channel_Data_T * channel,TSC_tIndex_T index)2056 TSC_tDelta_T TSC_Linrot_NormDelta(TSC_Channel_Data_T* channel, TSC_tIndex_T index)
2057 {
2058     uint32_t tmpdelta = channel->Delta;
2059 
2060     if (TSC_Globals.For_LinRot->p_DeltaCoeff[index] != 0x0100)
2061     {
2062         tmpdelta = (uint32_t)(tmpdelta * TSC_Globals.For_LinRot->p_DeltaCoeff[index]);
2063         tmpdelta = tmpdelta >> (uint8_t)8;
2064     }
2065     return (TSC_tDelta_T)tmpdelta;
2066 }
2067 #endif /*!<#if TOUCH_TOTAL_LNRTS > 0 */
2068 
2069 /**@} Private Functions */
2070 
2071 /**@} end of group TSC_Linrot_Functions */
2072 /**@} end of group TSC_Linrot_Driver */
2073 /**@} end of group TSC_Driver_Library */
2074