Subversion Repositories HomeAutomation

Rev

Rev 1289 | Rev 1292 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. #include "sns_Touch.h"
  3. point touchBuffer[sns_Touch_BUFFERSIZE];
  4. uint8_t rxbufidx;
  5. uint8_t pushStatus;
  6.  
  7. point lastValidPoint;
  8.  
  9. #ifdef sns_Touch_USEEEPROM
  10. #include "sns_Touch_eeprom.h"
  11. struct eeprom_sns_Touch EEMEM eeprom_sns_Touch =
  12. {
  13.     {
  14.         ///TODO: Define initialization values on the EEPROM variables here, this will generate a *.eep file that can be used to store this values to the node, can in future be done with a EEPROM module and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file.
  15.         0xAB,   // x
  16.         0x1234  // y
  17.     },
  18.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  19. };
  20. #endif
  21.  
  22. void sns_Touch_Init(void)
  23. {
  24. #ifdef sns_Touch_USEEEPROM
  25.     if (EEDATA_OK)
  26.     {
  27.       ///TODO: Use stored data to set initial values for the module
  28.       blablaX = eeprom_read_byte(EEDATA.x);
  29.       blablaY = eeprom_read_word(EEDATA.y);
  30.     } else
  31.     {   //The CRC of the EEPROM is not correct, store default values and update CRC
  32.       eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
  33.       eeprom_write_word_crc(EEDATA.y, 0x1234, WITHOUT_CRC);
  34.       EEDATA_UPDATE_CRC;
  35.     }
  36. #endif  
  37.     ///TODO: Initialize hardware etc here
  38.  
  39.     // to use PCINt lib, call this function: (the callback function look as a timer callback function)
  40.     // Pcint_SetCallbackPin(sns_Touch_PCINT, EXP_C , &sns_Touch_pcint_callback);
  41.  
  42.     ADC_Init();
  43.     Timer_SetTimeout(sns_Touch_POLL_TIMER, sns_Touch_POLL_PERIOD , TimerTypeFreeRunning, 0);
  44.    
  45.     rxbufidx = 0;
  46.     pushStatus = 0;
  47.     lastValidPoint.x=0;
  48.     lastValidPoint.y=0;
  49. }
  50.  
  51.  
  52. /*
  53. F1: Klar
  54. F2: Klar
  55. F3: Klar
  56. F4: Klar
  57. F5: Klar
  58. F6: Klar
  59. F7: Klar
  60. F8: Klar? (kontrollera funktion)
  61. F9:
  62. */
  63.  
  64. /*
  65. Touch gesture parser
  66. Implementation of 'A new gesture recognition algorithm and segmentation
  67. method of Korean scripts for gesture-allowed ink editor' by Mi Gyung Cho
  68.  
  69. Call function parseBuffer with a buffer containing x/y coordinates, the buffer start and end.
  70. Returns function results that describe the gesture in 24bits
  71.  
  72. Written by Linus Lundin, Jonas Andersson and Anders Runeson, 2009
  73.  
  74. To fix:
  75. Break out to a driver file
  76. */
  77. gesture parseBuffer(point *buffer, uint8_t startIndex, uint8_t endIndex)
  78. {
  79.     int16_t f1_k = 0, f3_tmp = 0, f4_tmp = 0, f5_tmp = 0, f9_tmp = 0;
  80.     uint8_t f7_tmp = 0, f7_sign = 0, f1_sign = 0, f3_yref = 0, xMin, xMax, yMin, yMax;
  81.     gesture functionData;
  82.     functionData.f1=0;
  83.     functionData.f7=0;
  84.    
  85.     /* Function 6 indicates the sign value of the y coordinates of the last point minus y coordinates of the first point */
  86.     functionData.f6 = CAN_MODULE_ENUM_TOUCH_GESTURE_F6_M;
  87.     if ((int16_t)buffer[endIndex].y - (int16_t)buffer[startIndex].y > 0)
  88.     {
  89.         functionData.f6 = CAN_MODULE_ENUM_TOUCH_GESTURE_F6_P;
  90.     }
  91.    
  92.     xMin = buffer[startIndex].x;
  93.     xMax = buffer[startIndex].x;
  94.     yMin = buffer[startIndex].y;
  95.     yMax = buffer[startIndex].y;
  96.     f3_yref = (buffer[startIndex].y + buffer[endIndex].y)/2;
  97.     f1_k = ((buffer[endIndex].y-buffer[startIndex].y)<<4)/(buffer[endIndex].x-buffer[startIndex].x);
  98.     f1_sign = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_U;
  99.  
  100.     for (uint8_t i = startIndex+1; i < endIndex-1; i++)
  101.     {
  102.         /* Function 1 indicates the number of intersection points between an input gesture g(x) and the straight line f(x)
  103.         which connects the first and last point of the gesture */
  104.         if (((f1_k*(buffer[i].x-buffer[0].x))>>4) + buffer[0].y < buffer[i].y)
  105.         {
  106.             if (f1_sign != CAN_MODULE_ENUM_TOUCH_GESTURE_F2_P)
  107.             {
  108.                 functionData.f1++;
  109.             }
  110.             f1_sign = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_P;
  111.         }
  112.         else
  113.         {
  114.             if (f1_sign != CAN_MODULE_ENUM_TOUCH_GESTURE_F2_M)
  115.             {
  116.                 functionData.f1++;
  117.             }
  118.             f1_sign = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_M;
  119.         }
  120.        
  121.         /* Function 3 indicates the sign value of area gap between g(x) and f(x) */
  122.         if (buffer[i].x > min(buffer[startIndex].x, buffer[endIndex].x) && buffer[i].x < max(buffer[startIndex].x, buffer[endIndex].x))
  123.         {
  124.             f3_tmp += f3_yref - (buffer[i].y + buffer[i-1].y)/2;
  125.         }
  126.        
  127.         /* find min an max of x and y */
  128.         if (xMin > buffer[i].x)
  129.         {
  130.             xMin = buffer[i].x;
  131.         }
  132.         if (xMax < buffer[i].x)
  133.         {
  134.             xMax = buffer[i].x;
  135.         }
  136.         if (yMin > buffer[i].y)
  137.         {
  138.             yMin = buffer[i].y;
  139.         }
  140.         if (yMax < buffer[i].y)
  141.         {
  142.             yMax = buffer[i].y;
  143.         }
  144.        
  145.         /* Function 4 represents the sign value of the sum of the x coordinates of all the points that constitute strokes
  146.         minus the x coordinates of the last point */
  147.         f4_tmp += (int16_t)buffer[i].x - (int16_t)buffer[endIndex].x;
  148.        
  149.         /* Function 5 checks the sign value of the sum of the x coordinates of all the points that constitute strokes
  150.         minus x coordinates of the first point */
  151.         f5_tmp += (int16_t)buffer[i].x - (int16_t)buffer[startIndex].x;
  152.     }
  153.    
  154.     /* Function 7 indicates the number of intersection points between an input gesture g(x) and all horizontal lines yi,
  155.     where i is between 0 and n, that constitute a gesture*/
  156.     for (uint8_t j = yMin; j < yMax-1; j++)
  157.     {
  158.         f7_tmp = 0xff;
  159.         f7_sign = 0;
  160.         for (uint8_t i = startIndex+1; i < endIndex-1; i++)
  161.         {
  162.             if (j > buffer[i].y)
  163.             {
  164.                 if (f7_sign != '+')
  165.                 {
  166.                     f7_tmp++;
  167.                 }
  168.                 f7_sign = '+';
  169.             }
  170.             else {
  171.                 if (f7_sign != '-')
  172.                 {
  173.                     f7_tmp++;
  174.                 }
  175.                 f7_sign = '-';
  176.             }
  177.         }
  178.         if (f7_tmp > functionData.f7)
  179.         {
  180.             functionData.f7 = f7_tmp;
  181.         }
  182.     }
  183.    
  184.     functionData.f1--;
  185.     /* Function 2 checks if the y coordinates of the points which exist between the intersection point and the last point are
  186.     greater than the y coordinates of the intersection point */
  187.     functionData.f2 = f1_sign;
  188.     if (functionData.f1 == 0)
  189.     {
  190.         functionData.f2 = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_U;
  191.     }
  192.    
  193.     /* Function 3 indicates the sign value of area gap between g(x) and f(x) */
  194.     functionData.f3 = CAN_MODULE_ENUM_TOUCH_GESTURE_F3_P;
  195.     if (f3_tmp > 0)
  196.     {
  197.         functionData.f3 = CAN_MODULE_ENUM_TOUCH_GESTURE_F3_M;
  198.     }
  199.        
  200.     /* Function 9 represents the sign value of the multiplication of x coordinates of the first point and the last point
  201.     minus the mediate value of x coordinates of all the points */
  202.     f9_tmp = ((buffer[startIndex].x - (xMax+xMin)/2)*(buffer[endIndex].x - (xMax+xMin)/2));
  203.     functionData.f9 = CAN_MODULE_ENUM_TOUCH_GESTURE_F9_M;
  204.     if (f9_tmp > 0)
  205.     {
  206.         functionData.f9 = CAN_MODULE_ENUM_TOUCH_GESTURE_F9_P;
  207.     }
  208.    
  209.     /* Function 5 checks the sign value of the sum of the x coordinates of all the points that constitute strokes
  210.     minus x coordinates of the first point */
  211.     functionData.f5 = CAN_MODULE_ENUM_TOUCH_GESTURE_F5_M;
  212.     if (f5_tmp > 0)
  213.     {
  214.         functionData.f5 = CAN_MODULE_ENUM_TOUCH_GESTURE_F5_P;
  215.     }
  216.    
  217.     /* Function 4 represents the sign value of the sum of the x coordinates of all the points that constitute strokes
  218.     minus the x coordinates of the last point */
  219.     functionData.f4 = CAN_MODULE_ENUM_TOUCH_GESTURE_F4_M;
  220.     if (f4_tmp > 0)
  221.     {
  222.         functionData.f4 = CAN_MODULE_ENUM_TOUCH_GESTURE_F4_P;
  223.     }
  224.    
  225.     /* Function 8 checks whether or not x coordinates of all the points except for the first point and the last point is between x0 and xn */
  226.     functionData.f8 = CAN_MODULE_ENUM_TOUCH_GESTURE_F8_M;
  227.     if (xMin < min(buffer[startIndex].x,buffer[endIndex].x) || xMax > max(buffer[startIndex].x,buffer[endIndex].x))
  228.     {
  229.         functionData.f8 = CAN_MODULE_ENUM_TOUCH_GESTURE_F8_P;
  230.     }
  231.        
  232.     //printf("1%u2%c3%c4%c5%c6%c7%u8%c9%c\n", f1, f2, f3, f4, f5, f6, f7, f8, f9);
  233.  
  234.     return functionData;
  235. }
  236.  
  237.  
  238. void sns_Touch_Process(void)
  239. {
  240.    
  241.     if (Timer_Expired(sns_Touch_POLL_TIMER)) {
  242.         //StdCan_Msg_t txMsg;
  243.         gpio_set_in(sns_Touch_XPLUS);
  244.         gpio_set_pullup(sns_Touch_XPLUS);   //turn on pullup for x+
  245.         gpio_set_out(sns_Touch_YPLUS);
  246.         gpio_set_pin(sns_Touch_YPLUS);      //turn on 1 on y+
  247.         gpio_set_out(sns_Touch_YMINUS);
  248.         gpio_clr_pin(sns_Touch_YMINUS);     //turn on 0 on y-
  249. #ifdef sns_Touch_SWITCH_XY
  250.             uint8_t adyval = ADC_Get(sns_Touch_TOUCHXAD)>>2;    //read x-
  251. #else
  252.             uint8_t adxval = ADC_Get(sns_Touch_TOUCHXAD)>>2;    //read x-
  253. #endif
  254.        
  255.         gpio_set_in(sns_Touch_YPLUS);
  256.         gpio_clr_pullup(sns_Touch_YPLUS);   //turn off pullup for y+
  257.         gpio_set_in(sns_Touch_YMINUS);
  258.         gpio_clr_pullup(sns_Touch_YMINUS);  //turn off pullup for y-
  259.         gpio_set_in(sns_Touch_XPLUS);
  260.         gpio_clr_pullup(sns_Touch_XPLUS);   //turn off pullup for x+
  261.        
  262.         gpio_set_in(sns_Touch_YPLUS);
  263.         gpio_set_pullup(sns_Touch_YPLUS);   //turn on pullup for y+
  264.         gpio_set_out(sns_Touch_XPLUS);
  265.         gpio_set_pin(sns_Touch_XPLUS);      //turn on 1 on x+
  266.         gpio_set_out(sns_Touch_XMINUS);
  267.         gpio_clr_pin(sns_Touch_XMINUS);     //turn on 0 on x-
  268. #ifdef sns_Touch_SWITCH_XY
  269.         uint8_t adxval = ADC_Get(sns_Touch_TOUCHYAD)>>2;    //read y-
  270. #else
  271.         uint8_t adyval = ADC_Get(sns_Touch_TOUCHYAD)>>2;    //read y-
  272. #endif
  273.         gpio_set_in(sns_Touch_XPLUS);
  274.         gpio_clr_pullup(sns_Touch_XPLUS);   //turn off pullup for x+
  275.         gpio_set_in(sns_Touch_XMINUS);
  276.         gpio_clr_pullup(sns_Touch_XMINUS);  //turn off pullup for x-
  277.         gpio_set_in(sns_Touch_YPLUS);
  278.         gpio_clr_pullup(sns_Touch_YPLUS);   //turn off pullup for y+
  279.        
  280.        
  281.  
  282.         if (adyval < 0xf0 && adxval < 0xf0 )
  283.         {
  284. #ifdef sns_Touch_INVERT_Y
  285.             adyval = 255-adyval;
  286. #endif
  287. #ifdef sns_Touch_INVERT_X
  288.             adxval = 255-adxval;
  289. #endif
  290.             lastValidPoint.x=adxval;
  291.             lastValidPoint.y=adyval;
  292.             pushStatus = 1;
  293.             uint8_t xdiff=0;
  294.             uint8_t ydiff=0;
  295.             if (rxbufidx > 0)
  296.             {
  297.                 xdiff = touchBuffer[rxbufidx-1].x - adxval;
  298.                 if (touchBuffer[rxbufidx-1].x < adxval)
  299.                 {
  300.                     xdiff = adxval - touchBuffer[rxbufidx-1].x;
  301.                 }
  302.                 ydiff = touchBuffer[rxbufidx-1].y - adyval;
  303.                 if (touchBuffer[rxbufidx-1].y < adyval)
  304.                 {
  305.                     ydiff = adyval - touchBuffer[rxbufidx-1].y;
  306.                 }
  307.             }
  308.             if (rxbufidx == 0 || (rxbufidx > 0 && xdiff+ydiff > 10))
  309.             {
  310.                 touchBuffer[rxbufidx].x = adxval;
  311.                 touchBuffer[rxbufidx].y = adyval;
  312.                 rxbufidx++;
  313.                 if (rxbufidx==sns_Touch_BUFFERSIZE)
  314.                 {
  315.                     rxbufidx=0;
  316.                 }
  317.  
  318.                 StdCan_Msg_t txMsg;
  319.                 StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  320.                 StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  321.                 txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  322.                 txMsg.Header.ModuleId = sns_Touch_ID;
  323.                 txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_RAW;
  324.                 txMsg.Length = 3;
  325.                 txMsg.Data[0] = CAN_MODULE_ENUM_TOUCH_RAW_STATUS_PRESSED;
  326.                 txMsg.Data[1] = adxval;
  327.                 txMsg.Data[2] = adyval;
  328.    
  329.                 StdCan_Put(&txMsg);
  330.             }
  331.             //printf("Y: %d X: %d\n", adyval, adxval);
  332.         }
  333.         else if (rxbufidx > 3)
  334.         {
  335.             if (pushStatus==1)
  336.             {
  337.                 pushStatus = 2;
  338.             }
  339.             //printf("Released %d\n", rxbufidx);
  340.             gesture functionData = parseBuffer(touchBuffer, 0, rxbufidx-1);
  341.            
  342.             StdCan_Msg_t txMsg;
  343.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  344.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  345.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  346.             txMsg.Header.ModuleId = sns_Touch_ID;
  347.             txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_GESTURE;
  348.             txMsg.Length = 3;
  349.             txMsg.Data[0] = functionData.f1;
  350.             txMsg.Data[1] = functionData.f7;
  351.             txMsg.Data[2] = functionData.f3<<7|functionData.f4<<6|functionData.f5<<5|functionData.f6<<4|functionData.f8<<3|functionData.f9<<2|functionData.f2;
  352.    
  353.             StdCan_Put(&txMsg);
  354.             /*for (uint8_t i = 0; i < rxbufidx; i++)
  355.             {
  356.                 printf("%3d ", touchBuffer[i].x);
  357.             }
  358.             printf("\n");
  359.             for (uint8_t i = 0; i < rxbufidx; i++)
  360.             {
  361.                 printf("%3d ", touchBuffer[i].y);
  362.             }
  363.             printf("\n");
  364.             */
  365.            
  366.             rxbufidx = 0;
  367.         }
  368.         else if (pushStatus==1)
  369.         {
  370.             rxbufidx = 0;
  371.             pushStatus = 2;
  372.         }
  373.        
  374.         if (pushStatus == 2)
  375.         {
  376.             pushStatus = 0;
  377.            
  378.             StdCan_Msg_t txMsg;
  379.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  380.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  381.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  382.             txMsg.Header.ModuleId = sns_Touch_ID;
  383.             txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_RAW;
  384.             txMsg.Length = 3;
  385.             txMsg.Data[0] = CAN_MODULE_ENUM_TOUCH_RAW_STATUS_RELEASED;
  386.             txMsg.Data[1] = lastValidPoint.x;
  387.             txMsg.Data[2] = lastValidPoint.y;
  388.  
  389.             StdCan_Put(&txMsg);
  390.         }
  391.     }
  392. }
  393.  
  394.  
  395. void sns_Touch_HandleMessage(StdCan_Msg_t *rxMsg)
  396. {
  397.     /*if (  StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_xyz && ///TODO: Change this to the actual class type
  398.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  399.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_xyz && ///TODO: Change this to the actual module type
  400.         rxMsg->Header.ModuleId == sns_Touch_ID)
  401.     {
  402.         switch (rxMsg->Header.Command)
  403.         {
  404.         case CAN_CMD_MODULE_DUMMY:
  405.         ///TODO: Do something dummy
  406.         break;
  407.         }
  408.     }*/
  409. }
  410.  
  411. void sns_Touch_List(uint8_t ModuleSequenceNumber)
  412. {
  413.     StdCan_Msg_t txMsg;
  414.    
  415.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  416.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  417.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  418.     txMsg.Header.ModuleId = sns_Touch_ID;
  419.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  420.     txMsg.Length = 6;
  421.  
  422.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  423.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  424.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  425.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  426.    
  427.     txMsg.Data[4] = NUMBER_OF_MODULES;
  428.     txMsg.Data[5] = ModuleSequenceNumber;
  429.    
  430.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  431. }
  432.