From 4b7e5967f26f69f3a86ddaa10177c7e7229835d8 Mon Sep 17 00:00:00 2001 From: GitWellBack <48095880+GitWellBack@users.noreply.github.com> Date: Wed, 1 May 2019 20:45:22 +1000 Subject: [PATCH 01/22] Initial MBI5042GP 16-bit LED PWM driver release --- common_features.mk | 20 +- drivers/macroblock/mbi5042gp.c | 566 +++++++++++++++++++++++++++++++++ drivers/macroblock/mbi5042gp.h | 52 +++ quantum/led_tables.c | 35 ++ quantum/led_tables.h | 5 + quantum/rgb_matrix.h | 3 + quantum/rgb_matrix_drivers.c | 20 ++ 7 files changed, 698 insertions(+), 3 deletions(-) create mode 100644 drivers/macroblock/mbi5042gp.c create mode 100644 drivers/macroblock/mbi5042gp.h diff --git a/common_features.mk b/common_features.mk index 8ac53ec45a5..c2c166607a0 100644 --- a/common_features.mk +++ b/common_features.mk @@ -1,4 +1,5 @@ # Copyright 2017 Fred Sundvik +# Copyright 2019 /u/KeepItUnder # # 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 @@ -193,7 +194,7 @@ ifeq ($(strip $(LED_MATRIX_ENABLE)), yes) endif RGB_MATRIX_ENABLE ?= no -VALID_RGB_MATRIX_TYPES := IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom +VALID_RGB_MATRIX_TYPES := IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 MBI5042 custom ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),) @@ -243,6 +244,14 @@ endif WS2812_DRIVER_REQUIRED := yes endif + ifeq ($(strip $(RGB_MATRIX_DRIVER)), MBI5042) + OPT_DEFS += -DMBI5042 + COMMON_VPATH += $(DRIVER_PATH)/macroblock + SRC += mbi5042gp.c + endif + + + ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes) OPT_DEFS += -DRGB_MATRIX_CUSTOM_KB endif @@ -350,8 +359,13 @@ ifeq ($(strip $(VISUALIZER_ENABLE)), yes) endif ifeq ($(strip $(CIE1931_CURVE)), yes) - OPT_DEFS += -DUSE_CIE1931_CURVE - LED_TABLES := yes + ifeq ($(strip $(RGB_MATRIX_ENABLE)), MBI5042) + OPT_DEFS += -DUSE_CIE1931_16_CURVE + LED_TABLES = yes + else + OPT_DEFS += -DUSE_CIE1931_CURVE + LED_TABLES = yes + endif endif ifeq ($(strip $(LED_TABLES)), yes) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c new file mode 100644 index 00000000000..ea7323c9e6a --- /dev/null +++ b/drivers/macroblock/mbi5042gp.c @@ -0,0 +1,566 @@ +/* Copyright 2019 /u/KeepItUnder + * + * 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 . + */ + +/* + * Macroblock's MBI5042GP is a 16-channel constant current LED driver. + * + * The chip has a data input interface, a set of synchronisation clocks + * and 16 PWM output pins capapble of 16-bit PWM. + * + * Data interface: SDI, SDO, DCLK + * General clock: GCLK + * Data Latch: LE + * + * Commands available (differentiated by numbers of rising edge DCLKS) + * Command is actioned on subsequent falling edge of LE: + * + * + * Data Latch + * ========== + * + * Take LE high. Keep high for maximum of 1 DCLK rising edges. + * + * Allow LE to fall - falling edge causes serial data to be + * transferred to the buffers only. + * + * + * Global Latch + * ============ + * + * Take LE high. Keep high for 2 or 3 DCLK rising edges. + * + * Allow LE to fall - falling edge causes buffer data to be + * transferred to the comparators. + * + * + * Read Configuration + * ================== + * + * Take LE high. Keep high for 4 or 5 DCLK rising edges. + * + * Allow LE to fall - falling edge moves config data to the + * shift registers. + * + * + * Write Configuration + * =================== + * + * Take LE high. Keep high for 10 or 11 DCLK rising edges. + * + * Allow LE to fall - falling edge transfers serial data + * to the configuration register ONLY IF "Enable Writing + * Configuration" is sent prior (see below) + * + * + * Reset PWM Counter + * ================= + * + * Take LE high. Keep high for 12 or 13 DCLK rising edges. + * + * Allow LE to fall - falling edge resets the PWM counter + * If bit "B" of the configuration register is "1" + * + * + * Enable Writing Configuration + * ============================ + * + * Take LE high. Keep high for 14 or 15 DCLK rising edges. + * + * Allow LE to fall - falling edge enables configuration + * writing. This should be sent immediately prior to any + * attempt to write to configuration register. + * + * + * Configuration Register + * ====================== + * + * 16 bits wide + * + * MSB Definition Value Function + * -------------------------------------------------------------------------------- + * | | | 0 (Default) | 15 x data latch + 1 global latch + * F | R/W | Data Loading | | + * | | | 1 | 16 x data latch + 1 global latch + * ----|-------|----------------|---------------|---------------------------------- + * E | | | | + * D | R/W | Reserved | Don't Care | N/A + * C | | | | + * ----|-------|----------------|---------------|---------------------------------- + * | | PWM counter | 0 (Default) | Disable + * B | R/W | reset | | + * | | | 1 | Enable (12/13 DCLKs + LE assert) + * ----|-------|----------------|---------------|---------------------------------- + * | | PWM data | 0 (Default) | Auto synchronization + * A | R/W | synch mode | | + * | | | 1 | Manual synchronization + * ----|-------|----------------|---------------|---------------------------------- + * 9 | | | | + * 8 | | | | + * 7 | R/W | Current gain | 000000 | 6'b101011 (Default) + * 6 | | adjustment | ~ | + * 5 | | | 111111 | + * 4 | | | | + * ----|-------|----------------|---------------|---------------------------------- + * 3 | | | | + * 2 | R/W | Reserved | Don't Care | N/A + * 1 | | | | + * 0 | | | | + * -------------------------------------------------------------------------------- + * LSB + * + */ + +//#include "mbi5042gp.h" +#include +#include "progmem.h" +#include "rgb_matrix.h" +#include "led_tables.h" + +#ifndef MBI5042GP_GCLK_SRC + #define MBI5042GP_GCLK_SRC PWM0 +#endif +#ifndef MBI5042GP_DCLK + #define MBI5042GP_DCLK PD4 +#endif +#ifndef MBI5042GP_LE + #define MBI5042GP_LE PD3 +#endif + +/** The PWM buffers the full rows of 16 PWM registers in each MBI5042 driver + * The buffers are arranged in serial format + * (MSB_R, MSB_G, MSB_B...LSB_R, LSB_G, LSB_B) + * as needed by the SDO pins on the MCU (R is B14; G is B13; B is B12) + * + * g_pwm_buffer has the DCLK-able output for an "R" row, a "G" row, and a "B" row of PWM + */ +uint16_t g_pwm_buffer[MBI5042GP_ROW_COUNT][16*16]; + +bool g_pwm_buffer_update_required = false; +uint8_t g_pwm_buffer_row = 0; + +void MBI5042GP_init( void ) { + /* Initialise all PWM arrays to zero. + * Perform one group transfer to turn LEDs off + * + * If there's a DMA requirement, set up DMA subsystems + */ + for (int i = 0; i < MBI5042GP_ROW_COUNT; i++) { + for (int j = 0; j < 256; j++) { + g_pwm_buffer[i][j] = 0; + } + } + + #if (MBI5042GP_GCLK_SRC == PWM0) + /* Setup PWM control registers for 2MHz (makes a nice clock) + * and also 50 percentage PWM + * + * Set PWM1 to be used as a 2kHz timer (interrupt but no output pin) + */ + + /* Enable PWM module clock */ + CLK_EnableModuleClock(PWM01_MODULE); + + /* Select PWM module clock source */ + CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); + + /* Combined method to configure PWM0 */ + PWM_ConfigOutputChannel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); + + /* Enable PWM Output path for PWMA channel 0 */ + PWM_EnableOutput(PWMA, 0x1); + + /* Set GPIO PA.12/PWM0 to be PWM0 */ + SYS->GPA_MFP |= SYS_GPA_MFP_PA12_PWM0; + + /* PWM1 Config */ + /* Combined method to configure PWM1 */ + PWM_ConfigOutputChannel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); + + /* Set interrupt handler */ + nvicEnableVector(PWMA_IRQn, 1); + + /* Need an interrupt for PWM1 */ + PWM_EnablePeriodInt(PWMA, PWM_CH1, PWM_PERIOD_INT_UNDERFLOW); + + /* Start PWM0 and PWM1 */ + PWM_Start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); + + #elif + #endif + + MBI5042GP_disable_rows(); + + MBI5042GP_set_current_gain(0b000011u); +} + +/** + * @brief Set LED driver current gain + * @detail The MBI5042 has a 6-bit current gain value (000000b ~ 111111b) + * used to adjust the global brightness of the LEDs attached to the PWM outputs + * + * Default value is 101011b + * + * Use MBI5042_CURRENT_GAIN to pass from keyboard config + */ +void MBI5042GP_set_current_gain( uint8_t gain ) { + /** MB data transfer requires: + * Tell chip config register change is coming (Enable Write Configutarion) + * Pass config register data (Write Configuration Register) + */ + uint16_t regConfig = 0b00111111u & gain; + + regConfig <<= 4; + regConfig |= MBI5042GP_CFGREG_DEFAULT; + + MBI5042GP_write_config_register(regConfig); +} + +/** + * @brief Write configuration register ONLY DURING INIT + * @detail Set the contents of the configuration register (see top for bitfields) + * Each register write needs 2 * 16 bit transfers (1 x setup and 1 x data) + * + * For the Ducky One 2 mini there are 3 drivers, so output all three configs at once + */ +void MBI5042GP_write_config_register( uint16_t regValue ) { + uint32_t b_mask; + uint16_t tmp_r, tmp_g, tmp_b; + + /* Set Mask for GPIOB */ + b_mask = PB->DMASK; + PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); + + /* LE Low & DCLK Low */ + MBI5042GP_LE = PAL_LOW; + MBI5042GP_DCLK = PAL_LOW; + + /* Do one DCLK cycle */ + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + + /* Set LE High */ + MBI5042GP_LE = PAL_HIGH; + + /* Loop 15 - Enable Write Configuration */ + for (int i = 0; i < 15; i++) { + /* Cycle DCLK */ + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + } + + /* Reset LE Low */ + MBI5042GP_LE = PAL_LOW; + + /* Loop 16 - Transfer actual command data to all 3 LED drivers */ + for (int i = 0; i < 16; i++) { + + tmp_r = tmp_g = tmp_b = regValue; + /* Set data bit */ + uint16_t bits = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); + PB->DOUT = bits; + + /* Cycle DCLK */ + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + + if (i == 5) { + MBI5042GP_LE = PAL_HIGH; + } + + /* Next bit to sample */ + regValue <<= 1; + } + + /* Put GPIOB DMASK back */ + PB->DMASK = b_mask; + + /* Reset LE Low */ + MBI5042GP_LE = PAL_LOW; +} + +void MBI5042GP_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { + /* + * @brief Pick a colour! Any colour! + */ + rgb_led led; + + if ( index >= 0 && index < DRIVER_LED_TOTAL ) { + // Convert index into row/column + led = g_rgb_leds[index]; + + // MBI5042GP_planar_recode(led.matrix_co.row, 15 - (led.matrix_co.col), red, green, blue); + if (index == 27 && IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { + MBI5042GP_planar_recode(led.matrix_co.row, led.matrix_co.col, 0xff, 0xff, 0xff); + } else { + MBI5042GP_planar_recode(led.matrix_co.row, led.matrix_co.col, red, green, blue); + } + + g_pwm_buffer_update_required = true; + } +} + +void MBI5042GP_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { + /* + * brief Set every led to the provided colour + */ + + for (int i = 0; i < MBI5042GP_ROW_COUNT; i++) { + for (int j = 0; j < 16; j++) { + if (i == 2) { + if (j == 0) { + if (IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { + MBI5042GP_planar_recode(i, j, 0xff, 0xff, 0xff); + } + } + } else { + MBI5042GP_planar_recode(i, j, red, green, blue); + } + } + } + + g_pwm_buffer_update_required = true; +} + +void MBI5042GP_update_pwm_buffers( void ) { + /** + * Pass current PWM row to MBI5042GP shift registers + * + * LE low + * Outer Loop 16 (one per register transfer - high to low): + * Inner Loop 16 (one per PWM bit): + * R_SDIN, G_SDIN & B_SDIN write + * DCLK High + * DCLK Low + * For final loop, set LE High + * + * Send Global Latch (16 DCLKs with LE high for last 3) + * + * Disable current row + * + * Reset PWM count: + * Loop 3: + * DCLK High + * DCLK Low + * LE High + * Loop 13: + * DCLK High + * DCLK Low + * LE Low + * + * Select new row (row meant for above data) + */ + + uint32_t b_mask; + + /* Set Mask for GPIOB */ + b_mask = PB->DMASK; + PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); + + // LE Low & DCLK Low + MBI5042GP_LE = PAL_LOW; + MBI5042GP_DCLK = PAL_LOW; + + for (int i = 0; i < 16; i++) { + /* Inner Loop 16 */ + for (int j = 0; j < 16; j++) { + + /* R_SDIN/G_SDIN/B_SDIN write */ + PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16*(15 - i) + j]; + + // If j is 15 set LE High + if (j == 15) { + MBI5042GP_LE = PAL_HIGH; + } + + /* Cycle DCLK */ + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + } // Inner Loop 16 + + // LE Low + MBI5042GP_LE = PAL_LOW; + } + + /* Send Global Latch */ + for (int i = 0; i < 16; i++) { + /* Cycle DCLK */ + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + + // if i is 13 set LE high + if (i == 13) { + MBI5042GP_LE = PAL_HIGH; + } + } + + // Reset LE Low + MBI5042GP_LE = PAL_LOW; + + // Reset Masks + PB->DMASK = b_mask; + + // Disable current row + MBI5042GP_disable_rows(); + + // Reset PWM count + // 3 DCLK cycles + for (int i = 0; i < 3; i++) { + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + } + + // Set LE High + MBI5042GP_LE = PAL_HIGH; + + // Loop 13 to generate PWM count reset + for (int i = 0; i < 13; i++) { + MBI5042GP_DCLK = PAL_HIGH; + MBI5042GP_DCLK = PAL_LOW; + } + + // Set LE Low + MBI5042GP_LE = PAL_LOW; + + // Set new row + MBI5042GP_enable_row(g_pwm_buffer_row); + + // increment row count + check + g_pwm_buffer_row++; + if (g_pwm_buffer_row >= MBI5042GP_ROW_COUNT) { + g_pwm_buffer_row = 0; + } +} + +/** + * @brief Write is a zero-output routine to handle the FLUSH from the RGB LED driver calls + * @details Since the RGB data is recoded every time a colour is changed (by the relevant + * single of "all" set_color routines), there is no point at which a mass flush of RGB + * information is needed. The MBI5042GP needs to be fed 16 sets of R, G, or B information + * for each row on a totally different schedule from the animations that affect the colours. + */ +void MBI5042GP_write_pwm_buffers( void ) { + +} + +/** + * @brief Bitwise reorder of RGB information. + * @details Recode the 8-bit standard RGB to 16-bit separated values and + * turn the 16-bit "chunky" values into 16 sequential bitwise "planes" + */ +void MBI5042GP_planar_recode( int row, int column, uint8_t red, uint8_t green, uint8_t blue) { + uint16_t cur_r = pgm_read_word( &CIE1931_16_CURVE[red] ); + uint16_t cur_g = pgm_read_word( &CIE1931_16_CURVE[green] ); + uint16_t cur_b = pgm_read_word( &CIE1931_16_CURVE[blue] ); + + //int row, column; + + for (int i = 0; i < 16; i ++) { + uint16_t tmp_r = cur_r; + uint16_t tmp_g = cur_g; + uint16_t tmp_b = cur_b; + + //g_pwm_buffer[row][0][i * column] = ; + g_pwm_buffer[row][i + (column * 16)] = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); + cur_r <<= 1; + cur_g <<= 1; + cur_b <<= 1; + } +} + +/** + * @brief Disable all LED Rows + */ +void MBI5042GP_disable_rows( void ) { + + // Quick and dirty hardcoded row clear + // 5 rows total + // TODO: Create enum that can be configured for individual MCUs + + // Row 0 + PC4 = PAL_LOW; + + // Row 1 + PC5 = PAL_LOW; + + // Row 2 + PB3 = PAL_LOW; + + // Row 3 + PB2 = PAL_LOW; + + // Row 4 + PD9 = PAL_LOW; +} + +/** + * @brief Disable specific LED row + */ +void MBI5042GP_disable_row( int row ) { + switch (row) { + case 0: // Row 0 + PC4 = PAL_LOW; + break; + case 1: // Row 1 + PC5 = PAL_LOW; + break; + case 2: // Row 2 + PB3 = PAL_LOW; + break; + case 3: // Row 3 + PB2 = PAL_LOW; + break; + case 4: // Row 4 + PD9 = PAL_LOW; + break; + } +} + +/** + * @brief Enable specific LED row + */ +void MBI5042GP_enable_row( int row ) { + switch (row) { + case 0: // Row 0 + PC4 = PAL_HIGH; + break; + case 1: // Row 1 + PC5 = PAL_HIGH; + break; + case 2: // Row 2 + PB3 = PAL_HIGH; + break; + case 3: // Row 3 + PB2 = PAL_HIGH; + break; + case 4: // Row 4 + PD9 = PAL_HIGH; + break; + } +} + + + +OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { + OSAL_IRQ_PROLOGUE(); + + /* Check for PWM1 underflow IRQ */ + if (PWM_GetPeriodIntFlag(PWMA, PWM_CH1) == 1) { + PWM_ClearPeriodIntFlag(PWMA, PWM_CH1); + MBI5042GP_update_pwm_buffers(); + } + + OSAL_IRQ_EPILOGUE(); +} diff --git a/drivers/macroblock/mbi5042gp.h b/drivers/macroblock/mbi5042gp.h new file mode 100644 index 00000000000..21414fd4fc4 --- /dev/null +++ b/drivers/macroblock/mbi5042gp.h @@ -0,0 +1,52 @@ +/* Copyright 2019 /u/KeepItUnder + * + * 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 . + */ + + +#ifndef MBI5024GP_DRIVER_H +#define MBI5024GP_DRIVER_H +#endif + +#include +#include + +/* #define MBI5042GP_CFGREG_DEFAULT 0x002b0ul */ +#define MBI5042GP_CFGREG_DEFAULT 0b1000010000000000u + +#define MBI5042GP_GCLK_GPIO PA12 +#define MBI5042GP_GCLK_SRC PWM0 +#define MBI5042GP_GCLK_SPD 4000000 +#define MBI5042GP_DCLK_GPIO PD4 +#define MBI5042GP_LE PD3 + +#define MBI5042GP_ROW_COUNT 5 +#define MBI5042GP_REFRESH_SPD 2000 + +void MBI5042GP_init( void ); + +void MBI5042GP_set_current_gain( uint8_t gain ); +void MBI5042GP_write_config_register( uint16_t regValue ); + +void MBI5042GP_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); +void MBI5042GP_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); + +void MBI5042GP_update_pwm_buffers( void ); +void MBI5042GP_write_pwm_buffers( void ); + +void MBI5042GP_planar_recode( int row, int column, uint8_t red, uint8_t green, uint8_t blue); + +void MBI5042GP_disable_rows( void ); +void MBI5042GP_disable_row( int row ); +void MBI5042GP_enable_row( int row ); diff --git a/quantum/led_tables.c b/quantum/led_tables.c index 9fbe642cc76..76587f754eb 100644 --- a/quantum/led_tables.c +++ b/quantum/led_tables.c @@ -1,5 +1,6 @@ /* Copyright 2017 Fred Sundvik +Copyright 2019 /u/KeepItUnder 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 @@ -40,4 +41,38 @@ const uint8_t CIE1931_CURVE[256] PROGMEM = { }; #endif +#ifdef USE_CIE1931_16_CURVE +// Lightness curve using the CIE 1931 lightness formula +//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm +const uint16_t CIE1931_16_CURVE[] PROGMEM = { + 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, + 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, + 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, + 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, + 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, + 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, + 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, + 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, + 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, + 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, + 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, + 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, + 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, 3045, 3099, + 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, + 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, + 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, + 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, + 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, + 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, + 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, + 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, + 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, + 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, + 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, + 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, + 15566, 15727, 15890, 16053, 16217, 16383, + }; +#endif + // clang-format on + diff --git a/quantum/led_tables.h b/quantum/led_tables.h index 8052d566cf9..4ce7f3af595 100644 --- a/quantum/led_tables.h +++ b/quantum/led_tables.h @@ -1,5 +1,6 @@ /* Copyright 2017 Fred Sundvik +Copyright 2019 /u/KeepItUnder 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 @@ -23,4 +24,8 @@ along with this program. If not, see . extern const uint8_t CIE1931_CURVE[] PROGMEM; #endif +#ifdef USE_CIE1931_16_CURVE +extern const uint16_t CIE1931_16_CURVE[] PROGMEM; +#endif + #endif diff --git a/quantum/rgb_matrix.h b/quantum/rgb_matrix.h index 771a1fcd35f..784877da0db 100644 --- a/quantum/rgb_matrix.h +++ b/quantum/rgb_matrix.h @@ -1,6 +1,7 @@ /* Copyright 2017 Jason Williams * Copyright 2017 Jack Humbert * Copyright 2018 Yiancar + * Copyright 2019 /u/KeepItUnder * * 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 @@ -36,6 +37,8 @@ # include "is31fl3741.h" #elif defined(WS2812) # include "ws2812.h" +#elif defined (MBI5042) + #include "mbi5042gp.h" #endif #ifndef RGB_MATRIX_LED_FLUSH_LIMIT diff --git a/quantum/rgb_matrix_drivers.c b/quantum/rgb_matrix_drivers.c index 2978e7bed9c..e989e0f0d77 100644 --- a/quantum/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix_drivers.c @@ -1,4 +1,5 @@ /* Copyright 2018 James Laird-Wah + * Copyright 2019 /u/KeepItUnder * * 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 @@ -172,4 +173,23 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color = setled, .set_color_all = setled_all, }; + +#elif defined(MBI5042) + +static void init( void ) +{ + MBI5042GP_init(); +} + +static void flush( void ) +{ + MBI5042GP_write_pwm_buffers(); +} + +const rgb_matrix_driver_t rgb_matrix_driver = { + .init = init, + .flush = flush, + .set_color = MBI5042GP_set_color, + .set_color_all = MBI5042GP_set_color_all, +}; #endif From db0df7cca09ef8109f0dc507a4cf3b51777fc519 Mon Sep 17 00:00:00 2001 From: GitWellBack <48095880+GitWellBack@users.noreply.github.com> Date: Sun, 12 May 2019 23:09:27 +1000 Subject: [PATCH 02/22] Update to cover latest RGB Matrix struct changes --- drivers/macroblock/mbi5042gp.c | 9 +++++---- drivers/macroblock/mbi5042gp.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c index ea7323c9e6a..a1f650f3f7c 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/drivers/macroblock/mbi5042gp.c @@ -295,17 +295,18 @@ void MBI5042GP_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) /* * @brief Pick a colour! Any colour! */ - rgb_led led; + //led_config_t led; + mbi_led led_pos; if ( index >= 0 && index < DRIVER_LED_TOTAL ) { // Convert index into row/column - led = g_rgb_leds[index]; + led_pos = g_mbi_leds[index]; // MBI5042GP_planar_recode(led.matrix_co.row, 15 - (led.matrix_co.col), red, green, blue); if (index == 27 && IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { - MBI5042GP_planar_recode(led.matrix_co.row, led.matrix_co.col, 0xff, 0xff, 0xff); + MBI5042GP_planar_recode(led_pos.row, led_pos.col, 0xff, 0xff, 0xff); } else { - MBI5042GP_planar_recode(led.matrix_co.row, led.matrix_co.col, red, green, blue); + MBI5042GP_planar_recode(led_pos.row, led_pos.col, red, green, blue); } g_pwm_buffer_update_required = true; diff --git a/drivers/macroblock/mbi5042gp.h b/drivers/macroblock/mbi5042gp.h index 21414fd4fc4..dbe31251c35 100644 --- a/drivers/macroblock/mbi5042gp.h +++ b/drivers/macroblock/mbi5042gp.h @@ -22,6 +22,16 @@ #include #include + + +typedef struct mbi_led { + uint8_t row; + uint8_t col; +} __attribute__((packed)) mbi_led; + + +extern const mbi_led g_mbi_leds[DRIVER_LED_TOTAL]; + /* #define MBI5042GP_CFGREG_DEFAULT 0x002b0ul */ #define MBI5042GP_CFGREG_DEFAULT 0b1000010000000000u From 3e5d05e475cf6503f7b5fbe7b39e3b4e9a24e082 Mon Sep 17 00:00:00 2001 From: GitWellBack <48095880+GitWellBack@users.noreply.github.com> Date: Mon, 3 Jun 2019 19:29:23 +1000 Subject: [PATCH 03/22] Update to integrate OSS re-engineer of NUMICRO MCU --- drivers/macroblock/mbi5042gp.c | 40 +++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c index a1f650f3f7c..fcbe95517f0 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/drivers/macroblock/mbi5042gp.c @@ -163,40 +163,50 @@ void MBI5042GP_init( void ) { } } - #if (MBI5042GP_GCLK_SRC == PWM0) - /* Setup PWM control registers for 2MHz (makes a nice clock) - * and also 50 percentage PWM + #if MBI5042GP_GCLK_SRC == PWM0 + /* Setup PWM0 control registers for 2MHz GCLK + * and also 50 percentage PWM duty (makes a nice clock) * * Set PWM1 to be used as a 2kHz timer (interrupt but no output pin) + * which is used for row refresh/enable. */ /* Enable PWM module clock */ - CLK_EnableModuleClock(PWM01_MODULE); + // CLK_EnableModuleClock(PWM01_MODULE); + // clks_lld_enable_module_clock(PWM01_MODULE); + clks_lld_enable_module_clock(PWM01_ModuleNum); /* Select PWM module clock source */ - CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); + // CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); + // clks_lld_set_module_clock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); + clks_lld_set_module_clock(PWM01_ModuleNum, CLK_CLKSEL1_PWM01_S_HCLK, 0); /* Combined method to configure PWM0 */ - PWM_ConfigOutputChannel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); + // PWM_ConfigOutputChannel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); + pwm_lld_config_output_channel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); /* Enable PWM Output path for PWMA channel 0 */ - PWM_EnableOutput(PWMA, 0x1); + // PWM_EnableOutput(PWMA, 0x1); + (PWMA)->POE |= PWM_CH1; /* Set GPIO PA.12/PWM0 to be PWM0 */ SYS->GPA_MFP |= SYS_GPA_MFP_PA12_PWM0; /* PWM1 Config */ /* Combined method to configure PWM1 */ - PWM_ConfigOutputChannel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); + // PWM_ConfigOutputChannel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); + pwm_lld_config_output_channel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); /* Set interrupt handler */ nvicEnableVector(PWMA_IRQn, 1); /* Need an interrupt for PWM1 */ - PWM_EnablePeriodInt(PWMA, PWM_CH1, PWM_PERIOD_INT_UNDERFLOW); + // (PWMA)->PIER = (PWMA)->PIER & ~(PWM_PIER_INT01TYPE_Msk | PWM_PIER_PWMIE1_Msk); + pwm_lld_enable_period_int(PWMA, PWM_CH1, PWM_PERIOD_INT_UNDERFLOW); /* Start PWM0 and PWM1 */ - PWM_Start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); + //PWM_Start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); + pwm_lld_start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); #elif #endif @@ -448,7 +458,7 @@ void MBI5042GP_update_pwm_buffers( void ) { /** * @brief Write is a zero-output routine to handle the FLUSH from the RGB LED driver calls * @details Since the RGB data is recoded every time a colour is changed (by the relevant - * single of "all" set_color routines), there is no point at which a mass flush of RGB + * single or "all" set_color routines), there is no point at which a mass flush of RGB * information is needed. The MBI5042GP needs to be fed 16 sets of R, G, or B information * for each row on a totally different schedule from the animations that affect the colours. */ @@ -558,8 +568,12 @@ OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { OSAL_IRQ_PROLOGUE(); /* Check for PWM1 underflow IRQ */ - if (PWM_GetPeriodIntFlag(PWMA, PWM_CH1) == 1) { - PWM_ClearPeriodIntFlag(PWMA, PWM_CH1); + // if (PWM_GetPeriodIntFlag(PWMA, PWM_CH1) == 1) { + // PWM_ClearPeriodIntFlag(PWMA, PWM_CH1); + // MBI5042GP_update_pwm_buffers(); + // } + if (pwm_lld_get_period_int(PWMA, PWM_CH1) == 1) { + pwm_lld_clear_period_int(PWMA, PWM_CH1); MBI5042GP_update_pwm_buffers(); } From 4cebae53c2e70c5ec465c891090c907da939cfbd Mon Sep 17 00:00:00 2001 From: Reza Jelveh Date: Tue, 1 Dec 2020 20:29:00 +0800 Subject: [PATCH 04/22] mbi5042gp: reduce interrupt priority to 3 Fixes an issue where the rgb light interferes with the keyboard boot --- drivers/macroblock/mbi5042gp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c index fcbe95517f0..df3a09450d2 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/drivers/macroblock/mbi5042gp.c @@ -198,7 +198,7 @@ void MBI5042GP_init( void ) { pwm_lld_config_output_channel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); /* Set interrupt handler */ - nvicEnableVector(PWMA_IRQn, 1); + nvicEnableVector(PWMA_IRQn, 3); /* Need an interrupt for PWM1 */ // (PWMA)->PIER = (PWMA)->PIER & ~(PWM_PIER_INT01TYPE_Msk | PWM_PIER_PWMIE1_Msk); From 436d0ec3f4ced69f4e198b342d91f270876f40b3 Mon Sep 17 00:00:00 2001 From: Reza Jelveh Date: Thu, 3 Dec 2020 14:20:46 +0800 Subject: [PATCH 05/22] mbi5042gp: clang-format files --- drivers/macroblock/mbi5042gp.c | 255 ++++++++++++++++----------------- drivers/macroblock/mbi5042gp.h | 32 ++--- 2 files changed, 138 insertions(+), 149 deletions(-) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c index df3a09450d2..b2b63e6d23a 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/drivers/macroblock/mbi5042gp.c @@ -14,81 +14,81 @@ * along with this program. If not, see . */ -/* +/* * Macroblock's MBI5042GP is a 16-channel constant current LED driver. - * + * * The chip has a data input interface, a set of synchronisation clocks * and 16 PWM output pins capapble of 16-bit PWM. - * + * * Data interface: SDI, SDO, DCLK * General clock: GCLK * Data Latch: LE - * + * * Commands available (differentiated by numbers of rising edge DCLKS) * Command is actioned on subsequent falling edge of LE: - * - * + * + * * Data Latch * ========== - * + * * Take LE high. Keep high for maximum of 1 DCLK rising edges. - * - * Allow LE to fall - falling edge causes serial data to be + * + * Allow LE to fall - falling edge causes serial data to be * transferred to the buffers only. - * - * + * + * * Global Latch * ============ - * + * * Take LE high. Keep high for 2 or 3 DCLK rising edges. - * + * * Allow LE to fall - falling edge causes buffer data to be * transferred to the comparators. - * - * + * + * * Read Configuration * ================== - * + * * Take LE high. Keep high for 4 or 5 DCLK rising edges. - * + * * Allow LE to fall - falling edge moves config data to the * shift registers. - * - * + * + * * Write Configuration * =================== - * + * * Take LE high. Keep high for 10 or 11 DCLK rising edges. - * + * * Allow LE to fall - falling edge transfers serial data * to the configuration register ONLY IF "Enable Writing * Configuration" is sent prior (see below) - * - * + * + * * Reset PWM Counter * ================= - * + * * Take LE high. Keep high for 12 or 13 DCLK rising edges. - * + * * Allow LE to fall - falling edge resets the PWM counter * If bit "B" of the configuration register is "1" - * - * + * + * * Enable Writing Configuration * ============================ - * + * * Take LE high. Keep high for 14 or 15 DCLK rising edges. - * + * * Allow LE to fall - falling edge enables configuration * writing. This should be sent immediately prior to any * attempt to write to configuration register. - * - * + * + * * Configuration Register * ====================== - * + * * 16 bits wide - * + * * MSB Definition Value Function * -------------------------------------------------------------------------------- * | | | 0 (Default) | 15 x data latch + 1 global latch @@ -120,7 +120,7 @@ * 0 | | | | * -------------------------------------------------------------------------------- * LSB - * + * */ //#include "mbi5042gp.h" @@ -130,31 +130,31 @@ #include "led_tables.h" #ifndef MBI5042GP_GCLK_SRC - #define MBI5042GP_GCLK_SRC PWM0 +# define MBI5042GP_GCLK_SRC PWM0 #endif #ifndef MBI5042GP_DCLK - #define MBI5042GP_DCLK PD4 +# define MBI5042GP_DCLK PD4 #endif #ifndef MBI5042GP_LE - #define MBI5042GP_LE PD3 +# define MBI5042GP_LE PD3 #endif /** The PWM buffers the full rows of 16 PWM registers in each MBI5042 driver * The buffers are arranged in serial format * (MSB_R, MSB_G, MSB_B...LSB_R, LSB_G, LSB_B) * as needed by the SDO pins on the MCU (R is B14; G is B13; B is B12) - * + * * g_pwm_buffer has the DCLK-able output for an "R" row, a "G" row, and a "B" row of PWM */ -uint16_t g_pwm_buffer[MBI5042GP_ROW_COUNT][16*16]; +uint16_t g_pwm_buffer[MBI5042GP_ROW_COUNT][16 * 16]; -bool g_pwm_buffer_update_required = false; -uint8_t g_pwm_buffer_row = 0; +bool g_pwm_buffer_update_required = false; +uint8_t g_pwm_buffer_row = 0; -void MBI5042GP_init( void ) { +void MBI5042GP_init(void) { /* Initialise all PWM arrays to zero. * Perform one group transfer to turn LEDs off - * + * * If there's a DMA requirement, set up DMA subsystems */ for (int i = 0; i < MBI5042GP_ROW_COUNT; i++) { @@ -163,53 +163,53 @@ void MBI5042GP_init( void ) { } } - #if MBI5042GP_GCLK_SRC == PWM0 - /* Setup PWM0 control registers for 2MHz GCLK - * and also 50 percentage PWM duty (makes a nice clock) - * - * Set PWM1 to be used as a 2kHz timer (interrupt but no output pin) - * which is used for row refresh/enable. - */ +#if MBI5042GP_GCLK_SRC == PWM0 + /* Setup PWM0 control registers for 2MHz GCLK + * and also 50 percentage PWM duty (makes a nice clock) + * + * Set PWM1 to be used as a 2kHz timer (interrupt but no output pin) + * which is used for row refresh/enable. + */ - /* Enable PWM module clock */ - // CLK_EnableModuleClock(PWM01_MODULE); - // clks_lld_enable_module_clock(PWM01_MODULE); - clks_lld_enable_module_clock(PWM01_ModuleNum); + /* Enable PWM module clock */ + // CLK_EnableModuleClock(PWM01_MODULE); + // clks_lld_enable_module_clock(PWM01_MODULE); + clks_lld_enable_module_clock(PWM01_ModuleNum); - /* Select PWM module clock source */ - // CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); - // clks_lld_set_module_clock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); - clks_lld_set_module_clock(PWM01_ModuleNum, CLK_CLKSEL1_PWM01_S_HCLK, 0); + /* Select PWM module clock source */ + // CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); + // clks_lld_set_module_clock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); + clks_lld_set_module_clock(PWM01_ModuleNum, CLK_CLKSEL1_PWM01_S_HCLK, 0); - /* Combined method to configure PWM0 */ - // PWM_ConfigOutputChannel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); - pwm_lld_config_output_channel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); + /* Combined method to configure PWM0 */ + // PWM_ConfigOutputChannel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); + pwm_lld_config_output_channel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); - /* Enable PWM Output path for PWMA channel 0 */ - // PWM_EnableOutput(PWMA, 0x1); - (PWMA)->POE |= PWM_CH1; + /* Enable PWM Output path for PWMA channel 0 */ + // PWM_EnableOutput(PWMA, 0x1); + (PWMA)->POE |= PWM_CH1; - /* Set GPIO PA.12/PWM0 to be PWM0 */ - SYS->GPA_MFP |= SYS_GPA_MFP_PA12_PWM0; + /* Set GPIO PA.12/PWM0 to be PWM0 */ + SYS->GPA_MFP |= SYS_GPA_MFP_PA12_PWM0; - /* PWM1 Config */ - /* Combined method to configure PWM1 */ - // PWM_ConfigOutputChannel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); - pwm_lld_config_output_channel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); + /* PWM1 Config */ + /* Combined method to configure PWM1 */ + // PWM_ConfigOutputChannel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); + pwm_lld_config_output_channel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); - /* Set interrupt handler */ - nvicEnableVector(PWMA_IRQn, 3); + /* Set interrupt handler */ + nvicEnableVector(PWMA_IRQn, 3); - /* Need an interrupt for PWM1 */ - // (PWMA)->PIER = (PWMA)->PIER & ~(PWM_PIER_INT01TYPE_Msk | PWM_PIER_PWMIE1_Msk); - pwm_lld_enable_period_int(PWMA, PWM_CH1, PWM_PERIOD_INT_UNDERFLOW); + /* Need an interrupt for PWM1 */ + // (PWMA)->PIER = (PWMA)->PIER & ~(PWM_PIER_INT01TYPE_Msk | PWM_PIER_PWMIE1_Msk); + pwm_lld_enable_period_int(PWMA, PWM_CH1, PWM_PERIOD_INT_UNDERFLOW); - /* Start PWM0 and PWM1 */ - //PWM_Start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); - pwm_lld_start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); + /* Start PWM0 and PWM1 */ + // PWM_Start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); + pwm_lld_start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); - #elif - #endif +#elif +#endif MBI5042GP_disable_rows(); @@ -220,12 +220,12 @@ void MBI5042GP_init( void ) { * @brief Set LED driver current gain * @detail The MBI5042 has a 6-bit current gain value (000000b ~ 111111b) * used to adjust the global brightness of the LEDs attached to the PWM outputs - * + * * Default value is 101011b - * + * * Use MBI5042_CURRENT_GAIN to pass from keyboard config */ -void MBI5042GP_set_current_gain( uint8_t gain ) { +void MBI5042GP_set_current_gain(uint8_t gain) { /** MB data transfer requires: * Tell chip config register change is coming (Enable Write Configutarion) * Pass config register data (Write Configuration Register) @@ -242,19 +242,19 @@ void MBI5042GP_set_current_gain( uint8_t gain ) { * @brief Write configuration register ONLY DURING INIT * @detail Set the contents of the configuration register (see top for bitfields) * Each register write needs 2 * 16 bit transfers (1 x setup and 1 x data) - * + * * For the Ducky One 2 mini there are 3 drivers, so output all three configs at once */ -void MBI5042GP_write_config_register( uint16_t regValue ) { +void MBI5042GP_write_config_register(uint16_t regValue) { uint32_t b_mask; uint16_t tmp_r, tmp_g, tmp_b; /* Set Mask for GPIOB */ - b_mask = PB->DMASK; + b_mask = PB->DMASK; PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); /* LE Low & DCLK Low */ - MBI5042GP_LE = PAL_LOW; + MBI5042GP_LE = PAL_LOW; MBI5042GP_DCLK = PAL_LOW; /* Do one DCLK cycle */ @@ -276,11 +276,10 @@ void MBI5042GP_write_config_register( uint16_t regValue ) { /* Loop 16 - Transfer actual command data to all 3 LED drivers */ for (int i = 0; i < 16; i++) { - tmp_r = tmp_g = tmp_b = regValue; /* Set data bit */ uint16_t bits = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); - PB->DOUT = bits; + PB->DOUT = bits; /* Cycle DCLK */ MBI5042GP_DCLK = PAL_HIGH; @@ -301,14 +300,14 @@ void MBI5042GP_write_config_register( uint16_t regValue ) { MBI5042GP_LE = PAL_LOW; } -void MBI5042GP_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) { +void MBI5042GP_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { /* * @brief Pick a colour! Any colour! */ - //led_config_t led; + // led_config_t led; mbi_led led_pos; - if ( index >= 0 && index < DRIVER_LED_TOTAL ) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { // Convert index into row/column led_pos = g_mbi_leds[index]; @@ -323,11 +322,11 @@ void MBI5042GP_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ) } } -void MBI5042GP_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { +void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { /* * brief Set every led to the provided colour */ - + for (int i = 0; i < MBI5042GP_ROW_COUNT; i++) { for (int j = 0; j < 16; j++) { if (i == 2) { @@ -345,10 +344,10 @@ void MBI5042GP_set_color_all( uint8_t red, uint8_t green, uint8_t blue ) { g_pwm_buffer_update_required = true; } -void MBI5042GP_update_pwm_buffers( void ) { +void MBI5042GP_update_pwm_buffers(void) { /** * Pass current PWM row to MBI5042GP shift registers - * + * * LE low * Outer Loop 16 (one per register transfer - high to low): * Inner Loop 16 (one per PWM bit): @@ -356,11 +355,11 @@ void MBI5042GP_update_pwm_buffers( void ) { * DCLK High * DCLK Low * For final loop, set LE High - * + * * Send Global Latch (16 DCLKs with LE high for last 3) - * + * * Disable current row - * + * * Reset PWM count: * Loop 3: * DCLK High @@ -370,26 +369,25 @@ void MBI5042GP_update_pwm_buffers( void ) { * DCLK High * DCLK Low * LE Low - * + * * Select new row (row meant for above data) */ uint32_t b_mask; /* Set Mask for GPIOB */ - b_mask = PB->DMASK; + b_mask = PB->DMASK; PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); // LE Low & DCLK Low - MBI5042GP_LE = PAL_LOW; + MBI5042GP_LE = PAL_LOW; MBI5042GP_DCLK = PAL_LOW; for (int i = 0; i < 16; i++) { /* Inner Loop 16 */ for (int j = 0; j < 16; j++) { - /* R_SDIN/G_SDIN/B_SDIN write */ - PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16*(15 - i) + j]; + PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16 * (15 - i) + j]; // If j is 15 set LE High if (j == 15) { @@ -399,7 +397,7 @@ void MBI5042GP_update_pwm_buffers( void ) { /* Cycle DCLK */ MBI5042GP_DCLK = PAL_HIGH; MBI5042GP_DCLK = PAL_LOW; - } // Inner Loop 16 + } // Inner Loop 16 // LE Low MBI5042GP_LE = PAL_LOW; @@ -462,28 +460,26 @@ void MBI5042GP_update_pwm_buffers( void ) { * information is needed. The MBI5042GP needs to be fed 16 sets of R, G, or B information * for each row on a totally different schedule from the animations that affect the colours. */ -void MBI5042GP_write_pwm_buffers( void ) { - -} +void MBI5042GP_write_pwm_buffers(void) {} /** * @brief Bitwise reorder of RGB information. * @details Recode the 8-bit standard RGB to 16-bit separated values and * turn the 16-bit "chunky" values into 16 sequential bitwise "planes" */ -void MBI5042GP_planar_recode( int row, int column, uint8_t red, uint8_t green, uint8_t blue) { - uint16_t cur_r = pgm_read_word( &CIE1931_16_CURVE[red] ); - uint16_t cur_g = pgm_read_word( &CIE1931_16_CURVE[green] ); - uint16_t cur_b = pgm_read_word( &CIE1931_16_CURVE[blue] ); +void MBI5042GP_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue) { + uint16_t cur_r = pgm_read_word(&CIE1931_16_CURVE[red]); + uint16_t cur_g = pgm_read_word(&CIE1931_16_CURVE[green]); + uint16_t cur_b = pgm_read_word(&CIE1931_16_CURVE[blue]); - //int row, column; + // int row, column; - for (int i = 0; i < 16; i ++) { + for (int i = 0; i < 16; i++) { uint16_t tmp_r = cur_r; uint16_t tmp_g = cur_g; uint16_t tmp_b = cur_b; - //g_pwm_buffer[row][0][i * column] = ; + // g_pwm_buffer[row][0][i * column] = ; g_pwm_buffer[row][i + (column * 16)] = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); cur_r <<= 1; cur_g <<= 1; @@ -494,8 +490,7 @@ void MBI5042GP_planar_recode( int row, int column, uint8_t red, uint8_t green, u /** * @brief Disable all LED Rows */ -void MBI5042GP_disable_rows( void ) { - +void MBI5042GP_disable_rows(void) { // Quick and dirty hardcoded row clear // 5 rows total // TODO: Create enum that can be configured for individual MCUs @@ -519,21 +514,21 @@ void MBI5042GP_disable_rows( void ) { /** * @brief Disable specific LED row */ -void MBI5042GP_disable_row( int row ) { +void MBI5042GP_disable_row(int row) { switch (row) { - case 0: // Row 0 + case 0: // Row 0 PC4 = PAL_LOW; break; - case 1: // Row 1 + case 1: // Row 1 PC5 = PAL_LOW; break; - case 2: // Row 2 + case 2: // Row 2 PB3 = PAL_LOW; break; - case 3: // Row 3 + case 3: // Row 3 PB2 = PAL_LOW; break; - case 4: // Row 4 + case 4: // Row 4 PD9 = PAL_LOW; break; } @@ -542,28 +537,26 @@ void MBI5042GP_disable_row( int row ) { /** * @brief Enable specific LED row */ -void MBI5042GP_enable_row( int row ) { +void MBI5042GP_enable_row(int row) { switch (row) { - case 0: // Row 0 + case 0: // Row 0 PC4 = PAL_HIGH; break; - case 1: // Row 1 + case 1: // Row 1 PC5 = PAL_HIGH; break; - case 2: // Row 2 + case 2: // Row 2 PB3 = PAL_HIGH; break; - case 3: // Row 3 + case 3: // Row 3 PB2 = PAL_HIGH; break; - case 4: // Row 4 + case 4: // Row 4 PD9 = PAL_HIGH; break; } } - - OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { OSAL_IRQ_PROLOGUE(); diff --git a/drivers/macroblock/mbi5042gp.h b/drivers/macroblock/mbi5042gp.h index dbe31251c35..b30a33fcdff 100644 --- a/drivers/macroblock/mbi5042gp.h +++ b/drivers/macroblock/mbi5042gp.h @@ -14,22 +14,18 @@ * along with this program. If not, see . */ - #ifndef MBI5024GP_DRIVER_H -#define MBI5024GP_DRIVER_H +# define MBI5024GP_DRIVER_H #endif #include #include - - typedef struct mbi_led { - uint8_t row; - uint8_t col; + uint8_t row; + uint8_t col; } __attribute__((packed)) mbi_led; - extern const mbi_led g_mbi_leds[DRIVER_LED_TOTAL]; /* #define MBI5042GP_CFGREG_DEFAULT 0x002b0ul */ @@ -44,19 +40,19 @@ extern const mbi_led g_mbi_leds[DRIVER_LED_TOTAL]; #define MBI5042GP_ROW_COUNT 5 #define MBI5042GP_REFRESH_SPD 2000 -void MBI5042GP_init( void ); +void MBI5042GP_init(void); -void MBI5042GP_set_current_gain( uint8_t gain ); -void MBI5042GP_write_config_register( uint16_t regValue ); +void MBI5042GP_set_current_gain(uint8_t gain); +void MBI5042GP_write_config_register(uint16_t regValue); -void MBI5042GP_set_color( int index, uint8_t red, uint8_t green, uint8_t blue ); -void MBI5042GP_set_color_all( uint8_t red, uint8_t green, uint8_t blue ); +void MBI5042GP_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue); -void MBI5042GP_update_pwm_buffers( void ); -void MBI5042GP_write_pwm_buffers( void ); +void MBI5042GP_update_pwm_buffers(void); +void MBI5042GP_write_pwm_buffers(void); -void MBI5042GP_planar_recode( int row, int column, uint8_t red, uint8_t green, uint8_t blue); +void MBI5042GP_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue); -void MBI5042GP_disable_rows( void ); -void MBI5042GP_disable_row( int row ); -void MBI5042GP_enable_row( int row ); +void MBI5042GP_disable_rows(void); +void MBI5042GP_disable_row(int row); +void MBI5042GP_enable_row(int row); From 587987a9406bb764ac3c8502ddcb456131d73bb1 Mon Sep 17 00:00:00 2001 From: Reza Jelveh Date: Thu, 3 Dec 2020 16:17:56 +0800 Subject: [PATCH 06/22] mbi5042gp: update for rebase --- common_features.mk | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/common_features.mk b/common_features.mk index c2c166607a0..cb2eae87d77 100644 --- a/common_features.mk +++ b/common_features.mk @@ -250,8 +250,6 @@ endif SRC += mbi5042gp.c endif - - ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes) OPT_DEFS += -DRGB_MATRIX_CUSTOM_KB endif @@ -359,7 +357,7 @@ ifeq ($(strip $(VISUALIZER_ENABLE)), yes) endif ifeq ($(strip $(CIE1931_CURVE)), yes) - ifeq ($(strip $(RGB_MATRIX_ENABLE)), MBI5042) + ifeq ($(strip $(RGB_MATRIX_DRIVER)), MBI5042) OPT_DEFS += -DUSE_CIE1931_16_CURVE LED_TABLES = yes else From abfc4b6b6dafc0008244734feaff16f94a8950f2 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 17 Dec 2023 17:07:43 +1100 Subject: [PATCH 07/22] Update mbi5042gp driver to work with the one2sf --- drivers/macroblock/mbi5042gp.c | 102 ++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c index b2b63e6d23a..4a909aa74f9 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/drivers/macroblock/mbi5042gp.c @@ -1,4 +1,5 @@ /* Copyright 2019 /u/KeepItUnder + * Copyright 2023 Hayley Hughes * * 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 @@ -124,6 +125,7 @@ */ //#include "mbi5042gp.h" +#include "hal.h" #include #include "progmem.h" #include "rgb_matrix.h" @@ -171,48 +173,68 @@ void MBI5042GP_init(void) { * which is used for row refresh/enable. */ - /* Enable PWM module clock */ - // CLK_EnableModuleClock(PWM01_MODULE); - // clks_lld_enable_module_clock(PWM01_MODULE); - clks_lld_enable_module_clock(PWM01_ModuleNum); + // Use the HCLK + // Note we need to 0 the bits first as the clksel register has a reset value + // of 0xFFFF_FFFF + CLK->CLKSEL1 &= ~CLK_CLKSEL1_PWM01_S_Msk; + CLK->CLKSEL1 |= 2 << CLK_CLKSEL1_PWM01_S_Pos; - /* Select PWM module clock source */ - // CLK_SetModuleClock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); - // clks_lld_set_module_clock(PWM01_MODULE, CLK_CLKSEL1_PWM01_S_HCLK | CLK_CLKSEL2_PWM01_EXT_HCLK, 0); - clks_lld_set_module_clock(PWM01_ModuleNum, CLK_CLKSEL1_PWM01_S_HCLK, 0); + CLK->CLKSEL2 &= ~CLK_CLKSEL2_PWM01_S_E_Msk; + CLK->CLKSEL2 |= 2 << CLK_CLKSEL2_PWM01_S_E_Pos; - /* Combined method to configure PWM0 */ - // PWM_ConfigOutputChannel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); - pwm_lld_config_output_channel(PWMA, PWM_CH0, MBI5042GP_GCLK_SPD, 50); + // Enable the PWM peripheral clock + CLK->APBCLK |= 1 << CLK_APBCLK_PWM01_EN_Pos; - /* Enable PWM Output path for PWMA channel 0 */ - // PWM_EnableOutput(PWMA, 0x1); - (PWMA)->POE |= PWM_CH1; + // Set prescaler for PWM0 and PWM1 to 1 + PWMA->PPR |= 1 << PWM_PPR_CP01_Pos; - /* Set GPIO PA.12/PWM0 to be PWM0 */ - SYS->GPA_MFP |= SYS_GPA_MFP_PA12_PWM0; + // Enable PWM interrupt vector + // Interrupt priority value taken from chibios defaults + nvicEnableVector(NUC123_PWMA_NUMBER, 3); - /* PWM1 Config */ - /* Combined method to configure PWM1 */ - // PWM_ConfigOutputChannel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); - pwm_lld_config_output_channel(PWMA, PWM_CH1, MBI5042GP_REFRESH_SPD, 50); + // Set clock division to 1 + PWMA->CSR |= 1 << PWM_CSR_CSR2_Pos; - /* Set interrupt handler */ - nvicEnableVector(PWMA_IRQn, 3); + // Set pin PA12 to PWM0 + SYS->GPA_MFP |= 1 << 12; - /* Need an interrupt for PWM1 */ - // (PWMA)->PIER = (PWMA)->PIER & ~(PWM_PIER_INT01TYPE_Msk | PWM_PIER_PWMIE1_Msk); - pwm_lld_enable_period_int(PWMA, PWM_CH1, PWM_PERIOD_INT_UNDERFLOW); + // Enable PWM0 output + PWMA->POE |= 1 << PWM_POE_PWM0_Pos; - /* Start PWM0 and PWM1 */ - // PWM_Start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); - pwm_lld_start(PWMA, (0x1u << PWM_CH0 | 0x1u << PWM_CH1)); + // Enable PWM0 and PWM1 auto reload + PWMA->PCR |= (1 << PWM_PCR_CH0MOD_Pos | 1 << PWM_PCR_CH1MOD_Pos); + + // Enable PWM1 reset interrupt + PWMA->PIER |= 1 << PWM_PIER_PWMIE1_Pos; + + // Set PWM0 freq to 9MHz and 50% duty cycle (it's just a nice clock) + // + // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] + // 72MHz/(1 + 1)*(1)*(3+1) + // + // duty = (CMR+1)/(CNR+1) + // (1+1)/(3+1) + PWMA->CNR0 = 3; + PWMA->CMR0 = 1; + + // Set PWM1 freq to 1.8kHz (duty doesn't matter) + // + // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] + // 72MHz/(1 + 1)*(1)*(3+1) + PWMA->CNR1 = 19999; + PWMA->CMR1 = 1; + + // Start PWM channel 0 and 1 + PWMA->PCR |= (1 << PWM_PCR_CH0EN_Pos | 1 << PWM_PCR_CH1EN_Pos); #elif #endif MBI5042GP_disable_rows(); + // Enable the LED controllers + PD5 = PAL_LOW; + MBI5042GP_set_current_gain(0b000011u); } @@ -312,11 +334,11 @@ void MBI5042GP_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { led_pos = g_mbi_leds[index]; // MBI5042GP_planar_recode(led.matrix_co.row, 15 - (led.matrix_co.col), red, green, blue); - if (index == 27 && IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { - MBI5042GP_planar_recode(led_pos.row, led_pos.col, 0xff, 0xff, 0xff); - } else { + /* if (index == 27 && IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { */ + /* MBI5042GP_planar_recode(led_pos.row, led_pos.col, 0xff, 0xff, 0xff); */ + /* } else { */ MBI5042GP_planar_recode(led_pos.row, led_pos.col, red, green, blue); - } + /* } */ g_pwm_buffer_update_required = true; } @@ -331,9 +353,9 @@ void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { for (int j = 0; j < 16; j++) { if (i == 2) { if (j == 0) { - if (IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { - MBI5042GP_planar_recode(i, j, 0xff, 0xff, 0xff); - } + /* if (IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { */ + /* MBI5042GP_planar_recode(i, j, 0xff, 0xff, 0xff); */ + /* } */ } } else { MBI5042GP_planar_recode(i, j, red, green, blue); @@ -561,12 +583,10 @@ OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { OSAL_IRQ_PROLOGUE(); /* Check for PWM1 underflow IRQ */ - // if (PWM_GetPeriodIntFlag(PWMA, PWM_CH1) == 1) { - // PWM_ClearPeriodIntFlag(PWMA, PWM_CH1); - // MBI5042GP_update_pwm_buffers(); - // } - if (pwm_lld_get_period_int(PWMA, PWM_CH1) == 1) { - pwm_lld_clear_period_int(PWMA, PWM_CH1); + if ((PWMA->PIIR >> PWM_PIIR_PWMIF1_Pos) & 1) { + /* Clear interrupt flag */ + PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; + MBI5042GP_update_pwm_buffers(); } From 54528096f2fef034e90c6af386aa366eba7fd7ef Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 17 Dec 2023 17:08:31 +1100 Subject: [PATCH 08/22] Add the ducky one2mini led config This needs changing to suit the one2sf but is enough to test the mbi5042 driver --- keyboards/ducky/one2sf/1967st/1967st.c | 64 +++++++++++++++++++++++++ keyboards/ducky/one2sf/1967st/config.h | 7 +++ keyboards/ducky/one2sf/1967st/info.json | 3 ++ keyboards/ducky/one2sf/1967st/rules.mk | 2 + 4 files changed, 76 insertions(+) create mode 100644 keyboards/ducky/one2sf/1967st/1967st.c diff --git a/keyboards/ducky/one2sf/1967st/1967st.c b/keyboards/ducky/one2sf/1967st/1967st.c new file mode 100644 index 00000000000..732e527a7fa --- /dev/null +++ b/keyboards/ducky/one2sf/1967st/1967st.c @@ -0,0 +1,64 @@ +/* Copyright 2019 /u/KeepItUnder + * Copyright 2023 Hayley Hughes + * + * 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 . + */ + +#include "config.h" +#include "quantum.h" + +const mbi_led g_mbi_leds[DRIVER_LED_TOTAL] = { + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, + { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, + { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 12 }, { 2, 13 }, + { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, + { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 5 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 4, 13 } +}; + +led_config_t g_led_config = { { +/** + * RGB Layout + * + * 0_0, 0_1, 0_2, 0_3, 0_4, 0_5, 0_6, 0_7, 0_8, 0_9, 0_10, 0_11, 0_12, 0_13 + * 1_0, 1_1, 1_2, 1_3, 1_4, 1_5, 1_6, 1_7, 1_8, 1_9, 1_10, 1_11, 1_12, ---- + * 2_0, 2_1, 2_2, 2_3, 2_4, 2_5, 2_6, 2_7, 2_8, 2_9, 2_10, 2_11, 2_12, 2_13 + * 3_0, 3_1, 3_2, 3_3, 3_4, 3_5, 3_6, 3_7, 3_8, 3_9, 3_10, 3_11, 3_12, ---- + * 4_0, 4_1, 4_2, ---, ---, 4_5, ---, ---, ---, ---, 4_10, 4_11, 4_12, 4_13 + * + */ + // Key Matrix to LED Index + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, NO_LED, NO_LED}, + { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, NO_LED, NO_LED, NO_LED }, + { 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, NO_LED, NO_LED }, + { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, NO_LED, 53, NO_LED, NO_LED }, + { 54, 55, 56, NO_LED, NO_LED, 57, NO_LED, NO_LED, NO_LED, NO_LED, 58, 59, 60, 61, NO_LED, NO_LED } +}, { + // Esc, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, Backspace + { 0, 0 }, { 16, 0 }, { 32, 0 }, { 48, 0 }, { 64, 0 }, {80, 0 }, { 96, 0 }, { 112, 0 }, { 128, 0 }, { 144, 0 }, {160, 0 }, {176, 0 }, { 192, 0 }, { 224, 0 }, + // Tab, Q, W, E, R, T, Y, U, I, O, P, [, ] + { 0, 16 }, { 16, 16 }, { 32, 16 }, { 48, 16 }, { 64, 16 }, {80, 16 }, { 96, 16 }, { 112, 16 }, { 128, 16 }, { 144, 16 }, {160, 16 }, {176, 16 }, { 192, 16 }, + // Caps Lock, A, S, D, F, G, H, J, K, L, ;, ', #, Enter + { 0, 32 }, { 16, 32 }, { 32, 32 }, { 48, 32 }, { 64, 32 }, {80, 32 }, { 96, 32 }, { 112, 32 }, { 128, 32 }, { 144, 32 }, {160, 32 }, {176, 32 }, { 192, 32 }, { 224, 32 }, + // Shift, \, Z, X, C, V, B, N, M, ,, ., /, Shift + { 0, 48 }, { 16, 48 }, { 32, 48 }, { 48, 48 }, { 64, 48 }, {80, 48 }, { 96, 48 }, { 112, 48 }, { 128, 48 }, { 144, 48 }, {160, 48 }, {176, 48 }, { 224, 48 }, + // Ctrl, Win, Alt, Space, AltGr, Win, Fn, Ctrl + { 0, 64 }, { 16, 64 }, { 32, 64 }, {80, 64 }, {160, 64 }, {176, 64 }, { 192, 64 }, { 224, 64 } +}, { + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, + 5, 5, 5, 4, 5, 5, 5, 5 + +} }; diff --git a/keyboards/ducky/one2sf/1967st/config.h b/keyboards/ducky/one2sf/1967st/config.h index 92448f54d16..4a4f511b9b0 100644 --- a/keyboards/ducky/one2sf/1967st/config.h +++ b/keyboards/ducky/one2sf/1967st/config.h @@ -20,3 +20,10 @@ along with this program. If not, see . #define DIP_SWITCH_MATRIX_GRID { {0,14}, {1,14}, {2,14}, {3,14} } #define GPIO_INPUT_PIN_DELAY (NUC123_HCLK / 6 / 1000000L) + +#define RGB_MATRIX_LED_COUNT 69 +#define DRIVER_LED_TOTAL RGB_MATRIX_LED_COUNT + +#define ENABLE_RGB_MATRIX_BREATHING +#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN +#define ENABLE_RGB_MATRIX_RAINBOW_BEACON diff --git a/keyboards/ducky/one2sf/1967st/info.json b/keyboards/ducky/one2sf/1967st/info.json index 72ba3c8ae85..bddea2cd54b 100644 --- a/keyboards/ducky/one2sf/1967st/info.json +++ b/keyboards/ducky/one2sf/1967st/info.json @@ -8,6 +8,9 @@ "device_version": "0.0.1", "force_nkro": true }, + "rgb_matrix": { + "driver": "MBI5042" + }, "matrix_pins": { "cols": ["B10", "B9", "C13", "C12", "C11", "C10", "C9", "C8", "A15", "A14", "A13", "D0", "D1", "D2", "B15", "B8"], "rows": ["D11", "B4", "B5", "B6", "B7"] diff --git a/keyboards/ducky/one2sf/1967st/rules.mk b/keyboards/ducky/one2sf/1967st/rules.mk index b7db490c11e..33ac599a8fe 100644 --- a/keyboards/ducky/one2sf/1967st/rules.mk +++ b/keyboards/ducky/one2sf/1967st/rules.mk @@ -30,3 +30,5 @@ RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output DIP_SWITCH_ENABLE = yes +RGB_MATRIX_ENABLE = yes + From d9430b6ee293722c301ba7f43e44d0da1a8466ca Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 17 Dec 2023 17:13:28 +1100 Subject: [PATCH 09/22] Flip the LED positions --- drivers/macroblock/mbi5042gp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/macroblock/mbi5042gp.c b/drivers/macroblock/mbi5042gp.c index 4a909aa74f9..178b57393a1 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/drivers/macroblock/mbi5042gp.c @@ -353,8 +353,6 @@ void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { for (int j = 0; j < 16; j++) { if (i == 2) { if (j == 0) { - /* if (IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { */ - /* MBI5042GP_planar_recode(i, j, 0xff, 0xff, 0xff); */ /* } */ } } else { @@ -409,7 +407,7 @@ void MBI5042GP_update_pwm_buffers(void) { /* Inner Loop 16 */ for (int j = 0; j < 16; j++) { /* R_SDIN/G_SDIN/B_SDIN write */ - PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16 * (15 - i) + j]; + PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16 * i + j]; // If j is 15 set LE High if (j == 15) { From 7f420cad285eef35d1bf55962e41fc04d0bfd8c3 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 17 Dec 2023 19:29:23 +1100 Subject: [PATCH 10/22] Change led config to match the one2sf board --- keyboards/ducky/one2sf/1967st/1967st.c | 57 ++++++++++---------------- keyboards/ducky/one2sf/1967st/config.h | 3 +- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/1967st.c b/keyboards/ducky/one2sf/1967st/1967st.c index 732e527a7fa..88699662a8a 100644 --- a/keyboards/ducky/one2sf/1967st/1967st.c +++ b/keyboards/ducky/one2sf/1967st/1967st.c @@ -18,47 +18,32 @@ #include "config.h" #include "quantum.h" +// Map physical layout to QMK led index const mbi_led g_mbi_leds[DRIVER_LED_TOTAL] = { - { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, - { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, - { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 12 }, { 2, 13 }, - { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, - { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 5 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 4, 13 } + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, { 0, 14 }, + { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, { 1, 13 }, { 1, 14 }, + { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 13 }, { 2, 14 }, + { 3, 0 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, { 3, 13 }, + { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 5 }, { 4, 7 }, { 4, 9 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 4, 13 }, { 4, 14 } }; led_config_t g_led_config = { { -/** - * RGB Layout - * - * 0_0, 0_1, 0_2, 0_3, 0_4, 0_5, 0_6, 0_7, 0_8, 0_9, 0_10, 0_11, 0_12, 0_13 - * 1_0, 1_1, 1_2, 1_3, 1_4, 1_5, 1_6, 1_7, 1_8, 1_9, 1_10, 1_11, 1_12, ---- - * 2_0, 2_1, 2_2, 2_3, 2_4, 2_5, 2_6, 2_7, 2_8, 2_9, 2_10, 2_11, 2_12, 2_13 - * 3_0, 3_1, 3_2, 3_3, 3_4, 3_5, 3_6, 3_7, 3_8, 3_9, 3_10, 3_11, 3_12, ---- - * 4_0, 4_1, 4_2, ---, ---, 4_5, ---, ---, ---, ---, 4_10, 4_11, 4_12, 4_13 - * - */ // Key Matrix to LED Index - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, NO_LED, NO_LED}, - { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, NO_LED, NO_LED, NO_LED }, - { 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, NO_LED, NO_LED }, - { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, NO_LED, 53, NO_LED, NO_LED }, - { 54, 55, 56, NO_LED, NO_LED, 57, NO_LED, NO_LED, NO_LED, NO_LED, 58, 59, 60, 61, NO_LED, NO_LED } + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, + { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }, + { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, NO_LED, 42, 43 }, + { 44, NO_LED, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, NO_LED }, + { 57, 58, 59, 60, NO_LED, 61, NO_LED, 62, NO_LED, 63, 64, 65, 66, 67, 68 }, }, { - // Esc, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, -, =, Backspace - { 0, 0 }, { 16, 0 }, { 32, 0 }, { 48, 0 }, { 64, 0 }, {80, 0 }, { 96, 0 }, { 112, 0 }, { 128, 0 }, { 144, 0 }, {160, 0 }, {176, 0 }, { 192, 0 }, { 224, 0 }, - // Tab, Q, W, E, R, T, Y, U, I, O, P, [, ] - { 0, 16 }, { 16, 16 }, { 32, 16 }, { 48, 16 }, { 64, 16 }, {80, 16 }, { 96, 16 }, { 112, 16 }, { 128, 16 }, { 144, 16 }, {160, 16 }, {176, 16 }, { 192, 16 }, - // Caps Lock, A, S, D, F, G, H, J, K, L, ;, ', #, Enter - { 0, 32 }, { 16, 32 }, { 32, 32 }, { 48, 32 }, { 64, 32 }, {80, 32 }, { 96, 32 }, { 112, 32 }, { 128, 32 }, { 144, 32 }, {160, 32 }, {176, 32 }, { 192, 32 }, { 224, 32 }, - // Shift, \, Z, X, C, V, B, N, M, ,, ., /, Shift - { 0, 48 }, { 16, 48 }, { 32, 48 }, { 48, 48 }, { 64, 48 }, {80, 48 }, { 96, 48 }, { 112, 48 }, { 128, 48 }, { 144, 48 }, {160, 48 }, {176, 48 }, { 224, 48 }, - // Ctrl, Win, Alt, Space, AltGr, Win, Fn, Ctrl - { 0, 64 }, { 16, 64 }, { 32, 64 }, {80, 64 }, {160, 64 }, {176, 64 }, { 192, 64 }, { 224, 64 } + { 0, 0 }, { 16, 0 }, { 32, 0 }, { 48, 0 }, { 64, 0 }, { 80, 0 }, { 96, 0 }, { 112, 0 }, { 128, 0 }, { 144, 0 }, { 160, 0 }, { 176, 0 }, { 192, 0 }, { 208, 0 }, { 224, 0 }, + { 0, 16 }, { 16, 16 }, { 32, 16 }, { 48, 16 }, { 64, 16 }, { 80, 16 }, { 96, 16 }, { 112, 16 }, { 128, 16 }, { 144, 16 }, { 160, 16 }, { 176, 16 }, { 192, 16 }, { 208, 16 }, { 224, 16 }, + { 0, 32 }, { 16, 32 }, { 32, 32 }, { 48, 32 }, { 64, 32 }, { 80, 32 }, { 96, 32 }, { 112, 32 }, { 128, 32 }, { 144, 32 }, { 160, 32 }, { 176, 32 }, { 208, 32 }, { 224, 32 }, + { 0, 48 }, { 32, 48 }, { 48, 48 }, { 64, 48 }, { 80, 48 }, { 96, 48 }, { 112, 48 }, { 128, 48 }, { 144, 48 }, { 160, 48 }, { 176, 48 }, { 192, 48 }, { 208, 48 }, + { 0, 64 }, { 16, 64 }, { 32, 64 }, { 48, 64 }, { 80, 64 }, { 112, 64 }, { 144, 64 }, { 160, 64 }, { 176, 64 }, { 192, 64 }, { 208, 64 }, { 224, 64 } }, { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, - 5, 5, 5, 4, 5, 5, 5, 5 - + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, + 5, 5, 5, 4, 4, 4, 5, 5, 5, 4, 4, 4 } }; diff --git a/keyboards/ducky/one2sf/1967st/config.h b/keyboards/ducky/one2sf/1967st/config.h index 4a4f511b9b0..a609ba73d3f 100644 --- a/keyboards/ducky/one2sf/1967st/config.h +++ b/keyboards/ducky/one2sf/1967st/config.h @@ -1,5 +1,6 @@ /* Copyright 2019 /u/KeepItUnder +Copyright 2023 Hayley Hughes 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 @@ -25,5 +26,5 @@ along with this program. If not, see . #define DRIVER_LED_TOTAL RGB_MATRIX_LED_COUNT #define ENABLE_RGB_MATRIX_BREATHING -#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN #define ENABLE_RGB_MATRIX_RAINBOW_BEACON +#define ENABLE_RGB_MATRIX_TYPING_HEATMAP From 41dc4aefcf6668cdb55239bc6818ff0124264952 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Mon, 18 Dec 2023 11:22:57 +1100 Subject: [PATCH 11/22] Move led driver into the keyboard --- builddefs/common_features.mk | 18 +- drivers/macroblock/mbi5042gp.h | 58 ---- keyboards/ducky/one2sf/1967st/1967st.c | 34 +- keyboards/ducky/one2sf/1967st/config.h | 1 - keyboards/ducky/one2sf/1967st/info.json | 2 +- .../ducky/one2sf/1967st/rgb_matrix_drivers.c | 320 ++++++++---------- keyboards/ducky/one2sf/1967st/rules.mk | 1 + quantum/led_tables.c | 35 -- quantum/rgb_matrix/rgb_matrix.h | 3 - quantum/rgb_matrix/rgb_matrix_drivers.c | 21 -- 10 files changed, 155 insertions(+), 338 deletions(-) delete mode 100644 drivers/macroblock/mbi5042gp.h rename drivers/macroblock/mbi5042gp.c => keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c (60%) diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index d2cca1dc8af..094eda6fef6 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -416,7 +416,7 @@ endif RGB_MATRIX_ENABLE ?= no -VALID_RGB_MATRIX_TYPES := aw20216 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a ckled2001 ws2812 MBI5042 custom +VALID_RGB_MATRIX_TYPES := aw20216 is31fl3731 is31fl3733 is31fl3736 is31fl3737 is31fl3741 is31fl3742a is31fl3743a is31fl3745 is31fl3746a ckled2001 ws2812 custom ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),) $(call CATASTROPHIC_ERROR,Invalid RGB_MATRIX_DRIVER,RGB_MATRIX_DRIVER="$(RGB_MATRIX_DRIVER)" is not a valid matrix type) @@ -524,12 +524,6 @@ endif APA102_DRIVER_REQUIRED := yes endif - ifeq ($(strip $(RGB_MATRIX_DRIVER)), MBI5042) - OPT_DEFS += -DMBI5042 - COMMON_VPATH += $(DRIVER_PATH)/macroblock - SRC += mbi5042gp.c - endif - ifeq ($(strip $(RGB_MATRIX_CUSTOM_KB)), yes) OPT_DEFS += -DRGB_MATRIX_CUSTOM_KB endif @@ -615,13 +609,8 @@ ifeq ($(strip $(APA102_DRIVER_REQUIRED)), yes) endif ifeq ($(strip $(CIE1931_CURVE)), yes) - ifeq ($(strip $(RGB_MATRIX_DRIVER)), MBI5042) - OPT_DEFS += -DUSE_CIE1931_16_CURVE - LED_TABLES := yes - else - OPT_DEFS += -DUSE_CIE1931_CURVE - LED_TABLES := yes - endif + OPT_DEFS += -DUSE_CIE1931_CURVE + LED_TABLES := yes endif ifeq ($(strip $(LED_TABLES)), yes) @@ -657,7 +646,6 @@ CUSTOM_MATRIX ?= no ifneq ($(strip $(CUSTOM_MATRIX)), yes) ifeq ($(filter $(CUSTOM_MATRIX),$(VALID_CUSTOM_MATRIX_TYPES)),) - $(call CATASTROPHIC_ERROR,Invalid CUSTOM_MATRIX,CUSTOM_MATRIX="$(CUSTOM_MATRIX)" is not a valid custom matrix type) endif diff --git a/drivers/macroblock/mbi5042gp.h b/drivers/macroblock/mbi5042gp.h deleted file mode 100644 index b30a33fcdff..00000000000 --- a/drivers/macroblock/mbi5042gp.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2019 /u/KeepItUnder - * - * 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 . - */ - -#ifndef MBI5024GP_DRIVER_H -# define MBI5024GP_DRIVER_H -#endif - -#include -#include - -typedef struct mbi_led { - uint8_t row; - uint8_t col; -} __attribute__((packed)) mbi_led; - -extern const mbi_led g_mbi_leds[DRIVER_LED_TOTAL]; - -/* #define MBI5042GP_CFGREG_DEFAULT 0x002b0ul */ -#define MBI5042GP_CFGREG_DEFAULT 0b1000010000000000u - -#define MBI5042GP_GCLK_GPIO PA12 -#define MBI5042GP_GCLK_SRC PWM0 -#define MBI5042GP_GCLK_SPD 4000000 -#define MBI5042GP_DCLK_GPIO PD4 -#define MBI5042GP_LE PD3 - -#define MBI5042GP_ROW_COUNT 5 -#define MBI5042GP_REFRESH_SPD 2000 - -void MBI5042GP_init(void); - -void MBI5042GP_set_current_gain(uint8_t gain); -void MBI5042GP_write_config_register(uint16_t regValue); - -void MBI5042GP_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void MBI5042GP_update_pwm_buffers(void); -void MBI5042GP_write_pwm_buffers(void); - -void MBI5042GP_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue); - -void MBI5042GP_disable_rows(void); -void MBI5042GP_disable_row(int row); -void MBI5042GP_enable_row(int row); diff --git a/keyboards/ducky/one2sf/1967st/1967st.c b/keyboards/ducky/one2sf/1967st/1967st.c index 88699662a8a..14eb70c49f4 100644 --- a/keyboards/ducky/one2sf/1967st/1967st.c +++ b/keyboards/ducky/one2sf/1967st/1967st.c @@ -18,32 +18,24 @@ #include "config.h" #include "quantum.h" -// Map physical layout to QMK led index -const mbi_led g_mbi_leds[DRIVER_LED_TOTAL] = { - { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, { 0, 14 }, - { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, { 1, 13 }, { 1, 14 }, - { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 13 }, { 2, 14 }, - { 3, 0 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, { 3, 13 }, - { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 5 }, { 4, 7 }, { 4, 9 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 4, 13 }, { 4, 14 } -}; - led_config_t g_led_config = { { // Key Matrix to LED Index - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, - { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }, - { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, NO_LED, 42, 43 }, - { 44, NO_LED, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, NO_LED }, - { 57, 58, 59, 60, NO_LED, 61, NO_LED, 62, NO_LED, 63, 64, 65, 66, 67, 68 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, NO_LED}, + { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, NO_LED}, + { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, NO_LED, 42, 43, NO_LED}, + { 44, NO_LED, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, NO_LED, NO_LED}, + { 57, 58, 59, 60, NO_LED, 61, NO_LED, 62, NO_LED, 63, 64, 65, 66, 67, 68, NO_LED}, }, { - { 0, 0 }, { 16, 0 }, { 32, 0 }, { 48, 0 }, { 64, 0 }, { 80, 0 }, { 96, 0 }, { 112, 0 }, { 128, 0 }, { 144, 0 }, { 160, 0 }, { 176, 0 }, { 192, 0 }, { 208, 0 }, { 224, 0 }, - { 0, 16 }, { 16, 16 }, { 32, 16 }, { 48, 16 }, { 64, 16 }, { 80, 16 }, { 96, 16 }, { 112, 16 }, { 128, 16 }, { 144, 16 }, { 160, 16 }, { 176, 16 }, { 192, 16 }, { 208, 16 }, { 224, 16 }, - { 0, 32 }, { 16, 32 }, { 32, 32 }, { 48, 32 }, { 64, 32 }, { 80, 32 }, { 96, 32 }, { 112, 32 }, { 128, 32 }, { 144, 32 }, { 160, 32 }, { 176, 32 }, { 208, 32 }, { 224, 32 }, - { 0, 48 }, { 32, 48 }, { 48, 48 }, { 64, 48 }, { 80, 48 }, { 96, 48 }, { 112, 48 }, { 128, 48 }, { 144, 48 }, { 160, 48 }, { 176, 48 }, { 192, 48 }, { 208, 48 }, + { 0, 0 }, { 16, 0 }, { 32, 0 }, { 48, 0 }, { 64, 0 }, { 80, 0 }, { 96, 0 }, { 112, 0 }, { 128, 0 }, { 144, 0 }, { 160, 0 }, { 176, 0 }, { 192, 0 }, { 208, 0 }, { 224, 0 }, + { 0, 16 }, { 16, 16 }, { 32, 16 }, { 48, 16 }, { 64, 16 }, { 80, 16 }, { 96, 16 }, { 112, 16 }, { 128, 16 }, { 144, 16 }, { 160, 16 }, { 176, 16 }, { 192, 16 }, { 208, 16 }, { 224, 16 }, + { 0, 32 }, { 16, 32 }, { 32, 32 }, { 48, 32 }, { 64, 32 }, { 80, 32 }, { 96, 32 }, { 112, 32 }, { 128, 32 }, { 144, 32 }, { 160, 32 }, { 176, 32 }, { 208, 32 }, { 224, 32 }, + { 0, 48 }, { 32, 48 }, { 48, 48 }, { 64, 48 }, { 80, 48 }, { 96, 48 }, { 112, 48 }, { 128, 48 }, { 144, 48 }, { 160, 48 }, { 176, 48 }, { 192, 48 }, { 208, 48 }, { 0, 64 }, { 16, 64 }, { 32, 64 }, { 48, 64 }, { 80, 64 }, { 112, 64 }, { 144, 64 }, { 160, 64 }, { 176, 64 }, { 192, 64 }, { 208, 64 }, { 224, 64 } }, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, + 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 4, 4, 4 -} }; +} }; + diff --git a/keyboards/ducky/one2sf/1967st/config.h b/keyboards/ducky/one2sf/1967st/config.h index a609ba73d3f..966eb307eab 100644 --- a/keyboards/ducky/one2sf/1967st/config.h +++ b/keyboards/ducky/one2sf/1967st/config.h @@ -23,7 +23,6 @@ along with this program. If not, see . #define GPIO_INPUT_PIN_DELAY (NUC123_HCLK / 6 / 1000000L) #define RGB_MATRIX_LED_COUNT 69 -#define DRIVER_LED_TOTAL RGB_MATRIX_LED_COUNT #define ENABLE_RGB_MATRIX_BREATHING #define ENABLE_RGB_MATRIX_RAINBOW_BEACON diff --git a/keyboards/ducky/one2sf/1967st/info.json b/keyboards/ducky/one2sf/1967st/info.json index bddea2cd54b..8cc3f92a329 100644 --- a/keyboards/ducky/one2sf/1967st/info.json +++ b/keyboards/ducky/one2sf/1967st/info.json @@ -9,7 +9,7 @@ "force_nkro": true }, "rgb_matrix": { - "driver": "MBI5042" + "driver": "custom" }, "matrix_pins": { "cols": ["B10", "B9", "C13", "C12", "C11", "C10", "C9", "C8", "A15", "A14", "A13", "D0", "D1", "D2", "B15", "B8"], diff --git a/drivers/macroblock/mbi5042gp.c b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c similarity index 60% rename from drivers/macroblock/mbi5042gp.c rename to keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c index 178b57393a1..f89b5d97d96 100644 --- a/drivers/macroblock/mbi5042gp.c +++ b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c @@ -1,5 +1,5 @@ /* Copyright 2019 /u/KeepItUnder - * Copyright 2023 Hayley Hughes + * Copyright 2023 Hayley Hughes * * 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 @@ -16,130 +16,69 @@ */ /* - * Macroblock's MBI5042GP is a 16-channel constant current LED driver. - * - * The chip has a data input interface, a set of synchronisation clocks - * and 16 PWM output pins capapble of 16-bit PWM. - * - * Data interface: SDI, SDO, DCLK - * General clock: GCLK - * Data Latch: LE - * - * Commands available (differentiated by numbers of rising edge DCLKS) - * Command is actioned on subsequent falling edge of LE: - * - * - * Data Latch - * ========== - * - * Take LE high. Keep high for maximum of 1 DCLK rising edges. - * - * Allow LE to fall - falling edge causes serial data to be - * transferred to the buffers only. - * - * - * Global Latch - * ============ - * - * Take LE high. Keep high for 2 or 3 DCLK rising edges. - * - * Allow LE to fall - falling edge causes buffer data to be - * transferred to the comparators. - * - * - * Read Configuration - * ================== - * - * Take LE high. Keep high for 4 or 5 DCLK rising edges. - * - * Allow LE to fall - falling edge moves config data to the - * shift registers. - * - * - * Write Configuration - * =================== - * - * Take LE high. Keep high for 10 or 11 DCLK rising edges. - * - * Allow LE to fall - falling edge transfers serial data - * to the configuration register ONLY IF "Enable Writing - * Configuration" is sent prior (see below) - * - * - * Reset PWM Counter - * ================= - * - * Take LE high. Keep high for 12 or 13 DCLK rising edges. - * - * Allow LE to fall - falling edge resets the PWM counter - * If bit "B" of the configuration register is "1" - * - * - * Enable Writing Configuration - * ============================ - * - * Take LE high. Keep high for 14 or 15 DCLK rising edges. - * - * Allow LE to fall - falling edge enables configuration - * writing. This should be sent immediately prior to any - * attempt to write to configuration register. - * - * - * Configuration Register - * ====================== - * - * 16 bits wide - * - * MSB Definition Value Function - * -------------------------------------------------------------------------------- - * | | | 0 (Default) | 15 x data latch + 1 global latch - * F | R/W | Data Loading | | - * | | | 1 | 16 x data latch + 1 global latch - * ----|-------|----------------|---------------|---------------------------------- - * E | | | | - * D | R/W | Reserved | Don't Care | N/A - * C | | | | - * ----|-------|----------------|---------------|---------------------------------- - * | | PWM counter | 0 (Default) | Disable - * B | R/W | reset | | - * | | | 1 | Enable (12/13 DCLKs + LE assert) - * ----|-------|----------------|---------------|---------------------------------- - * | | PWM data | 0 (Default) | Auto synchronization - * A | R/W | synch mode | | - * | | | 1 | Manual synchronization - * ----|-------|----------------|---------------|---------------------------------- - * 9 | | | | - * 8 | | | | - * 7 | R/W | Current gain | 000000 | 6'b101011 (Default) - * 6 | | adjustment | ~ | - * 5 | | | 111111 | - * 4 | | | | - * ----|-------|----------------|---------------|---------------------------------- - * 3 | | | | - * 2 | R/W | Reserved | Don't Care | N/A - * 1 | | | | - * 0 | | | | - * -------------------------------------------------------------------------------- - * LSB - * + * MBIA045 datasheet available at + * https://pc-clinic.bg/wp-content/uploads/2021/05/mbia045-datasheet-va.00-en.pdf */ -//#include "mbi5042gp.h" -#include "hal.h" #include + +#include "config.h" +#include "hal.h" #include "progmem.h" #include "rgb_matrix.h" -#include "led_tables.h" - -#ifndef MBI5042GP_GCLK_SRC -# define MBI5042GP_GCLK_SRC PWM0 -#endif -#ifndef MBI5042GP_DCLK -# define MBI5042GP_DCLK PD4 -#endif -#ifndef MBI5042GP_LE -# define MBI5042GP_LE PD3 -#endif + +#define MBIA045_CFGREG_DEFAULT 0b1000010000000000u + +#define MBIA045_DCLK PD4 +#define MBIA045_LE PD3 +#define MBIA045_EN PD5 + +#define MBIA045_ROW_COUNT 5 + +typedef struct mbi_led { + uint8_t row; + uint8_t col; +} __attribute__((packed)) mbi_led; + +// Map physical layout to QMK led index +const mbi_led g_mbi_leds[RGB_MATRIX_LED_COUNT] = { + { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, { 0, 14 }, + { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, { 1, 13 }, { 1, 14 }, + { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 13 }, { 2, 14 }, + { 3, 0 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, { 3, 13 }, + { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 5 }, { 4, 7 }, { 4, 9 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 4, 13 }, { 4, 14 } +}; + +// Lightness curve using the CIE 1931 lightness formula +// Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm +const uint16_t CIE1931_16_CURVE[] PROGMEM = { + 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, + 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, + 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, + 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, + 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, + 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, + 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, + 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, + 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, + 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, + 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, + 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, + 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, 3045, 3099, + 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, + 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, + 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, + 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, + 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, + 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, + 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, + 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, + 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, + 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, + 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, + 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, + 15566, 15727, 15890, 16053, 16217, 16383, + }; /** The PWM buffers the full rows of 16 PWM registers in each MBI5042 driver * The buffers are arranged in serial format @@ -148,24 +87,35 @@ * * g_pwm_buffer has the DCLK-able output for an "R" row, a "G" row, and a "B" row of PWM */ -uint16_t g_pwm_buffer[MBI5042GP_ROW_COUNT][16 * 16]; +uint16_t g_pwm_buffer[MBIA045_ROW_COUNT][16 * 16]; bool g_pwm_buffer_update_required = false; uint8_t g_pwm_buffer_row = 0; -void MBI5042GP_init(void) { +void MBIA045_init(void); +void MBIA045_set_current_gain(uint8_t gain); +void MBIA045_write_config_register(uint16_t regValue); +void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue); +void MBIA045_update_pwm_buffers(void); +void MBIA045_write_pwm_buffers(void); +void MBIA045_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue); +void MBIA045_disable_rows(void); +void MBIA045_disable_row(int row); +void MBIA045_enable_row(int row); + +void MBIA045_init(void) { /* Initialise all PWM arrays to zero. * Perform one group transfer to turn LEDs off * * If there's a DMA requirement, set up DMA subsystems */ - for (int i = 0; i < MBI5042GP_ROW_COUNT; i++) { + for (int i = 0; i < MBIA045_ROW_COUNT; i++) { for (int j = 0; j < 256; j++) { g_pwm_buffer[i][j] = 0; } } -#if MBI5042GP_GCLK_SRC == PWM0 /* Setup PWM0 control registers for 2MHz GCLK * and also 50 percentage PWM duty (makes a nice clock) * @@ -216,7 +166,7 @@ void MBI5042GP_init(void) { // (1+1)/(3+1) PWMA->CNR0 = 3; PWMA->CMR0 = 1; - + // Set PWM1 freq to 1.8kHz (duty doesn't matter) // // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] @@ -224,18 +174,15 @@ void MBI5042GP_init(void) { PWMA->CNR1 = 19999; PWMA->CMR1 = 1; - // Start PWM channel 0 and 1 + // Start PWM channel 0 and 1 PWMA->PCR |= (1 << PWM_PCR_CH0EN_Pos | 1 << PWM_PCR_CH1EN_Pos); -#elif -#endif - - MBI5042GP_disable_rows(); + MBIA045_disable_rows(); // Enable the LED controllers PD5 = PAL_LOW; - MBI5042GP_set_current_gain(0b000011u); + MBIA045_set_current_gain(0b000011u); } /** @@ -247,7 +194,7 @@ void MBI5042GP_init(void) { * * Use MBI5042_CURRENT_GAIN to pass from keyboard config */ -void MBI5042GP_set_current_gain(uint8_t gain) { +void MBIA045_set_current_gain(uint8_t gain) { /** MB data transfer requires: * Tell chip config register change is coming (Enable Write Configutarion) * Pass config register data (Write Configuration Register) @@ -255,9 +202,9 @@ void MBI5042GP_set_current_gain(uint8_t gain) { uint16_t regConfig = 0b00111111u & gain; regConfig <<= 4; - regConfig |= MBI5042GP_CFGREG_DEFAULT; + regConfig |= MBIA045_CFGREG_DEFAULT; - MBI5042GP_write_config_register(regConfig); + MBIA045_write_config_register(regConfig); } /** @@ -267,7 +214,7 @@ void MBI5042GP_set_current_gain(uint8_t gain) { * * For the Ducky One 2 mini there are 3 drivers, so output all three configs at once */ -void MBI5042GP_write_config_register(uint16_t regValue) { +void MBIA045_write_config_register(uint16_t regValue) { uint32_t b_mask; uint16_t tmp_r, tmp_g, tmp_b; @@ -276,25 +223,25 @@ void MBI5042GP_write_config_register(uint16_t regValue) { PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); /* LE Low & DCLK Low */ - MBI5042GP_LE = PAL_LOW; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_LE = PAL_LOW; + MBIA045_DCLK = PAL_LOW; /* Do one DCLK cycle */ - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; /* Set LE High */ - MBI5042GP_LE = PAL_HIGH; + MBIA045_LE = PAL_HIGH; /* Loop 15 - Enable Write Configuration */ for (int i = 0; i < 15; i++) { /* Cycle DCLK */ - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; } /* Reset LE Low */ - MBI5042GP_LE = PAL_LOW; + MBIA045_LE = PAL_LOW; /* Loop 16 - Transfer actual command data to all 3 LED drivers */ for (int i = 0; i < 16; i++) { @@ -304,11 +251,11 @@ void MBI5042GP_write_config_register(uint16_t regValue) { PB->DOUT = bits; /* Cycle DCLK */ - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; if (i == 5) { - MBI5042GP_LE = PAL_HIGH; + MBIA045_LE = PAL_HIGH; } /* Next bit to sample */ @@ -319,44 +266,44 @@ void MBI5042GP_write_config_register(uint16_t regValue) { PB->DMASK = b_mask; /* Reset LE Low */ - MBI5042GP_LE = PAL_LOW; + MBIA045_LE = PAL_LOW; } -void MBI5042GP_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { +void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { /* * @brief Pick a colour! Any colour! */ // led_config_t led; mbi_led led_pos; - if (index >= 0 && index < DRIVER_LED_TOTAL) { + if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { // Convert index into row/column led_pos = g_mbi_leds[index]; - // MBI5042GP_planar_recode(led.matrix_co.row, 15 - (led.matrix_co.col), red, green, blue); + // MBIA045_planar_recode(led.matrix_co.row, 15 - (led.matrix_co.col), red, green, blue); /* if (index == 27 && IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { */ - /* MBI5042GP_planar_recode(led_pos.row, led_pos.col, 0xff, 0xff, 0xff); */ + /* MBIA045_planar_recode(led_pos.row, led_pos.col, 0xff, 0xff, 0xff); */ /* } else { */ - MBI5042GP_planar_recode(led_pos.row, led_pos.col, red, green, blue); + MBIA045_planar_recode(led_pos.row, led_pos.col, red, green, blue); /* } */ g_pwm_buffer_update_required = true; } } -void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { +void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { /* * brief Set every led to the provided colour */ - for (int i = 0; i < MBI5042GP_ROW_COUNT; i++) { + for (int i = 0; i < MBIA045_ROW_COUNT; i++) { for (int j = 0; j < 16; j++) { if (i == 2) { if (j == 0) { /* } */ } } else { - MBI5042GP_planar_recode(i, j, red, green, blue); + MBIA045_planar_recode(i, j, red, green, blue); } } } @@ -364,9 +311,9 @@ void MBI5042GP_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { g_pwm_buffer_update_required = true; } -void MBI5042GP_update_pwm_buffers(void) { +void MBIA045_update_pwm_buffers(void) { /** - * Pass current PWM row to MBI5042GP shift registers + * Pass current PWM row to MBIA045 shift registers * * LE low * Outer Loop 16 (one per register transfer - high to low): @@ -400,8 +347,8 @@ void MBI5042GP_update_pwm_buffers(void) { PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); // LE Low & DCLK Low - MBI5042GP_LE = PAL_LOW; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_LE = PAL_LOW; + MBIA045_DCLK = PAL_LOW; for (int i = 0; i < 16; i++) { /* Inner Loop 16 */ @@ -411,64 +358,64 @@ void MBI5042GP_update_pwm_buffers(void) { // If j is 15 set LE High if (j == 15) { - MBI5042GP_LE = PAL_HIGH; + MBIA045_LE = PAL_HIGH; } /* Cycle DCLK */ - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; } // Inner Loop 16 // LE Low - MBI5042GP_LE = PAL_LOW; + MBIA045_LE = PAL_LOW; } /* Send Global Latch */ for (int i = 0; i < 16; i++) { /* Cycle DCLK */ - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; // if i is 13 set LE high if (i == 13) { - MBI5042GP_LE = PAL_HIGH; + MBIA045_LE = PAL_HIGH; } } // Reset LE Low - MBI5042GP_LE = PAL_LOW; + MBIA045_LE = PAL_LOW; // Reset Masks PB->DMASK = b_mask; // Disable current row - MBI5042GP_disable_rows(); + MBIA045_disable_rows(); // Reset PWM count // 3 DCLK cycles for (int i = 0; i < 3; i++) { - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; } // Set LE High - MBI5042GP_LE = PAL_HIGH; + MBIA045_LE = PAL_HIGH; // Loop 13 to generate PWM count reset for (int i = 0; i < 13; i++) { - MBI5042GP_DCLK = PAL_HIGH; - MBI5042GP_DCLK = PAL_LOW; + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; } // Set LE Low - MBI5042GP_LE = PAL_LOW; + MBIA045_LE = PAL_LOW; // Set new row - MBI5042GP_enable_row(g_pwm_buffer_row); + MBIA045_enable_row(g_pwm_buffer_row); // increment row count + check g_pwm_buffer_row++; - if (g_pwm_buffer_row >= MBI5042GP_ROW_COUNT) { + if (g_pwm_buffer_row >= MBIA045_ROW_COUNT) { g_pwm_buffer_row = 0; } } @@ -477,17 +424,17 @@ void MBI5042GP_update_pwm_buffers(void) { * @brief Write is a zero-output routine to handle the FLUSH from the RGB LED driver calls * @details Since the RGB data is recoded every time a colour is changed (by the relevant * single or "all" set_color routines), there is no point at which a mass flush of RGB - * information is needed. The MBI5042GP needs to be fed 16 sets of R, G, or B information + * information is needed. The MBIA045 needs to be fed 16 sets of R, G, or B information * for each row on a totally different schedule from the animations that affect the colours. */ -void MBI5042GP_write_pwm_buffers(void) {} +void MBIA045_write_pwm_buffers(void) {} /** * @brief Bitwise reorder of RGB information. * @details Recode the 8-bit standard RGB to 16-bit separated values and * turn the 16-bit "chunky" values into 16 sequential bitwise "planes" */ -void MBI5042GP_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue) { +void MBIA045_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue) { uint16_t cur_r = pgm_read_word(&CIE1931_16_CURVE[red]); uint16_t cur_g = pgm_read_word(&CIE1931_16_CURVE[green]); uint16_t cur_b = pgm_read_word(&CIE1931_16_CURVE[blue]); @@ -510,7 +457,7 @@ void MBI5042GP_planar_recode(int row, int column, uint8_t red, uint8_t green, ui /** * @brief Disable all LED Rows */ -void MBI5042GP_disable_rows(void) { +void MBIA045_disable_rows(void) { // Quick and dirty hardcoded row clear // 5 rows total // TODO: Create enum that can be configured for individual MCUs @@ -534,7 +481,7 @@ void MBI5042GP_disable_rows(void) { /** * @brief Disable specific LED row */ -void MBI5042GP_disable_row(int row) { +void MBIA045_disable_row(int row) { switch (row) { case 0: // Row 0 PC4 = PAL_LOW; @@ -557,7 +504,7 @@ void MBI5042GP_disable_row(int row) { /** * @brief Enable specific LED row */ -void MBI5042GP_enable_row(int row) { +void MBIA045_enable_row(int row) { switch (row) { case 0: // Row 0 PC4 = PAL_HIGH; @@ -585,8 +532,15 @@ OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { /* Clear interrupt flag */ PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; - MBI5042GP_update_pwm_buffers(); + MBIA045_update_pwm_buffers(); } OSAL_IRQ_EPILOGUE(); } + +const rgb_matrix_driver_t rgb_matrix_driver = { + .init = MBIA045_init, + .flush = MBIA045_write_pwm_buffers, + .set_color = MBIA045_set_color, + .set_color_all = MBIA045_set_color_all, +}; diff --git a/keyboards/ducky/one2sf/1967st/rules.mk b/keyboards/ducky/one2sf/1967st/rules.mk index 33ac599a8fe..c6a35c4ec1e 100644 --- a/keyboards/ducky/one2sf/1967st/rules.mk +++ b/keyboards/ducky/one2sf/1967st/rules.mk @@ -32,3 +32,4 @@ DIP_SWITCH_ENABLE = yes RGB_MATRIX_ENABLE = yes +SRC += rgb_matrix_drivers.c diff --git a/quantum/led_tables.c b/quantum/led_tables.c index 76587f754eb..9fbe642cc76 100644 --- a/quantum/led_tables.c +++ b/quantum/led_tables.c @@ -1,6 +1,5 @@ /* Copyright 2017 Fred Sundvik -Copyright 2019 /u/KeepItUnder 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 @@ -41,38 +40,4 @@ const uint8_t CIE1931_CURVE[256] PROGMEM = { }; #endif -#ifdef USE_CIE1931_16_CURVE -// Lightness curve using the CIE 1931 lightness formula -//Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm -const uint16_t CIE1931_16_CURVE[] PROGMEM = { - 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, - 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, - 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, - 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, - 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, - 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, - 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, - 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, - 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, - 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, - 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, - 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, - 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, 3045, 3099, - 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, - 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, - 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, - 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, - 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, - 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, - 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, - 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, - 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, - 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, - 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, - 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, - 15566, 15727, 15890, 16053, 16217, 16383, - }; -#endif - // clang-format on - diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index 7b055daebed..38040fb0ccc 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -1,7 +1,6 @@ /* Copyright 2017 Jason Williams * Copyright 2017 Jack Humbert * Copyright 2018 Yiancar - * Copyright 2019 /u/KeepItUnder * * 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 @@ -43,8 +42,6 @@ # include "aw20216.h" #elif defined(WS2812) # include "ws2812.h" -#elif defined (MBI5042) - #include "mbi5042gp.h" #endif #ifndef RGB_MATRIX_LED_FLUSH_LIMIT diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index 7c757d13544..695ecc78a47 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c @@ -1,6 +1,4 @@ /* Copyright 2018 James Laird-Wah - * Copyright 2019 /u/KeepItUnder - * Copyright 2023 Hayley Hughes * * 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 @@ -482,23 +480,4 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color = setled, .set_color_all = setled_all, }; - -#elif defined(MBI5042) - -static void init( void ) -{ - MBI5042GP_init(); -} - -static void flush( void ) -{ - MBI5042GP_write_pwm_buffers(); -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = MBI5042GP_set_color, - .set_color_all = MBI5042GP_set_color_all, -}; #endif From a3e8d08fe0a7f824b5a6fb44bc90b322ae618ee5 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Mon, 18 Dec 2023 14:50:09 +1100 Subject: [PATCH 12/22] Double buffer the LED colors and cleanup code --- keyboards/ducky/one2sf/1967st/config.h | 2 +- .../ducky/one2sf/1967st/rgb_matrix_drivers.c | 225 ++++++------------ quantum/led_tables.h | 5 - 3 files changed, 75 insertions(+), 157 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/config.h b/keyboards/ducky/one2sf/1967st/config.h index 966eb307eab..5be70f8384d 100644 --- a/keyboards/ducky/one2sf/1967st/config.h +++ b/keyboards/ducky/one2sf/1967st/config.h @@ -25,5 +25,5 @@ along with this program. If not, see . #define RGB_MATRIX_LED_COUNT 69 #define ENABLE_RGB_MATRIX_BREATHING -#define ENABLE_RGB_MATRIX_RAINBOW_BEACON +#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT #define ENABLE_RGB_MATRIX_TYPING_HEATMAP diff --git a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c index f89b5d97d96..980687b88b7 100644 --- a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c +++ b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c @@ -20,65 +20,43 @@ * https://pc-clinic.bg/wp-content/uploads/2021/05/mbia045-datasheet-va.00-en.pdf */ -#include +#ifdef RGB_MATRIX_ENABLE -#include "config.h" -#include "hal.h" -#include "progmem.h" -#include "rgb_matrix.h" +# include -#define MBIA045_CFGREG_DEFAULT 0b1000010000000000u +# include "config.h" +# include "hal.h" +# include "progmem.h" +# include "rgb_matrix.h" -#define MBIA045_DCLK PD4 -#define MBIA045_LE PD3 -#define MBIA045_EN PD5 +# define MBIA045_CFGREG_DEFAULT 0b1000010000000000u -#define MBIA045_ROW_COUNT 5 +# define MBIA045_DCLK PD4 +# define MBIA045_LE PD3 +# define MBIA045_EN PD5 + +# define MBIA045_ROW_COUNT 5 typedef struct mbi_led { uint8_t row; uint8_t col; } __attribute__((packed)) mbi_led; +typedef struct mbi_color { + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) mbi_color; + // Map physical layout to QMK led index -const mbi_led g_mbi_leds[RGB_MATRIX_LED_COUNT] = { - { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 }, { 0, 10 }, { 0, 11 }, { 0, 12 }, { 0, 13 }, { 0, 14 }, - { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 1, 6 }, { 1, 7 }, { 1, 8 }, { 1, 9 }, { 1, 10 }, { 1, 11 }, { 1, 12 }, { 1, 13 }, { 1, 14 }, - { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }, { 2, 6 }, { 2, 7 }, { 2, 8 }, { 2, 9 }, { 2, 10 }, { 2, 11 }, { 2, 13 }, { 2, 14 }, - { 3, 0 }, { 3, 2 }, { 3, 3 }, { 3, 4 }, { 3, 5 }, { 3, 6 }, { 3, 7 }, { 3, 8 }, { 3, 9 }, { 3, 10 }, { 3, 11 }, { 3, 12 }, { 3, 13 }, - { 4, 0 }, { 4, 1 }, { 4, 2 }, { 4, 3 }, { 4, 5 }, { 4, 7 }, { 4, 9 }, { 4, 10 }, { 4, 11 }, { 4, 12 }, { 4, 13 }, { 4, 14 } -}; +const mbi_led g_mbi_leds[RGB_MATRIX_LED_COUNT] = {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}, {2, 11}, {2, 13}, {2, 14}, {3, 0}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}, {3, 11}, {3, 12}, {3, 13}, {4, 0}, {4, 1}, {4, 2}, {4, 3}, {4, 5}, {4, 7}, {4, 9}, {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14}}; // Lightness curve using the CIE 1931 lightness formula // Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm const uint16_t CIE1931_16_CURVE[] PROGMEM = { - 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, - 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, - 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, - 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, - 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, - 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, - 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, - 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, - 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, - 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, - 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, - 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, - 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, 3045, 3099, - 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, - 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, - 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, - 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, - 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, - 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, - 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, - 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, - 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, - 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, - 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, - 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, - 15566, 15727, 15890, 16053, 16217, 16383, - }; + 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, + 3045, 3099, 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, 15566, 15727, 15890, 16053, 16217, 16383, +}; /** The PWM buffers the full rows of 16 PWM registers in each MBI5042 driver * The buffers are arranged in serial format @@ -87,7 +65,8 @@ const uint16_t CIE1931_16_CURVE[] PROGMEM = { * * g_pwm_buffer has the DCLK-able output for an "R" row, a "G" row, and a "B" row of PWM */ -uint16_t g_pwm_buffer[MBIA045_ROW_COUNT][16 * 16]; +uint16_t g_pwm_buffer[MBIA045_ROW_COUNT][16 * 16]; +mbi_color g_led_buffer[RGB_MATRIX_LED_COUNT]; bool g_pwm_buffer_update_required = false; uint8_t g_pwm_buffer_row = 0; @@ -98,11 +77,9 @@ void MBIA045_write_config_register(uint16_t regValue); void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue); void MBIA045_update_pwm_buffers(void); -void MBIA045_write_pwm_buffers(void); -void MBIA045_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue); +void MBIA045_flush(void); void MBIA045_disable_rows(void); -void MBIA045_disable_row(int row); -void MBIA045_enable_row(int row); +void MBIA045_select_row(int row); void MBIA045_init(void) { /* Initialise all PWM arrays to zero. @@ -180,7 +157,7 @@ void MBIA045_init(void) { MBIA045_disable_rows(); // Enable the LED controllers - PD5 = PAL_LOW; + MBIA045_EN = PAL_LOW; MBIA045_set_current_gain(0b000011u); } @@ -273,42 +250,16 @@ void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { /* * @brief Pick a colour! Any colour! */ - // led_config_t led; - mbi_led led_pos; - - if (index >= 0 && index < RGB_MATRIX_LED_COUNT) { - // Convert index into row/column - led_pos = g_mbi_leds[index]; - - // MBIA045_planar_recode(led.matrix_co.row, 15 - (led.matrix_co.col), red, green, blue); - /* if (index == 27 && IS_HOST_LED_ON(USB_LED_CAPS_LOCK)) { */ - /* MBIA045_planar_recode(led_pos.row, led_pos.col, 0xff, 0xff, 0xff); */ - /* } else { */ - MBIA045_planar_recode(led_pos.row, led_pos.col, red, green, blue); - /* } */ - - g_pwm_buffer_update_required = true; - } + g_led_buffer[index] = (mbi_color){red, green, blue}; } void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { /* * brief Set every led to the provided colour */ - - for (int i = 0; i < MBIA045_ROW_COUNT; i++) { - for (int j = 0; j < 16; j++) { - if (i == 2) { - if (j == 0) { - /* } */ - } - } else { - MBIA045_planar_recode(i, j, red, green, blue); - } - } + for (size_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { + g_led_buffer[i] = (mbi_color){red, green, blue}; } - - g_pwm_buffer_update_required = true; } void MBIA045_update_pwm_buffers(void) { @@ -340,6 +291,8 @@ void MBIA045_update_pwm_buffers(void) { * Select new row (row meant for above data) */ + if (!g_pwm_buffer_update_required) return; + uint32_t b_mask; /* Set Mask for GPIOB */ @@ -364,7 +317,7 @@ void MBIA045_update_pwm_buffers(void) { /* Cycle DCLK */ MBIA045_DCLK = PAL_HIGH; MBIA045_DCLK = PAL_LOW; - } // Inner Loop 16 + } // Inner Loop 16 // LE Low MBIA045_LE = PAL_LOW; @@ -388,9 +341,6 @@ void MBIA045_update_pwm_buffers(void) { // Reset Masks PB->DMASK = b_mask; - // Disable current row - MBIA045_disable_rows(); - // Reset PWM count // 3 DCLK cycles for (int i = 0; i < 3; i++) { @@ -411,7 +361,7 @@ void MBIA045_update_pwm_buffers(void) { MBIA045_LE = PAL_LOW; // Set new row - MBIA045_enable_row(g_pwm_buffer_row); + MBIA045_select_row(g_pwm_buffer_row); // increment row count + check g_pwm_buffer_row++; @@ -421,47 +371,41 @@ void MBIA045_update_pwm_buffers(void) { } /** - * @brief Write is a zero-output routine to handle the FLUSH from the RGB LED driver calls - * @details Since the RGB data is recoded every time a colour is changed (by the relevant - * single or "all" set_color routines), there is no point at which a mass flush of RGB - * information is needed. The MBIA045 needs to be fed 16 sets of R, G, or B information - * for each row on a totally different schedule from the animations that affect the colours. - */ -void MBIA045_write_pwm_buffers(void) {} - -/** - * @brief Bitwise reorder of RGB information. - * @details Recode the 8-bit standard RGB to 16-bit separated values and - * turn the 16-bit "chunky" values into 16 sequential bitwise "planes" + * @brief Send the color buffer to the PWM buffer */ -void MBIA045_planar_recode(int row, int column, uint8_t red, uint8_t green, uint8_t blue) { - uint16_t cur_r = pgm_read_word(&CIE1931_16_CURVE[red]); - uint16_t cur_g = pgm_read_word(&CIE1931_16_CURVE[green]); - uint16_t cur_b = pgm_read_word(&CIE1931_16_CURVE[blue]); - - // int row, column; - - for (int i = 0; i < 16; i++) { - uint16_t tmp_r = cur_r; - uint16_t tmp_g = cur_g; - uint16_t tmp_b = cur_b; - - // g_pwm_buffer[row][0][i * column] = ; - g_pwm_buffer[row][i + (column * 16)] = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); - cur_r <<= 1; - cur_g <<= 1; - cur_b <<= 1; +void MBIA045_flush(void) { + mbi_led led_pos; + mbi_color color; + + for (size_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { + led_pos = g_mbi_leds[i]; + color = g_led_buffer[i]; + + // Convert color values from 8 to 16 bit + uint16_t cur_r = pgm_read_word(&CIE1931_16_CURVE[color.r]); + uint16_t cur_g = pgm_read_word(&CIE1931_16_CURVE[color.g]); + uint16_t cur_b = pgm_read_word(&CIE1931_16_CURVE[color.b]); + + // Construct the pwm buffer + for (int i = 0; i < 16; i++) { + uint16_t tmp_r = cur_r; + uint16_t tmp_g = cur_g; + uint16_t tmp_b = cur_b; + + g_pwm_buffer[led_pos.row][i + (led_pos.col * 16)] = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); + cur_r <<= 1; + cur_g <<= 1; + cur_b <<= 1; + } } + + g_pwm_buffer_update_required = true; } /** * @brief Disable all LED Rows */ void MBIA045_disable_rows(void) { - // Quick and dirty hardcoded row clear - // 5 rows total - // TODO: Create enum that can be configured for individual MCUs - // Row 0 PC4 = PAL_LOW; @@ -479,46 +423,24 @@ void MBIA045_disable_rows(void) { } /** - * @brief Disable specific LED row + * @brief Enable the specific LED row, disabling all others */ -void MBIA045_disable_row(int row) { - switch (row) { - case 0: // Row 0 - PC4 = PAL_LOW; - break; - case 1: // Row 1 - PC5 = PAL_LOW; - break; - case 2: // Row 2 - PB3 = PAL_LOW; - break; - case 3: // Row 3 - PB2 = PAL_LOW; - break; - case 4: // Row 4 - PD9 = PAL_LOW; - break; - } -} - -/** - * @brief Enable specific LED row - */ -void MBIA045_enable_row(int row) { +void MBIA045_select_row(int row) { + MBIA045_disable_rows(); switch (row) { - case 0: // Row 0 + case 0: // Row 0 PC4 = PAL_HIGH; break; - case 1: // Row 1 + case 1: // Row 1 PC5 = PAL_HIGH; break; - case 2: // Row 2 + case 2: // Row 2 PB3 = PAL_HIGH; break; - case 3: // Row 3 + case 3: // Row 3 PB2 = PAL_HIGH; break; - case 4: // Row 4 + case 4: // Row 4 PD9 = PAL_HIGH; break; } @@ -531,7 +453,6 @@ OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { if ((PWMA->PIIR >> PWM_PIIR_PWMIF1_Pos) & 1) { /* Clear interrupt flag */ PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; - MBIA045_update_pwm_buffers(); } @@ -539,8 +460,10 @@ OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { } const rgb_matrix_driver_t rgb_matrix_driver = { - .init = MBIA045_init, - .flush = MBIA045_write_pwm_buffers, - .set_color = MBIA045_set_color, + .init = MBIA045_init, + .flush = MBIA045_flush, + .set_color = MBIA045_set_color, .set_color_all = MBIA045_set_color_all, }; + +#endif diff --git a/quantum/led_tables.h b/quantum/led_tables.h index 609e84f386d..cd3e5d74c11 100644 --- a/quantum/led_tables.h +++ b/quantum/led_tables.h @@ -1,6 +1,5 @@ /* Copyright 2017 Fred Sundvik -Copyright 2019 /u/KeepItUnder 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 @@ -22,7 +21,3 @@ along with this program. If not, see . #ifdef USE_CIE1931_CURVE extern const uint8_t CIE1931_CURVE[] PROGMEM; #endif - -#ifdef USE_CIE1931_16_CURVE -extern const uint16_t CIE1931_16_CURVE[] PROGMEM; -#endif From 34f4bee55a7ea4ba8e3a40bab86c7c41761b1f54 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 17 Dec 2023 19:40:41 +1100 Subject: [PATCH 13/22] Update one2sf default keymaps to be RGB friendly --- keyboards/ducky/one2sf/keymaps/default/keymap.c | 6 +++--- keyboards/ducky/one2sf/keymaps/default_ansi/keymap.c | 6 +++--- keyboards/ducky/one2sf/keymaps/default_iso/keymap.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/keyboards/ducky/one2sf/keymaps/default/keymap.c b/keyboards/ducky/one2sf/keymaps/default/keymap.c index 044b5067f64..4cf33660da2 100644 --- a/keyboards/ducky/one2sf/keymaps/default/keymap.c +++ b/keyboards/ducky/one2sf/keymaps/default/keymap.c @@ -40,15 +40,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, _______, _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, _______, KC_INS, _______, KC_UP, KC_PAUSE, KC_PGUP, KC_HOME, KC_PSCR, _______, KC_HOME, _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D, _______, KC_SCRL, KC_LEFT, KC_DOWN, KC_RIGHT, KC_PGDN, KC_END, _______, _______, KC_END, - _______, _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, _______, _______, _______, _______, MO(2), _______, _______, _______, _______, _______ ), [_COLOUR] = LAYOUT_all( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, _______, _______, _______, _______, _______, _______, + _______, _______, RGB_HUI, RGB_SAI, RGB_VAI, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), diff --git a/keyboards/ducky/one2sf/keymaps/default_ansi/keymap.c b/keyboards/ducky/one2sf/keymaps/default_ansi/keymap.c index 089f5f5f073..5c90dd7029f 100644 --- a/keyboards/ducky/one2sf/keymaps/default_ansi/keymap.c +++ b/keyboards/ducky/one2sf/keymaps/default_ansi/keymap.c @@ -40,15 +40,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, _______, _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, _______, KC_INS, _______, KC_UP, KC_PAUS, KC_PGUP, KC_HOME, KC_PSCR, _______, KC_HOME, _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D, _______, KC_SCRL, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_END, _______, KC_END, - _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, _______, _______, _______, _______, MO(2), _______, _______, _______, _______, _______ ), [_COLOUR] = LAYOUT_ansi( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, _______, _______, _______, _______, _______, _______, + _______, RGB_HUI, RGB_SAI, RGB_VAI, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), diff --git a/keyboards/ducky/one2sf/keymaps/default_iso/keymap.c b/keyboards/ducky/one2sf/keymaps/default_iso/keymap.c index be678520e6f..36e4bf4f701 100644 --- a/keyboards/ducky/one2sf/keymaps/default_iso/keymap.c +++ b/keyboards/ducky/one2sf/keymaps/default_iso/keymap.c @@ -40,15 +40,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, _______, _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_WH_U, _______, KC_INS, _______, KC_UP, KC_PAUS, KC_PGUP, KC_HOME, KC_PSCR, KC_HOME, _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_WH_D, _______, KC_SCRL, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDN, KC_END, _______, _______, KC_END, - _______, _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______, _______, _______, _______, _______, MO(2), _______, _______, _______, _______, _______ ), [_COLOUR] = LAYOUT_iso( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, RGB_SPI, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, _______, _______, _______, _______, _______, _______, + _______, _______, RGB_HUI, RGB_SAI, RGB_VAI, RGB_MOD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), From 982173cb3fe461040491c4653e2465e9b8e00b91 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Mon, 18 Dec 2023 16:56:42 +1100 Subject: [PATCH 14/22] Update documentation --- keyboards/ducky/one2sf/1967st/readme.md | 3 +-- keyboards/ducky/one2sf/readme.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/readme.md b/keyboards/ducky/one2sf/1967st/readme.md index cb3739efbb7..c22f0d3b5e6 100644 --- a/keyboards/ducky/one2sf/1967st/readme.md +++ b/keyboards/ducky/one2sf/1967st/readme.md @@ -5,11 +5,10 @@ A 65% keyboard by Ducky. This firmware was tested on the Ducky One 2 SF 1967ST version. * Keyboard Maintainer: [f7urry](https://github.com/f7urry) -* Hardware Supported: Ducky One 2 SF RGB (DKON1967ST), NUC123SD4AN0 + MBI5043GP +* Hardware Supported: Ducky One 2 SF RGB (DKON1967ST), NUC123SD4AN0 + MBIA045 * Only ANSI layout is supported at this time * ISO compiles but is **untested** * VIA still WIP. - * RGB LEDs are currently disabled until the driver is merged. ## Compiling the Firmware: diff --git a/keyboards/ducky/one2sf/readme.md b/keyboards/ducky/one2sf/readme.md index fb37adb7e9e..d32e0950cec 100644 --- a/keyboards/ducky/one2sf/readme.md +++ b/keyboards/ducky/one2sf/readme.md @@ -5,4 +5,4 @@ A 65% keyboard by Ducky. The only supported keyboard version at this time is the DKON1967ST. * Hardware Supported: - * [DKON1967ST](1967st/), NUC123SD4AN0 + MBI5043GP + * [DKON1967ST](1967st/), NUC123SD4AN0 + MBIA045 From 76e2d0677868d9fee271db0f16000203dff0d070 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Tue, 19 Dec 2023 11:08:42 +1100 Subject: [PATCH 15/22] Switch to using ChibiOS PWM driver --- keyboards/ducky/one2sf/1967st/halconf.h | 22 +++++ .../ducky/one2sf/1967st/rgb_matrix_drivers.c | 86 +++++-------------- 2 files changed, 42 insertions(+), 66 deletions(-) create mode 100644 keyboards/ducky/one2sf/1967st/halconf.h diff --git a/keyboards/ducky/one2sf/1967st/halconf.h b/keyboards/ducky/one2sf/1967st/halconf.h new file mode 100644 index 00000000000..1950c3e4c17 --- /dev/null +++ b/keyboards/ducky/one2sf/1967st/halconf.h @@ -0,0 +1,22 @@ +/* Copyright 2023 Hayley Hughes + * + * 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 . + */ + +#pragma once + +#define HAL_USE_PWM TRUE +#define HAL_USE_PAL TRUE + +#include_next diff --git a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c index 980687b88b7..212e8072a51 100644 --- a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c +++ b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c @@ -76,11 +76,23 @@ void MBIA045_set_current_gain(uint8_t gain); void MBIA045_write_config_register(uint16_t regValue); void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue); -void MBIA045_update_pwm_buffers(void); +void MBIA045_update_pwm_buffers(PWMDriver *pwm); void MBIA045_flush(void); void MBIA045_disable_rows(void); void MBIA045_select_row(int row); +static const PWMConfig g_pwm_cfg = { + 2000000, + 5, + NULL, + { + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, // Channel 0, pin PA15 + {PWM_OUTPUT_DISABLED, MBIA045_update_pwm_buffers}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL}, + } +}; + void MBIA045_init(void) { /* Initialise all PWM arrays to zero. * Perform one group transfer to turn LEDs off @@ -100,59 +112,12 @@ void MBIA045_init(void) { * which is used for row refresh/enable. */ - // Use the HCLK - // Note we need to 0 the bits first as the clksel register has a reset value - // of 0xFFFF_FFFF - CLK->CLKSEL1 &= ~CLK_CLKSEL1_PWM01_S_Msk; - CLK->CLKSEL1 |= 2 << CLK_CLKSEL1_PWM01_S_Pos; - - CLK->CLKSEL2 &= ~CLK_CLKSEL2_PWM01_S_E_Msk; - CLK->CLKSEL2 |= 2 << CLK_CLKSEL2_PWM01_S_E_Pos; - - // Enable the PWM peripheral clock - CLK->APBCLK |= 1 << CLK_APBCLK_PWM01_EN_Pos; - - // Set prescaler for PWM0 and PWM1 to 1 - PWMA->PPR |= 1 << PWM_PPR_CP01_Pos; - - // Enable PWM interrupt vector - // Interrupt priority value taken from chibios defaults - nvicEnableVector(NUC123_PWMA_NUMBER, 3); - - // Set clock division to 1 - PWMA->CSR |= 1 << PWM_CSR_CSR2_Pos; - - // Set pin PA12 to PWM0 - SYS->GPA_MFP |= 1 << 12; - - // Enable PWM0 output - PWMA->POE |= 1 << PWM_POE_PWM0_Pos; + palSetPadMode(GPIOA, 12, 1); - // Enable PWM0 and PWM1 auto reload - PWMA->PCR |= (1 << PWM_PCR_CH0MOD_Pos | 1 << PWM_PCR_CH1MOD_Pos); + pwmStart(&PWMD1, &g_pwm_cfg); - // Enable PWM1 reset interrupt - PWMA->PIER |= 1 << PWM_PIER_PWMIE1_Pos; - - // Set PWM0 freq to 9MHz and 50% duty cycle (it's just a nice clock) - // - // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] - // 72MHz/(1 + 1)*(1)*(3+1) - // - // duty = (CMR+1)/(CNR+1) - // (1+1)/(3+1) - PWMA->CNR0 = 3; - PWMA->CMR0 = 1; - - // Set PWM1 freq to 1.8kHz (duty doesn't matter) - // - // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] - // 72MHz/(1 + 1)*(1)*(3+1) - PWMA->CNR1 = 19999; - PWMA->CMR1 = 1; - - // Start PWM channel 0 and 1 - PWMA->PCR |= (1 << PWM_PCR_CH0EN_Pos | 1 << PWM_PCR_CH1EN_Pos); + pwmEnableChannel(&PWMD1, 0, 10); + pwmEnableChannel(&PWMD1, 1, 100000); MBIA045_disable_rows(); @@ -160,6 +125,8 @@ void MBIA045_init(void) { MBIA045_EN = PAL_LOW; MBIA045_set_current_gain(0b000011u); + + pwmEnableChannelNotification(&PWMD1, 1); } /** @@ -262,7 +229,7 @@ void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { } } -void MBIA045_update_pwm_buffers(void) { +void MBIA045_update_pwm_buffers(PWMDriver *pwm) { /** * Pass current PWM row to MBIA045 shift registers * @@ -446,19 +413,6 @@ void MBIA045_select_row(int row) { } } -OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { - OSAL_IRQ_PROLOGUE(); - - /* Check for PWM1 underflow IRQ */ - if ((PWMA->PIIR >> PWM_PIIR_PWMIF1_Pos) & 1) { - /* Clear interrupt flag */ - PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; - MBIA045_update_pwm_buffers(); - } - - OSAL_IRQ_EPILOGUE(); -} - const rgb_matrix_driver_t rgb_matrix_driver = { .init = MBIA045_init, .flush = MBIA045_flush, From 3f43c5d435043f51c58a971160c7f21f25ba21ab Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Tue, 19 Dec 2023 12:33:46 +1100 Subject: [PATCH 16/22] Revert "Switch to using ChibiOS PWM driver" This reverts commit 76e2d0677868d9fee271db0f16000203dff0d070. --- keyboards/ducky/one2sf/1967st/halconf.h | 22 ----- .../ducky/one2sf/1967st/rgb_matrix_drivers.c | 86 ++++++++++++++----- 2 files changed, 66 insertions(+), 42 deletions(-) delete mode 100644 keyboards/ducky/one2sf/1967st/halconf.h diff --git a/keyboards/ducky/one2sf/1967st/halconf.h b/keyboards/ducky/one2sf/1967st/halconf.h deleted file mode 100644 index 1950c3e4c17..00000000000 --- a/keyboards/ducky/one2sf/1967st/halconf.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2023 Hayley Hughes - * - * 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 . - */ - -#pragma once - -#define HAL_USE_PWM TRUE -#define HAL_USE_PAL TRUE - -#include_next diff --git a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c index 212e8072a51..980687b88b7 100644 --- a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c +++ b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c @@ -76,23 +76,11 @@ void MBIA045_set_current_gain(uint8_t gain); void MBIA045_write_config_register(uint16_t regValue); void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue); -void MBIA045_update_pwm_buffers(PWMDriver *pwm); +void MBIA045_update_pwm_buffers(void); void MBIA045_flush(void); void MBIA045_disable_rows(void); void MBIA045_select_row(int row); -static const PWMConfig g_pwm_cfg = { - 2000000, - 5, - NULL, - { - {PWM_OUTPUT_ACTIVE_HIGH, NULL}, // Channel 0, pin PA15 - {PWM_OUTPUT_DISABLED, MBIA045_update_pwm_buffers}, - {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_DISABLED, NULL}, - } -}; - void MBIA045_init(void) { /* Initialise all PWM arrays to zero. * Perform one group transfer to turn LEDs off @@ -112,12 +100,59 @@ void MBIA045_init(void) { * which is used for row refresh/enable. */ - palSetPadMode(GPIOA, 12, 1); + // Use the HCLK + // Note we need to 0 the bits first as the clksel register has a reset value + // of 0xFFFF_FFFF + CLK->CLKSEL1 &= ~CLK_CLKSEL1_PWM01_S_Msk; + CLK->CLKSEL1 |= 2 << CLK_CLKSEL1_PWM01_S_Pos; + + CLK->CLKSEL2 &= ~CLK_CLKSEL2_PWM01_S_E_Msk; + CLK->CLKSEL2 |= 2 << CLK_CLKSEL2_PWM01_S_E_Pos; + + // Enable the PWM peripheral clock + CLK->APBCLK |= 1 << CLK_APBCLK_PWM01_EN_Pos; + + // Set prescaler for PWM0 and PWM1 to 1 + PWMA->PPR |= 1 << PWM_PPR_CP01_Pos; + + // Enable PWM interrupt vector + // Interrupt priority value taken from chibios defaults + nvicEnableVector(NUC123_PWMA_NUMBER, 3); + + // Set clock division to 1 + PWMA->CSR |= 1 << PWM_CSR_CSR2_Pos; + + // Set pin PA12 to PWM0 + SYS->GPA_MFP |= 1 << 12; + + // Enable PWM0 output + PWMA->POE |= 1 << PWM_POE_PWM0_Pos; - pwmStart(&PWMD1, &g_pwm_cfg); + // Enable PWM0 and PWM1 auto reload + PWMA->PCR |= (1 << PWM_PCR_CH0MOD_Pos | 1 << PWM_PCR_CH1MOD_Pos); - pwmEnableChannel(&PWMD1, 0, 10); - pwmEnableChannel(&PWMD1, 1, 100000); + // Enable PWM1 reset interrupt + PWMA->PIER |= 1 << PWM_PIER_PWMIE1_Pos; + + // Set PWM0 freq to 9MHz and 50% duty cycle (it's just a nice clock) + // + // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] + // 72MHz/(1 + 1)*(1)*(3+1) + // + // duty = (CMR+1)/(CNR+1) + // (1+1)/(3+1) + PWMA->CNR0 = 3; + PWMA->CMR0 = 1; + + // Set PWM1 freq to 1.8kHz (duty doesn't matter) + // + // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] + // 72MHz/(1 + 1)*(1)*(3+1) + PWMA->CNR1 = 19999; + PWMA->CMR1 = 1; + + // Start PWM channel 0 and 1 + PWMA->PCR |= (1 << PWM_PCR_CH0EN_Pos | 1 << PWM_PCR_CH1EN_Pos); MBIA045_disable_rows(); @@ -125,8 +160,6 @@ void MBIA045_init(void) { MBIA045_EN = PAL_LOW; MBIA045_set_current_gain(0b000011u); - - pwmEnableChannelNotification(&PWMD1, 1); } /** @@ -229,7 +262,7 @@ void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { } } -void MBIA045_update_pwm_buffers(PWMDriver *pwm) { +void MBIA045_update_pwm_buffers(void) { /** * Pass current PWM row to MBIA045 shift registers * @@ -413,6 +446,19 @@ void MBIA045_select_row(int row) { } } +OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { + OSAL_IRQ_PROLOGUE(); + + /* Check for PWM1 underflow IRQ */ + if ((PWMA->PIIR >> PWM_PIIR_PWMIF1_Pos) & 1) { + /* Clear interrupt flag */ + PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; + MBIA045_update_pwm_buffers(); + } + + OSAL_IRQ_EPILOGUE(); +} + const rgb_matrix_driver_t rgb_matrix_driver = { .init = MBIA045_init, .flush = MBIA045_flush, From 430a52ee2d27740624070c631d30d5da1cd61b87 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 24 Dec 2023 15:28:15 +1100 Subject: [PATCH 17/22] Move led configuration to info.json --- keyboards/ducky/one2sf/1967st/1967st.c | 476 +++++++++++++++++- keyboards/ducky/one2sf/1967st/config.h | 2 - keyboards/ducky/one2sf/1967st/info.json | 76 ++- .../ducky/one2sf/1967st/rgb_matrix_drivers.c | 469 ----------------- keyboards/ducky/one2sf/1967st/rules.mk | 4 - 5 files changed, 528 insertions(+), 499 deletions(-) delete mode 100644 keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c diff --git a/keyboards/ducky/one2sf/1967st/1967st.c b/keyboards/ducky/one2sf/1967st/1967st.c index 14eb70c49f4..371bd99d93f 100644 --- a/keyboards/ducky/one2sf/1967st/1967st.c +++ b/keyboards/ducky/one2sf/1967st/1967st.c @@ -15,27 +15,457 @@ * along with this program. If not, see . */ -#include "config.h" -#include "quantum.h" - -led_config_t g_led_config = { { - // Key Matrix to LED Index - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, NO_LED}, - { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, NO_LED}, - { 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, NO_LED, 42, 43, NO_LED}, - { 44, NO_LED, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, NO_LED, NO_LED}, - { 57, 58, 59, 60, NO_LED, 61, NO_LED, 62, NO_LED, 63, 64, 65, 66, 67, 68, NO_LED}, -}, { - { 0, 0 }, { 16, 0 }, { 32, 0 }, { 48, 0 }, { 64, 0 }, { 80, 0 }, { 96, 0 }, { 112, 0 }, { 128, 0 }, { 144, 0 }, { 160, 0 }, { 176, 0 }, { 192, 0 }, { 208, 0 }, { 224, 0 }, - { 0, 16 }, { 16, 16 }, { 32, 16 }, { 48, 16 }, { 64, 16 }, { 80, 16 }, { 96, 16 }, { 112, 16 }, { 128, 16 }, { 144, 16 }, { 160, 16 }, { 176, 16 }, { 192, 16 }, { 208, 16 }, { 224, 16 }, - { 0, 32 }, { 16, 32 }, { 32, 32 }, { 48, 32 }, { 64, 32 }, { 80, 32 }, { 96, 32 }, { 112, 32 }, { 128, 32 }, { 144, 32 }, { 160, 32 }, { 176, 32 }, { 208, 32 }, { 224, 32 }, - { 0, 48 }, { 32, 48 }, { 48, 48 }, { 64, 48 }, { 80, 48 }, { 96, 48 }, { 112, 48 }, { 128, 48 }, { 144, 48 }, { 160, 48 }, { 176, 48 }, { 192, 48 }, { 208, 48 }, - { 0, 64 }, { 16, 64 }, { 32, 64 }, { 48, 64 }, { 80, 64 }, { 112, 64 }, { 144, 64 }, { 160, 64 }, { 176, 64 }, { 192, 64 }, { 208, 64 }, { 224, 64 } -}, { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, - 5, 5, 5, 4, 4, 4, 5, 5, 5, 4, 4, 4 -} }; +/* + * MBIA045 LED matrix driver. + * + * Datasheet available at + * https://pc-clinic.bg/wp-content/uploads/2021/05/mbia045-datasheet-va.00-en.pdf + */ + +#ifdef RGB_MATRIX_ENABLE + +# include + +# include "config.h" +# include "hal.h" +# include "progmem.h" +# include "rgb_matrix.h" + +# define MBIA045_CFGREG_DEFAULT 0b1000010000000000u + +# define MBIA045_DCLK PD4 +# define MBIA045_LE PD3 +# define MBIA045_EN PD5 + +# define MBIA045_ROW_COUNT 5 + +typedef struct mbi_led { + uint8_t row; + uint8_t col; +} __attribute__((packed)) mbi_led; + +typedef struct mbi_color { + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) mbi_color; + +// Map physical layout to QMK led index +const mbi_led g_mbi_leds[RGB_MATRIX_LED_COUNT] = {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}, {2, 11}, {2, 13}, {2, 14}, {3, 0}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}, {3, 11}, {3, 12}, {3, 13}, {4, 0}, {4, 1}, {4, 2}, {4, 3}, {4, 5}, {4, 7}, {4, 9}, {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14}}; + +// Lightness curve using the CIE 1931 lightness formula +// Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm +const uint16_t CIE1931_16_CURVE[] PROGMEM = { + 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, + 3045, 3099, 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, 15566, 15727, 15890, 16053, 16217, 16383, +}; + +/** The PWM buffers the full rows of 16 PWM registers in each MBI5042 driver + * The buffers are arranged in serial format + * (MSB_R, MSB_G, MSB_B...LSB_R, LSB_G, LSB_B) + * as needed by the SDO pins on the MCU (R is B14; G is B13; B is B12) + * + * g_pwm_buffer has the DCLK-able output for an "R" row, a "G" row, and a "B" row of PWM + */ +uint16_t g_pwm_buffer[MBIA045_ROW_COUNT][16 * 16]; +mbi_color g_led_buffer[RGB_MATRIX_LED_COUNT]; + +bool g_pwm_buffer_update_required = false; +uint8_t g_pwm_buffer_row = 0; + +void MBIA045_init(void); +void MBIA045_set_current_gain(uint8_t gain); +void MBIA045_write_config_register(uint16_t regValue); +void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue); +void MBIA045_update_pwm_buffers(void); +void MBIA045_flush(void); +void MBIA045_disable_rows(void); +void MBIA045_select_row(int row); + +void MBIA045_init(void) { + /* Initialise all PWM arrays to zero. + * Perform one group transfer to turn LEDs off + * + * If there's a DMA requirement, set up DMA subsystems + */ + for (int i = 0; i < MBIA045_ROW_COUNT; i++) { + for (int j = 0; j < 256; j++) { + g_pwm_buffer[i][j] = 0; + } + } + + /* Setup PWM0 control registers for 2MHz GCLK + * and also 50 percentage PWM duty (makes a nice clock) + * + * Set PWM1 to be used as a 2kHz timer (interrupt but no output pin) + * which is used for row refresh/enable. + */ + + // Use the HCLK + // Note we need to 0 the bits first as the clksel register has a reset value + // of 0xFFFF_FFFF + CLK->CLKSEL1 &= ~CLK_CLKSEL1_PWM01_S_Msk; + CLK->CLKSEL1 |= 2 << CLK_CLKSEL1_PWM01_S_Pos; + + CLK->CLKSEL2 &= ~CLK_CLKSEL2_PWM01_S_E_Msk; + CLK->CLKSEL2 |= 2 << CLK_CLKSEL2_PWM01_S_E_Pos; + + // Enable the PWM peripheral clock + CLK->APBCLK |= 1 << CLK_APBCLK_PWM01_EN_Pos; + + // Set prescaler for PWM0 and PWM1 to 1 + PWMA->PPR |= 1 << PWM_PPR_CP01_Pos; + + // Enable PWM interrupt vector + // Interrupt priority value taken from chibios defaults + nvicEnableVector(NUC123_PWMA_NUMBER, 3); + + // Set clock division to 1 + PWMA->CSR |= 1 << PWM_CSR_CSR2_Pos; + + // Set pin PA12 to PWM0 + SYS->GPA_MFP |= 1 << 12; + + // Enable PWM0 output + PWMA->POE |= 1 << PWM_POE_PWM0_Pos; + + // Enable PWM0 and PWM1 auto reload + PWMA->PCR |= (1 << PWM_PCR_CH0MOD_Pos | 1 << PWM_PCR_CH1MOD_Pos); + + // Enable PWM1 reset interrupt + PWMA->PIER |= 1 << PWM_PIER_PWMIE1_Pos; + + // Set PWM0 freq to 9MHz and 50% duty cycle (it's just a nice clock) + // + // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] + // 72MHz/(1 + 1)*(1)*(3+1) + // + // duty = (CMR+1)/(CNR+1) + // (1+1)/(3+1) + PWMA->CNR0 = 3; + PWMA->CMR0 = 1; + + // Set PWM1 freq to 1.8kHz (duty doesn't matter) + // + // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] + // 72MHz/(1 + 1)*(1)*(3+1) + PWMA->CNR1 = 19999; + PWMA->CMR1 = 1; + + // Start PWM channel 0 and 1 + PWMA->PCR |= (1 << PWM_PCR_CH0EN_Pos | 1 << PWM_PCR_CH1EN_Pos); + + MBIA045_disable_rows(); + + // Enable the LED controllers + MBIA045_EN = PAL_LOW; + + MBIA045_set_current_gain(0b000011u); +} + +/** + * @brief Set LED driver current gain + * @detail The MBI5042 has a 6-bit current gain value (000000b ~ 111111b) + * used to adjust the global brightness of the LEDs attached to the PWM outputs + * + * Default value is 101011b + * + * Use MBI5042_CURRENT_GAIN to pass from keyboard config + */ +void MBIA045_set_current_gain(uint8_t gain) { + /** MB data transfer requires: + * Tell chip config register change is coming (Enable Write Configutarion) + * Pass config register data (Write Configuration Register) + */ + uint16_t regConfig = 0b00111111u & gain; + + regConfig <<= 4; + regConfig |= MBIA045_CFGREG_DEFAULT; + + MBIA045_write_config_register(regConfig); +} + +/** + * @brief Write configuration register ONLY DURING INIT + * @detail Set the contents of the configuration register (see top for bitfields) + * Each register write needs 2 * 16 bit transfers (1 x setup and 1 x data) + * + * For the Ducky One 2 mini there are 3 drivers, so output all three configs at once + */ +void MBIA045_write_config_register(uint16_t regValue) { + uint32_t b_mask; + uint16_t tmp_r, tmp_g, tmp_b; + + /* Set Mask for GPIOB */ + b_mask = PB->DMASK; + PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); + + /* LE Low & DCLK Low */ + MBIA045_LE = PAL_LOW; + MBIA045_DCLK = PAL_LOW; + + /* Do one DCLK cycle */ + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + + /* Set LE High */ + MBIA045_LE = PAL_HIGH; + + /* Loop 15 - Enable Write Configuration */ + for (int i = 0; i < 15; i++) { + /* Cycle DCLK */ + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + } + + /* Reset LE Low */ + MBIA045_LE = PAL_LOW; + + /* Loop 16 - Transfer actual command data to all 3 LED drivers */ + for (int i = 0; i < 16; i++) { + tmp_r = tmp_g = tmp_b = regValue; + /* Set data bit */ + uint16_t bits = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); + PB->DOUT = bits; + + /* Cycle DCLK */ + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + + if (i == 5) { + MBIA045_LE = PAL_HIGH; + } + + /* Next bit to sample */ + regValue <<= 1; + } + + /* Put GPIOB DMASK back */ + PB->DMASK = b_mask; + + /* Reset LE Low */ + MBIA045_LE = PAL_LOW; +} + +void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + /* + * @brief Pick a colour! Any colour! + */ + g_led_buffer[index] = (mbi_color){red, green, blue}; +} + +void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + /* + * brief Set every led to the provided colour + */ + for (size_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { + g_led_buffer[i] = (mbi_color){red, green, blue}; + } +} + +void MBIA045_update_pwm_buffers(void) { + /** + * Pass current PWM row to MBIA045 shift registers + * + * LE low + * Outer Loop 16 (one per register transfer - high to low): + * Inner Loop 16 (one per PWM bit): + * R_SDIN, G_SDIN & B_SDIN write + * DCLK High + * DCLK Low + * For final loop, set LE High + * + * Send Global Latch (16 DCLKs with LE high for last 3) + * + * Disable current row + * + * Reset PWM count: + * Loop 3: + * DCLK High + * DCLK Low + * LE High + * Loop 13: + * DCLK High + * DCLK Low + * LE Low + * + * Select new row (row meant for above data) + */ + + if (!g_pwm_buffer_update_required) return; + + uint32_t b_mask; + + /* Set Mask for GPIOB */ + b_mask = PB->DMASK; + PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); + + // LE Low & DCLK Low + MBIA045_LE = PAL_LOW; + MBIA045_DCLK = PAL_LOW; + + for (int i = 0; i < 16; i++) { + /* Inner Loop 16 */ + for (int j = 0; j < 16; j++) { + /* R_SDIN/G_SDIN/B_SDIN write */ + PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16 * i + j]; + + // If j is 15 set LE High + if (j == 15) { + MBIA045_LE = PAL_HIGH; + } + + /* Cycle DCLK */ + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + } // Inner Loop 16 + + // LE Low + MBIA045_LE = PAL_LOW; + } + + /* Send Global Latch */ + for (int i = 0; i < 16; i++) { + /* Cycle DCLK */ + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + + // if i is 13 set LE high + if (i == 13) { + MBIA045_LE = PAL_HIGH; + } + } + + // Reset LE Low + MBIA045_LE = PAL_LOW; + + // Reset Masks + PB->DMASK = b_mask; + + // Reset PWM count + // 3 DCLK cycles + for (int i = 0; i < 3; i++) { + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + } + + // Set LE High + MBIA045_LE = PAL_HIGH; + + // Loop 13 to generate PWM count reset + for (int i = 0; i < 13; i++) { + MBIA045_DCLK = PAL_HIGH; + MBIA045_DCLK = PAL_LOW; + } + + // Set LE Low + MBIA045_LE = PAL_LOW; + + // Set new row + MBIA045_select_row(g_pwm_buffer_row); + + // increment row count + check + g_pwm_buffer_row++; + if (g_pwm_buffer_row >= MBIA045_ROW_COUNT) { + g_pwm_buffer_row = 0; + } +} + +/** + * @brief Send the color buffer to the PWM buffer + */ +void MBIA045_flush(void) { + mbi_led led_pos; + mbi_color color; + + for (size_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { + led_pos = g_mbi_leds[i]; + color = g_led_buffer[i]; + + // Convert color values from 8 to 16 bit + uint16_t cur_r = pgm_read_word(&CIE1931_16_CURVE[color.r]); + uint16_t cur_g = pgm_read_word(&CIE1931_16_CURVE[color.g]); + uint16_t cur_b = pgm_read_word(&CIE1931_16_CURVE[color.b]); + + // Construct the pwm buffer + for (int i = 0; i < 16; i++) { + uint16_t tmp_r = cur_r; + uint16_t tmp_g = cur_g; + uint16_t tmp_b = cur_b; + + g_pwm_buffer[led_pos.row][i + (led_pos.col * 16)] = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); + cur_r <<= 1; + cur_g <<= 1; + cur_b <<= 1; + } + } + + g_pwm_buffer_update_required = true; +} + +/** + * @brief Disable all LED Rows + */ +void MBIA045_disable_rows(void) { + // Row 0 + PC4 = PAL_LOW; + + // Row 1 + PC5 = PAL_LOW; + + // Row 2 + PB3 = PAL_LOW; + + // Row 3 + PB2 = PAL_LOW; + + // Row 4 + PD9 = PAL_LOW; +} + +/** + * @brief Enable the specific LED row, disabling all others + */ +void MBIA045_select_row(int row) { + MBIA045_disable_rows(); + switch (row) { + case 0: // Row 0 + PC4 = PAL_HIGH; + break; + case 1: // Row 1 + PC5 = PAL_HIGH; + break; + case 2: // Row 2 + PB3 = PAL_HIGH; + break; + case 3: // Row 3 + PB2 = PAL_HIGH; + break; + case 4: // Row 4 + PD9 = PAL_HIGH; + break; + } +} + +OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { + OSAL_IRQ_PROLOGUE(); + + /* Check for PWM1 underflow IRQ */ + if ((PWMA->PIIR >> PWM_PIIR_PWMIF1_Pos) & 1) { + /* Clear interrupt flag */ + PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; + MBIA045_update_pwm_buffers(); + } + + OSAL_IRQ_EPILOGUE(); +} + +const rgb_matrix_driver_t rgb_matrix_driver = { + .init = MBIA045_init, + .flush = MBIA045_flush, + .set_color = MBIA045_set_color, + .set_color_all = MBIA045_set_color_all, +}; +#endif diff --git a/keyboards/ducky/one2sf/1967st/config.h b/keyboards/ducky/one2sf/1967st/config.h index 5be70f8384d..e6ca932f52e 100644 --- a/keyboards/ducky/one2sf/1967st/config.h +++ b/keyboards/ducky/one2sf/1967st/config.h @@ -22,8 +22,6 @@ along with this program. If not, see . #define GPIO_INPUT_PIN_DELAY (NUC123_HCLK / 6 / 1000000L) -#define RGB_MATRIX_LED_COUNT 69 - #define ENABLE_RGB_MATRIX_BREATHING #define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT #define ENABLE_RGB_MATRIX_TYPING_HEATMAP diff --git a/keyboards/ducky/one2sf/1967st/info.json b/keyboards/ducky/one2sf/1967st/info.json index 8cc3f92a329..69150d2d4cc 100644 --- a/keyboards/ducky/one2sf/1967st/info.json +++ b/keyboards/ducky/one2sf/1967st/info.json @@ -8,8 +8,82 @@ "device_version": "0.0.1", "force_nkro": true }, + "features": { + "rgb_matrix": true + }, "rgb_matrix": { - "driver": "custom" + "driver": "custom", + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0, "flags": 4}, + {"matrix": [0, 1], "x": 16, "y": 0, "flags": 4}, + {"matrix": [0, 2], "x": 32, "y": 0, "flags": 4}, + {"matrix": [0, 3], "x": 48, "y": 0, "flags": 4}, + {"matrix": [0, 4], "x": 64, "y": 0, "flags": 4}, + {"matrix": [0, 5], "x": 80, "y": 0, "flags": 4}, + {"matrix": [0, 6], "x": 96, "y": 0, "flags": 4}, + {"matrix": [0, 7], "x": 112, "y": 0, "flags": 4}, + {"matrix": [0, 8], "x": 128, "y": 0, "flags": 4}, + {"matrix": [0, 9], "x": 144, "y": 0, "flags": 4}, + {"matrix": [0, 10], "x": 160, "y": 0, "flags": 4}, + {"matrix": [0, 11], "x": 176, "y": 0, "flags": 4}, + {"matrix": [0, 12], "x": 192, "y": 0, "flags": 4}, + {"matrix": [0, 13], "x": 208, "y": 0, "flags": 4}, + {"matrix": [0, 14], "x": 224, "y": 0, "flags": 4}, + {"matrix": [1, 0], "x": 0, "y": 16, "flags": 4}, + {"matrix": [1, 1], "x": 16, "y": 16, "flags": 4}, + {"matrix": [1, 2], "x": 32, "y": 16, "flags": 4}, + {"matrix": [1, 3], "x": 48, "y": 16, "flags": 4}, + {"matrix": [1, 4], "x": 64, "y": 16, "flags": 4}, + {"matrix": [1, 5], "x": 80, "y": 16, "flags": 4}, + {"matrix": [1, 6], "x": 96, "y": 16, "flags": 4}, + {"matrix": [1, 7], "x": 112, "y": 16, "flags": 4}, + {"matrix": [1, 8], "x": 128, "y": 16, "flags": 4}, + {"matrix": [1, 9], "x": 144, "y": 16, "flags": 4}, + {"matrix": [1, 10], "x": 160, "y": 16, "flags": 4}, + {"matrix": [1, 11], "x": 176, "y": 16, "flags": 4}, + {"matrix": [1, 12], "x": 192, "y": 16, "flags": 4}, + {"matrix": [1, 13], "x": 208, "y": 16, "flags": 4}, + {"matrix": [1, 14], "x": 224, "y": 16, "flags": 4}, + {"matrix": [2, 0], "x": 0, "y": 32, "flags": 5}, + {"matrix": [2, 1], "x": 16, "y": 32, "flags": 4}, + {"matrix": [2, 2], "x": 32, "y": 32, "flags": 4}, + {"matrix": [2, 3], "x": 48, "y": 32, "flags": 4}, + {"matrix": [2, 4], "x": 64, "y": 32, "flags": 4}, + {"matrix": [2, 5], "x": 80, "y": 32, "flags": 4}, + {"matrix": [2, 6], "x": 96, "y": 32, "flags": 4}, + {"matrix": [2, 7], "x": 112, "y": 32, "flags": 4}, + {"matrix": [2, 8], "x": 128, "y": 32, "flags": 4}, + {"matrix": [2, 9], "x": 144, "y": 32, "flags": 4}, + {"matrix": [2, 10], "x": 160, "y": 32, "flags": 4}, + {"matrix": [2, 11], "x": 176, "y": 32, "flags": 4}, + {"matrix": [2, 13], "x": 208, "y": 32, "flags": 4}, + {"matrix": [2, 14], "x": 224, "y": 32, "flags": 4}, + {"matrix": [3, 0], "x": 0, "y": 48, "flags": 5}, + {"matrix": [3, 2], "x": 32, "y": 48, "flags": 4}, + {"matrix": [3, 3], "x": 48, "y": 48, "flags": 4}, + {"matrix": [3, 4], "x": 64, "y": 48, "flags": 4}, + {"matrix": [3, 5], "x": 80, "y": 48, "flags": 4}, + {"matrix": [3, 6], "x": 96, "y": 48, "flags": 4}, + {"matrix": [3, 7], "x": 112, "y": 48, "flags": 4}, + {"matrix": [3, 8], "x": 128, "y": 48, "flags": 4}, + {"matrix": [3, 9], "x": 144, "y": 48, "flags": 4}, + {"matrix": [3, 10], "x": 160, "y": 48, "flags": 4}, + {"matrix": [3, 11], "x": 176, "y": 48, "flags": 4}, + {"matrix": [3, 12], "x": 192, "y": 48, "flags": 5}, + {"matrix": [3, 13], "x": 208, "y": 48, "flags": 4}, + {"matrix": [4, 0], "x": 0, "y": 64, "flags": 5}, + {"matrix": [4, 1], "x": 16, "y": 64, "flags": 5}, + {"matrix": [4, 2], "x": 32, "y": 64, "flags": 5}, + {"matrix": [4, 3], "x": 48, "y": 64, "flags": 4}, + {"matrix": [4, 5], "x": 80, "y": 64, "flags": 4}, + {"matrix": [4, 7], "x": 112, "y": 64, "flags": 4}, + {"matrix": [4, 9], "x": 144, "y": 64, "flags": 5}, + {"matrix": [4, 10], "x": 160, "y": 64, "flags": 5}, + {"matrix": [4, 11], "x": 176, "y": 64, "flags": 5}, + {"matrix": [4, 12], "x": 192, "y": 64, "flags": 4}, + {"matrix": [4, 13], "x": 208, "y": 64, "flags": 4}, + {"matrix": [4, 14], "x": 224, "y": 64, "flags": 4} + ] }, "matrix_pins": { "cols": ["B10", "B9", "C13", "C12", "C11", "C10", "C9", "C8", "A15", "A14", "A13", "D0", "D1", "D2", "B15", "B8"], diff --git a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c b/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c deleted file mode 100644 index 980687b88b7..00000000000 --- a/keyboards/ducky/one2sf/1967st/rgb_matrix_drivers.c +++ /dev/null @@ -1,469 +0,0 @@ -/* Copyright 2019 /u/KeepItUnder - * Copyright 2023 Hayley Hughes - * - * 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 . - */ - -/* - * MBIA045 datasheet available at - * https://pc-clinic.bg/wp-content/uploads/2021/05/mbia045-datasheet-va.00-en.pdf - */ - -#ifdef RGB_MATRIX_ENABLE - -# include - -# include "config.h" -# include "hal.h" -# include "progmem.h" -# include "rgb_matrix.h" - -# define MBIA045_CFGREG_DEFAULT 0b1000010000000000u - -# define MBIA045_DCLK PD4 -# define MBIA045_LE PD3 -# define MBIA045_EN PD5 - -# define MBIA045_ROW_COUNT 5 - -typedef struct mbi_led { - uint8_t row; - uint8_t col; -} __attribute__((packed)) mbi_led; - -typedef struct mbi_color { - uint8_t r; - uint8_t g; - uint8_t b; -} __attribute__((packed)) mbi_color; - -// Map physical layout to QMK led index -const mbi_led g_mbi_leds[RGB_MATRIX_LED_COUNT] = {{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {0, 9}, {0, 10}, {0, 11}, {0, 12}, {0, 13}, {0, 14}, {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {2, 9}, {2, 10}, {2, 11}, {2, 13}, {2, 14}, {3, 0}, {3, 2}, {3, 3}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, {3, 9}, {3, 10}, {3, 11}, {3, 12}, {3, 13}, {4, 0}, {4, 1}, {4, 2}, {4, 3}, {4, 5}, {4, 7}, {4, 9}, {4, 10}, {4, 11}, {4, 12}, {4, 13}, {4, 14}}; - -// Lightness curve using the CIE 1931 lightness formula -// Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm -const uint16_t CIE1931_16_CURVE[] PROGMEM = { - 0, 7, 14, 21, 28, 36, 43, 50, 57, 64, 71, 78, 85, 93, 100, 107, 114, 121, 128, 135, 142, 149, 157, 164, 172, 180, 189, 197, 206, 215, 225, 234, 244, 254, 265, 276, 287, 298, 310, 322, 334, 346, 359, 373, 386, 400, 414, 428, 443, 458, 474, 490, 506, 522, 539, 557, 574, 592, 610, 629, 648, 668, 688, 708, 729, 750, 771, 793, 815, 838, 861, 885, 909, 933, 958, 983, 1009, 1035, 1061, 1088, 1116, 1144, 1172, 1201, 1230, 1260, 1290, 1321, 1353, 1384, 1417, 1449, 1482, 1516, 1550, 1585, 1621, 1656, 1693, 1729, 1767, 1805, 1843, 1882, 1922, 1962, 2003, 2044, 2085, 2128, 2171, 2214, 2258, 2303, 2348, 2394, 2440, 2487, 2535, 2583, 2632, 2681, 2731, 2782, 2833, 2885, 2938, 2991, - 3045, 3099, 3154, 3210, 3266, 3323, 3381, 3439, 3498, 3558, 3618, 3679, 3741, 3803, 3867, 3930, 3995, 4060, 4126, 4193, 4260, 4328, 4397, 4466, 4536, 4607, 4679, 4752, 4825, 4899, 4973, 5049, 5125, 5202, 5280, 5358, 5437, 5517, 5598, 5680, 5762, 5845, 5929, 6014, 6100, 6186, 6273, 6361, 6450, 6540, 6630, 6722, 6814, 6907, 7001, 7095, 7191, 7287, 7385, 7483, 7582, 7682, 7782, 7884, 7986, 8090, 8194, 8299, 8405, 8512, 8620, 8729, 8838, 8949, 9060, 9173, 9286, 9400, 9516, 9632, 9749, 9867, 9986, 10106, 10227, 10348, 10471, 10595, 10720, 10845, 10972, 11100, 11228, 11358, 11489, 11620, 11753, 11887, 12021, 12157, 12294, 12432, 12570, 12710, 12851, 12993, 13136, 13279, 13424, 13570, 13718, 13866, 14015, 14165, 14317, 14469, 14622, 14777, 14933, 15089, 15247, 15406, 15566, 15727, 15890, 16053, 16217, 16383, -}; - -/** The PWM buffers the full rows of 16 PWM registers in each MBI5042 driver - * The buffers are arranged in serial format - * (MSB_R, MSB_G, MSB_B...LSB_R, LSB_G, LSB_B) - * as needed by the SDO pins on the MCU (R is B14; G is B13; B is B12) - * - * g_pwm_buffer has the DCLK-able output for an "R" row, a "G" row, and a "B" row of PWM - */ -uint16_t g_pwm_buffer[MBIA045_ROW_COUNT][16 * 16]; -mbi_color g_led_buffer[RGB_MATRIX_LED_COUNT]; - -bool g_pwm_buffer_update_required = false; -uint8_t g_pwm_buffer_row = 0; - -void MBIA045_init(void); -void MBIA045_set_current_gain(uint8_t gain); -void MBIA045_write_config_register(uint16_t regValue); -void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue); -void MBIA045_update_pwm_buffers(void); -void MBIA045_flush(void); -void MBIA045_disable_rows(void); -void MBIA045_select_row(int row); - -void MBIA045_init(void) { - /* Initialise all PWM arrays to zero. - * Perform one group transfer to turn LEDs off - * - * If there's a DMA requirement, set up DMA subsystems - */ - for (int i = 0; i < MBIA045_ROW_COUNT; i++) { - for (int j = 0; j < 256; j++) { - g_pwm_buffer[i][j] = 0; - } - } - - /* Setup PWM0 control registers for 2MHz GCLK - * and also 50 percentage PWM duty (makes a nice clock) - * - * Set PWM1 to be used as a 2kHz timer (interrupt but no output pin) - * which is used for row refresh/enable. - */ - - // Use the HCLK - // Note we need to 0 the bits first as the clksel register has a reset value - // of 0xFFFF_FFFF - CLK->CLKSEL1 &= ~CLK_CLKSEL1_PWM01_S_Msk; - CLK->CLKSEL1 |= 2 << CLK_CLKSEL1_PWM01_S_Pos; - - CLK->CLKSEL2 &= ~CLK_CLKSEL2_PWM01_S_E_Msk; - CLK->CLKSEL2 |= 2 << CLK_CLKSEL2_PWM01_S_E_Pos; - - // Enable the PWM peripheral clock - CLK->APBCLK |= 1 << CLK_APBCLK_PWM01_EN_Pos; - - // Set prescaler for PWM0 and PWM1 to 1 - PWMA->PPR |= 1 << PWM_PPR_CP01_Pos; - - // Enable PWM interrupt vector - // Interrupt priority value taken from chibios defaults - nvicEnableVector(NUC123_PWMA_NUMBER, 3); - - // Set clock division to 1 - PWMA->CSR |= 1 << PWM_CSR_CSR2_Pos; - - // Set pin PA12 to PWM0 - SYS->GPA_MFP |= 1 << 12; - - // Enable PWM0 output - PWMA->POE |= 1 << PWM_POE_PWM0_Pos; - - // Enable PWM0 and PWM1 auto reload - PWMA->PCR |= (1 << PWM_PCR_CH0MOD_Pos | 1 << PWM_PCR_CH1MOD_Pos); - - // Enable PWM1 reset interrupt - PWMA->PIER |= 1 << PWM_PIER_PWMIE1_Pos; - - // Set PWM0 freq to 9MHz and 50% duty cycle (it's just a nice clock) - // - // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] - // 72MHz/(1 + 1)*(1)*(3+1) - // - // duty = (CMR+1)/(CNR+1) - // (1+1)/(3+1) - PWMA->CNR0 = 3; - PWMA->CMR0 = 1; - - // Set PWM1 freq to 1.8kHz (duty doesn't matter) - // - // freq = HCLK/[(prescale+1)*(clock divider)*(CNR+1)] - // 72MHz/(1 + 1)*(1)*(3+1) - PWMA->CNR1 = 19999; - PWMA->CMR1 = 1; - - // Start PWM channel 0 and 1 - PWMA->PCR |= (1 << PWM_PCR_CH0EN_Pos | 1 << PWM_PCR_CH1EN_Pos); - - MBIA045_disable_rows(); - - // Enable the LED controllers - MBIA045_EN = PAL_LOW; - - MBIA045_set_current_gain(0b000011u); -} - -/** - * @brief Set LED driver current gain - * @detail The MBI5042 has a 6-bit current gain value (000000b ~ 111111b) - * used to adjust the global brightness of the LEDs attached to the PWM outputs - * - * Default value is 101011b - * - * Use MBI5042_CURRENT_GAIN to pass from keyboard config - */ -void MBIA045_set_current_gain(uint8_t gain) { - /** MB data transfer requires: - * Tell chip config register change is coming (Enable Write Configutarion) - * Pass config register data (Write Configuration Register) - */ - uint16_t regConfig = 0b00111111u & gain; - - regConfig <<= 4; - regConfig |= MBIA045_CFGREG_DEFAULT; - - MBIA045_write_config_register(regConfig); -} - -/** - * @brief Write configuration register ONLY DURING INIT - * @detail Set the contents of the configuration register (see top for bitfields) - * Each register write needs 2 * 16 bit transfers (1 x setup and 1 x data) - * - * For the Ducky One 2 mini there are 3 drivers, so output all three configs at once - */ -void MBIA045_write_config_register(uint16_t regValue) { - uint32_t b_mask; - uint16_t tmp_r, tmp_g, tmp_b; - - /* Set Mask for GPIOB */ - b_mask = PB->DMASK; - PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); - - /* LE Low & DCLK Low */ - MBIA045_LE = PAL_LOW; - MBIA045_DCLK = PAL_LOW; - - /* Do one DCLK cycle */ - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - - /* Set LE High */ - MBIA045_LE = PAL_HIGH; - - /* Loop 15 - Enable Write Configuration */ - for (int i = 0; i < 15; i++) { - /* Cycle DCLK */ - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - } - - /* Reset LE Low */ - MBIA045_LE = PAL_LOW; - - /* Loop 16 - Transfer actual command data to all 3 LED drivers */ - for (int i = 0; i < 16; i++) { - tmp_r = tmp_g = tmp_b = regValue; - /* Set data bit */ - uint16_t bits = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); - PB->DOUT = bits; - - /* Cycle DCLK */ - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - - if (i == 5) { - MBIA045_LE = PAL_HIGH; - } - - /* Next bit to sample */ - regValue <<= 1; - } - - /* Put GPIOB DMASK back */ - PB->DMASK = b_mask; - - /* Reset LE Low */ - MBIA045_LE = PAL_LOW; -} - -void MBIA045_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - /* - * @brief Pick a colour! Any colour! - */ - g_led_buffer[index] = (mbi_color){red, green, blue}; -} - -void MBIA045_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - /* - * brief Set every led to the provided colour - */ - for (size_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { - g_led_buffer[i] = (mbi_color){red, green, blue}; - } -} - -void MBIA045_update_pwm_buffers(void) { - /** - * Pass current PWM row to MBIA045 shift registers - * - * LE low - * Outer Loop 16 (one per register transfer - high to low): - * Inner Loop 16 (one per PWM bit): - * R_SDIN, G_SDIN & B_SDIN write - * DCLK High - * DCLK Low - * For final loop, set LE High - * - * Send Global Latch (16 DCLKs with LE high for last 3) - * - * Disable current row - * - * Reset PWM count: - * Loop 3: - * DCLK High - * DCLK Low - * LE High - * Loop 13: - * DCLK High - * DCLK Low - * LE Low - * - * Select new row (row meant for above data) - */ - - if (!g_pwm_buffer_update_required) return; - - uint32_t b_mask; - - /* Set Mask for GPIOB */ - b_mask = PB->DMASK; - PB->DMASK = ~(0x1u << 14 | 0x1u << 13 | 0x1u << 12); - - // LE Low & DCLK Low - MBIA045_LE = PAL_LOW; - MBIA045_DCLK = PAL_LOW; - - for (int i = 0; i < 16; i++) { - /* Inner Loop 16 */ - for (int j = 0; j < 16; j++) { - /* R_SDIN/G_SDIN/B_SDIN write */ - PB->DOUT = g_pwm_buffer[g_pwm_buffer_row][16 * i + j]; - - // If j is 15 set LE High - if (j == 15) { - MBIA045_LE = PAL_HIGH; - } - - /* Cycle DCLK */ - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - } // Inner Loop 16 - - // LE Low - MBIA045_LE = PAL_LOW; - } - - /* Send Global Latch */ - for (int i = 0; i < 16; i++) { - /* Cycle DCLK */ - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - - // if i is 13 set LE high - if (i == 13) { - MBIA045_LE = PAL_HIGH; - } - } - - // Reset LE Low - MBIA045_LE = PAL_LOW; - - // Reset Masks - PB->DMASK = b_mask; - - // Reset PWM count - // 3 DCLK cycles - for (int i = 0; i < 3; i++) { - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - } - - // Set LE High - MBIA045_LE = PAL_HIGH; - - // Loop 13 to generate PWM count reset - for (int i = 0; i < 13; i++) { - MBIA045_DCLK = PAL_HIGH; - MBIA045_DCLK = PAL_LOW; - } - - // Set LE Low - MBIA045_LE = PAL_LOW; - - // Set new row - MBIA045_select_row(g_pwm_buffer_row); - - // increment row count + check - g_pwm_buffer_row++; - if (g_pwm_buffer_row >= MBIA045_ROW_COUNT) { - g_pwm_buffer_row = 0; - } -} - -/** - * @brief Send the color buffer to the PWM buffer - */ -void MBIA045_flush(void) { - mbi_led led_pos; - mbi_color color; - - for (size_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) { - led_pos = g_mbi_leds[i]; - color = g_led_buffer[i]; - - // Convert color values from 8 to 16 bit - uint16_t cur_r = pgm_read_word(&CIE1931_16_CURVE[color.r]); - uint16_t cur_g = pgm_read_word(&CIE1931_16_CURVE[color.g]); - uint16_t cur_b = pgm_read_word(&CIE1931_16_CURVE[color.b]); - - // Construct the pwm buffer - for (int i = 0; i < 16; i++) { - uint16_t tmp_r = cur_r; - uint16_t tmp_g = cur_g; - uint16_t tmp_b = cur_b; - - g_pwm_buffer[led_pos.row][i + (led_pos.col * 16)] = ((0x1u & (tmp_r >> 15)) << 14) | ((0x1u & (tmp_g >> 15)) << 13) | ((0x1u & (tmp_b >> 15)) << 12); - cur_r <<= 1; - cur_g <<= 1; - cur_b <<= 1; - } - } - - g_pwm_buffer_update_required = true; -} - -/** - * @brief Disable all LED Rows - */ -void MBIA045_disable_rows(void) { - // Row 0 - PC4 = PAL_LOW; - - // Row 1 - PC5 = PAL_LOW; - - // Row 2 - PB3 = PAL_LOW; - - // Row 3 - PB2 = PAL_LOW; - - // Row 4 - PD9 = PAL_LOW; -} - -/** - * @brief Enable the specific LED row, disabling all others - */ -void MBIA045_select_row(int row) { - MBIA045_disable_rows(); - switch (row) { - case 0: // Row 0 - PC4 = PAL_HIGH; - break; - case 1: // Row 1 - PC5 = PAL_HIGH; - break; - case 2: // Row 2 - PB3 = PAL_HIGH; - break; - case 3: // Row 3 - PB2 = PAL_HIGH; - break; - case 4: // Row 4 - PD9 = PAL_HIGH; - break; - } -} - -OSAL_IRQ_HANDLER(NUC123_PWMA_HANDLER) { - OSAL_IRQ_PROLOGUE(); - - /* Check for PWM1 underflow IRQ */ - if ((PWMA->PIIR >> PWM_PIIR_PWMIF1_Pos) & 1) { - /* Clear interrupt flag */ - PWMA->PIIR |= 1 << PWM_PIIR_PWMIF1_Pos; - MBIA045_update_pwm_buffers(); - } - - OSAL_IRQ_EPILOGUE(); -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = MBIA045_init, - .flush = MBIA045_flush, - .set_color = MBIA045_set_color, - .set_color_all = MBIA045_set_color_all, -}; - -#endif diff --git a/keyboards/ducky/one2sf/1967st/rules.mk b/keyboards/ducky/one2sf/1967st/rules.mk index c6a35c4ec1e..2e3cc4c16b4 100644 --- a/keyboards/ducky/one2sf/1967st/rules.mk +++ b/keyboards/ducky/one2sf/1967st/rules.mk @@ -29,7 +29,3 @@ BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow AUDIO_ENABLE = no # Audio output DIP_SWITCH_ENABLE = yes - -RGB_MATRIX_ENABLE = yes - -SRC += rgb_matrix_drivers.c From e4b364ecd955c64ec1752440d007077d05e4489d Mon Sep 17 00:00:00 2001 From: Hayley Date: Sat, 13 Jan 2024 19:17:17 +1100 Subject: [PATCH 18/22] Remove old include Co-authored-by: Drashna Jaelre --- keyboards/ducky/one2sf/1967st/1967st.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/1967st.c b/keyboards/ducky/one2sf/1967st/1967st.c index 371bd99d93f..fda822defbb 100644 --- a/keyboards/ducky/one2sf/1967st/1967st.c +++ b/keyboards/ducky/one2sf/1967st/1967st.c @@ -25,8 +25,6 @@ #ifdef RGB_MATRIX_ENABLE # include - -# include "config.h" # include "hal.h" # include "progmem.h" # include "rgb_matrix.h" From 5e9ea73b122ff5998c14e6625a6cde7a6251e57d Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 18 Feb 2024 17:25:35 +1100 Subject: [PATCH 19/22] Fix row 5 enable pin --- keyboards/ducky/one2sf/1967st/1967st.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/1967st.c b/keyboards/ducky/one2sf/1967st/1967st.c index fda822defbb..998dda3b54a 100644 --- a/keyboards/ducky/one2sf/1967st/1967st.c +++ b/keyboards/ducky/one2sf/1967st/1967st.c @@ -419,7 +419,7 @@ void MBIA045_disable_rows(void) { PB2 = PAL_LOW; // Row 4 - PD9 = PAL_LOW; + PD8 = PAL_LOW; } /** @@ -441,7 +441,7 @@ void MBIA045_select_row(int row) { PB2 = PAL_HIGH; break; case 4: // Row 4 - PD9 = PAL_HIGH; + PD8 = PAL_HIGH; break; } } From 48ed9765d8eebbef6a4291b6246534965ea1b092 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Sun, 18 Feb 2024 17:33:46 +1100 Subject: [PATCH 20/22] Move keyboard features into info.json --- keyboards/ducky/one2sf/1967st/info.json | 5 +++++ keyboards/ducky/one2sf/1967st/rules.mk | 14 -------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/info.json b/keyboards/ducky/one2sf/1967st/info.json index 69150d2d4cc..aa469a0047b 100644 --- a/keyboards/ducky/one2sf/1967st/info.json +++ b/keyboards/ducky/one2sf/1967st/info.json @@ -9,6 +9,11 @@ "force_nkro": true }, "features": { + "bootmagic_enable": true, + "dip_switch_enable": true, + "extrakey_enable": true, + "mousekey_enable": true, + "nkro_enable": true, "rgb_matrix": true }, "rgb_matrix": { diff --git a/keyboards/ducky/one2sf/1967st/rules.mk b/keyboards/ducky/one2sf/1967st/rules.mk index 2e3cc4c16b4..5eb1c44f8a1 100644 --- a/keyboards/ducky/one2sf/1967st/rules.mk +++ b/keyboards/ducky/one2sf/1967st/rules.mk @@ -15,17 +15,3 @@ BOARD = NUC123SD4AN0 MCU = cortex-m0 # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 ARMV = 6 - -# Build Options -# change yes to no to disable -# -BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = no # Console for debug -COMMAND_ENABLE = no # Commands for debug and configuration -NKRO_ENABLE = yes # Enable N-Key Rollover -BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality -RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow -AUDIO_ENABLE = no # Audio output -DIP_SWITCH_ENABLE = yes From 486822199ecc665d12e7798036e13d896d440d89 Mon Sep 17 00:00:00 2001 From: Hayley Date: Sun, 18 Feb 2024 22:32:05 +1100 Subject: [PATCH 21/22] Move animations to info.json Additionally clean up info.json feature names Co-authored-by: Joel Challis --- keyboards/ducky/one2sf/1967st/config.h | 5 ----- keyboards/ducky/one2sf/1967st/info.json | 15 ++++++++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/keyboards/ducky/one2sf/1967st/config.h b/keyboards/ducky/one2sf/1967st/config.h index e6ca932f52e..92448f54d16 100644 --- a/keyboards/ducky/one2sf/1967st/config.h +++ b/keyboards/ducky/one2sf/1967st/config.h @@ -1,6 +1,5 @@ /* Copyright 2019 /u/KeepItUnder -Copyright 2023 Hayley Hughes 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 @@ -21,7 +20,3 @@ along with this program. If not, see . #define DIP_SWITCH_MATRIX_GRID { {0,14}, {1,14}, {2,14}, {3,14} } #define GPIO_INPUT_PIN_DELAY (NUC123_HCLK / 6 / 1000000L) - -#define ENABLE_RGB_MATRIX_BREATHING -#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT -#define ENABLE_RGB_MATRIX_TYPING_HEATMAP diff --git a/keyboards/ducky/one2sf/1967st/info.json b/keyboards/ducky/one2sf/1967st/info.json index aa469a0047b..3585f7e0c01 100644 --- a/keyboards/ducky/one2sf/1967st/info.json +++ b/keyboards/ducky/one2sf/1967st/info.json @@ -9,14 +9,19 @@ "force_nkro": true }, "features": { - "bootmagic_enable": true, - "dip_switch_enable": true, - "extrakey_enable": true, - "mousekey_enable": true, - "nkro_enable": true, + "bootmagic": true, + "dip_switch": true, + "extrakey": true, + "mousekey": true, + "nkro": true, "rgb_matrix": true }, "rgb_matrix": { + "animations": { + "breathing": true, + "cycle_left_right": true, + "typing_heatmap": true + }, "driver": "custom", "layout": [ {"matrix": [0, 0], "x": 0, "y": 0, "flags": 4}, From e30672f5adfe99fcd9759d0c51c76d52f416f219 Mon Sep 17 00:00:00 2001 From: Hayley Hughes Date: Tue, 20 Feb 2024 22:00:23 +1100 Subject: [PATCH 22/22] Add missing led to matrix layout --- keyboards/ducky/one2sf/1967st/info.json | 1 + 1 file changed, 1 insertion(+) diff --git a/keyboards/ducky/one2sf/1967st/info.json b/keyboards/ducky/one2sf/1967st/info.json index 3585f7e0c01..2dd46b71863 100644 --- a/keyboards/ducky/one2sf/1967st/info.json +++ b/keyboards/ducky/one2sf/1967st/info.json @@ -66,6 +66,7 @@ {"matrix": [2, 9], "x": 144, "y": 32, "flags": 4}, {"matrix": [2, 10], "x": 160, "y": 32, "flags": 4}, {"matrix": [2, 11], "x": 176, "y": 32, "flags": 4}, + {"matrix": [2, 12], "x": 192, "y": 32, "flags": 4}, {"matrix": [2, 13], "x": 208, "y": 32, "flags": 4}, {"matrix": [2, 14], "x": 224, "y": 32, "flags": 4}, {"matrix": [3, 0], "x": 0, "y": 48, "flags": 5},