WM_NOTIFICATION_RELEASED message not fired

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

    • WM_NOTIFICATION_RELEASED message not fired

      Hello.
      I have a simple GUI Window with a button on it.
      my problem is that when I remove (release) my finger (pressure) from the (any) widget on analog touch screen, the WM_NOTIFICATION_RELEASED is not fired in Dialog callback routine(_cbDialog) and Cursor is also jumped to other position which is different from last coordinate of my finger.(the values of x and y coordinates are right in pressed state).
      --------------------------------------------------------------------------------------------------------------------------------------
      Used Components : LPC1788 as Micro and XPT2046 IC to read analog touch screen by SPI.
      Used Software : KEIL
      Method description:
      1-I call GUI_TOUCH_Exec from OS timer regularly.(there is no problem here).
      2-I have defined a Variable named IsPressed which is used to store the active low PENIRQ pin on XPT2046 .

      static uint32_t IsPressed;
      void CheckTouch()
      {
      IsPressed=GPIO_PinRead(TOUCH_INTERRUPT_PIN.Portnum,TOUCH_INTERRUPT_PIN.Pinnum);//IsPressed=0 so we have a //press,
      IsPressed=1 so the Touch panel is released.
      }
      3-I have defined GUI_TOUCH_X_ActivateX , GUI_TOUCH_X_ActivateY , GUI_TOUCH_X_MeasureX , GUI_TOUCH_X_MeasureY as follows:(I use KEIL SPI middleware to read/write from/to
      XPT2046 IC)
      void GUI_TOUCH_X_ActivateX(void) {
      CheckTouch();//I use this Function to check whether PENIRQ pin on XPT2046 is LOW(Tuch Panel is Pressed)
      if (IsPressed==0)//Touch Panel Is Pressed, so I send Command to XPT2046 to initiate ADC conversion
      {
      ARM_DRIVER_SPI* SPI_Drv=&Driver_SPI0;
      SPI_Drv->Control(ARM_SPI_CONTROL_SS,ARM_SPI_SS_ACTIVE);
      SPI_Drv->Send(&X_Active_Y_Out,sizeof(X_Active_Y_Out));
      }
      }

      void GUI_TOUCH_X_ActivateY(void) {

      if (IsPressed==0)//Touch Panel Is Pressed, so I send Command to XPT2046 to initiate ADC conversion
      {
      ARM_DRIVER_SPI* SPI_Drv=&Driver_SPI0;
      SPI_Drv->Control(ARM_SPI_CONTROL_SS,ARM_SPI_SS_ACTIVE);
      SPI_Drv->Send(&Y_Active_X_Out,sizeof(Y_Active_X_Out));
      }
      }

      int GUI_TOUCH_X_MeasureX(void) {
      uint16_t result=-1;
      if (IsPressed==0)//Touch Panel Is Pressed, so I send Command to XPT2046 to get back X
      {
      ARM_DRIVER_SPI* SPI_Drv=&Driver_SPI0;
      DelayUS(2);
      SPI_Drv->Control(ARM_SPI_CONTROL_SS,ARM_SPI_SS_ACTIVE);
      SPI_Drv->Receive(X_Out,sizeof(X_Out));

      result=(X_Out[0]<<8) | X_Out[1];
      result>>=3;
      result&=0x0FFF;

      SPI_Drv->Control(ARM_SPI_CONTROL_SS,ARM_SPI_SS_INACTIVE);
      return result;
      }
      return -1;
      //return -1 if there is no press to indicate an unpressed state.(I think so...)}

      int GUI_TOUCH_X_MeasureY(void) {
      uint16_t result=-1;
      if (IsPressed==0)//Touch Panel Is Pressed, so I send Command to XPT2046 to get back X
      {
      ARM_DRIVER_SPI* SPI_Drv=&Driver_SPI0;
      SPI_Drv->Control(ARM_SPI_CONTROL_SS,ARM_SPI_SS_ACTIVE);
      SPI_Drv->Receive(Y_Out,sizeof(Y_Out));

      result=(Y_Out[0]<<8) | Y_Out[1];
      result>>=3;
      result&=0x0FFF;

      SPI_Drv->Control(ARM_SPI_CONTROL_SS,ARM_SPI_SS_INACTIVE);
      return result;
      }
      return -1;//return -1 if there is no press to indicate an unpressed state.(I think so...)
      }
      4-Above function all work properly and GUI_TOUCH_GetState() function return true X and Y position, but as I said before the WM_NOTIFICATION_RELEASED message is not fired in Dialog callback routine(_cbDialog) when I remove my finger from any widgets on touch screen.
      5-my dialog source:

      #include "DIALOG.h"

      #define ID_WINDOW_0 (GUI_ID_USER + 0x00)
      #define ID_BUTTON_0 (GUI_ID_USER + 0x01)

      /*********************************************************************
      *
      * _aDialogCreate
      */
      static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
      { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 800, 480, 0, 0x0, 0 },
      { BUTTON_CreateIndirect, "Button", ID_BUTTON_0, 15, 14, 407, 138, 0, 0x0, 0 },
      // USER START (Optionally insert additional widgets)
      // USER END
      };

      // USER START (Optionally insert additional static code)
      //a Test Callback method for BUTTON to see whether created butten react to
      WM_NOTIFICATION_RELEASED (the result is NO)
      static void _cbButton(WM_MESSAGE * pMsg) {
      int NCode;
      int Id;
      WM_HWIN hParentWin;
      GUI_PID_STATE *pid_State;
      // USER START (Optionally insert additional variables)
      // USER END

      switch (pMsg->MsgId) {
      case WM_TOUCH:
      pid_State=(GUI_PID_STATE*)pMsg->Data.p;
      if (pid_State->Pressed==1)
      {
      BUTTON_SetText(pMsg->hWin,"Pressed");//Yes this message works.
      }
      else
      {
      BUTTON_SetText(pMsg->hWin,"Not Pressed");//I can get here
      }

      break;
      case WM_NOTIFICATION_RELEASED:
      BUTTON_SetText(pMsg->hWin,"Realese From Button");//but I can not get
      WM_NOTIFICATION_RELEASED
      break;

      default:
      BUTTON_Callback(pMsg);
      break;
      }
      }
      // USER END

      /*********************************************************************
      *
      * _cbDialog
      */
      static void _cbDialog(WM_MESSAGE * pMsg) {
      int NCode;
      int Id;
      WM_HWIN hItem;
      // USER START (Optionally insert additional variables)
      // USER END

      switch (pMsg->MsgId) {
      case WM_INIT_DIALOG:
      hItem=WM_GetDialogItem(pMsg->hWin,ID_BUTTON_0);
      WM_SetCallback(hItem,_cbButton);
      break;
      case WM_NOTIFY_PARENT:
      Id = WM_GetId(pMsg->hWinSrc);
      NCode = pMsg->Data.v;
      switch(Id) {
      case ID_BUTTON_0: // Notifications sent by 'Button'
      switch(NCode) {
      case WM_NOTIFICATION_CLICKED:
      // USER START (Optionally insert code for reacting on notification message)
      // USER END
      break;
      case WM_NOTIFICATION_RELEASED:
      // USER START (Optionally insert code for reacting on notification message)
      BUTTON_SetText(pMsg->hWinSrc,"Rel");// The Code never reach here
      // USER END
      break;

      // USER START (Optionally insert additional code for further notification handling)
      // USER END
      }
      break;
      // USER START (Optionally insert additional code for further Ids)
      // USER END
      }
      break;
      // USER START (Optionally insert additional message handling)
      // USER END
      default:
      WM_DefaultProc(pMsg);
      break;
      }
      }

      /*********************************************************************
      *
      * Public code
      *
      **********************************************************************
      */
      /*********************************************************************
      *
      * CreateWindow
      */
      WM_HWIN CreateWindow(void);
      WM_HWIN CreateWindow(void) {
      WM_HWIN hWin;

      hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
      return hWin;
      }
      /*************************** End of file ****************************/
      Somewhere in the forum I read that one should enable "release event for EMwin" , but I don't know what is that and What should I do to enable
      WM_NOTIFICATION_RELEASED for my widgets?
      Thank you.
    • Hello.
      Thank you for your help.
      but my problem is that the WM_NOTIFICATION_RELEASED is never activated (called) when I release a widget (Like button) .
      even DEBUG mode shows that WM_NOTIFICATION_RELEASED never get fired (activated) in DIALOG callback(_cbDialog).So I can not execute any code in response to WM_NOTIFICATION_RELEASED.
      thanks.
    • i think you have a problem on touch code

      i use this code


      if(!TP_INT_IN)
      {
      Ptr_dd = GET_TOUCH();

      GUI_TOUCH_StoreState(Ptr_dd->x, Ptr_dd->y ); // GUI_CURSOR_SetPosition(Ptr_dd->x, Ptr_dd->y );
      xPhys = Ptr_dd->x;
      yPhys = Ptr_dd->y;

      }
      else
      GUI_TOUCH_StoreState(-1, -1);
    • WM_NOTIFICATION_RELEASED not fired

      Hello.
      Thanks again for the help.
      but because I am using an analog resistive Touch Screen and according to "page 1081 of emWin User Manual" ebook , the GUI_TOUCH_Exec() calls GUI_TOUCH_StoreState() internally and I think GUI_TOUCH_Exec() used returned results fromGUI_TOUCH_X_MeasureX() and GUI_TOUCH_X_MeasureY() functions to fill GUI_TOUCH_StoreState() parameters.
      Also GUI_PID_GetState() function detects X , Y Positions and Pressed state rightly.
      I still have the problem.
      Thank you.
    • Hi,

      First thing you might want to try is to return the last measured coordinates even if the IsPressed variable is 1.

      If this doesn't work can try something like this:

      C Source Code

      1. static int aRefX[] = { 10, 790, 790, 10, 400 }; // These are reference points
      2. static int aRefY[] = { 10, 10, 470, 470, 240 };
      3. static int aSampleX[] = { 10, 2030, 2030, 10, 1015 }; // These are A/D values measured at the reference points
      4. static int aSampleY[] = { 10, 10, 1600, 1600, 800 };
      5. static void InitTouch(void) {
      6. GUI_TOUCH_EnableCalibration(1);
      7. GUI_TOUCH_CalcCoefficients(5, aRefX, aRefY, aSampleX, aSampleY, LCD_GetXSize(), LCD_YSize());
      8. }
      9. static void ReadTouch(void) {
      10. static GUI_PID_STATE State;
      11. static int IsPressed;
      12. int x;
      13. int y;
      14. if (CheckTouch() == 0) { // Change the function to return the state of the GPIO
      15. //
      16. // Set pressed flag
      17. //
      18. IsPressed = 1;
      19. State.x = ReadADValueX(); // Read A/D value for x
      20. State.y = ReadADValueY(); // Read A/D value for y
      21. State.Pressed = 1; // set Pressed to 0
      22. //
      23. // Pass touch to emWin, it will get automatically calibrated
      24. //
      25. GUI_TOUCH_StoreStateEx(&State);
      26. } else {
      27. if (IsPressed) {
      28. IsPressed = 0;
      29. State.Pressed = 0;
      30. //
      31. // Pass touch state to emWin, only the pressed has changed, we use the same x/y coordinates as before.
      32. //
      33. GUI_TOUCH_StoreStateEx(&State);
      34. }
      35. }
      36. }
      Display All


      The static arrays are reference points in x and y and sample points (raw A/D value) in x and y. Please take a look into the manual at chapter 26.5 'Touch Screen Calibration'. There is an explanation regarding those points. You have to measure the A/D values for each reference point and write it down. Later on you can use this values in the sample arrays.

      If this is done call the function InitTouch which enables touch calibration and calculates coeffecients to be used.

      The function ReadTouch() gets called periodically (e.g. by your OS timer). If touch gets detected the A/D values are read and passed to emWin. Internally they will be transformed into pixel coordinates. The static variable IsPressed signals a pressed event. If no touch is detected we have to pass an up event to emWin (State.Pressed == 0). Of course, only once after the last press on the touch screen.

      Regards
      Sven
      Please read the forum rules before posting.

      Keep in mind, this is *not* a support forum.
      Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
      Should you be entitled to support you can contact us via our support system: segger.com/ticket/

      Or you can contact us via e-mail.