Subversion Repositories HomeAutomation

Rev

Rev 1290 | Rev 1293 | 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: Klar
  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;
  80.     uint8_t f7_tmp = 0, f7_sign = 0, f1_sign = 0, f3_yref = 0, xMin, xMax, yMin, yMax, f9_tmp;
  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 and 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.    
  204.     f9_tmp = ((buffer[startIndex].x - (xMax+xMin)/2 > 0) ^ (buffer[endIndex].x - (xMax+xMin)/2 > 0));
  205.    
  206.     functionData.f9 = CAN_MODULE_ENUM_TOUCH_GESTURE_F9_M;
  207.     if (!f9_tmp)
  208.     {
  209.         functionData.f9 = CAN_MODULE_ENUM_TOUCH_GESTURE_F9_P;
  210.     }
  211.    
  212.     /* Function 5 checks the sign value of the sum of the x coordinates of all the points that constitute strokes
  213.     minus x coordinates of the first point */
  214.     functionData.f5 = CAN_MODULE_ENUM_TOUCH_GESTURE_F5_M;
  215.     if (f5_tmp > 0)
  216.     {
  217.         functionData.f5 = CAN_MODULE_ENUM_TOUCH_GESTURE_F5_P;
  218.     }
  219.    
  220.     /* Function 4 represents the sign value of the sum of the x coordinates of all the points that constitute strokes
  221.     minus the x coordinates of the last point */
  222.     functionData.f4 = CAN_MODULE_ENUM_TOUCH_GESTURE_F4_M;
  223.     if (f4_tmp > 0)
  224.     {
  225.         functionData.f4 = CAN_MODULE_ENUM_TOUCH_GESTURE_F4_P;
  226.     }
  227.    
  228.     /* 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 */
  229.     functionData.f8 = CAN_MODULE_ENUM_TOUCH_GESTURE_F8_M;
  230.     if (xMin < min(buffer[startIndex].x,buffer[endIndex].x) || xMax > max(buffer[startIndex].x,buffer[endIndex].x))
  231.     {
  232.         functionData.f8 = CAN_MODULE_ENUM_TOUCH_GESTURE_F8_P;
  233.     }
  234.        
  235.     //printf("1%u2%c3%c4%c5%c6%c7%u8%c9%c\n", f1, f2, f3, f4, f5, f6, f7, f8, f9);
  236.  
  237.     return functionData;
  238. }
  239.  
  240.  
  241. void sns_Touch_Process(void)
  242. {
  243.    
  244.     if (Timer_Expired(sns_Touch_POLL_TIMER)) {
  245.         //StdCan_Msg_t txMsg;
  246.         gpio_set_in(sns_Touch_XPLUS);
  247.         gpio_set_pullup(sns_Touch_XPLUS);   //turn on pullup for x+
  248.         gpio_set_out(sns_Touch_YPLUS);
  249.         gpio_set_pin(sns_Touch_YPLUS);      //turn on 1 on y+
  250.         gpio_set_out(sns_Touch_YMINUS);
  251.         gpio_clr_pin(sns_Touch_YMINUS);     //turn on 0 on y-
  252. #ifdef sns_Touch_SWITCH_XY
  253.             uint8_t adyval = ADC_Get(sns_Touch_TOUCHXAD)>>2;    //read x-
  254. #else
  255.             uint8_t adxval = ADC_Get(sns_Touch_TOUCHXAD)>>2;    //read x-
  256. #endif
  257.        
  258.         gpio_set_in(sns_Touch_YPLUS);
  259.         gpio_clr_pullup(sns_Touch_YPLUS);   //turn off pullup for y+
  260.         gpio_set_in(sns_Touch_YMINUS);
  261.         gpio_clr_pullup(sns_Touch_YMINUS);  //turn off pullup for y-
  262.         gpio_set_in(sns_Touch_XPLUS);
  263.         gpio_clr_pullup(sns_Touch_XPLUS);   //turn off pullup for x+
  264.        
  265.         gpio_set_in(sns_Touch_YPLUS);
  266.         gpio_set_pullup(sns_Touch_YPLUS);   //turn on pullup for y+
  267.         gpio_set_out(sns_Touch_XPLUS);
  268.         gpio_set_pin(sns_Touch_XPLUS);      //turn on 1 on x+
  269.         gpio_set_out(sns_Touch_XMINUS);
  270.         gpio_clr_pin(sns_Touch_XMINUS);     //turn on 0 on x-
  271. #ifdef sns_Touch_SWITCH_XY
  272.         uint8_t adxval = ADC_Get(sns_Touch_TOUCHYAD)>>2;    //read y-
  273. #else
  274.         uint8_t adyval = ADC_Get(sns_Touch_TOUCHYAD)>>2;    //read y-
  275. #endif
  276.         gpio_set_in(sns_Touch_XPLUS);
  277.         gpio_clr_pullup(sns_Touch_XPLUS);   //turn off pullup for x+
  278.         gpio_set_in(sns_Touch_XMINUS);
  279.         gpio_clr_pullup(sns_Touch_XMINUS);  //turn off pullup for x-
  280.         gpio_set_in(sns_Touch_YPLUS);
  281.         gpio_clr_pullup(sns_Touch_YPLUS);   //turn off pullup for y+
  282.        
  283.        
  284.  
  285.         if (adyval < 0xf0 && adxval < 0xf0 )
  286.         {
  287. #ifdef sns_Touch_INVERT_Y
  288.             adyval = 255-adyval;
  289. #endif
  290. #ifdef sns_Touch_INVERT_X
  291.             adxval = 255-adxval;
  292. #endif
  293.             lastValidPoint.x=adxval;
  294.             lastValidPoint.y=adyval;
  295.             pushStatus = 1;
  296.             uint8_t xdiff=0;
  297.             uint8_t ydiff=0;
  298.             if (rxbufidx > 0)
  299.             {
  300.                 xdiff = touchBuffer[rxbufidx-1].x - adxval;
  301.                 if (touchBuffer[rxbufidx-1].x < adxval)
  302.                 {
  303.                     xdiff = adxval - touchBuffer[rxbufidx-1].x;
  304.                 }
  305.                 ydiff = touchBuffer[rxbufidx-1].y - adyval;
  306.                 if (touchBuffer[rxbufidx-1].y < adyval)
  307.                 {
  308.                     ydiff = adyval - touchBuffer[rxbufidx-1].y;
  309.                 }
  310.             }
  311.             if (rxbufidx == 0 || (rxbufidx > 0 && xdiff+ydiff > 10))
  312.             {
  313.                 touchBuffer[rxbufidx].x = adxval;
  314.                 touchBuffer[rxbufidx].y = adyval;
  315.                 rxbufidx++;
  316.                 if (rxbufidx==sns_Touch_BUFFERSIZE)
  317.                 {
  318.                     rxbufidx=0;
  319.                 }
  320.  
  321.                 StdCan_Msg_t txMsg;
  322.                 StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  323.                 StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  324.                 txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  325.                 txMsg.Header.ModuleId = sns_Touch_ID;
  326.                 txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_RAW;
  327.                 txMsg.Length = 3;
  328.                 txMsg.Data[0] = CAN_MODULE_ENUM_TOUCH_RAW_STATUS_PRESSED;
  329.                 txMsg.Data[1] = adxval;
  330.                 txMsg.Data[2] = adyval;
  331.    
  332.                 StdCan_Put(&txMsg);
  333.             }
  334.             //printf("Y: %d X: %d\n", adyval, adxval);
  335.         }
  336.         else if (rxbufidx > 3)
  337.         {
  338.             if (pushStatus==1)
  339.             {
  340.                 pushStatus = 2;
  341.             }
  342.             //printf("Released %d\n", rxbufidx);
  343.             gesture functionData = parseBuffer(touchBuffer, 0, rxbufidx-1);
  344.            
  345.             StdCan_Msg_t txMsg;
  346.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  347.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  348.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  349.             txMsg.Header.ModuleId = sns_Touch_ID;
  350.             txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_GESTURE;
  351.             txMsg.Length = 3;
  352.             txMsg.Data[0] = functionData.f1;
  353.             txMsg.Data[1] = functionData.f7;
  354.             txMsg.Data[2] = functionData.f3<<7|functionData.f4<<6|functionData.f5<<5|functionData.f6<<4|functionData.f8<<3|functionData.f9<<2|functionData.f2;
  355.    
  356.             StdCan_Put(&txMsg);
  357.             /*for (uint8_t i = 0; i < rxbufidx; i++)
  358.             {
  359.                 printf("%3d ", touchBuffer[i].x);
  360.             }
  361.             printf("\n");
  362.             for (uint8_t i = 0; i < rxbufidx; i++)
  363.             {
  364.                 printf("%3d ", touchBuffer[i].y);
  365.             }
  366.             printf("\n");
  367.             */
  368.            
  369.             rxbufidx = 0;
  370.         }
  371.         else if (pushStatus==1)
  372.         {
  373.             rxbufidx = 0;
  374.             pushStatus = 2;
  375.         }
  376.        
  377.         if (pushStatus == 2)
  378.         {
  379.             pushStatus = 0;
  380.            
  381.             StdCan_Msg_t txMsg;
  382.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  383.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  384.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  385.             txMsg.Header.ModuleId = sns_Touch_ID;
  386.             txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_RAW;
  387.             txMsg.Length = 3;
  388.             txMsg.Data[0] = CAN_MODULE_ENUM_TOUCH_RAW_STATUS_RELEASED;
  389.             txMsg.Data[1] = lastValidPoint.x;
  390.             txMsg.Data[2] = lastValidPoint.y;
  391.  
  392.             StdCan_Put(&txMsg);
  393.         }
  394.     }
  395. }
  396.  
  397.  
  398. void sns_Touch_HandleMessage(StdCan_Msg_t *rxMsg)
  399. {
  400.     /*if (  StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_xyz && ///TODO: Change this to the actual class type
  401.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  402.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_xyz && ///TODO: Change this to the actual module type
  403.         rxMsg->Header.ModuleId == sns_Touch_ID)
  404.     {
  405.         switch (rxMsg->Header.Command)
  406.         {
  407.         case CAN_CMD_MODULE_DUMMY:
  408.         ///TODO: Do something dummy
  409.         break;
  410.         }
  411.     }*/
  412. }
  413.  
  414. void sns_Touch_List(uint8_t ModuleSequenceNumber)
  415. {
  416.     StdCan_Msg_t txMsg;
  417.    
  418.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  419.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  420.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  421.     txMsg.Header.ModuleId = sns_Touch_ID;
  422.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  423.     txMsg.Length = 6;
  424.  
  425.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  426.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  427.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  428.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  429.    
  430.     txMsg.Data[4] = NUMBER_OF_MODULES;
  431.     txMsg.Data[5] = ModuleSequenceNumber;
  432.    
  433.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  434. }
  435.