1 /********************* (C) COPYRIGHT 2007 RAISONANCE S.A.S. *******************/
5 * @brief Various utilities for the pointer management for STM32-primer.
10 * @version 1.5 various corrections reported by Ron Miller to suppress jittery
14 /******************************************************************************/
16 /* Includes ------------------------------------------------------------------*/
21 /* Private define ------------------------------------------------------------*/
23 #define POS_MAX (SCREEN_WIDTH - POINTER_WIDTH - 1)
24 #define POINTER_DIVIDER 50
25 #define POINTER_DEFAULT_COLOR RGB_BLUE
27 // defines for pointer move
28 #define ANGLEPAUSE 500
29 #define DEFAULT_ANGLESTART 25
30 #define MIN_ANGLE_FOR_SHIFT_UP (ANGLEPAUSE+CurrentAngleStart)
31 #define MIN_ANGLE_FOR_SHIFT_DOWN (ANGLEPAUSE-CurrentAngleStart)
32 #define MIN_ANGLE_FOR_SHIFT_RIGHT (signed)(0+CurrentAngleStart)
33 #define MIN_ANGLE_FOR_SHIFT_LEFT (signed)(0-CurrentAngleStart)
34 #define DEFAULT_SPEED_ON_ANGLE 60
36 /* Private variables ---------------------------------------------------------*/
37 static int divider = 0;
39 unsigned char BallPointerBmp[ POINTER_WIDTH ] = { 0x38, 0x7C, 0xFF, 0xFF, 0xFF, 0x7C, 0x38 } ;
40 unsigned char locbuf[ POINTER_WIDTH ];
41 unsigned char DefaultAreaStore[ 2 * POINTER_WIDTH * POINTER_WIDTH ];
43 // Variables for pointer.
44 u8* CurrentPointerBmp = 0;
45 u8 CurrentPointerWidth = 0;
46 u8 CurrentPointerHeight = 0;
47 u16 CurrentSpeedOnAngle = DEFAULT_SPEED_ON_ANGLE;
48 u32 CurrentAngleStart = DEFAULT_ANGLESTART ;
49 unsigned char* ptrAreaStore = DefaultAreaStore;
50 u16 CurrentPointerColor = POINTER_DEFAULT_COLOR;
51 enum POINTER_mode Pointer_Mode = POINTER_UNDEF;
52 enum POINTER_state Pointer_State = POINTER_S_UNDEF;
57 // Init pointer Info Structure (structure definition in circle.h)
58 tPointer_Info POINTER_Info = {
59 SCREEN_WIDTH - POINTER_WIDTH / 2,
60 SCREEN_WIDTH - POINTER_WIDTH / 2,
64 /* Private function prototypes -----------------------------------------------*/
65 static int POINTER_Move ( void );
67 /* Private functions ---------------------------------------------------------*/
69 /*******************************************************************************
73 *******************************************************************************/
75 * Moves LCD pointer according to Mems indications.
77 * @retval 0 The pointer resides in the screen
78 * @retval -1 The pointer touche the screen edges.
81 /******************************************************************************/
82 static int POINTER_Move( void )
85 s16 oldPointer_xPos = POINTER_Info.xPos;
86 s16 oldPointer_yPos = POINTER_Info.yPos;
87 s16 unmodied_shift_PosX;
88 s16 unmodied_shift_PosY;
89 signed outx = MEMS_Info.OutX_F16 >> 4;
90 signed outy = MEMS_Info.OutY_F16 >> 4;
92 POINTER_Info.shift_PosX = POINTER_Info.shift_PosY = 0;
94 // The move depends on the screen orientation
95 switch( LCD_GetScreenOrientation() )
99 MEMS_Info.RELATIVE_X = outx;
100 MEMS_Info.RELATIVE_Y = outy;
102 if( outx > MIN_ANGLE_FOR_SHIFT_RIGHT )
104 POINTER_Info.shift_PosX = ( outx - MIN_ANGLE_FOR_SHIFT_RIGHT );
106 else if( outx < MIN_ANGLE_FOR_SHIFT_LEFT )
108 POINTER_Info.shift_PosX = ( outx - MIN_ANGLE_FOR_SHIFT_LEFT );
111 if( outy < -MIN_ANGLE_FOR_SHIFT_UP )
113 POINTER_Info.shift_PosY = ( outy + MIN_ANGLE_FOR_SHIFT_UP );
115 else if( outy > -MIN_ANGLE_FOR_SHIFT_DOWN )
117 POINTER_Info.shift_PosY = ( outy + MIN_ANGLE_FOR_SHIFT_DOWN );
123 MEMS_Info.RELATIVE_X = -( outy );
124 MEMS_Info.RELATIVE_Y = outx;
126 if( outy > MIN_ANGLE_FOR_SHIFT_RIGHT )
128 POINTER_Info.shift_PosX = -( outy - MIN_ANGLE_FOR_SHIFT_RIGHT );
130 else if( outy < MIN_ANGLE_FOR_SHIFT_LEFT )
132 POINTER_Info.shift_PosX = -( outy - MIN_ANGLE_FOR_SHIFT_LEFT );
135 if( outx < -MIN_ANGLE_FOR_SHIFT_UP )
137 POINTER_Info.shift_PosY = ( outx + MIN_ANGLE_FOR_SHIFT_UP );
139 else if( outx > -MIN_ANGLE_FOR_SHIFT_DOWN )
141 POINTER_Info.shift_PosY = ( outx + MIN_ANGLE_FOR_SHIFT_DOWN );
147 MEMS_Info.RELATIVE_X = -( outx );
148 MEMS_Info.RELATIVE_Y = -( outy );
150 if( outx > MIN_ANGLE_FOR_SHIFT_RIGHT )
152 POINTER_Info.shift_PosX = ( MIN_ANGLE_FOR_SHIFT_RIGHT - outx );
154 else if( outx < MIN_ANGLE_FOR_SHIFT_LEFT )
156 POINTER_Info.shift_PosX = ( MIN_ANGLE_FOR_SHIFT_LEFT - outx );
159 if( outy > MIN_ANGLE_FOR_SHIFT_UP )
161 POINTER_Info.shift_PosY = -( outy - MIN_ANGLE_FOR_SHIFT_UP );
163 else if( outy < MIN_ANGLE_FOR_SHIFT_DOWN )
165 POINTER_Info.shift_PosY = +( MIN_ANGLE_FOR_SHIFT_DOWN - outy );
171 MEMS_Info.RELATIVE_X = outy;
172 MEMS_Info.RELATIVE_Y = -( outx );
174 if( outy > MIN_ANGLE_FOR_SHIFT_RIGHT )
176 POINTER_Info.shift_PosX = ( outy - MIN_ANGLE_FOR_SHIFT_RIGHT );
178 else if( outy < MIN_ANGLE_FOR_SHIFT_LEFT )
180 POINTER_Info.shift_PosX = ( outy - MIN_ANGLE_FOR_SHIFT_LEFT );
183 if( outx > MIN_ANGLE_FOR_SHIFT_UP )
185 POINTER_Info.shift_PosY = ( MIN_ANGLE_FOR_SHIFT_UP - outx);
187 else if( outx < MIN_ANGLE_FOR_SHIFT_DOWN )
189 POINTER_Info.shift_PosY = ( MIN_ANGLE_FOR_SHIFT_DOWN - outx );
196 unmodied_shift_PosX = POINTER_Info.shift_PosX;
197 unmodied_shift_PosY = POINTER_Info.shift_PosY;
199 POINTER_Info.shift_PosX /= CurrentSpeedOnAngle;
200 POINTER_Info.shift_PosY /= CurrentSpeedOnAngle;
202 if( Pointer_Mode == POINTER_APPLICATION )
204 if ( Application_Pointer_Mgr )
206 Application_Pointer_Mgr( POINTER_Info.shift_PosX, POINTER_Info.shift_PosY );
212 POINTER_Info.xPos += POINTER_Info.shift_PosX;
213 POINTER_Info.yPos += POINTER_Info.shift_PosY;
215 if( POINTER_Info.xPos < POINTER_Info.X_PosMin )
217 POINTER_Info.xPos = POINTER_Info.X_PosMin;
220 if( POINTER_Info.xPos > POINTER_Info.X_PosMax )
222 POINTER_Info.xPos = POINTER_Info.X_PosMax;
225 if( POINTER_Info.yPos < POINTER_Info.Y_PosMin )
227 POINTER_Info.yPos = POINTER_Info.Y_PosMin;
230 if( POINTER_Info.yPos > POINTER_Info.Y_PosMax )
232 POINTER_Info.yPos = POINTER_Info.Y_PosMax;
235 if( ( Pointer_Mode != POINTER_MENU ) && ( Pointer_Mode != POINTER_RESTORE_LESS ) &&
236 ( ( oldPointer_xPos != POINTER_Info.xPos ) || ( oldPointer_yPos != POINTER_Info.yPos ) ) )
239 POINTER_SetCurrentAreaStore( 0 );
241 // Restore previously drawn area.
242 POINTER_Restore( oldPointer_xPos, oldPointer_yPos, POINTER_WIDTH, POINTER_WIDTH );
244 // Save new area and draw pointer
245 POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
246 POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH, CurrentPointerBmp );
249 if( ( Pointer_Mode == POINTER_RESTORE_LESS ) &&
250 ( ( oldPointer_xPos != POINTER_Info.xPos ) || ( oldPointer_yPos != POINTER_Info.yPos ) ) )
253 POINTER_SetCurrentAreaStore( 0 );
255 // Restore previously drawn area.
256 POINTER_Restore( oldPointer_xPos, oldPointer_yPos, CurrentPointerWidth, CurrentPointerHeight );
258 // Save new area and draw pointer
259 POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight );
260 POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
263 // Is the pointer touching one edge of the screen ?
264 if( ( POINTER_Info.xPos == POS_MIN ) || ( POINTER_Info.yPos == POS_MIN ) ||
265 ( POINTER_Info.xPos == POS_MAX ) || ( POINTER_Info.yPos == POS_MAX ) )
273 /* Public functions for CircleOS ---------------------------------------------*/
275 /*******************************************************************************
279 *******************************************************************************/
281 * Initialize pointer. Called at CircleOS startup. Set default pointer at the
282 * middle of the screen and allows it to move into the whole screen.
284 * @attention This function must <b>NOT</b> be called by the user.
287 /******************************************************************************/
288 void POINTER_Init( void )
290 // Increase pointer sensibility.
291 POINTER_SetCurrentSpeedOnAngle( DEFAULT_SPEED_ON_ANGLE );
292 POINTER_SetCurrentAngleStart( DEFAULT_ANGLESTART );
293 POINTER_SetCurrentPointer( POINTER_WIDTH, POINTER_WIDTH, BallPointerBmp );
294 POINTER_SetMode( POINTER_ON );
295 POINTER_SetPos( 56, 56 );
296 POINTER_SetRectScreen();
298 CurrentPointerColor = POINTER_DEFAULT_COLOR;
301 /*******************************************************************************
305 *******************************************************************************/
308 * Called by the CircleOS scheduler to manage the pointer.
310 * @attention This function must <b>NOT</b> be called by the user.
313 /******************************************************************************/
314 void POINTER_Handler( void )
316 switch( Pointer_Mode )
324 // Where is the MEMS ?
325 MEMS_GetPosition( &OUT_X, &OUT_Y );
332 /* Public functions ----------------------------------------------------------*/
334 /*******************************************************************************
336 * POINTER_SetCurrentPointer
338 *******************************************************************************/
341 * Set the dimension and the bitmap of the pointer.
342 * @note The bitmap is a monochrome one!
344 * @param[in] width width of the pointer (u8)
345 * @param[in] height height of the pointer (u8)
346 * @param[in] bmp pointer to an array of width * height bits.
349 /********************************************************************************/
350 void POINTER_SetCurrentPointer( u8 width, u8 height, u8* bmp )
354 bmp = BallPointerBmp;
357 CurrentPointerWidth = width;
358 CurrentPointerHeight = height;
359 CurrentPointerBmp = bmp;
362 /*******************************************************************************
364 * POINTER_GetCurrentAngleStart
366 *******************************************************************************/
369 * Get the current minimal angle to move pointer
371 * @return current minimal angle.
374 /******************************************************************************/
375 u16 POINTER_GetCurrentAngleStart( void )
377 return CurrentAngleStart;
380 /*******************************************************************************
382 * POINTER_SetCurrentAngleStart
384 *******************************************************************************/
387 * Set the current minimal angle to move pointer
389 * @param[in] newangle The new minimal angle to move pointer.
392 /******************************************************************************/
393 void POINTER_SetCurrentAngleStart( u16 newangle )
395 CurrentAngleStart = newangle;
398 /*******************************************************************************
400 * POINTER_GetCurrentSpeedOnAngle
402 *******************************************************************************/
405 * Return the current speed/angle ratio.
407 * @return current ratio.
410 /******************************************************************************/
411 u16 POINTER_GetCurrentSpeedOnAngle( void )
413 return CurrentSpeedOnAngle;
416 /*******************************************************************************
418 * POINTER_SetCurrentSpeedOnAngle
420 *******************************************************************************/
423 * Set the current speed/angle ratio.
425 * @param[in] newspeed New speed/angle ratio.
428 /******************************************************************************/
429 void POINTER_SetCurrentSpeedOnAngle( u16 newspeed )
431 CurrentSpeedOnAngle = newspeed;
434 /*******************************************************************************
436 * POINTER_SetCurrentAreaStore
438 *******************************************************************************/
441 * Change the current storage area. If the provided value is NULL, the default
442 * storage area will be used.
444 * @param[in] ptr New storage area (may be null).
446 * @warning Memory space pointed by the provided pointer must be large enough
447 * to store a color bitmap corresponding to the pointer area.
448 * In other words, space must be width * height * 2 large.
451 /******************************************************************************/
452 void POINTER_SetCurrentAreaStore( u8* ptr )
454 ptrAreaStore = ( ptr == 0 ) ? DefaultAreaStore : ptr;
457 /*******************************************************************************
461 *******************************************************************************/
464 * Change the current mode of the pointer management.
466 * @note Must be called only ONCE!!
468 * @param[in] mode New pointer management mode.
471 /******************************************************************************/
472 void POINTER_SetMode( enum POINTER_mode mode )
480 case POINTER_APPLICATION:
481 ptr = (u16*)DefaultAreaStore;
482 color = DRAW_GetBGndColor();
484 for ( i = 0; i < (CurrentPointerWidth*CurrentPointerHeight) ; i++ )
489 POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
492 case POINTER_RESTORE_LESS:
493 POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight, CurrentPointerBmp );
497 POINTER_SetCurrentAreaStore( 0 );
498 POINTER_Save( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
499 POINTER_Draw( POINTER_Info.xPos, POINTER_Info.yPos, CurrentPointerWidth, CurrentPointerHeight,CurrentPointerBmp );
503 POINTER_Info.xPos = ( SCREEN_WIDTH - POINTER_WIDTH ) / 2;
504 POINTER_Info.yPos = ( SCREEN_WIDTH - POINTER_WIDTH ) / 2;
507 if( Pointer_Mode == POINTER_ON )
509 POINTER_SetCurrentAreaStore( 0 );
510 POINTER_Restore( POINTER_Info.xPos, POINTER_Info.yPos, POINTER_WIDTH, POINTER_WIDTH );
518 /*******************************************************************************
522 *******************************************************************************/
525 * Return the current mode of the pointer management
527 * @return Current pointer management mode.
530 /******************************************************************************/
531 enum POINTER_mode POINTER_GetMode( void )
536 /*******************************************************************************
540 *******************************************************************************/
543 * Return current pointer state.
545 * @return Current pointer state.
548 /******************************************************************************/
549 enum POINTER_state POINTER_GetState( void )
551 return Pointer_State;
554 /*******************************************************************************
558 *******************************************************************************/
561 * Set new limits for the move of the pointer
563 * @param[in] x Horizontal coordinate of the bottom left corner of the new area.
564 * @param[in] y Vertical coordinate of the bottom left corner of the new are.
565 * @param[in] width New area width.
566 * @param[in] height New area height.
568 * @warning The (0x0) point in on the low left corner.
571 /******************************************************************************/
572 void POINTER_SetRect( s16 x, s16 y, s16 width, s16 height )
574 POINTER_Info.X_PosMin = x;
576 if( POINTER_Info.xPos < POINTER_Info.X_PosMin )
578 POINTER_Info.xPos = POINTER_Info.X_PosMin;
581 POINTER_Info.X_PosMax = x + width - 1;
583 if( POINTER_Info.xPos > POINTER_Info.X_PosMax )
585 POINTER_Info.xPos = POINTER_Info.X_PosMax;
588 POINTER_Info.Y_PosMin = y;
590 if( POINTER_Info.yPos < POINTER_Info.Y_PosMin )
592 POINTER_Info.yPos = POINTER_Info.Y_PosMin;
595 POINTER_Info.Y_PosMax = y + height - 1;
597 if( POINTER_Info.yPos > POINTER_Info.Y_PosMax )
599 POINTER_Info.yPos = POINTER_Info.Y_PosMax;
603 /*******************************************************************************
605 * POINTER_SetRectScreen
607 *******************************************************************************/
610 * Allow the pointer to move on the whole screen.
613 /******************************************************************************/
614 void POINTER_SetRectScreen( void )
616 POINTER_SetRect( 0, 0, POS_MAX, POS_MAX );
619 /*******************************************************************************
623 *******************************************************************************/
626 * Return the current position of the pointer (on the screen).
628 * @return The current pointer screen position with X in the LSB and Y in the MSB.
630 * @warning The (0x0) point in on the low left corner.
632 /******************************************************************************/
633 u16 POINTER_GetPos( void )
635 return ( POINTER_Info.xPos | ( POINTER_Info.yPos << 8 ) );
638 /*******************************************************************************
642 *******************************************************************************/
645 * Force the screen position of the pointer.
647 * @param[in] x New horizontal coordinate.
648 * @param[in] y New vertical coordinate.
650 * @warning The (0x0) point in on the low left corner.
653 /******************************************************************************/
654 void POINTER_SetPos( u16 x, u16 y )
656 POINTER_Info.xPos = x;
657 POINTER_Info.yPos = y;
660 /*******************************************************************************
664 *******************************************************************************/
669 * @param[in] x Horizontal coordinate of the bottom left corner of the pointer.
670 * @param[in] y Vertical coordinate of the bottom left corner of the pointer.
671 * @param[in] width Pointer bitmap width.
672 * @param[in] height Pointer bitmap height.
673 * @param[in] bmp Pointer to width * height bit array. If null used default
676 * @note The provided bitmap is a monochrome one.
677 * @warning The (0x0) point in on the low left corner.
680 /******************************************************************************/
681 void POINTER_Draw( u8 x, u8 y, u8 width, u8 height, u8* bmp )
686 char* ptr = ptrAreaStore;
690 // No bitmap provided, use the default one!
693 bmp = BallPointerBmp;
696 // Select the screen area were going to take care about!
697 LCD_SetRect_For_Cmd( x, y, width, height );
699 // Let draw to the LCD screen.
700 LCD_SendLCDCmd( ST7637_RAMWR );
702 while( n < ( width * height ) )
704 if( Pointer_Mode != POINTER_RESTORE_LESS )
706 // Draw pixel using current storage area data for background pixels.
708 LCD_SendLCDData( ( bmp[ l + ( i / 8 ) ] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? ( POINTER_GetColor() & 255 ) : c );
711 LCD_SendLCDData( ( bmp[ l + ( i / 8 ) ] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? ( POINTER_GetColor() >> 8 ) : c );
715 // POINTER_RESTORE_LESS: use current background color for background color.
716 c = DRAW_GetBGndColor();
717 val = ( bmp[ l + ( i / 8 ) ] & ( 1 << ( 7 - ( i % 8 ) ) ) ) ? POINTER_GetColor() : c;
719 LCD_SendLCDData( val & 255 );
720 LCD_SendLCDData( val >> 8 );
737 /*******************************************************************************
741 *******************************************************************************/
744 * Save the background of the pointer.
746 * @param[in] x Horizontal coordinate of the bottom left corner of the area to save.
747 * @param[in] y Vertical coordinate of the bottom left corner of the area to save.
748 * @param[in] width Width of the area to save.
749 * @param[in] height Height of the area to save.
751 * @note The store area must be large enough to store all the pixels (16 bits).
752 * @warning The (0x0) point in on the low left corner.
753 * @see POINTER_Restore
754 * @see POINTER_SetCurrentAreaStore
757 /******************************************************************************/
758 void POINTER_Save( u8 x, u8 y, u8 width, u8 height )
761 char* ptr = ptrAreaStore;
762 int bytesize = ( width * height ) * 2; // 2 bytes per pixel.
764 // Is this pointer management mode, don't save pointer background!
765 if( Pointer_Mode == POINTER_RESTORE_LESS )
770 // Select the LCD screen area to read.
771 LCD_SetRect_For_Cmd ( x, y, width, height );
773 // Send the memory read command to the LCD controller.
774 LCD_SendLCDCmd( ST7637_RAMRD );
776 // First returned byte is a dummy!
779 for( i = 0; i < bytesize; i++ )
781 *ptr++ = LCD_ReadLCDData();
785 /*******************************************************************************
789 *******************************************************************************/
792 * Restore the background of the pointer with data saved in the current store area.
794 * @param[in] x Horizontal coordinate of the bottom left corner of the area to restore.
795 * @param[in] y Vertical coordinate of the bottom left corner of the area to restore.
796 * @param[in] width Width of the area to restore.
797 * @param[in] height Height of the area to restore.
799 * @warning The (0x0) point in on the low left corner.
801 * @see POINTER_SetCurrentAreaStore
804 /******************************************************************************/
805 void POINTER_Restore( u8 x, u8 y, u8 width, u8 height )
808 char* ptr = ptrAreaStore;
809 int bytesize = ( width * height ) * 2; // 2 bytes per pixel.
811 // Select the screen area to write.
812 LCD_SetRect_For_Cmd( x, y, width, height );
814 // Send the memory write command to the LCD controller.
815 LCD_SendLCDCmd( ST7637_RAMWR );
817 for( i = 0; i < bytesize; i++ )
819 // In this mode, use background color (no data was previously saved).
820 if ( Pointer_Mode == POINTER_RESTORE_LESS )
822 LCD_SendLCDData( DRAW_GetBGndColor() );
826 LCD_SendLCDData( *ptr++ );
831 /*******************************************************************************
833 * POINTER_SetApplication_Pointer_Mgr
835 *******************************************************************************/
838 * Provides an user defined pointer manager.
840 * @param[in] mgr Pointer to the user defined pointer manager.
843 /******************************************************************************/
844 void POINTER_SetApplication_Pointer_Mgr( tAppPtrMgr mgr )
846 Application_Pointer_Mgr = mgr;
849 /*******************************************************************************
853 *******************************************************************************/
856 * Set the pointer color.
858 * @param[in] color The new pointer color.
861 /******************************************************************************/
862 void POINTER_SetColor( u16 color )
864 CurrentPointerColor = color;
867 /*******************************************************************************
871 *******************************************************************************/
874 * Return the current pointer color.
876 * @return Current pointer color.
879 /******************************************************************************/
880 u16 POINTER_GetColor( void )
882 return CurrentPointerColor;
885 /*******************************************************************************
889 *******************************************************************************/
892 * Get pointer informations.
894 * @return A pointer to a pointer information structure.
897 /******************************************************************************/
898 tPointer_Info* POINTER_GetInfo( void )
900 return &POINTER_Info;