Subversion Repositories DashDisplay

Rev

Rev 6 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include "stm32f1xx_hal.h"
  2.  
  3. #include "switches.h"
  4.  
  5.  
  6. typedef enum {
  7.         PH_00 = 0, PH_10 = 2, PH_11 = 3, PH_01 = 1,
  8. } eGreyCode;
  9.  
  10. typedef struct {
  11. GPIO_TypeDef * GPIO;
  12. uint16_t Pin;
  13. uint16_t Debounce;
  14. } sGPIOPin;
  15.  
  16. volatile int dial_pos[MAX_DIALS];
  17. volatile int dial_last[MAX_DIALS]; // previous debounced switch position
  18.  
  19. volatile int push_pos[MAX_PUSHBUTTONS];
  20.  
  21. volatile static int sw_newstate[MAX_SWITCHES]; //< debounced switch state
  22. volatile static int sw_count[MAX_SWITCHES]; //< debounce counter
  23.  
  24. static const sGPIOPin sw_arr[MAX_SWITCHES] =
  25.         { { SW1_I_GPIO_Port, SW1_I_Pin , 5}, // these two pins used to encode SW1 phase
  26.                         { SW1_Q_GPIO_Port, SW1_Q_Pin, 5 }, // "                             SW1 phase
  27.                         { SW2_I_GPIO_Port, SW2_I_Pin , 5}, // these two pins used to encode SW2 phase
  28.                         { SW2_Q_GPIO_Port, SW2_Q_Pin , 5}, // "                             SW2 phase
  29.                         { SW1_PUSH_GPIO_Port, SW1_PUSH_Pin, 10 }, // two debounced switches
  30. { SW2_PUSH_GPIO_Port, SW2_PUSH_Pin, 10 }, };
  31.  
  32. // call this to setup switch states
  33. void InitSwitches(void) {
  34. int i;
  35.  
  36. for (i = 0; i < MAX_SWITCHES; i++) {
  37.         sw_newstate[i] = 0;
  38.         sw_count[i] = 0;
  39. }
  40.  
  41. // reset the dial positions
  42. dial_pos[0] = 0;
  43. dial_pos[1] = 0;
  44. }
  45.  
  46. // this gray encodes the dial , but you cannot turn the switch back below 0
  47. void EncodeDial(int i) {
  48. if (i < MAX_DIALS && i >= 0) {
  49.         int sw_index = i << 1;
  50.         // dial 0 uses switches 0 and 1
  51.         // dial 1 uses switches 2 and 3
  52.         int current = sw_newstate[sw_index] | (sw_newstate[sw_index + 1] << 1);
  53.         switch (dial_last[i]) {
  54.         case PH_00:
  55.                 if (current == PH_10)
  56.                         dial_pos[i]++;
  57.                 if (current == PH_01 && dial_pos[i]>0)
  58.                         dial_pos[i]--;
  59.                 break;
  60.         case PH_10:
  61.                 if (current == PH_11)
  62.                         dial_pos[i]++;
  63.                 if (current == PH_00 && dial_pos[i]>0)
  64.                         dial_pos[i]--;
  65.                 break;
  66.         case PH_11:
  67.                 if (current == PH_01)
  68.                         dial_pos[i]++;
  69.                 if (current == PH_10 && dial_pos[i]>0)
  70.                         dial_pos[i]--;
  71.                 break;
  72.         case PH_01:
  73.                 if (current == PH_00)
  74.                         dial_pos[i]++;
  75.                 if (current == PH_11 && dial_pos[i]>0)
  76.                         dial_pos[i]--;
  77.                 break;
  78.         default:
  79.                 break;
  80.         }
  81.         dial_last[i] = current;
  82. }
  83.  
  84. }
  85.  
  86. // this is the interrupt handler , dealling with the switches
  87. void HandleSwitches(void)
  88. {
  89.  
  90.   int i;
  91.  
  92.   for (i = 0; i < MAX_SWITCHES; i++)
  93.   {
  94.  
  95.     int sw = HAL_GPIO_ReadPin(sw_arr[i].GPIO, sw_arr[i].Pin) == GPIO_PIN_RESET;
  96.  
  97.     // bouncing, reset counter
  98.     if (sw == sw_newstate[i])
  99.     {
  100.           sw_count[i] = 0;
  101.     }
  102.     else
  103.     {
  104.         // count up to debounce time
  105.           if (sw_count[i] < sw_arr[i].Debounce)
  106.           {
  107.                 sw_count[i]++;
  108.  
  109.                 if (sw_count[i] == sw_arr[i].Debounce)
  110.                 {
  111.                         sw_newstate[i] = sw;
  112.                 }
  113.          }
  114.     }
  115.   }
  116. // we now have debounced switch states in sw_newstate . So we can go ahead and feed some of the
  117.  
  118.   EncodeDial(0);
  119.   EncodeDial(1);
  120.   push_pos[0] =sw_newstate[4];
  121.   push_pos[1] =sw_newstate[5];
  122.  
  123. }
  124.  
  125. void reset_dial(int dial,int value) {
  126.   if(dial>=0 && dial < MAX_DIALS)
  127.         dial_pos[dial]= value;
  128. }
  129.  
  130.