hid fw working as intended
This commit is contained in:
parent
0aa7b8871e
commit
1e6e8a2062
1 changed files with 169 additions and 32 deletions
|
|
@ -15,10 +15,38 @@ PCD_HandleTypeDef hpcd_USB_FS;
|
|||
|
||||
void SystemClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void key_matrix_select(int row);
|
||||
static int key_matrix_query(int debounce_time);
|
||||
static uint32_t poll_encoders(void);
|
||||
static uint32_t poll_keys(void);
|
||||
|
||||
enum keybits {
|
||||
KEYBITS_VOL_UP = 0x20,
|
||||
KEYBITS_VOL_DOWN = 0x40,
|
||||
/* These match up with the record descriptor in usbd_hid.c */
|
||||
KEYBITS_NEXT = 0x01,
|
||||
KEYBITS_PREV = 0x02,
|
||||
KEYBITS_STOP = 0x04,
|
||||
KEYBITS_PLAY_PAUSE = 0x08,
|
||||
KEYBITS_MUTE = 0x10,
|
||||
KEYBITS_VOL_UP = 0x20,
|
||||
KEYBITS_VOL_DOWN = 0x40,
|
||||
};
|
||||
|
||||
enum key_names {
|
||||
KEY_2 = 0,
|
||||
KEY_3 = 1,
|
||||
KEY_1 = 2,
|
||||
KEY_ENC = 3,
|
||||
KEY_4 = 4
|
||||
};
|
||||
|
||||
enum keymap_rows {
|
||||
KEYMAP_BOTTOM_LEFT_ENC = 0,
|
||||
KEYMAP_TOP_RIGHT_ENC = 1,
|
||||
};
|
||||
|
||||
enum key_matrix_params {
|
||||
KEY_MATRIX_ROWS = 5,
|
||||
KEY_MATRIX_COLS = 2,
|
||||
};
|
||||
|
||||
void sendKeybits(uint8_t keybits);
|
||||
|
|
@ -67,39 +95,69 @@ int main(void)
|
|||
TIM3->EGR = 1; // Generate an update event
|
||||
TIM3->CR1 = 1; // Enable the counter
|
||||
|
||||
uint16_t tim1_last = TIM1->CNT, tim3_last = TIM3->CNT;
|
||||
int vol_delta = 0;
|
||||
bool tx_vol_reset = 0;
|
||||
while (1) {
|
||||
uint16_t tim1_now = TIM1->CNT, tim3_now = TIM3->CNT;
|
||||
int16_t tim1_delta = (int16_t)(tim1_now - tim1_last);
|
||||
int16_t tim3_delta = (int16_t)(tim3_now - tim3_last);
|
||||
|
||||
vol_delta += tim3_delta - tim1_delta;
|
||||
|
||||
#define VOL_DELTA_INC 4
|
||||
uint8_t keybits = 0;
|
||||
if (!tx_vol_reset) {
|
||||
if (vol_delta >= VOL_DELTA_INC) {
|
||||
keybits |= KEYBITS_VOL_UP;
|
||||
vol_delta -= VOL_DELTA_INC;
|
||||
tx_vol_reset = 1;
|
||||
} else if (vol_delta <= -VOL_DELTA_INC) {
|
||||
keybits |= KEYBITS_VOL_DOWN;
|
||||
vol_delta += VOL_DELTA_INC;
|
||||
tx_vol_reset = 1;
|
||||
}
|
||||
} else {
|
||||
tx_vol_reset = 0;
|
||||
uint32_t keybits = poll_encoders();
|
||||
for (int i=0; i<10; i++) {
|
||||
keybits |= poll_keys();
|
||||
HAL_Delay(1);
|
||||
}
|
||||
sendKeybits(keybits);
|
||||
|
||||
tim1_last = tim1_now;
|
||||
tim3_last = tim3_now;
|
||||
HAL_Delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t poll_encoders() {
|
||||
static bool tx_vol_reset = 0;
|
||||
static uint16_t tim1_last = 0, tim3_last = 0; /* timers init to 0 */
|
||||
static int vol_delta = 0;
|
||||
|
||||
uint16_t tim1_now = TIM1->CNT, tim3_now = TIM3->CNT;
|
||||
int16_t tim1_delta = (int16_t)(tim1_now - tim1_last);
|
||||
int16_t tim3_delta = (int16_t)(tim3_now - tim3_last);
|
||||
|
||||
/* Gang both encoders */
|
||||
vol_delta += tim3_delta - tim1_delta;
|
||||
|
||||
#define VOL_DELTA_INC 4
|
||||
uint8_t keybits = 0;
|
||||
if (!tx_vol_reset) {
|
||||
/* Customize encoder action here */
|
||||
if (vol_delta >= VOL_DELTA_INC) {
|
||||
keybits |= KEYBITS_VOL_UP;
|
||||
vol_delta -= VOL_DELTA_INC;
|
||||
tx_vol_reset = 1;
|
||||
} else if (vol_delta <= -VOL_DELTA_INC) {
|
||||
keybits |= KEYBITS_VOL_DOWN;
|
||||
vol_delta += VOL_DELTA_INC;
|
||||
tx_vol_reset = 1;
|
||||
}
|
||||
} else {
|
||||
tx_vol_reset = 0;
|
||||
}
|
||||
|
||||
tim1_last = tim1_now;
|
||||
tim3_last = tim3_now;
|
||||
return keybits;
|
||||
}
|
||||
|
||||
static uint32_t poll_keys() {
|
||||
int debounce_time = 5; /* 5 * 10 ms loop timing increments */
|
||||
uint32_t val = key_matrix_query(debounce_time);
|
||||
uint32_t state = val&0xffff, edges = val>>16;
|
||||
uint32_t pressed = state & edges;
|
||||
(void)edges; /* unused */
|
||||
uint32_t keybits = 0;
|
||||
|
||||
if (pressed & (1 << KEY_3))
|
||||
keybits |= KEYBITS_PLAY_PAUSE;
|
||||
if (pressed & (1 << KEY_3 << KEY_MATRIX_ROWS))
|
||||
keybits |= KEYBITS_PREV;
|
||||
if (pressed & (1 << KEY_4 << KEY_MATRIX_ROWS))
|
||||
keybits |= KEYBITS_NEXT;
|
||||
if (pressed & (1 << KEY_ENC << KEY_MATRIX_ROWS))
|
||||
keybits |= KEYBITS_MUTE;
|
||||
|
||||
return keybits;
|
||||
}
|
||||
|
||||
const uint8_t _asciimap[128] =
|
||||
{
|
||||
|
|
@ -308,14 +366,93 @@ static void MX_GPIO_Init(void) {
|
|||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
GPIOA->MODER = 0x28000000 | (2<<(8*2)) | (2<<(9*2));
|
||||
GPIOB->MODER = (2<<(4*2)) | (2<<(5*2));
|
||||
GPIOA->PUPDR = 0x24000000 | (1<<(8*2)) | (1<<(9*2));
|
||||
/* Left encoder (SW2) A/B inputs: PA9/PA8 (TIM1 CH1/2)
|
||||
* Right encoder (SW7) A/B inputs: PB4/PB5 (TIM3 CH1/2)
|
||||
* Key matrix: PB2 -> encoder switches left/right
|
||||
* PB8 -> SW3/8
|
||||
* PB1 -> SW4/9
|
||||
* PA15 -> SW5/10
|
||||
* PA0 -> SW6/11
|
||||
* key matrix inputs: PA1/PA4
|
||||
*
|
||||
* Physical key layout:
|
||||
*
|
||||
* +------------|USB|------------+
|
||||
* | SW9 SW11 SW10 SW8 |
|
||||
* | SW2 SW7 |
|
||||
* | SW4 SW6 SW5 SW3 |
|
||||
* +-----------------------------+
|
||||
*
|
||||
* Logical key layout:
|
||||
*
|
||||
* +------------|USB|------------+
|
||||
* | KT1 KT2 KT3 KT4 |
|
||||
* | EL ER |
|
||||
* | KB1 KB2 KB3 KB4 |
|
||||
* +-----------------------------+
|
||||
*
|
||||
*/
|
||||
GPIOA->MODER = 0x28000000 | (2<<(8*2)) | (2<<(9*2)) | (1<<(15*2))| (1<<(0*2));
|
||||
GPIOB->MODER = (2<<(4*2)) | (2<<(5*2)) | (1<<(1*2)) | (1<<(2*2)) | (1<<(8*2));
|
||||
GPIOA->PUPDR = 0x24000000 | (1<<(8*2)) | (1<<(9*2)) | (2<<(1*2)) | (2<<(4*2));
|
||||
GPIOB->PUPDR = (1<<(4*2)) | (1<<(5*2));
|
||||
GPIOA->AFR[1]= 0x00000022;
|
||||
GPIOB->AFR[0]= 0x00110000;
|
||||
}
|
||||
|
||||
static void key_matrix_select(int row) {
|
||||
uint16_t bsrr_a = 0, bsrr_b = 0;
|
||||
/* A0 -> A15 -> B1 -> B2 -> B8 */
|
||||
switch (row) {
|
||||
case 0: bsrr_a = 1<<0; break;
|
||||
case 1: bsrr_a = 1<<15; break;
|
||||
case 2: bsrr_b = 1<<1; break;
|
||||
case 3: bsrr_b = 1<<2; break;
|
||||
case 4: bsrr_b = 1<<8; break;
|
||||
}
|
||||
uint16_t mask_a = (1<<15) | (1<<0), mask_b = (1<<1) | (1<<2) | (1<<8);
|
||||
/* Reset all pins except for selected pin */
|
||||
GPIOA->BSRR = (mask_a<<16) ^ ((bsrr_a<<16) | bsrr_a) ;
|
||||
GPIOB->BSRR = (mask_b<<16) ^ ((bsrr_b<<16) | bsrr_b) ;
|
||||
}
|
||||
|
||||
static int key_matrix_query(int debounce_time) {
|
||||
static int debounce_states[KEY_MATRIX_COLS][KEY_MATRIX_ROWS] = {0};
|
||||
static int key_matrix_row = -1;
|
||||
static uint32_t matrix_state = 0;
|
||||
uint32_t matrix_state_edges = 0;
|
||||
if (key_matrix_row < 0) { /* On first iteration just set outputs and return */
|
||||
key_matrix_row = 0;
|
||||
key_matrix_select(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int input = GPIOA->IDR;
|
||||
int pressed[KEY_MATRIX_COLS] = { input & (1<<4), input & (1<<1) };
|
||||
for (int i=0; i<KEY_MATRIX_COLS; i++) {
|
||||
if (debounce_states[i][key_matrix_row] > 0) {
|
||||
/* debounce timer running */
|
||||
debounce_states[i][key_matrix_row]--;
|
||||
} else {
|
||||
uint32_t bit = 1 << key_matrix_row << (KEY_MATRIX_ROWS * i);
|
||||
uint32_t old_matrix_state = matrix_state;
|
||||
if (pressed[i])
|
||||
matrix_state |= bit;
|
||||
else
|
||||
matrix_state &= ~bit;
|
||||
|
||||
uint32_t edge = old_matrix_state ^ matrix_state;
|
||||
if (edge)
|
||||
debounce_states[i][key_matrix_row] = debounce_time;
|
||||
matrix_state_edges |= edge;
|
||||
}
|
||||
}
|
||||
|
||||
key_matrix_row = (key_matrix_row+1) % KEY_MATRIX_ROWS;
|
||||
key_matrix_select(key_matrix_row);
|
||||
return (matrix_state_edges<<16) | matrix_state;
|
||||
}
|
||||
|
||||
void Error_Handler(void)
|
||||
{
|
||||
while(1){
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue