Subversion Repositories HomeAutomation

Rev

Rev 1384 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. #include "sns_rotary.h"
  3. uint8_t rotaryEncoder_Position = 0;
  4. uint8_t rotaryEncoder_Position_old = 0;
  5. uint8_t rotaryEncoder_Button_Position = 0;
  6. uint8_t rotaryEncoder_Button_Position_old = 0;
  7. uint8_t FlagBlockTransmission = 0;
  8.  
  9.  
  10. void sns_rotary_pcint_callback(uint8_t id, uint8_t status)
  11. {
  12.     uint8_t rot_data = 0;
  13.     static uint8_t rot_lastdir = 0, rot_laststate = 0;
  14.  
  15.     //Take care of button push
  16.     if (gpio_get_state(ROTARY_BTN) != rotaryEncoder_Button_Position){ //The buttonstate has changed!
  17.         rotaryEncoder_Button_Position = gpio_get_state(ROTARY_BTN);
  18.     }
  19.     //Take care of rotary encoder movement
  20.     if(gpio_get_state(ROTARY_CH1)){
  21.         rot_data |= 0x01;
  22.     }
  23.     if(gpio_get_state(ROTARY_CH2)){
  24.         rot_data |= 0x02;
  25.     }
  26.  
  27.     if( rot_data==0 || rot_data==3 ){ // Are both signals high or low?
  28.         if( rot_data==0 && rot_laststate!=rot_data ){ // Are both signals low? In that case we are finished with one turn and should print out the direction it went.
  29.             if( rot_lastdir&0x01 ){
  30.             #if ROTARY_CHx_INVERT_DIRECTION==1
  31.                 rotaryEncoder_Position--;   // Moving clockwise
  32.             #else
  33.                 rotaryEncoder_Position++;   // Moving counter clockwise
  34.             #endif
  35.             }else{
  36.             #if ROTARY_CHx_INVERT_DIRECTION==1
  37.                 rotaryEncoder_Position++;   // Moving counter clockwise
  38.             #else
  39.                 rotaryEncoder_Position--;   // Moving clockwise
  40.             #endif
  41.             }
  42.         }
  43.         rot_laststate = rot_data;
  44.     } else { // No, only one of the signals are high. We can use this to find out what direction we are moving.
  45.         rot_lastdir = rot_data;
  46.     }
  47. }
  48.  
  49. void BlockTransmission_callback(uint8_t timer)
  50. {
  51.     FlagBlockTransmission = 0;
  52. }
  53.  
  54. #if ROTARY_SECOND_ENABLE != 0
  55. uint8_t rotaryEncoder_second_Position = 0;
  56. uint8_t rotaryEncoder_second_Position_old = 0;
  57. uint8_t rotaryEncoder_second_Button_Position = 0;
  58. uint8_t rotaryEncoder_second_Button_Position_old = 0;
  59. uint8_t FlagBlockTransmission_second = 0;
  60.  
  61. void sns_rotary_pcint_second_callback(uint8_t id, uint8_t status)
  62. {
  63.     uint8_t rot_data = 0;
  64.     static uint8_t rot_lastdir = 0, rot_laststate = 0;
  65.  
  66.     //Take care of button push
  67.     if (gpio_get_state(ROTARY_BTN_SECOND) != rotaryEncoder_second_Button_Position){ //The buttonstate has changed!
  68.         rotaryEncoder_second_Button_Position = gpio_get_state(ROTARY_BTN_SECOND);
  69.     }
  70.     //Take care of rotary encoder movement
  71.     if(gpio_get_state(ROTARY_CH1_SECOND)){
  72.         rot_data |= 0x01;
  73.     }
  74.     if(gpio_get_state(ROTARY_CH2_SECOND)){
  75.         rot_data |= 0x02;
  76.     }
  77.  
  78.     if( rot_data==0 || rot_data==3 ){ // Are both signals high or low?
  79.         if( rot_data==0 && rot_laststate!=rot_data ){ // Are both signals low? In that case we are finished with one turn and should print out the direction it went.
  80.             if( rot_lastdir&0x01 ){
  81.             #if ROTARY_CHx_INVERT_DIRECTION_SECOND==1
  82.                 rotaryEncoder_second_Position--;    // Moving clockwise
  83.             #else
  84.                 rotaryEncoder_second_Position++;    // Moving counter clockwise
  85.             #endif
  86.             }else{
  87.             #if ROTARY_CHx_INVERT_DIRECTION_SECOND==1
  88.                 rotaryEncoder_second_Position++;    // Moving counter clockwise
  89.             #else
  90.                 rotaryEncoder_second_Position--;    // Moving clockwise
  91.             #endif
  92.             }
  93.         }
  94.         rot_laststate = rot_data;
  95.     } else { // No, only one of the signals are high. We can use this to find out what direction we are moving.
  96.         rot_lastdir = rot_data;
  97.     }
  98. }
  99.  
  100. void BlockTransmission_second_callback(uint8_t timer)
  101. {
  102.     FlagBlockTransmission_second = 0;
  103. }
  104. #endif
  105. void sns_rotary_Init(void)
  106. {
  107.     /*
  108.      * Initialize rotaryencoders and buttons
  109.      */
  110.     rotaryEncoder_Position = 0; // Set initial value to 0
  111.     rotaryEncoder_Position_old = 0; // Set initial value to 0
  112.  
  113.     gpio_set_in(ROTARY_CH1);    // Set to input
  114.     gpio_set_pin(ROTARY_CH1);   // Enable pull-up
  115.     gpio_set_in(ROTARY_CH2);    // Set to input
  116.     gpio_set_pin(ROTARY_CH2);   // Enable pull-up
  117.     gpio_set_in(ROTARY_BTN);    // Set to input
  118.     gpio_set_pin(ROTARY_BTN);   // Enable pull-up
  119.  
  120.     // Enable IO-pin interrupt
  121.     Pcint_SetCallbackPin(sns_rotary_PCINT_CH1, ROTARY_CH1, &sns_rotary_pcint_callback);
  122.     Pcint_SetCallbackPin(sns_rotary_PCINT_CH2, ROTARY_CH2, &sns_rotary_pcint_callback);
  123.     Pcint_SetCallbackPin(sns_rotary_PCINT_BTN, ROTARY_BTN, &sns_rotary_pcint_callback);
  124.  
  125. #if ROTARY_SECOND_ENABLE != 0
  126.     rotaryEncoder_second_Position = 0;  // Set initial value to 0
  127.     rotaryEncoder_second_Position_old = 0;  // Set initial value to 0
  128.  
  129.     gpio_set_in(ROTARY_CH1_SECOND); // Set to input
  130.     gpio_set_pin(ROTARY_CH1_SECOND);    // Enable pull-up
  131.     gpio_set_in(ROTARY_CH2_SECOND); // Set to input
  132.     gpio_set_pin(ROTARY_CH2_SECOND);    // Enable pull-up
  133.     gpio_set_in(ROTARY_BTN_SECOND); // Set to input
  134.     gpio_set_pin(ROTARY_BTN_SECOND);    // Enable pull-up
  135.  
  136.     // Enable IO-pin interrupt
  137.     Pcint_SetCallbackPin(sns_rotary_PCINT_CH1_SECOND, ROTARY_CH1_SECOND, &sns_rotary_pcint_second_callback);
  138.     Pcint_SetCallbackPin(sns_rotary_PCINT_CH2_SECOND, ROTARY_CH2_SECOND, &sns_rotary_pcint_second_callback);
  139.     Pcint_SetCallbackPin(sns_rotary_PCINT_BTN_SECOND, ROTARY_BTN_SECOND, &sns_rotary_pcint_second_callback);
  140. #endif
  141.  
  142. }
  143.  
  144. void sns_rotary_Process(void)
  145. {
  146.     if (rotaryEncoder_Position != rotaryEncoder_Position_old && !FlagBlockTransmission)
  147.     {
  148.         FlagBlockTransmission=1;
  149.         Timer_SetTimeout(sns_rotary_TIMER, sns_rotary_SEND_DELAY, TimerTypeOneShot, &BlockTransmission_callback);
  150.         StdCan_Msg_t txMsg;
  151.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  152.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  153.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ROTARY;
  154.         txMsg.Header.ModuleId = sns_rotary_ID;
  155.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_ROTARY_SWITCH;
  156.         txMsg.Length = 4;
  157.         txMsg.Data[0] = 0x01;
  158.         if ((rotaryEncoder_Position > rotaryEncoder_Position_old || (rotaryEncoder_Position_old==0xff && rotaryEncoder_Position==0x00)) && !(rotaryEncoder_Position_old==0x00 && rotaryEncoder_Position==0xff)) {
  159.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_ROTARY_SWITCH_DIRECTION_CLOCKWISE; //Clockwice
  160.             txMsg.Data[2] = rotaryEncoder_Position-rotaryEncoder_Position_old;
  161.             if (txMsg.Data[2]>127)
  162.             {
  163.                 txMsg.Data[2] = 256-txMsg.Data[2];
  164.             }
  165.         } else {
  166.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_ROTARY_SWITCH_DIRECTION_COUNTERCLOCKWISE;  //Counter Clockwice
  167.             txMsg.Data[2] = rotaryEncoder_Position_old-rotaryEncoder_Position;
  168.             if (txMsg.Data[2]>127)
  169.             {
  170.                 txMsg.Data[2] = 256-txMsg.Data[2];
  171.             }
  172.         }
  173.         txMsg.Data[3] = rotaryEncoder_Position;
  174.  
  175.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  176.         rotaryEncoder_Position_old = rotaryEncoder_Position;
  177.     }
  178.     if (rotaryEncoder_Button_Position != rotaryEncoder_Button_Position_old)
  179.     {
  180.         rotaryEncoder_Button_Position_old = rotaryEncoder_Button_Position;
  181.         StdCan_Msg_t txMsg;
  182.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  183.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  184.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ROTARY;
  185.         txMsg.Header.ModuleId = sns_rotary_ID;
  186.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_BUTTON;
  187.         txMsg.Length = 2;
  188.         txMsg.Data[0] = 0x01;
  189. #if ROTARY_BTN_INVERT_OUTPUT==1
  190.         if (rotaryEncoder_Button_Position_old)
  191.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_RELEASED;
  192.         else
  193.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_PRESSED;
  194.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  195. #else
  196.         if (rotaryEncoder_Button_Position_old)
  197.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_PRESSED;
  198.         else
  199.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_RELEASED;
  200.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  201. #endif
  202.     }
  203. #if ROTARY_SECOND_ENABLE != 0
  204.     if (rotaryEncoder_second_Position != rotaryEncoder_second_Position_old && !FlagBlockTransmission_second)
  205.     {
  206.         FlagBlockTransmission_second=1;
  207.         Timer_SetTimeout(sns_rotary_TIMER_second, sns_rotary_SEND_DELAY, TimerTypeOneShot, &BlockTransmission_second_callback);
  208.         StdCan_Msg_t txMsg;
  209.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  210.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  211.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ROTARY;
  212.         txMsg.Header.ModuleId = sns_rotary_ID;
  213.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_ROTARY_SWITCH;
  214.         txMsg.Length = 4;
  215.         txMsg.Data[0] = 0x02;
  216.         if ((rotaryEncoder_second_Position > rotaryEncoder_second_Position_old || (rotaryEncoder_second_Position_old==0xff && rotaryEncoder_second_Position==0x00)) && !(rotaryEncoder_second_Position_old==0x00 && rotaryEncoder_second_Position==0xff)) {
  217.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_ROTARY_SWITCH_DIRECTION_CLOCKWISE; //Clockwice
  218.             txMsg.Data[2] = rotaryEncoder_second_Position-rotaryEncoder_second_Position_old;
  219.             if (txMsg.Data[2]>127)
  220.             {
  221.                 txMsg.Data[2] = 256-txMsg.Data[2];
  222.             }
  223.         } else {
  224.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_ROTARY_SWITCH_DIRECTION_COUNTERCLOCKWISE;  //Counter Clockwice
  225.             txMsg.Data[2] = rotaryEncoder_second_Position_old-rotaryEncoder_second_Position;
  226.             if (txMsg.Data[2]>127)
  227.             {
  228.                 txMsg.Data[2] = 256-txMsg.Data[2];
  229.             }
  230.         }
  231.         txMsg.Data[3] = rotaryEncoder_second_Position;
  232.  
  233.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  234.         rotaryEncoder_second_Position_old = rotaryEncoder_second_Position;
  235.     }
  236.     if (rotaryEncoder_second_Button_Position != rotaryEncoder_second_Button_Position_old)
  237.     {
  238.         rotaryEncoder_second_Button_Position_old = rotaryEncoder_second_Button_Position;
  239.         StdCan_Msg_t txMsg;
  240.         StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS);
  241.         StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  242.         txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ROTARY;
  243.         txMsg.Header.ModuleId = sns_rotary_ID;
  244.         txMsg.Header.Command = CAN_MODULE_CMD_PHYSICAL_BUTTON;
  245.         txMsg.Length = 2;
  246.         txMsg.Data[0] = 0x02;
  247. #if ROTARY_BTN_INVERT_OUTPUT_SECOND==1
  248.         if (rotaryEncoder_second_Button_Position_old)
  249.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_RELEASED;
  250.         else
  251.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_PRESSED;
  252.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  253. #else
  254.         if (rotaryEncoder_second_Button_Position_old)
  255.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_PRESSED;
  256.         else
  257.             txMsg.Data[1] = CAN_MODULE_ENUM_PHYSICAL_BUTTON_STATUS_RELEASED;
  258.         while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  259. #endif
  260.     }
  261.  
  262. #endif
  263.  
  264. }
  265.  
  266. void sns_rotary_HandleMessage(StdCan_Msg_t *rxMsg)
  267. {
  268.  
  269. }
  270.  
  271. void sns_rotary_List(uint8_t ModuleSequenceNumber)
  272. {
  273.     StdCan_Msg_t txMsg;
  274.  
  275.     StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_SNS); ///TODO: Change this to the actual class type
  276.     StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
  277.     txMsg.Header.ModuleType = CAN_MODULE_TYPE_SNS_ROTARY; ///TODO: Change this to the actual module type
  278.     txMsg.Header.ModuleId = sns_rotary_ID;
  279.     txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
  280.     txMsg.Length = 6;
  281.  
  282.     uint32_t HwId=BIOS_GetHwId();
  283.     txMsg.Data[0] = HwId&0xff;
  284.     txMsg.Data[1] = (HwId>>8)&0xff;
  285.     txMsg.Data[2] = (HwId>>16)&0xff;
  286.     txMsg.Data[3] = (HwId>>24)&0xff;
  287.  
  288.     txMsg.Data[4] = NUMBER_OF_MODULES;
  289.     txMsg.Data[5] = ModuleSequenceNumber;
  290.  
  291.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  292. }
  293.