Rev 38 | Rev 47 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 38 | Rev 44 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | #include "stm32l1xx_hal.h" |
1 | #include "stm32l1xx_hal.h" |
| 2 | 2 | ||
| 3 | #include "switches.h" |
3 | #include "switches.h" |
| 4 | 4 | ||
| - | 5 | extern TIM_HandleTypeDef htim3; |
|
| - | 6 | extern TIM_HandleTypeDef htim9; |
|
| - | 7 | ||
| 5 | 8 | ||
| 6 | typedef enum { |
9 | typedef enum { |
| 7 | PH_00 = 0, PH_10 = 2, PH_11 = 3, PH_01 = 1, |
10 | PH_00 = 0, PH_10 = 2, PH_11 = 3, PH_01 = 1, |
| 8 | } eGreyCode; |
11 | } eGreyCode; |
| 9 | 12 | ||
| Line 11... | Line 14... | ||
| 11 | GPIO_TypeDef * GPIO; |
14 | GPIO_TypeDef * GPIO; |
| 12 | uint16_t Pin; |
15 | uint16_t Pin; |
| 13 | uint16_t Debounce; |
16 | uint16_t Debounce; |
| 14 | } sGPIOPin; |
17 | } sGPIOPin; |
| 15 | 18 | ||
| 16 | volatile int dial_pos[MAX_DIALS]; |
- | |
| 17 | volatile int dial_last[MAX_DIALS]; // previous debounced switch position |
- | |
| 18 | 19 | ||
| 19 | volatile int push_pos[MAX_PUSHBUTTONS]; |
20 | volatile int push_pos[MAX_PUSHBUTTONS]; |
| - | 21 | volatile int sw_count[MAX_PUSHBUTTONS]; //< debounced switch state |
|
| - | 22 | volatile int sw_newstate[MAX_PUSHBUTTONS]; //< debounced switch state |
|
| 20 | 23 | ||
| 21 | volatile static int sw_newstate[MAX_SWITCHES]; //< debounced switch state |
24 | volatile int dial_count[MAX_DIALS]; |
| - | 25 | volatile int dial_pos[MAX_DIALS]; |
|
| 22 | volatile static int sw_count[MAX_SWITCHES]; //< debounce counter |
26 | volatile int dial_last[MAX_DIALS]; // previous debounced switch position |
| 23 | 27 | ||
| 24 | static const sGPIOPin sw_arr[MAX_SWITCHES] = |
28 | static const sGPIOPin sw_arr[MAX_PUSHBUTTONS] = |
| 25 | { { SW1_I_GPIO_Port, SW1_I_Pin , 3}, // these two pins used to encode SW1 phase |
- | |
| 26 | { SW1_Q_GPIO_Port, SW1_Q_Pin, 3 }, // " SW1 phase |
- | |
| 27 | { SW2_I_GPIO_Port, SW2_I_Pin , 3}, // these two pins used to encode SW2 phase |
- | |
| 28 | { SW2_Q_GPIO_Port, SW2_Q_Pin , 3}, // " SW2 phase |
- | |
| - | 29 | { |
|
| 29 | { SW1_PUSH_GPIO_Port, SW1_PUSH_Pin, 10 }, // two debounced switches |
30 | { SW1_PUSH_GPIO_Port, SW1_PUSH_Pin, 10 }, // two debounced switches |
| 30 | { SW2_PUSH_GPIO_Port, SW2_PUSH_Pin, 10 }, }; |
31 | { SW2_PUSH_GPIO_Port, SW2_PUSH_Pin, 10 }, |
| - | 32 | }; |
|
| 31 | 33 | ||
| 32 | // call this to setup switch states |
34 | // call this to setup switch states |
| 33 | void InitSwitches(void) { |
35 | void InitSwitches(void) { |
| 34 | int i; |
36 | int i; |
| 35 | 37 | ||
| 36 | for (i = 0; i < MAX_SWITCHES; i++) { |
38 | for (i = 0; i < MAX_PUSHBUTTONS; i++) { |
| 37 | sw_newstate[i] = 0; |
39 | sw_newstate[i] = 0; |
| 38 | sw_count[i] = 0; |
40 | sw_count[i] = 0; |
| - | 41 | push_pos[i] = 0; |
|
| 39 | } |
42 | } |
| 40 | - | ||
| 41 | // reset the dial positions |
43 | // 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) { |
44 | for(i=0; i< MAX_DIALS; i++) |
| 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 | } |
45 | { |
| 81 | dial_last[i] = current; |
46 | dial_pos[i] = 0; |
| 82 | } |
47 | } |
| - | 48 | dial_count[0] = __HAL_TIM_GET_COUNTER(&htim9) >> 1; |
|
| - | 49 | dial_count[1] = __HAL_TIM_GET_COUNTER(&htim3) >> 1; |
|
| - | 50 | } |
|
| 83 | 51 | ||
| 84 | } |
- | |
| 85 | 52 | ||
| 86 | // this is the interrupt handler , dealling with the switches |
53 | // this is the interrupt handler , dealling with the switches |
| 87 | void HandleSwitches(void) |
54 | void HandleSwitches(void) |
| 88 | { |
55 | { |
| 89 | 56 | ||
| 90 | int i; |
57 | int i; |
| 91 | 58 | ||
| 92 | for (i = 0; i < MAX_SWITCHES; i++) |
59 | for (i = 0; i < MAX_PUSHBUTTONS; i++) |
| 93 | { |
60 | { |
| 94 | 61 | ||
| 95 | int sw = HAL_GPIO_ReadPin(sw_arr[i].GPIO, sw_arr[i].Pin) == GPIO_PIN_RESET; |
62 | int sw = HAL_GPIO_ReadPin(sw_arr[i].GPIO, sw_arr[i].Pin) == GPIO_PIN_RESET; |
| 96 | 63 | ||
| 97 | // bouncing, reset counter |
64 | // bouncing, reset counter |
| Line 111... | Line 78... | ||
| 111 | sw_newstate[i] = sw; |
78 | sw_newstate[i] = sw; |
| 112 | } |
79 | } |
| 113 | } |
80 | } |
| 114 | } |
81 | } |
| 115 | } |
82 | } |
| - | 83 | push_pos[0] =sw_newstate[0]; |
|
| 116 | // we now have debounced switch states in sw_newstate . So we can go ahead and feed some of the |
84 | push_pos[1] =sw_newstate[1]; |
| 117 | 85 | ||
| 118 | EncodeDial(0); |
- | |
| 119 | EncodeDial(1); |
- | |
| 120 | push_pos[0] =sw_newstate[4]; |
86 | int cnt0 = __HAL_TIM_GET_COUNTER(&htim9) >> 1; // counts 2 per step |
| 121 | push_pos[1] =sw_newstate[5]; |
87 | int cnt1 = __HAL_TIM_GET_COUNTER(&htim3) >> 1; // counts 2 per step |
| 122 | 88 | ||
| - | 89 | // always count up, or count down to zero but dont wrap |
|
| 123 | } |
90 | |
| - | 91 | if ((dial_pos[0] != 0) || (cnt0 > dial_count[0])) |
|
| - | 92 | dial_pos[0] += cnt0 - dial_count[0]; |
|
| - | 93 | dial_count[0] = cnt0; |
|
| - | 94 | ||
| - | 95 | if ((dial_pos[1] != 0) || (cnt1 > dial_count[1])) |
|
| - | 96 | dial_pos[1] += cnt1 - dial_count[1]; |
|
| - | 97 | dial_count[1] = cnt1; |
|
| 124 | 98 | ||
| 125 | void reset_dial(int dial,int value) { |
- | |
| 126 | if(dial>=0 && dial < MAX_DIALS) |
- | |
| 127 | dial_pos[dial]= value; |
- | |
| 128 | } |
99 | } |
| 129 | 100 | ||
| - | 101 | ||