Subversion Repositories HomeAutomation

Rev

Rev 1286 | Rev 1288 | 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. To fix:
  62. Break out to a driver file
  63. */
  64. gesture parseBuffer(point *buffer, uint8_t startIndex, uint8_t endIndex)
  65. {
  66.     int16_t f1_k = 0, f3_tmp = 0, f4_tmp = 0, f5_tmp = 0, f9_tmp = 0;
  67.     uint8_t f7_tmp = 0, f7_sign = 0, f1_sign = 0, f3_yref = 0, xMin, xMax, yMin, yMax;
  68.     gesture functionData;
  69.     functionData.f1=0;
  70.     functionData.f7=0;
  71.    
  72.     /* Function 6 indicates the sign value of the y coordinates of the last point minus y coordinates of the first point */
  73.     functionData.f6 = CAN_MODULE_ENUM_TOUCH_GESTURE_F6_M;
  74.     if ((int16_t)buffer[endIndex].y - (int16_t)buffer[startIndex].y > 0)
  75.     {
  76.         functionData.f6 = CAN_MODULE_ENUM_TOUCH_GESTURE_F6_P;
  77.     }
  78.    
  79.     xMin = buffer[startIndex].x;
  80.     xMax = buffer[startIndex].x;
  81.     yMin = buffer[startIndex].y;
  82.     yMax = buffer[startIndex].y;
  83.     f3_yref = (buffer[startIndex].y + buffer[endIndex].y)/2;
  84.     f1_k = ((buffer[endIndex].y-buffer[startIndex].y)<<4)/(buffer[endIndex].x-buffer[startIndex].x);
  85.     f1_sign = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_U;
  86.  
  87.     for (uint8_t i = startIndex+1; i < endIndex-1; i++)
  88.     {
  89.         /* Function 1 indicates the number of intersection points between an input gesture g(x) and the straight line f(x)
  90.         which connects the first and last point of the gesture */
  91.         if (((f1_k*(buffer[i].x-buffer[0].x))>>4) + buffer[0].y < buffer[i].y)
  92.         {
  93.             if (f1_sign != CAN_MODULE_ENUM_TOUCH_GESTURE_F2_P)
  94.             {
  95.                 functionData.f1++;
  96.             }
  97.             f1_sign = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_P;
  98.         }
  99.         else
  100.         {
  101.             if (f1_sign != CAN_MODULE_ENUM_TOUCH_GESTURE_F2_M)
  102.             {
  103.                 functionData.f1++;
  104.             }
  105.             f1_sign = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_M;
  106.         }
  107.        
  108.         /* Function 3 indicates the sign value of area gap between g(x) and f(x) */
  109.         if (buffer[i].x > min(buffer[startIndex].x, buffer[endIndex].x) && buffer[i].x < max(buffer[startIndex].x, buffer[endIndex].x))
  110.         {
  111.             f3_tmp += f3_yref - (buffer[i].y + buffer[i-1].y)/2;
  112.         }
  113.        
  114.         /* find min an max of x and y */
  115.         if (xMin > buffer[i].x)
  116.         {
  117.             xMin = buffer[i].x;
  118.         }
  119.         if (xMax < buffer[i].x)
  120.         {
  121.             xMax = buffer[i].x;
  122.         }
  123.         if (yMin > buffer[i].y)
  124.         {
  125.             yMin = buffer[i].y;
  126.         }
  127.         if (yMax < buffer[i].y)
  128.         {
  129.             yMax = buffer[i].y;
  130.         }
  131.        
  132.         /* Function 4 represents the sign value of the sum of the x coordinates of all the points that constitute strokes
  133.         minus the x coordinates of the last point */
  134.         f4_tmp += (int16_t)buffer[i].x - (int16_t)buffer[endIndex].x;
  135.        
  136.         /* Function 5 checks the sign value of the sum of the x coordinates of all the points that constitute strokes
  137.         minus x coordinates of the first point */
  138.         f5_tmp += (int16_t)buffer[i].x - (int16_t)buffer[startIndex].x;
  139.     }
  140.    
  141.     /* Function 7 indicates the number of intersection points between an input gesture g(x) and all horizontal lines yi,
  142.     where i is between 0 and n, that constitute a gesture*/
  143.     for (uint8_t j = yMin; j < yMax-1; j++)
  144.     {
  145.         f7_tmp = 0xff;
  146.         f7_sign = 0;
  147.         for (uint8_t i = startIndex+1; i < endIndex-1; i++)
  148.         {
  149.             if (j > buffer[i].y)
  150.             {
  151.                 if (f7_sign != '+')
  152.                 {
  153.                     f7_tmp++;
  154.                 }
  155.                 f7_sign = '+';
  156.             }
  157.             else {
  158.                 if (f7_sign != '-')
  159.                 {
  160.                     f7_tmp++;
  161.                 }
  162.                 f7_sign = '-';
  163.             }
  164.         }
  165.         if (f7_tmp > functionData.f7)
  166.         {
  167.             functionData.f7 = f7_tmp;
  168.         }
  169.     }
  170.    
  171.     functionData.f1--;
  172.     /* Function 2 checks if the y coordinates of the points which exist between the intersection point and the last point are
  173.     greater than the y coordinates of the intersection point */
  174.     functionData.f2 = f1_sign;
  175.     if (functionData.f1 == 0)
  176.     {
  177.         functionData.f2 = CAN_MODULE_ENUM_TOUCH_GESTURE_F2_U;
  178.     }
  179.    
  180.     /* Function 3 indicates the sign value of area gap between g(x) and f(x) */
  181.     functionData.f3 = CAN_MODULE_ENUM_TOUCH_GESTURE_F3_P;
  182.     if (f3_tmp > 0)
  183.     {
  184.         functionData.f3 = CAN_MODULE_ENUM_TOUCH_GESTURE_F3_M;
  185.     }
  186.        
  187.     /* Function 9 represents the sign value of the multiplication of x coordinates of the first point and the last point
  188.     minus the mediate value of x coordinates of all the points */
  189.     f9_tmp = ((buffer[startIndex].x - (xMax+xMin)/2)*(buffer[endIndex].x - (xMax+xMin)/2));
  190.     functionData.f9 = CAN_MODULE_ENUM_TOUCH_GESTURE_F9_M;
  191.     if (f9_tmp > 0)
  192.     {
  193.         functionData.f9 = CAN_MODULE_ENUM_TOUCH_GESTURE_F9_P;
  194.     }
  195.    
  196.     /* Function 5 checks the sign value of the sum of the x coordinates of all the points that constitute strokes
  197.     minus x coordinates of the first point */
  198.     functionData.f5 = CAN_MODULE_ENUM_TOUCH_GESTURE_F5_M;
  199.     if (f5_tmp > 0)
  200.     {
  201.         functionData.f5 = CAN_MODULE_ENUM_TOUCH_GESTURE_F5_P;
  202.     }
  203.    
  204.     /* Function 4 represents the sign value of the sum of the x coordinates of all the points that constitute strokes
  205.     minus the x coordinates of the last point */
  206.     functionData.f4 = CAN_MODULE_ENUM_TOUCH_GESTURE_F4_M;
  207.     if (f4_tmp > 0)
  208.     {
  209.         functionData.f4 = CAN_MODULE_ENUM_TOUCH_GESTURE_F4_P;
  210.     }
  211.    
  212.     /* 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 */
  213.     functionData.f8 = CAN_MODULE_ENUM_TOUCH_GESTURE_F8_M;
  214.     if (xMin < min(buffer[startIndex].x,buffer[endIndex].x) || xMax > max(buffer[startIndex].x,buffer[endIndex].x))
  215.     {
  216.         functionData.f8 = CAN_MODULE_ENUM_TOUCH_GESTURE_F8_P;
  217.     }
  218.        
  219.     //printf("1%u2%c3%c4%c5%c6%c7%u8%c9%c\n", f1, f2, f3, f4, f5, f6, f7, f8, f9);
  220.  
  221.     return functionData;
  222. }
  223.  
  224.  
  225. void sns_Touch_Process(void)
  226. {
  227.    
  228.     if (Timer_Expired(sns_Touch_POLL_TIMER)) {
  229.         //StdCan_Msg_t txMsg;
  230.         gpio_set_in(sns_Touch_XPLUS);
  231.         gpio_set_pullup(sns_Touch_XPLUS);   //turn on pullup for x+
  232.         gpio_set_out(sns_Touch_YPLUS);
  233.         gpio_set_pin(sns_Touch_YPLUS);      //turn on 1 on y+
  234.         gpio_set_out(sns_Touch_YMINUS);
  235.         gpio_clr_pin(sns_Touch_YMINUS);     //turn on 0 on y-
  236.         #ifdef sns_Touch_SWITCH_XY
  237.             uint8_t adyval = ADC_Get(sns_Touch_TOUCHXAD)>>2;    //read x-
  238.         #else
  239.             uint8_t adxval = ADC_Get(sns_Touch_TOUCHXAD)>>2;    //read x-
  240.         #endif
  241.        
  242.         gpio_set_in(sns_Touch_YPLUS);
  243.         gpio_clr_pullup(sns_Touch_YPLUS);   //turn off pullup for y+
  244.         gpio_set_in(sns_Touch_YMINUS);
  245.         gpio_clr_pullup(sns_Touch_YMINUS);  //turn off pullup for y-
  246.         gpio_set_in(sns_Touch_XPLUS);
  247.         gpio_clr_pullup(sns_Touch_XPLUS);   //turn off pullup for x+
  248.        
  249.         gpio_set_in(sns_Touch_YPLUS);
  250.         gpio_set_pullup(sns_Touch_YPLUS);   //turn on pullup for y+
  251.         gpio_set_out(sns_Touch_XPLUS);
  252.         gpio_set_pin(sns_Touch_XPLUS);      //turn on 1 on x+
  253.         gpio_set_out(sns_Touch_XMINUS);
  254.         gpio_clr_pin(sns_Touch_XMINUS);     //turn on 0 on x-
  255.         #ifdef sns_Touch_SWITCH_XY
  256.             uint8_t adxval = ADC_Get(sns_Touch_TOUCHYAD)>>2;    //read y-
  257.         #else
  258.             uint8_t adyval = ADC_Get(sns_Touch_TOUCHYAD)>>2;    //read y-
  259.         #endif
  260.         gpio_set_in(sns_Touch_XPLUS);
  261.         gpio_clr_pullup(sns_Touch_XPLUS);   //turn off pullup for x+
  262.         gpio_set_in(sns_Touch_XMINUS);
  263.         gpio_clr_pullup(sns_Touch_XMINUS);  //turn off pullup for x-
  264.         gpio_set_in(sns_Touch_YPLUS);
  265.         gpio_clr_pullup(sns_Touch_YPLUS);   //turn off pullup for y+
  266.        
  267.        
  268.  
  269.         if (adyval < 0xf0 && adxval < 0xf0 )
  270.         {
  271. #ifdef sns_Touch_INVERT_Y
  272.             adyval = 255-adyval;
  273.         #endif
  274.         #ifdef sns_Touch_INVERT_X
  275.             adxval = 255-adxval;
  276.         #endif
  277.             pushStatus = 1;
  278.             uint8_t xdiff=0;
  279.             uint8_t ydiff=0;
  280.             if (rxbufidx > 0)
  281.             {
  282.                 xdiff = touchBuffer[rxbufidx-1].x - adxval;
  283.                 if (touchBuffer[rxbufidx-1].x < adxval)
  284.                 {
  285.                     xdiff = adxval - touchBuffer[rxbufidx-1].x;
  286.                 }
  287.                 ydiff = touchBuffer[rxbufidx-1].y - adyval;
  288.                 if (touchBuffer[rxbufidx-1].y < adyval)
  289.                 {
  290.                     ydiff = adyval - touchBuffer[rxbufidx-1].y;
  291.                 }
  292.             }
  293.             if (rxbufidx == 0 || (rxbufidx > 0 && xdiff+ydiff > 10))
  294.             {
  295.                 touchBuffer[rxbufidx].x = adxval;
  296.                 touchBuffer[rxbufidx].y = adyval;
  297.                 rxbufidx++;
  298.                 if (rxbufidx==sns_Touch_BUFFERSIZE)
  299.                 {
  300.                     rxbufidx=0;
  301.                 }
  302.  
  303.                 StdCan_Msg_t txMsg;
  304.                 StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  305.                 StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  306.                 txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  307.                 txMsg.Header.ModuleId = sns_Touch_ID;
  308.                 txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_RAW;
  309.                 txMsg.Length = 3;
  310.                 txMsg.Data[0] = CAN_MODULE_ENUM_TOUCH_RAW_STATUS_PRESSED;
  311.                 txMsg.Data[1] = adxval;
  312.                 txMsg.Data[2] = adyval;
  313.    
  314.                 StdCan_Put(&txMsg);
  315.             }
  316.             //printf("Y: %d X: %d\n", adyval, adxval);
  317.         }
  318.         else if (rxbufidx > 3)
  319.         {
  320.             if (pushStatus==1)
  321.             {
  322.                 pushStatus = 2;
  323.             }
  324.             //printf("Released %d\n", rxbufidx);
  325.             gesture functionData = parseBuffer(touchBuffer, 0, rxbufidx-1);
  326.            
  327.             StdCan_Msg_t txMsg;
  328.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  329.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  330.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  331.             txMsg.Header.ModuleId = sns_Touch_ID;
  332.             txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_GESTURE;
  333.             txMsg.Length = 3;
  334.             txMsg.Data[0] = functionData.f1;
  335.             txMsg.Data[1] = functionData.f7;
  336.             txMsg.Data[2] = functionData.f3<<7|functionData.f4<<6|functionData.f5<<5|functionData.f6<<4|functionData.f8<<3|functionData.f9<<2|functionData.f2;
  337.    
  338.             StdCan_Put(&txMsg);
  339.             /*for (uint8_t i = 0; i < rxbufidx; i++)
  340.             {
  341.                 printf("%3d ", touchBuffer[i].x);
  342.             }
  343.             printf("\n");
  344.             for (uint8_t i = 0; i < rxbufidx; i++)
  345.             {
  346.                 printf("%3d ", touchBuffer[i].y);
  347.             }
  348.             printf("\n");
  349.             */
  350.            
  351.             rxbufidx = 0;
  352.         }
  353.         else if (pushStatus==1)
  354.         {
  355.             pushStatus = 2;
  356.         }
  357.        
  358.         if (pushStatus == 2)
  359.         {
  360.             pushStatus = 0;
  361.            
  362.             StdCan_Msg_t txMsg;
  363.             StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  364.             StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  365.             txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  366.             txMsg.Header.ModuleId = sns_Touch_ID;
  367.             txMsg.Header.Command = CAN_MODULE_CMD_TOUCH_RAW;
  368.             txMsg.Length = 3;
  369.             txMsg.Data[0] = CAN_MODULE_ENUM_TOUCH_RAW_STATUS_RELEASED;
  370.             txMsg.Data[1] = adxval;
  371.             txMsg.Data[2] = adyval;
  372.  
  373.             StdCan_Put(&txMsg);
  374.         }
  375.     }
  376. }
  377.  
  378.  
  379. void sns_Touch_HandleMessage(StdCan_Msg_t *rxMsg)
  380. {
  381.     /*if (  StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_xyz && ///TODO: Change this to the actual class type
  382.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_FROM_OWNER &&
  383.         rxMsg->Header.ModuleType == CAN_MODULE_TYPE_xyz && ///TODO: Change this to the actual module type
  384.         rxMsg->Header.ModuleId == sns_Touch_ID)
  385.     {
  386.         switch (rxMsg->Header.Command)
  387.         {
  388.         case CAN_CMD_MODULE_DUMMY:
  389.         ///TODO: Do something dummy
  390.         break;
  391.         }
  392.     }*/
  393. }
  394.  
  395. void sns_Touch_List(uint8_t ModuleSequenceNumber)
  396. {
  397.     StdCan_Msg_t txMsg;
  398.    
  399.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  400.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  401.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_TOUCH;
  402.     txMsg.Header.ModuleId = sns_Touch_ID;
  403.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  404.     txMsg.Length = 6;
  405.  
  406.     txMsg.Data[0] = NODE_HW_ID_BYTE0;
  407.     txMsg.Data[1] = NODE_HW_ID_BYTE1;
  408.     txMsg.Data[2] = NODE_HW_ID_BYTE2;
  409.     txMsg.Data[3] = NODE_HW_ID_BYTE3;
  410.    
  411.     txMsg.Data[4] = NUMBER_OF_MODULES;
  412.     txMsg.Data[5] = ModuleSequenceNumber;
  413.    
  414.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  415. }
  416.