#include "stm32f1xx_hal.h"
#include "switches.h"
typedef enum {
PH_00 = 0, PH_10 = 2, PH_11 = 3, PH_01 = 1,
} eGreyCode;
typedef struct {
GPIO_TypeDef * GPIO;
uint16_t Pin;
} sGPIOPin;
volatile int dial_pos[MAX_DIALS];
volatile int dial_last[MAX_DIALS]; // previous debounced switch position
volatile int push_pos[MAX_PUSHBUTTONS];
volatile static int sw_newstate[MAX_SWITCHES]; //< debounced switch state
volatile static int sw_count[MAX_SWITCHES]; //< debounce counter
static const sGPIOPin sw_arr[MAX_SWITCHES] =
{ { SW1_I_GPIO_Port, SW1_I_Pin }, // these two pins used to encode SW1 phase
{ SW1_Q_GPIO_Port, SW1_Q_Pin }, // " SW1 phase
{ SW2_I_GPIO_Port, SW2_I_Pin }, // these two pins used to encode SW2 phase
{ SW2_Q_GPIO_Port, SW2_Q_Pin }, // " SW2 phase
{ SW1_PUSH_GPIO_Port, SW1_PUSH_Pin }, // two debounced switches
{ SW2_PUSH_GPIO_Port, SW2_PUSH_Pin }, };
// call this to setup switch states
void InitSwitches(void) {
int i;
for (i = 0; i < MAX_SWITCHES; i++) {
sw_newstate[i] = 0;
sw_count[i] = 0;
}
// reset the dial positions
dial_pos[0] = 0;
dial_pos[1] = 1;
}
// this gray encodes the dial .
void EncodeDial(int i) {
if (i < MAX_DIALS && i >= 0) {
int sw_index = i << 1;
// dial 0 uses switches 0 and 1
// dial 1 uses switches 2 and 3
int current = sw_newstate[sw_index] | (sw_newstate[sw_index + 1] << 1);
switch (dial_last[i]) {
case PH_00:
if (current == PH_10)
dial_pos[i]++;
if (current == PH_01)
dial_pos[i]--;
break;
case PH_10:
if (current == PH_11)
dial_pos[i]++;
if (current == PH_00)
dial_pos[i]--;
break;
case PH_11:
if (current == PH_01)
dial_pos[i]++;
if (current == PH_10)
dial_pos[i]--;
break;
case PH_01:
if (current == PH_00)
dial_pos[i]++;
if (current == PH_11)
dial_pos[i]--;
break;
default:
break;
}
dial_last[i] = current;
}
}
// this is the interrupt handler , dealling with the switches
void HandleSwitches(void)
{
int i;
for (i = 0; i < MAX_SWITCHES; i++)
{
int sw = HAL_GPIO_ReadPin(sw_arr[i].GPIO, sw_arr[i].Pin) == GPIO_PIN_RESET;
// bouncing, reset counter
if (sw != sw_newstate[i])
{
sw_count[i] = 0;
}
else
{
// count up to debounce time
if (sw_count[i] < DEBOUNCE_TIME)
{
sw_count[i]++;
if (sw_count[i] == DEBOUNCE_TIME)
{
sw_newstate[i] = sw;
}
}
}
}
// we now have debounced switch states in sw_newstate . So we can go ahead and feed some of the
EncodeDial(0);
EncodeDial(1);
}
void zero_dial(int dial) {
if(dial>=0 && dial < MAX_DIALS)
dial_pos[dial]= 0;
}