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