Subversion Repositories HomeAutomation

Rev

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