Add Dip Switch as a core feature (#6140)
* Add Dip Switches as a core feature * Add documentation for Dip Switch feature * Update Preonic Rev3 to use new feature and remove custom matrix * Apply suggestions from code review Co-Authored-By: noroadsleft <18669334+noroadsleft@users.noreply.github.com> * Remove custom matrix line completely Rather than just disabling it Co-Authored-By: fauxpark <fauxpark@gmail.com> * DIP changes Co-Authored-By: fauxpark <fauxpark@gmail.com> * Use better check for DIP Switch configuration * Add to show features * Add bitmask callback for dip switch * Fix OLKB Boards dip switch config * Update docs to include bitmask example * Fix comments/documentation Co-Authored-By: fauxpark <fauxpark@gmail.com> * Fix issues with docs and use example from @tuzonghua * Fix wording Co-Authored-By: fauxpark <fauxpark@gmail.com> * Fix example to use proper formatting Bad, BAAAAAAD drashna!!! * Handle dip switch initialization betterbetter_chibios_wait
parent
9f46606dff
commit
dab4967f1b
@ -0,0 +1,90 @@ |
||||
# DIP Switches |
||||
|
||||
DIP switches are supported by adding this to your `rules.mk`: |
||||
|
||||
DIP_SWITCH_ENABLE = yes |
||||
|
||||
and this to your `config.h`: |
||||
|
||||
```c |
||||
#define DIP_SWITCH_PINS { B14, A15, A10, B9 } |
||||
``` |
||||
|
||||
## Callbacks |
||||
|
||||
The callback functions can be inserted into your `<keyboard>.c`: |
||||
|
||||
```c |
||||
void dip_switch_update_kb(uint8_t index, bool active) { |
||||
dip_switch_update_user(index, active); |
||||
} |
||||
``` |
||||
|
||||
|
||||
or `keymap.c`: |
||||
|
||||
```c |
||||
void dip_switch_update_user(uint8_t index, bool active) { |
||||
switch (index) { |
||||
case 0: |
||||
if(active) { audio_on(); } else { audio_off(); } |
||||
break; |
||||
case 1: |
||||
if(active) { clicky_on(); } else { clicky_off(); } |
||||
break; |
||||
case 2: |
||||
if(active) { music_on(); } else { music_off(); } |
||||
break; |
||||
case 3: |
||||
if (active) { |
||||
#ifdef AUDIO_ENABLE |
||||
PLAY_SONG(plover_song); |
||||
#endif |
||||
layer_on(_PLOVER); |
||||
} else { |
||||
#ifdef AUDIO_ENABLE |
||||
PLAY_SONG(plover_gb_song); |
||||
#endif |
||||
layer_off(_PLOVER); |
||||
} |
||||
break; |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Additionally, we support bit mask functions which allow for more complex handling. |
||||
|
||||
|
||||
```c |
||||
void dip_switch_update_mask_kb(uint32_t state) { |
||||
dip_switch_update_mask_user(state); |
||||
} |
||||
``` |
||||
|
||||
|
||||
or `keymap.c`: |
||||
|
||||
```c |
||||
void dip_switch_update_mask_user(uint32_t state) { |
||||
if (state & (1UL<<0) && state & (1UL<<1)) { |
||||
layer_on(_ADJUST); // C on esc |
||||
} else { |
||||
layer_off(_ADJUST); |
||||
} |
||||
if (state & (1UL<<0)) { |
||||
layer_on(_TEST_A); // A on ESC |
||||
} else { |
||||
layer_off(_TEST_A); |
||||
} |
||||
if (state & (1UL<<1)) { |
||||
layer_on(_TEST_B); // B on esc |
||||
} else { |
||||
layer_off(_TEST_B); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
|
||||
## Hardware |
||||
|
||||
One side of the DIP switch should be wired directly to the pin on the MCU, and the other side to ground. It should not matter which side is connected to which, as it should be functionally the same. |
@ -1,176 +0,0 @@ |
||||
#include <stdint.h> |
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include "hal.h" |
||||
#include "timer.h" |
||||
#include "wait.h" |
||||
#include "printf.h" |
||||
#include "backlight.h" |
||||
#include "matrix.h" |
||||
#include "action.h" |
||||
#include "keycode.h" |
||||
#include <string.h> |
||||
|
||||
/*
|
||||
* col: { B11, B10, B2, B1, A7, B0 } |
||||
* row: { A10, A9, A8, B15, C13, C14, C15, A2 } |
||||
*/ |
||||
/* matrix state(1:on, 0:off) */ |
||||
static matrix_row_t matrix[MATRIX_ROWS]; |
||||
static matrix_row_t matrix_debouncing[MATRIX_COLS]; |
||||
static bool debouncing = false; |
||||
static uint16_t debouncing_time = 0; |
||||
|
||||
static bool dip_switch[4] = {0, 0, 0, 0}; |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_user(void) {} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_user(void) {} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_kb(void) { |
||||
matrix_init_user(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_kb(void) { |
||||
matrix_scan_user(); |
||||
} |
||||
|
||||
void matrix_init(void) { |
||||
printf("matrix init\n"); |
||||
//debug_matrix = true;
|
||||
|
||||
// dip switch setup
|
||||
palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP); |
||||
palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP); |
||||
palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP); |
||||
palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP); |
||||
|
||||
// actual matrix setup
|
||||
palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL); |
||||
|
||||
palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN); |
||||
|
||||
|
||||
memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t)); |
||||
memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_row_t)); |
||||
|
||||
|
||||
matrix_init_quantum(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void dip_update(uint8_t index, bool active) { } |
||||
|
||||
bool last_dip_switch[4] = {0}; |
||||
|
||||
uint8_t matrix_scan(void) { |
||||
// dip switch
|
||||
dip_switch[0] = !palReadPad(GPIOB, 14); |
||||
dip_switch[1] = !palReadPad(GPIOA, 15); |
||||
dip_switch[2] = !palReadPad(GPIOA, 10); |
||||
dip_switch[3] = !palReadPad(GPIOB, 9); |
||||
for (uint8_t i = 0; i < 4; i++) { |
||||
if (last_dip_switch[i] ^ dip_switch[i]) |
||||
dip_update(i, dip_switch[i]); |
||||
} |
||||
memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch)); |
||||
|
||||
// actual matrix
|
||||
for (int col = 0; col < MATRIX_COLS; col++) { |
||||
matrix_row_t data = 0; |
||||
|
||||
// strobe col { B11, B10, B2, B1, A7, B0 }
|
||||
switch (col) { |
||||
case 0: palSetPad(GPIOB, 11); break; |
||||
case 1: palSetPad(GPIOB, 10); break; |
||||
case 2: palSetPad(GPIOB, 2); break; |
||||
case 3: palSetPad(GPIOB, 1); break; |
||||
case 4: palSetPad(GPIOA, 7); break; |
||||
case 5: palSetPad(GPIOB, 0); break; |
||||
} |
||||
|
||||
// need wait to settle pin state
|
||||
wait_us(20); |
||||
|
||||
// read row data { A10, A9, A8, B15, C13, C14, C15, A2 }
|
||||
data = ( |
||||
(palReadPad(GPIOA, 10) << 0 ) | |
||||
(palReadPad(GPIOA, 9) << 1 ) | |
||||
(palReadPad(GPIOA, 8) << 2 ) | |
||||
(palReadPad(GPIOB, 15) << 3 ) | |
||||
(palReadPad(GPIOC, 13) << 4 ) | |
||||
(palReadPad(GPIOC, 14) << 5 ) | |
||||
(palReadPad(GPIOC, 15) << 6 ) | |
||||
(palReadPad(GPIOA, 2) << 7 ) |
||||
); |
||||
|
||||
// unstrobe col { B11, B10, B2, B1, A7, B0 }
|
||||
switch (col) { |
||||
case 0: palClearPad(GPIOB, 11); break; |
||||
case 1: palClearPad(GPIOB, 10); break; |
||||
case 2: palClearPad(GPIOB, 2); break; |
||||
case 3: palClearPad(GPIOB, 1); break; |
||||
case 4: palClearPad(GPIOA, 7); break; |
||||
case 5: palClearPad(GPIOB, 0); break; |
||||
} |
||||
|
||||
if (matrix_debouncing[col] != data) { |
||||
matrix_debouncing[col] = data; |
||||
debouncing = true; |
||||
debouncing_time = timer_read(); |
||||
} |
||||
} |
||||
|
||||
if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { |
||||
for (int row = 0; row < MATRIX_ROWS; row++) { |
||||
matrix[row] = 0; |
||||
for (int col = 0; col < MATRIX_COLS; col++) { |
||||
matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col); |
||||
} |
||||
} |
||||
debouncing = false; |
||||
} |
||||
|
||||
matrix_scan_quantum(); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
bool matrix_is_on(uint8_t row, uint8_t col) { |
||||
return (matrix[row] & (1<<col)); |
||||
} |
||||
|
||||
matrix_row_t matrix_get_row(uint8_t row) { |
||||
return matrix[row]; |
||||
} |
||||
|
||||
void matrix_print(void) { |
||||
printf("\nr/c 01234567\n"); |
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
||||
printf("%X0: ", row); |
||||
matrix_row_t data = matrix_get_row(row); |
||||
for (int col = 0; col < MATRIX_COLS; col++) { |
||||
if (data & (1<<col)) |
||||
printf("1"); |
||||
else |
||||
printf("0"); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
} |
@ -1,187 +0,0 @@ |
||||
#include <stdint.h> |
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
#include "hal.h" |
||||
#include "timer.h" |
||||
#include "wait.h" |
||||
#include "printf.h" |
||||
#include "backlight.h" |
||||
#include "matrix.h" |
||||
#include "action.h" |
||||
#include "keycode.h" |
||||
#include <string.h> |
||||
|
||||
/*
|
||||
* col: { B11, B10, B2, B1, A7, B0 } |
||||
* row: { A10, A9, A8, B15, C13, C14, C15, A2 } |
||||
*/ |
||||
/* matrix state(1:on, 0:off) */ |
||||
static matrix_row_t matrix[MATRIX_ROWS]; |
||||
static matrix_col_t matrix_debouncing[MATRIX_COLS]; |
||||
static bool debouncing = false; |
||||
static uint16_t debouncing_time = 0; |
||||
|
||||
static bool dip_switch[4] = {0, 0, 0, 0}; |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_user(void) {} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_user(void) {} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_kb(void) { |
||||
matrix_init_user(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_kb(void) { |
||||
matrix_scan_user(); |
||||
} |
||||
|
||||
void matrix_init(void) { |
||||
printf("matrix init\n"); |
||||
//debug_matrix = true;
|
||||
|
||||
// dip switch setup
|
||||
palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP); |
||||
palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP); |
||||
palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP); |
||||
palSetPadMode(GPIOB, 9, PAL_MODE_INPUT_PULLUP); |
||||
|
||||
// actual matrix setup
|
||||
palSetPadMode(GPIOB, 11, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 10, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOA, 7, PAL_MODE_OUTPUT_PUSHPULL); |
||||
palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL); |
||||
|
||||
palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOC, 13, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOC, 14, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOC, 15, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 2, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 3, PAL_MODE_INPUT_PULLDOWN); |
||||
palSetPadMode(GPIOA, 6, PAL_MODE_INPUT_PULLDOWN); |
||||
|
||||
|
||||
memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t)); |
||||
memset(matrix_debouncing, 0, MATRIX_COLS * sizeof(matrix_col_t)); |
||||
|
||||
|
||||
matrix_init_quantum(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void dip_update(uint8_t index, bool active) { } |
||||
|
||||
__attribute__ ((weak)) |
||||
void encoder_update(bool clockwise) { } |
||||
|
||||
bool last_dip_switch[4] = {0}; |
||||
|
||||
#ifndef ENCODER_RESOLUTION |
||||
#define ENCODER_RESOLUTION 4 |
||||
#endif |
||||
|
||||
uint8_t matrix_scan(void) { |
||||
// dip switch
|
||||
dip_switch[0] = !palReadPad(GPIOB, 14); |
||||
dip_switch[1] = !palReadPad(GPIOA, 15); |
||||
dip_switch[2] = !palReadPad(GPIOA, 10); |
||||
dip_switch[3] = !palReadPad(GPIOB, 9); |
||||
for (uint8_t i = 0; i < 4; i++) { |
||||
if (last_dip_switch[i] ^ dip_switch[i]) |
||||
dip_update(i, dip_switch[i]); |
||||
} |
||||
memcpy(last_dip_switch, dip_switch, sizeof(&dip_switch)); |
||||
|
||||
// actual matrix
|
||||
for (int col = 0; col < MATRIX_COLS; col++) { |
||||
matrix_col_t data = 0; |
||||
|
||||
// strobe col { B11, B10, B2, B1, A7, B0 }
|
||||
switch (col) { |
||||
case 0: palSetPad(GPIOB, 11); break; |
||||
case 1: palSetPad(GPIOB, 10); break; |
||||
case 2: palSetPad(GPIOB, 2); break; |
||||
case 3: palSetPad(GPIOB, 1); break; |
||||
case 4: palSetPad(GPIOA, 7); break; |
||||
case 5: palSetPad(GPIOB, 0); break; |
||||
} |
||||
|
||||
// need wait to settle pin state
|
||||
wait_us(20); |
||||
|
||||
// read row data { A10, A9, A8, B15, C13, C14, C15, A2 }
|
||||
data = ( |
||||
(palReadPad(GPIOA, 10) << 0 ) | |
||||
(palReadPad(GPIOA, 9) << 1 ) | |
||||
(palReadPad(GPIOA, 8) << 2 ) | |
||||
(palReadPad(GPIOB, 15) << 3 ) | |
||||
(palReadPad(GPIOC, 13) << 4 ) | |
||||
(palReadPad(GPIOC, 14) << 5 ) | |
||||
(palReadPad(GPIOC, 15) << 6 ) | |
||||
(palReadPad(GPIOA, 2) << 7 ) | |
||||
(palReadPad(GPIOA, 3) << 8 ) | |
||||
(palReadPad(GPIOA, 6) << 9 ) |
||||
); |
||||
|
||||
// unstrobe col { B11, B10, B2, B1, A7, B0 }
|
||||
switch (col) { |
||||
case 0: palClearPad(GPIOB, 11); break; |
||||
case 1: palClearPad(GPIOB, 10); break; |
||||
case 2: palClearPad(GPIOB, 2); break; |
||||
case 3: palClearPad(GPIOB, 1); break; |
||||
case 4: palClearPad(GPIOA, 7); break; |
||||
case 5: palClearPad(GPIOB, 0); break; |
||||
} |
||||
|
||||
if (matrix_debouncing[col] != data) { |
||||
matrix_debouncing[col] = data; |
||||
debouncing = true; |
||||
debouncing_time = timer_read(); |
||||
} |
||||
} |
||||
|
||||
if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { |
||||
for (int row = 0; row < MATRIX_ROWS; row++) { |
||||
matrix[row] = 0; |
||||
for (int col = 0; col < MATRIX_COLS; col++) { |
||||
matrix[row] |= ((matrix_debouncing[col] & (1 << row) ? 1 : 0) << col); |
||||
} |
||||
} |
||||
debouncing = false; |
||||
} |
||||
|
||||
matrix_scan_quantum(); |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
bool matrix_is_on(uint8_t row, uint8_t col) { |
||||
return (matrix[row] & (1<<col)); |
||||
} |
||||
|
||||
matrix_row_t matrix_get_row(uint8_t row) { |
||||
return matrix[row]; |
||||
} |
||||
|
||||
void matrix_print(void) { |
||||
printf("\nr/c 01234567\n"); |
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
||||
printf("%X0: ", row); |
||||
matrix_row_t data = matrix_get_row(row); |
||||
for (int col = 0; col < MATRIX_COLS; col++) { |
||||
if (data & (1<<col)) |
||||
printf("1"); |
||||
else |
||||
printf("0"); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
} |
@ -0,0 +1,71 @@ |
||||
/*
|
||||
* Copyright 2018 Jack Humbert <jack.humb@gmail.com> |
||||
* Copyright 2019 Drashna Jaelre (Christopher Courtney) <drashna@live.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#include "dip_switch.h" |
||||
|
||||
// for memcpy
|
||||
#include <string.h> |
||||
|
||||
|
||||
#if !defined(DIP_SWITCH_PINS) |
||||
# error "No DIP switch pads defined by DIP_SWITCH_PINS" |
||||
#endif |
||||
|
||||
#define NUMBER_OF_DIP_SWITCHES (sizeof(dip_switch_pad)/sizeof(pin_t)) |
||||
static pin_t dip_switch_pad[] = DIP_SWITCH_PINS; |
||||
static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; |
||||
static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = { 0 }; |
||||
|
||||
|
||||
__attribute__((weak)) |
||||
void dip_switch_update_user(uint8_t index, bool active) {} |
||||
|
||||
__attribute__((weak)) |
||||
void dip_switch_update_kb(uint8_t index, bool active) { dip_switch_update_user(index, active); } |
||||
|
||||
__attribute__((weak)) |
||||
void dip_switch_update_mask_user(uint32_t state) {} |
||||
|
||||
__attribute__((weak)) |
||||
void dip_switch_update_mask_kb(uint32_t state) { dip_switch_update_mask_user(state); } |
||||
|
||||
void dip_switch_init(void) { |
||||
for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { |
||||
setPinInputHigh(dip_switch_pad[i]); |
||||
} |
||||
dip_switch_read(true); |
||||
} |
||||
|
||||
|
||||
void dip_switch_read(bool forced) { |
||||
bool has_dip_state_changed = false; |
||||
uint32_t dip_switch_mask = 0; |
||||
|
||||
for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { |
||||
dip_switch_state[i] = !readPin(dip_switch_pad[i]); |
||||
dip_switch_mask |= dip_switch_state[i] << i; |
||||
if (last_dip_switch_state[i] ^ dip_switch_state[i] || forced) { |
||||
has_dip_state_changed = true; |
||||
dip_switch_update_kb(i, dip_switch_state[i]); |
||||
} |
||||
} |
||||
if (has_dip_state_changed) { |
||||
dip_switch_update_mask_kb(dip_switch_mask); |
||||
} |
||||
memcpy(last_dip_switch_state, dip_switch_state, sizeof(&dip_switch_state)); |
||||
} |
@ -0,0 +1,29 @@ |
||||
/*
|
||||
* Copyright 2018 Jack Humbert <jack.humb@gmail.com> |
||||
* Copyright 2018 Drashna Jaelre (Christopher Courtney) <drashna@live.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/ |
||||
|
||||
#pragma once |
||||
|
||||
#include "quantum.h" |
||||
|
||||
void dip_switch_update_kb(uint8_t index, bool active); |
||||
void dip_switch_update_user(uint8_t index, bool active); |
||||
void dip_switch_update_mask_user(uint32_t state); |
||||
void dip_switch_update_mask_kb(uint32_t state); |
||||
|
||||
void dip_switch_init(void); |
||||
void dip_switch_read(bool forced); |
Loading…
Reference in new issue