Final HS60v2 changes. (#4790)

* initial commit, this now mostly works

- RGB controls work
- Dynamic keymap still broken due to eeprom
- Via works

* STM32 eeprom update

- Update EEPROM emulation library to handle 8bit data like AVR.
- This library also allows for multiple page pairs resulting in greater EEPROM size flexibility

* hs60 changes

* HS60 hhkb added

* Update keyboards/hs60/v2/config.h

Co-Authored-By: yiancar <yiangosyiangou@cytanet.com.cy>
pull/4798/head 0.6.223
yiancar 6 years ago committed by MechMerlin
parent 2c0bc5ed6b
commit 2bfac351ed

@ -24,10 +24,10 @@
#include "wait.h" #include "wait.h"
#endif #endif
#include "is31fl3733.h"
#include <string.h> #include <string.h>
#include "i2c_master.h" #include "i2c_master.h"
#include "progmem.h" #include "progmem.h"
#include "rgb_matrix.h"
// This is a 7-bit address, that gets left-shifted and bit 0 // This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol) // set to 0 for write, 1 for read (as per I2C protocol)

@ -20,9 +20,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config_common.h" #include "config_common.h"
/* USB Device descriptor parameter */ /* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED #define VENDOR_ID 0x8968
#define PRODUCT_ID 0x0258 #define PRODUCT_ID 0x4853
#define DEVICE_VER 0x0001 #define DEVICE_VER 0x0002
#define MANUFACTURER Yiancar-Designs #define MANUFACTURER Yiancar-Designs
#define PRODUCT HS60 V2 #define PRODUCT HS60 V2
#define DESCRIPTION GH60 compatible, tool free RGB keyboard #define DESCRIPTION GH60 compatible, tool free RGB keyboard
@ -39,7 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DIODE_DIRECTION COL2ROW #define DIODE_DIRECTION COL2ROW
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */ /* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
#define DEBOUNCE 0 #define DEBOUNCING_DELAY 5
/* define if matrix has ghost (lacks anti-ghosting diodes) */ /* define if matrix has ghost (lacks anti-ghosting diodes) */
//#define MATRIX_HAS_GHOST //#define MATRIX_HAS_GHOST
@ -70,48 +70,63 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
//#define FORCE_NKRO //#define FORCE_NKRO
/*
* Magic Key Options
*
* Magic keys are hotkey commands that allow control over firmware functions of
* the keyboard. They are best used in combination with the HID Listen program,
* found here: https://www.pjrc.com/teensy/hid_listen.html
*
* The options below allow the magic key functionality to be changed. This is
* useful if your keyboard/keypad is missing keys and you want magic key support.
*
*/
/* key combination for magic key command */ /* key combination for magic key command */
#define IS_COMMAND() ( \ #define IS_COMMAND() ( \
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
) )
/* /* Backlight options */
* Feature disable options
* These options are also useful to firmware size reduction.
*/
/* disable debug print */ #define RGB_BACKLIGHT_ENABLED 1
//#define NO_DEBUG
/* disable print */ #define RGB_BACKLIGHT_HS60
//#define NO_PRINT
/* Backlight options */ // they aren't really used if RGB_BACKLIGHT_HS60 defined
#define RGB_BACKLIGHT_USE_SPLIT_BACKSPACE 0
#define RGB_BACKLIGHT_USE_SPLIT_LEFT_SHIFT 0
#define RGB_BACKLIGHT_USE_SPLIT_RIGHT_SHIFT 0
#define RGB_BACKLIGHT_USE_7U_SPACEBAR 0
#define RGB_BACKLIGHT_USE_ISO_ENTER 0
#define RGB_BACKLIGHT_DISABLE_HHKB_BLOCKER_LEDS 0
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects // disable backlight when USB suspended (PC sleep/hibernate/shutdown)
#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended #define RGB_BACKLIGHT_DISABLE_WHEN_USB_SUSPENDED 0
#define RGB_MATRIX_SKIP_FRAMES 3
#define DRIVER_ADDR_1 0b1010000 // disable backlight after timeout in minutes, 0 = no timeout
#define DRIVER_ADDR_2 0b1010000 // this is here for compliancy reasons. #define RGB_BACKLIGHT_DISABLE_AFTER_TIMEOUT 0
#define DRIVER_COUNT 2 // the default effect (RGB test)
#ifdef HS60_ANSI #define RGB_BACKLIGHT_EFFECT 255
#define DRIVER_1_LED_TOTAL 61
#else
#define DRIVER_1_LED_TOTAL 62
#endif
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL #define DRIVER_COUNT 2
#define DRIVER_LED_TOTAL 64
// These define which keys in the matrix are alphas/mods
// Used for backlight effects so colors are different for
// alphas vs. mods
// Each value is for a row, bit 0 is column 0
// Alpha=0 Mod=1
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0010000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0000000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0010000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0010000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0011110000000111
// TODO: refactor with new user EEPROM code (coming soon)
#define EEPROM_MAGIC 0x451F
#define EEPROM_MAGIC_ADDR 32
// Bump this every time we change what we store
// This will automatically reset the EEPROM with defaults
// and avoid loading invalid data from the EEPROM
#define EEPROM_VERSION 0x08
#define EEPROM_VERSION_ADDR 34
// Backlight config starts after EEPROM version
#define RGB_BACKLIGHT_CONFIG_EEPROM_ADDR 35
// Dynamic keymap starts after backlight config (35+31)
#define DYNAMIC_KEYMAP_EEPROM_ADDR 66
#define DYNAMIC_KEYMAP_LAYER_COUNT 4
// Dynamic macro starts after dynamic keymaps (66+(4*5*14*2)) = (66+560)
#define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR 626
#define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE 398
#define DYNAMIC_KEYMAP_MACRO_COUNT 16

@ -19,3 +19,5 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Include overwrites for specific keymap */ /* Include overwrites for specific keymap */
#define HS60_ANSI #define HS60_ANSI
#undef PRODUCT_ID
#define PRODUCT_ID 0x4854

@ -26,11 +26,25 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1) , KC_APP, KC_RCTL), KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1) , KC_APP, KC_RCTL),
[1] = LAYOUT_60_ansi( /* FN */ [1] = LAYOUT_60_ansi( /* FN */
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL ,\ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL ,\
KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET , KC_TRNS,\ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET, KC_TRNS,\
KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, KC_TRNS,\ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, BR_DEC, BR_INC, ES_DEC, ES_INC, KC_TRNS,\
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
[2] = LAYOUT_60_ansi( /* Empty for dynamic keymaps */
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
[3] = LAYOUT_60_ansi( /* Empty for dynamic keymaps */
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
}; };
void matrix_init_user(void) { void matrix_init_user(void) {

@ -1,6 +1,6 @@
The default keymap for ANSI HS60 The default keymap for ANSI HS60 V2
================================ ===================================
![Layout image](https://imgur.com/CSyPw0J.png) ![Layout image](https://i.imgur.com/m8t5CfE.png)
Default layer is normal ANSI and Fn layer is used for RGB functions, Volume control and arrow cluster Default layer is normal ANSI and Fn layer is used for RGB functions, Volume control and arrow cluster

@ -26,11 +26,25 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1) , KC_APP, KC_RCTL), KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1) , KC_APP, KC_RCTL),
[1] = LAYOUT_60_iso( /* FN */ [1] = LAYOUT_60_iso( /* FN */
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL ,\ KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL ,\
KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET , \ KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RESET , \
KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\ KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, KC_TRNS, KC_TRNS,\ KC_TRNS, KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, BR_DEC, BR_INC, ES_DEC, ES_INC, KC_TRNS,\
KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), KC_VOLU, KC_VOLD, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
[2] = LAYOUT_60_iso( /* Empty for dynamic keymaps */
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
[3] = LAYOUT_60_iso( /* Empty for dynamic keymaps */
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
}; };
void matrix_init_user(void) { void matrix_init_user(void) {

@ -1,6 +1,6 @@
The default keymap for ISO HS60 The default keymap for ISO HS60 V2
=============================== ==================================
![Layout image](https://imgur.com/HXj4tYL.png) ![Layout image](https://imgur.com/6go4vQV.png)
Default layer is normal ISO and Fn layer is used for RGB functions, Volume control and arrow cluster Default layer is normal ISO and Fn layer is used for RGB functions, Volume control and arrow cluster

@ -19,3 +19,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Include overwrites for specific keymap */ /* Include overwrites for specific keymap */
#define HS60_HHKB #define HS60_HHKB
#undef PRODUCT_ID
#define PRODUCT_ID 0x4855
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_0
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_1
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_2
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_3
#undef RGB_BACKLIGHT_ALPHAS_MODS_ROW_4
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_0 0b0000000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_1 0b0000000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_2 0b0011000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_3 0b0011000000000001
#define RGB_BACKLIGHT_ALPHAS_MODS_ROW_4 0b0011100000000111

@ -19,18 +19,32 @@
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT_60_hhkb( /* Base */ [0] = LAYOUT_60_hhkb( /* Base */
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_GRV, KC_BSLS, \ KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_GRV, KC_BSLS,\
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC,\
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \ KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(1), \ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(1),\
KC_LCTL, KC_LGUI,KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL ), KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL ),
[1] = LAYOUT_60_hhkb( /* FN */ [1] = LAYOUT_60_hhkb( /* FN */
RESET, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,\ RESET, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, KC_TRNS,\
KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, RGB_SPI, RGB_SPD, KC_UP, KC_TRNS, KC_DEL, \ KC_TRNS, EF_DEC, EF_INC, H1_DEC, H1_INC, H2_DEC, H2_INC, BR_DEC, BR_INC, ES_DEC, ES_INC, KC_UP, KC_TRNS, KC_DEL, \
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, \ KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \ KC_TRNS, KC_TRNS, S1_DEC, S1_INC, S2_DEC, S2_INC, KC_TRNS, KC_TRNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS ) KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS ),
[2] = LAYOUT_60_hhkb( /* Empty for dynamic keymaps */
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS ),
[3] = LAYOUT_60_hhkb( /* Empty for dynamic keymaps */
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,\
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS ),
}; };
void matrix_init_user(void) { void matrix_init_user(void) {

@ -0,0 +1,6 @@
The default keymap for HHKB HS60 V2
===================================
![Layout image](https://imgur.com/usbrQWL.png)
Default layer is normal HHKB with 7U space. Fn layer is used for RGB functions, Volume control and arrow cluster

@ -139,7 +139,7 @@
#define STM32_GPT_USE_TIM1 FALSE #define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE #define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 FALSE #define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM4 FALSE #define STM32_GPT_USE_TIM4 TRUE
#define STM32_GPT_USE_TIM6 TRUE #define STM32_GPT_USE_TIM6 TRUE
#define STM32_GPT_USE_TIM7 TRUE #define STM32_GPT_USE_TIM7 TRUE
#define STM32_GPT_USE_TIM8 TRUE #define STM32_GPT_USE_TIM8 TRUE

@ -1,4 +1,9 @@
# project specific files # project specific files
SRC = keyboards/zeal60/zeal60.c \
keyboards/zeal60/rgb_backlight.c \
drivers/issi/is31fl3733.c \
quantum/color.c \
drivers/arm/i2c_master.c
## chip/board settings ## chip/board settings
# the next two should match the directories in # the next two should match the directories in
@ -44,15 +49,18 @@ DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave
# Build Options # Build Options
# comment out to disable the options. # comment out to disable the options.
# #
BACKLIGHT_ENABLE = no BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
MOUSEKEY_ENABLE = yes # Mouse keys MOUSEKEY_ENABLE = yes # Mouse keys
EXTRAKEY_ENABLE = yes # Audio control and System control EXTRAKEY_ENABLE = yes # Audio control and System control
CONSOLE_ENABLE = no # Console for debug CONSOLE_ENABLE = no # Console for debug
COMMAND_ENABLE = no # Commands for debug and configuration COMMAND_ENABLE = no # Commands for debug and configuration
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
NKRO_ENABLE = yes # USB Nkey Rollover NKRO_ENABLE = yes # USB Nkey Rollover
AUDIO_ENABLE = no AUDIO_ENABLE = no # Audio output on port C6
RGB_MATRIX_ENABLE = IS31FL3733 # Use RGB matrix
NO_USB_STARTUP_CHECK = no # Disable initialization only when usb is plugged in NO_USB_STARTUP_CHECK = no # Disable initialization only when usb is plugged in
#SERIAL_LINK_ENABLE = yes #SERIAL_LINK_ENABLE = yes
RAW_ENABLE = yes
DYNAMIC_KEYMAP_ENABLE = yes
CIE1931_CURVE = yes

@ -13,623 +13,6 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "v2.h" #ifndef RGB_BACKLIGHT_HS60
#error RGB_BACKLIGHT_M60_A not defined, recheck config.h
//#include "is31fl3733.h"
// Please ignore this is for upcoming features
/*#ifdef RAW_ENABLE
void raw_hid_receive( uint8_t *data, uint8_t length )
{
uint8_t command = data[0];
switch ( command )
{
case id_protocol_version:
{
msg_protocol_version *msg = (msg_protocol_version*)&data[1];
msg->version = PROTOCOL_VERSION;
break;
}
#if USE_KEYMAPS_IN_EEPROM
case id_keymap_keycode_load:
{
msg_keymap_keycode_load *msg = (msg_keymap_keycode_load*)&data[1];
msg->keycode = keymap_keycode_load( msg->layer, msg->row, msg->column );
break;
}
case id_keymap_keycode_save:
{
msg_keymap_keycode_save *msg = (msg_keymap_keycode_save*)&data[1];
keymap_keycode_save( msg->layer, msg->row, msg->column, msg->keycode);
break;
}
case id_keymap_default_save:
{
keymap_default_save();
break;
}
#endif // USE_KEYMAPS_IN_EEPROM
case id_backlight_config_set_values:
{
msg_backlight_config_set_values *msg = (msg_backlight_config_set_values*)&data[1];
backlight_config_set_values(msg);
backlight_config_save();
break;
}
case id_backlight_config_set_alphas_mods:
{
msg_backlight_config_set_alphas_mods *msg = (msg_backlight_config_set_alphas_mods*)&data[1];
backlight_config_set_alphas_mods( msg->alphas_mods );
backlight_config_save();
break;
}
case id_backlight_set_key_color:
{
msg_backlight_set_key_color *msg = (msg_backlight_set_key_color*)&data[1];
backlight_set_key_color(msg->row, msg->column, msg->hsv);
break;
}
case id_system_get_state:
{
msg_system_state *msg = (msg_system_state*)&data[1];
msg->value = backlight_get_tick();
break;
}
default:
{
// Unhandled message.
data[0] = id_unhandled;
break;
}
}
// Return same buffer with values changed
raw_hid_send( data, length );
}
#endif*/
#ifdef HS60_ANSI
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations
* driver
* | R location
* | | G location
* | | | B location
* | | | | */
{0, B_1, A_1, C_1}, //MX1
{0, E_1, D_1, F_1}, //MX2
{0, H_1, G_1, I_1}, //MX3
{0, K_1, J_1, L_1}, //MX4
{0, B_2, A_2, C_2}, //MX6
{0, E_2, D_2, F_2}, //MX7
{0, H_2, G_2, I_2}, //MX8
{0, K_2, J_2, L_2}, //MX14
{0, B_3, A_3, C_3}, //MX11
{0, E_3, D_3, F_3}, //MX12
{0, H_3, G_3, I_3}, //MX13
{0, K_3, J_3, L_3}, //MX19
{0, B_4, A_4, C_4}, //MX16
{0, E_4, D_4, F_4}, //MX17
{0, H_4, G_4, I_4}, //MX18
{0, K_4, J_4, L_4}, //MX23
{0, B_5, A_5, C_5}, //MX20
{0, E_5, D_5, F_5}, //MX21
{0, H_5, G_5, I_5}, //MX22
{0, K_5, J_5, L_5}, //MX27
{0, B_6, A_6, C_6}, //MX24
{0, E_6, D_6, F_6}, //MX25
{0, H_6, G_6, I_6}, //MX26
{0, K_6, J_6, L_6}, //MX31
{0, B_7, A_7, C_7}, //MX28
{0, E_7, D_7, F_7}, //MX29
{0, H_7, G_7, I_7}, //MX30
{0, K_7, J_7, L_7}, //MX36
{0, B_8, A_8, C_8}, //MX33
{0, E_8, D_8, F_8}, //MX34
{0, H_8, G_8, I_8}, //MX35
{0, K_8, J_8, L_8}, //MX40
{0, B_9, A_9, C_9}, //MX37
{0, E_9, D_9, F_9}, //MX38
{0, H_9, G_9, I_9}, //MX39
{0, K_9, J_9, L_9}, //MX44
{0, B_10, A_10, C_10}, //MX41
{0, E_10, D_10, F_10}, //MX42
{0, H_10, G_10, I_10}, //MX43
{0, K_10, J_10, L_10}, //MX48
{0, B_11, A_11, C_11}, //MX45
{0, E_11, D_11, F_11}, //MX46
{0, H_11, G_11, I_11}, //MX47
{0, K_11, J_11, L_11}, //MX53
{0, B_12, A_12, C_12}, //MX50
{0, E_12, D_12, F_12}, //MX51
{0, H_12, G_12, I_12}, //MX52
{0, B_13, A_13, C_13}, //MX55
{0, E_13, D_13, F_13}, //MX56
{0, K_13, J_13, L_13}, //MX61
{0, B_14, A_14, C_14}, //MX59
{0, E_14, D_14, F_14}, //MX57
{0, H_14, G_14, I_14}, //MX60
{0, K_14, J_14, L_14}, //MX62
{0, B_15, A_15, C_15}, //MX5
{0, E_15, D_15, F_15}, //MX10
{0, H_15, G_15, I_15}, //MX15
{0, K_15, J_15, L_15}, //MX32
{0, E_16, D_16, F_16}, //MX49
{0, H_16, G_16, I_16}, //MX54
{0, K_16, J_16, L_16}, //MX58
};
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
//
// MX1, MX6, MX11, MX16, MX20, MX24, MX28, MX33, MX37, MX41, MX45, MX50, MX55, MX59,
// MX2, MX7, MX12, MX17, MX21, MX25, MX29, MX34, MX38, MX42, MX46, MX51, MX56, ---,
// MX3, MX8, MX13, MX18, MX22, MX26, MX30, MX35, MX39, MX43, MX47, MX52, MX57, MX60,
// MX4, ---, MX14, MX19, MX23, MX27, MX31, MX36, MX40, MX44, MX48, MX53, ---, MX61,
// MX5, MX10, MX15, ---, ---, ---, MX32, ---, ---, ---, MX49, MX54, MX58, MX62
/* {row | col << 4}
* | {x=0..224, y=0..64}
* | | modifier
* | | | */
{{0|(0<<4)}, { 0, 0}, 1}, //MX1
{{1|(0<<4)}, { 0, 16}, 1}, //MX2
{{2|(0<<4)}, { 0, 32}, 1}, //MX3
{{3|(0<<4)}, { 0, 48}, 1}, //MX4
{{0|(1<<4)}, { 17, 0}, 0}, //MX6
{{1|(1<<4)}, { 17, 16}, 0}, //MX7
{{2|(1<<4)}, { 17, 32}, 0}, //MX8
{{3|(2<<4)}, { 34, 48}, 0}, //MX14
{{0|(2<<4)}, { 34, 0}, 0}, //MX11
{{1|(2<<4)}, { 34, 16}, 0}, //MX12
{{2|(2<<4)}, { 34, 32}, 0}, //MX13
{{3|(3<<4)}, { 51, 48}, 0}, //MX19
{{0|(3<<4)}, { 51, 0}, 0}, //MX16
{{1|(3<<4)}, { 51, 16}, 0}, //MX17
{{2|(3<<4)}, { 51, 32}, 0}, //MX18
{{3|(4<<4)}, { 68, 48}, 0}, //MX23
{{0|(4<<4)}, { 68, 0}, 0}, //MX20
{{1|(4<<4)}, { 68, 16}, 0}, //MX21
{{2|(4<<4)}, { 68, 32}, 0}, //MX22
{{3|(5<<4)}, { 85, 48}, 0}, //MX27
{{0|(5<<4)}, { 85, 0}, 0}, //MX24
{{1|(5<<4)}, { 85, 16}, 0}, //MX25
{{2|(5<<4)}, { 85, 32}, 0}, //MX26
{{3|(6<<4)}, {102, 48}, 0}, //MX31
{{0|(6<<4)}, {102, 0}, 0}, //MX28
{{1|(6<<4)}, {102, 16}, 0}, //MX29
{{2|(6<<4)}, {102, 32}, 0}, //MX30
{{3|(7<<4)}, {119, 48}, 0}, //MX36
{{0|(7<<4)}, {119, 0}, 0}, //MX33
{{1|(7<<4)}, {119, 16}, 0}, //MX34
{{2|(7<<4)}, {119, 32}, 0}, //MX35
{{3|(8<<4)}, {136, 48}, 0}, //MX40
{{0|(8<<4)}, {136, 0}, 0}, //MX37
{{1|(8<<4)}, {136, 16}, 0}, //MX38
{{2|(8<<4)}, {136, 32}, 0}, //MX39
{{3|(9<<4)}, {153, 48}, 0}, //MX44
{{0|(9<<4)}, {153, 0}, 0}, //MX41
{{1|(9<<4)}, {153, 16}, 0}, //MX42
{{2|(9<<4)}, {153, 32}, 0}, //MX43
{{3|(10<<4)}, {170, 48}, 0}, //MX48
{{0|(10<<4)}, {170, 0}, 0}, //MX45
{{1|(10<<4)}, {170, 16}, 0}, //MX46
{{2|(10<<4)}, {170, 32}, 0}, //MX47
{{3|(11<<4)}, {187, 48}, 0}, //MX53
{{0|(11<<4)}, {187, 0}, 0}, //MX50
{{1|(11<<4)}, {187, 16}, 0}, //MX51
{{2|(11<<4)}, {187, 32}, 0}, //MX52
{{0|(12<<4)}, {204, 0}, 0}, //MX55
{{1|(12<<4)}, {204, 16}, 0}, //MX56
{{3|(13<<4)}, {221, 48}, 1}, //MX61
{{0|(13<<4)}, {221, 0}, 1}, //MX59
{{2|(12<<4)}, {221, 16}, 0}, //MX57
{{2|(13<<4)}, {221, 32}, 1}, //MX60
{{4|(13<<4)}, {221, 64}, 1}, //MX62
{{4|(0<<4)}, { 0, 64}, 1}, //MX5
{{4|(1<<4)}, { 17, 64}, 1}, //MX10
{{4|(2<<4)}, { 34, 64}, 1}, //MX15
{{4|(5<<4)}, {102, 64}, 0}, //MX32
{{4|(10<<4)}, {170, 64}, 1}, //MX49
{{4|(11<<4)}, {187, 64}, 1}, //MX54
{{4|(12<<4)}, {204, 64}, 1} //MX58
};
#elif defined(HS60_HHKB)
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations
* driver
* | R location
* | | G location
* | | | B location
* | | | | */
{0, B_1, A_1, C_1}, //MX1
{0, E_1, D_1, F_1}, //MX2
{0, H_1, G_1, I_1}, //MX3
{0, K_1, J_1, L_1}, //MX4
{0, B_2, A_2, C_2}, //MX6
{0, E_2, D_2, F_2}, //MX7
{0, H_2, G_2, I_2}, //MX8
{0, K_2, J_2, L_2}, //MX14
{0, B_3, A_3, C_3}, //MX11
{0, E_3, D_3, F_3}, //MX12
{0, H_3, G_3, I_3}, //MX13
{0, K_3, J_3, L_3}, //MX19
{0, B_4, A_4, C_4}, //MX16
{0, E_4, D_4, F_4}, //MX17
{0, H_4, G_4, I_4}, //MX18
{0, K_4, J_4, L_4}, //MX23
{0, B_5, A_5, C_5}, //MX20
{0, E_5, D_5, F_5}, //MX21
{0, H_5, G_5, I_5}, //MX22
{0, K_5, J_5, L_5}, //MX27
{0, B_6, A_6, C_6}, //MX24
{0, E_6, D_6, F_6}, //MX25
{0, H_6, G_6, I_6}, //MX26
{0, K_6, J_6, L_6}, //MX31
{0, B_7, A_7, C_7}, //MX28
{0, E_7, D_7, F_7}, //MX29
{0, H_7, G_7, I_7}, //MX30
{0, K_7, J_7, L_7}, //MX36
{0, B_8, A_8, C_8}, //MX33
{0, E_8, D_8, F_8}, //MX34
{0, H_8, G_8, I_8}, //MX35
{0, K_8, J_8, L_8}, //MX40
{0, B_9, A_9, C_9}, //MX37
{0, E_9, D_9, F_9}, //MX38
{0, H_9, G_9, I_9}, //MX39
{0, K_9, J_9, L_9}, //MX44
{0, B_10, A_10, C_10}, //MX41
{0, E_10, D_10, F_10}, //MX42
{0, H_10, G_10, I_10}, //MX43
{0, K_10, J_10, L_10}, //MX48
{0, B_11, A_11, C_11}, //MX45
{0, E_11, D_11, F_11}, //MX46
{0, H_11, G_11, I_11}, //MX47
{0, K_11, J_11, L_11}, //MX53
{0, B_12, A_12, C_12}, //MX50
{0, E_12, D_12, F_12}, //MX51
{0, H_12, G_12, I_12}, //MX52
{0, K_12, J_12, L_12}, //MX64
{0, B_13, A_13, C_13}, //MX55
{0, E_13, D_13, F_13}, //MX56
{0, H_13, G_13, I_13}, //MX63
{0, K_13, J_13, L_13}, //MX61
{0, B_14, A_14, C_14}, //MX59
{0, E_14, D_14, F_14}, //MX57
{0, H_14, G_14, I_14}, //MX60
{0, K_14, J_14, L_14}, //MX62
{0, B_15, A_15, C_15}, //MX5
{0, E_15, D_15, F_15}, //MX10
{0, H_15, G_15, I_15}, //MX15
{0, K_15, J_15, L_15}, //MX32
{0, H_16, G_16, I_16}, //MX54
{0, K_16, J_16, L_16}, //MX58
};
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
//
// MX1, MX6, MX11, MX16, MX20, MX24, MX28, MX33, MX37, MX41, MX45, MX50, MX55, MX59,
// MX2, MX7, MX12, MX17, MX21, MX25, MX29, MX34, MX38, MX42, MX46, MX51, MX56, MX64,
// MX3, MX8, MX13, MX18, MX22, MX26, MX30, MX35, MX39, MX43, MX47, MX52, MX57, MX60,
// MX4, ----, MX14, MX19, MX23, MX27, MX31, MX36, MX40, MX44, MX48, MX53, MX63, MX61,
// MX5, MX10, MX15, ----, ----, ----, MX32, ----, ---, ----, ----, MX54, MX58, MX62
/* {row | col << 4}
* | {x=0..224, y=0..64}
* | | modifier
* | | | */
{{0|(0<<4)}, { 0, 0}, 1}, //MX1
{{1|(0<<4)}, { 0, 16}, 1}, //MX2
{{2|(0<<4)}, { 0, 32}, 1}, //MX3
{{3|(0<<4)}, { 0, 48}, 1}, //MX4
{{0|(1<<4)}, { 17, 0}, 0}, //MX6
{{1|(1<<4)}, { 17, 16}, 0}, //MX7
{{2|(1<<4)}, { 17, 32}, 0}, //MX8
{{3|(2<<4)}, { 34, 48}, 0}, //MX14
{{0|(2<<4)}, { 34, 0}, 0}, //MX11
{{1|(2<<4)}, { 34, 16}, 0}, //MX12
{{2|(2<<4)}, { 34, 32}, 0}, //MX13
{{3|(3<<4)}, { 51, 48}, 0}, //MX19
{{0|(3<<4)}, { 51, 0}, 0}, //MX16
{{1|(3<<4)}, { 51, 16}, 0}, //MX17
{{2|(3<<4)}, { 51, 32}, 0}, //MX18
{{3|(4<<4)}, { 68, 48}, 0}, //MX23
{{0|(4<<4)}, { 68, 0}, 0}, //MX20
{{1|(4<<4)}, { 68, 16}, 0}, //MX21
{{2|(4<<4)}, { 68, 32}, 0}, //MX22
{{3|(5<<4)}, { 85, 48}, 0}, //MX27
{{0|(5<<4)}, { 85, 0}, 0}, //MX24
{{1|(5<<4)}, { 85, 16}, 0}, //MX25
{{2|(5<<4)}, { 85, 32}, 0}, //MX26
{{3|(6<<4)}, {102, 48}, 0}, //MX31
{{0|(6<<4)}, {102, 0}, 0}, //MX28
{{1|(6<<4)}, {102, 16}, 0}, //MX29
{{2|(6<<4)}, {102, 32}, 0}, //MX30
{{3|(7<<4)}, {119, 48}, 0}, //MX36
{{0|(7<<4)}, {119, 0}, 0}, //MX33
{{1|(7<<4)}, {119, 16}, 0}, //MX34
{{2|(7<<4)}, {119, 32}, 0}, //MX35
{{3|(8<<4)}, {136, 48}, 0}, //MX40
{{0|(8<<4)}, {136, 0}, 0}, //MX37
{{1|(8<<4)}, {136, 16}, 0}, //MX38
{{2|(8<<4)}, {136, 32}, 0}, //MX39
{{3|(9<<4)}, {153, 48}, 0}, //MX44
{{0|(9<<4)}, {153, 0}, 0}, //MX41
{{1|(9<<4)}, {153, 16}, 0}, //MX42
{{2|(9<<4)}, {153, 32}, 0}, //MX43
{{3|(10<<4)}, {170, 48}, 0}, //MX48
{{0|(10<<4)}, {170, 0}, 0}, //MX45
{{1|(10<<4)}, {170, 16}, 0}, //MX46
{{2|(10<<4)}, {170, 32}, 0}, //MX47
{{3|(11<<4)}, {187, 48}, 0}, //MX53
{{0|(11<<4)}, {187, 0}, 0}, //MX50
{{1|(11<<4)}, {187, 16}, 0}, //MX51
{{2|(11<<4)}, {187, 32}, 0}, //MX52
{{1|(13<<4)}, {221, 0}, 1}, //MX64
{{0|(12<<4)}, {204, 0}, 0}, //MX55
{{1|(12<<4)}, {204, 16}, 0}, //MX56
{{3|(12<<4)}, {204, 48}, 0}, //MX63
{{3|(13<<4)}, {212, 48}, 1}, //MX61
{{0|(13<<4)}, {221, 0}, 0}, //MX59
{{2|(12<<4)}, {221, 16}, 0}, //MX57
{{2|(13<<4)}, {221, 32}, 1}, //MX60
{{4|(13<<4)}, {221, 64}, 1}, //MX62
{{4|(0<<4)}, { 0, 64}, 1}, //MX5
{{4|(1<<4)}, { 17, 64}, 1}, //MX10
{{4|(2<<4)}, { 34, 64}, 1}, //MX15
{{4|(5<<4)}, {102, 64}, 0}, //MX32
{{4|(11<<4)}, {187, 64}, 1}, //MX54
{{4|(12<<4)}, {204, 64}, 1} //MX58
};
#else //ISO layout
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations
* driver
* | R location
* | | G location
* | | | B location
* | | | | */
{0, B_1, A_1, C_1}, //MX1
{0, E_1, D_1, F_1}, //MX2
{0, H_1, G_1, I_1}, //MX3
{0, K_1, J_1, L_1}, //MX4
{0, B_2, A_2, C_2}, //MX6
{0, E_2, D_2, F_2}, //MX7
{0, H_2, G_2, I_2}, //MX8
{0, K_2, J_2, L_2}, //MX14
{0, B_3, A_3, C_3}, //MX11
{0, E_3, D_3, F_3}, //MX12
{0, H_3, G_3, I_3}, //MX13
{0, K_3, J_3, L_3}, //MX19
{0, B_4, A_4, C_4}, //MX16
{0, E_4, D_4, F_4}, //MX17
{0, H_4, G_4, I_4}, //MX18
{0, K_4, J_4, L_4}, //MX23
{0, B_5, A_5, C_5}, //MX20
{0, E_5, D_5, F_5}, //MX21
{0, H_5, G_5, I_5}, //MX22
{0, K_5, J_5, L_5}, //MX27
{0, B_6, A_6, C_6}, //MX24
{0, E_6, D_6, F_6}, //MX25
{0, H_6, G_6, I_6}, //MX26
{0, K_6, J_6, L_6}, //MX31
{0, B_7, A_7, C_7}, //MX28
{0, E_7, D_7, F_7}, //MX29
{0, H_7, G_7, I_7}, //MX30
{0, K_7, J_7, L_7}, //MX36
{0, B_8, A_8, C_8}, //MX33
{0, E_8, D_8, F_8}, //MX34
{0, H_8, G_8, I_8}, //MX35
{0, K_8, J_8, L_8}, //MX40
{0, B_9, A_9, C_9}, //MX37
{0, E_9, D_9, F_9}, //MX38
{0, H_9, G_9, I_9}, //MX39
{0, K_9, J_9, L_9}, //MX44
{0, B_10, A_10, C_10}, //MX41
{0, E_10, D_10, F_10}, //MX42
{0, H_10, G_10, I_10}, //MX43
{0, K_10, J_10, L_10}, //MX48
{0, B_11, A_11, C_11}, //MX45
{0, E_11, D_11, F_11}, //MX46
{0, H_11, G_11, I_11}, //MX47
{0, K_11, J_11, L_11}, //MX53
{0, B_12, A_12, C_12}, //MX50
{0, E_12, D_12, F_12}, //MX51
{0, H_12, G_12, I_12}, //MX52
{0, K_12, J_12, L_12}, //MX9
{0, B_13, A_13, C_13}, //MX55
{0, E_13, D_13, F_13}, //MX56
{0, K_13, J_13, L_13}, //MX61
{0, B_14, A_14, C_14}, //MX59
{0, E_14, D_14, F_14}, //MX57
{0, H_14, G_14, I_14}, //MX60
{0, K_14, J_14, L_14}, //MX62
{0, B_15, A_15, C_15}, //MX5
{0, E_15, D_15, F_15}, //MX10
{0, H_15, G_15, I_15}, //MX15
{0, K_15, J_15, L_15}, //MX32
{0, E_16, D_16, F_16}, //MX49
{0, H_16, G_16, I_16}, //MX54
{0, K_16, J_16, L_16}, //MX58
};
const rgb_led g_rgb_leds[DRIVER_LED_TOTAL] = {
//
// MX1, MX6, MX11, MX16, MX20, MX24, MX28, MX33, MX37, MX41, MX45, MX50, MX55, MX59,
// MX2, MX7, MX12, MX17, MX21, MX25, MX29, MX34, MX38, MX42, MX46, MX51, MX56, ---,
// MX3, MX8, MX13, MX18, MX22, MX26, MX30, MX35, MX39, MX43, MX47, MX52, MX57, MX60,
// MX4, ---, MX14, MX19, MX23, MX27, MX31, MX36, MX40, MX44, MX48, MX53, ---, MX61,
// MX5, MX10, MX15, ---, ---, ---, MX32, ---, ---, ---, MX49, MX54, MX58, MX62
/* {row | col << 4}
* | {x=0..224, y=0..64}
* | | modifier
* | | | */
{{0|(0<<4)}, { 0, 0}, 1}, //MX1
{{1|(0<<4)}, { 0, 16}, 1}, //MX2
{{2|(0<<4)}, { 0, 32}, 1}, //MX3
{{3|(0<<4)}, { 0, 48}, 1}, //MX4
{{0|(1<<4)}, { 17, 0}, 0}, //MX6
{{1|(1<<4)}, { 17, 16}, 0}, //MX7
{{2|(1<<4)}, { 17, 32}, 0}, //MX8
{{3|(2<<4)}, { 34, 48}, 0}, //MX14
{{0|(2<<4)}, { 34, 0}, 0}, //MX11
{{1|(2<<4)}, { 34, 16}, 0}, //MX12
{{2|(2<<4)}, { 34, 32}, 0}, //MX13
{{3|(3<<4)}, { 51, 48}, 0}, //MX19
{{0|(3<<4)}, { 51, 0}, 0}, //MX16
{{1|(3<<4)}, { 51, 16}, 0}, //MX17
{{2|(3<<4)}, { 51, 32}, 0}, //MX18
{{3|(4<<4)}, { 68, 48}, 0}, //MX23
{{0|(4<<4)}, { 68, 0}, 0}, //MX20
{{1|(4<<4)}, { 68, 16}, 0}, //MX21
{{2|(4<<4)}, { 68, 32}, 0}, //MX22
{{3|(5<<4)}, { 85, 48}, 0}, //MX27
{{0|(5<<4)}, { 85, 0}, 0}, //MX24
{{1|(5<<4)}, { 85, 16}, 0}, //MX25
{{2|(5<<4)}, { 85, 32}, 0}, //MX26
{{3|(6<<4)}, {102, 48}, 0}, //MX31
{{0|(6<<4)}, {102, 0}, 0}, //MX28
{{1|(6<<4)}, {102, 16}, 0}, //MX29
{{2|(6<<4)}, {102, 32}, 0}, //MX30
{{3|(7<<4)}, {119, 48}, 0}, //MX36
{{0|(7<<4)}, {119, 0}, 0}, //MX33
{{1|(7<<4)}, {119, 16}, 0}, //MX34
{{2|(7<<4)}, {119, 32}, 0}, //MX35
{{3|(8<<4)}, {136, 48}, 0}, //MX40
{{0|(8<<4)}, {136, 0}, 0}, //MX37
{{1|(8<<4)}, {136, 16}, 0}, //MX38
{{2|(8<<4)}, {136, 32}, 0}, //MX39
{{3|(9<<4)}, {153, 48}, 0}, //MX44
{{0|(9<<4)}, {153, 0}, 0}, //MX41
{{1|(9<<4)}, {153, 16}, 0}, //MX42
{{2|(9<<4)}, {153, 32}, 0}, //MX43
{{3|(10<<4)}, {170, 48}, 0}, //MX48
{{0|(10<<4)}, {170, 0}, 0}, //MX45
{{1|(10<<4)}, {170, 16}, 0}, //MX46
{{2|(10<<4)}, {170, 32}, 0}, //MX47
{{3|(11<<4)}, {187, 48}, 0}, //MX53
{{0|(11<<4)}, {187, 0}, 0}, //MX50
{{1|(11<<4)}, {187, 16}, 0}, //MX51
{{2|(11<<4)}, {187, 32}, 0}, //MX52
{{3|(2<<4)}, { 17, 32}, 1}, //MX9
{{0|(12<<4)}, {204, 0}, 0}, //MX55
{{1|(12<<4)}, {204, 16}, 0}, //MX56
{{3|(13<<4)}, {221, 48}, 1}, //MX61
{{0|(13<<4)}, {221, 0}, 1}, //MX59
{{2|(12<<4)}, {204, 32}, 0}, //MX57
{{2|(13<<4)}, {221, 24}, 1}, //MX60
{{4|(13<<4)}, {221, 64}, 1}, //MX62
{{4|(0<<4)}, { 0, 64}, 1}, //MX5
{{4|(1<<4)}, { 17, 64}, 1}, //MX10
{{4|(2<<4)}, { 34, 64}, 1}, //MX15
{{4|(5<<4)}, {102, 64}, 0}, //MX32
{{4|(10<<4)}, {170, 64}, 1}, //MX49
{{4|(11<<4)}, {187, 64}, 1}, //MX54
{{4|(12<<4)}, {204, 64}, 1} //MX58
};
#endif #endif
void bootmagic_lite(void)
{
// The lite version of TMK's bootmagic made by Wilba.
// 100% less potential for accidentally making the
// keyboard do stupid things.
// We need multiple scans because debouncing can't be turned off.
matrix_scan();
wait_ms(10);
matrix_scan();
// If the Esc and space bar are held down on power up,
// reset the EEPROM valid state and jump to bootloader.
// Assumes Esc is at [0,0] and spacebar is at [4,6].
// This isn't very generalized, but we need something that doesn't
// rely on user's keymaps in firmware or EEPROM.
if ( ( matrix_get_row(0) & (1<<0) ) &&
( matrix_get_row(4) & (1<<6) ) )
{
// Set the TMK/QMK EEPROM state as invalid.
eeconfig_disable();
//eeprom_set_valid(false);
// Jump to bootloader.
bootloader_jump();
}
}
void matrix_init_kb(void) {
// put your keyboard start-up code here
// runs once when the firmware starts up
bootmagic_lite();
// Please ignore this is for upcoming features
// If the EEPROM has the magic, the data is good.
// OK to load from EEPROM.
/*if (eeprom_is_valid())
{
backlight_config_load();
// TODO: do something to "turn on" keymaps in EEPROM?
}
else
{
// If the EEPROM has not been saved before, or is out of date,
// save the default values to the EEPROM. Default values
// come from construction of the zeal_backlight_config instance.
backlight_config_save();
// Clear the LED colors stored in EEPROM
for ( int row=0; row < MATRIX_ROWS; row++ )
{
HSV hsv;
for ( int column=0; column < MATRIX_COLS; column++ )
{
hsv.h = rand() & 0xFF;
hsv.s = rand() & 0x7F;
hsv.v = 255;
backlight_set_key_color( row, column, hsv );
}
}
#ifdef USE_KEYMAPS_IN_EEPROM
keymap_default_save();
#endif
// Save the magic number last, in case saving was interrupted
eeprom_set_valid(true);
}*/
matrix_init_user();
}
void matrix_scan_kb(void) {
matrix_scan_user();
}
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
return process_record_user(keycode, record);
}
void led_set_kb(uint8_t usb_led) {
//backlight_set_indicator_state(usb_led);
}

@ -13,12 +13,13 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef HS60_H #pragma once
#define HS60_H
#define XXX KC_NO #define XXX KC_NO
#include "quantum.h" #include "quantum.h"
#include "../../zeal60/rgb_backlight_keycodes.h"
#include "../../zeal60/zeal60_keycodes.h"
// This a shortcut to help you visually see your layout. // This a shortcut to help you visually see your layout.
@ -63,5 +64,3 @@
{ K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \
{ K40, K41, K42, XXX, XXX, XXX, K46, XXX, XXX, XXX, XXX, K4B, K4C, K4D } \ { K40, K41, K42, XXX, XXX, XXX, K46, XXX, XXX, XXX, XXX, K4B, K4C, K4D } \
} }
#endif

@ -15,27 +15,44 @@
*/ */
#if RGB_BACKLIGHT_ENABLED #if RGB_BACKLIGHT_ENABLED
#if defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_ZEAL65) || defined (RGB_BACKLIGHT_M60_A) || defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_KOYU) #if defined (RGB_BACKLIGHT_ZEAL60) || defined (RGB_BACKLIGHT_ZEAL65) || defined (RGB_BACKLIGHT_M60_A) || defined(RGB_BACKLIGHT_M6_B) || defined(RGB_BACKLIGHT_KOYU) || defined(RGB_BACKLIGHT_HS60)
#else #else
#error None of the following was defined: RGB_BACKLIGHT_ZEAL60, RGB_BACKLIGHT_ZEAL65, RGB_BACKLIGHT_M60_A, RGB_BACKLIGHT_M6_B, RGB_BACKLIGHT_KOYU #error None of the following was defined: RGB_BACKLIGHT_ZEAL60, RGB_BACKLIGHT_ZEAL65, RGB_BACKLIGHT_M60_A, RGB_BACKLIGHT_M6_B, RGB_BACKLIGHT_KOYU
#endif #endif
#ifndef MAX
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#endif
#ifndef MIN
#define MIN(a,b) ((a) < (b)? (a): (b))
#endif
#include "quantum.h" #include "quantum.h"
#include "rgb_backlight.h" #include "rgb_backlight.h"
#include "rgb_backlight_api.h" #include "rgb_backlight_api.h"
#include "rgb_backlight_keycodes.h" #include "rgb_backlight_keycodes.h"
#if !defined(RGB_BACKLIGHT_HS60)
#include <avr/io.h> #include <avr/io.h>
#include <util/delay.h> #include <util/delay.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "drivers/avr/i2c_master.h"
#else
#include "ch.h"
#include "hal.h"
#include "drivers/arm/i2c_master.h"
#include "tmk_core/common/eeprom.h"
#endif
#include "progmem.h" #include "progmem.h"
#include "quantum/color.h" #include "quantum/color.h"
#include "drivers/avr/i2c_master.h"
#if defined (RGB_BACKLIGHT_M6_B) #if defined (RGB_BACKLIGHT_M6_B)
#include "drivers/issi/is31fl3218.h" #include "drivers/issi/is31fl3218.h"
#define BACKLIGHT_LED_COUNT 6 #define BACKLIGHT_LED_COUNT 6
#elif defined (RGB_BACKLIGHT_HS60)
#include "drivers/issi/is31fl3733.h"
#define BACKLIGHT_LED_COUNT 64
#else #else
#include "drivers/issi/is31fl3731.h" #include "drivers/issi/is31fl3731.h"
#define BACKLIGHT_LED_COUNT 72 #define BACKLIGHT_LED_COUNT 72
@ -84,7 +101,88 @@ uint8_t g_key_hit[BACKLIGHT_LED_COUNT];
// Ticks since any key was last hit. // Ticks since any key was last hit.
uint32_t g_any_key_hit = 0; uint32_t g_any_key_hit = 0;
#if !defined(RGB_BACKLIGHT_M6_B) #if defined(RGB_BACKLIGHT_HS60)
// This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol)
// ADDR_2 is not needed. it is here as a dummy
#define ISSI_ADDR_1 0x50
#define ISSI_ADDR_2 0x50
const is31_led g_is31_leds[DRIVER_LED_TOTAL] = {
/* Refer to IS31 manual for these locations
* driver
* | R location
* | | G location
* | | | B location
* | | | | */
{0, B_1, A_1, C_1}, //LA1
{0, E_1, D_1, F_1}, //LA2
{0, H_1, G_1, I_1}, //LA3
{0, K_1, J_1, L_1}, //LA4
{0, B_2, A_2, C_2}, //LA5
{0, E_2, D_2, F_2}, //LA6
{0, H_2, G_2, I_2}, //LA7
{0, K_2, J_2, L_2}, //LA8
{0, B_3, A_3, C_3}, //LA9
{0, E_3, D_3, F_3}, //LA10
{0, H_3, G_3, I_3}, //LA11
{0, K_3, J_3, L_3}, //LA12
{0, B_4, A_4, C_4}, //LA13
{0, E_4, D_4, F_4}, //LA14
{0, H_4, G_4, I_4}, //LA15
{0, K_4, J_4, L_4}, //LA16
{0, B_5, A_5, C_5}, //LA17
{0, E_5, D_5, F_5}, //LA18
{0, H_5, G_5, I_5}, //LA19
{0, K_5, J_5, L_5}, //LA20
{0, B_6, A_6, C_6}, //LA21
{0, E_6, D_6, F_6}, //LA22
{0, H_6, G_6, I_6}, //LA23
{0, K_6, J_6, L_6}, //LA24
{0, B_7, A_7, C_7}, //LA25
{0, E_7, D_7, F_7}, //LA26
{0, H_7, G_7, I_7}, //LA27
{0, K_7, J_7, L_7}, //LA28
{0, B_8, A_8, C_8}, //LA29
{0, E_8, D_8, F_8}, //LA30
{0, H_8, G_8, I_8}, //LA31
{0, K_8, J_8, L_8}, //LA32
{0, B_9, A_9, C_9}, //LA33
{0, E_9, D_9, F_9}, //LA34
{0, H_9, G_9, I_9}, //LA35
{0, K_9, J_9, L_9}, //LA36
{0, B_10, A_10, C_10}, //LA37
{0, E_10, D_10, F_10}, //LA38
{0, H_10, G_10, I_10}, //LA39
{0, K_10, J_10, L_10}, //LA40
{0, B_11, A_11, C_11}, //LA41
{0, E_11, D_11, F_11}, //LA42
{0, H_11, G_11, I_11}, //LA43
{0, K_11, J_11, L_11}, //LA44
{0, B_12, A_12, C_12}, //LA45
{0, E_12, D_12, F_12}, //LA46
{0, H_12, G_12, I_12}, //LA47
{0, K_12, J_12, L_12}, //LA48
{0, B_13, A_13, C_13}, //LA49
{0, E_13, D_13, F_13}, //LA50
{0, H_13, G_13, I_13}, //LA51
{0, K_13, J_13, L_13}, //LA52
{0, B_14, A_14, C_14}, //LA53
{0, E_14, D_14, F_14}, //LA54
{0, H_14, G_14, I_14}, //LA55
{0, K_14, J_14, L_14}, //LA56
{0, B_15, A_15, C_15}, //LA57
{0, E_15, D_15, F_15}, //LA58
{0, H_15, G_15, I_15}, //LA59
{0, K_15, J_15, L_15}, //LA60
{0, B_16, A_16, C_16}, //LA61
{0, E_16, D_16, F_16}, //LA62
{0, H_16, G_16, I_16}, //LA63
{0, K_16, J_16, L_16}, //LA64
};
#elif !defined(RGB_BACKLIGHT_M6_B)
// This is a 7-bit address, that gets left-shifted and bit 0 // This is a 7-bit address, that gets left-shifted and bit 0
// set to 0 for write, 1 for read (as per I2C protocol) // set to 0 for write, 1 for read (as per I2C protocol)
#define ISSI_ADDR_1 0x74 #define ISSI_ADDR_1 0x74
@ -272,6 +370,85 @@ const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
{0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {255,233}, {228,201}, {235,255}, {237,255}, {0,27}, {0,64}, {0,101}, {0,137}, {0,174}, {255,233}, {228,201}, {235,255}, {237,255},
{195,128}, {206,136}, {215,152}, {222,175}, {205,234}, {209,255}, {214,255}, {219,255}, {223,255} {195,128}, {206,136}, {215,152}, {222,175}, {205,234}, {209,255}, {214,255}, {219,255}, {223,255}
}; };
#elif defined (RGB_BACKLIGHT_HS60) && defined (HS60_ANSI)
const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
// LA1..LA47
{0,0}, {4,16}, {6,32}, {10,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48},
{48,0}, {56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48},
{96,0}, {104,16}, {108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32},
{148,48}, {144,0}, {152,16}, {156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32},
{255,255},// LA48 does not exist, dummy
// LA49..LA50
{192,0}, {200,16},
{255,255},// LA51 does not exit, dummy
// LA52..LA60
{210,48}, {216,0}, {220,16}, {214,32}, {222,64}, {2,64}, {22,64}, {42,64}, {102,64},
{255,255},// LA61 does not exit, dummy
{162,64}, {182,64}, {202,64}
};
const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
// LA1..LA47
{96,255}, {109,255}, {128,242}, {148,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188},
{85,255}, {96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131},
{70,255}, {70,129}, {129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152},
{53,255}, {39,157}, {255,101}, {222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174},
{255,255},// LA48 does not exist, dummy
// LA49..LA50
{39,255}, {23,238},
{255,255},// LA51 does not exit, dummy
// LA52..LA60
{235,255}, {33,255}, {19,255}, {255,233}, {224,255}, {160,255}, {164,255}, {169,255}, {188,255},
{255,255},// LA61 does not exit, dummy
{209,255}, {215,255}, {220,255}
};
#elif defined (RGB_BACKLIGHT_HS60) && defined (HS60_HHKB)
const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
// LA1..LA60
{0,0}, {4,16}, {6,32}, {10,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48},
{48,0}, {56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48},
{96,0}, {104,16}, {108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32},
{148,48}, {144,0}, {152,16}, {156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32},
{224,0}, {192,0}, {200,16}, {202,48}, {224,48}, {208,0}, {220,16}, {214,32}, {220,64}, {4,64}, {24,64}, {44,64}, {112,64},
{255,255}, {255,255}, // LA61..LA62 does not exit, dummy
// LA63..LA64
{180,64}, {200,64}
};
const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
// LA1..LA60
{96,255}, {109,255}, {128,242}, {148,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188},
{85,255}, {96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131},
{70,255}, {70,129}, {129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152},
{53,255}, {39,157}, {255,101}, {222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174}, {32,255},
{39,255}, {23,238}, {233,242}, {237,255}, {35,255}, {19,255}, {255,233}, {223,255}, {161,255}, {165,255}, {170,255}, {192,255},
{255,255}, {255,255}, // LA61..LA62 does not exit, dummy
// LA63..LA64
{214,255}, {219,255}
};
#elif defined (RGB_BACKLIGHT_HS60) //HS60_ISO
const Point g_map_led_to_point[BACKLIGHT_LED_COUNT] PROGMEM = {
// LA1..LA50
{0,0}, {4,16}, {6,32}, {2,48}, {16,0}, {24,16}, {28,32}, {36,48}, {32,0}, {40,16}, {44,32}, {52,48}, {48,0},
{56,16}, {60,32}, {68,48}, {64,0}, {72,16}, {76,32}, {84,48}, {80,0}, {88,16}, {92,32}, {100,48}, {96,0}, {104,16},
{108,32}, {116,48}, {112,0}, {120,16}, {124,32}, {132,48}, {128,0}, {136,16}, {140,32}, {148,48}, {144,0}, {152,16},
{156,32}, {164,48}, {160,0}, {168,16}, {172,32}, {180,48}, {176,0}, {184, 16}, {188,32}, {20,48}, {192,0}, {200,16},
{255,255},// LA51 does not exit, dummy
// LA52..LA60
{210,48}, {216,0}, {220,16}, {222,24}, {222,64}, {2,64}, {22,64}, {42,64}, {102,64},
{255,255},// LA61 does not exit, dummy
{162,64}, {182,64}, {202,64}
};
const Point g_map_led_to_point_polar[BACKLIGHT_LED_COUNT] PROGMEM = {
// LA1..LA50
{96,255}, {109,255}, {128,242}, {147,255}, {93,255}, {105,238}, {128,192}, {154,216}, {89,255}, {101,208}, {128,155}, {159,188}, {85,255},
{96,181}, {128,119}, {165,163}, {81,255}, {89,157}, {128,82}, {173,143}, {75,255}, {81,139}, {128,46}, {183,131}, {70,255}, {70,129},
{129,9}, {195,128}, {64,255}, {58,129}, {255,27}, {206,136}, {58,255}, {47,139}, {255,64}, {215,152}, {53,255}, {39,157}, {255,101},
{222,175}, {47,255}, {32,181}, {255,137}, {228,201}, {43,255}, {27,208}, {255, 174}, {150,246}, {39,255}, {23,238},
{255,255},// LA51 does not exit, dummy
// LA52..LA60
{235,255}, {33,255}, {19,255}, {10,255}, {224,255}, {160,255}, {164,255}, {169,255}, {188,255},
{255,255},// LA61 does not exit, dummy
{209,255}, {215,255}, {220,255}
};
#elif defined (RGB_BACKLIGHT_M6_B) #elif defined (RGB_BACKLIGHT_M6_B)
// M6-B is really simple: // M6-B is really simple:
// 0 3 5 // 0 3 5
@ -397,6 +574,48 @@ const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
{ 36+16, 36+15, 36+5, 36+4, 36+3, 36+2, 36+1, 54+9, 54+10, 54+11, 54+12, 54+6, 54+7, 54+8 }, { 36+16, 36+15, 36+5, 36+4, 36+3, 36+2, 36+1, 54+9, 54+10, 54+11, 54+12, 54+6, 54+7, 54+8 },
{ 36+17, 36+8, 36+7, 36+6, 255, 255, 255, 36+0, 255, 54+13, 54+14, 54+15, 54+16, 54+17 } { 36+17, 36+8, 36+7, 36+6, 255, 255, 255, 36+0, 255, 54+13, 54+14, 54+15, 54+16, 54+17 }
}; };
#elif defined (RGB_BACKLIGHT_HS60) && defined (HS60_ANSI)
//
// LA1, LA5, LA9, LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53,
// LA2, LA6, LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50, ---,
// LA3, LA7, LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,
// LA4, ---, LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44, ---, LA52,
// LA57, LA58, LA59, ---, ---, ---, LA60, ---, ---, ---, LA62, LA63, LA64, LA56
const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
{ 1-1, 5-1, 9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1 },
{ 2-1, 6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1, 255 },
{ 3-1, 7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1 },
{ 4-1, 255, 8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1, 255, 52-1 },
{ 57-1, 58-1, 59-1, 255, 255, 255, 60-1, 255, 255, 255, 62-1, 63-1, 64-1, 56-1 }
};
#elif defined (RGB_BACKLIGHT_HS60) && defined (HS60_HHKB)
//
// LA1, LA5, LA9, LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53,
// LA2, LA6, LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50, LA48,
// LA3, LA7, LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,
// LA4, ---, LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44, LA51, LA52,
// LA57, LA58, LA59, ---, ---, ---, LA60, ---, ---, ---, ---, LA63, LA64, LA56
const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
{ 1-1, 5-1, 9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1 },
{ 2-1, 6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1, 48-1 },
{ 3-1, 7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1 },
{ 4-1, 255, 8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1, 51-1, 52-1 },
{ 57-1, 58-1, 59-1, 255, 255, 255, 60-1, 255, 255, 255, 255, 63-1, 64-1, 56-1 }
};
#elif defined (RGB_BACKLIGHT_HS60) //HS60_ISO
//
// LA1, LA5, LA9, LA13, LA17, LA21, LA25, LA29, LA33, LA37, LA41, LA45, LA49, LA53,
// LA2, LA6, LA10, LA14, LA18, LA22, LA26, LA30, LA34, LA38, LA42, LA46, LA50, ---,
// LA3, LA7, LA11, LA15, LA19, LA23, LA27, LA31, LA35, LA39, LA43, LA47, LA54, LA55,
// LA4, LA48, LA8, LA12, LA16, LA20, LA24, LA28, LA32, LA36, LA40, LA44, ---, LA52,
// LA57, LA58, LA59, ---, ---, ---, LA60, ---, ---, ---, LA62, LA63, LA64, LA56
const uint8_t g_map_row_column_to_led[MATRIX_ROWS][MATRIX_COLS] PROGMEM = {
{ 1-1, 5-1, 9-1, 13-1, 17-1, 21-1, 25-1, 29-1, 33-1, 37-1, 41-1, 45-1, 49-1, 53-1 },
{ 2-1, 6-1, 10-1, 14-1, 18-1, 22-1, 26-1, 30-1, 34-1, 38-1, 42-1, 46-1, 50-1, 255 },
{ 3-1, 7-1, 11-1, 15-1, 19-1, 23-1, 27-1, 31-1, 35-1, 39-1, 43-1, 47-1, 54-1, 55-1 },
{ 4-1, 48-1, 8-1, 12-1, 16-1, 20-1, 24-1, 28-1, 32-1, 36-1, 40-1, 44-1, 255, 52-1 },
{ 57-1, 58-1, 59-1, 255, 255, 255, 60-1, 255, 255, 255, 62-1, 63-1, 64-1, 56-1 }
};
#elif defined (RGB_BACKLIGHT_M6_B) #elif defined (RGB_BACKLIGHT_M6_B)
// M6-B is really simple: // M6-B is really simple:
// 0 3 5 // 0 3 5
@ -419,6 +638,9 @@ void backlight_update_pwm_buffers(void)
{ {
#if defined (RGB_BACKLIGHT_M6_B) #if defined (RGB_BACKLIGHT_M6_B)
IS31FL3218_update_pwm_buffers(); IS31FL3218_update_pwm_buffers();
#elif defined (RGB_BACKLIGHT_HS60)
IS31FL3733_update_pwm_buffers( ISSI_ADDR_1, ISSI_ADDR_2 );
IS31FL3733_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
#else #else
IS31FL3731_update_pwm_buffers( ISSI_ADDR_1, ISSI_ADDR_2 ); IS31FL3731_update_pwm_buffers( ISSI_ADDR_1, ISSI_ADDR_2 );
IS31FL3731_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 ); IS31FL3731_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
@ -429,6 +651,8 @@ void backlight_set_color( int index, uint8_t red, uint8_t green, uint8_t blue )
{ {
#if defined (RGB_BACKLIGHT_M6_B) #if defined (RGB_BACKLIGHT_M6_B)
IS31FL3218_set_color( index, red, green, blue ); IS31FL3218_set_color( index, red, green, blue );
#elif defined (RGB_BACKLIGHT_HS60)
IS31FL3733_set_color( index, red, green, blue );
#else #else
IS31FL3731_set_color( index, red, green, blue ); IS31FL3731_set_color( index, red, green, blue );
#endif #endif
@ -438,6 +662,8 @@ void backlight_set_color_all( uint8_t red, uint8_t green, uint8_t blue )
{ {
#if defined (RGB_BACKLIGHT_M6_B) #if defined (RGB_BACKLIGHT_M6_B)
IS31FL3218_set_color_all( red, green, blue ); IS31FL3218_set_color_all( red, green, blue );
#elif defined (RGB_BACKLIGHT_HS60)
IS31FL3733_set_color_all( red, green, blue );
#else #else
IS31FL3731_set_color_all( red, green, blue ); IS31FL3731_set_color_all( red, green, blue );
#endif #endif
@ -452,6 +678,7 @@ void backlight_set_key_hit(uint8_t row, uint8_t column)
g_any_key_hit = 0; g_any_key_hit = 0;
} }
#if !defined(RGB_BACKLIGHT_HS60)
// This is (F_CPU/1024) / 20 Hz // This is (F_CPU/1024) / 20 Hz
// = 15625 Hz / 20 Hz // = 15625 Hz / 20 Hz
// = 781 // = 781
@ -487,6 +714,29 @@ void backlight_timer_disable(void)
{ {
TIMSK3 &= ~_BV(OCIE3A); TIMSK3 &= ~_BV(OCIE3A);
} }
#else //STM32, use GPT with TIM4. Enable in halconf.h
static void gpt_backlight_timer_task(GPTDriver *gptp);
// Timer setup at 200Khz, callback at 10k ticks = 20Hz
static GPTConfig gpt4cfg1 = {
.frequency = 200000U,
.callback = gpt_backlight_timer_task
};
void backlight_timer_init(void)
{
gptStart(&GPTD4, &gpt4cfg1);
}
void backlight_timer_enable(void)
{
gptStartContinuous(&GPTD4, 10000);
}
void backlight_timer_disable(void)
{
gptStopTimer(&GPTD4);
}
#endif //!defined(RGB_BACKLIGHT_HS60)
void backlight_set_suspend_state(bool state) void backlight_set_suspend_state(bool state)
{ {
@ -921,7 +1171,11 @@ void backlight_effect_indicators(void)
} }
} }
#if !defined(RGB_BACKLIGHT_HS60)
ISR(TIMER3_COMPA_vect) ISR(TIMER3_COMPA_vect)
#else //STM32 interrupt
static void gpt_backlight_timer_task(GPTDriver *gptp)
#endif
{ {
// delay 1 second before driving LEDs or doing anything else // delay 1 second before driving LEDs or doing anything else
static uint8_t startup_tick = 0; static uint8_t startup_tick = 0;
@ -1378,6 +1632,27 @@ void backlight_init_drivers(void)
#if defined(RGB_BACKLIGHT_M6_B) #if defined(RGB_BACKLIGHT_M6_B)
IS31FL3218_init(); IS31FL3218_init();
#elif defined(RGB_BACKLIGHT_HS60)
IS31FL3733_init( ISSI_ADDR_1 );
for ( int index = 0; index < BACKLIGHT_LED_COUNT; index++ )
{
#if defined (HS60_ANSI)
bool enabled = !( ( index == 48-1 ) || //LA48
( index == 51-1 ) || //LA51
( index == 61-1 ) ); //LA61
#elif defined (HS60_HHKB)
bool enabled = !( ( index == 61-1 ) || //LA61
( index == 62-1 ) ); //LA62
#else //HS60_ISO
bool enabled = !( ( index == 51-1 ) || //LA51
( index == 61-1 ) ); //LA61
#endif
// This only caches it for later
IS31FL3733_set_led_control_register( index, enabled, enabled, enabled );
}
// This actually updates the LED drivers
IS31FL3733_update_led_control_registers( ISSI_ADDR_1, ISSI_ADDR_2 );
#else #else
IS31FL3731_init( ISSI_ADDR_1 ); IS31FL3731_init( ISSI_ADDR_1 );
IS31FL3731_init( ISSI_ADDR_2 ); IS31FL3731_init( ISSI_ADDR_2 );
@ -1668,7 +1943,6 @@ void backlight_test_led( uint8_t index, bool red, bool green, bool blue )
} }
} }
} }
#endif // defined(RGB_DEBUGGING_ONLY)
void backlight_debug_led( bool state ) void backlight_debug_led( bool state )
{ {
@ -1685,5 +1959,6 @@ void backlight_debug_led( bool state )
PORTE &= ~(1<<6); PORTE &= ~(1<<6);
} }
} }
#endif // defined(RGB_DEBUGGING_ONLY)
#endif // BACKLIGHT_ENABLED #endif // BACKLIGHT_ENABLED

@ -10,664 +10,206 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
* This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by
* https://github.com/leaflabs/libmaple * Artur F.
* *
* Modifications for QMK and STM32F303 by Yiancar * Modifications for QMK and STM32F303 by Yiancar
*/ */
#include <stdio.h>
#include <string.h>
#include "eeprom_stm32.h" #include "eeprom_stm32.h"
/*****************************************************************************
* Allows to use the internal flash to store non volatile data. To initialize
* the functionality use the EEPROM_Init() function. Be sure that by reprogramming
* of the controller just affected pages will be deleted. In other case the non
* volatile data will be lost.
******************************************************************************/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Functions -----------------------------------------------------------------*/
uint8_t DataBuf[FEE_PAGE_SIZE];
/*****************************************************************************
* Delete Flash Space used for user Data, deletes the whole space between
* RW_PAGE_BASE_ADDRESS and the last uC Flash Page
******************************************************************************/
uint16_t EEPROM_Init(void) {
// unlock flash
FLASH_Unlock();
FLASH_Status EE_ErasePage(uint32_t); // Clear Flags
//FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR);
uint16_t EE_CheckPage(uint32_t, uint16_t);
uint16_t EE_CheckErasePage(uint32_t, uint16_t);
uint16_t EE_Format(void);
uint32_t EE_FindValidPage(void);
uint16_t EE_GetVariablesCount(uint32_t, uint16_t);
uint16_t EE_PageTransfer(uint32_t, uint32_t, uint16_t);
uint16_t EE_VerifyPageFullWriteVariable(uint16_t, uint16_t);
uint32_t PageBase0 = EEPROM_PAGE0_BASE;
uint32_t PageBase1 = EEPROM_PAGE1_BASE;
uint32_t PageSize = EEPROM_PAGE_SIZE;
uint16_t Status = EEPROM_NOT_INIT;
// See http://www.st.com/web/en/resource/technical/document/application_note/CD00165693.pdf
/**
* @brief Check page for blank
* @param page base address
* @retval Success or error
* EEPROM_BAD_FLASH: page not empty after erase
* EEPROM_OK: page blank
*/
uint16_t EE_CheckPage(uint32_t pageBase, uint16_t status)
{
uint32_t pageEnd = pageBase + (uint32_t)PageSize;
// Page Status not EEPROM_ERASED and not a "state"
if ((*(__IO uint16_t*)pageBase) != EEPROM_ERASED && (*(__IO uint16_t*)pageBase) != status)
return EEPROM_BAD_FLASH;
for(pageBase += 4; pageBase < pageEnd; pageBase += 4)
if ((*(__IO uint32_t*)pageBase) != 0xFFFFFFFF) // Verify if slot is empty
return EEPROM_BAD_FLASH;
return EEPROM_OK;
}
/**
* @brief Erase page with increment erase counter (page + 2)
* @param page base address
* @retval Success or error
* FLASH_COMPLETE: success erase
* - Flash error code: on write Flash error
*/
FLASH_Status EE_ErasePage(uint32_t pageBase)
{
FLASH_Status FlashStatus;
uint16_t data = (*(__IO uint16_t*)(pageBase));
if ((data == EEPROM_ERASED) || (data == EEPROM_VALID_PAGE) || (data == EEPROM_RECEIVE_DATA))
data = (*(__IO uint16_t*)(pageBase + 2)) + 1;
else
data = 0;
FlashStatus = FLASH_ErasePage(pageBase);
if (FlashStatus == FLASH_COMPLETE)
FlashStatus = FLASH_ProgramHalfWord(pageBase + 2, data);
return FlashStatus; return FEE_DENSITY_BYTES;
} }
/*****************************************************************************
* Erase the whole reserved Flash Space used for user Data
******************************************************************************/
void EEPROM_Erase (void) {
/** int page_num = 0;
* @brief Check page for blank and erase it
* @param page base address // delete all pages from specified start page to the last page
* @retval Success or error do {
* - Flash error code: on write Flash error FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page_num * FEE_PAGE_SIZE));
* - EEPROM_BAD_FLASH: page not empty after erase page_num++;
* - EEPROM_OK: page blank } while (page_num < FEE_DENSITY_PAGES);
*/
uint16_t EE_CheckErasePage(uint32_t pageBase, uint16_t status)
{
uint16_t FlashStatus;
if (EE_CheckPage(pageBase, status) != EEPROM_OK)
{
FlashStatus = EE_ErasePage(pageBase);
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
return EE_CheckPage(pageBase, status);
}
return EEPROM_OK;
} }
/*****************************************************************************
* Writes once data byte to flash on specified address. If a byte is already
* written, the whole page must be copied to a buffer, the byte changed and
* the manipulated buffer written after PageErase.
*******************************************************************************/
uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) {
/** FLASH_Status FlashStatus = FLASH_COMPLETE;
* @brief Find valid Page for write or read operation
* @param Page0: Page0 base address
* Page1: Page1 base address
* @retval Valid page address (PAGE0 or PAGE1) or NULL in case of no valid page was found
*/
uint32_t EE_FindValidPage(void)
{
uint16_t status0 = (*(__IO uint16_t*)PageBase0); // Get Page0 actual status
uint16_t status1 = (*(__IO uint16_t*)PageBase1); // Get Page1 actual status
if (status0 == EEPROM_VALID_PAGE && status1 == EEPROM_ERASED) uint32_t page;
return PageBase0; int i;
if (status1 == EEPROM_VALID_PAGE && status0 == EEPROM_ERASED)
return PageBase1;
// exit if desired address is above the limit (e.G. under 2048 Bytes for 4 pages)
if (Address > FEE_DENSITY_BYTES) {
return 0; return 0;
}
/**
* @brief Calculate unique variables in EEPROM
* @param start: address of first slot to check (page + 4)
* @param end: page end address
* @param address: 16 bit virtual address of the variable to excluse (or 0XFFFF)
* @retval count of variables
*/
uint16_t EE_GetVariablesCount(uint32_t pageBase, uint16_t skipAddress)
{
uint16_t varAddress, nextAddress;
uint32_t idx;
uint32_t pageEnd = pageBase + (uint32_t)PageSize;
uint16_t count = 0;
for (pageBase += 6; pageBase < pageEnd; pageBase += 4)
{
varAddress = (*(__IO uint16_t*)pageBase);
if (varAddress == 0xFFFF || varAddress == skipAddress)
continue;
count++;
for(idx = pageBase + 4; idx < pageEnd; idx += 4)
{
nextAddress = (*(__IO uint16_t*)idx);
if (nextAddress == varAddress)
{
count--;
break;
} }
}
}
return count;
}
/** // calculate which page is affected (Pagenum1/Pagenum2...PagenumN)
* @brief Transfers last updated variables data from the full Page to an empty one. page = (FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address)) & 0x00000FFF;
* @param newPage: new page base address
* @param oldPage: old page base address
* @param SkipAddress: 16 bit virtual address of the variable (or 0xFFFF)
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - EEPROM_OUT_SIZE: if valid new page is full
* - Flash error code: on write Flash error
*/
uint16_t EE_PageTransfer(uint32_t newPage, uint32_t oldPage, uint16_t SkipAddress)
{
uint32_t oldEnd, newEnd;
uint32_t oldIdx, newIdx, idx;
uint16_t address, data, found;
FLASH_Status FlashStatus;
// Transfer process: transfer variables from old to the new active page
newEnd = newPage + ((uint32_t)PageSize);
// Find first free element in new page
for (newIdx = newPage + 4; newIdx < newEnd; newIdx += 4)
if ((*(__IO uint32_t*)newIdx) == 0xFFFFFFFF) // Verify if element
break; // contents are 0xFFFFFFFF
if (newIdx >= newEnd)
return EEPROM_OUT_SIZE;
oldEnd = oldPage + 4;
oldIdx = oldPage + (uint32_t)(PageSize - 2);
for (; oldIdx > oldEnd; oldIdx -= 4)
{
address = *(__IO uint16_t*)oldIdx;
if (address == 0xFFFF || address == SkipAddress)
continue; // it's means that power off after write data
found = 0;
for (idx = newPage + 6; idx < newIdx; idx += 4)
if ((*(__IO uint16_t*)(idx)) == address)
{
found = 1;
break;
}
if (found) if (page % FEE_PAGE_SIZE) page = page + FEE_PAGE_SIZE;
continue; page = (page / FEE_PAGE_SIZE) - 1;
if (newIdx < newEnd) // if current data is 0xFF, the byte is empty, just overwrite with the new one
{ if ((*(__IO uint16_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) == FEE_EMPTY_WORD) {
data = (*(__IO uint16_t*)(oldIdx - 2));
FlashStatus = FLASH_ProgramHalfWord(newIdx, data);
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
FlashStatus = FLASH_ProgramHalfWord(newIdx + 2, address); FlashStatus = FLASH_ProgramHalfWord(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address), (uint16_t)(0x00FF & DataByte));
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
newIdx += 4;
}
else
return EEPROM_OUT_SIZE;
} }
else {
// Erase the old Page: Set old Page status to EEPROM_EEPROM_ERASED status // Copy Page to a buffer
data = EE_CheckErasePage(oldPage, EEPROM_ERASED); memcpy(DataBuf, (uint8_t*)FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE), FEE_PAGE_SIZE); // !!! Calculate base address for the desired page
if (data != EEPROM_OK)
return data;
// Set new Page status // check if new data is differ to current data, return if not, proceed if yes
FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_VALID_PAGE); if (DataByte == *(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) {
if (FlashStatus != FLASH_COMPLETE) return 0;
return FlashStatus;
return EEPROM_OK;
}
/**
* @brief Verify if active page is full and Writes variable in EEPROM.
* @param Address: 16 bit virtual address of the variable
* @param Data: 16 bit data to be written as variable value
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - EEPROM_PAGE_FULL: if valid page is full (need page transfer)
* - EEPROM_NO_VALID_PAGE: if no valid page was found
* - EEPROM_OUT_SIZE: if EEPROM size exceeded
* - Flash error code: on write Flash error
*/
uint16_t EE_VerifyPageFullWriteVariable(uint16_t Address, uint16_t Data)
{
FLASH_Status FlashStatus;
uint32_t idx, pageBase, pageEnd, newPage;
uint16_t count;
// Get valid Page for write operation
pageBase = EE_FindValidPage();
if (pageBase == 0)
return EEPROM_NO_VALID_PAGE;
// Get the valid Page end Address
pageEnd = pageBase + PageSize; // Set end of page
for (idx = pageEnd - 2; idx > pageBase; idx -= 4)
{
if ((*(__IO uint16_t*)idx) == Address) // Find last value for address
{
count = (*(__IO uint16_t*)(idx - 2)); // Read last data
if (count == Data)
return EEPROM_OK;
if (count == 0xFFFF)
{
FlashStatus = FLASH_ProgramHalfWord(idx - 2, Data); // Set variable data
if (FlashStatus == FLASH_COMPLETE)
return EEPROM_OK;
}
break;
}
}
// Check each active page address starting from begining
for (idx = pageBase + 4; idx < pageEnd; idx += 4)
if ((*(__IO uint32_t*)idx) == 0xFFFFFFFF) // Verify if element
{ // contents are 0xFFFFFFFF
FlashStatus = FLASH_ProgramHalfWord(idx, Data); // Set variable data
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
FlashStatus = FLASH_ProgramHalfWord(idx + 2, Address); // Set variable virtual address
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
return EEPROM_OK;
} }
// Empty slot not found, need page transfer // manipulate desired data byte in temp data array if new byte is differ to the current
// Calculate unique variables in page DataBuf[FEE_ADDR_OFFSET(Address)] = DataByte;
count = EE_GetVariablesCount(pageBase, Address) + 1;
if (count >= (PageSize / 4 - 1))
return EEPROM_OUT_SIZE;
if (pageBase == PageBase1)
newPage = PageBase0; // New page address where variable will be moved to
else
newPage = PageBase1;
// Set the new Page status to RECEIVE_DATA status
FlashStatus = FLASH_ProgramHalfWord(newPage, EEPROM_RECEIVE_DATA);
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
// Write the variable passed as parameter in the new active page
FlashStatus = FLASH_ProgramHalfWord(newPage + 4, Data);
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
FlashStatus = FLASH_ProgramHalfWord(newPage + 6, Address);
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
return EE_PageTransfer(newPage, pageBase, Address);
}
/*EEPROMClass::EEPROMClass(void)
{
PageBase0 = EEPROM_PAGE0_BASE;
PageBase1 = EEPROM_PAGE1_BASE;
PageSize = EEPROM_PAGE_SIZE;
Status = EEPROM_NOT_INIT;
}*/
/*
uint16_t EEPROM_init(uint32_t pageBase0, uint32_t pageBase1, uint32_t pageSize)
{
PageBase0 = pageBase0;
PageBase1 = pageBase1;
PageSize = pageSize;
return EEPROM_init();
}*/
uint16_t EEPROM_init(void)
{
uint16_t status0 = 6, status1 = 6;
FLASH_Status FlashStatus;
FLASH_Unlock();
Status = EEPROM_NO_VALID_PAGE;
status0 = (*(__IO uint16_t *)PageBase0); //Erase Page
status1 = (*(__IO uint16_t *)PageBase1); FlashStatus = FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + page);
switch (status0) // Write new data (whole page) to flash if data has beed changed
{ for(i = 0; i < (FEE_PAGE_SIZE / 2); i++) {
/* if ((__IO uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]) != 0xFFFF) {
Page0 Page1 FlashStatus = FLASH_ProgramHalfWord((FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)) + (i * 2), (uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]));
----- -----
EEPROM_ERASED EEPROM_VALID_PAGE Page1 valid, Page0 erased
EEPROM_RECEIVE_DATA Page1 need set to valid, Page0 erased
EEPROM_ERASED make EE_Format
any Error: EEPROM_NO_VALID_PAGE
*/
case EEPROM_ERASED:
if (status1 == EEPROM_VALID_PAGE) // Page0 erased, Page1 valid
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
else if (status1 == EEPROM_RECEIVE_DATA) // Page0 erased, Page1 receive
{
FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
if (FlashStatus != FLASH_COMPLETE)
Status = FlashStatus;
else
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
}
else if (status1 == EEPROM_ERASED) // Both in erased state so format EEPROM
Status = EEPROM_format();
break;
/*
Page0 Page1
----- -----
EEPROM_RECEIVE_DATA EEPROM_VALID_PAGE Transfer Page1 to Page0
EEPROM_ERASED Page0 need set to valid, Page1 erased
any EEPROM_NO_VALID_PAGE
*/
case EEPROM_RECEIVE_DATA:
if (status1 == EEPROM_VALID_PAGE) // Page0 receive, Page1 valid
Status = EE_PageTransfer(PageBase0, PageBase1, 0xFFFF);
else if (status1 == EEPROM_ERASED) // Page0 receive, Page1 erased
{
Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
if (Status == EEPROM_OK)
{
FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
if (FlashStatus != FLASH_COMPLETE)
Status = FlashStatus;
else
Status = EEPROM_OK;
}
}
break;
/*
Page0 Page1
----- -----
EEPROM_VALID_PAGE EEPROM_VALID_PAGE Error: EEPROM_NO_VALID_PAGE
EEPROM_RECEIVE_DATA Transfer Page0 to Page1
any Page0 valid, Page1 erased
*/
case EEPROM_VALID_PAGE:
if (status1 == EEPROM_VALID_PAGE) // Both pages valid
Status = EEPROM_NO_VALID_PAGE;
else if (status1 == EEPROM_RECEIVE_DATA)
Status = EE_PageTransfer(PageBase1, PageBase0, 0xFFFF);
else
Status = EE_CheckErasePage(PageBase1, EEPROM_ERASED);
break;
/*
Page0 Page1
----- -----
any EEPROM_VALID_PAGE Page1 valid, Page0 erased
EEPROM_RECEIVE_DATA Page1 valid, Page0 erased
any EEPROM_NO_VALID_PAGE
*/
default:
if (status1 == EEPROM_VALID_PAGE)
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED); // Check/Erase Page0
else if (status1 == EEPROM_RECEIVE_DATA)
{
FlashStatus = FLASH_ProgramHalfWord(PageBase1, EEPROM_VALID_PAGE);
if (FlashStatus != FLASH_COMPLETE)
Status = FlashStatus;
else
Status = EE_CheckErasePage(PageBase0, EEPROM_ERASED);
}
break;
} }
return Status;
}
/**
* @brief Erases PAGE0 and PAGE1 and writes EEPROM_VALID_PAGE / 0 header to PAGE0
* @param PAGE0 and PAGE1 base addresses
* @retval Status of the last operation (Flash write or erase) done during EEPROM formating
*/
uint16_t EEPROM_format(void)
{
uint16_t status;
FLASH_Status FlashStatus;
FLASH_Unlock();
// Erase Page0
status = EE_CheckErasePage(PageBase0, EEPROM_VALID_PAGE);
if (status != EEPROM_OK)
return status;
if ((*(__IO uint16_t*)PageBase0) == EEPROM_ERASED)
{
// Set Page0 as valid page: Write VALID_PAGE at Page0 base address
FlashStatus = FLASH_ProgramHalfWord(PageBase0, EEPROM_VALID_PAGE);
if (FlashStatus != FLASH_COMPLETE)
return FlashStatus;
} }
// Erase Page1
return EE_CheckErasePage(PageBase1, EEPROM_ERASED);
}
/**
* @brief Returns the erase counter for current page
* @param Data: Global variable contains the read variable value
* @retval Success or error status:
* - EEPROM_OK: if erases counter return.
* - EEPROM_NO_VALID_PAGE: if no valid page was found.
*/
uint16_t EEPROM_erases(uint16_t *Erases)
{
uint32_t pageBase;
if (Status != EEPROM_OK)
if (EEPROM_init() != EEPROM_OK)
return Status;
// Get active Page for read operation
pageBase = EE_FindValidPage();
if (pageBase == 0)
return EEPROM_NO_VALID_PAGE;
*Erases = (*(__IO uint16_t*)pageBase+2);
return EEPROM_OK;
}
/**
* @brief Returns the last stored variable data, if found,
* which correspond to the passed virtual address
* @param Address: Variable virtual address
* @retval Data for variable or EEPROM_DEFAULT_DATA, if any errors
*/
/*
uint16_t EEPROM_read (uint16_t Address)
{
uint16_t data;
EEPROM_read(Address, &data);
return data;
}*/
/**
* @brief Returns the last stored variable data, if found,
* which correspond to the passed virtual address
* @param Address: Variable virtual address
* @param Data: Pointer to data variable
* @retval Success or error status:
* - EEPROM_OK: if variable was found
* - EEPROM_BAD_ADDRESS: if the variable was not found
* - EEPROM_NO_VALID_PAGE: if no valid page was found.
*/
uint16_t EEPROM_read(uint16_t Address, uint16_t *Data)
{
uint32_t pageBase, pageEnd;
// Set default data (empty EEPROM)
*Data = EEPROM_DEFAULT_DATA;
if (Status == EEPROM_NOT_INIT)
if (EEPROM_init() != EEPROM_OK)
return Status;
// Get active Page for read operation
pageBase = EE_FindValidPage();
if (pageBase == 0)
return EEPROM_NO_VALID_PAGE;
// Get the valid Page end Address
pageEnd = pageBase + ((uint32_t)(PageSize - 2));
// Check each active page address starting from end
for (pageBase += 6; pageEnd >= pageBase; pageEnd -= 4)
if ((*(__IO uint16_t*)pageEnd) == Address) // Compare the read address with the virtual address
{
*Data = (*(__IO uint16_t*)(pageEnd - 2)); // Get content of Address-2 which is variable value
return EEPROM_OK;
} }
return FlashStatus;
// Return ReadStatus value: (0: variable exist, 1: variable doesn't exist)
return EEPROM_BAD_ADDRESS;
}
/**
* @brief Writes/upadtes variable data in EEPROM.
* @param VirtAddress: Variable virtual address
* @param Data: 16 bit data to be written
* @retval Success or error status:
* - FLASH_COMPLETE: on success
* - EEPROM_BAD_ADDRESS: if address = 0xFFFF
* - EEPROM_PAGE_FULL: if valid page is full
* - EEPROM_NO_VALID_PAGE: if no valid page was found
* - EEPROM_OUT_SIZE: if no empty EEPROM variables
* - Flash error code: on write Flash error
*/
uint16_t EEPROM_write(uint16_t Address, uint16_t Data)
{
if (Status == EEPROM_NOT_INIT)
if (EEPROM_init() != EEPROM_OK)
return Status;
if (Address == 0xFFFF)
return EEPROM_BAD_ADDRESS;
// Write the variable virtual address and value in the EEPROM
uint16_t status = EE_VerifyPageFullWriteVariable(Address, Data);
return status;
}
/**
* @brief Writes/upadtes variable data in EEPROM.
The value is written only if differs from the one already saved at the same address.
* @param VirtAddress: Variable virtual address
* @param Data: 16 bit data to be written
* @retval Success or error status:
* - EEPROM_SAME_VALUE: If new Data matches existing EEPROM Data
* - FLASH_COMPLETE: on success
* - EEPROM_BAD_ADDRESS: if address = 0xFFFF
* - EEPROM_PAGE_FULL: if valid page is full
* - EEPROM_NO_VALID_PAGE: if no valid page was found
* - EEPROM_OUT_SIZE: if no empty EEPROM variables
* - Flash error code: on write Flash error
*/
uint16_t EEPROM_update(uint16_t Address, uint16_t Data)
{
uint16_t temp;
EEPROM_read(Address, &temp);
if (temp == Data)
return EEPROM_SAME_VALUE;
else
return EEPROM_write(Address, Data);
} }
/*****************************************************************************
* Read once data byte from a specified address.
*******************************************************************************/
uint8_t EEPROM_ReadDataByte (uint16_t Address) {
/** uint8_t DataByte = 0xFF;
* @brief Return number of variable
* @retval Number of variables
*/
uint16_t EEPROM_count(uint16_t *Count)
{
if (Status == EEPROM_NOT_INIT)
if (EEPROM_init() != EEPROM_OK)
return Status;
// Get valid Page for write operation
uint32_t pageBase = EE_FindValidPage();
if (pageBase == 0)
return EEPROM_NO_VALID_PAGE; // No valid page, return max. numbers
*Count = EE_GetVariablesCount(pageBase, 0xFFFF); // Get Byte from specified address
return EEPROM_OK; DataByte = (*(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address)));
}
uint16_t EEPROM_maxcount(void) return DataByte;
{
return ((PageSize / 4)-1);
} }
/*****************************************************************************
* Wrap library in AVR style functions.
*******************************************************************************/
uint8_t eeprom_read_byte (const uint8_t *Address) uint8_t eeprom_read_byte (const uint8_t *Address)
{ {
const uint16_t p = (const uint32_t) Address; const uint16_t p = (const uint32_t) Address;
uint16_t temp; return EEPROM_ReadDataByte(p);
EEPROM_read(p, &temp);
return (uint8_t) temp;
} }
void eeprom_write_byte (uint8_t *Address, uint8_t Value) void eeprom_write_byte (uint8_t *Address, uint8_t Value)
{ {
uint16_t p = (uint32_t) Address; uint16_t p = (uint32_t) Address;
EEPROM_write(p, (uint16_t) Value); EEPROM_WriteDataByte(p, Value);
} }
void eeprom_update_byte (uint8_t *Address, uint8_t Value) void eeprom_update_byte (uint8_t *Address, uint8_t Value)
{ {
uint16_t p = (uint32_t) Address; uint16_t p = (uint32_t) Address;
EEPROM_update(p, (uint16_t) Value); EEPROM_WriteDataByte(p, Value);
} }
uint16_t eeprom_read_word (const uint16_t *Address) uint16_t eeprom_read_word (const uint16_t *Address)
{ {
const uint16_t p = (const uint32_t) Address; const uint16_t p = (const uint32_t) Address;
uint16_t temp; return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8);
EEPROM_read(p, &temp);
return temp;
} }
void eeprom_write_word (uint16_t *Address, uint16_t Value) void eeprom_write_word (uint16_t *Address, uint16_t Value)
{ {
uint16_t p = (uint32_t) Address; uint16_t p = (uint32_t) Address;
EEPROM_write(p, Value); EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8));
} }
void eeprom_update_word (uint16_t *Address, uint16_t Value) void eeprom_update_word (uint16_t *Address, uint16_t Value)
{ {
uint16_t p = (uint32_t) Address; uint16_t p = (uint32_t) Address;
EEPROM_update(p, Value); EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8));
} }
uint32_t eeprom_read_dword (const uint32_t *Address) uint32_t eeprom_read_dword (const uint32_t *Address)
{ {
const uint16_t p = (const uint32_t) Address; const uint16_t p = (const uint32_t) Address;
uint16_t temp1, temp2; return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8)
EEPROM_read(p, &temp1); | (EEPROM_ReadDataByte(p+2) << 16) | (EEPROM_ReadDataByte(p+3) << 24);
EEPROM_read(p + 1, &temp2);
return temp1 | (temp2 << 16);
} }
void eeprom_write_dword (uint32_t *Address, uint32_t Value) void eeprom_write_dword (uint32_t *Address, uint32_t Value)
{ {
uint16_t temp = (uint16_t) Value; uint16_t p = (const uint32_t) Address;
uint16_t p = (uint32_t) Address; EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_write(p, temp); EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8));
temp = (uint16_t) (Value >> 16); EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16));
EEPROM_write(p + 1, temp); EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24));
} }
void eeprom_update_dword (uint32_t *Address, uint32_t Value) void eeprom_update_dword (uint32_t *Address, uint32_t Value)
{ {
uint16_t temp = (uint16_t) Value; uint16_t p = (const uint32_t) Address;
uint16_t p = (uint32_t) Address; EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_update(p, temp); EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8));
temp = (uint16_t) (Value >> 16); EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16));
EEPROM_update(p + 1, temp); EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24));
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
const uint8_t *p = (const uint8_t *)addr;
uint8_t *dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}
void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
} }

@ -10,15 +10,17 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
* This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and * This files are free to use from http://engsta.com/stm32-flash-memory-eeprom-emulator/ by
* https://github.com/leaflabs/libmaple * Artur F.
* *
* Modifications for QMK and STM32F303 by Yiancar * Modifications for QMK and STM32F303 by Yiancar
*
* 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 half of the pages account for the total EEPROM size.
* This library also assumes that the pages are not used by the firmware.
*/ */
// This file must be modified if the MCU is not defined below.
// This library also assumes that the pages are not used by the firmware.
#ifndef __EEPROM_H #ifndef __EEPROM_H
#define __EEPROM_H #define __EEPROM_H
@ -38,9 +40,11 @@
#ifndef EEPROM_PAGE_SIZE #ifndef EEPROM_PAGE_SIZE
#if defined (MCU_STM32F103RB) #if defined (MCU_STM32F103RB)
#define EEPROM_PAGE_SIZE (uint16_t)0x400 /* Page size = 1KByte */ #define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
#define FEE_DENSITY_PAGES 2 // How many pages are used
#elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC) #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC)
#define EEPROM_PAGE_SIZE (uint16_t)0x800 /* Page size = 2KByte */ #define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
#define FEE_DENSITY_PAGES 4 // How many pages are used
#else #else
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#endif #endif
@ -48,48 +52,30 @@
#ifndef EEPROM_START_ADDRESS #ifndef EEPROM_START_ADDRESS
#if defined (MCU_STM32F103RB) #if defined (MCU_STM32F103RB)
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 128 * 1024 - 2 * EEPROM_PAGE_SIZE)) #define FEE_MCU_FLASH_SIZE 128 // Size in Kb
#elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) #elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 512 * 1024 - 2 * EEPROM_PAGE_SIZE)) #define FEE_MCU_FLASH_SIZE 512 // Size in Kb
#elif defined (MCU_STM32F103RD) #elif defined (MCU_STM32F103RD)
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 384 * 1024 - 2 * EEPROM_PAGE_SIZE)) #define FEE_MCU_FLASH_SIZE 384 // Size in Kb
#elif defined (MCU_STM32F303CC) #elif defined (MCU_STM32F303CC)
#define EEPROM_START_ADDRESS ((uint32_t)(0x8000000 + 256 * 1024 - 2 * EEPROM_PAGE_SIZE)) #define FEE_MCU_FLASH_SIZE 256 // Size in Kb
#else #else
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)." #error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#endif #endif
#endif #endif
/* Pages 0 and 1 base and end addresses */ // DONT CHANGE
#define EEPROM_PAGE0_BASE ((uint32_t)(EEPROM_START_ADDRESS + 0x000)) // Choose location for the first EEPROM Page address on the top of flash
#define EEPROM_PAGE1_BASE ((uint32_t)(EEPROM_START_ADDRESS + EEPROM_PAGE_SIZE)) #define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
#define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1)
/* Page status definitions */ #define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
#define EEPROM_ERASED ((uint16_t)0xFFFF) /* PAGE is empty */ #define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
#define EEPROM_RECEIVE_DATA ((uint16_t)0xEEEE) /* PAGE is marked to receive data */ #define FEE_ADDR_OFFSET(Address)(Address * 2) // 1Byte per Word will be saved to preserve Flash
#define EEPROM_VALID_PAGE ((uint16_t)0x0000) /* PAGE containing valid data */
/* Page full define */
enum uint16_t
{
EEPROM_OK = ((uint16_t)0x0000),
EEPROM_OUT_SIZE = ((uint16_t)0x0081),
EEPROM_BAD_ADDRESS = ((uint16_t)0x0082),
EEPROM_BAD_FLASH = ((uint16_t)0x0083),
EEPROM_NOT_INIT = ((uint16_t)0x0084),
EEPROM_SAME_VALUE = ((uint16_t)0x0085),
EEPROM_NO_VALID_PAGE = ((uint16_t)0x00AB)
};
#define EEPROM_DEFAULT_DATA 0xFFFF
uint16_t EEPROM_init(void); // Use this function to initialize the functionality
uint16_t EEPROM_format(void); uint16_t EEPROM_Init(void);
uint16_t EEPROM_erases(uint16_t *); void EEPROM_Erase (void);
uint16_t EEPROM_read (uint16_t address, uint16_t *data); uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte);
uint16_t EEPROM_write(uint16_t address, uint16_t data); uint8_t EEPROM_ReadDataByte (uint16_t Address);
uint16_t EEPROM_update(uint16_t address, uint16_t data);
uint16_t EEPROM_count(uint16_t *);
uint16_t EEPROM_maxcount(void);
#endif /* __EEPROM_H */ #endif /* __EEPROM_H */

@ -186,3 +186,18 @@ void FLASH_Lock(void)
/* Set the Lock Bit to lock the FPEC and the FCR */ /* Set the Lock Bit to lock the FPEC and the FCR */
FLASH->CR |= FLASH_CR_LOCK; FLASH->CR |= FLASH_CR_LOCK;
} }
/**
* @brief Clears the FLASH's pending flags.
* @param FLASH_FLAG: specifies the FLASH flags to clear.
* This parameter can be any combination of the following values:
* @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
* @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
* @arg FLASH_FLAG_EOP: FLASH End of Programming flag
* @retval None
*/
void FLASH_ClearFlag(uint32_t FLASH_FLAG)
{
/* Clear the flags */
FLASH->SR = FLASH_FLAG;
}

@ -45,6 +45,7 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);
void FLASH_Unlock(void); void FLASH_Unlock(void);
void FLASH_Lock(void); void FLASH_Lock(void);
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -33,7 +33,7 @@ void eeconfig_init_kb(void) {
*/ */
void eeconfig_init_quantum(void) { void eeconfig_init_quantum(void) {
#ifdef STM32_EEPROM_ENABLE #ifdef STM32_EEPROM_ENABLE
EEPROM_format(); EEPROM_Erase();
#endif #endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
eeprom_update_byte(EECONFIG_DEBUG, 0); eeprom_update_byte(EECONFIG_DEBUG, 0);
@ -74,7 +74,7 @@ void eeconfig_enable(void)
void eeconfig_disable(void) void eeconfig_disable(void)
{ {
#ifdef STM32_EEPROM_ENABLE #ifdef STM32_EEPROM_ENABLE
EEPROM_format(); EEPROM_Erase();
#endif #endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
} }

@ -25,8 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED #define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEED
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF #define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
/* eeprom parameteter address */ /* EEPROM parameter address */
#if !defined(STM32_EEPROM_ENABLE)
#define EECONFIG_MAGIC (uint16_t *)0 #define EECONFIG_MAGIC (uint16_t *)0
#define EECONFIG_DEBUG (uint8_t *)2 #define EECONFIG_DEBUG (uint8_t *)2
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3 #define EECONFIG_DEFAULT_LAYER (uint8_t *)3
@ -42,24 +41,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define EECONFIG_KEYBOARD (uint32_t *)15 #define EECONFIG_KEYBOARD (uint32_t *)15
#define EECONFIG_USER (uint32_t *)19 #define EECONFIG_USER (uint32_t *)19
#else
/* STM32F3 uses 16byte block. Reconfigure memory map */
#define EECONFIG_MAGIC (uint16_t *)0
#define EECONFIG_DEBUG (uint8_t *)1
#define EECONFIG_DEFAULT_LAYER (uint8_t *)2
#define EECONFIG_KEYMAP (uint8_t *)3
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)4
#define EECONFIG_BACKLIGHT (uint8_t *)5
#define EECONFIG_AUDIO (uint8_t *)6
#define EECONFIG_RGBLIGHT (uint32_t *)7
#define EECONFIG_UNICODEMODE (uint8_t *)9
#define EECONFIG_STENOMODE (uint8_t *)10
// EEHANDS for two handed boards
#define EECONFIG_HANDEDNESS (uint8_t *)11
#define EECONFIG_KEYBOARD (uint32_t *)12
#define EECONFIG_USER (uint32_t *)14
#endif
/* debug bit */ /* debug bit */
#define EECONFIG_DEBUG_ENABLE (1<<0) #define EECONFIG_DEBUG_ENABLE (1<<0)
#define EECONFIG_DEBUG_MATRIX (1<<1) #define EECONFIG_DEBUG_MATRIX (1<<1)

@ -20,5 +20,4 @@ void eeprom_update_dword (uint32_t *__p, uint32_t __value);
void eeprom_update_block (const void *__src, void *__dst, uint32_t __n); void eeprom_update_block (const void *__src, void *__dst, uint32_t __n);
#endif #endif
#endif /* TMK_CORE_COMMON_EEPROM_H_ */ #endif /* TMK_CORE_COMMON_EEPROM_H_ */

@ -113,7 +113,7 @@ int main(void) {
chSysInit(); chSysInit();
#ifdef STM32_EEPROM_ENABLE #ifdef STM32_EEPROM_ENABLE
EEPROM_init(); EEPROM_Init();
#endif #endif
// TESTING // TESTING

Loading…
Cancel
Save