From b08389c1be8735814860acf45950ef960caef984 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 13:12:50 +0800 Subject: [PATCH 01/32] Add a new led driver for Keychron's keyboards. --- common_features.mk | 9 +- drivers/led/ckled2001.c | 232 ++++++++++++++++ drivers/led/ckled2001.h | 339 ++++++++++++++++++++++++ lib/chibios-contrib | 2 +- quantum/rgb_matrix/rgb_matrix.h | 2 + quantum/rgb_matrix/rgb_matrix_drivers.c | 49 +++- 6 files changed, 630 insertions(+), 3 deletions(-) create mode 100644 drivers/led/ckled2001.c create mode 100644 drivers/led/ckled2001.h diff --git a/common_features.mk b/common_features.mk index 6a9754e58e84..e38c758bc383 100644 --- a/common_features.mk +++ b/common_features.mk @@ -243,7 +243,7 @@ endif endif RGB_MATRIX_ENABLE ?= no -VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom +VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 CKLED2001 WS2812 custom ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),) @@ -299,6 +299,13 @@ endif QUANTUM_LIB_SRC += i2c_master.c endif + ifeq ($(strip $(RGB_MATRIX_DRIVER)), CKLED2001) + OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE + COMMON_VPATH += $(DRIVER_PATH)/led + SRC += ckled2001.c + QUANTUM_LIB_SRC += i2c_master.c + endif + ifeq ($(strip $(RGB_MATRIX_DRIVER)), WS2812) OPT_DEFS += -DWS2812 WS2812_DRIVER_REQUIRED := yes diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c new file mode 100644 index 000000000000..0220228143df --- /dev/null +++ b/drivers/led/ckled2001.c @@ -0,0 +1,232 @@ +/* Copyright 2021 @ Keychron (https://www.keychron.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ckled2001.h" +#include "i2c_master.h" +#include "wait.h" + + +#ifndef CKLED2001_TIMEOUT +# define CKLED2001_TIMEOUT 100 +#endif + +#ifndef CKLED2001_PERSISTENCE +# define CKLED2001_PERSISTENCE 0 +#endif + +#ifndef PHASE_CHANNEL +# define PHASE_CHANNEL MSKPHASE_12CHANNEL +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the CKLED2001 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in CKLED2001_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[DRIVER_COUNT][192]; +bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; + +uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0}; +bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; + +bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + // If the transaction fails function returns false. + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if CKLED2001_PERSISTENCE > 0 + for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { + return false; + } +#endif + return true; +} + +bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // Assumes PG1 is already selected. + // If any of the transactions fails function returns false. + // Transmit PWM registers in 12 transfers of 16 bytes. + // g_twi_transfer_buffer[] is 20 bytes + + // Iterate over the pwm_buffer contents at 16 byte intervals. + for (int i = 0; i < 192; i += 16) { + g_twi_transfer_buffer[0] = i; + // Copy the data from i to i+15. + // Device will auto-increment register for data after the first byte + // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#if CKLED2001_PERSISTENCE > 0 + for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { + return false; + } +#endif + } + return true; +} + +void CKLED2001_init(uint8_t addr) { + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to shutdown mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); + //** Setting internal channel pulldown/pullup + CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL); + //** Select number of scan phase + CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL); + //** Setting PWM Delay Phase + CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE); + //** Setting Driving/Sinking Channel Slew Rate + CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE); + //** Setting Iref + CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE); + + /*--------Set LED CONTROL PAGE (Page 0)------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for(int i = 0; i < LED_CONTROL_ON_OFF_LENGTH ; i++) { + CKLED2001_write_register(addr, i, 0x00); + } + + /*--------Set PWM PAGE (Page 1)------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); + for(int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { + CKLED2001_write_register(addr, i, 0x00); + } + + /*--------Set CURRENT PAGE (Page 4)------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE); + for(int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { + CKLED2001_write_register(addr, i, 0xFF); + } + + /*--------Enable LEDs ON/OFF------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for(int i = 0; i< LED_CONTROL_ON_OFF_LENGTH ; i++) { + CKLED2001_write_register(addr, i, 0xFF); + } + + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); +} + +void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + ckled2001_led led = g_ckled2001_leds[index]; + + g_pwm_buffer[led.driver][led.r] = red; + g_pwm_buffer[led.driver][led.g] = green; + g_pwm_buffer[led.driver][led.b] = blue; + g_pwm_buffer_update_required[led.driver] = true; + } +} + +void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + CKLED2001_set_color(i, red, green, blue); + } +} + +void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + ckled2001_led led = g_ckled2001_leds[index]; + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } + else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } + else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } + else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); + + // If any of the transactions fail we risk writing dirty PG0, + // refresh page 0 just in case. + if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) { + g_led_control_registers_update_required[index] = true; + } + } + g_pwm_buffer_update_required[index] = false; +} + +void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + CKLED2001_write_register(addr,CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < 24; i++) { + CKLED2001_write_register(addr, i, g_led_control_registers[index][i]); + } + } + g_led_control_registers_update_required[index] = false; +} + +void CKLED2001_return_normal(uint8_t addr) { + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); +} + +void CKLED2001_shutdown(uint8_t addr) { + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to shutdown mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); + //** Write SW Sleep Register + CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE); +} \ No newline at end of file diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h new file mode 100644 index 000000000000..b6fdd39cd310 --- /dev/null +++ b/drivers/led/ckled2001.h @@ -0,0 +1,339 @@ +/* Copyright 2021 @ Keychron (https://www.keychron.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include "progmem.h" + +typedef struct ckled2001_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) ckled2001_led; + +extern const ckled2001_led __flash g_ckled2001_leds[DRIVER_LED_TOTAL]; + +void CKLED2001_init(uint8_t addr); +bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data); +bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index); +void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index); + +void CKLED2001_return_normal(uint8_t addr); +void CKLED2001_shutdown(uint8_t addr); + +/*--------Registers Page Define------------*/ +#define CONFIGURE_CMD_PAGE 0xFD +#define LED_CONTROL_PAGE 0x00 +#define LED_PWM_PAGE 0x01 +#define FUNCTION_PAGE 0x03 +#define CURRENT_TUNE_PAGE 0x04 + +/*--------Function Register: address 0x00------------*/ +#define CONFIGURATION_REG 0x00 +#define MSKSW_SHUT_DOWN_MODE (0x0<<0) +#define MSKSW_NORMAL_MODE (0x1<<0) + +#define DRIVER_ID_REG 0x11 +#define CKLED2001_ID 0x8A + +#define PDU_REG 0x13 +#define MSKSET_CA_CB_CHANNEL 0xAA +#define MSKCLR_CA_CB_CHANNEL 0x00 + +#define SCAN_PHASE_REG 0x14 +#define MSKPHASE_12CHANNEL 0x00 +#define MSKPHASE_11CHANNEL 0x01 +#define MSKPHASE_10CHANNEL 0x02 +#define MSKPHASE_9CHANNEL 0x03 +#define MSKPHASE_8CHANNEL 0x04 +#define MSKPHASE_7CHANNEL 0x05 +#define MSKPHASE_6CHANNEL 0x06 +#define MSKPHASE_5CHANNEL 0x07 +#define MSKPHASE_4CHANNEL 0x08 +#define MSKPHASE_3CHANNEL 0x09 +#define MSKPHASE_2CHANNEL 0x0A +#define MSKPHASE_1CHANNEL 0x0B + +#define SLEW_RATE_CONTROL_MODE1_REG 0x15 +#define MSKPWM_DELAY_PHASE_ENABLE 0x04 +#define MSKPWM_DELAY_PHASE_DISABLE 0x00 + +#define SLEW_RATE_CONTROL_MODE2_REG 0x16 +#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE 0xC0 +#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00 + +#define OPEN_SHORT_ENABLE_REG 0x17 +#define MSKOPEN_DETECTION_ENABLE (0x01<<7) +#define MSKOPEN_DETECTION_DISABLE (0x00) + +#define MSKSHORT_DETECTION_ENABLE (0x01<<6) +#define MSKSHORT_DETECTION_DISABLE (0x00) + +#define OPEN_SHORT_DUTY_REG 0x18 +#define OPEN_SHORT_FLAG_REG 0x19 + +#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01<<7) +#define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00) + +#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01<<6) +#define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00) + +#define SOFTWARE_SLEEP_REG 0x1A +#define MSKSLEEP_ENABLE 0x02 +#define MSKSLEEP_DISABLE 0x00 + +/*--------LED Control Registers------------*/ +#define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0 +#define LED_CONTROL_ON_OFF_LAST_ADDR 0x17 +#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR-LED_CONTROL_ON_OFF_FIRST_ADDR)+1) + +#define LED_CONTROL_OPEN_FIRST_ADDR 0x18 +#define LED_CONTROL_OPEN_LAST_ADDR 0x2F +#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR-LED_CONTROL_OPEN_FIRST_ADDR)+1) + +#define LED_CONTROL_SHORT_FIRST_ADDR 0x30 +#define LED_CONTROL_SHORT_LAST_ADDR 0x47 +#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR-LED_CONTROL_SHORT_FIRST_ADDR)+1) + +#define LED_CONTROL_PAGE_LENGTH 0x48 + +/*--------LED Control Registers------------*/ +#define LED_PWM_FIRST_ADDR 0x00 +#define LED_PWM_LAST_ADDR 0xBF +#define LED_PWM_LENGTH 0xC0 + +/*--------Current Tune Registers------------*/ +#define LED_CURRENT_TUNE_FIRST_ADDR 0x00 +#define LED_CURRENT_TUNE_LAST_ADDR 0x0B +#define LED_CURRENT_TUNE_LENGTH 0x0C + +#define A_1 0x00 +#define A_2 0x01 +#define A_3 0x02 +#define A_4 0x03 +#define A_5 0x04 +#define A_6 0x05 +#define A_7 0x06 +#define A_8 0x07 +#define A_9 0x08 +#define A_10 0x09 +#define A_11 0x0A +#define A_12 0x0B +#define A_13 0x0C +#define A_14 0x0D +#define A_15 0x0E +#define A_16 0x0F + +#define B_1 0x10 +#define B_2 0x11 +#define B_3 0x12 +#define B_4 0x13 +#define B_5 0x14 +#define B_6 0x15 +#define B_7 0x16 +#define B_8 0x17 +#define B_9 0x18 +#define B_10 0x19 +#define B_11 0x1A +#define B_12 0x1B +#define B_13 0x1C +#define B_14 0x1D +#define B_15 0x1E +#define B_16 0x1F + +#define C_1 0x20 +#define C_2 0x21 +#define C_3 0x22 +#define C_4 0x23 +#define C_5 0x24 +#define C_6 0x25 +#define C_7 0x26 +#define C_8 0x27 +#define C_9 0x28 +#define C_10 0x29 +#define C_11 0x2A +#define C_12 0x2B +#define C_13 0x2C +#define C_14 0x2D +#define C_15 0x2E +#define C_16 0x2F + +#define D_1 0x30 +#define D_2 0x31 +#define D_3 0x32 +#define D_4 0x33 +#define D_5 0x34 +#define D_6 0x35 +#define D_7 0x36 +#define D_8 0x37 +#define D_9 0x38 +#define D_10 0x39 +#define D_11 0x3A +#define D_12 0x3B +#define D_13 0x3C +#define D_14 0x3D +#define D_15 0x3E +#define D_16 0x3F + +#define E_1 0x40 +#define E_2 0x41 +#define E_3 0x42 +#define E_4 0x43 +#define E_5 0x44 +#define E_6 0x45 +#define E_7 0x46 +#define E_8 0x47 +#define E_9 0x48 +#define E_10 0x49 +#define E_11 0x4A +#define E_12 0x4B +#define E_13 0x4C +#define E_14 0x4D +#define E_15 0x4E +#define E_16 0x4F + +#define F_1 0x50 +#define F_2 0x51 +#define F_3 0x52 +#define F_4 0x53 +#define F_5 0x54 +#define F_6 0x55 +#define F_7 0x56 +#define F_8 0x57 +#define F_9 0x58 +#define F_10 0x59 +#define F_11 0x5A +#define F_12 0x5B +#define F_13 0x5C +#define F_14 0x5D +#define F_15 0x5E +#define F_16 0x5F + +#define G_1 0x60 +#define G_2 0x61 +#define G_3 0x62 +#define G_4 0x63 +#define G_5 0x64 +#define G_6 0x65 +#define G_7 0x66 +#define G_8 0x67 +#define G_9 0x68 +#define G_10 0x69 +#define G_11 0x6A +#define G_12 0x6B +#define G_13 0x6C +#define G_14 0x6D +#define G_15 0x6E +#define G_16 0x6F + +#define H_1 0x70 +#define H_2 0x71 +#define H_3 0x72 +#define H_4 0x73 +#define H_5 0x74 +#define H_6 0x75 +#define H_7 0x76 +#define H_8 0x77 +#define H_9 0x78 +#define H_10 0x79 +#define H_11 0x7A +#define H_12 0x7B +#define H_13 0x7C +#define H_14 0x7D +#define H_15 0x7E +#define H_16 0x7F + +#define I_1 0x80 +#define I_2 0x81 +#define I_3 0x82 +#define I_4 0x83 +#define I_5 0x84 +#define I_6 0x85 +#define I_7 0x86 +#define I_8 0x87 +#define I_9 0x88 +#define I_10 0x89 +#define I_11 0x8A +#define I_12 0x8B +#define I_13 0x8C +#define I_14 0x8D +#define I_15 0x8E +#define I_16 0x8F + +#define J_1 0x90 +#define J_2 0x91 +#define J_3 0x92 +#define J_4 0x93 +#define J_5 0x94 +#define J_6 0x95 +#define J_7 0x96 +#define J_8 0x97 +#define J_9 0x98 +#define J_10 0x99 +#define J_11 0x9A +#define J_12 0x9B +#define J_13 0x9C +#define J_14 0x9D +#define J_15 0x9E +#define J_16 0x9F + +#define K_1 0xA0 +#define K_2 0xA1 +#define K_3 0xA2 +#define K_4 0xA3 +#define K_5 0xA4 +#define K_6 0xA5 +#define K_7 0xA6 +#define K_8 0xA7 +#define K_9 0xA8 +#define K_10 0xA9 +#define K_11 0xAA +#define K_12 0xAB +#define K_13 0xAC +#define K_14 0xAD +#define K_15 0xAE +#define K_16 0xAF + +#define L_1 0xB0 +#define L_2 0xB1 +#define L_3 0xB2 +#define L_4 0xB3 +#define L_5 0xB4 +#define L_6 0xB5 +#define L_7 0xB6 +#define L_8 0xB7 +#define L_9 0xB8 +#define L_10 0xB9 +#define L_11 0xBA +#define L_12 0xBB +#define L_13 0xBC +#define L_14 0xBD +#define L_15 0xBE +#define L_16 0xBF \ No newline at end of file diff --git a/lib/chibios-contrib b/lib/chibios-contrib index d1c2126d1cd8..4568901a91e9 160000 --- a/lib/chibios-contrib +++ b/lib/chibios-contrib @@ -1 +1 @@ -Subproject commit d1c2126d1cd867c50127da84425805e225df8555 +Subproject commit 4568901a91e9bef78ea96a7a83e8150fe1f7353a diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index f53e011c1bd9..1b4389c5b8e2 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -33,6 +33,8 @@ # include "is31fl3737.h" #elif defined(IS31FL3741) # include "is31fl3741.h" +#elif defined(CKLED2001) +# include "ckled2001.h" #elif defined(AW20216) # include "aw20216.h" #elif defined(WS2812) diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index 4335088eb89d..e4345866acb7 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c @@ -23,7 +23,7 @@ * be here if shared between boards. */ -#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) +#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) || defined(CKLED2001) # include "i2c_master.h" // TODO: Remove this at some later date @@ -80,6 +80,18 @@ static void init(void) { # elif defined(IS31FL3741) IS31FL3741_init(DRIVER_ADDR_1); + +# elif defined(CKLED2001) + CKLED2001_init(DRIVER_ADDR_1); +# if defined(DRIVER_ADDR_2) + CKLED2001_init(DRIVER_ADDR_2); +# if defined(DRIVER_ADDR_3) + CKLED2001_init(DRIVER_ADDR_3); +# if defined(DRIVER_ADDR_4) + CKLED2001_init(DRIVER_ADDR_4); +# endif +# endif +# endif # endif for (int index = 0; index < DRIVER_LED_TOTAL; index++) { @@ -94,6 +106,8 @@ static void init(void) { IS31FL3737_set_led_control_register(index, enabled, enabled, enabled); # elif defined(IS31FL3741) IS31FL3741_set_led_control_register(index, enabled, enabled, enabled); +# elif defined(CKLED2001) + CKLED2001_set_led_control_register(index, enabled, enabled, enabled); # endif } @@ -130,6 +144,18 @@ static void init(void) { # elif defined(IS31FL3741) IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); + +# elif defined(CKLED2001) + CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0); +# if defined(DRIVER_ADDR_2) + CKLED2001_update_led_control_registers(DRIVER_ADDR_2, 1); +# if defined(DRIVER_ADDR_3) + CKLED2001_update_led_control_registers(DRIVER_ADDR_3, 2); +# if defined(DRIVER_ADDR_4) + CKLED2001_update_led_control_registers(DRIVER_ADDR_4, 3); +# endif +# endif +# endif # endif } @@ -204,6 +230,27 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color = IS31FL3741_set_color, .set_color_all = IS31FL3741_set_color_all, }; + +# elif defined(CKLED2001) +static void flush(void) { + CKLED2001_update_pwm_buffers(DRIVER_ADDR_1, 0); +# if defined(DRIVER_ADDR_2) + CKLED2001_update_pwm_buffers(DRIVER_ADDR_2, 1); +# if defined(DRIVER_ADDR_3) + CKLED2001_update_pwm_buffers(DRIVER_ADDR_3, 2); +# if defined(DRIVER_ADDR_4) + CKLED2001_update_pwm_buffers(DRIVER_ADDR_4, 3); +# endif +# endif +# endif +} + +const rgb_matrix_driver_t rgb_matrix_driver = { + .init = init, + .flush = flush, + .set_color = CKLED2001_set_color, + .set_color_all = CKLED2001_set_color_all, +}; # endif #elif defined(AW20216) From c94ccf6637e09a6b41963fa2055c4345110f7649 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 15:10:19 +0800 Subject: [PATCH 02/32] Update ckled2001.c/ckled2001.h. --- drivers/led/ckled2001.c | 55 ++-- drivers/led/ckled2001.h | 382 ++++++++++++------------ quantum/rgb_matrix/rgb_matrix_drivers.c | 4 +- 3 files changed, 219 insertions(+), 222 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 0220228143df..1003608e106e 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -97,48 +97,48 @@ bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { } void CKLED2001_init(uint8_t addr) { - //** Select to function page + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - //** Setting LED driver to shutdown mode + // Setting LED driver to shutdown mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); - //** Setting internal channel pulldown/pullup + // Setting internal channel pulldown/pullup CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL); - //** Select number of scan phase + // Select number of scan phase CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL); - //** Setting PWM Delay Phase + // Setting PWM Delay Phase CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE); - //** Setting Driving/Sinking Channel Slew Rate + // Setting Driving/Sinking Channel Slew Rate CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE); - //** Setting Iref + // Setting Iref CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE); - /*--------Set LED CONTROL PAGE (Page 0)------------*/ + // Set LED CONTROL PAGE (Page 0) CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for(int i = 0; i < LED_CONTROL_ON_OFF_LENGTH ; i++) { + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH ; i++) { CKLED2001_write_register(addr, i, 0x00); } - /*--------Set PWM PAGE (Page 1)------------*/ + // Set PWM PAGE (Page 1) CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); - for(int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { CKLED2001_write_register(addr, i, 0x00); } - /*--------Set CURRENT PAGE (Page 4)------------*/ + // Set CURRENT PAGE (Page 4) CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE); - for(int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { CKLED2001_write_register(addr, i, 0xFF); } - /*--------Enable LEDs ON/OFF------------*/ + // Enable LEDs ON/OFF CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for(int i = 0; i< LED_CONTROL_ON_OFF_LENGTH ; i++) { + for (int i = 0; i< LED_CONTROL_ON_OFF_LENGTH ; i++) { CKLED2001_write_register(addr, i, 0xFF); } - //** Select to function page + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - //** Setting LED driver to normal mode + // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } @@ -171,20 +171,17 @@ void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, boo if (red) { g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); - } - else { + } else { g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); } if (green) { g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); - } - else { + } else { g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); } if (blue) { g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); - } - else { + } else { g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); } @@ -207,7 +204,7 @@ void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) { void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { if (g_led_control_registers_update_required[index]) { - CKLED2001_write_register(addr,CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); for (int i = 0; i < 24; i++) { CKLED2001_write_register(addr, i, g_led_control_registers[index][i]); } @@ -216,17 +213,17 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { } void CKLED2001_return_normal(uint8_t addr) { - //** Select to function page + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - //** Setting LED driver to normal mode + // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } void CKLED2001_shutdown(uint8_t addr) { - //** Select to function page + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - //** Setting LED driver to shutdown mode + // Setting LED driver to shutdown mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); - //** Write SW Sleep Register + // Write SW Sleep Register CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE); } \ No newline at end of file diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h index b6fdd39cd310..0135726a6d08 100644 --- a/drivers/led/ckled2001.h +++ b/drivers/led/ckled2001.h @@ -48,101 +48,101 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index); void CKLED2001_return_normal(uint8_t addr); void CKLED2001_shutdown(uint8_t addr); -/*--------Registers Page Define------------*/ -#define CONFIGURE_CMD_PAGE 0xFD -#define LED_CONTROL_PAGE 0x00 -#define LED_PWM_PAGE 0x01 -#define FUNCTION_PAGE 0x03 -#define CURRENT_TUNE_PAGE 0x04 - -/*--------Function Register: address 0x00------------*/ -#define CONFIGURATION_REG 0x00 -#define MSKSW_SHUT_DOWN_MODE (0x0<<0) -#define MSKSW_NORMAL_MODE (0x1<<0) - -#define DRIVER_ID_REG 0x11 -#define CKLED2001_ID 0x8A - -#define PDU_REG 0x13 -#define MSKSET_CA_CB_CHANNEL 0xAA -#define MSKCLR_CA_CB_CHANNEL 0x00 - -#define SCAN_PHASE_REG 0x14 -#define MSKPHASE_12CHANNEL 0x00 -#define MSKPHASE_11CHANNEL 0x01 -#define MSKPHASE_10CHANNEL 0x02 -#define MSKPHASE_9CHANNEL 0x03 -#define MSKPHASE_8CHANNEL 0x04 -#define MSKPHASE_7CHANNEL 0x05 -#define MSKPHASE_6CHANNEL 0x06 -#define MSKPHASE_5CHANNEL 0x07 -#define MSKPHASE_4CHANNEL 0x08 -#define MSKPHASE_3CHANNEL 0x09 -#define MSKPHASE_2CHANNEL 0x0A -#define MSKPHASE_1CHANNEL 0x0B - -#define SLEW_RATE_CONTROL_MODE1_REG 0x15 -#define MSKPWM_DELAY_PHASE_ENABLE 0x04 -#define MSKPWM_DELAY_PHASE_DISABLE 0x00 - -#define SLEW_RATE_CONTROL_MODE2_REG 0x16 -#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE 0xC0 -#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00 - -#define OPEN_SHORT_ENABLE_REG 0x17 -#define MSKOPEN_DETECTION_ENABLE (0x01<<7) -#define MSKOPEN_DETECTION_DISABLE (0x00) - -#define MSKSHORT_DETECTION_ENABLE (0x01<<6) -#define MSKSHORT_DETECTION_DISABLE (0x00) - -#define OPEN_SHORT_DUTY_REG 0x18 -#define OPEN_SHORT_FLAG_REG 0x19 - -#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01<<7) -#define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00) - -#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01<<6) -#define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00) - -#define SOFTWARE_SLEEP_REG 0x1A -#define MSKSLEEP_ENABLE 0x02 -#define MSKSLEEP_DISABLE 0x00 - -/*--------LED Control Registers------------*/ -#define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0 -#define LED_CONTROL_ON_OFF_LAST_ADDR 0x17 -#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR-LED_CONTROL_ON_OFF_FIRST_ADDR)+1) - -#define LED_CONTROL_OPEN_FIRST_ADDR 0x18 -#define LED_CONTROL_OPEN_LAST_ADDR 0x2F -#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR-LED_CONTROL_OPEN_FIRST_ADDR)+1) - -#define LED_CONTROL_SHORT_FIRST_ADDR 0x30 -#define LED_CONTROL_SHORT_LAST_ADDR 0x47 -#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR-LED_CONTROL_SHORT_FIRST_ADDR)+1) +// Registers Page Define +#define CONFIGURE_CMD_PAGE 0xFD +#define LED_CONTROL_PAGE 0x00 +#define LED_PWM_PAGE 0x01 +#define FUNCTION_PAGE 0x03 +#define CURRENT_TUNE_PAGE 0x04 + +// Function Register: address 0x00 +#define CONFIGURATION_REG 0x00 +#define MSKSW_SHUT_DOWN_MODE (0x0<<0) +#define MSKSW_NORMAL_MODE (0x1<<0) + +#define DRIVER_ID_REG 0x11 +#define CKLED2001_ID 0x8A + +#define PDU_REG 0x13 +#define MSKSET_CA_CB_CHANNEL 0xAA +#define MSKCLR_CA_CB_CHANNEL 0x00 + +#define SCAN_PHASE_REG 0x14 +#define MSKPHASE_12CHANNEL 0x00 +#define MSKPHASE_11CHANNEL 0x01 +#define MSKPHASE_10CHANNEL 0x02 +#define MSKPHASE_9CHANNEL 0x03 +#define MSKPHASE_8CHANNEL 0x04 +#define MSKPHASE_7CHANNEL 0x05 +#define MSKPHASE_6CHANNEL 0x06 +#define MSKPHASE_5CHANNEL 0x07 +#define MSKPHASE_4CHANNEL 0x08 +#define MSKPHASE_3CHANNEL 0x09 +#define MSKPHASE_2CHANNEL 0x0A +#define MSKPHASE_1CHANNEL 0x0B + +#define SLEW_RATE_CONTROL_MODE1_REG 0x15 +#define MSKPWM_DELAY_PHASE_ENABLE 0x04 +#define MSKPWM_DELAY_PHASE_DISABLE 0x00 + +#define SLEW_RATE_CONTROL_MODE2_REG 0x16 +#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE 0xC0 +#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00 + +#define OPEN_SHORT_ENABLE_REG 0x17 +#define MSKOPEN_DETECTION_ENABLE (0x01<<7) +#define MSKOPEN_DETECTION_DISABLE (0x00) + +#define MSKSHORT_DETECTION_ENABLE (0x01<<6) +#define MSKSHORT_DETECTION_DISABLE (0x00) + +#define OPEN_SHORT_DUTY_REG 0x18 +#define OPEN_SHORT_FLAG_REG 0x19 + +#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01<<7) +#define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00) + +#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01<<6) +#define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00) + +#define SOFTWARE_SLEEP_REG 0x1A +#define MSKSLEEP_ENABLE 0x02 +#define MSKSLEEP_DISABLE 0x00 + +// LED Control Registers +#define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0 +#define LED_CONTROL_ON_OFF_LAST_ADDR 0x17 +#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR-LED_CONTROL_ON_OFF_FIRST_ADDR)+1) + +#define LED_CONTROL_OPEN_FIRST_ADDR 0x18 +#define LED_CONTROL_OPEN_LAST_ADDR 0x2F +#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR-LED_CONTROL_OPEN_FIRST_ADDR)+1) + +#define LED_CONTROL_SHORT_FIRST_ADDR 0x30 +#define LED_CONTROL_SHORT_LAST_ADDR 0x47 +#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR-LED_CONTROL_SHORT_FIRST_ADDR)+1) #define LED_CONTROL_PAGE_LENGTH 0x48 -/*--------LED Control Registers------------*/ -#define LED_PWM_FIRST_ADDR 0x00 -#define LED_PWM_LAST_ADDR 0xBF -#define LED_PWM_LENGTH 0xC0 - -/*--------Current Tune Registers------------*/ -#define LED_CURRENT_TUNE_FIRST_ADDR 0x00 -#define LED_CURRENT_TUNE_LAST_ADDR 0x0B -#define LED_CURRENT_TUNE_LENGTH 0x0C - -#define A_1 0x00 -#define A_2 0x01 -#define A_3 0x02 -#define A_4 0x03 -#define A_5 0x04 -#define A_6 0x05 -#define A_7 0x06 -#define A_8 0x07 -#define A_9 0x08 +// LED Control Registers +#define LED_PWM_FIRST_ADDR 0x00 +#define LED_PWM_LAST_ADDR 0xBF +#define LED_PWM_LENGTH 0xC0 + +// Current Tune Registers +#define LED_CURRENT_TUNE_FIRST_ADDR 0x00 +#define LED_CURRENT_TUNE_LAST_ADDR 0x0B +#define LED_CURRENT_TUNE_LENGTH 0x0C + +#define A_1 0x00 +#define A_2 0x01 +#define A_3 0x02 +#define A_4 0x03 +#define A_5 0x04 +#define A_6 0x05 +#define A_7 0x06 +#define A_8 0x07 +#define A_9 0x08 #define A_10 0x09 #define A_11 0x0A #define A_12 0x0B @@ -151,15 +151,15 @@ void CKLED2001_shutdown(uint8_t addr); #define A_15 0x0E #define A_16 0x0F -#define B_1 0x10 -#define B_2 0x11 -#define B_3 0x12 -#define B_4 0x13 -#define B_5 0x14 -#define B_6 0x15 -#define B_7 0x16 -#define B_8 0x17 -#define B_9 0x18 +#define B_1 0x10 +#define B_2 0x11 +#define B_3 0x12 +#define B_4 0x13 +#define B_5 0x14 +#define B_6 0x15 +#define B_7 0x16 +#define B_8 0x17 +#define B_9 0x18 #define B_10 0x19 #define B_11 0x1A #define B_12 0x1B @@ -168,15 +168,15 @@ void CKLED2001_shutdown(uint8_t addr); #define B_15 0x1E #define B_16 0x1F -#define C_1 0x20 -#define C_2 0x21 -#define C_3 0x22 -#define C_4 0x23 -#define C_5 0x24 -#define C_6 0x25 -#define C_7 0x26 -#define C_8 0x27 -#define C_9 0x28 +#define C_1 0x20 +#define C_2 0x21 +#define C_3 0x22 +#define C_4 0x23 +#define C_5 0x24 +#define C_6 0x25 +#define C_7 0x26 +#define C_8 0x27 +#define C_9 0x28 #define C_10 0x29 #define C_11 0x2A #define C_12 0x2B @@ -185,15 +185,15 @@ void CKLED2001_shutdown(uint8_t addr); #define C_15 0x2E #define C_16 0x2F -#define D_1 0x30 -#define D_2 0x31 -#define D_3 0x32 -#define D_4 0x33 -#define D_5 0x34 -#define D_6 0x35 -#define D_7 0x36 -#define D_8 0x37 -#define D_9 0x38 +#define D_1 0x30 +#define D_2 0x31 +#define D_3 0x32 +#define D_4 0x33 +#define D_5 0x34 +#define D_6 0x35 +#define D_7 0x36 +#define D_8 0x37 +#define D_9 0x38 #define D_10 0x39 #define D_11 0x3A #define D_12 0x3B @@ -202,15 +202,15 @@ void CKLED2001_shutdown(uint8_t addr); #define D_15 0x3E #define D_16 0x3F -#define E_1 0x40 -#define E_2 0x41 -#define E_3 0x42 -#define E_4 0x43 -#define E_5 0x44 -#define E_6 0x45 -#define E_7 0x46 -#define E_8 0x47 -#define E_9 0x48 +#define E_1 0x40 +#define E_2 0x41 +#define E_3 0x42 +#define E_4 0x43 +#define E_5 0x44 +#define E_6 0x45 +#define E_7 0x46 +#define E_8 0x47 +#define E_9 0x48 #define E_10 0x49 #define E_11 0x4A #define E_12 0x4B @@ -219,15 +219,15 @@ void CKLED2001_shutdown(uint8_t addr); #define E_15 0x4E #define E_16 0x4F -#define F_1 0x50 -#define F_2 0x51 -#define F_3 0x52 -#define F_4 0x53 -#define F_5 0x54 -#define F_6 0x55 -#define F_7 0x56 -#define F_8 0x57 -#define F_9 0x58 +#define F_1 0x50 +#define F_2 0x51 +#define F_3 0x52 +#define F_4 0x53 +#define F_5 0x54 +#define F_6 0x55 +#define F_7 0x56 +#define F_8 0x57 +#define F_9 0x58 #define F_10 0x59 #define F_11 0x5A #define F_12 0x5B @@ -236,15 +236,15 @@ void CKLED2001_shutdown(uint8_t addr); #define F_15 0x5E #define F_16 0x5F -#define G_1 0x60 -#define G_2 0x61 -#define G_3 0x62 -#define G_4 0x63 -#define G_5 0x64 -#define G_6 0x65 -#define G_7 0x66 -#define G_8 0x67 -#define G_9 0x68 +#define G_1 0x60 +#define G_2 0x61 +#define G_3 0x62 +#define G_4 0x63 +#define G_5 0x64 +#define G_6 0x65 +#define G_7 0x66 +#define G_8 0x67 +#define G_9 0x68 #define G_10 0x69 #define G_11 0x6A #define G_12 0x6B @@ -253,15 +253,15 @@ void CKLED2001_shutdown(uint8_t addr); #define G_15 0x6E #define G_16 0x6F -#define H_1 0x70 -#define H_2 0x71 -#define H_3 0x72 -#define H_4 0x73 -#define H_5 0x74 -#define H_6 0x75 -#define H_7 0x76 -#define H_8 0x77 -#define H_9 0x78 +#define H_1 0x70 +#define H_2 0x71 +#define H_3 0x72 +#define H_4 0x73 +#define H_5 0x74 +#define H_6 0x75 +#define H_7 0x76 +#define H_8 0x77 +#define H_9 0x78 #define H_10 0x79 #define H_11 0x7A #define H_12 0x7B @@ -270,15 +270,15 @@ void CKLED2001_shutdown(uint8_t addr); #define H_15 0x7E #define H_16 0x7F -#define I_1 0x80 -#define I_2 0x81 -#define I_3 0x82 -#define I_4 0x83 -#define I_5 0x84 -#define I_6 0x85 -#define I_7 0x86 -#define I_8 0x87 -#define I_9 0x88 +#define I_1 0x80 +#define I_2 0x81 +#define I_3 0x82 +#define I_4 0x83 +#define I_5 0x84 +#define I_6 0x85 +#define I_7 0x86 +#define I_8 0x87 +#define I_9 0x88 #define I_10 0x89 #define I_11 0x8A #define I_12 0x8B @@ -287,15 +287,15 @@ void CKLED2001_shutdown(uint8_t addr); #define I_15 0x8E #define I_16 0x8F -#define J_1 0x90 -#define J_2 0x91 -#define J_3 0x92 -#define J_4 0x93 -#define J_5 0x94 -#define J_6 0x95 -#define J_7 0x96 -#define J_8 0x97 -#define J_9 0x98 +#define J_1 0x90 +#define J_2 0x91 +#define J_3 0x92 +#define J_4 0x93 +#define J_5 0x94 +#define J_6 0x95 +#define J_7 0x96 +#define J_8 0x97 +#define J_9 0x98 #define J_10 0x99 #define J_11 0x9A #define J_12 0x9B @@ -304,15 +304,15 @@ void CKLED2001_shutdown(uint8_t addr); #define J_15 0x9E #define J_16 0x9F -#define K_1 0xA0 -#define K_2 0xA1 -#define K_3 0xA2 -#define K_4 0xA3 -#define K_5 0xA4 -#define K_6 0xA5 -#define K_7 0xA6 -#define K_8 0xA7 -#define K_9 0xA8 +#define K_1 0xA0 +#define K_2 0xA1 +#define K_3 0xA2 +#define K_4 0xA3 +#define K_5 0xA4 +#define K_6 0xA5 +#define K_7 0xA6 +#define K_8 0xA7 +#define K_9 0xA8 #define K_10 0xA9 #define K_11 0xAA #define K_12 0xAB @@ -321,15 +321,15 @@ void CKLED2001_shutdown(uint8_t addr); #define K_15 0xAE #define K_16 0xAF -#define L_1 0xB0 -#define L_2 0xB1 -#define L_3 0xB2 -#define L_4 0xB3 -#define L_5 0xB4 -#define L_6 0xB5 -#define L_7 0xB6 -#define L_8 0xB7 -#define L_9 0xB8 +#define L_1 0xB0 +#define L_2 0xB1 +#define L_3 0xB2 +#define L_4 0xB3 +#define L_5 0xB4 +#define L_6 0xB5 +#define L_7 0xB6 +#define L_8 0xB7 +#define L_9 0xB8 #define L_10 0xB9 #define L_11 0xBA #define L_12 0xBB diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index e4345866acb7..64c302a405be 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c @@ -107,7 +107,7 @@ static void init(void) { # elif defined(IS31FL3741) IS31FL3741_set_led_control_register(index, enabled, enabled, enabled); # elif defined(CKLED2001) - CKLED2001_set_led_control_register(index, enabled, enabled, enabled); + CKLED2001_set_led_control_register(index, enabled, enabled, enabled); # endif } @@ -144,7 +144,7 @@ static void init(void) { # elif defined(IS31FL3741) IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); - + # elif defined(CKLED2001) CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0); # if defined(DRIVER_ADDR_2) From 8c68c25cffd58561b06c3d4a9a771b85032f35fb Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 15:27:15 +0800 Subject: [PATCH 03/32] Update ckled2001.c/ckled2001.h. --- drivers/led/ckled2001.c | 14 ++++++-------- drivers/led/ckled2001.h | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 1003608e106e..8d19b3dc70b6 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -18,7 +18,6 @@ #include "i2c_master.h" #include "wait.h" - #ifndef CKLED2001_TIMEOUT # define CKLED2001_TIMEOUT 100 #endif @@ -114,25 +113,25 @@ void CKLED2001_init(uint8_t addr) { // Set LED CONTROL PAGE (Page 0) CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH ; i++) { + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { CKLED2001_write_register(addr, i, 0x00); } // Set PWM PAGE (Page 1) CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); - for (int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { CKLED2001_write_register(addr, i, 0x00); } // Set CURRENT PAGE (Page 4) CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE); - for (int i = 0; i < LED_CURRENT_TUNE_LENGTH ; i++) { + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { CKLED2001_write_register(addr, i, 0xFF); } // Enable LEDs ON/OFF CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for (int i = 0; i< LED_CONTROL_ON_OFF_LENGTH ; i++) { + for (int i = 0; i< LED_CONTROL_ON_OFF_LENGTH; i++) { CKLED2001_write_register(addr, i, 0xFF); } @@ -190,9 +189,8 @@ void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, boo void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) { if (g_pwm_buffer_update_required[index]) { - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); - + // If any of the transactions fail we risk writing dirty PG0, // refresh page 0 just in case. if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) { @@ -215,7 +213,7 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { void CKLED2001_return_normal(uint8_t addr) { // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to normal mode + // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h index 0135726a6d08..26cf988b81a8 100644 --- a/drivers/led/ckled2001.h +++ b/drivers/led/ckled2001.h @@ -57,8 +57,8 @@ void CKLED2001_shutdown(uint8_t addr); // Function Register: address 0x00 #define CONFIGURATION_REG 0x00 -#define MSKSW_SHUT_DOWN_MODE (0x0<<0) -#define MSKSW_NORMAL_MODE (0x1<<0) +#define MSKSW_SHUT_DOWN_MODE (0x0 << 0) +#define MSKSW_NORMAL_MODE (0x1 << 0) #define DRIVER_ID_REG 0x11 #define CKLED2001_ID 0x8A @@ -90,39 +90,39 @@ void CKLED2001_shutdown(uint8_t addr); #define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00 #define OPEN_SHORT_ENABLE_REG 0x17 -#define MSKOPEN_DETECTION_ENABLE (0x01<<7) +#define MSKOPEN_DETECTION_ENABLE (0x01 << 7) #define MSKOPEN_DETECTION_DISABLE (0x00) -#define MSKSHORT_DETECTION_ENABLE (0x01<<6) +#define MSKSHORT_DETECTION_ENABLE (0x01 << 6) #define MSKSHORT_DETECTION_DISABLE (0x00) #define OPEN_SHORT_DUTY_REG 0x18 #define OPEN_SHORT_FLAG_REG 0x19 -#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01<<7) +#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01 << 7) #define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00) -#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01<<6) +#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01 << 6) #define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00) #define SOFTWARE_SLEEP_REG 0x1A #define MSKSLEEP_ENABLE 0x02 #define MSKSLEEP_DISABLE 0x00 -// LED Control Registers +// LED Control Registers #define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0 #define LED_CONTROL_ON_OFF_LAST_ADDR 0x17 -#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR-LED_CONTROL_ON_OFF_FIRST_ADDR)+1) +#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR-LED_CONTROL_ON_OFF_FIRST_ADDR) + 1) #define LED_CONTROL_OPEN_FIRST_ADDR 0x18 #define LED_CONTROL_OPEN_LAST_ADDR 0x2F -#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR-LED_CONTROL_OPEN_FIRST_ADDR)+1) +#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR-LED_CONTROL_OPEN_FIRST_ADDR) + 1) #define LED_CONTROL_SHORT_FIRST_ADDR 0x30 #define LED_CONTROL_SHORT_LAST_ADDR 0x47 -#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR-LED_CONTROL_SHORT_FIRST_ADDR)+1) +#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR-LED_CONTROL_SHORT_FIRST_ADDR) + 1) -#define LED_CONTROL_PAGE_LENGTH 0x48 +#define LED_CONTROL_PAGE_LENGTH 0x48 // LED Control Registers #define LED_PWM_FIRST_ADDR 0x00 From e5ff8ad0cc4b4b2c3a686d362f2ba9b6f3bf8124 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 15:40:09 +0800 Subject: [PATCH 04/32] Update ckled2001.c/ckled2001.h. --- drivers/led/ckled2001.c | 4 ++-- drivers/led/ckled2001.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 8d19b3dc70b6..c59c7248124f 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -131,10 +131,10 @@ void CKLED2001_init(uint8_t addr) { // Enable LEDs ON/OFF CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for (int i = 0; i< LED_CONTROL_ON_OFF_LENGTH; i++) { + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { CKLED2001_write_register(addr, i, 0xFF); } - + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); // Setting LED driver to normal mode diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h index 26cf988b81a8..efe399690a84 100644 --- a/drivers/led/ckled2001.h +++ b/drivers/led/ckled2001.h @@ -112,15 +112,15 @@ void CKLED2001_shutdown(uint8_t addr); // LED Control Registers #define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0 #define LED_CONTROL_ON_OFF_LAST_ADDR 0x17 -#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR-LED_CONTROL_ON_OFF_FIRST_ADDR) + 1) +#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR - LED_CONTROL_ON_OFF_FIRST_ADDR) + 1) #define LED_CONTROL_OPEN_FIRST_ADDR 0x18 #define LED_CONTROL_OPEN_LAST_ADDR 0x2F -#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR-LED_CONTROL_OPEN_FIRST_ADDR) + 1) +#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR - LED_CONTROL_OPEN_FIRST_ADDR) + 1) #define LED_CONTROL_SHORT_FIRST_ADDR 0x30 #define LED_CONTROL_SHORT_LAST_ADDR 0x47 -#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR-LED_CONTROL_SHORT_FIRST_ADDR) + 1) +#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR - LED_CONTROL_SHORT_FIRST_ADDR) + 1) #define LED_CONTROL_PAGE_LENGTH 0x48 From 1e7f20d747945fc5e8821eaded255cf5dbd7d812 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 16:03:14 +0800 Subject: [PATCH 05/32] Update ckled2001.c --- drivers/led/ckled2001.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index c59c7248124f..b0d3db2fabde 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -211,9 +211,8 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { } void CKLED2001_return_normal(uint8_t addr) { - // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } From 1aabe7b8c74af07227e1df8cc3b2f4bfb0f0bc0e Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 17:41:17 +0800 Subject: [PATCH 06/32] Add a new led driver --- common_features.mk | 9 +- drivers/led/ckled2001.c | 227 ++++++++++++++++ drivers/led/ckled2001.h | 339 ++++++++++++++++++++++++ lib/chibios-contrib | 2 +- quantum/rgb_matrix/rgb_matrix.h | 2 + quantum/rgb_matrix/rgb_matrix_drivers.c | 49 +++- 6 files changed, 625 insertions(+), 3 deletions(-) create mode 100644 drivers/led/ckled2001.c create mode 100644 drivers/led/ckled2001.h diff --git a/common_features.mk b/common_features.mk index 7dd63be5be2e..59d9a5fbd9d5 100644 --- a/common_features.mk +++ b/common_features.mk @@ -232,7 +232,7 @@ endif endif RGB_MATRIX_ENABLE ?= no -VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 WS2812 custom +VALID_RGB_MATRIX_TYPES := AW20216 IS31FL3731 IS31FL3733 IS31FL3737 IS31FL3741 CKLED2001 WS2812 custom ifeq ($(strip $(RGB_MATRIX_ENABLE)), yes) ifeq ($(filter $(RGB_MATRIX_DRIVER),$(VALID_RGB_MATRIX_TYPES)),) @@ -288,6 +288,13 @@ endif QUANTUM_LIB_SRC += i2c_master.c endif + ifeq ($(strip $(RGB_MATRIX_DRIVER)), CKLED2001) + OPT_DEFS += -DCKLED2001 -DSTM32_I2C -DHAL_USE_I2C=TRUE + COMMON_VPATH += $(DRIVER_PATH)/led + SRC += ckled2001.c + QUANTUM_LIB_SRC += i2c_master.c + endif + ifeq ($(strip $(RGB_MATRIX_DRIVER)), WS2812) OPT_DEFS += -DWS2812 WS2812_DRIVER_REQUIRED := yes diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c new file mode 100644 index 000000000000..adefc8dc10c7 --- /dev/null +++ b/drivers/led/ckled2001.c @@ -0,0 +1,227 @@ +/* Copyright 2021 @ Keychron (https://www.keychron.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ckled2001.h" +#include "i2c_master.h" +#include "wait.h" + +#ifndef CKLED2001_TIMEOUT +# define CKLED2001_TIMEOUT 100 +#endif + +#ifndef CKLED2001_PERSISTENCE +# define CKLED2001_PERSISTENCE 0 +#endif + +#ifndef PHASE_CHANNEL +# define PHASE_CHANNEL MSKPHASE_12CHANNEL +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the CKLED2001 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in CKLED2001_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[DRIVER_COUNT][192]; +bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; + +uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0}; +bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; + +bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + // If the transaction fails function returns false. + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if CKLED2001_PERSISTENCE > 0 + for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { + return false; + } +#endif + return true; +} + +bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // Assumes PG1 is already selected. + // If any of the transactions fails function returns false. + // Transmit PWM registers in 12 transfers of 16 bytes. + // g_twi_transfer_buffer[] is 20 bytes + + // Iterate over the pwm_buffer contents at 16 byte intervals. + for (int i = 0; i < 192; i += 16) { + g_twi_transfer_buffer[0] = i; + // Copy the data from i to i+15. + // Device will auto-increment register for data after the first byte + // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#if CKLED2001_PERSISTENCE > 0 + for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { + return false; + } +#endif + } + return true; +} + +void CKLED2001_init(uint8_t addr) { + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to shutdown mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); + //** Setting internal channel pulldown/pullup + CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL); + //** Select number of scan phase + CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL); + //** Setting PWM Delay Phase + CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE); + //** Setting Driving/Sinking Channel Slew Rate + CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE); + //** Setting Iref + CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE); + + /*--------Set LED CONTROL PAGE (Page 0)------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0x00); + } + + /*--------Set PWM PAGE (Page 1)------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0x00); + } + + /*--------Set CURRENT PAGE (Page 4)------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE); + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0xFF); + } + + /*--------Enable LEDs ON/OFF------------*/ + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0xFF); + } + + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); +} + +void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + ckled2001_led led = g_ckled2001_leds[index]; + + g_pwm_buffer[led.driver][led.r] = red; + g_pwm_buffer[led.driver][led.g] = green; + g_pwm_buffer[led.driver][led.b] = blue; + g_pwm_buffer_update_required[led.driver] = true; + } +} + +void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + CKLED2001_set_color(i, red, green, blue); + } +} + +void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + ckled2001_led led = g_ckled2001_leds[index]; + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); + + // If any of the transactions fail we risk writing dirty PG0, + // refresh page 0 just in case. + if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) { + g_led_control_registers_update_required[index] = true; + } + } + g_pwm_buffer_update_required[index] = false; +} + +void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < 24; i++) { + CKLED2001_write_register(addr, i, g_led_control_registers[index][i]); + } + } + g_led_control_registers_update_required[index] = false; +} + +void CKLED2001_return_normal(uint8_t addr) { + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); +} + +void CKLED2001_shutdown(uint8_t addr) { + //** Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + //** Setting LED driver to shutdown mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); + //** Write SW Sleep Register + CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE); +} \ No newline at end of file diff --git a/drivers/led/ckled2001.h b/drivers/led/ckled2001.h new file mode 100644 index 000000000000..444836f82838 --- /dev/null +++ b/drivers/led/ckled2001.h @@ -0,0 +1,339 @@ +/* Copyright 2021 @ Keychron (https://www.keychron.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include "progmem.h" + +typedef struct ckled2001_led { + uint8_t driver : 2; + uint8_t r; + uint8_t g; + uint8_t b; +} __attribute__((packed)) ckled2001_led; + +extern const ckled2001_led __flash g_ckled2001_leds[DRIVER_LED_TOTAL]; + +void CKLED2001_init(uint8_t addr); +bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data); +bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer); + +void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); +void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue); + +void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue); + +// This should not be called from an interrupt +// (eg. from a timer interrupt). +// Call this while idle (in between matrix scans). +// If the buffer is dirty, it will update the driver with the buffer. +void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index); +void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index); + +void CKLED2001_return_normal(uint8_t addr); +void CKLED2001_shutdown(uint8_t addr); + +/*--------Registers Page Define------------*/ +#define CONFIGURE_CMD_PAGE 0xFD +#define LED_CONTROL_PAGE 0x00 +#define LED_PWM_PAGE 0x01 +#define FUNCTION_PAGE 0x03 +#define CURRENT_TUNE_PAGE 0x04 + +/*--------Function Register: address 0x00------------*/ +#define CONFIGURATION_REG 0x00 +#define MSKSW_SHUT_DOWN_MODE (0x0 << 0) +#define MSKSW_NORMAL_MODE (0x1 << 0) + +#define DRIVER_ID_REG 0x11 +#define CKLED2001_ID 0x8A + +#define PDU_REG 0x13 +#define MSKSET_CA_CB_CHANNEL 0xAA +#define MSKCLR_CA_CB_CHANNEL 0x00 + +#define SCAN_PHASE_REG 0x14 +#define MSKPHASE_12CHANNEL 0x00 +#define MSKPHASE_11CHANNEL 0x01 +#define MSKPHASE_10CHANNEL 0x02 +#define MSKPHASE_9CHANNEL 0x03 +#define MSKPHASE_8CHANNEL 0x04 +#define MSKPHASE_7CHANNEL 0x05 +#define MSKPHASE_6CHANNEL 0x06 +#define MSKPHASE_5CHANNEL 0x07 +#define MSKPHASE_4CHANNEL 0x08 +#define MSKPHASE_3CHANNEL 0x09 +#define MSKPHASE_2CHANNEL 0x0A +#define MSKPHASE_1CHANNEL 0x0B + +#define SLEW_RATE_CONTROL_MODE1_REG 0x15 +#define MSKPWM_DELAY_PHASE_ENABLE 0x04 +#define MSKPWM_DELAY_PHASE_DISABLE 0x00 + +#define SLEW_RATE_CONTROL_MODE2_REG 0x16 +#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE 0xC0 +#define MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_DISABLE 0x00 + +#define OPEN_SHORT_ENABLE_REG 0x17 +#define MSKOPEN_DETECTION_ENABLE (0x01 << 7) +#define MSKOPEN_DETECTION_DISABLE (0x00) + +#define MSKSHORT_DETECTION_ENABLE (0x01 << 6) +#define MSKSHORT_DETECTION_DISABLE (0x00) + +#define OPEN_SHORT_DUTY_REG 0x18 +#define OPEN_SHORT_FLAG_REG 0x19 + +#define MSKOPEN_DETECTION_INTERRUPT_ENABLE (0x01 << 7) +#define MSKOPEN_DETECTION_INTERRUPT_DISABLE (0x00) + +#define MSKSHORT_DETECTION_INTERRUPT_ENABLE (0x01 << 6) +#define MSKSHORT_DETECTION_INTERRUPT_DISABLE (0x00) + +#define SOFTWARE_SLEEP_REG 0x1A +#define MSKSLEEP_ENABLE 0x02 +#define MSKSLEEP_DISABLE 0x00 + +/*--------LED Control Registers------------*/ +#define LED_CONTROL_ON_OFF_FIRST_ADDR 0x0 +#define LED_CONTROL_ON_OFF_LAST_ADDR 0x17 +#define LED_CONTROL_ON_OFF_LENGTH ((LED_CONTROL_ON_OFF_LAST_ADDR - LED_CONTROL_ON_OFF_FIRST_ADDR) + 1) + +#define LED_CONTROL_OPEN_FIRST_ADDR 0x18 +#define LED_CONTROL_OPEN_LAST_ADDR 0x2F +#define LED_CONTROL_OPEN_LENGTH ((LED_CONTROL_OPEN_LAST_ADDR - LED_CONTROL_OPEN_FIRST_ADDR) + 1) + +#define LED_CONTROL_SHORT_FIRST_ADDR 0x30 +#define LED_CONTROL_SHORT_LAST_ADDR 0x47 +#define LED_CONTROL_SHORT_LENGTH ((LED_CONTROL_SHORT_LAST_ADDR - LED_CONTROL_SHORT_FIRST_ADDR) + 1) + +#define LED_CONTROL_PAGE_LENGTH 0x48 + +/*--------LED Control Registers------------*/ +#define LED_PWM_FIRST_ADDR 0x00 +#define LED_PWM_LAST_ADDR 0xBF +#define LED_PWM_LENGTH 0xC0 + +/*--------Current Tune Registers------------*/ +#define LED_CURRENT_TUNE_FIRST_ADDR 0x00 +#define LED_CURRENT_TUNE_LAST_ADDR 0x0B +#define LED_CURRENT_TUNE_LENGTH 0x0C + +#define A_1 0x00 +#define A_2 0x01 +#define A_3 0x02 +#define A_4 0x03 +#define A_5 0x04 +#define A_6 0x05 +#define A_7 0x06 +#define A_8 0x07 +#define A_9 0x08 +#define A_10 0x09 +#define A_11 0x0A +#define A_12 0x0B +#define A_13 0x0C +#define A_14 0x0D +#define A_15 0x0E +#define A_16 0x0F + +#define B_1 0x10 +#define B_2 0x11 +#define B_3 0x12 +#define B_4 0x13 +#define B_5 0x14 +#define B_6 0x15 +#define B_7 0x16 +#define B_8 0x17 +#define B_9 0x18 +#define B_10 0x19 +#define B_11 0x1A +#define B_12 0x1B +#define B_13 0x1C +#define B_14 0x1D +#define B_15 0x1E +#define B_16 0x1F + +#define C_1 0x20 +#define C_2 0x21 +#define C_3 0x22 +#define C_4 0x23 +#define C_5 0x24 +#define C_6 0x25 +#define C_7 0x26 +#define C_8 0x27 +#define C_9 0x28 +#define C_10 0x29 +#define C_11 0x2A +#define C_12 0x2B +#define C_13 0x2C +#define C_14 0x2D +#define C_15 0x2E +#define C_16 0x2F + +#define D_1 0x30 +#define D_2 0x31 +#define D_3 0x32 +#define D_4 0x33 +#define D_5 0x34 +#define D_6 0x35 +#define D_7 0x36 +#define D_8 0x37 +#define D_9 0x38 +#define D_10 0x39 +#define D_11 0x3A +#define D_12 0x3B +#define D_13 0x3C +#define D_14 0x3D +#define D_15 0x3E +#define D_16 0x3F + +#define E_1 0x40 +#define E_2 0x41 +#define E_3 0x42 +#define E_4 0x43 +#define E_5 0x44 +#define E_6 0x45 +#define E_7 0x46 +#define E_8 0x47 +#define E_9 0x48 +#define E_10 0x49 +#define E_11 0x4A +#define E_12 0x4B +#define E_13 0x4C +#define E_14 0x4D +#define E_15 0x4E +#define E_16 0x4F + +#define F_1 0x50 +#define F_2 0x51 +#define F_3 0x52 +#define F_4 0x53 +#define F_5 0x54 +#define F_6 0x55 +#define F_7 0x56 +#define F_8 0x57 +#define F_9 0x58 +#define F_10 0x59 +#define F_11 0x5A +#define F_12 0x5B +#define F_13 0x5C +#define F_14 0x5D +#define F_15 0x5E +#define F_16 0x5F + +#define G_1 0x60 +#define G_2 0x61 +#define G_3 0x62 +#define G_4 0x63 +#define G_5 0x64 +#define G_6 0x65 +#define G_7 0x66 +#define G_8 0x67 +#define G_9 0x68 +#define G_10 0x69 +#define G_11 0x6A +#define G_12 0x6B +#define G_13 0x6C +#define G_14 0x6D +#define G_15 0x6E +#define G_16 0x6F + +#define H_1 0x70 +#define H_2 0x71 +#define H_3 0x72 +#define H_4 0x73 +#define H_5 0x74 +#define H_6 0x75 +#define H_7 0x76 +#define H_8 0x77 +#define H_9 0x78 +#define H_10 0x79 +#define H_11 0x7A +#define H_12 0x7B +#define H_13 0x7C +#define H_14 0x7D +#define H_15 0x7E +#define H_16 0x7F + +#define I_1 0x80 +#define I_2 0x81 +#define I_3 0x82 +#define I_4 0x83 +#define I_5 0x84 +#define I_6 0x85 +#define I_7 0x86 +#define I_8 0x87 +#define I_9 0x88 +#define I_10 0x89 +#define I_11 0x8A +#define I_12 0x8B +#define I_13 0x8C +#define I_14 0x8D +#define I_15 0x8E +#define I_16 0x8F + +#define J_1 0x90 +#define J_2 0x91 +#define J_3 0x92 +#define J_4 0x93 +#define J_5 0x94 +#define J_6 0x95 +#define J_7 0x96 +#define J_8 0x97 +#define J_9 0x98 +#define J_10 0x99 +#define J_11 0x9A +#define J_12 0x9B +#define J_13 0x9C +#define J_14 0x9D +#define J_15 0x9E +#define J_16 0x9F + +#define K_1 0xA0 +#define K_2 0xA1 +#define K_3 0xA2 +#define K_4 0xA3 +#define K_5 0xA4 +#define K_6 0xA5 +#define K_7 0xA6 +#define K_8 0xA7 +#define K_9 0xA8 +#define K_10 0xA9 +#define K_11 0xAA +#define K_12 0xAB +#define K_13 0xAC +#define K_14 0xAD +#define K_15 0xAE +#define K_16 0xAF + +#define L_1 0xB0 +#define L_2 0xB1 +#define L_3 0xB2 +#define L_4 0xB3 +#define L_5 0xB4 +#define L_6 0xB5 +#define L_7 0xB6 +#define L_8 0xB7 +#define L_9 0xB8 +#define L_10 0xB9 +#define L_11 0xBA +#define L_12 0xBB +#define L_13 0xBC +#define L_14 0xBD +#define L_15 0xBE +#define L_16 0xBF \ No newline at end of file diff --git a/lib/chibios-contrib b/lib/chibios-contrib index d1c2126d1cd8..4568901a91e9 160000 --- a/lib/chibios-contrib +++ b/lib/chibios-contrib @@ -1 +1 @@ -Subproject commit d1c2126d1cd867c50127da84425805e225df8555 +Subproject commit 4568901a91e9bef78ea96a7a83e8150fe1f7353a diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index f53e011c1bd9..1b4389c5b8e2 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -33,6 +33,8 @@ # include "is31fl3737.h" #elif defined(IS31FL3741) # include "is31fl3741.h" +#elif defined(CKLED2001) +# include "ckled2001.h" #elif defined(AW20216) # include "aw20216.h" #elif defined(WS2812) diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c index 4335088eb89d..64c302a405be 100644 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ b/quantum/rgb_matrix/rgb_matrix_drivers.c @@ -23,7 +23,7 @@ * be here if shared between boards. */ -#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) +#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3737) || defined(IS31FL3741) || defined(CKLED2001) # include "i2c_master.h" // TODO: Remove this at some later date @@ -80,6 +80,18 @@ static void init(void) { # elif defined(IS31FL3741) IS31FL3741_init(DRIVER_ADDR_1); + +# elif defined(CKLED2001) + CKLED2001_init(DRIVER_ADDR_1); +# if defined(DRIVER_ADDR_2) + CKLED2001_init(DRIVER_ADDR_2); +# if defined(DRIVER_ADDR_3) + CKLED2001_init(DRIVER_ADDR_3); +# if defined(DRIVER_ADDR_4) + CKLED2001_init(DRIVER_ADDR_4); +# endif +# endif +# endif # endif for (int index = 0; index < DRIVER_LED_TOTAL; index++) { @@ -94,6 +106,8 @@ static void init(void) { IS31FL3737_set_led_control_register(index, enabled, enabled, enabled); # elif defined(IS31FL3741) IS31FL3741_set_led_control_register(index, enabled, enabled, enabled); +# elif defined(CKLED2001) + CKLED2001_set_led_control_register(index, enabled, enabled, enabled); # endif } @@ -130,6 +144,18 @@ static void init(void) { # elif defined(IS31FL3741) IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); + +# elif defined(CKLED2001) + CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0); +# if defined(DRIVER_ADDR_2) + CKLED2001_update_led_control_registers(DRIVER_ADDR_2, 1); +# if defined(DRIVER_ADDR_3) + CKLED2001_update_led_control_registers(DRIVER_ADDR_3, 2); +# if defined(DRIVER_ADDR_4) + CKLED2001_update_led_control_registers(DRIVER_ADDR_4, 3); +# endif +# endif +# endif # endif } @@ -204,6 +230,27 @@ const rgb_matrix_driver_t rgb_matrix_driver = { .set_color = IS31FL3741_set_color, .set_color_all = IS31FL3741_set_color_all, }; + +# elif defined(CKLED2001) +static void flush(void) { + CKLED2001_update_pwm_buffers(DRIVER_ADDR_1, 0); +# if defined(DRIVER_ADDR_2) + CKLED2001_update_pwm_buffers(DRIVER_ADDR_2, 1); +# if defined(DRIVER_ADDR_3) + CKLED2001_update_pwm_buffers(DRIVER_ADDR_3, 2); +# if defined(DRIVER_ADDR_4) + CKLED2001_update_pwm_buffers(DRIVER_ADDR_4, 3); +# endif +# endif +# endif +} + +const rgb_matrix_driver_t rgb_matrix_driver = { + .init = init, + .flush = flush, + .set_color = CKLED2001_set_color, + .set_color_all = CKLED2001_set_color_all, +}; # endif #elif defined(AW20216) From 93371893ce476b76d8aab6c0daa1fe22759bfef7 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Mon, 18 Oct 2021 18:15:54 +0800 Subject: [PATCH 07/32] Update ckled2001.c --- drivers/led/ckled2001.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index fdb9e34e2fb9..3a778d91e33b 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -210,9 +210,7 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { } void CKLED2001_return_normal(uint8_t addr) { - // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } @@ -223,4 +221,4 @@ void CKLED2001_shutdown(uint8_t addr) { CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); // Write SW Sleep Register CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE); -} \ No newline at end of file +} From bdafa945e774135183077c4fbe72e7630562b31f Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Wed, 20 Oct 2021 11:49:11 +0800 Subject: [PATCH 08/32] Update ckled2001.c --- drivers/led/ckled2001.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 3a778d91e33b..1d5fe86ef426 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -210,7 +210,9 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { } void CKLED2001_return_normal(uint8_t addr) { + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } From 4459ddfc27344b46e428157672f8cf0ddb660bf6 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Wed, 20 Oct 2021 11:53:33 +0800 Subject: [PATCH 09/32] Update ckled2001.c --- drivers/led/ckled2001.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 1d5fe86ef426..3a778d91e33b 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -210,9 +210,7 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { } void CKLED2001_return_normal(uint8_t addr) { - // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } From 9a94daf05ad3bf266e27ae93c647e2159db94024 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Wed, 20 Oct 2021 12:02:31 +0800 Subject: [PATCH 10/32] Update ckled2001.c --- drivers/led/ckled2001.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 3a778d91e33b..09c3ced679e9 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -210,7 +210,9 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { } void CKLED2001_return_normal(uint8_t addr) { + // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + // Setting IC to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } From 68f7cd5c6eaf3198f5a6d3d72c4a28c7b9863d21 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Wed, 20 Oct 2021 12:04:57 +0800 Subject: [PATCH 11/32] Delete ckled2001.c --- drivers/led/ckled2001.c | 226 ---------------------------------------- 1 file changed, 226 deletions(-) delete mode 100644 drivers/led/ckled2001.c diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c deleted file mode 100644 index 09c3ced679e9..000000000000 --- a/drivers/led/ckled2001.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Copyright 2021 @ Keychron (https://www.keychron.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "ckled2001.h" -#include "i2c_master.h" -#include "wait.h" - -#ifndef CKLED2001_TIMEOUT -# define CKLED2001_TIMEOUT 100 -#endif - -#ifndef CKLED2001_PERSISTENCE -# define CKLED2001_PERSISTENCE 0 -#endif - -#ifndef PHASE_CHANNEL -# define PHASE_CHANNEL MSKPHASE_12CHANNEL -#endif - -// Transfer buffer for TWITransmitData() -uint8_t g_twi_transfer_buffer[20]; - -// These buffers match the CKLED2001 PWM registers. -// The control buffers match the PG0 LED On/Off registers. -// Storing them like this is optimal for I2C transfers to the registers. -// We could optimize this and take out the unused registers from these -// buffers and the transfers in CKLED2001_write_pwm_buffer() but it's -// probably not worth the extra complexity. -uint8_t g_pwm_buffer[DRIVER_COUNT][192]; -bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; - -uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0}; -bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; - -bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data) { - // If the transaction fails function returns false. - g_twi_transfer_buffer[0] = reg; - g_twi_transfer_buffer[1] = data; - -#if CKLED2001_PERSISTENCE > 0 - for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { - return false; - } - } -#else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { - return false; - } -#endif - return true; -} - -bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { - // Assumes PG1 is already selected. - // If any of the transactions fails function returns false. - // Transmit PWM registers in 12 transfers of 16 bytes. - // g_twi_transfer_buffer[] is 20 bytes - - // Iterate over the pwm_buffer contents at 16 byte intervals. - for (int i = 0; i < 192; i += 16) { - g_twi_transfer_buffer[0] = i; - // Copy the data from i to i+15. - // Device will auto-increment register for data after the first byte - // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. - for (int j = 0; j < 16; j++) { - g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; - } - -#if CKLED2001_PERSISTENCE > 0 - for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { - return false; - } - } -#else - if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { - return false; - } -#endif - } - return true; -} - -void CKLED2001_init(uint8_t addr) { - // Select to function page - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to shutdown mode - CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); - // Setting internal channel pulldown/pullup - CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL); - // Select number of scan phase - CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL); - // Setting PWM Delay Phase - CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE); - // Setting Driving/Sinking Channel Slew Rate - CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE); - // Setting Iref - CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE); - // Set LED CONTROL PAGE (Page 0) - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { - CKLED2001_write_register(addr, i, 0x00); - } - - // Set PWM PAGE (Page 1) - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); - for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { - CKLED2001_write_register(addr, i, 0x00); - } - - // Set CURRENT PAGE (Page 4) - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE); - for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { - CKLED2001_write_register(addr, i, 0xFF); - } - - // Enable LEDs ON/OFF - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { - CKLED2001_write_register(addr, i, 0xFF); - } - - // Select to function page - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to normal mode - CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); -} - -void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - if (index >= 0 && index < DRIVER_LED_TOTAL) { - ckled2001_led led = g_ckled2001_leds[index]; - - g_pwm_buffer[led.driver][led.r] = red; - g_pwm_buffer[led.driver][led.g] = green; - g_pwm_buffer[led.driver][led.b] = blue; - g_pwm_buffer_update_required[led.driver] = true; - } -} - -void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { - for (int i = 0; i < DRIVER_LED_TOTAL; i++) { - CKLED2001_set_color(i, red, green, blue); - } -} - -void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { - ckled2001_led led = g_ckled2001_leds[index]; - - uint8_t control_register_r = led.r / 8; - uint8_t control_register_g = led.g / 8; - uint8_t control_register_b = led.b / 8; - uint8_t bit_r = led.r % 8; - uint8_t bit_g = led.g % 8; - uint8_t bit_b = led.b % 8; - - if (red) { - g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); - } else { - g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); - } - if (green) { - g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); - } else { - g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); - } - if (blue) { - g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); - } else { - g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); - } - - g_led_control_registers_update_required[led.driver] = true; -} - -void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) { - if (g_pwm_buffer_update_required[index]) { - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); - - // If any of the transactions fail we risk writing dirty PG0, - // refresh page 0 just in case. - if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) { - g_led_control_registers_update_required[index] = true; - } - } - g_pwm_buffer_update_required[index] = false; -} - -void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { - if (g_led_control_registers_update_required[index]) { - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); - for (int i = 0; i < 24; i++) { - CKLED2001_write_register(addr, i, g_led_control_registers[index][i]); - } - } - g_led_control_registers_update_required[index] = false; -} - -void CKLED2001_return_normal(uint8_t addr) { - // Select to function page - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting IC to normal mode - CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); -} - -void CKLED2001_shutdown(uint8_t addr) { - // Select to function page - CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to shutdown mode - CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); - // Write SW Sleep Register - CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE); -} From 15c4cc0ed06ba39e42d10cf36d47ba68141c6fea Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Wed, 20 Oct 2021 12:06:39 +0800 Subject: [PATCH 12/32] Create ckled2001.c --- drivers/led/ckled2001.c | 226 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 drivers/led/ckled2001.c diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c new file mode 100644 index 000000000000..09c3ced679e9 --- /dev/null +++ b/drivers/led/ckled2001.c @@ -0,0 +1,226 @@ +/* Copyright 2021 @ Keychron (https://www.keychron.com) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "ckled2001.h" +#include "i2c_master.h" +#include "wait.h" + +#ifndef CKLED2001_TIMEOUT +# define CKLED2001_TIMEOUT 100 +#endif + +#ifndef CKLED2001_PERSISTENCE +# define CKLED2001_PERSISTENCE 0 +#endif + +#ifndef PHASE_CHANNEL +# define PHASE_CHANNEL MSKPHASE_12CHANNEL +#endif + +// Transfer buffer for TWITransmitData() +uint8_t g_twi_transfer_buffer[20]; + +// These buffers match the CKLED2001 PWM registers. +// The control buffers match the PG0 LED On/Off registers. +// Storing them like this is optimal for I2C transfers to the registers. +// We could optimize this and take out the unused registers from these +// buffers and the transfers in CKLED2001_write_pwm_buffer() but it's +// probably not worth the extra complexity. +uint8_t g_pwm_buffer[DRIVER_COUNT][192]; +bool g_pwm_buffer_update_required[DRIVER_COUNT] = {false}; + +uint8_t g_led_control_registers[DRIVER_COUNT][24] = {0}; +bool g_led_control_registers_update_required[DRIVER_COUNT] = {false}; + +bool CKLED2001_write_register(uint8_t addr, uint8_t reg, uint8_t data) { + // If the transaction fails function returns false. + g_twi_transfer_buffer[0] = reg; + g_twi_transfer_buffer[1] = data; + +#if CKLED2001_PERSISTENCE > 0 + for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 2, CKLED2001_TIMEOUT) != 0) { + return false; + } +#endif + return true; +} + +bool CKLED2001_write_pwm_buffer(uint8_t addr, uint8_t *pwm_buffer) { + // Assumes PG1 is already selected. + // If any of the transactions fails function returns false. + // Transmit PWM registers in 12 transfers of 16 bytes. + // g_twi_transfer_buffer[] is 20 bytes + + // Iterate over the pwm_buffer contents at 16 byte intervals. + for (int i = 0; i < 192; i += 16) { + g_twi_transfer_buffer[0] = i; + // Copy the data from i to i+15. + // Device will auto-increment register for data after the first byte + // Thus this sets registers 0x00-0x0F, 0x10-0x1F, etc. in one transfer. + for (int j = 0; j < 16; j++) { + g_twi_transfer_buffer[1 + j] = pwm_buffer[i + j]; + } + +#if CKLED2001_PERSISTENCE > 0 + for (uint8_t i = 0; i < CKLED2001_PERSISTENCE; i++) { + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { + return false; + } + } +#else + if (i2c_transmit(addr << 1, g_twi_transfer_buffer, 17, CKLED2001_TIMEOUT) != 0) { + return false; + } +#endif + } + return true; +} + +void CKLED2001_init(uint8_t addr) { + // Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + // Setting LED driver to shutdown mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); + // Setting internal channel pulldown/pullup + CKLED2001_write_register(addr, PDU_REG, MSKSET_CA_CB_CHANNEL); + // Select number of scan phase + CKLED2001_write_register(addr, SCAN_PHASE_REG, PHASE_CHANNEL); + // Setting PWM Delay Phase + CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE1_REG, MSKPWM_DELAY_PHASE_ENABLE); + // Setting Driving/Sinking Channel Slew Rate + CKLED2001_write_register(addr, SLEW_RATE_CONTROL_MODE2_REG, MSKDRIVING_SINKING_CHHANNEL_SLEWRATE_ENABLE); + // Setting Iref + CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_DISABLE); + // Set LED CONTROL PAGE (Page 0) + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0x00); + } + + // Set PWM PAGE (Page 1) + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0x00); + } + + // Set CURRENT PAGE (Page 4) + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, CURRENT_TUNE_PAGE); + for (int i = 0; i < LED_CURRENT_TUNE_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0xFF); + } + + // Enable LEDs ON/OFF + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < LED_CONTROL_ON_OFF_LENGTH; i++) { + CKLED2001_write_register(addr, i, 0xFF); + } + + // Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + // Setting LED driver to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); +} + +void CKLED2001_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { + if (index >= 0 && index < DRIVER_LED_TOTAL) { + ckled2001_led led = g_ckled2001_leds[index]; + + g_pwm_buffer[led.driver][led.r] = red; + g_pwm_buffer[led.driver][led.g] = green; + g_pwm_buffer[led.driver][led.b] = blue; + g_pwm_buffer_update_required[led.driver] = true; + } +} + +void CKLED2001_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { + for (int i = 0; i < DRIVER_LED_TOTAL; i++) { + CKLED2001_set_color(i, red, green, blue); + } +} + +void CKLED2001_set_led_control_register(uint8_t index, bool red, bool green, bool blue) { + ckled2001_led led = g_ckled2001_leds[index]; + + uint8_t control_register_r = led.r / 8; + uint8_t control_register_g = led.g / 8; + uint8_t control_register_b = led.b / 8; + uint8_t bit_r = led.r % 8; + uint8_t bit_g = led.g % 8; + uint8_t bit_b = led.b % 8; + + if (red) { + g_led_control_registers[led.driver][control_register_r] |= (1 << bit_r); + } else { + g_led_control_registers[led.driver][control_register_r] &= ~(1 << bit_r); + } + if (green) { + g_led_control_registers[led.driver][control_register_g] |= (1 << bit_g); + } else { + g_led_control_registers[led.driver][control_register_g] &= ~(1 << bit_g); + } + if (blue) { + g_led_control_registers[led.driver][control_register_b] |= (1 << bit_b); + } else { + g_led_control_registers[led.driver][control_register_b] &= ~(1 << bit_b); + } + + g_led_control_registers_update_required[led.driver] = true; +} + +void CKLED2001_update_pwm_buffers(uint8_t addr, uint8_t index) { + if (g_pwm_buffer_update_required[index]) { + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_PWM_PAGE); + + // If any of the transactions fail we risk writing dirty PG0, + // refresh page 0 just in case. + if (!CKLED2001_write_pwm_buffer(addr, g_pwm_buffer[index])) { + g_led_control_registers_update_required[index] = true; + } + } + g_pwm_buffer_update_required[index] = false; +} + +void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { + if (g_led_control_registers_update_required[index]) { + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, LED_CONTROL_PAGE); + for (int i = 0; i < 24; i++) { + CKLED2001_write_register(addr, i, g_led_control_registers[index][i]); + } + } + g_led_control_registers_update_required[index] = false; +} + +void CKLED2001_return_normal(uint8_t addr) { + // Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + // Setting IC to normal mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); +} + +void CKLED2001_shutdown(uint8_t addr) { + // Select to function page + CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); + // Setting LED driver to shutdown mode + CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_SHUT_DOWN_MODE); + // Write SW Sleep Register + CKLED2001_write_register(addr, SOFTWARE_SLEEP_REG, MSKSLEEP_ENABLE); +} From 067e0d51dc51b1d5bca420d5d014f12ae64f13e7 Mon Sep 17 00:00:00 2001 From: lalalademaxiya1 <66767061+lalalademaxiya1@users.noreply.github.com> Date: Wed, 20 Oct 2021 12:30:59 +0800 Subject: [PATCH 13/32] Update ckled2001.c --- drivers/led/ckled2001.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/led/ckled2001.c b/drivers/led/ckled2001.c index 09c3ced679e9..6307303437d5 100644 --- a/drivers/led/ckled2001.c +++ b/drivers/led/ckled2001.c @@ -136,7 +136,7 @@ void CKLED2001_init(uint8_t addr) { // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting LED driver to normal mode + // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } @@ -212,7 +212,7 @@ void CKLED2001_update_led_control_registers(uint8_t addr, uint8_t index) { void CKLED2001_return_normal(uint8_t addr) { // Select to function page CKLED2001_write_register(addr, CONFIGURE_CMD_PAGE, FUNCTION_PAGE); - // Setting IC to normal mode + // Setting LED driver to normal mode CKLED2001_write_register(addr, CONFIGURATION_REG, MSKSW_NORMAL_MODE); } From acfd125d1495a0161a754d9c957083ca8a9f5d1f Mon Sep 17 00:00:00 2001 From: lokher Date: Thu, 4 Nov 2021 16:37:39 +0800 Subject: [PATCH 14/32] Update chibios-contrib --- lib/chibios-contrib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/chibios-contrib b/lib/chibios-contrib index 4568901a91e9..d1c2126d1cd8 160000 --- a/lib/chibios-contrib +++ b/lib/chibios-contrib @@ -1 +1 @@ -Subproject commit 4568901a91e9bef78ea96a7a83e8150fe1f7353a +Subproject commit d1c2126d1cd867c50127da84425805e225df8555 From 1070360624c2160c5cd272f668192a3ba4111ad4 Mon Sep 17 00:00:00 2001 From: lokher Date: Thu, 4 Nov 2021 17:09:03 +0800 Subject: [PATCH 15/32] Add STM32L432 support and STM32L4 series EEPROM emulation --- builddefs/mcu_selection.mk | 34 ++ common_features.mk | 6 + data/schemas/keyboard.jsonschema | 2 +- docs/compatible_microcontrollers.md | 3 +- lib/python/qmk/constants.py | 2 +- .../GENERIC_STM32_L432KC/board/board.mk | 9 + .../GENERIC_STM32_L432KC/configs/board.h | 18 + .../GENERIC_STM32_L432KC/configs/config.h | 26 + .../GENERIC_STM32_L432KC/configs/mcuconf.h | 262 +++++++++ tmk_core/common/chibios/eeprom_stm32_defs.h | 4 +- tmk_core/common/chibios/eeprom_stm32_l4.c | 553 ++++++++++++++++++ tmk_core/common/chibios/eeprom_stm32_l4.h | 34 ++ tmk_core/common/chibios/flash_stm32.c | 47 ++ tmk_core/common/chibios/flash_stm32.h | 1 + 14 files changed, 996 insertions(+), 5 deletions(-) create mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk create mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h create mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h create mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h create mode 100644 tmk_core/common/chibios/eeprom_stm32_l4.c create mode 100644 tmk_core/common/chibios/eeprom_stm32_l4.h diff --git a/builddefs/mcu_selection.mk b/builddefs/mcu_selection.mk index 1251b7a2b7c2..76de85c2308f 100644 --- a/builddefs/mcu_selection.mk +++ b/builddefs/mcu_selection.mk @@ -472,6 +472,40 @@ ifneq ($(findstring STM32G474, $(MCU)),) UF2_FAMILY ?= STM32G4 endif +ifneq (,$(filter $(MCU),STM32L432)) + # Cortex version + MCU = cortex-m4 + + # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 + ARMV = 7 + + ## chip/board settings + # - the next two should match the directories in + # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) + MCU_FAMILY = STM32 + MCU_SERIES = STM32L4xx + + # Linker script to use + # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ + # or /ld/ + MCU_LDSCRIPT ?= STM32L432xC + + # Startup code to use + # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ + MCU_STARTUP ?= stm32l4xx + + # Board: it should exist either in /os/hal/boards/, + # /boards/, or drivers/boards/ + BOARD ?= GENERIC_STM32_L432KC + + PLATFORM_NAME ?= platform_l432 + + USE_FPU ?= yes + + # UF2 settings + UF2_FAMILY ?= STM32L4 +endif + ifneq (,$(filter $(MCU),STM32L433 STM32L443)) # Cortex version MCU = cortex-m4 diff --git a/common_features.mk b/common_features.mk index b605dfbe5e5b..ed60eecbcc8c 100644 --- a/common_features.mk +++ b/common_features.mk @@ -154,6 +154,12 @@ else COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom SRC += eeprom_driver.c SRC += eeprom_stm32_L0_L1.c + else ifneq ($(filter $(MCU_SERIES),STM32L4xx),) + OPT_DEFS += -DEEPROM_DRIVER + COMMON_VPATH += $(DRIVER_PATH)/eeprom + SRC += eeprom_driver.c + SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32_l4.c + SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c else # This will effectively work the same as "transient" if not supported by the chip SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index 65d44c94d2ce..e4916c2ab3ad 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -13,7 +13,7 @@ }, "processor": { "type": "string", - "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK66FX1M0", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L433", "STM32L443", "GD32VF103", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"] + "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK66FX1M0", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L443", "GD32VF103", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"] }, "audio": { "type": "object", diff --git a/docs/compatible_microcontrollers.md b/docs/compatible_microcontrollers.md index 39e9061c2026..44f1b662e522 100644 --- a/docs/compatible_microcontrollers.md +++ b/docs/compatible_microcontrollers.md @@ -35,6 +35,7 @@ You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) s * [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html) * [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) * [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) + * [STM32L432](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) * [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) * [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) @@ -53,4 +54,4 @@ There is limited support for one of Atmel's ATSAM microcontrollers, that being t ### GigaDevice -[ChibiOS-Contrib](https://github.com/ChibiOS/ChibiOS-Contrib) has support for the GigaDevice [GD32VF103 series](https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/mainstream-line/gd32vf103-series/) microcontrollers and provides configurations for the [SiPeed Longan Nano](https://longan.sipeed.com/en/) development board that uses this microcontroller. It is largely pin and feature compatible with STM32F103 and STM32F303 microcontrollers. \ No newline at end of file +[ChibiOS-Contrib](https://github.com/ChibiOS/ChibiOS-Contrib) has support for the GigaDevice [GD32VF103 series](https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/mainstream-line/gd32vf103-series/) microcontrollers and provides configurations for the [SiPeed Longan Nano](https://longan.sipeed.com/en/) development board that uses this microcontroller. It is largely pin and feature compatible with STM32F103 and STM32F303 microcontrollers. diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index 73f596ba2c91..5c3900155f0d 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -13,7 +13,7 @@ MAX_KEYBOARD_SUBFOLDERS = 5 # Supported processor types -CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L433', 'STM32L443', 'GD32VF103' +CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L443', 'GD32VF103' LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk new file mode 100644 index 000000000000..1250385eb8e2 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.c + +# Required include directories +BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h new file mode 100644 index 000000000000..75abe5147019 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h @@ -0,0 +1,18 @@ +/* Copyright 2018-2021 Harrison Chan (@Xelus) + * + * 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 3 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 + +#include_next "board.h" diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h new file mode 100644 index 000000000000..c27c61b19aa4 --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h @@ -0,0 +1,26 @@ +/* Copyright 2018-2021 Harrison Chan (@Xelus) + * + * 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 . + */ + +/* Address for jumping to bootloader on STM32 chips. */ +/* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. + */ +#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 + +#define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH + +#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP +# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE +#endif diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h new file mode 100644 index 000000000000..1157888d732e --- /dev/null +++ b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h @@ -0,0 +1,262 @@ +/* + ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * STM32L4xx drivers configuration. + * The following settings override the default settings present in + * the various device driver implementation headers. + * Note that the settings for each driver only have effect if the whole + * driver is enabled in halconf.h. + * + * IRQ priorities: + * 15...0 Lowest...Highest. + * + * DMA priorities: + * 0...3 Lowest...Highest. + */ + +#ifndef MCUCONF_H +#define MCUCONF_H + +#define STM32L4xx_MCUCONF +#define STM32L432_MCUCONF + +/* + * HAL driver system settings. + */ +#define STM32_NO_INIT FALSE +#define STM32_VOS STM32_VOS_RANGE1 +#define STM32_PVD_ENABLE FALSE +#define STM32_PLS STM32_PLS_LEV0 +#define STM32_HSI16_ENABLED TRUE +#define STM32_HSI48_ENABLED TRUE +#define STM32_LSI_ENABLED TRUE +#define STM32_HSE_ENABLED FALSE +#define STM32_LSE_ENABLED FALSE +#define STM32_MSIPLL_ENABLED FALSE +#define STM32_MSIRANGE STM32_MSIRANGE_4M +#define STM32_MSISRANGE STM32_MSISRANGE_4M +#define STM32_SW STM32_SW_PLL +#define STM32_PLLSRC STM32_PLLSRC_HSI16 +#define STM32_PLLM_VALUE 1 +#define STM32_PLLN_VALUE 10 +#define STM32_PLLPDIV_VALUE 0 +#define STM32_PLLP_VALUE 7 +#define STM32_PLLQ_VALUE 2 +#define STM32_PLLR_VALUE 2 +#define STM32_HPRE STM32_HPRE_DIV1 +#define STM32_PPRE1 STM32_PPRE1_DIV1 +#define STM32_PPRE2 STM32_PPRE2_DIV1 +#define STM32_STOPWUCK STM32_STOPWUCK_MSI +#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK +#define STM32_MCOPRE STM32_MCOPRE_DIV1 +#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK +#define STM32_PLLSAI1N_VALUE 24 +#define STM32_PLLSAI1PDIV_VALUE 0 +#define STM32_PLLSAI1P_VALUE 7 +#define STM32_PLLSAI1Q_VALUE 2 +#define STM32_PLLSAI1R_VALUE 2 + +/* + * Peripherals clock sources. + */ +#define STM32_USART1SEL STM32_USART1SEL_SYSCLK +#define STM32_USART2SEL STM32_USART2SEL_SYSCLK +#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK +#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK +#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK +#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 +#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 +#define STM32_SAI1SEL STM32_SAI1SEL_OFF +#define STM32_CLK48SEL STM32_CLK48SEL_HSI48 +#define STM32_ADCSEL STM32_ADCSEL_SYSCLK +#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 +#define STM32_RTCSEL STM32_RTCSEL_LSI + +/* + * IRQ system settings. + */ +#define STM32_IRQ_EXTI0_PRIORITY 6 +#define STM32_IRQ_EXTI1_PRIORITY 6 +#define STM32_IRQ_EXTI2_PRIORITY 6 +#define STM32_IRQ_EXTI3_PRIORITY 6 +#define STM32_IRQ_EXTI4_PRIORITY 6 +#define STM32_IRQ_EXTI5_9_PRIORITY 6 +#define STM32_IRQ_EXTI10_15_PRIORITY 6 +#define STM32_IRQ_EXTI1635_38_PRIORITY 6 +#define STM32_IRQ_EXTI18_PRIORITY 6 +#define STM32_IRQ_EXTI19_PRIORITY 6 +#define STM32_IRQ_EXTI20_PRIORITY 6 +#define STM32_IRQ_EXTI21_22_PRIORITY 15 + +#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7 +#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7 +#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7 +#define STM32_IRQ_TIM1_CC_PRIORITY 7 +#define STM32_IRQ_TIM2_PRIORITY 7 +#define STM32_IRQ_TIM6_PRIORITY 7 +#define STM32_IRQ_TIM7_PRIORITY 7 + +#define STM32_IRQ_USART1_PRIORITY 12 +#define STM32_IRQ_USART2_PRIORITY 12 +#define STM32_IRQ_LPUART1_PRIORITY 12 + +/* + * ADC driver system settings. + */ +#define STM32_ADC_COMPACT_SAMPLES FALSE +#define STM32_ADC_USE_ADC1 FALSE +#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) +#define STM32_ADC_ADC1_DMA_PRIORITY 2 +#define STM32_ADC_ADC12_IRQ_PRIORITY 5 +#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 +#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 +#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2 + +/* + * CAN driver system settings. + */ +#define STM32_CAN_USE_CAN1 FALSE +#define STM32_CAN_CAN1_IRQ_PRIORITY 11 + +/* + * DAC driver system settings. + */ +#define STM32_DAC_DUAL_MODE FALSE +#define STM32_DAC_USE_DAC1_CH1 FALSE +#define STM32_DAC_USE_DAC1_CH2 FALSE +#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 +#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 +#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) + +/* + * GPT driver system settings. + */ +#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM2 FALSE +#define STM32_GPT_USE_TIM6 FALSE +#define STM32_GPT_USE_TIM7 FALSE +#define STM32_GPT_USE_TIM15 FALSE +#define STM32_GPT_USE_TIM16 FALSE + +/* + * I2C driver system settings. + */ +#define STM32_I2C_USE_I2C1 FALSE +#define STM32_I2C_USE_I2C3 FALSE +#define STM32_I2C_BUSY_TIMEOUT 50 +#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) +#define STM32_I2C_I2C1_IRQ_PRIORITY 5 +#define STM32_I2C_I2C3_IRQ_PRIORITY 5 +#define STM32_I2C_I2C1_DMA_PRIORITY 3 +#define STM32_I2C_I2C3_DMA_PRIORITY 3 +#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") + +/* + * ICU driver system settings. + */ +#define STM32_ICU_USE_TIM1 FALSE +#define STM32_ICU_USE_TIM2 FALSE +#define STM32_ICU_USE_TIM15 FALSE +#define STM32_ICU_USE_TIM16 FALSE + +/* + * PWM driver system settings. + */ +#define STM32_PWM_USE_ADVANCED FALSE +#define STM32_PWM_USE_TIM1 FALSE +#define STM32_PWM_USE_TIM2 FALSE +#define STM32_PWM_USE_TIM15 FALSE +#define STM32_PWM_USE_TIM16 FALSE + +/* + * RTC driver system settings. + */ +#define STM32_RTC_PRESA_VALUE 32 +#define STM32_RTC_PRESS_VALUE 1024 +#define STM32_RTC_CR_INIT 0 +#define STM32_RTC_TAMPCR_INIT 0 + +/* + * SERIAL driver system settings. + */ +#define STM32_SERIAL_USE_USART1 FALSE +#define STM32_SERIAL_USE_USART2 FALSE +#define STM32_SERIAL_USE_LPUART1 FALSE +#define STM32_SERIAL_USART1_PRIORITY 12 +#define STM32_SERIAL_USART2_PRIORITY 12 +#define STM32_SERIAL_LPUART1_PRIORITY 12 + +/* + * SPI driver system settings. + */ +#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI3 FALSE +#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) +#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) +#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) +#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) +#define STM32_SPI_SPI1_DMA_PRIORITY 1 +#define STM32_SPI_SPI3_DMA_PRIORITY 1 +#define STM32_SPI_SPI1_IRQ_PRIORITY 10 +#define STM32_SPI_SPI3_IRQ_PRIORITY 10 +#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") + +/* + * ST driver system settings. + */ +#define STM32_ST_IRQ_PRIORITY 8 +#define STM32_ST_USE_TIMER 2 + +/* + * TRNG driver system settings. + */ +#define STM32_TRNG_USE_RNG1 FALSE + +/* + * UART driver system settings. + */ +#define STM32_UART_USE_USART1 FALSE +#define STM32_UART_USE_USART2 FALSE +#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) +#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) +#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) +#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) +#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") + +/* + * USB driver system settings. + */ +#define STM32_USB_USE_USB1 TRUE +#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE +#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 +#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 + +/* + * WDG driver system settings. + */ +#define STM32_WDG_USE_IWDG FALSE + +/* + * WSPI driver system settings. + */ +#define STM32_WSPI_USE_QUADSPI1 FALSE +#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) + +#endif /* MCUCONF_H */ diff --git a/tmk_core/common/chibios/eeprom_stm32_defs.h b/tmk_core/common/chibios/eeprom_stm32_defs.h index 66904f247f58..99059b236260 100644 --- a/tmk_core/common/chibios/eeprom_stm32_defs.h +++ b/tmk_core/common/chibios/eeprom_stm32_defs.h @@ -25,7 +25,7 @@ # ifndef FEE_PAGE_COUNT # define FEE_PAGE_COUNT 2 // How many pages are used # endif -# elif defined(STM32F103xE) || defined(STM32F303xC) || defined(STM32F072xB) || defined(STM32F070xB) +# elif defined(STM32F103xE) || defined(STM32F303xC) || defined(STM32F072xB) || defined(STM32F070xB) || defined(STM32L432xx) # ifndef FEE_PAGE_SIZE # define FEE_PAGE_SIZE 0x800 // Page size = 2KByte # endif @@ -47,7 +47,7 @@ # define FEE_MCU_FLASH_SIZE 32 // Size in Kb # elif defined(GD32VF103C8) # define FEE_MCU_FLASH_SIZE 64 // Size in Kb -# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) || defined(GD32VF103CB) +# elif defined(STM32F103xB) || defined(STM32F072xB) || defined(STM32F070xB) || defined(GD32VF103CB) || defined(STM32L432xx) # define FEE_MCU_FLASH_SIZE 128 // Size in Kb # elif defined(STM32F303xC) || defined(STM32F401xC) # define FEE_MCU_FLASH_SIZE 256 // Size in Kb diff --git a/tmk_core/common/chibios/eeprom_stm32_l4.c b/tmk_core/common/chibios/eeprom_stm32_l4.c new file mode 100644 index 000000000000..e934ad436426 --- /dev/null +++ b/tmk_core/common/chibios/eeprom_stm32_l4.c @@ -0,0 +1,553 @@ +/* + * This software is experimental and a work in progress. + * Under no circumstances should these files be used in relation to any critical system(s). + * Use of these files is at your own risk. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by + * Artur F. + * + * Modifications for QMK and STM32L432 by lalalademaxiya1 & lokher + * + * TODO: Add ECC correction interrupt handler. + */ + +#include +#include +#include +#include "flash_stm32.h" +#include "eeprom_stm32_l4.h" +#include "print.h" +/* + * We emulate eeprom by writing a snapshot compacted view of eeprom contents, + * followed by a write log of any change since that snapshot: + * + * === SIMULATED EEPROM CONTENTS === + * + * ┌─ Compacted─┬─ Write Log ──┐ + * │............│[DWord][DWord]│ + * │FFFF....FFFF│[DWord][DWord]│ + * │FFFFFFFFFFFF│[DWord][DWord]│ + * │....FFFFFFFF│[DWord][DWord]│ + * ├────────────┼──────────────┤ + * └──PAGE_BASE │ │ + * PAGE_LAST─┴─WRITE_BASE │ + * WRITE_LAST ──┘ + * + * Compacted contents are the 1's complement of the actual EEPROM contents. + * e.g. An 'FFFF' represents a '0000' value. + * + * The size of the 'compacted' area is equal to the size of the 'emulated' eeprom. + * The size of the compacted-area and write log are configurable, and the combined + * size of Compacted + WriteLog is a multiple FEE_PAGE_SIZE, which is MCU dependent. + * Simulated Eeprom contents are located at the end of available flash space. + * + * The following configuration defines can be set: + * + * FEE_PAGE_COUNT # Total number of pages to use for eeprom simulation (Compact + Write log) + * FEE_DENSITY_BYTES # Size of simulated eeprom. (Defaults to one pages of FEE_PAGE_COUNT) + * NOTE: The current implementation does not include page swapping, + * and FEE_DENSITY_BYTES will consume that amount of RAM as a cached view of actual EEPROM contents. + * + * The maximum size of FEE_DENSITY_BYTES is currently 8192. The write log size equals + * FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES. + * The larger the write log, the less frequently the compacted area needs to be rewritten. + * + * + * *** General Algorithm *** + * + * During initialization: + * The contents of the Compacted-flash area are loaded and the 1's complement value + * is cached into memory (e.g. 0xFFFF in Flash represents 0x0000 in cache). + * Write log entries are processed until a 0xFFFF is reached. + * Each log entry updates 1/2/4 byte(s) in the cache. + * + * During reads: + * EEPROM contents are given back directly from the cache in memory. + * + * During writes: + * The contents of the cache is updated first. + * If the Compacted-flash area corresponding to the write address is unprogrammed, the 1's complement of the value is written directly into Compacted-flash + * Otherwise: + * If the write log is full, erase both the Compacted-flash area and the Write log, then write cached contents to the Compacted-flash area. + * Otherwise a Write log entry is constructed and appended to the next free position in the Write log. + * + * + * *** Write Log Structure *** + * + * Each log entry compose of double word (2 x 32-bit) due to the minimum program size of STM32L432 flash. + * + * === WRITE LOG ENTRY FORMATS === + * + * ╔══════════ Byte-Entry ═════════╗ + * ║ 00 01 XX XX ║ FF FF FF YY ║ + * ║ └─┬─┘ └─┬─┘ ║ └┘ ║ + * ║ Len Address ║ ~Value ║ + * ╚═══════════════╩═══════════════╝ + * + * ╔══════════ Word-Entry ═════════╗ + * ║ 00 02 XX XX ║ FF FF YY YY ║ + * ║ └─┬─┘ └─┬─┘ ║ └─┬─┘ ║ + * ║ Len Address ║ ~Value ║ + * ╚═══════════════╩═══════════════╝ + * + * ╔══════════ DWord-Entry ═══════╗ + * ║ 00 04 XX XX ║ FF FF FF FF ║ + * ║ └─┬─┘ └─┬─┘ ║ └───┬────┘ ║ + * ║ Len Address ║ ~Value ║ + * ╚═══════════════╩═══════════════╝ + * + */ + +#include "eeprom_stm32_defs.h" +#if !defined(FEE_PAGE_SIZE) || !defined(FEE_PAGE_COUNT) || !defined(FEE_MCU_FLASH_SIZE) || !defined(FEE_PAGE_BASE_ADDRESS) +# error "not implemented." +#endif + +/* These bits indicate that the length of data which was wrote to log space */ +#define FEE_BYTE_FLAG 0x00010000 +#define FEE_WORD_FLAG 0x00020000 +#define FEE_DWORD_FLAG 0x00040000 + +/* Flash byte value after erase */ +#define FEE_EMPTY_BYTE ((uint8_t)0xFF) +/* Flash double byte value after erase */ +#define FEE_EMPTY_DBYTE ((uint16_t)0xFFFF) +/* Flash word value after erase */ +#define FEE_EMPTY_WORD ((uint32_t)0xFFFFFFFF) +/* Flash double word value after erase */ +#define FEE_EMPTY_DWORD ((uint64_t)0xFFFFFFFFFFFFFFFF) + +/* Size of combined compacted eeprom and write log pages */ +#define FEE_DENSITY_MAX_SIZE (FEE_PAGE_COUNT * FEE_PAGE_SIZE) + +#ifndef FEE_MCU_FLASH_SIZE_IGNORE_CHECK /* *TODO: Get rid of this check */ +# if FEE_DENSITY_MAX_SIZE > (FEE_MCU_FLASH_SIZE * 1024) +# pragma message STR(FEE_DENSITY_MAX_SIZE) " > " STR(FEE_MCU_FLASH_SIZE * 1024) +# error emulated eeprom: FEE_DENSITY_MAX_SIZE is greater than available flash size +# endif +#endif + +/* Size of emulated eeprom */ +#ifdef FEE_DENSITY_BYTES +# if (FEE_DENSITY_BYTES > FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) +# error emulated eeprom: FEE_DENSITY_BYTES exceeds FEE_DENSITY_MAX_SIZE +# endif +# if (FEE_DENSITY_BYTES == FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " == " STR(FEE_DENSITY_MAX_SIZE) +# warning emulated eeprom: FEE_DENSITY_BYTES leaves no room for a write log. This will greatly increase the flash wear rate! +# endif +# if FEE_DENSITY_BYTES > FEE_ADDRESS_MAX_SIZE +# pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE) +# error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows +# endif +# if ((FEE_DENSITY_BYTES) % 2) == 1 +# error emulated eeprom: FEE_DENSITY_BYTES must be even +# endif +#else +/* Default to one page of allocated space used for emulated eeprom, 3 pages for write log */ +# define FEE_DENSITY_BYTES FEE_PAGE_SIZE +#endif + +/* Size of write log */ +#ifdef FEE_WRITE_LOG_BYTES +# if ((FEE_DENSITY_BYTES + FEE_WRITE_LOG_BYTES) > FEE_DENSITY_MAX_SIZE) +# pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) +# error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE +# endif +# if ((FEE_WRITE_LOG_BYTES) % 2) == 1 +# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even +# endif +#else +/* Default to use all remaining space */ +# define FEE_WRITE_LOG_BYTES (FEE_PAGE_COUNT * FEE_PAGE_SIZE - FEE_DENSITY_BYTES) +#endif + +/* In-memory contents of emulated eeprom for faster access */ +/* *TODO: Implement page swapping */ +static uint64_t DWordBuf[FEE_DENSITY_BYTES / 8]; +static uint8_t *DataBuf = (uint8_t *)DWordBuf; + +/* Pointer to the first available slot within the write log */ +static uint32_t *empty_slot; + +/* Start of the emulated eeprom compacted flash area */ +#define FEE_COMPACTED_BASE_ADDRESS FEE_PAGE_BASE_ADDRESS +/* End of the emulated eeprom compacted flash area */ +#define FEE_COMPACTED_LAST_ADDRESS (FEE_COMPACTED_BASE_ADDRESS + FEE_DENSITY_BYTES) +/* Start of the emulated eeprom write log */ +#define FEE_WRITE_LOG_BASE_ADDRESS FEE_COMPACTED_LAST_ADDRESS +/* End of the emulated eeprom write log */ +#define FEE_WRITE_LOG_LAST_ADDRESS (FEE_WRITE_LOG_BASE_ADDRESS + FEE_WRITE_LOG_BYTES) + +uint16_t EEPROM_Init(void) { + /* Load emulated eeprom contents from compacted flash into memory */ + uint32_t *src = (uint32_t *)FEE_COMPACTED_BASE_ADDRESS; + uint32_t *dest = (uint32_t *)DataBuf; + for (; src < (uint32_t *)FEE_COMPACTED_LAST_ADDRESS; ++src, ++dest) { + *dest = ~*src; + } + + /* Replay write log */ + uint32_t *log_addr; + for (log_addr = (uint32_t *)FEE_WRITE_LOG_BASE_ADDRESS; log_addr < (uint32_t *)FEE_WRITE_LOG_LAST_ADDRESS; log_addr += 2) { + uint32_t address = *log_addr; + uint32_t data = ~*(log_addr + 1); + if (address == FEE_EMPTY_WORD) { + break; + } + /* Check if value is in bytes */ + else if ((address & FEE_BYTE_FLAG) == FEE_BYTE_FLAG) { + uint8_t value = (uint8_t)(data & 0xFF); + uint16_t addr = (uint16_t)address; + DataBuf[addr] = value; + } + /* Check if value is in words */ + else if ((address & FEE_WORD_FLAG) == FEE_WORD_FLAG) { + uint16_t value = (uint16_t)(data & 0xFFFF); + uint16_t addr = (uint16_t)address; + *(uint16_t *)(&DataBuf[addr]) = value; + } + /* Check if value is in double words */ + else if ((address & FEE_DWORD_FLAG) == FEE_DWORD_FLAG) { + uint32_t value = data; + uint16_t addr = (uint16_t)address; + *(uint32_t *)(&DataBuf[addr]) = value; + } + } + + empty_slot = log_addr; + + return FEE_DENSITY_BYTES; +} + +/* Clear flash contents (doesn't touch in-memory DataBuf) */ +static void eeprom_clear(void) { + FLASH_Unlock(); + + for (uint16_t page_num = 0; page_num < FEE_PAGE_COUNT; ++page_num) { + FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE)); + } + + FLASH_Lock(); + + empty_slot = (uint32_t *)FEE_WRITE_LOG_BASE_ADDRESS; +} + +/* Erase emulated eeprom */ +void EEPROM_Erase(void) { + /* Erase compacted pages and write log */ + eeprom_clear(); + /* re-initialize to reset DataBuf */ + EEPROM_Init(); +} + +/* Compact write log */ +static uint8_t eeprom_compact(void) { + /* Erase compacted pages and write log */ + eeprom_clear(); + + FLASH_Unlock(); + + FLASH_Status final_status = FLASH_COMPLETE; + + /* Write emulated eeprom contents from memory to compacted flash */ + uint64_t *src = (uint64_t *)DataBuf; + uint32_t dest = FEE_COMPACTED_BASE_ADDRESS; + uint64_t value; + for (; dest < FEE_COMPACTED_LAST_ADDRESS; ++src, dest += 8) { + value = *src; + if (value) { + FLASH_Status status = FLASH_ProgramDoubleWord(dest, ~value); + if (status != FLASH_COMPLETE) final_status = status; + } + } + + FLASH_Lock(); + + return final_status; +} + +static uint8_t eeprom_write_direct_entry(uint16_t Address) { + /* Check if we can just write this directly to the compacted flash area */ + uint32_t directAddress = FEE_COMPACTED_BASE_ADDRESS + (Address & 0xFFF8); + + /* Write the value directly to the compacted area without a log entry */ + if (*(uint64_t *)directAddress == FEE_EMPTY_DWORD) { + /* Write the value directly to the compacted area without a log entry */ + uint64_t value = ~*(uint64_t *)(&DataBuf[Address & 0xFFF8]); + + /* Early exit if a write isn't needed */ + if (value == FEE_EMPTY_DWORD) return FLASH_COMPLETE; + + FLASH_Unlock(); + + /* write to flash */ + FLASH_Status status = FLASH_ProgramDoubleWord(directAddress, value); + + FLASH_Lock(); + + return status; + } + return 0; +} + +static uint8_t eeprom_write_log_byte_entry(uint16_t Address) { + /* if we can't find an empty spot, we must compact emulated eeprom */ + if (empty_slot >= (uint32_t *)FEE_WRITE_LOG_LAST_ADDRESS) { + /* compact the write log into the compacted flash area */ + return eeprom_compact(); + } + + FLASH_Unlock(); + + /* Pack address and value into the same word */ + uint64_t value = (((uint64_t)(~DataBuf[Address])) << 32) | (FEE_BYTE_FLAG) | Address; + + /* write to flash */ + FLASH_Status status = FLASH_ProgramDoubleWord((uint32_t)empty_slot, value); + + empty_slot += 2; + + FLASH_Lock(); + + return status; +} + +static uint8_t eeprom_write_log_word_entry(uint16_t Address) { + /* if we can't find an empty spot, we must compact emulated eeprom */ + if (empty_slot >= (uint32_t *)FEE_WRITE_LOG_LAST_ADDRESS) { + /* compact the write log into the compacted flash area */ + return eeprom_compact(); + } + + FLASH_Unlock(); + + /* Pack address and value into the same word */ + uint64_t value = (((uint64_t)(~(*(uint16_t *)&DataBuf[Address]))) << 32) | (FEE_WORD_FLAG) | Address; + + /* write to flash */ + FLASH_Status status = FLASH_ProgramDoubleWord((uint32_t)empty_slot, value); + + empty_slot += 2; + + FLASH_Lock(); + + return status; +} + +static uint8_t eeprom_write_log_dword_entry(uint16_t Address) { + /* if we can't find an empty spot, we must compact emulated eeprom */ + if (empty_slot >= (uint32_t *)FEE_WRITE_LOG_LAST_ADDRESS) { + /* compact the write log into the compacted flash area */ + return eeprom_compact(); + } + + FLASH_Unlock(); + + /* Pack address and value into the same word */ + uint64_t value = (((uint64_t)(~(*(uint32_t *)&DataBuf[Address]))) << 32) | (FEE_DWORD_FLAG) | Address; + + /* write to flash */ + FLASH_Status status = FLASH_ProgramDoubleWord((uint32_t)empty_slot, value); + + empty_slot += 2; + + FLASH_Lock(); + + return status; +} + +uint8_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) { + /* if the address is out-of-bounds, do nothing */ + if (Address >= (FEE_DENSITY_BYTES)) { + return FLASH_BAD_ADDRESS; + } + + /* if the value is the same, don't bother writing it */ + if (DataBuf[Address] == DataByte) { + return 0; + } + + /* keep DataBuf cache in sync */ + DataBuf[Address] = DataByte; + + /* perform the write into flash memory */ + /* First, attempt to write directly into the compacted flash area */ + FLASH_Status status = eeprom_write_direct_entry(Address); + + if (!status) { + eeprom_write_log_byte_entry(Address); + } + + return status; +} + +uint8_t EEPROM_WriteDataWord(uint16_t Address, uint16_t DataWord) { + /* if the address is out-of-bounds, do nothing */ + if (Address >= (FEE_DENSITY_BYTES)) { + return FLASH_BAD_ADDRESS; + } + + /* if the value is the same, don't bother writing it */ + if (*(uint16_t *)&DataBuf[Address] == DataWord) { + return 0; + } + + /* keep DataBuf cache in sync */ + *(uint16_t *)(&DataBuf[Address]) = DataWord; + + /* perform the write into flash memory */ + /* First, attempt to write directly into the compacted flash area */ + FLASH_Status status = eeprom_write_direct_entry(Address); + + if (!status) { + eeprom_write_log_word_entry(Address); + } + + return status; +} + +uint8_t EEPROM_WriteDataDWord(uint16_t Address, uint32_t DataDWord) { + /* if the address is out-of-bounds, do nothing */ + if (Address >= (FEE_DENSITY_BYTES)) { + return FLASH_BAD_ADDRESS; + } + + /* if the value is the same, don't bother writing it */ + if (*(uint32_t *)&DataBuf[Address] == DataDWord) { + return 0; + } + + /* keep DataBuf cache in sync */ + *(uint32_t *)&DataBuf[Address] = DataDWord; + + /* perform the write into flash memory */ + /* First, attempt to write directly into the compacted flash area */ + FLASH_Status status = eeprom_write_direct_entry(Address); + + if (!status) { + eeprom_write_log_dword_entry(Address); + } + + return status; +} + +uint8_t EEPROM_ReadDataByte(uint16_t Address) { + uint8_t DataByte = 0xFF; + + if (Address < FEE_DENSITY_BYTES) { + DataByte = DataBuf[Address]; + } + + return DataByte; +} + +uint16_t EEPROM_ReadDataWord(uint16_t Address) { + uint16_t DataWord = 0xFFFF; + + if (Address < FEE_DENSITY_BYTES - 1) { + /* Check word alignment */ + if (Address % 2) { + DataWord = DataBuf[Address] | (DataBuf[Address + 1] << 8); + } else { + DataWord = *(uint16_t *)(&DataBuf[Address]); + } + } + + return DataWord; +} + +/***************************************************************************** + * Bind to eeprom_driver.c + *******************************************************************************/ +void eeprom_driver_init(void) { EEPROM_Init(); } + +void eeprom_driver_erase(void) { EEPROM_Erase(); } + +void eeprom_read_block(void *buf, const void *addr, size_t len) { + const uint8_t *src = (const uint8_t *)addr; + uint8_t * dest = (uint8_t *)buf; + + /* Check word alignment */ + if (len && (uint32_t)src % 2) { + /* Read the unaligned first byte */ + *dest++ = EEPROM_ReadDataByte((const uintptr_t)((uint16_t *)src)); + --len; + } + + uint16_t value; + bool aligned = ((uint32_t)dest % 2 == 0); + while (len > 1) { + value = EEPROM_ReadDataWord((const uintptr_t)((uint16_t *)src)); + if (aligned) { + *(uint16_t *)dest = value; + dest += 2; + } else { + *dest++ = value; + *dest++ = value >> 8; + } + src += 2; + len -= 2; + } + if (len) { + *dest = EEPROM_ReadDataByte((const uintptr_t)src); + } +} + +void eeprom_write_block(const void *buf, void *addr, size_t len) { + uint8_t * dest = (uint8_t *)addr; + const uint8_t *src = (const uint8_t *)buf; + + /* Check word alignment */ + if (len && (uintptr_t)dest % 2) { + /* Write the unaligned first byte */ + EEPROM_WriteDataByte((uintptr_t)dest++, *src++); + --len; + } + + if ((uintptr_t)dest % 4 == 0) { + uint32_t dwvalue; + bool dwaligned = ((uint32_t)src % 4 == 0); + + while (len > 1) { + if (dwaligned) { + dwvalue = *(uint32_t *)src; + } else { + dwvalue = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8) | (*(uint8_t *)(src + 2) << 16) | (*(uint8_t *)(src + 3) << 24); + } + EEPROM_WriteDataDWord((uintptr_t)((uint16_t *)dest), dwvalue); + dest += 4; + src += 4; + len -= 4; + } + } + + if ((uintptr_t)dest % 2 == 0) { + uint16_t wvalue; + bool waligned = ((uintptr_t)src % 2 == 0); + + while (len > 1) { + if (waligned) { + wvalue = *(uint16_t *)src; + } else { + wvalue = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8); + } + EEPROM_WriteDataWord((uintptr_t)((uint16_t *)dest), wvalue); + dest += 2; + src += 2; + len -= 2; + } + } + + if (len) { + EEPROM_WriteDataByte((uintptr_t)dest, *src); + } +} diff --git a/tmk_core/common/chibios/eeprom_stm32_l4.h b/tmk_core/common/chibios/eeprom_stm32_l4.h new file mode 100644 index 000000000000..cd6abec460b7 --- /dev/null +++ b/tmk_core/common/chibios/eeprom_stm32_l4.h @@ -0,0 +1,34 @@ +/* + * This software is experimental and a work in progress. + * Under no circumstances should these files be used in relation to any critical system(s). + * Use of these files is at your own risk. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by + * Artur F. + * + * Modifications for QMK and STM32L432 by lalalademaxiya1 + * + * This library assumes 8-bit data locations. To add a new MCU, please provide the flash + * page size and the total flash size in Kb. The number of available pages must be a multiple + * of 2. Only one page for the total EEPROM size. + * This library also assumes that the pages are not used by the firmware. + */ + +#pragma once + +typedef unsigned long long uint64_t; + +uint16_t EEPROM_Init(void); +void EEPROM_Erase(void); +uint8_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte); +uint8_t EEPROM_WriteDataWord(uint16_t Address, uint16_t DataWord); +uint8_t EEPROM_WriteDataDWord(uint16_t Address, uint32_t DataDWord); +uint8_t EEPROM_ReadDataByte(uint16_t Address); +uint16_t EEPROM_ReadDataWord(uint16_t Address); diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index 72c41b8b784d..b40f6eeab3c3 100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c @@ -51,6 +51,15 @@ static uint8_t ADDR2PAGE(uint32_t Page_Address) { } #endif +#if defined(STM32L4XX) +# define FLASH_SR_PGERR FLASH_SR_PROGERR +# define FLASH_OBR_OPTERR FLASH_SR_OPERR +# define FLASH_KEY1 0x45670123U +# define FLASH_KEY2 0xCDEF89ABU + +static uint32_t ADDR2PAGE(uint32_t Page_Address) { return (Page_Address - FLASH_BASE) / 0x800; } +#endif + /* Delay definition */ #define EraseTimeout ((uint32_t)0x00000FFF) #define ProgramTimeout ((uint32_t)0x0000001F) @@ -128,6 +137,9 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { #if defined(FLASH_CR_SNB) FLASH->CR &= ~FLASH_CR_SNB; FLASH->CR |= FLASH_CR_SER | (ADDR2PAGE(Page_Address) << FLASH_CR_SNB_Pos); +#elif defined(FLASH_CR_PNB) + FLASH->CR &= ~FLASH_CR_PNB; + FLASH->CR |= FLASH_CR_PER | (ADDR2PAGE(Page_Address) << FLASH_CR_PNB_Pos); #else FLASH->CR |= FLASH_CR_PER; FLASH->AR = Page_Address; @@ -140,6 +152,8 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { /* if the erase operation is completed, disable the configured Bits */ #if defined(FLASH_CR_SNB) FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB); +#elif defined(FLASH_CR_PNB) + FLASH->CR &= ~(FLASH_CR_PER | FLASH_CR_PNB); #else FLASH->CR &= ~FLASH_CR_PER; #endif @@ -184,6 +198,39 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { return status; } +#if defined(STM32L4XX) +/** + * @brief Programs double words at a specified address. + * @param Address: specifies the address to be programmed. + * @param Data: specifies the data to be programmed. + * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, + * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. + */ +FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) { + FLASH_Status status = FLASH_BAD_ADDRESS; + + if (IS_FLASH_ADDRESS(Address)) { + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if (status == FLASH_COMPLETE) { + /* if the previous operation is completed, proceed to program the new data */ + FLASH->CR |= FLASH_CR_PG; + *(__IO uint32_t*)Address = (uint32_t)Data; + __ISB(); + *(__IO uint32_t*)(Address + 4U) = (uint32_t)(Data >> 32); + /* Wait for last operation to be completed */ + status = FLASH_WaitForLastOperation(ProgramTimeout); + if (status != FLASH_TIMEOUT) { + /* if the program operation is completed, disable the PG Bit */ + FLASH->CR &= ~FLASH_CR_PG; + } + FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); + } + } + return status; +} +#endif + /** * @brief Unlocks the FLASH Program Erase Controller. * @param None diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h index 6c66642ec5c7..97f8ea7cfe2b 100644 --- a/tmk_core/common/chibios/flash_stm32.h +++ b/tmk_core/common/chibios/flash_stm32.h @@ -35,6 +35,7 @@ typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); FLASH_Status FLASH_ErasePage(uint32_t Page_Address); FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); +FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data); void FLASH_Unlock(void); void FLASH_Lock(void); From 66936f279bbcb5a9665d71cba4533dc0e994354a Mon Sep 17 00:00:00 2001 From: lokher Date: Thu, 4 Nov 2021 22:03:13 +0800 Subject: [PATCH 16/32] Update copyright --- .../boards/GENERIC_STM32_L432KC/configs/board.h | 2 +- .../boards/GENERIC_STM32_L432KC/configs/config.h | 3 ++- tmk_core/common/chibios/eeprom_stm32_l4.h | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h index 75abe5147019..a9272d1ec7c6 100644 --- a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h +++ b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h @@ -1,4 +1,4 @@ -/* Copyright 2018-2021 Harrison Chan (@Xelus) +/* Copyright 2021 @ lokher (https://www.keychron.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h index c27c61b19aa4..7386db20784e 100644 --- a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h +++ b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h @@ -1,4 +1,5 @@ -/* Copyright 2018-2021 Harrison Chan (@Xelus) +/* Copyright 2021 @ lokher (https://www.keychron.com) + * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tmk_core/common/chibios/eeprom_stm32_l4.h b/tmk_core/common/chibios/eeprom_stm32_l4.h index cd6abec460b7..61dd8358d52a 100644 --- a/tmk_core/common/chibios/eeprom_stm32_l4.h +++ b/tmk_core/common/chibios/eeprom_stm32_l4.h @@ -13,12 +13,12 @@ * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by * Artur F. * - * Modifications for QMK and STM32L432 by lalalademaxiya1 + * Modifications for QMK and STM32L432 by lalalademaxiya1 & lokher + * + * To add a new MCU, please provide the flash page size and the total flash size in Kb. + * The number of available pages must be at least two. Only one page for the total EEPROM size. + * It is recommend to set the number of log page to 3~5 times of data page for better Wear leveling. * - * This library assumes 8-bit data locations. To add a new MCU, please provide the flash - * page size and the total flash size in Kb. The number of available pages must be a multiple - * of 2. Only one page for the total EEPROM size. - * This library also assumes that the pages are not used by the firmware. */ #pragma once From 2f8070b0202c1d8151f707201dc2a54961b44623 Mon Sep 17 00:00:00 2001 From: lokher Date: Fri, 5 Nov 2021 10:02:51 +0800 Subject: [PATCH 17/32] Update eeprom_stm32_l4.c --- tmk_core/common/chibios/eeprom_stm32_l4.c | 51 ++++++++++------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/tmk_core/common/chibios/eeprom_stm32_l4.c b/tmk_core/common/chibios/eeprom_stm32_l4.c index e934ad436426..9db4d9a134bc 100644 --- a/tmk_core/common/chibios/eeprom_stm32_l4.c +++ b/tmk_core/common/chibios/eeprom_stm32_l4.c @@ -162,8 +162,8 @@ # pragma message STR(FEE_DENSITY_BYTES) " + " STR(FEE_WRITE_LOG_BYTES) " > " STR(FEE_DENSITY_MAX_SIZE) # error emulated eeprom: FEE_WRITE_LOG_BYTES exceeds remaining FEE_DENSITY_MAX_SIZE # endif -# if ((FEE_WRITE_LOG_BYTES) % 2) == 1 -# error emulated eeprom: FEE_WRITE_LOG_BYTES must be even +# if ((FEE_WRITE_LOG_BYTES) % 8) != 0 +# error emulated eeprom: FEE_WRITE_LOG_BYTES must be a multiple of 8 # endif #else /* Default to use all remaining space */ @@ -505,49 +505,42 @@ void eeprom_read_block(void *buf, const void *addr, size_t len) { void eeprom_write_block(const void *buf, void *addr, size_t len) { uint8_t * dest = (uint8_t *)addr; const uint8_t *src = (const uint8_t *)buf; + uint8_t write_len; - /* Check word alignment */ - if (len && (uintptr_t)dest % 2) { - /* Write the unaligned first byte */ - EEPROM_WriteDataByte((uintptr_t)dest++, *src++); - --len; - } + while (len > 0) { + /* Check and try to write double word fisrt */ + if ((uintptr_t)dest % 4 == 0 && len >= 4) { + uint32_t dwvalue; + bool dwaligned = ((uint32_t)src % 4 == 0); - if ((uintptr_t)dest % 4 == 0) { - uint32_t dwvalue; - bool dwaligned = ((uint32_t)src % 4 == 0); - - while (len > 1) { if (dwaligned) { dwvalue = *(uint32_t *)src; } else { dwvalue = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8) | (*(uint8_t *)(src + 2) << 16) | (*(uint8_t *)(src + 3) << 24); } EEPROM_WriteDataDWord((uintptr_t)((uint16_t *)dest), dwvalue); - dest += 4; - src += 4; - len -= 4; + write_len = 4; } - } - - if ((uintptr_t)dest % 2 == 0) { - uint16_t wvalue; - bool waligned = ((uintptr_t)src % 2 == 0); + /* Check and try to write word */ + else if ((uintptr_t)dest % 2 == 0 && len >= 2) { + uint16_t wvalue; + bool waligned = ((uintptr_t)src % 2 == 0); - while (len > 1) { if (waligned) { wvalue = *(uint16_t *)src; } else { wvalue = *(uint8_t *)src | (*(uint8_t *)(src + 1) << 8); } EEPROM_WriteDataWord((uintptr_t)((uint16_t *)dest), wvalue); - dest += 2; - src += 2; - len -= 2; + write_len = 2; + } else { + /* Write the unaligned or single byte */ + EEPROM_WriteDataByte((uintptr_t)dest++, *src++); + write_len = 1; } - } - if (len) { - EEPROM_WriteDataByte((uintptr_t)dest, *src); + dest += write_len; + src += write_len; + len -= write_len; } -} +} \ No newline at end of file From 60588e6dd715811393c38a259bd778825bfcbccb Mon Sep 17 00:00:00 2001 From: lokher Date: Fri, 5 Nov 2021 10:16:24 +0800 Subject: [PATCH 18/32] Update eeprom_stm32_l4.h --- tmk_core/common/chibios/eeprom_stm32_l4.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmk_core/common/chibios/eeprom_stm32_l4.h b/tmk_core/common/chibios/eeprom_stm32_l4.h index 61dd8358d52a..eb29d4d87d22 100644 --- a/tmk_core/common/chibios/eeprom_stm32_l4.h +++ b/tmk_core/common/chibios/eeprom_stm32_l4.h @@ -15,7 +15,7 @@ * * Modifications for QMK and STM32L432 by lalalademaxiya1 & lokher * - * To add a new MCU, please provide the flash page size and the total flash size in Kb. + * To add a new MCU, please provide the flash page size and the total flash size in Kb. * The number of available pages must be at least two. Only one page for the total EEPROM size. * It is recommend to set the number of log page to 3~5 times of data page for better Wear leveling. * From 720eb9a2269a4a6d4a716f05e5e1f086612ba006 Mon Sep 17 00:00:00 2001 From: lokher Date: Wed, 17 Nov 2021 09:16:56 +0800 Subject: [PATCH 19/32] Update tmk_core/common/chibios/eeprom_stm32_l4.c Co-authored-by: Sergey Vlasov --- tmk_core/common/chibios/eeprom_stm32_l4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tmk_core/common/chibios/eeprom_stm32_l4.c b/tmk_core/common/chibios/eeprom_stm32_l4.c index 9db4d9a134bc..8f33881749bb 100644 --- a/tmk_core/common/chibios/eeprom_stm32_l4.c +++ b/tmk_core/common/chibios/eeprom_stm32_l4.c @@ -148,8 +148,8 @@ # pragma message STR(FEE_DENSITY_BYTES) " > " STR(FEE_ADDRESS_MAX_SIZE) # error emulated eeprom: FEE_DENSITY_BYTES is greater than FEE_ADDRESS_MAX_SIZE allows # endif -# if ((FEE_DENSITY_BYTES) % 2) == 1 -# error emulated eeprom: FEE_DENSITY_BYTES must be even +# if ((FEE_DENSITY_BYTES) % 8) != 0 +# error emulated eeprom: FEE_DENSITY_BYTES must be a multiple of 8 # endif #else /* Default to one page of allocated space used for emulated eeprom, 3 pages for write log */ From 7b2b6641a477ed078d249811772aef47ec308452 Mon Sep 17 00:00:00 2001 From: lokher Date: Mon, 7 Feb 2022 15:55:46 +0800 Subject: [PATCH 20/32] Update flash_stm32.h --- tmk_core/common/chibios/flash_stm32.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tmk_core/common/chibios/flash_stm32.h b/tmk_core/common/chibios/flash_stm32.h index 97f8ea7cfe2b..ed2240674c8d 100644 --- a/tmk_core/common/chibios/flash_stm32.h +++ b/tmk_core/common/chibios/flash_stm32.h @@ -34,8 +34,11 @@ typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); FLASH_Status FLASH_ErasePage(uint32_t Page_Address); -FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); +#if defined(STM32L4XX) FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data); +#else +FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); +#endif void FLASH_Unlock(void); void FLASH_Lock(void); From 18ddd7bfef01ee793c1e9f0daba845cc208fad77 Mon Sep 17 00:00:00 2001 From: lokher Date: Mon, 7 Feb 2022 15:56:57 +0800 Subject: [PATCH 21/32] Update flash_stm32.c --- tmk_core/common/chibios/flash_stm32.c | 29 ++++++++++++++------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/tmk_core/common/chibios/flash_stm32.c b/tmk_core/common/chibios/flash_stm32.c index b40f6eeab3c3..c61ef1ae76f7 100644 --- a/tmk_core/common/chibios/flash_stm32.c +++ b/tmk_core/common/chibios/flash_stm32.c @@ -164,14 +164,15 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) { return status; } +#if defined(STM32L4XX) /** - * @brief Programs a half word at a specified address. + * @brief Programs double words at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ -FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { +FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) { FLASH_Status status = FLASH_BAD_ADDRESS; if (IS_FLASH_ADDRESS(Address)) { @@ -179,13 +180,10 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { status = FLASH_WaitForLastOperation(ProgramTimeout); if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ - -#if defined(FLASH_CR_PSIZE) - FLASH->CR &= ~FLASH_CR_PSIZE; - FLASH->CR |= FLASH_CR_PSIZE_0; -#endif FLASH->CR |= FLASH_CR_PG; - *(__IO uint16_t*)Address = Data; + *(__IO uint32_t*)Address = (uint32_t)Data; + __ISB(); + *(__IO uint32_t*)(Address + 4U) = (uint32_t)(Data >> 32); /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if (status != FLASH_TIMEOUT) { @@ -198,15 +196,15 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { return status; } -#if defined(STM32L4XX) +#else /** - * @brief Programs double words at a specified address. + * @brief Programs a half word at a specified address. * @param Address: specifies the address to be programmed. * @param Data: specifies the data to be programmed. * @retval FLASH Status: The returned value can be: FLASH_ERROR_PG, * FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT. */ -FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) { +FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { FLASH_Status status = FLASH_BAD_ADDRESS; if (IS_FLASH_ADDRESS(Address)) { @@ -214,10 +212,13 @@ FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) { status = FLASH_WaitForLastOperation(ProgramTimeout); if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ + +#if defined(FLASH_CR_PSIZE) + FLASH->CR &= ~FLASH_CR_PSIZE; + FLASH->CR |= FLASH_CR_PSIZE_0; +#endif FLASH->CR |= FLASH_CR_PG; - *(__IO uint32_t*)Address = (uint32_t)Data; - __ISB(); - *(__IO uint32_t*)(Address + 4U) = (uint32_t)(Data >> 32); + *(__IO uint16_t*)Address = Data; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(ProgramTimeout); if (status != FLASH_TIMEOUT) { From c78ae9a7dd6dd38a8c525590c37ff1734f59df32 Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:14:39 +0800 Subject: [PATCH 22/32] Delete keyboard.jsonschema --- data/schemas/keyboard.jsonschema | 361 ------------------------------- 1 file changed, 361 deletions(-) delete mode 100644 data/schemas/keyboard.jsonschema diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema deleted file mode 100644 index e4916c2ab3ad..000000000000 --- a/data/schemas/keyboard.jsonschema +++ /dev/null @@ -1,361 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "qmk.keyboard.v1", - "title": "Keyboard Information", - "type": "object", - "properties": { - "keyboard_name": {"$ref": "qmk.definitions.v1#/text_identifier"}, - "maintainer": {"$ref": "qmk.definitions.v1#/text_identifier"}, - "manufacturer": {"$ref": "qmk.definitions.v1#/text_identifier"}, - "url": { - "type": "string", - "format": "uri" - }, - "processor": { - "type": "string", - "enum": ["cortex-m0", "cortex-m0plus", "cortex-m3", "cortex-m4", "MKL26Z64", "MK20DX128", "MK20DX256", "MK66FX1M0", "STM32F042", "STM32F072", "STM32F103", "STM32F303", "STM32F401", "STM32F405", "STM32F407", "STM32F411", "STM32F446", "STM32G431", "STM32G474", "STM32L412", "STM32L422", "STM32L432", "STM32L433", "STM32L443", "GD32VF103", "atmega16u2", "atmega32u2", "atmega16u4", "atmega32u4", "at90usb162", "at90usb646", "at90usb647", "at90usb1286", "at90usb1287", "atmega32a", "atmega328p", "atmega328", "attiny85", "unknown"] - }, - "audio": { - "type": "object", - "additionalProperties": false, - "properties": { - "pins": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}, - "voices": {"type": "boolean"} - } - }, - "backlight": { - "type": "object", - "additionalProperties": false, - "properties": { - "breathing": {"type": "boolean"}, - "breathing_period": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "levels": { - "type": "number", - "min": 1, - "max": 31, - "multipleOf": 1 - }, - "pin": {"$ref": "qmk.definitions.v1#/mcu_pin"} - } - }, - "bluetooth": { - "type": "object", - "additionalProperties": false, - "properties": { - "driver": { - "type": "string", - "enum": ["AdafruitBLE", "RN42"] - }, - "lto": {"type": "boolean"}, - } - }, - "board": { - "type": "string", - "minLength": 2, - "pattern": "^[a-zA-Z_][0-9a-zA-Z_]*$" - }, - "bootloader": { - "type": "string", - "enum": ["atmel-dfu", "bootloadhid", "bootloadHID", "caterina", "halfkay", "kiibohd", "lufa-dfu", "lufa-ms", "micronucleus", "qmk-dfu", "qmk-hid", "stm32-dfu", "stm32duino", "gd32v-dfu", "unknown", "usbasploader", "USBasp", "tinyuf2"], - }, - "bootloader_instructions": { - "type": "string", - "description": "Instructions for putting the keyboard into a mode that allows for firmware flashing." - }, - "build": { - "type": "object", - "additionalProperties": false, - "properties": { - "debounce_type": { - "type": "string", - "enum": ["custom", "eager_pk", "eager_pr", "sym_defer_pk", "sym_eager_pk"] - }, - "firmware_format": { - "type": "string", - "enum": ["bin", "hex", "uf2"] - }, - "lto": {"type": "boolean"}, - } - }, - "diode_direction": { - "type": "string", - "enum": ["COL2ROW", "ROW2COL"] - }, - "debounce": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "combo": { - "type": "object", - "properties": { - "count": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "term": {"$ref": "qmk.definitions.v1#/unsigned_int"} - } - }, - "community_layouts": { - "type": "array", - "items": {"$ref": "qmk.definitions.v1#/filename"} - }, - "features": {"$ref": "qmk.definitions.v1#/boolean_array"}, - "indicators": { - "type": "object", - "properties": { - "caps_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "num_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "scroll_lock": {"$ref": "qmk.definitions.v1#/mcu_pin"} - } - }, - "layout_aliases": { - "type": "object", - "additionalProperties": {"$ref": "qmk.definitions.v1#/layout_macro"} - }, - "layouts": { - "type": "object", - "additionalProperties": { - "type": "object", - "additionalProperties": false, - "properties": { - "filename": { - "type": "string" - }, - "c_macro": { - "type": "boolean" - }, - "layout": { - "type": "array", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "label": {"type": "string"}, - "matrix": { - "type": "array", - "minItems": 2, - "maxItems": 2, - "items": { - "type": "number", - "min": 0, - "multipleOf": 1 - } - }, - "r": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}, - "rx": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}, - "ry": {"$ref": "qmk.definitions.v1#/unsigned_decimal"}, - "h": {"$ref": "qmk.definitions.v1#/key_unit"}, - "w": {"$ref": "qmk.definitions.v1#/key_unit"}, - "x": {"$ref": "qmk.definitions.v1#/key_unit"}, - "y": {"$ref": "qmk.definitions.v1#/key_unit"} - } - } - } - } - } - }, - "leader_key": { - "type": "object", - "properties": { - "timing": {"type": "boolean"}, - "strict_processing": {"type": "boolean"}, - "timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"} - } - }, - "matrix_pins": { - "type": "object", - "additionalProperties": false, - "properties": { - "custom": {"type": "boolean"}, - "custom_lite": {"type": "boolean"}, - "ghost": {"type": "boolean"}, - "io_delay": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "direct": { - "type": "array", - "items": {"$ref": "qmk.definitions.v1#/mcu_pin_array"} - }, - "cols": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}, - "rows": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}, - "unused": {"$ref": "qmk.definitions.v1#/mcu_pin_array"} - } - }, - "mouse_key": { - "type": "object", - "properties": { - "enabled": {"type": "boolean"}, - "delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"} - "interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"} - "max_speed": {"$ref": "qmk.definitions.v1#/unsigned_int_8"} - "time_to_max": {"$ref": "qmk.definitions.v1#/unsigned_int_8"} - "wheel_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"} - } - }, - "oneshot": { - "type": "object", - "properties": { - "tap_toggle": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"} - } - }, - "rgblight": { - "type": "object", - "additionalProperties": false, - "properties": { - "animations": { - "type": "object", - "additionalProperties": { - "type": "boolean" - } - }, - "brightness_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "hue_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "layers": { - "type": "object", - "additionalProperties": false, - "properties": { - "blink": {"type": "boolean"}, - "enabled": {"type": "boolean"}, - "max": { - "type": "number", - "min": 1, - "max": 32, - "multipleOf": 1 - }, - "override_rgb": {"type": "boolean"} - } - }, - "led_count": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "max_brightness": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "pin": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "rgbw": {"type": "boolean"}, - "saturation_steps": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "sleep": {"type": "boolean"}, - "split": {"type": "boolean"}, - "split_count": { - "type": "array", - "minLength": 2, - "maxLength": 2, - "items": {"$ref": "qmk.definitions.v1#/unsigned_int"} - } - } - }, - "split": { - "type": "object", - "additionalProperties": false, - "properties": { - "enabled": {"type": "boolean"}, - "matrix_grid": { - "type": "array", - "items": {"$ref": "qmk.definitions.v1#/mcu_pin"} - }, - "matrix_pins": { - "type": "object", - "additionalProperties": false, - "properties": { - "right": { - "type": "object", - "additionalProperties": false, - "properties": { - "direct": { - "type": "array", - "items": {"$ref": "qmk.definitions.v1#/mcu_pin_array"} - }, - "cols": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}, - "rows": {"$ref": "qmk.definitions.v1#/mcu_pin_array"}, - "unused": {"$ref": "qmk.definitions.v1#/mcu_pin_array"} - } - } - } - }, - "main": { - "type": "string", - "enum": ["eeprom", "left", "matrix_grid", "pin", "right"] - }, - "soft_serial_pin": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "soft_serial_speed": { - "type": "number", - "min": 0, - "max": 5, - "multipleOf": 1 - }, - "transport": { - "type": "object", - "additionalProperties": false, - "properties": { - "protocol": { - "type": "string", - "enum": ["custom", "i2c", "serial", "serial_usart"] - }, - "sync_matrix_state": {"type": "boolean"}, - "sync_modifiers": {"type": "boolean"} - } - }, - "usb_detect": { - "type": "object", - "additionalProperties": false, - "properties": { - "enabled": {"type": "boolean"}, - "polling_interval": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "timeout": {"$ref": "qmk.definitions.v1#/unsigned_int"} - } - } - } - }, - "tags": { - "type": "array", - "items": {"type": "string"} - }, - "tapping": { - "type": "object", - "properties": { - "force_hold": {"type": "boolean"}, - "force_hold_per_key": {"type": "boolean"}, - "ignore_mod_tap_interrupt": {"type": "boolean"}, - "ignore_mod_tap_interrupt_per_key": {"type": "boolean"}, - "permissive_hold": {"type": "boolean"}, - "permissive_hold_per_key": {"type": "boolean"}, - "retro": {"type": "boolean"}, - "retro_per_key": {"type": "boolean"}, - "term": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - "term_per_key": {"type": "boolean"}, - "toggle": {"$ref": "qmk.definitions.v1#/unsigned_int"}, - } - }, - "usb": { - "type": "object", - "additionalProperties": false, - "properties": { - "device_ver": {"$ref": "qmk.definitions.v1#/hex_number_4d"}, - "force_nkro": {"type": "boolean"}, - "pid": {"$ref": "qmk.definitions.v1#/hex_number_4d"}, - "vid": {"$ref": "qmk.definitions.v1#/hex_number_4d"}, - "max_power": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "no_startup_check": {"type": "boolean"}, - "polling_interval": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "shared_endpoint": { - "type": "object", - "additionalProperties": false, - "properties": { - "keyboard": {"type": "boolean"}, - "mouse": {"type": "boolean"} - } - }, - "suspend_wakeup_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "wait_for": {"type": "boolean"}, - } - }, - "qmk": { - "type": "object", - "additionalProperties": false, - "properties": { - "keys_per_scan": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "tap_keycode_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - "tap_capslock_delay": {"$ref": "qmk.definitions.v1#/unsigned_int_8"}, - } - }, - "qmk_lufa_bootloader": { - "type": "object", - "additionalProperties": false, - "properties": { - "esc_output": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "esc_input": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "led": {"$ref": "qmk.definitions.v1#/mcu_pin"}, - "speaker": {"$ref": "qmk.definitions.v1#/mcu_pin"} - } - } - } -} From 84d9d6d1d6eb74d018e83b52b3f15ba18c673a08 Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:15:31 +0800 Subject: [PATCH 23/32] Delete compatible_microcontrollers.md --- docs/compatible_microcontrollers.md | 57 ----------------------------- 1 file changed, 57 deletions(-) delete mode 100644 docs/compatible_microcontrollers.md diff --git a/docs/compatible_microcontrollers.md b/docs/compatible_microcontrollers.md deleted file mode 100644 index 44f1b662e522..000000000000 --- a/docs/compatible_microcontrollers.md +++ /dev/null @@ -1,57 +0,0 @@ -# Compatible Microcontrollers - -QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB or more, though it will *just* squeeze into 16kB with most features disabled. - -## Atmel AVR - -The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB stack: - -* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) -* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) -* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) -* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162) - -Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead: - -* [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A) -* [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P) -* [ATmega328](https://www.microchip.com/wwwproducts/en/ATmega328) - -## ARM - -You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) supports. Most have plenty of flash. Known to work are: - -### STMicroelectronics (STM32) - - * [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html) - * [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html) - * [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html) - * [STM32F401](https://www.st.com/en/microcontrollers-microprocessors/stm32f401.html) - * [STM32F405](https://www.st.com/en/microcontrollers-microprocessors/stm32f405-415.html) - * [STM32F407](https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html) - * [STM32F411](https://www.st.com/en/microcontrollers-microprocessors/stm32f411.html) - * [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html) - * [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html) - * [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html) - * [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L432](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) - * [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) - -### NXP (Kinetis) - - * [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x) - * [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50) - * [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72) - * [MK66FX1M0](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k66-180-mhz-dual-high-speed-full-speed-usbs-2mb-flash-microcontrollers-mcus-based-on-arm-cortex-m4-core:K66_180) - -## Atmel ATSAM - -There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). - -## RISC-V - -### GigaDevice - -[ChibiOS-Contrib](https://github.com/ChibiOS/ChibiOS-Contrib) has support for the GigaDevice [GD32VF103 series](https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/mainstream-line/gd32vf103-series/) microcontrollers and provides configurations for the [SiPeed Longan Nano](https://longan.sipeed.com/en/) development board that uses this microcontroller. It is largely pin and feature compatible with STM32F103 and STM32F303 microcontrollers. From acd5ac1a1f3ac2b255f16684534bbf24451d4ae7 Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:15:52 +0800 Subject: [PATCH 24/32] Delete constants.py --- lib/python/qmk/constants.py | 38 ------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 lib/python/qmk/constants.py diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py deleted file mode 100644 index 5c3900155f0d..000000000000 --- a/lib/python/qmk/constants.py +++ /dev/null @@ -1,38 +0,0 @@ -"""Information that should be available to the python library. -""" -from os import environ -from pathlib import Path - -# The root of the qmk_firmware tree. -QMK_FIRMWARE = Path.cwd() - -# Upstream repo url -QMK_FIRMWARE_UPSTREAM = 'qmk/qmk_firmware' - -# This is the number of directories under `qmk_firmware/keyboards` that will be traversed. This is currently a limitation of our make system. -MAX_KEYBOARD_SUBFOLDERS = 5 - -# Supported processor types -CHIBIOS_PROCESSORS = 'cortex-m0', 'cortex-m0plus', 'cortex-m3', 'cortex-m4', 'MKL26Z64', 'MK20DX128', 'MK20DX256', 'MK66FX1M0', 'STM32F042', 'STM32F072', 'STM32F103', 'STM32F303', 'STM32F401', 'STM32F407', 'STM32F411', 'STM32F446', 'STM32G431', 'STM32G474', 'STM32L412', 'STM32L422', 'STM32L432', 'STM32L433', 'STM32L443', 'GD32VF103' -LUFA_PROCESSORS = 'at90usb162', 'atmega16u2', 'atmega32u2', 'atmega16u4', 'atmega32u4', 'at90usb646', 'at90usb647', 'at90usb1286', 'at90usb1287', None -VUSB_PROCESSORS = 'atmega32a', 'atmega328p', 'atmega328', 'attiny85' - -# Common format strings -DATE_FORMAT = '%Y-%m-%d' -DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z' -TIME_FORMAT = '%H:%M:%S' - -# Used when generating matrix locations -COL_LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijilmnopqrstuvwxyz' -ROW_LETTERS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnop' - -# Mapping between info.json and config.h keys -LED_INDICATORS = { - 'caps_lock': 'LED_CAPS_LOCK_PIN', - 'num_lock': 'LED_NUM_LOCK_PIN', - 'scroll_lock': 'LED_SCROLL_LOCK_PIN', -} - -# Constants that should match their counterparts in make -BUILD_DIR = environ.get('BUILD_DIR', '.build') -KEYBOARD_OUTPUT_PREFIX = f'{BUILD_DIR}/obj_' From 9f698cc3a36ff4ca7ced050b50242a4f147831ef Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:16:54 +0800 Subject: [PATCH 25/32] Delete board.mk --- .../chibios/boards/GENERIC_STM32_L432KC/board/board.mk | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk b/platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk deleted file mode 100644 index 1250385eb8e2..000000000000 --- a/platforms/chibios/boards/GENERIC_STM32_L432KC/board/board.mk +++ /dev/null @@ -1,9 +0,0 @@ -# List of all the board related files. -BOARDSRC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC/board.c - -# Required include directories -BOARDINC = $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L432KC - -# Shared variables -ALLCSRC += $(BOARDSRC) -ALLINC += $(BOARDINC) From 40d06cc9832942d85949e9187795754e8f0b23bd Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:17:04 +0800 Subject: [PATCH 26/32] Delete board.h --- .../GENERIC_STM32_L432KC/configs/board.h | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h deleted file mode 100644 index a9272d1ec7c6..000000000000 --- a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/board.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2021 @ lokher (https://www.keychron.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 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 - -#include_next "board.h" From a235870942a5dbf177e7c4ecdc60526e2eddd943 Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:17:17 +0800 Subject: [PATCH 27/32] Delete config.h --- .../GENERIC_STM32_L432KC/configs/config.h | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h deleted file mode 100644 index 7386db20784e..000000000000 --- a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/config.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2021 @ lokher (https://www.keychron.com) - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Address for jumping to bootloader on STM32 chips. */ -/* It is chip dependent, the correct number can be looked up by checking against ST's application note AN2606. - */ -#define STM32_BOOTLOADER_ADDRESS 0x1FFF0000 - -#define PAL_STM32_OSPEED_HIGHEST PAL_STM32_OSPEED_HIGH - -#ifndef EARLY_INIT_PERFORM_BOOTLOADER_JUMP -# define EARLY_INIT_PERFORM_BOOTLOADER_JUMP TRUE -#endif From b64fcd1781bd7c0a2ee87349d36d8cfe2c4b199f Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 09:17:30 +0800 Subject: [PATCH 28/32] Delete mcuconf.h --- .../GENERIC_STM32_L432KC/configs/mcuconf.h | 262 ------------------ 1 file changed, 262 deletions(-) delete mode 100644 platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h diff --git a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h b/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h deleted file mode 100644 index 1157888d732e..000000000000 --- a/platforms/chibios/boards/GENERIC_STM32_L432KC/configs/mcuconf.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* - * STM32L4xx drivers configuration. - * The following settings override the default settings present in - * the various device driver implementation headers. - * Note that the settings for each driver only have effect if the whole - * driver is enabled in halconf.h. - * - * IRQ priorities: - * 15...0 Lowest...Highest. - * - * DMA priorities: - * 0...3 Lowest...Highest. - */ - -#ifndef MCUCONF_H -#define MCUCONF_H - -#define STM32L4xx_MCUCONF -#define STM32L432_MCUCONF - -/* - * HAL driver system settings. - */ -#define STM32_NO_INIT FALSE -#define STM32_VOS STM32_VOS_RANGE1 -#define STM32_PVD_ENABLE FALSE -#define STM32_PLS STM32_PLS_LEV0 -#define STM32_HSI16_ENABLED TRUE -#define STM32_HSI48_ENABLED TRUE -#define STM32_LSI_ENABLED TRUE -#define STM32_HSE_ENABLED FALSE -#define STM32_LSE_ENABLED FALSE -#define STM32_MSIPLL_ENABLED FALSE -#define STM32_MSIRANGE STM32_MSIRANGE_4M -#define STM32_MSISRANGE STM32_MSISRANGE_4M -#define STM32_SW STM32_SW_PLL -#define STM32_PLLSRC STM32_PLLSRC_HSI16 -#define STM32_PLLM_VALUE 1 -#define STM32_PLLN_VALUE 10 -#define STM32_PLLPDIV_VALUE 0 -#define STM32_PLLP_VALUE 7 -#define STM32_PLLQ_VALUE 2 -#define STM32_PLLR_VALUE 2 -#define STM32_HPRE STM32_HPRE_DIV1 -#define STM32_PPRE1 STM32_PPRE1_DIV1 -#define STM32_PPRE2 STM32_PPRE2_DIV1 -#define STM32_STOPWUCK STM32_STOPWUCK_MSI -#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK -#define STM32_MCOPRE STM32_MCOPRE_DIV1 -#define STM32_LSCOSEL STM32_LSCOSEL_NOCLOCK -#define STM32_PLLSAI1N_VALUE 24 -#define STM32_PLLSAI1PDIV_VALUE 0 -#define STM32_PLLSAI1P_VALUE 7 -#define STM32_PLLSAI1Q_VALUE 2 -#define STM32_PLLSAI1R_VALUE 2 - -/* - * Peripherals clock sources. - */ -#define STM32_USART1SEL STM32_USART1SEL_SYSCLK -#define STM32_USART2SEL STM32_USART2SEL_SYSCLK -#define STM32_LPUART1SEL STM32_LPUART1SEL_SYSCLK -#define STM32_I2C1SEL STM32_I2C1SEL_SYSCLK -#define STM32_I2C3SEL STM32_I2C3SEL_SYSCLK -#define STM32_LPTIM1SEL STM32_LPTIM1SEL_PCLK1 -#define STM32_LPTIM2SEL STM32_LPTIM2SEL_PCLK1 -#define STM32_SAI1SEL STM32_SAI1SEL_OFF -#define STM32_CLK48SEL STM32_CLK48SEL_HSI48 -#define STM32_ADCSEL STM32_ADCSEL_SYSCLK -#define STM32_SWPMI1SEL STM32_SWPMI1SEL_PCLK1 -#define STM32_RTCSEL STM32_RTCSEL_LSI - -/* - * IRQ system settings. - */ -#define STM32_IRQ_EXTI0_PRIORITY 6 -#define STM32_IRQ_EXTI1_PRIORITY 6 -#define STM32_IRQ_EXTI2_PRIORITY 6 -#define STM32_IRQ_EXTI3_PRIORITY 6 -#define STM32_IRQ_EXTI4_PRIORITY 6 -#define STM32_IRQ_EXTI5_9_PRIORITY 6 -#define STM32_IRQ_EXTI10_15_PRIORITY 6 -#define STM32_IRQ_EXTI1635_38_PRIORITY 6 -#define STM32_IRQ_EXTI18_PRIORITY 6 -#define STM32_IRQ_EXTI19_PRIORITY 6 -#define STM32_IRQ_EXTI20_PRIORITY 6 -#define STM32_IRQ_EXTI21_22_PRIORITY 15 - -#define STM32_IRQ_TIM1_BRK_TIM15_PRIORITY 7 -#define STM32_IRQ_TIM1_UP_TIM16_PRIORITY 7 -#define STM32_IRQ_TIM1_TRGCO_TIM17_PRIORITY 7 -#define STM32_IRQ_TIM1_CC_PRIORITY 7 -#define STM32_IRQ_TIM2_PRIORITY 7 -#define STM32_IRQ_TIM6_PRIORITY 7 -#define STM32_IRQ_TIM7_PRIORITY 7 - -#define STM32_IRQ_USART1_PRIORITY 12 -#define STM32_IRQ_USART2_PRIORITY 12 -#define STM32_IRQ_LPUART1_PRIORITY 12 - -/* - * ADC driver system settings. - */ -#define STM32_ADC_COMPACT_SAMPLES FALSE -#define STM32_ADC_USE_ADC1 FALSE -#define STM32_ADC_ADC1_DMA_STREAM STM32_DMA_STREAM_ID(1, 1) -#define STM32_ADC_ADC1_DMA_PRIORITY 2 -#define STM32_ADC_ADC12_IRQ_PRIORITY 5 -#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 5 -#define STM32_ADC_ADC123_CLOCK_MODE ADC_CCR_CKMODE_AHB_DIV1 -#define STM32_ADC_ADC123_PRESC ADC_CCR_PRESC_DIV2 - -/* - * CAN driver system settings. - */ -#define STM32_CAN_USE_CAN1 FALSE -#define STM32_CAN_CAN1_IRQ_PRIORITY 11 - -/* - * DAC driver system settings. - */ -#define STM32_DAC_DUAL_MODE FALSE -#define STM32_DAC_USE_DAC1_CH1 FALSE -#define STM32_DAC_USE_DAC1_CH2 FALSE -#define STM32_DAC_DAC1_CH1_IRQ_PRIORITY 10 -#define STM32_DAC_DAC1_CH2_IRQ_PRIORITY 10 -#define STM32_DAC_DAC1_CH1_DMA_PRIORITY 2 -#define STM32_DAC_DAC1_CH2_DMA_PRIORITY 2 -#define STM32_DAC_DAC1_CH1_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) -#define STM32_DAC_DAC1_CH2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) - -/* - * GPT driver system settings. - */ -#define STM32_GPT_USE_TIM1 FALSE -#define STM32_GPT_USE_TIM2 FALSE -#define STM32_GPT_USE_TIM6 FALSE -#define STM32_GPT_USE_TIM7 FALSE -#define STM32_GPT_USE_TIM15 FALSE -#define STM32_GPT_USE_TIM16 FALSE - -/* - * I2C driver system settings. - */ -#define STM32_I2C_USE_I2C1 FALSE -#define STM32_I2C_USE_I2C3 FALSE -#define STM32_I2C_BUSY_TIMEOUT 50 -#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) -#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) -#define STM32_I2C_I2C3_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) -#define STM32_I2C_I2C3_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2) -#define STM32_I2C_I2C1_IRQ_PRIORITY 5 -#define STM32_I2C_I2C3_IRQ_PRIORITY 5 -#define STM32_I2C_I2C1_DMA_PRIORITY 3 -#define STM32_I2C_I2C3_DMA_PRIORITY 3 -#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure") - -/* - * ICU driver system settings. - */ -#define STM32_ICU_USE_TIM1 FALSE -#define STM32_ICU_USE_TIM2 FALSE -#define STM32_ICU_USE_TIM15 FALSE -#define STM32_ICU_USE_TIM16 FALSE - -/* - * PWM driver system settings. - */ -#define STM32_PWM_USE_ADVANCED FALSE -#define STM32_PWM_USE_TIM1 FALSE -#define STM32_PWM_USE_TIM2 FALSE -#define STM32_PWM_USE_TIM15 FALSE -#define STM32_PWM_USE_TIM16 FALSE - -/* - * RTC driver system settings. - */ -#define STM32_RTC_PRESA_VALUE 32 -#define STM32_RTC_PRESS_VALUE 1024 -#define STM32_RTC_CR_INIT 0 -#define STM32_RTC_TAMPCR_INIT 0 - -/* - * SERIAL driver system settings. - */ -#define STM32_SERIAL_USE_USART1 FALSE -#define STM32_SERIAL_USE_USART2 FALSE -#define STM32_SERIAL_USE_LPUART1 FALSE -#define STM32_SERIAL_USART1_PRIORITY 12 -#define STM32_SERIAL_USART2_PRIORITY 12 -#define STM32_SERIAL_LPUART1_PRIORITY 12 - -/* - * SPI driver system settings. - */ -#define STM32_SPI_USE_SPI1 FALSE -#define STM32_SPI_USE_SPI3 FALSE -#define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 3) -#define STM32_SPI_SPI1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 4) -#define STM32_SPI_SPI3_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 1) -#define STM32_SPI_SPI3_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 2) -#define STM32_SPI_SPI1_DMA_PRIORITY 1 -#define STM32_SPI_SPI3_DMA_PRIORITY 1 -#define STM32_SPI_SPI1_IRQ_PRIORITY 10 -#define STM32_SPI_SPI3_IRQ_PRIORITY 10 -#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") - -/* - * ST driver system settings. - */ -#define STM32_ST_IRQ_PRIORITY 8 -#define STM32_ST_USE_TIMER 2 - -/* - * TRNG driver system settings. - */ -#define STM32_TRNG_USE_RNG1 FALSE - -/* - * UART driver system settings. - */ -#define STM32_UART_USE_USART1 FALSE -#define STM32_UART_USE_USART2 FALSE -#define STM32_UART_USART1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) -#define STM32_UART_USART1_TX_DMA_STREAM STM32_DMA_STREAM_ID(2, 6) -#define STM32_UART_USART2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6) -#define STM32_UART_USART2_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 7) -#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure") - -/* - * USB driver system settings. - */ -#define STM32_USB_USE_USB1 TRUE -#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE -#define STM32_USB_USB1_HP_IRQ_PRIORITY 13 -#define STM32_USB_USB1_LP_IRQ_PRIORITY 14 - -/* - * WDG driver system settings. - */ -#define STM32_WDG_USE_IWDG FALSE - -/* - * WSPI driver system settings. - */ -#define STM32_WSPI_USE_QUADSPI1 FALSE -#define STM32_WSPI_QUADSPI1_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) - -#endif /* MCUCONF_H */ From 5d3e394d7c244cbc57004b96d3448e6fbf744d6f Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 10:09:06 +0800 Subject: [PATCH 29/32] Delete mcu_selection.mk --- builddefs/mcu_selection.mk | 702 ------------------------------------- 1 file changed, 702 deletions(-) delete mode 100644 builddefs/mcu_selection.mk diff --git a/builddefs/mcu_selection.mk b/builddefs/mcu_selection.mk deleted file mode 100644 index 76de85c2308f..000000000000 --- a/builddefs/mcu_selection.mk +++ /dev/null @@ -1,702 +0,0 @@ -MCU_ORIG := $(MCU) - -ifneq ($(findstring MKL26Z64, $(MCU)),) - # Cortex version - MCU = cortex-m0plus - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 6 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = KINETIS - MCU_SERIES = KL2x - - # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= MKL26Z64 - - # Startup code to use - # - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= kl2x - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= PJRC_TEENSY_LC -endif - -ifneq ($(findstring MK20DX128, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = KINETIS - MCU_SERIES = K20x - - # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= MK20DX128 - - # Startup code to use - # - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= k20x5 - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= PJRC_TEENSY_3 -endif - -ifneq ($(findstring MK20DX256, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = KINETIS - MCU_SERIES = K20x - - # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= MK20DX256 - - # Startup code to use - # - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= k20x7 - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= PJRC_TEENSY_3_1 -endif - -ifneq ($(findstring MK66FX1M0, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = KINETIS - MCU_SERIES = MK66F18 - - # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= MK66FX1M0 - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= MK66F18 - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= PJRC_TEENSY_3_6 -endif - -ifneq ($(findstring STM32F042, $(MCU)),) - # Cortex version - MCU = cortex-m0 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 6 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F0xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F042x6 - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f0xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F042X6 - - USE_FPU ?= no - - # UF2 settings - UF2_FAMILY ?= STM32F0 - - # Stack sizes: Since this chip has limited RAM capacity, the stack area needs to be reduced. - # This ensures that the EEPROM page buffer fits into RAM - USE_PROCESS_STACKSIZE = 0x600 - USE_EXCEPTIONS_STACKSIZE = 0x300 -endif - -ifneq ($(findstring STM32F072, $(MCU)),) - # Cortex version - MCU = cortex-m0 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 6 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F0xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F072xB - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f0xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F072XB - - USE_FPU ?= no - - # UF2 settings - UF2_FAMILY ?= STM32F0 -endif - -ifneq ($(findstring STM32F103, $(MCU)),) - # Cortex version - MCU = cortex-m3 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F1xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F103x8 - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f1xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F103 - - USE_FPU ?= no - - # UF2 settings - UF2_FAMILY ?= STM32F1 -endif - -ifneq ($(findstring STM32F303, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F3xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F303xC - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f3xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F303XC - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32F3 -endif - -ifneq ($(findstring STM32F401, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - ifeq ($(strip $(BOOTLOADER)), tinyuf2) - MCU_LDSCRIPT ?= STM32F401xC_tinyuf2 - FIRMWARE_FORMAT ?= uf2 - else - MCU_LDSCRIPT ?= STM32F401xC - endif - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= BLACKPILL_STM32_F401 - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F405, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F4xx - - # Linker script to use - # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F405xG - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F405XG - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F407, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F407xE - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F407XE - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F411, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - ifeq ($(strip $(BOOTLOADER)), tinyuf2) - MCU_LDSCRIPT ?= STM32F411xE_tinyuf2 - FIRMWARE_FORMAT ?= uf2 - else - MCU_LDSCRIPT ?= STM32F411xE - endif - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= BLACKPILL_STM32_F411 - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32F4 -endif - -ifneq ($(findstring STM32F446, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32F4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32F446xE - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32f4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_F446XE - - USE_FPU ?= yes -endif - -ifneq ($(findstring STM32G431, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32G4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32G431xB - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32g4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_G431XB - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32G4 -endif - -ifneq ($(findstring STM32G474, $(MCU)),) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32G4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32G474xE - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32g4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_G474XE - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32G4 -endif - -ifneq (,$(filter $(MCU),STM32L432)) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32L4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32L432xC - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32l4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_L432KC - - PLATFORM_NAME ?= platform_l432 - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32L4 -endif - -ifneq (,$(filter $(MCU),STM32L433 STM32L443)) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32L4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32L432xC - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32l4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_L433XC - - PLATFORM_NAME ?= platform_l432 - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32L4 -endif - -ifneq (,$(filter $(MCU),STM32L412 STM32L422)) - # Cortex version - MCU = cortex-m4 - - # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 - ARMV = 7 - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = STM32 - MCU_SERIES = STM32L4xx - - # Linker script to use - # - it should exist either in /os/common/startup/ARMCMx/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= STM32L412xB - - # Startup code to use - # - it should exist in /os/common/startup/ARMCMx/compilers/GCC/mk/ - MCU_STARTUP ?= stm32l4xx - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= GENERIC_STM32_L412XB - - PLATFORM_NAME ?= platform_l432 - - USE_FPU ?= yes - - # UF2 settings - UF2_FAMILY ?= STM32L4 -endif - -ifneq ($(findstring GD32VF103, $(MCU)),) - # RISC-V - MCU = risc-v - - # RISC-V extensions and abi configuration - MCU_ARCH = rv32imac - MCU_ABI = ilp32 - MCU_CMODEL = medlow - - ## chip/board settings - # - the next two should match the directories in - # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) - MCU_FAMILY = GD32V - MCU_SERIES = GD32VF103 - - # Linker script to use - # - it should exist either in /os/common/startup/RISCV-ECLIC/compilers/GCC/ld/ - # or /ld/ - MCU_LDSCRIPT ?= GD32VF103xB - - # Startup code to use - # - it should exist in /os/common/startup/RISCV-ECLIC/compilers/GCC/mk/ - MCU_STARTUP ?= gd32vf103 - - # Board: it should exist either in /os/hal/boards/, - # /boards/, or drivers/boards/ - BOARD ?= SIPEED_LONGAN_NANO - - USE_FPU ?= no -endif - -ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2 atmega16u4 atmega32u4 at90usb646 at90usb647 at90usb1286 at90usb1287)) - PROTOCOL = LUFA - - # Processor frequency. - # This will define a symbol, F_CPU, in all source code files equal to the - # processor frequency in Hz. You can then use this symbol in your source code to - # calculate timings. Do NOT tack on a 'UL' at the end, this will be done - # automatically to create a 32-bit value in your source code. - # - # This will be an integer division of F_USB below, as it is sourced by - # F_USB after it has run through any CPU prescalers. Note that this value - # does not *change* the processor frequency - it should merely be updated to - # reflect the processor speed set externally so that the code can use accurate - # software delays. - F_CPU ?= 16000000 - - # LUFA specific - # - # Target architecture (see library "Board Types" documentation). - ARCH = AVR8 - - # Input clock frequency. - # This will define a symbol, F_USB, in all source code files equal to the - # input clock frequency (before any prescaling is performed) in Hz. This value may - # differ from F_CPU if prescaling is used on the latter, and is required as the - # raw input clock is fed directly to the PLL sections of the AVR for high speed - # clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' - # at the end, this will be done automatically to create a 32-bit value in your - # source code. - # - # If no clock division is performed on the input clock inside the AVR (via the - # CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. - F_USB ?= $(F_CPU) - - # Interrupt driven control endpoint task - ifeq (,$(filter $(NO_INTERRUPT_CONTROL_ENDPOINT),yes)) - OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT - endif - ifneq (,$(filter $(MCU),at90usb162 atmega16u2 atmega32u2)) - NO_I2C = yes - endif -endif - -ifneq (,$(filter $(MCU),atmega32a)) - # MCU name for avrdude - AVRDUDE_MCU = m32 - - PROTOCOL = VUSB - - # Processor frequency. - # This will define a symbol, F_CPU, in all source code files equal to the - # processor frequency in Hz. You can then use this symbol in your source code to - # calculate timings. Do NOT tack on a 'UL' at the end, this will be done - # automatically to create a 32-bit value in your source code. - F_CPU ?= 12000000 -endif - -ifneq (,$(filter $(MCU),atmega328p)) - # MCU name for avrdude - AVRDUDE_MCU = m328p - - PROTOCOL = VUSB - - # Processor frequency. - # This will define a symbol, F_CPU, in all source code files equal to the - # processor frequency in Hz. You can then use this symbol in your source code to - # calculate timings. Do NOT tack on a 'UL' at the end, this will be done - # automatically to create a 32-bit value in your source code. - F_CPU ?= 16000000 -endif - -ifneq (,$(filter $(MCU),atmega328)) - # MCU name for avrdude - AVRDUDE_MCU = m328 - - PROTOCOL = VUSB - - # Processor frequency. - # This will define a symbol, F_CPU, in all source code files equal to the - # processor frequency in Hz. You can then use this symbol in your source code to - # calculate timings. Do NOT tack on a 'UL' at the end, this will be done - # automatically to create a 32-bit value in your source code. - F_CPU ?= 16000000 -endif - -ifneq (,$(filter $(MCU),attiny85)) - PROTOCOL = VUSB - - # Processor frequency. - # This will define a symbol, F_CPU, in all source code files equal to the - # processor frequency in Hz. You can then use this symbol in your source code to - # calculate timings. Do NOT tack on a 'UL' at the end, this will be done - # automatically to create a 32-bit value in your source code. - F_CPU ?= 16500000 -endif From 31514321c7e447690b224b006bb2a8b6abbaf939 Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 12:20:37 +0800 Subject: [PATCH 30/32] update flash_stm32.h --- common_features.mk | 6 ++++++ platforms/chibios/flash_stm32.h | 5 +---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/common_features.mk b/common_features.mk index 7ff19e808425..4efde67dfdf2 100644 --- a/common_features.mk +++ b/common_features.mk @@ -197,6 +197,12 @@ else COMMON_VPATH += $(PLATFORM_PATH)/$(PLATFORM_KEY)/$(DRIVER_DIR)/eeprom SRC += eeprom_driver.c SRC += eeprom_stm32_L0_L1.c + else ifneq ($(filter $(MCU_SERIES),STM32L4xx),) + OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_STM32_FLASH_EMULATED + COMMON_VPATH += $(DRIVER_PATH)/eeprom + SRC += eeprom_driver.c + SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32_l4.c + SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c else ifneq ($(filter $(MCU_SERIES),KL2x K20x),) # Teensy EEPROM implementations OPT_DEFS += -DEEPROM_TEENSY diff --git a/platforms/chibios/flash_stm32.h b/platforms/chibios/flash_stm32.h index ed2240674c8d..97f8ea7cfe2b 100644 --- a/platforms/chibios/flash_stm32.h +++ b/platforms/chibios/flash_stm32.h @@ -34,11 +34,8 @@ typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); FLASH_Status FLASH_ErasePage(uint32_t Page_Address); -#if defined(STM32L4XX) -FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data); -#else FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data); -#endif +FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data); void FLASH_Unlock(void); void FLASH_Lock(void); From 5ab36e77b6538e57712b3edd7ae6469792e53af2 Mon Sep 17 00:00:00 2001 From: lokher Date: Tue, 8 Feb 2022 14:10:42 +0800 Subject: [PATCH 31/32] Update flash_stm32.c --- platforms/chibios/flash_stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platforms/chibios/flash_stm32.c b/platforms/chibios/flash_stm32.c index c61ef1ae76f7..6b0e59bb4a2e 100644 --- a/platforms/chibios/flash_stm32.c +++ b/platforms/chibios/flash_stm32.c @@ -213,10 +213,10 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) { if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ -#if defined(FLASH_CR_PSIZE) +# if defined(FLASH_CR_PSIZE) FLASH->CR &= ~FLASH_CR_PSIZE; FLASH->CR |= FLASH_CR_PSIZE_0; -#endif +# endif FLASH->CR |= FLASH_CR_PG; *(__IO uint16_t*)Address = Data; /* Wait for last operation to be completed */ From 08b488c22165e6299ec11d5d0a13e793cfd5914e Mon Sep 17 00:00:00 2001 From: lokher Date: Wed, 9 Feb 2022 11:24:13 +0800 Subject: [PATCH 32/32] Update flash_stm32.c --- platforms/chibios/flash_stm32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platforms/chibios/flash_stm32.c b/platforms/chibios/flash_stm32.c index 6b0e59bb4a2e..6953a3ead319 100644 --- a/platforms/chibios/flash_stm32.c +++ b/platforms/chibios/flash_stm32.c @@ -180,6 +180,8 @@ FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) { status = FLASH_WaitForLastOperation(ProgramTimeout); if (status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to program the new data */ + /* disable data cache first */ + FLASH->ACR &= ~FLASH_ACR_DCEN; FLASH->CR |= FLASH_CR_PG; *(__IO uint32_t*)Address = (uint32_t)Data; __ISB(); @@ -191,6 +193,11 @@ FLASH_Status FLASH_ProgramDoubleWord(uint32_t Address, uint64_t Data) { FLASH->CR &= ~FLASH_CR_PG; } FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR); + /* reset data cache */ + FLASH->ACR |= FLASH_ACR_DCRST; + FLASH->ACR &= ~FLASH_ACR_DCRST; + /* enable data cache */ + FLASH->ACR |= FLASH_ACR_DCEN; } } return status;