[Keyboard] Update the Scarlet Bandana (#5058)
* remove unneeded file * make an appropriate readme * amend the LAYOUT macro to adhere to new QMK standards and create an appropriate keymap * add QMK Configurator support * a bunch of changes lol * delete unneeded routines * update date to modern times * remove a useless prototype * add in drashna's suggestions on PRrgb7seg
parent
80e733798a
commit
afa4763ef5
@ -0,0 +1,12 @@ |
||||
{ |
||||
"keyboard_name": "Scarlet Bandana Version IV Mark 2", |
||||
"url": "", |
||||
"maintainer": "qmk", |
||||
"width": 18.5, |
||||
"height": 5, |
||||
"layouts": { |
||||
"LAYOUT_all": { |
||||
"layout": [{"x":0, "y":0}, {"x":1, "y":0}, {"x":2.5, "y":0}, {"x":3.5, "y":0}, {"x":4.5, "y":0}, {"x":5.5, "y":0}, {"x":6.5, "y":0}, {"x":7.5, "y":0}, {"x":8.5, "y":0}, {"x":9.5, "y":0}, {"x":10.5, "y":0}, {"x":11.5, "y":0}, {"x":12.5, "y":0}, {"x":13.5, "y":0}, {"x":14.5, "y":0}, {"x":15.5, "y":0}, {"x":16.5, "y":0}, {"x":17.5, "y":0}, {"x":0, "y":1}, {"x":1, "y":1}, {"x":2.5, "y":1, "w":1.5}, {"x":4, "y":1}, {"x":5, "y":1}, {"x":6, "y":1}, {"x":7, "y":1}, {"x":8, "y":1}, {"x":9, "y":1}, {"x":10, "y":1}, {"x":11, "y":1}, {"x":12, "y":1}, {"x":13, "y":1}, {"x":14, "y":1}, {"x":15, "y":1}, {"x":16, "y":1, "w":1.5}, {"x":17.5, "y":1}, {"x":0, "y":2}, {"x":1, "y":2}, {"x":2.5, "y":2, "w":1.75}, {"x":4.25, "y":2}, {"x":5.25, "y":2}, {"x":6.25, "y":2}, {"x":7.25, "y":2}, {"x":8.25, "y":2}, {"x":9.25, "y":2}, {"x":10.25, "y":2}, {"x":11.25, "y":2}, {"x":12.25, "y":2}, {"x":13.25, "y":2}, {"x":14.25, "y":2}, {"x":15.25, "y":2, "w":2.25}, {"x":17.5, "y":2}, {"x":0, "y":3}, {"x":1, "y":3}, {"x":2.5, "y":3, "w":2.25}, {"x":4.75, "y":3}, {"x":5.75, "y":3}, {"x":6.75, "y":3}, {"x":7.75, "y":3}, {"x":8.75, "y":3}, {"x":9.75, "y":3}, {"x":10.75, "y":3}, {"x":11.75, "y":3}, {"x":12.75, "y":3}, {"x":13.75, "y":3}, {"x":14.75, "y":3, "w":1.75}, {"x":16.5, "y":3}, {"x":17.5, "y":3}, {"x":0, "y":4}, {"x":1, "y":4}, {"x":2.5, "y":4, "w":1.25}, {"x":3.75, "y":4, "w":1.25}, {"x":5, "y":4, "w":1.25}, {"x":6.25, "y":4, "w":2.25}, {"x":8.5, "y":4, "w":1.75}, {"x":10.25, "y":4, "w":2.25}, {"x":12.5, "y":4}, {"x":13.5, "y":4}, {"x":14.5, "y":4}, {"x":15.5, "y":4}, {"x":16.5, "y":4}, {"x":17.5, "y":4}] |
||||
} |
||||
} |
||||
} |
@ -1,326 +0,0 @@ |
||||
/*
|
||||
Copyright 2012 Jun Wako <wakojun@gmail.com> |
||||
Copyright 2017 Cole Markham <cole@ccmcomputing.net> |
||||
|
||||
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/>.
|
||||
*/ |
||||
|
||||
/*
|
||||
* scan matrix |
||||
*/ |
||||
#include <stdint.h> |
||||
#include <stdbool.h> |
||||
#if defined(__AVR__) |
||||
#include <avr/io.h> |
||||
#include "pincontrol.h" |
||||
#endif |
||||
#include "wait.h" |
||||
#include "print.h" |
||||
#include "debug.h" |
||||
#include "util.h" |
||||
#include "matrix.h" |
||||
#include "config.h" |
||||
#include "timer.h" |
||||
//#include "audio.h"
|
||||
|
||||
#ifndef DEBOUNCING_DELAY |
||||
# define DEBOUNCING_DELAY 5 |
||||
#endif |
||||
|
||||
#if (DEBOUNCING_DELAY > 0) |
||||
static uint16_t debouncing_time; |
||||
static bool debouncing = false; |
||||
#endif |
||||
|
||||
#if (MATRIX_COLS <= 8) |
||||
# define print_matrix_header() print("\nr/c 01234567\n") |
||||
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) |
||||
# define matrix_bitpop(i) bitpop(matrix[i]) |
||||
# define ROW_SHIFTER ((uint8_t)1) |
||||
#elif (MATRIX_COLS <= 16) |
||||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") |
||||
# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) |
||||
# define matrix_bitpop(i) bitpop16(matrix[i]) |
||||
# define ROW_SHIFTER ((uint16_t)1) |
||||
#elif (MATRIX_COLS <= 32) |
||||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") |
||||
# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) |
||||
# define matrix_bitpop(i) bitpop32(matrix[i]) |
||||
# define ROW_SHIFTER ((uint32_t)1) |
||||
#endif |
||||
|
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS]; |
||||
|
||||
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; |
||||
static const uint8_t col_pins[4] = MATRIX_COL_PINS; |
||||
static const uint8_t xcol_pins[MATRIX_COLS - 16] = MATRIX_XCOL_PINS; |
||||
//
|
||||
//float init_song[][2] = SONG(QWERTY_SOUND);
|
||||
|
||||
/* matrix state(1:on, 0:off) */ |
||||
static matrix_row_t matrix[MATRIX_ROWS]; |
||||
static matrix_row_t matrix_debouncing[MATRIX_ROWS]; |
||||
static void init_rows(void); |
||||
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col); |
||||
static void unselect_cols(void); |
||||
static void init_cols(void); |
||||
static void select_col(uint8_t col); |
||||
//static void demux_enable(bool enabled);
|
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_quantum(void) { |
||||
matrix_init_kb(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_quantum(void) { |
||||
matrix_scan_kb(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_kb(void) { |
||||
matrix_init_user(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_kb(void) { |
||||
matrix_scan_user(); |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_init_user(void) { |
||||
} |
||||
|
||||
__attribute__ ((weak)) |
||||
void matrix_scan_user(void) { |
||||
} |
||||
|
||||
inline |
||||
uint8_t matrix_rows(void) |
||||
{ |
||||
return MATRIX_ROWS; |
||||
} |
||||
|
||||
inline |
||||
uint8_t matrix_cols(void) |
||||
{ |
||||
return MATRIX_COLS; |
||||
} |
||||
|
||||
void matrix_init(void) |
||||
{ |
||||
debug_enable = true; |
||||
debug_matrix = true; |
||||
debug_mouse = true; |
||||
dprintf("matrix init"); |
||||
// initialize row and col
|
||||
init_cols(); |
||||
init_rows(); |
||||
|
||||
|
||||
// PLAY_NOTE_ARRAY(init_song, false, 0);
|
||||
|
||||
|
||||
// initialize matrix state: all keys off
|
||||
for (uint8_t i=0; i < MATRIX_ROWS; i++) { |
||||
matrix[i] = 0; |
||||
matrix_debouncing[i] = 0; |
||||
} |
||||
|
||||
matrix_init_quantum(); |
||||
|
||||
} |
||||
|
||||
uint8_t _matrix_scan(void) |
||||
{ |
||||
// Set col, read rows
|
||||
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) { |
||||
# if (DEBOUNCING_DELAY > 0) |
||||
bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col); |
||||
if (matrix_changed) { |
||||
debouncing = true; |
||||
debouncing_time = timer_read(); |
||||
} |
||||
# else |
||||
read_rows_on_col(matrix, current_col); |
||||
# endif |
||||
|
||||
} |
||||
|
||||
// Unselect cols
|
||||
unselect_cols(); |
||||
|
||||
# if (DEBOUNCING_DELAY > 0) |
||||
if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCING_DELAY)) { |
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
||||
matrix[i] = matrix_debouncing[i]; |
||||
} |
||||
debouncing = false; |
||||
} |
||||
# endif |
||||
|
||||
return 1; |
||||
} |
||||
|
||||
uint8_t matrix_scan(void) |
||||
{ |
||||
uint8_t ret = _matrix_scan(); |
||||
matrix_scan_quantum(); |
||||
return ret; |
||||
} |
||||
|
||||
bool matrix_is_modified(void) |
||||
{ |
||||
if (debouncing) return false; |
||||
return true; |
||||
} |
||||
|
||||
inline |
||||
bool matrix_is_on(uint8_t row, uint8_t col) |
||||
{ |
||||
return (matrix[row] & ((matrix_row_t)1<<col)); |
||||
} |
||||
|
||||
inline |
||||
matrix_row_t matrix_get_row(uint8_t row) |
||||
{ |
||||
return matrix[row]; |
||||
} |
||||
|
||||
void matrix_print(void) |
||||
{ |
||||
print("\nr/c 0123456789ABCDEF\n"); |
||||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
||||
phex(row); print(": "); |
||||
pbin_reverse16(matrix_get_row(row)); |
||||
print("\n"); |
||||
} |
||||
} |
||||
|
||||
uint8_t matrix_key_count(void) |
||||
{ |
||||
uint8_t count = 0; |
||||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { |
||||
count += bitpop16(matrix[i]); |
||||
} |
||||
return count; |
||||
} |
||||
|
||||
|
||||
static void init_rows(void) |
||||
{ |
||||
for(uint8_t x = 0; x < MATRIX_ROWS; x++) { |
||||
uint8_t pin = row_pins[x]; |
||||
pinMode(pin, PinDirectionInput); |
||||
digitalWrite(pin, PinLevelHigh); |
||||
} |
||||
} |
||||
|
||||
|
||||
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) |
||||
{ |
||||
bool matrix_changed = false; |
||||
|
||||
// Select col and wait for col selection to stabilize
|
||||
select_col(current_col); |
||||
wait_us(30); |
||||
// wait_ms(1000);
|
||||
// PLAY_NOTE_ARRAY(init_song, false, 0);
|
||||
|
||||
// For each row...
|
||||
for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) |
||||
{ |
||||
|
||||
// Store last value of row prior to reading
|
||||
matrix_row_t last_row_value = current_matrix[row_index]; |
||||
|
||||
// Check row pin state
|
||||
uint8_t pin = row_pins[row_index]; |
||||
if (digitalRead(pin) == 0) |
||||
{ |
||||
// Pin LO, set col bit
|
||||
current_matrix[row_index] |= (ROW_SHIFTER << current_col); |
||||
} |
||||
else |
||||
{ |
||||
// Pin HI, clear col bit
|
||||
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col); |
||||
} |
||||
|
||||
// Determine if the matrix changed state
|
||||
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) |
||||
{ |
||||
matrix_changed = true; |
||||
} |
||||
} |
||||
|
||||
return matrix_changed; |
||||
} |
||||
|
||||
static void select_col(uint8_t col) |
||||
{ |
||||
for (uint8_t y = 16; y < MATRIX_COLS; y++) { |
||||
uint8_t pin = xcol_pins[y-16]; |
||||
if (y == col) { |
||||
digitalWrite(pin, PinLevelLow); |
||||
} else { |
||||
digitalWrite(pin, PinLevelHigh); |
||||
} |
||||
} |
||||
if (col >= 16) { |
||||
// demux_enable(false);
|
||||
// digitalWrite(MATRIX_EN_PIN, PinLevelHigh);
|
||||
} else { |
||||
for(uint8_t x = 0; x < 4; x++) { |
||||
uint8_t pin = col_pins[x]; |
||||
pinMode(pin, PinDirectionOutput); |
||||
digitalWrite(pin, (col >> x) & 0x1); |
||||
} |
||||
// demux_enable(true);
|
||||
digitalWrite(MATRIX_EN_PIN, PinLevelLow); |
||||
} |
||||
} |
||||
|
||||
static void init_cols(void) { |
||||
for (uint8_t y = 16; y < MATRIX_COLS; y++) { |
||||
uint8_t pin = xcol_pins[y-16]; |
||||
pinMode(pin, PinDirectionOutput); |
||||
} |
||||
for(uint8_t x = 0; x < 4; x++) { |
||||
uint8_t pin = col_pins[x]; |
||||
pinMode(pin, PinDirectionOutput); |
||||
} |
||||
pinMode(MATRIX_EN_PIN, PinDirectionOutput); |
||||
// digitalWrite(MATRIX_EN_PIN, PinLevelHigh);
|
||||
unselect_cols(); |
||||
} |
||||
|
||||
static void unselect_cols(void) |
||||
{ |
||||
for (uint8_t y = 16; y < MATRIX_COLS; y++) { |
||||
uint8_t pin = xcol_pins[y-16]; |
||||
digitalWrite(pin, PinLevelHigh); |
||||
} |
||||
// demux_enable(false);
|
||||
// digitalWrite(MATRIX_EN_PIN, PinLevelHigh);
|
||||
} |
||||
|
||||
//static void demux_enable(uint8_t state)
|
||||
//{
|
||||
// if (enabled){
|
||||
// digitalWrite(F7, PinLevelLow);
|
||||
// } else {
|
||||
// digitalWrite(F7, PinLevelHigh);
|
||||
// }
|
||||
//}
|
@ -1,31 +1,11 @@ |
||||
# Meira |
||||
|
||||
 |
||||
|
||||
A 4x12 ortholinear low-profile keyboard. |
||||
# Scarlet Bandana Version IV Mark 2 |
||||
|
||||
Keyboard Maintainer: [Cole Markham](https://github.com/colemarkham) |
||||
Hardware Supported: Meira/ProMicro, Meira/FeatherBLE |
||||
Hardware Availability: [WoodKeys.click](https://woodkeys.click/meira) |
||||
|
||||
Two controllers are support: the Pro Micro, and the Adafruit Feather BLE 32u4. Support for each is defined as a hardware revision subfolder in QMK. Main differences include processor frequencies and matrix pinouts. |
||||
Hardware Supported: Scarlet Bandana Version IV Mark 2 |
||||
Hardware Availability: [WoodKeys.click](https://woodkeys.click/product/scarlet-bandana-version-iv-mark-2/) |
||||
|
||||
Make example for this keyboard (after setting up your build environment): |
||||
|
||||
make meira/promicro:default |
||||
|
||||
or |
||||
|
||||
make meira/featherble:default |
||||
|
||||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information on generic QMK configuration and setup. |
||||
|
||||
Both the Pro Micro and the Feather BLE use the Catalina bootloader, which is typically programmed using avrdude. |
||||
|
||||
## Matrix |
||||
|
||||
In order to have enough pins for the matrix and other functions, a custom matrix is implemented using a demultiplexer to scan the columns. Since the demux is active low, the diodes must be oriented with the cathode connected to the demux pin. When looking at the bottom of the board with the controller at the top right, the cathode mark on the diode should be toward the left. |
||||
|
||||
## LED Controller |
||||
make scarletbandana:default |
||||
|
||||
The in-switch LEDs are driven by an ISSI LED controller (IS31FL3731). The micro controller communicates with this chip using I2C. Individual LED control is possible, but currently only general backlighting support is implemented. This functionality is located in lighting.c, issi.c, and TWILib.c. |
||||
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs). |
||||
|
Loading…
Reference in new issue