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;