This adds support for LEDs that are directly connected to the MCU, either in a matrix or to single pins.led_matrix_direct
@ -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 |