Analog touch screen WM event

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Analog touch screen WM event

    I imlemnted the hardwar routins for the analog touch scrren as described in the manual (24.4 Touch screen driver), and it was easy and fun, saved me a lot of work and time.
    These are working:

    GUI_TOUCH_X_ActivateX(), GUI_TOUCH_X_ActivateY()
    GUI_TOUCH_X_MeasureX(), GUI_TOUCH_X_MeasureY()
    A call to GUI_TOUCH_Exec() is in a saparate thread (freeRTOS).
    GUI_TOUCH_Calibrate() is called at initialization.


    So I get this working just fine ( in the GUI_Task):
    //---------

    GUI_PID_GetState(&pState);
    MULTIEDIT_SetText(hItem ,"");
    MULTIEDIT_AddText(hItem,"X = ");
    MULTIEDIT_AddText(hItem,int2str(pState.x,0));
    MULTIEDIT_AddText(hItem,"\nY = ");
    MULTIEDIT_AddText(hItem,int2str(pState.y,0));
    if(pState.Pressed == 1)
    MULTIEDIT_AddText(hItem,"\nPressed");
    else
    MULTIEDIT_AddText(hItem,"\nNOTPressed");
    //-----------------

    It displays the correct X,Y and state.


    Whoever, no events are generated for the WM callback: static void _cbDialog(WM_MESSAGE * pMsg) ,

    What am I missing?

    Thanks
    Johanan
  • I found
    WM_HANDLE_PID() in WM.h, I added a call to it:

    Source Code

    1. GUI_TOUCH_Exec();
    2. WM_HandlePID();


    Still no msg is sent
    :(

    Is there a more detailed reference for function that are not documented in the user manual?
    I searched many sample code, can't find what is missing in my code
    Johanan

  • Hello Johanan,

    Please note the descriptions of the function GUI_PID_GetState() and GUI_PID_GetCurrentState() in the emWin user manual. GUI_PID_GetState() performs a destructive read on the PID FIFO. This way all PID states you fetch will not be processed again by the Window Manager.

    Best regards,
    Adrian
  • Thanks,
    I changed GUI_PID_GetState to GUI_PID_GetCurrentState, but still no WM event is fired.
    Do I have to add something after GUI_TOUCH_EXEC()? (like store touch state?)
    //---------------------


    if (_xpos > 4000 || _xpos < 300 ) _xpos = 0;
    if (_ypos > 4000 || _ypos < 300 ) _ypos = 0;

    xpos = _xpos ; //med_filter_avr(_xpos,0);
    ypos = _ypos ; //med_filter_avr(_ypos,1);

    if(calibrated)
    {
    GUI_TOUCH_Exec();
    // Need to fire WM msg here ???
    }

    .
    ..

    int GUI_TOUCH_X_MeasureX (void) {
    return xpos;
    }
    int GUI_TOUCH_X_MeasureY (void) {
    return ypos;
    }


    Johanan
  • Adrian,
    Thanks for this hint, but as it still not working, I am missing something.
    I assume that when I touch a window (widget) it then will get the focus, so how does it work??
    If I touch the main window, will it not have the input focus by default?
    (As before - the PID_State gets the correct values but no msg is sent to WM, also I now show the cursor - it does not move to the touch point )
    Your help is appreciated.
    Thanks
    Johanan
  • Hello Johanan,

    Please note that the widget type determines the ability to get the input focus. If your window is not able to get the focus, you may want to overwrite its callback function in order to enable focussability. For detailed information on how to do this, please refer to the chapter "The Window Manager (WM)" in the emWin user manual.

    Best regards,
    Adrian
  • I have been digging into this for a very long time ( I think now it is the 7th day, only on this issue, which should have been rather simple), here is what I found.
    I fount that there is a system call WM_Handel_PID() which I think is not working OK. This function is called by a global function pointer WM-pfHandlePID.

    I verified that the pointer is pointing to the original function. (they are the same int value)
    Now i decided to write my on PID handler and test if it sends messages to the windows.
    I set the handler point to to my handler, this way:


    C Source Code

    1. int MY_WM_HandlePID(void);
    2. void touchScreen_Task(const void * param){
    3. // get xpos and ypos
    4. .
    5. .
    6. GUI_TOUCH_StoreState(xpos,ypos);
    7. WM_pfHandlePID = MY_WM_HandlePID; // set handler to my function
    8. }
    9. int MY_WM_HandlePID(void) {
    10. WM_MESSAGE Msg;
    11. WM_HWIN underXY;
    12. GUI_PID_STATE state, oldState;
    13. GUI_PID_GetState(&state);
    14. underXY = WM_Screen2hWin(state.x,state.y);
    15. if( state.x != oldState.x || state.y != state.y )
    16. {
    17. oldState .x = state .x;
    18. oldState .y = state.y;
    19. Msg.MsgId = WM_PID_STATE_CHANGED;
    20. WM__SendMessage(underXY, &Msg); // now WM gets this msg !!!
    21. return 1;
    22. }
    23. return 0;
    24. }
    Display All


    I wrote this just as a test, but this is working and sending that msg to the window.
    So I am pretty sure that original WM_HandlePID is not functioning correctly for some reason.

    I am using STmicroelectronics lib:
    STemWIn524b_CM4_OS_keil.lib

    without sources, it is very hard to debug.

    So what could be the problem? is it possible that some issue with this lib file?
    Is it possible to get the function WM_HandlePID() source code so I can put some breakpoints in it and figure out what is wrong?
    (Well I guess no, but its worth asking)

    Is the way I set that function pointer safe?

    Thanks
    Johanan

    The post was edited 1 time, last by johanan ().

  • Hello Johanan,

    I am afraid we can not provide you with the source code. If you prefer to work with emWin source code, we can offer you an upgrade contract. For details about that, please contact info@segger.com.

    Anyhow if there would be a problem in such an important Window Manager related function, we would have a lot of support requests from our customers. In fact we do not, so I would recommend searching the origin of the problem in your implementation. Please understand that you do not have a support request, so I can not support you that much, but here are some hints:

    Please check the following:
    - Is the touch task called regularly?
    - Does ist always call a ...StoreState() function?
    - Does the touch task recognize the touch has been released?
    - When the touch screen is pressed, is there a focussed window, so it can process the user input?
    - Parent windows are usually informed of touch events. Is this true in your application? Creating a custom callback function might be required to implement in order to be able to check that.
    - Is there a possibility your custom callback functions swallow events? Check switch/case statements to call the internal callback function (WM_DefaultProc() or <WIDGET>_Callback()) in all cases your application does not already handle properly.

    For detailed information about the Window Manager and touch events, please refer to the chapters in the emWin user manual.

    Best regards,
    Adrian
  • Hello Adrian,
    Well, I had other priorities, but came back to this issue now, and I have to solve it.
    I reduced the code to the minimum:
    I defined the 4 functions exactly as in the manual:

    Source Code

    1. // touch screen GUI functions
    2. //Prepares measurement for Y-axis.
    3. void GUI_TOUCH_X_ActivateX(void){...}
    4. //Prepares measurement for X-axis.
    5. void GUI_TOUCH_X_ActivateY(void){...}
    6. int GUI_TOUCH_X_MeasureX(void) {... }
    7. int GUI_TOUCH_X_MeasureY(void) {...}



    Then the Wm callback function is reduced to just one slider, made by the GUIBuilder, with no changes to the code.

    The touch screen task is now just this loop (an OS task, with 10 ms delay, runs 100 times/sec)

    Source Code

    1. while(1){
    2. GUI_TOUCH_Exec();
    3. // with the next line using my function - all is working (I can slide the slider), without, it, I get no events
    4. WM_pfHandlePID = MY_WM_HandlePID ;
    5. osDelay(10);
    6. }



    From the above code, it is clear that all the TS functions are working OK (since it works with my handler), whoever, the original function that is assigned to the pointer pfHandlePID does not trigger any events.
    I have no idea why is that. I can only hope that my handler is doing a good job and that this approach is safe.
    Maybe I should put it all in a critical code section, as I don't know where and when this function pointer is updated.

    Will be happy to have your comments,
    Regards
    Johanan
  • Hello Johanan,

    Of course I would recommend using the internal function to handle PID events. Please note that identifiers which are not described in the emWin user manual should never be subject to change. WM_pfHandlePID is not described in the user manual.

    I see in your first post that your callback function is called _cbDialog(). Please note that a dialog consists of a dialog window and a client window. You can set a callback function for both. The function GUI_CreateDialogBox() can be used to set a callback function for the client window. The function WM_SetCallback() can be used to set a callback function for the dialog window.

    Best regards,
    Adrian
  • Hi Adrian,
    Of course I prefer to use only documented features. As I said, I reduced the code to the bare minimum in order to catch what am I doing wrong.
    As a last request I wonder if you can take a look maybe something is missing in my init code. here is the GUI Task, with some initialization and then the while(1) loop:


    Source Code

    1. void GUI_Task(void const * argument) {
    2. BaseType_t q = pdFAIL;
    3. WM_HWIN mainWin;
    4. WM_HWIN hItem;
    5. char * qMsg = NULL;
    6. GUI_PID_STATE pState;
    7. GUI_Init();
    8. WM_MULTIBUF_Enable(1);
    9. GUI_SelectLayer(1);
    10. GUI_CURSOR_Show();
    11. GUI_SetBkColor(GUI_BLACK);
    12. WM_SetCreateFlags(WM_CF_MEMDEV);
    13. WM_EnableMemdev(WM_HBKWIN);
    14. mainWin = CreateWindow();
    15. while(1)
    16. {
    17. GUI_PID_GetCurrentState(&pState);
    18. GUI_CURSOR_SetPosition (pState.x,pState.y);
    19. GUI_Delay (20);
    20. }
    21. }
    Display All


    the actual screen is made by the GUI builder, I did not touch the code:

    C Source Code

    1. /*********************************************************************
    2. * *
    3. * SEGGER Microcontroller GmbH & Co. KG *
    4. * Solutions for real time microcontroller applications *
    5. * *
    6. **********************************************************************
    7. * *
    8. * C-file generated by: *
    9. * *
    10. * GUI_Builder for emWin version 5.22 *
    11. * Compiled Jul 4 2013, 15:16:01 *
    12. * (c) 2013 Segger Microcontroller GmbH & Co. KG *
    13. * *
    14. **********************************************************************
    15. * *
    16. * Internet: www.segger.com Support: support@segger.com *
    17. * *
    18. **********************************************************************
    19. */
    20. // USER START (Optionally insert additional includes)
    21. // USER END
    22. #include "DIALOG.h"
    23. /*********************************************************************
    24. *
    25. * Defines
    26. *
    27. **********************************************************************
    28. */
    29. #define ID_WINDOW_0 (GUI_ID_USER + 0x02)
    30. #define ID_TEXT_0 (GUI_ID_USER + 0x03)
    31. #define ID_SLIDER_0 (GUI_ID_USER + 0x04)
    32. #define ID_MULTIEDIT_0 (GUI_ID_USER + 0x05)
    33. #define ID_PROGBAR_0 (GUI_ID_USER + 0x06)
    34. #define ID_EDIT_0 (GUI_ID_USER + 0x07)
    35. // USER START (Optionally insert additional defines)
    36. // USER END
    37. /*********************************************************************
    38. *
    39. * Static data
    40. *
    41. **********************************************************************
    42. */
    43. // USER START (Optionally insert additional static data)
    44. // USER END
    45. /*********************************************************************
    46. *
    47. * _aDialogCreate
    48. */
    49. static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
    50. { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 800, 480, 0, 0x0, 0 },
    51. { TEXT_CreateIndirect, "Text", ID_TEXT_0, 489, 348, 80, 20, 0, 0x0, 0 },
    52. { SLIDER_CreateIndirect, "Slider", ID_SLIDER_0, 23, 76, 737, 20, 0, 0x0, 0 },
    53. { MULTIEDIT_CreateIndirect, "Multiedit", ID_MULTIEDIT_0, 60, 117, 380, 298, 0, 0x0, 0 },
    54. { PROGBAR_CreateIndirect, "Progbar", ID_PROGBAR_0, 28, 43, 730, 20, 0, 0x0, 0 },
    55. { EDIT_CreateIndirect, "Edit", ID_EDIT_0, 620, 117, 136, 20, 0, 0x64, 0 },
    56. // USER START (Optionally insert additional widgets)
    57. // USER END
    58. };
    59. /*********************************************************************
    60. *
    61. * Static code
    62. *
    63. **********************************************************************
    64. */
    65. // USER START (Optionally insert additional static code)
    66. // USER END
    67. /*********************************************************************
    68. *
    69. * _cbDialog
    70. */
    71. static void _cbDialog(WM_MESSAGE * pMsg) {
    72. WM_HWIN hItem;
    73. int NCode;
    74. int Id;
    75. // USER START (Optionally insert additional variables)
    76. // USER END
    77. switch (pMsg->MsgId) {
    78. case WM_INIT_DIALOG:
    79. //
    80. // Initialization of 'Window'
    81. //
    82. hItem = pMsg->hWin;
    83. WINDOW_SetBkColor(hItem, 0x0080FF00);
    84. //
    85. // Initialization of 'Multiedit'
    86. //
    87. hItem = WM_GetDialogItem(pMsg->hWin, ID_MULTIEDIT_0);
    88. MULTIEDIT_SetText(hItem, "Multiedit");
    89. //
    90. // Initialization of 'Edit'
    91. //
    92. hItem = WM_GetDialogItem(pMsg->hWin, ID_EDIT_0);
    93. EDIT_SetText(hItem, "123");
    94. // USER START (Optionally insert additional code for further widget initialization)
    95. // USER END
    96. break;
    97. case WM_NOTIFY_PARENT:
    98. Id = WM_GetId(pMsg->hWinSrc);
    99. NCode = pMsg->Data.v;
    100. switch(Id) {
    101. case ID_SLIDER_0: // Notifications sent by 'Slider'
    102. switch(NCode) {
    103. case WM_NOTIFICATION_CLICKED:
    104. // USER START (Optionally insert code for reacting on notification message)
    105. // USER END
    106. break;
    107. case WM_NOTIFICATION_RELEASED:
    108. // USER START (Optionally insert code for reacting on notification message)
    109. // USER END
    110. break;
    111. case WM_NOTIFICATION_VALUE_CHANGED:
    112. // USER START (Optionally insert code for reacting on notification message)
    113. // USER END
    114. break;
    115. // USER START (Optionally insert additional code for further notification handling)
    116. // USER END
    117. }
    118. break;
    119. case ID_MULTIEDIT_0: // Notifications sent by 'Multiedit'
    120. switch(NCode) {
    121. case WM_NOTIFICATION_CLICKED:
    122. // USER START (Optionally insert code for reacting on notification message)
    123. // USER END
    124. break;
    125. case WM_NOTIFICATION_RELEASED:
    126. // USER START (Optionally insert code for reacting on notification message)
    127. // USER END
    128. break;
    129. case WM_NOTIFICATION_VALUE_CHANGED:
    130. // USER START (Optionally insert code for reacting on notification message)
    131. // USER END
    132. break;
    133. // USER START (Optionally insert additional code for further notification handling)
    134. // USER END
    135. }
    136. break;
    137. case ID_EDIT_0: // Notifications sent by 'Edit'
    138. switch(NCode) {
    139. case WM_NOTIFICATION_CLICKED:
    140. // USER START (Optionally insert code for reacting on notification message)
    141. // USER END
    142. break;
    143. case WM_NOTIFICATION_RELEASED:
    144. // USER START (Optionally insert code for reacting on notification message)
    145. // USER END
    146. break;
    147. case WM_NOTIFICATION_VALUE_CHANGED:
    148. // USER START (Optionally insert code for reacting on notification message)
    149. // USER END
    150. break;
    151. // USER START (Optionally insert additional code for further notification handling)
    152. // USER END
    153. }
    154. break;
    155. // USER START (Optionally insert additional code for further Ids)
    156. // USER END
    157. }
    158. break;
    159. // USER START (Optionally insert additional message handling)
    160. // USER END
    161. default:
    162. WM_DefaultProc(pMsg);
    163. break;
    164. }
    165. }
    166. /*********************************************************************
    167. *
    168. * Public code
    169. *
    170. **********************************************************************
    171. */
    172. /*********************************************************************
    173. *
    174. * CreateWindow
    175. */
    176. WM_HWIN CreateWindow(void);
    177. WM_HWIN CreateWindow(void) {
    178. WM_HWIN hWin;
    179. hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
    180. return hWin;
    181. }
    182. // USER START (Optionally insert additional public code)
    183. // USER END
    184. /*************************** End of file ****************************/
    Display All


    Again, thank you very much for your assistance.
    Johanan
  • Hello Johanan,

    You do not have to set the cursor manually. This should be performed automatically by emWin. Please also try creating the dialog on layer 0. Currently you are creating it on layer 1. Please also note that the function GUI_SetBkColor() is not a drawing function. It just sets a color. Drawing operations using the background color are e.g. GUI_Clear() or any text output performed in the normal text mode (GUI_TM_NORMAL).

    Best regards,
    Adrian
  • Hello Johanan,

    I am just trying to simplify the application. If you want to use multiple layers, you will have to make sure they are set up properly. For details please refer to the chapter "Multi layer / multi display support" in the emWin user manual.

    Please note that the STemWin library is created by ST, so I am not able to answer specific questions about it.

    Best regards,
    Adrian