This adds support for LEDs that are directly connected to the MCU, either in a matrix or to single pins.led_matrix_direct
parent
a5a31a5fc0
commit
f8896d8b92
@ -0,0 +1,103 @@ |
|||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert |
||||||
|
* Copyright 2019 Clueboard |
||||||
|
* |
||||||
|
* 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/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __AVR__ |
||||||
|
# include <avr/interrupt.h> |
||||||
|
# include <avr/io.h> |
||||||
|
# include <util/delay.h> |
||||||
|
# define led_wait_us(us) wait_us(us) |
||||||
|
#else |
||||||
|
# include "ch.h" |
||||||
|
# include "hal.h" |
||||||
|
# define led_wait_us(us) chSysPolledDelayX(US2RTC(STM32_SYSCLK, us)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <string.h> |
||||||
|
#include "led_matrix_pinmatrix.h" |
||||||
|
#include "led_tables.h" |
||||||
|
#include "progmem.h" |
||||||
|
#include "quantum.h" |
||||||
|
#include "backlight.h" |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_pwm_buffer is an array that represents the duty cycle (0-255) for each LED. |
||||||
|
* FIXME: Map this from the wiring matrix to a physical location matrix at some point |
||||||
|
*/ |
||||||
|
uint8_t g_pwm_buffer[LED_MATRIX_ROWS * LED_MATRIX_COLS]; |
||||||
|
const pin_t led_row_pins[LED_MATRIX_ROWS] = LED_MATRIX_ROW_PINS; |
||||||
|
const pin_t led_col_pins[LED_MATRIX_COLS] = LED_MATRIX_COL_PINS; |
||||||
|
|
||||||
|
|
||||||
|
void led_matrix_pinmatrix_init_pins(void) { |
||||||
|
/* Set all pins to output, we are not interested in reading any information.
|
||||||
|
*/ |
||||||
|
for (uint8_t x = 0; x < LED_MATRIX_ROWS; x++) { |
||||||
|
setPinOutput(led_row_pins[x]); |
||||||
|
writePinLow(led_row_pins[x]); |
||||||
|
} |
||||||
|
|
||||||
|
for (uint8_t x = 0; x < LED_MATRIX_COLS; x++) { |
||||||
|
setPinOutput(led_col_pins[x]); |
||||||
|
writePinLow(led_col_pins[x]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void led_matrix_pinmatrix_set_value(int index, uint8_t value) { |
||||||
|
/* Set the brighness for a single LED.
|
||||||
|
*/ |
||||||
|
if (index >= 0 && index < LED_DRIVER_LED_COUNT) { |
||||||
|
g_pwm_buffer[index] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void led_matrix_pinmatrix_set_value_all(uint8_t value) { |
||||||
|
/* Set the brighness for all LEDs.
|
||||||
|
*/ |
||||||
|
for (int i = 0; i < LED_DRIVER_LED_COUNT; i++) { |
||||||
|
led_matrix_pinmatrix_set_value(i, value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void led_matrix_pinmatrix_flush(void) { |
||||||
|
/* This is a basic bit-banged pwm implementation.
|
||||||
|
*/ |
||||||
|
uint8_t led_count = 0; |
||||||
|
for (uint8_t row = 0; row < LED_MATRIX_ROWS; row++) { |
||||||
|
writePinLow(led_row_pins[row]); |
||||||
|
for (uint8_t col = 0; col < LED_MATRIX_COLS; col++) { |
||||||
|
/* We spend ~128us on each LED, dividing that time between lit and unlit.
|
||||||
|
*/ |
||||||
|
const uint8_t brightness = pgm_read_byte(&CIE1931_CURVE[g_pwm_buffer[led_count]]) / 2; |
||||||
|
if (brightness > 0) { |
||||||
|
writePinHigh(led_col_pins[col]); |
||||||
|
for (int i = 0; i < 128; i++) { |
||||||
|
if (i == brightness) { |
||||||
|
writePinLow(led_col_pins[col]); |
||||||
|
} |
||||||
|
led_wait_us(1); |
||||||
|
} |
||||||
|
} else { |
||||||
|
led_wait_us(128); |
||||||
|
} |
||||||
|
led_count++; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert |
||||||
|
* Copyright 2019 Clueboard |
||||||
|
* |
||||||
|
* 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/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef LED_MATRIX_PINMATRIX_DRIVER_H |
||||||
|
#define LED_MATRIX_PINMATRIX_DRIVER_H |
||||||
|
|
||||||
|
void led_matrix_pinmatrix_init_pins(void); |
||||||
|
void led_matrix_pinmatrix_set_value(int index, uint8_t value); |
||||||
|
void led_matrix_pinmatrix_set_value_all(uint8_t value); |
||||||
|
void led_matrix_pinmatrix_flush(void); |
||||||
|
void led_matrix_pinmatrix_select_row(uint8_t row); |
||||||
|
void led_matrix_pinmatrix_unselect_row(uint8_t row); |
||||||
|
void led_matrix_pinmatrix_unselect_rows(void); |
||||||
|
|
||||||
|
#endif // LED_MATRIX_PINMATRIX_DRIVER_H
|
@ -0,0 +1,95 @@ |
|||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert |
||||||
|
* Copyright 2019 Clueboard |
||||||
|
* |
||||||
|
* 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/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifdef __AVR__ |
||||||
|
# include <avr/interrupt.h> |
||||||
|
# include <avr/io.h> |
||||||
|
# include <util/delay.h> |
||||||
|
# define led_wait_us(us) wait_us(us) |
||||||
|
#else |
||||||
|
# include "ch.h" |
||||||
|
# include "hal.h" |
||||||
|
# define led_wait_us(us) chSysPolledDelayX(US2RTC(STM32_SYSCLK, us)) |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <string.h> |
||||||
|
#include "led_matrix_pins.h" |
||||||
|
#include "led_tables.h" |
||||||
|
#include "progmem.h" |
||||||
|
#include "quantum.h" |
||||||
|
#include "backlight.h" |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g_pwm_buffer is an array that represents the duty cycle (0-255) for each LED. |
||||||
|
*/ |
||||||
|
uint8_t g_pwm_buffer[LED_DRIVER_LED_COUNT]; |
||||||
|
const pin_t led_pins[LED_DRIVER_LED_COUNT] = LED_MATRIX_PINS; |
||||||
|
|
||||||
|
#ifdef LED_MATRIX_PIN_SINK |
||||||
|
# define led_pin_on(pin) writePinLow(pin) |
||||||
|
# define led_pin_off(pin) writePinHigh(pin) |
||||||
|
#else |
||||||
|
# define led_pin_on(pin) writePinHigh(pin) |
||||||
|
# define led_pin_off(pin) writePinLow(pin) |
||||||
|
#endif |
||||||
|
|
||||||
|
void led_matrix_pins_init_pins(void) { |
||||||
|
/* Set all pins to output, we are not interested in reading any information.
|
||||||
|
*/ |
||||||
|
for (uint8_t x = 0; x < LED_DRIVER_LED_COUNT; x++) { |
||||||
|
setPinOutput(led_pins[x]); |
||||||
|
led_pin_off(led_pins[x]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void led_matrix_pins_set_value(int index, uint8_t value) { |
||||||
|
/* Set the brighness for a single LED.
|
||||||
|
*/ |
||||||
|
if (index >= 0 && index < LED_DRIVER_LED_COUNT) { |
||||||
|
g_pwm_buffer[index] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void led_matrix_pins_set_value_all(uint8_t value) { |
||||||
|
/* Set the brighness for all LEDs.
|
||||||
|
*/ |
||||||
|
for (int i = 0; i < LED_DRIVER_LED_COUNT; i++) { |
||||||
|
led_matrix_pins_set_value(i, value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void led_matrix_pins_flush(void) { |
||||||
|
/* This is a basic bit-banged pwm implementation.
|
||||||
|
*/ |
||||||
|
for (uint8_t i = 0; i < LED_DRIVER_LED_COUNT; i++) { |
||||||
|
/* We spend ~1.3ms on each LED, dividing that time between lit and unlit.
|
||||||
|
*/ |
||||||
|
if (g_pwm_buffer[i] > 0) { |
||||||
|
uint8_t brightness = pgm_read_byte(&CIE1931_CURVE[g_pwm_buffer[i]]) / 2; |
||||||
|
led_pin_on(led_pins[i]); |
||||||
|
led_wait_us(brightness); |
||||||
|
led_pin_off(led_pins[i]); |
||||||
|
led_wait_us(128 - brightness); |
||||||
|
} else { |
||||||
|
led_wait_us(128); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
/* Copyright 2017 Jason Williams
|
||||||
|
* Copyright 2018 Jack Humbert |
||||||
|
* Copyright 2019 Clueboard |
||||||
|
* |
||||||
|
* 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/>.
|
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef LED_MATRIX_PINS_DRIVER_H |
||||||
|
#define LED_MATRIX_PINS_DRIVER_H |
||||||
|
|
||||||
|
void led_matrix_pins_init_pins(void); |
||||||
|
void led_matrix_pins_set_value(int index, uint8_t value); |
||||||
|
void led_matrix_pins_set_value_all(uint8_t value); |
||||||
|
void led_matrix_pins_flush(void); |
||||||
|
void led_matrix_pins_select_row(uint8_t row); |
||||||
|
void led_matrix_pins_unselect_row(uint8_t row); |
||||||
|
void led_matrix_pins_unselect_rows(void); |
||||||
|
|
||||||
|
#endif // LED_MATRIX_PINS_DRIVER_H
|
@ -0,0 +1,39 @@ |
|||||||
|
#include QMK_KEYBOARD_H |
||||||
|
|
||||||
|
enum custom_keycodes { |
||||||
|
UP_URL = SAFE_RANGE |
||||||
|
}; |
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { |
||||||
|
LAYOUT_ortho_4x4( |
||||||
|
KC_0, KC_1, KC_2, KC_3, |
||||||
|
KC_4, KC_5, KC_6, KC_7, |
||||||
|
KC_8, KC_9, KC_A, KC_B, |
||||||
|
KC_C, RESET, KC_E, BL_STEP |
||||||
|
) |
||||||
|
}; |
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) { |
||||||
|
switch (keycode) { |
||||||
|
case UP_URL: |
||||||
|
if (record->event.pressed) { |
||||||
|
SEND_STRING("http://1upkeyboards.com"); |
||||||
|
} |
||||||
|
return false; |
||||||
|
break; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
#ifdef ENCODER_ENABLE |
||||||
|
#include "encoder.h" |
||||||
|
void encoder_update_user(int8_t index, bool clockwise) { |
||||||
|
if (index == 0) { /* First encoder */ |
||||||
|
if (clockwise) { |
||||||
|
tap_code(KC_VOLU); |
||||||
|
} else { |
||||||
|
tap_code(KC_VOLD); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
#endif |
@ -1 +0,0 @@ |
|||||||
#include "sweet16.h" |
|
@ -1,30 +0,0 @@ |
|||||||
#pragma once |
|
||||||
|
|
||||||
#include "quantum.h" |
|
||||||
|
|
||||||
// Any changes to the layout names and/or definitions must also be made to info.json
|
|
||||||
|
|
||||||
#define LAYOUT_ortho_4x4( \ |
|
||||||
K00, K01, K02, K03, \
|
|
||||||
K10, K11, K12, K13, \
|
|
||||||
K20, K21, K22, K23, \
|
|
||||||
K30, K31, K32, K33 \
|
|
||||||
) { \
|
|
||||||
{ K00, K01, K02, K03 }, \
|
|
||||||
{ K10, K11, K12, K13 }, \
|
|
||||||
{ K20, K21, K22, K23 }, \
|
|
||||||
{ K30, K31, K32, K33 } \
|
|
||||||
} |
|
||||||
|
|
||||||
#define LAYOUT_numpad_4x4( \ |
|
||||||
K00, K01, K02, K03, \
|
|
||||||
K10, K11, K12, \
|
|
||||||
K20, K21, K22, K23, \
|
|
||||||
K31, K32 \
|
|
||||||
) { \
|
|
||||||
{ K00, K01, K02, K03 }, \
|
|
||||||
{ K10, K11, K12, KC_NO }, \
|
|
||||||
{ K20, K21, K22, K23 }, \
|
|
||||||
{ KC_NO, K31, K32, KC_NO } \
|
|
||||||
} |
|
||||||
|
|
@ -1,6 +1,5 @@ |
|||||||
class NoSuchKeyboardError(Exception): |
class NoSuchKeyboardError(Exception): |
||||||
"""Raised when we can't find a keyboard/keymap directory. |
"""Raised when we can't find a keyboard/keymap directory. |
||||||
""" |
""" |
||||||
|
|
||||||
def __init__(self, message): |
def __init__(self, message): |
||||||
self.message = message |
self.message = message |
||||||
|
Loading…
Reference in new issue