1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - libraries - tp
3   File:     tp.c
4 
5   Copyright 2003-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2009-06-19#$
14   $Rev: 10786 $
15   $Author: okajima_manabu $
16  *---------------------------------------------------------------------------*/
17 
18 #include <nitro.h>
19 #include <nitro/spi/ARM9/tp.h>
20 #include <nitro/spi/common/config.h>
21 #include "spi.h"
22 
23 #define TP_RAW_MAX  0x1000
24 #define TP_CALIBRATE_DOT_INV_SCALE_SHIFT    (28 - TP_CALIBRATE_DOT_SCALE_SHIFT)
25 #define TP_CALIBRATE_DOT2ORIGIN_SCALE_SHIFT (TP_CALIBRATE_DOT_SCALE_SHIFT - TP_CALIBRATE_ORIGIN_SCALE_SHIFT)
26 
27 /*===========================================================================*
28     Static function prototype definition
29  *===========================================================================*/
30 
31 static void TPi_TpCallback(PXIFifoTag tag, u32 data, BOOL err);
32 
33 /*---------------------------------------------------------------------------*
34     Static variable definitions
35  *---------------------------------------------------------------------------*/
36 typedef struct
37 {
38     s32     x0;                        // X coordinate intercept
39     s32     xDotSize;                  // X dot width
40     s32     xDotSizeInv;               // X denominator
41 
42     s32     y0;                        // Y coordinate intercept
43     s32     yDotSize;                  // Y dot width
44     s32     yDotSizeInv;               // Y denominator
45 
46 }
47 TPiCalibrateParam;
48 
49 #pragma  warn_padding off
50 static struct
51 {
52     TPRecvCallback callback;           // User callback function called when TP value obtained
53     TPData  buf;                       // TP value receive buffer when TP value is obtained once
54     u16     index;                     // Latest buffer index during auto-sampling
55     u16     frequence;                 // Auto-sampling frequency in a single frame
56     TPData *samplingBufs;              // Pointer to the TP value buffer during auto-sampling
57     u16     bufSize;                   // TP buffer size during auto-sampling
58     // PADDING 2 BYTE
59     TPiCalibrateParam calibrate;       // Calibration parameters
60     u16     calibrate_flg;             // calibration flag
61 
62     vu16    state;                     // Touch panel status
63     vu16    err_flg;                   // Error flag
64     vu16    command_flg;               // Flag while request command is executing
65 }
66 tpState;
67 #pragma  warn_padding reset
68 
69 
70 /*---------------------------------------------------------------------------*
71     Inline sub-routine definition
72 
73     The response from ARM7 for these instructions are returned via the PXI library.
74     To obtain the response from the ARM7, specify the callback for the "PXI_FIFO_TAG_TOUCHPANEL" tag to PXI.
75 
76  *---------------------------------------------------------------------------*/
77 
78 /*---------------------------------------------------------------------------*
79   Name:         TPi_SamplingNow
80 
81   Description:  Samples touch panel once.
82 
83   Arguments:    None.
84 
85   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
86 
87  *---------------------------------------------------------------------------*/
TPi_SamplingNow(void)88 static inline BOOL TPi_SamplingNow(void)
89 {
90     // Send packet [0]
91     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TOUCHPANEL,
92                                SPI_PXI_START_BIT
93                                | SPI_PXI_END_BIT
94                                | (0 << SPI_PXI_INDEX_SHIFT)
95                                | (SPI_PXI_COMMAND_TP_SAMPLING << 8), 0))
96     {
97         return FALSE;
98     }
99 
100     return TRUE;
101 }
102 
103 /*---------------------------------------------------------------------------*
104   Name:         TPi_AutoSamplingOn
105 
106   Description:  Begins auto-sampling the touch panel.
107 
108   Arguments:    vCount: V-Count at which to carry out sampling.
109                             If sampling is done multiple times per each single frame, the single frame is divided in time starting here.
110 
111                 frequency - Frequency of sampling for 1 frame.
112 
113   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
114 
115  *---------------------------------------------------------------------------*/
TPi_AutoSamplingOn(u16 vCount,u8 frequency)116 static inline BOOL TPi_AutoSamplingOn(u16 vCount, u8 frequency)
117 {
118     // Send packet [0]
119     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TOUCHPANEL,
120                                SPI_PXI_START_BIT
121                                | (0 << SPI_PXI_INDEX_SHIFT)
122                                | (SPI_PXI_COMMAND_TP_AUTO_ON << 8) | (u32)frequency, 0))
123     {
124         return FALSE;
125     }
126 
127     // Send packet [1]
128     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TOUCHPANEL,
129                                SPI_PXI_END_BIT | (1 << SPI_PXI_INDEX_SHIFT) | (u32)vCount, 0))
130     {
131         return FALSE;
132     }
133 
134     return TRUE;
135 }
136 
137 /*---------------------------------------------------------------------------*
138   Name:         TPi_AutoSamplingOff
139 
140   Description:  Stop auto-sampling the touch panel
141 
142   Arguments:    None.
143 
144   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
145 
146  *---------------------------------------------------------------------------*/
TPi_AutoSamplingOff(void)147 static inline BOOL TPi_AutoSamplingOff(void)
148 {
149     // Send packet [0]
150     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TOUCHPANEL,
151                                SPI_PXI_START_BIT
152                                | SPI_PXI_END_BIT
153                                | (0 << SPI_PXI_INDEX_SHIFT)
154                                | (SPI_PXI_COMMAND_TP_AUTO_OFF << 8), 0))
155     {
156         return FALSE;
157     }
158 
159     return TRUE;
160 }
161 
162 /*---------------------------------------------------------------------------*
163   Name:         TPi_SetupStability
164 
165   Description:  Sets stability determination parameters for sampling
166 
167   Arguments:    range - For continuous sampling, error for which detected voltage is considered stable.
168                         The detection value is 12 bits, 0 - 4095.
169 
170   Returns:      BOOL - Returns TRUE when the command was successfully sent via PXI and FALSE on failure.
171 
172  *---------------------------------------------------------------------------*/
TPi_SetupStability(u16 range)173 static inline BOOL TPi_SetupStability(u16 range)
174 {
175     // Send packet [0]
176     if (0 > PXI_SendWordByFifo(PXI_FIFO_TAG_TOUCHPANEL,
177                                SPI_PXI_START_BIT
178                                | SPI_PXI_END_BIT
179                                | (0 << SPI_PXI_INDEX_SHIFT)
180                                | (SPI_PXI_COMMAND_TP_SETUP_STABILITY << 8) | (u32)range, 0))
181     {
182         return FALSE;
183     }
184 
185     return TRUE;
186 }
187 
188 
189 /*---------------------------------------------------------------------------*
190   Name:         TPi_CopyTpFromSystemWork
191 
192   Description:  Takes the touch screen values data written to shared memory from ARM7, and reads them out to a separate region.
193 
194 
195   Returns:      result - Stores the latest touch panel value that was read.
196  *---------------------------------------------------------------------------*/
TPi_CopyTpFromSystemWork(TPData * result)197 static inline void TPi_CopyTpFromSystemWork(TPData *result)
198 {
199     SPITpData spi_tp;
200 
201     spi_tp.halfs[0] = *(u16 *)(&(OS_GetSystemWork()->touch_panel[0]));
202     spi_tp.halfs[1] = *(u16 *)(&(OS_GetSystemWork()->touch_panel[2]));
203 
204     // Read from system area (2 byte access)
205     result->x = (u16)spi_tp.e.x;
206     result->y = (u16)spi_tp.e.y;
207     result->touch = (u8)spi_tp.e.touch;
208     result->validity = (u8)spi_tp.e.validity;
209 }
210 
211 
212 /*---------------------------------------------------------------------------*
213   Name:         TPi_ErrorAtPxi
214 
215   Description:  Processing for an error in PXI communication with ARM7.
216                 If a callback is set, this returns the TP_RESULT_PXI_BUSY callback
217 
218 
219   Arguments:    command - Request type
220 
221   Returns:      None.
222  *---------------------------------------------------------------------------*/
TPi_ErrorAtPxi(TPRequestCommand command)223 static inline void TPi_ErrorAtPxi(TPRequestCommand command)
224 {
225 
226     tpState.err_flg |= (1 << command);
227 
228     if (tpState.callback)
229     {
230         (tpState.callback) (command, TP_RESULT_PXI_BUSY, 0);
231     }
232 }
233 
234 
235 /*===========================================================================*
236     Function definition
237  *===========================================================================*/
238 
239 /*---------------------------------------------------------------------------*
240   Name:         TPi_TpCallback
241 
242   Description:  This is the function called when PXI receives a touch screen-related message from the ARM7.
243 
244                 This saves the touch screen values from ARM7, and if a callback function is set, it also calls the user callback.
245 
246 
247 
248   Arguments:    tag -  Tag so PXI can distinguish type
249                 data - Message data from ARM7
250                 err -  PXI transfer error flag
251 
252   Returns:      None.
253  *---------------------------------------------------------------------------*/
TPi_TpCallback(PXIFifoTag tag,u32 data,BOOL err)254 static void TPi_TpCallback(PXIFifoTag tag, u32 data, BOOL err)
255 {
256 #pragma unused(tag)
257 
258     u16     result;
259     u16     command;
260 
261     result = (u16)(data & SPI_PXI_DATA_MASK);
262     command = (u16)((result & 0x7f00) >> 8);
263 
264     // PXI transfer error
265     if (err)
266     {
267         TPi_ErrorAtPxi((TPRequestCommand)command);
268         return;
269     }
270 
271     if (command == SPI_PXI_COMMAND_TP_AUTO_SAMPLING)
272     {
273         // Notification that auto-sampling execution has completed
274 //        tpState.index = (u16) (result & 0x00FF);
275         tpState.index++;
276         if (tpState.index >= tpState.bufSize)
277         {
278             tpState.index = 0;
279         }
280 
281         // Save touch panel values from the shared area
282         TPi_CopyTpFromSystemWork(&tpState.samplingBufs[tpState.index]);
283 
284         if (tpState.callback)
285         {
286             (tpState.callback) ((TPRequestCommand)command, TP_RESULT_SUCCESS, (u8)tpState.index);
287         }
288         return;
289     }
290 
291     if (!(data & SPI_PXI_END_BIT))
292     {
293         return;
294     }
295 
296     SDK_ASSERT(result & 0x8000);
297 
298     switch ((u8)(result & 0x00ff))
299     {
300     case SPI_PXI_RESULT_SUCCESS:
301         // Process when successful
302         switch (command)
303         {
304         case SPI_PXI_COMMAND_TP_SAMPLING:
305             // Obtain sampling result
306             TPi_CopyTpFromSystemWork(&tpState.buf);
307             tpState.state = TP_STATE_READY;
308             break;
309 
310         case SPI_PXI_COMMAND_TP_AUTO_ON:
311             tpState.state = TP_STATE_AUTO_SAMPLING;
312             break;
313 
314         case SPI_PXI_COMMAND_TP_AUTO_OFF:
315             tpState.state = TP_STATE_READY;
316             break;
317         }
318 
319         // Turn off busy flag
320         tpState.command_flg &= ~(1 << command);
321 
322         // callback call
323         if (tpState.callback)
324         {
325             (tpState.callback) ((TPRequestCommand)command, TP_RESULT_SUCCESS, 0);
326         }
327         break;
328 
329     case SPI_PXI_RESULT_EXCLUSIVE:
330         result = TP_RESULT_EXCLUSIVE;
331         goto common;
332 
333     case SPI_PXI_RESULT_INVALID_PARAMETER:
334         result = TP_RESULT_INVALID_PARAMETER;
335         goto common;
336 
337     case SPI_PXI_RESULT_ILLEGAL_STATUS:
338         result = TP_RESULT_ILLEGAL_STATUS;
339 
340       common:
341         // Error processing
342         // Set error flag
343         tpState.err_flg |= (1 << command);
344         tpState.command_flg &= ~(1 << command);
345 
346         if (tpState.callback)
347         {
348             (tpState.callback) ((TPRequestCommand)command, (TPRequestResult)(result & 0xff), 0);
349         }
350         break;
351 
352     case SPI_PXI_RESULT_INVALID_COMMAND:
353     default:
354         // Abnormal end
355 //        OS_TPrintf("result=%x\n",result);
356         OS_TPanic("Get illegal TP command from ARM7!\n");
357         return;
358     }
359 }
360 
361 
362 
363 
364 /*---------------------------------------------------------------------------*
365   Name:         TP_Init
366 
367   Description:  Touch panel library initialization
368 
369   Arguments:    None.
370 
371   Returns:      None.
372  *---------------------------------------------------------------------------*/
TP_Init(void)373 void TP_Init(void)
374 {
375     static u16 initial = FALSE;
376 
377     if (initial)
378     {
379         return;
380     }
381     initial = TRUE;
382 
383     //****************************************************************
384     // Initialize TP.
385     //****************************************************************
386     PXI_Init();
387 
388     tpState.index = 0;
389     tpState.callback = NULL;
390     tpState.samplingBufs = NULL;
391     tpState.state = TP_STATE_READY;
392     tpState.calibrate_flg = FALSE;
393     tpState.command_flg = 0;
394     tpState.err_flg = 0;
395 
396     // 2003/05/18 Add by terui.
397     while (!PXI_IsCallbackReady(PXI_FIFO_TAG_TOUCHPANEL, PXI_PROC_ARM7))
398     {
399     }
400 
401     PXI_SetFifoRecvCallback(PXI_FIFO_TAG_TOUCHPANEL, TPi_TpCallback);
402 }
403 
404 
405 /*---------------------------------------------------------------------------*
406   Name:         TP_GetUserInfo
407 
408   Description:  This function gets calibration parameters from the system's internal flash memory.
409 
410 
411   Returns:      param - Pointer to area for obtaining parameters
412                 BOOL  - TRUE if the values were successfully acquired
413                         Returns FALSE if valid values could not be found.
414  *---------------------------------------------------------------------------*/
TP_GetUserInfo(TPCalibrateParam * calibrate)415 BOOL TP_GetUserInfo(TPCalibrateParam *calibrate)
416 {
417     NVRAMConfig *info = (NVRAMConfig *)(OS_GetSystemWork()->nvramUserInfo);
418 //    s16 x0, y0, xdot, ydot;
419     u16     x1, y1, x2, y2, dx1, dy1, dx2, dy2;
420 
421     SDK_NULL_ASSERT(calibrate);
422 
423     x1 = info->ncd.tp.raw_x1;
424     y1 = info->ncd.tp.raw_y1;
425     dx1 = (u16)(info->ncd.tp.dx1);
426     dy1 = (u16)(info->ncd.tp.dy1);
427     x2 = info->ncd.tp.raw_x2;
428     y2 = info->ncd.tp.raw_y2;
429     dx2 = (u16)(info->ncd.tp.dx2);
430     dy2 = (u16)(info->ncd.tp.dy2);
431 
432     /* For now, since there is no enable flag for the calibration value */
433     if ((x1 == 0 && x2 == 0 && y1 == 0 && y2 == 0) ||
434         (TP_CalcCalibrateParam(calibrate, x1, y1, dx1, dy1, x2, y2, dx2, dy2) != 0))
435     {
436         // Since a CRC check on the data is not performed in the IPL, if values are abnormal, zero-clear all parameters and return TRUE.
437         //
438         // In this case, the TP value always becomes (0,0) after calibration.
439         calibrate->x0 = 0;
440         calibrate->y0 = 0;
441         calibrate->xDotSize = 0;
442         calibrate->yDotSize = 0;
443         return TRUE;
444     }
445     return TRUE;
446 }
447 
448 
449 /*---------------------------------------------------------------------------*
450   Name:         TP_SetCalibrateParam
451 
452   Description:  Set parameters for calibration.
453                 After parameters are set with this function, the values are used for calibration in TP_WaitCalibratedResult(), TP_GetLatestCalibratedPointInAuto(), TP_GetCalibratedPoint(), and TP_GetUnCalibratedPoint().
454 
455 
456                  At this point, the reciprocal of the dot size is calculated in advance.
457 
458   Arguments:    param - Pointer to the calibration parameters to set
459                         If NULL is set, further coordinate conversions due to calibration will not be carried out.
460                          (Default value: NULL)
461 
462   Returns:      None.
463  *---------------------------------------------------------------------------*/
TP_SetCalibrateParam(const TPCalibrateParam * param)464 void TP_SetCalibrateParam(const TPCalibrateParam *param)
465 {
466     OSIntrMode enabled;
467 
468     if (param == NULL)
469     {
470         tpState.calibrate_flg = FALSE;
471         return;
472     }
473 
474     // Calculate the reciprocals of xDotSize and yDotSize in advance
475     enabled = OS_DisableInterrupts();
476 
477     if (param->xDotSize != 0)
478     {
479         CP_SetDiv32_32(0x10000000, (u32)param->xDotSize);
480 
481         tpState.calibrate.x0 = param->x0;
482         tpState.calibrate.xDotSize = param->xDotSize;
483         tpState.calibrate.xDotSizeInv = (s32)CP_GetDivResult32();
484     }
485     else
486     {
487         tpState.calibrate.x0 = 0;
488         tpState.calibrate.xDotSize = 0;
489         tpState.calibrate.xDotSizeInv = 0;
490     }
491 
492     if (param->yDotSize != 0)
493     {
494         CP_SetDiv32_32(0x10000000, (u32)param->yDotSize);
495 
496         tpState.calibrate.y0 = param->y0;
497         tpState.calibrate.yDotSize = param->yDotSize;
498         tpState.calibrate.yDotSizeInv = (s32)CP_GetDivResult32();
499     }
500     else
501     {
502         tpState.calibrate.y0 = 0;
503         tpState.calibrate.yDotSize = 0;
504         tpState.calibrate.yDotSizeInv = 0;
505     }
506 
507     (void)OS_RestoreInterrupts(enabled);
508 
509     tpState.calibrate_flg = TRUE;
510 
511 }
512 
513 
514 /*---------------------------------------------------------------------------*
515   Name:         TP_SetCallback
516 
517   Description:  Sets the user callback function that is invoked when processing results are returned from the Touch Screen.
518 
519 
520   Arguments:    callback - User callback function pointer
521                            If NULL, callback is not called (default:NULL)
522 
523   Returns:      None.
524  *---------------------------------------------------------------------------*/
TP_SetCallback(TPRecvCallback callback)525 void TP_SetCallback(TPRecvCallback callback)
526 {
527     OSIntrMode enabled;
528 
529     enabled = OS_DisableInterrupts();
530     tpState.callback = callback;
531     (void)OS_RestoreInterrupts(enabled);
532 }
533 
534 
535 
536 /*---------------------------------------------------------------------------*
537   Name:         TP_RequestSamplingAsync
538 
539   Description:  Request a touch panel value from ARM7.
540                 After calling this function, you can use TP_WaitRawResult() or TP_WaitCalibratedResult() to read Touch Screen values.
541                 Cannot be used while auto sampling.
542 
543 
544   Arguments:    None.
545 
546   Returns:      None.
547  *---------------------------------------------------------------------------*/
TP_RequestSamplingAsync(void)548 void TP_RequestSamplingAsync(void)
549 {
550     OSIntrMode enabled;
551 
552     SDK_ASSERT(!(tpState.command_flg & TP_REQUEST_COMMAND_FLAG_SAMPLING));
553 
554     enabled = OS_DisableInterrupts();
555 
556     if (TPi_SamplingNow() == FALSE)
557     {
558         // Failure on PXI send
559         (void)OS_RestoreInterrupts(enabled);
560         TPi_ErrorAtPxi(TP_REQUEST_COMMAND_SAMPLING);
561         return;
562     }
563     tpState.command_flg |= TP_REQUEST_COMMAND_FLAG_SAMPLING;
564     tpState.err_flg &= ~TP_REQUEST_COMMAND_FLAG_SAMPLING;
565 
566     (void)OS_RestoreInterrupts(enabled);
567 }
568 
569 
570 /*---------------------------------------------------------------------------*
571   Name:         TP_WaitRawResult
572 
573   Description:  Waits for the ARM7 to set the touch screen values, then reads the uncalibrated raw values.
574 
575                 Data that is acquired here has already been subjected to chattering measures.
576 
577   Arguments:    None.
578 
579   Returns:      result:   Pointer to a variable that is used to acquire touch panel values
580                          Takes uncalibrated values (0 - 4095) as x,y coordinates.
581                 u32: Returns 0 if data was obtained successfully and a non-zero value on failure.
582 
583  *---------------------------------------------------------------------------*/
TP_WaitRawResult(TPData * result)584 u32 TP_WaitRawResult(TPData *result)
585 {
586     SDK_NULL_ASSERT(result);
587 
588     TP_WaitBusy(TP_REQUEST_COMMAND_FLAG_SAMPLING);
589 
590     if (tpState.err_flg & TP_REQUEST_COMMAND_FLAG_SAMPLING)
591     {
592         return 1;
593     }
594 
595     *result = tpState.buf;
596     return 0;
597 }
598 
599 
600 
601 /*---------------------------------------------------------------------------*
602   Name:         TP_GetCalibratedResult
603 
604   Description:  Assumes that the ARM7 has set the touch screen values, and reads values that correspond to calibrated screen coordinates.
605 
606                 Data that is acquired here has already been subjected to chattering measures.
607 
608   Arguments:    result:   Pointer to a variable that is used to acquire touch panel values
609                          The x, y coordinates will be the values corresponding to the screen coordinates.
610                          If calibration parameters have not been set, this function obtains Touch Screen values in the range (0-4095).
611 
612 
613   Returns:      u32: Returns 0 if data was obtained successfully and a non-zero value on failure.
614 
615  *---------------------------------------------------------------------------*/
TP_GetCalibratedResult(TPData * result)616 u32 TP_GetCalibratedResult(TPData *result)
617 {
618     SDK_NULL_ASSERT(result);
619 
620     if (tpState.err_flg & TP_REQUEST_COMMAND_FLAG_SAMPLING)
621     {
622         return 1;
623     }
624 
625     *result = tpState.buf;
626     TP_GetCalibratedPoint(result, result);
627     return 0;
628 }
629 
630 
631 /*---------------------------------------------------------------------------*
632   Name:         TP_WaitCalibratedResult
633 
634   Description:  Waits for the ARM7 to set the touch screen values, and reads values that correspond to calibrated screen coordinates.
635 
636                 Data that is acquired here has already been subjected to chattering measures.
637 
638   Arguments:    result:   Pointer to a variable that is used to acquire touch panel values
639                          The x, y coordinates will be the values corresponding to the screen coordinates.
640                          If calibration parameters have not been set, this function obtains Touch Screen values in the range (0-4095).
641 
642 
643   Returns:      u32: Returns 0 if data was obtained successfully and a non-zero value on failure.
644 
645  *---------------------------------------------------------------------------*/
TP_WaitCalibratedResult(TPData * result)646 u32 TP_WaitCalibratedResult(TPData *result)
647 {
648     TP_WaitBusy(TP_REQUEST_COMMAND_FLAG_SAMPLING);
649     return TP_GetCalibratedResult(result);
650 }
651 
652 
653 /*---------------------------------------------------------------------------*
654   Name:         TP_RequestAutoSamplingStartAsync
655 
656   Description:  Sends a request to ARM7 to start auto sampling touch panel values.
657                 In one frame, data is sampled 'frequence' times at equal intervals, and the results are stored to an array specified by 'samplingBufs'.
658 
659 
660   Arguments:    vcount:        Sets the VCOUNT value, which is used as the standard for auto sampling
661                 frequence:     Setting for the number of times sampling will be done in one frame
662                 samplingBufs:   Sets the area where auto-sampling data will be stored
663                 bufSize      - Sets the buffer size
664                                The samplingBufs array is used as a ring buffer of size bufSize.
665 
666   Returns:      None.
667  *---------------------------------------------------------------------------*/
TP_RequestAutoSamplingStartAsync(u16 vcount,u16 frequence,TPData samplingBufs[],u16 bufSize)668 void TP_RequestAutoSamplingStartAsync(u16 vcount, u16 frequence, TPData samplingBufs[], u16 bufSize)
669 {
670     u32     i;
671     OSIntrMode enabled;
672 
673     SDK_NULL_ASSERT(samplingBufs);
674     SDK_ASSERT(vcount < HW_LCD_LINES);
675     SDK_ASSERT(frequence != 0 && frequence <= SPI_TP_SAMPLING_FREQUENCY_MAX);
676     SDK_ASSERT(tpState.state == TP_STATE_READY);
677     SDK_ASSERT(!(tpState.command_flg & TP_REQUEST_COMMAND_FLAG_AUTO_ON));
678     SDK_ASSERT(bufSize != 0);
679 
680     tpState.samplingBufs = samplingBufs;
681     tpState.index = 0;
682     tpState.frequence = frequence;
683     tpState.bufSize = bufSize;
684 
685     for (i = 0; i < bufSize; i++)
686     {
687         tpState.samplingBufs[i].touch = TP_TOUCH_OFF;
688     }
689 
690     enabled = OS_DisableInterrupts();
691 
692     if ((u8)TPi_AutoSamplingOn(vcount, (u8)frequence) == FALSE)
693     {
694         // Failure on PXI send
695         (void)OS_RestoreInterrupts(enabled);
696         TPi_ErrorAtPxi(TP_REQUEST_COMMAND_AUTO_ON);
697         return;
698     }
699     tpState.command_flg |= TP_REQUEST_COMMAND_FLAG_AUTO_ON;
700     tpState.err_flg &= ~TP_REQUEST_COMMAND_FLAG_AUTO_ON;
701 
702     (void)OS_RestoreInterrupts(enabled);
703 }
704 
705 /*---------------------------------------------------------------------------*
706   Name:         TP_RequestAutoSamplingStopAsync
707 
708   Description:  Sends a request to ARM7 to stop auto sampling touch panel values.
709 
710   Arguments:    None.
711 
712   Returns:      None.
713  *---------------------------------------------------------------------------*/
TP_RequestAutoSamplingStopAsync(void)714 void TP_RequestAutoSamplingStopAsync(void)
715 {
716     OSIntrMode enabled;
717 
718     SDK_ASSERT(tpState.state == TP_STATE_AUTO_SAMPLING);
719     SDK_ASSERT(!(tpState.command_flg & TP_REQUEST_COMMAND_FLAG_AUTO_OFF));
720 
721     enabled = OS_DisableInterrupts();
722 
723     if (TPi_AutoSamplingOff() == FALSE)
724     {
725         // Failure on PXI send
726         (void)OS_RestoreInterrupts(enabled);
727         TPi_ErrorAtPxi(TP_REQUEST_COMMAND_AUTO_OFF);
728         return;
729     }
730 
731     tpState.command_flg |= TP_REQUEST_COMMAND_FLAG_AUTO_OFF;
732     tpState.err_flg &= ~TP_REQUEST_COMMAND_FLAG_AUTO_OFF;
733 
734     (void)OS_RestoreInterrupts(enabled);
735 
736 }
737 
738 
739 /*---------------------------------------------------------------------------*
740   Name:         TP_RequestSetStabilityAsync
741 
742   Description:  Sets touch panel anti-chattering parameters.
743                 Sets the number of times to retry sampling before values stabilize, and a range for determining whether values have stabilized.
744 
745 
746   Arguments:    retry:   This argument is not used internally.
747                 range:   Range for determining whether the values have stabilized.
748                          Coordinate values that do not converge within this range are invalid.
749                          (Range: 0 to 4095, Default value: 20)
750 
751   Returns:      None.
752  *---------------------------------------------------------------------------*/
TP_RequestSetStabilityAsync(u8 retry,u16 range)753 void TP_RequestSetStabilityAsync(u8 retry, u16 range)
754 {
755 #pragma unused( retry )
756     OSIntrMode enabled;
757 
758     SDK_ASSERT(range != 0);
759     SDK_ASSERT(range < 255);
760 
761     enabled = OS_DisableInterrupts();
762 
763     if (TPi_SetupStability(range) == FALSE)
764     {
765         // Failure on PXI send
766         (void)OS_RestoreInterrupts(enabled);
767         TPi_ErrorAtPxi(TP_REQUEST_COMMAND_SET_STABILITY);
768         return;
769     }
770     tpState.command_flg |= TP_REQUEST_COMMAND_FLAG_SET_STABILITY;
771     tpState.err_flg &= ~TP_REQUEST_COMMAND_FLAG_SET_STABILITY;
772 
773     (void)OS_RestoreInterrupts(enabled);
774 }
775 
776 
777 
778 /*---------------------------------------------------------------------------*
779   Name:         TP_GetLatestRawPointInAuto
780 
781   Description:  Obtains the latest, valid touch panel values from the results of auto-sampling.
782                 The x and y coordinates of the values take the uncalibrated range (0-4095).
783 
784   Arguments:    None.
785 
786   Returns:      result - Pointer for obtaining the latest, valid touch panel value
787  *---------------------------------------------------------------------------*/
TP_GetLatestRawPointInAuto(TPData * result)788 void TP_GetLatestRawPointInAuto(TPData *result)
789 {
790     s32     i, curr_index;
791     TPData *tp;
792 
793     SDK_NULL_ASSERT(result);
794     SDK_NULL_ASSERT(tpState.samplingBufs);
795 
796     result->validity = TP_VALIDITY_INVALID_XY;
797 
798     curr_index = tpState.index;
799 
800     // If the sampling buffer size is 1, return the current coordinate values unchanged
801     if (tpState.frequence == 1 || tpState.bufSize == 1)
802     {
803         *result = tpState.samplingBufs[curr_index];
804         return;
805     }
806 
807     // Search for the most recent of the valid sampling values
808     for (i = 0; i < tpState.frequence && i < tpState.bufSize - 1; i++)
809     {
810         s32     index;
811 
812         index = curr_index - i;
813         if (index < 0)
814         {
815             index += tpState.bufSize;
816         }
817 
818         tp = &tpState.samplingBufs[index];
819 
820         if (!tp->touch)
821         {
822             *result = *tp;
823             return;
824         }
825 
826         // If invalid data is present refer to the next-older sampling value
827         if (result->validity & TP_VALIDITY_INVALID_X)
828         {
829             /* X-coordinate */
830             if (!(tp->validity & TP_VALIDITY_INVALID_X))
831             {
832                 result->x = tp->x;
833                 if (i != 0)
834                 {
835                     result->validity &= ~TP_VALIDITY_INVALID_X;
836                 }
837             }
838         }
839 
840         if (result->validity & TP_VALIDITY_INVALID_Y)
841         {
842             /* Y-coordinate */
843             if (!(tp->validity & TP_VALIDITY_INVALID_Y))
844             {
845                 result->y = tp->y;
846                 if (i != 0)
847                 {
848                     result->validity &= ~TP_VALIDITY_INVALID_Y;
849                 }
850             }
851         }
852 
853         if (result->validity == TP_VALIDITY_VALID)
854         {
855             result->touch = TP_TOUCH_ON;
856             return;
857         }
858     }
859 
860     // When an invalid coordinate value is left, return the value that could be obtained.
861     result->touch = TP_TOUCH_ON;
862     return;
863 }
864 
865 
866 
867 /*---------------------------------------------------------------------------*
868   Name:         TP_GetLatestCalibratedPointInAuto
869 
870   Description:  Obtains the latest, valid touch panel values from the results of auto-sampling.
871                 The x and y coordinates of the values take the range of screen coordinates.
872 
873   Arguments:    None.
874 
875   Returns:      result - Pointer for obtaining the latest, valid touch panel value
876  *---------------------------------------------------------------------------*/
TP_GetLatestCalibratedPointInAuto(TPData * result)877 void TP_GetLatestCalibratedPointInAuto(TPData *result)
878 {
879     SDK_NULL_ASSERT(result);
880 
881     TP_GetLatestRawPointInAuto(result);
882 
883     TP_GetCalibratedPoint(result, result);
884 
885 }
886 
887 
888 /*---------------------------------------------------------------------------*
889   Name:         TP_GetLatestIndexInAuto
890 
891   Description:  Returns the index in the loop buffer (in which values are stored by auto-sampling) for the data that was last sampled.
892 
893 
894   Arguments:    None.
895 
896   Returns:      u16 - Index to the data that was last sampled.
897  *---------------------------------------------------------------------------*/
TP_GetLatestIndexInAuto(void)898 u16 TP_GetLatestIndexInAuto(void)
899 {
900     return tpState.index;
901 }
902 
903 
904 
905 
906 /*---------------------------------------------------------------------------*
907   Name:         TP_CalcCalibrateParam
908 
909   Description:  Calculates calibration parameters from the Touch Screen values and the screen coordinates for two points.
910 
911 
912   Arguments:    raw_x1, raw_y1 - Point 1's touch panel values
913                 dx1, dy1       - Point 1's screen coordinates
914                 raw_x2, raw_y2 - Point 2's touch panel values
915                 dx2, dy2,      - Point 2's screen coordinates
916 
917   Returns:      calibrate      - Calibration parameters
918                 u32            - Returns zero for valid parameters and nonzero for invalid parameters.
919 
920 
921  *---------------------------------------------------------------------------*/
TP_CalcCalibrateParam(TPCalibrateParam * calibrate,u16 raw_x1,u16 raw_y1,u16 dx1,u16 dy1,u16 raw_x2,u16 raw_y2,u16 dx2,u16 dy2)922 u32 TP_CalcCalibrateParam(TPCalibrateParam *calibrate,
923                           u16 raw_x1, u16 raw_y1,
924                           u16 dx1, u16 dy1, u16 raw_x2, u16 raw_y2, u16 dx2, u16 dy2)
925 {
926     s32     rx_width, dx_width, ry_width, dy_width;
927     s32     tmp32;
928     OSIntrMode enabled;
929 
930 #define IN_S16_RANGE(x) ((x) < 0x8000 && (x) >= -0x8000)
931 
932     /*                                                                  */
933     /* xDotSize = ((raw_x1 - raw_x2) << SCALE_SHIFT) / (dx1 - dx2)      */
934     /* x0 = ((raw_x1 + raw_x2) - (dx1 + dx2) * xDotSize) / 2            */
935     /* xDotSize = ((raw_x1 - raw_x2) << SCALE_SHIFT) / (dx1 - dx2)      */
936     /* x0 = ((raw_x1 + raw_x2) - (dx1 + dx2) * xDotSize) / 2            */
937     /*                                                                  */
938 
939     SDK_NULL_ASSERT(calibrate);
940     // Check the coordinate range
941     if (raw_x1 >= TP_RAW_MAX || raw_y1 >= TP_RAW_MAX || raw_x2 >= TP_RAW_MAX
942         || raw_y2 >= TP_RAW_MAX)
943     {
944         return 1;
945     }
946     if (dx1 >= GX_LCD_SIZE_X || dx2 >= GX_LCD_SIZE_X || dy1 >= GX_LCD_SIZE_Y
947         || dy2 >= GX_LCD_SIZE_Y)
948     {
949         return 1;
950     }
951     if (dx1 == dx2 || dy1 == dy2 || raw_x1 == raw_x2 || raw_y1 == raw_y2)
952     {
953         return 1;
954     }
955 
956     rx_width = raw_x1 - raw_x2;
957     dx_width = dx1 - dx2;
958 
959     enabled = OS_DisableInterrupts();
960 
961     // Calculate xDotSize
962     CP_SetDiv32_32(((u32)rx_width) << TP_CALIBRATE_DOT_SCALE_SHIFT, (u32)dx_width);
963 
964     ry_width = raw_y1 - raw_y2;
965     dy_width = dy1 - dy2;
966 
967     tmp32 = CP_GetDivResult32();
968     CP_SetDiv32_32(((u32)ry_width) << TP_CALIBRATE_DOT_SCALE_SHIFT, (u32)dy_width);
969 
970     if (!IN_S16_RANGE(tmp32))
971     {
972         (void)OS_RestoreInterrupts(enabled);
973         return 1;
974     }
975     calibrate->xDotSize = (s16)tmp32;
976     tmp32 = (s16)((((s32)(raw_x1 + raw_x2) << TP_CALIBRATE_DOT_SCALE_SHIFT)
977                    - ((s32)(dx1 + dx2) * calibrate->xDotSize)) >> (TP_CALIBRATE_DOT_SCALE_SHIFT -
978                                                                    TP_CALIBRATE_ORIGIN_SCALE_SHIFT +
979                                                                    1));
980     if (!IN_S16_RANGE(tmp32))
981     {
982         (void)OS_RestoreInterrupts(enabled);
983         return 1;
984     }
985     calibrate->x0 = (s16)tmp32;
986 
987     tmp32 = CP_GetDivResult32();
988     (void)OS_RestoreInterrupts(enabled);
989 
990     if (!IN_S16_RANGE(tmp32))
991     {
992         return 1;
993     }
994     calibrate->yDotSize = (s16)tmp32;
995     tmp32 = (s16)((((s32)(raw_y1 + raw_y2) << TP_CALIBRATE_DOT_SCALE_SHIFT)
996                    - ((s32)(dy1 + dy2) * calibrate->yDotSize)) >> (TP_CALIBRATE_DOT_SCALE_SHIFT -
997                                                                    TP_CALIBRATE_ORIGIN_SCALE_SHIFT +
998                                                                    1));
999     if (!IN_S16_RANGE(tmp32))
1000     {
1001         return 1;
1002     }
1003     calibrate->y0 = (s16)tmp32;
1004 
1005     return 0;
1006 }
1007 
1008 
1009 /*---------------------------------------------------------------------------*
1010   Name:         TP_GetCalibratedPoint
1011 
1012   Description:  Convert a touch panel value to a screen coordinate
1013                 Touch Screen values will be output unchanged when calibration parameters have not been set.
1014                 It is OK to pass the same pointer to the disp and raw arguments.
1015 
1016 
1017   Arguments:    raw      - Pointer to the touch panel value that is the conversion source
1018 
1019   ReturnValue:  disp     - Pointer to the variable in which the value that has been converted to a screen coordinate was stored
1020  *---------------------------------------------------------------------------*/
TP_GetCalibratedPoint(TPData * disp,const TPData * raw)1021 void TP_GetCalibratedPoint(TPData *disp, const TPData *raw)
1022 {
1023     TPiCalibrateParam *cal;
1024 
1025     enum
1026     { MAX_X = GX_LCD_SIZE_X - 1, MAX_Y = GX_LCD_SIZE_Y - 1 };
1027 
1028     // ----------------------------------------
1029     // dx = (raw_x * x0) / xDotSize
1030     // dy = (raw_y * y0) / yDotSize
1031     // ----------------------------------------
1032 
1033     SDK_NULL_ASSERT(disp);
1034     SDK_NULL_ASSERT(raw);
1035     SDK_NULL_ASSERT(tpState.calibrate_flg);
1036 
1037     if (!tpState.calibrate_flg)
1038     {
1039         *disp = *raw;
1040         return;
1041     }
1042 
1043     cal = &tpState.calibrate;
1044 
1045     disp->touch = raw->touch;
1046     disp->validity = raw->validity;
1047 
1048     if (raw->touch == 0)
1049     {
1050         disp->x = 0;
1051         disp->y = 0;
1052         return;
1053     }
1054 
1055     // X coordinate conversion
1056     // disp->x = (x - x0) / xDotSize;
1057     disp->x =
1058         (u16)((((u64)(raw->x << TP_CALIBRATE_ORIGIN_SCALE_SHIFT) -
1059                 cal->x0) * cal->xDotSizeInv) >> (TP_CALIBRATE_DOT_INV_SCALE_SHIFT +
1060                                                  TP_CALIBRATE_ORIGIN_SCALE_SHIFT));
1061 
1062     if ((s16)disp->x < 0)
1063     {
1064         disp->x = 0;
1065     }
1066     else if ((s16)disp->x > MAX_X)
1067     {
1068         disp->x = MAX_X;
1069     }
1070     // Y coordinate conversion
1071     // disp->y = (y - y0) / yDotSize;
1072     disp->y =
1073         (u16)((((u64)(raw->y << TP_CALIBRATE_ORIGIN_SCALE_SHIFT) -
1074                 cal->y0) * cal->yDotSizeInv) >> (TP_CALIBRATE_DOT_INV_SCALE_SHIFT +
1075                                                  TP_CALIBRATE_ORIGIN_SCALE_SHIFT));
1076 
1077     if ((s16)disp->y < 0)
1078     {
1079         disp->y = 0;
1080     }
1081     else if ((s16)disp->y > MAX_Y)
1082     {
1083         disp->y = MAX_Y;
1084     }
1085 }
1086 
1087 /*---------------------------------------------------------------------------*
1088   Name:         TP_GetUnCalibratedPoint
1089 
1090   Description:  Gets the inverse transformation results of a calibration
1091                 Conversion from a screen coordinate to a touch panel value.
1092                 Screen coordinates will be output unchanged when calibration parameters have not been set.
1093 
1094 
1095   Arguments:    dx, dy       - Screen XY coordinates.
1096 
1097   ReturnValue:  raw_x, raw_y - Pointer for returning the corresponding touch panel value
1098  *---------------------------------------------------------------------------*/
TP_GetUnCalibratedPoint(u16 * raw_x,u16 * raw_y,u16 dx,u16 dy)1099 void TP_GetUnCalibratedPoint(u16 *raw_x, u16 *raw_y, u16 dx, u16 dy)
1100 {
1101     TPiCalibrateParam *cal;
1102 
1103     // ----------------------------------------
1104     // raw_x = dx * xDotSize + x0;
1105     // raw_y = dy * yDotSize + y0;
1106     // ----------------------------------------
1107 
1108     SDK_NULL_ASSERT(raw_x);
1109     SDK_NULL_ASSERT(raw_y);
1110     SDK_ASSERT(tpState.calibrate_flg);
1111 
1112     if (!tpState.calibrate_flg)
1113     {
1114         *raw_x = dx;
1115         *raw_y = dy;
1116         return;
1117     }
1118 
1119     cal = &tpState.calibrate;
1120 
1121     *raw_x =
1122         (u16)((((s32)(dx * cal->xDotSize) >> TP_CALIBRATE_DOT2ORIGIN_SCALE_SHIFT) +
1123                (s32)cal->x0) >> TP_CALIBRATE_ORIGIN_SCALE_SHIFT);
1124     *raw_y =
1125         (u16)((((s32)(dy * cal->yDotSize) >> TP_CALIBRATE_DOT2ORIGIN_SCALE_SHIFT) +
1126                (s32)cal->y0) >> TP_CALIBRATE_ORIGIN_SCALE_SHIFT);
1127 }
1128 
1129 
1130 /*---------------------------------------------------------------------------*
1131   Name:         TP_WaitBusy
1132 
1133   Description:  Waits until ARM7 completes a touch panel request
1134 
1135   Arguments:    command_flgs  - Type of request to the touch panel
1136 
1137   Returns:      None.
1138  *---------------------------------------------------------------------------*/
TP_WaitBusy(TPRequestCommandFlag command_flgs)1139 void TP_WaitBusy(TPRequestCommandFlag command_flgs)
1140 {
1141 #ifdef  SDK_DEBUG
1142     if (!(tpState.command_flg & command_flgs))
1143     {
1144         return;
1145     }
1146 #endif
1147     // Fall into an infinite loop if interrupts are OFF
1148     SDK_ASSERT(OS_GetCpsrIrq() == OS_INTRMODE_IRQ_ENABLE);
1149     SDK_ASSERT(reg_OS_IME == 1);
1150     SDK_ASSERT(OS_GetIrqMask() & OS_IE_SPFIFO_RECV);
1151 
1152     // Place ASSERT statements before starting the loop.
1153     // Calls to this function must be prohibited while interrupts are disabled.
1154     // This is due to the fact that some conditions may influence whether the tpState flag has already been cleared.
1155 
1156     while (tpState.command_flg & command_flgs)
1157     {
1158         // Do nothing
1159     }
1160 
1161     return;
1162 }
1163 
1164 /*---------------------------------------------------------------------------*
1165   Name:         TP_WaitAllBusy
1166 
1167   Description:  Waits until ARM7 completes all of the touch panel requests
1168 
1169   Arguments:    None.
1170 
1171   Returns:      None.
1172  *---------------------------------------------------------------------------*/
TP_WaitAllBusy(void)1173 void TP_WaitAllBusy(void)
1174 {
1175 #ifdef  SDK_DEBUG
1176     if (!tpState.command_flg)
1177     {
1178         return;
1179     }
1180 #endif
1181     // Fall into an infinite loop if interrupts are OFF
1182     SDK_ASSERT(OS_GetCpsrIrq() == OS_INTRMODE_IRQ_ENABLE);
1183     SDK_ASSERT(reg_OS_IME == 1);
1184     SDK_ASSERT(OS_GetIrqMask() & OS_IE_SPFIFO_RECV);
1185 
1186     while (tpState.command_flg)
1187     {
1188         // Do nothing
1189     }
1190 
1191     return;
1192 }
1193 
1194 
1195 /*---------------------------------------------------------------------------*
1196   Name:         TP_CheckBusy
1197 
1198   Description:  Checks whether or not touch panel requests to ARM7 are busy.
1199 
1200   Arguments:    command_flgs  - Type of request to the touch panel
1201 
1202   Returns:      u32          - Returns zero if it is not busy and a non-zero value otherwise.
1203 
1204  *---------------------------------------------------------------------------*/
TP_CheckBusy(TPRequestCommandFlag command_flgs)1205 u32 TP_CheckBusy(TPRequestCommandFlag command_flgs)
1206 {
1207     return (u32)(tpState.command_flg & command_flgs);
1208 }
1209 
1210 
1211 
1212 /*---------------------------------------------------------------------------*
1213   Name:         TP_CheckError
1214 
1215   Description:  Checks whether or not touch panel request to ARM7 terminated with an error.
1216 
1217   Arguments:    command_flgs  - Type of request to the touch panel
1218 
1219   Returns:      u32           - Returns zero if an error has not occurred and a non-zero value otherwise.
1220 
1221  *---------------------------------------------------------------------------*/
TP_CheckError(TPRequestCommandFlag command_flgs)1222 u32 TP_CheckError(TPRequestCommandFlag command_flgs)
1223 {
1224     return (u32)(tpState.err_flg & command_flgs);
1225 }
1226