aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common_features.mk51
-rw-r--r--docs/_summary.md1
-rw-r--r--docs/eeprom_driver.md50
-rw-r--r--docs/hardware_drivers.md4
-rw-r--r--drivers/eeprom/eeprom_custom.c-template46
-rw-r--r--drivers/eeprom/eeprom_driver.c73
-rw-r--r--drivers/eeprom/eeprom_driver.h22
-rw-r--r--drivers/eeprom/eeprom_i2c.c120
-rw-r--r--drivers/eeprom/eeprom_i2c.h115
-rw-r--r--drivers/eeprom/eeprom_transient.c52
-rw-r--r--drivers/eeprom/eeprom_transient.h25
-rw-r--r--quantum/audio/audio_arm.c2
-rw-r--r--quantum/rgblight.c8
-rw-r--r--tmk_core/common.mk30
-rw-r--r--tmk_core/common/arm_atsam/eeprom.c13
-rw-r--r--tmk_core/common/chibios/eeprom_stm32.c6
-rw-r--r--tmk_core/common/chibios/eeprom_teensy.c25
-rw-r--r--tmk_core/common/eeconfig.c10
-rw-r--r--tmk_core/common/eeprom.h9
-rw-r--r--tmk_core/common/test/eeprom.c6
20 files changed, 616 insertions, 52 deletions
diff --git a/common_features.mk b/common_features.mk
index 6c3646db9..900b27c46 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -102,6 +102,57 @@ ifeq ($(strip $(UNICODE_COMMON)), yes)
102 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c 102 SRC += $(QUANTUM_DIR)/process_keycode/process_unicode_common.c
103endif 103endif
104 104
105VALID_EEPROM_DRIVER_TYPES := vendor custom transient i2c
106EEPROM_DRIVER ?= vendor
107ifeq ($(filter $(EEPROM_DRIVER),$(VALID_EEPROM_DRIVER_TYPES)),)
108 $(error EEPROM_DRIVER="$(EEPROM_DRIVER)" is not a valid EEPROM driver)
109else
110 OPT_DEFS += -DEEPROM_ENABLE
111 ifeq ($(strip $(EEPROM_DRIVER)), custom)
112 OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_CUSTOM
113 COMMON_VPATH += $(DRIVER_PATH)/eeprom
114 SRC += eeprom_driver.c
115 else ifeq ($(strip $(EEPROM_DRIVER)), i2c)
116 OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_I2C
117 COMMON_VPATH += $(DRIVER_PATH)/eeprom
118 QUANTUM_LIB_SRC += i2c_master.c
119 SRC += eeprom_driver.c eeprom_i2c.c
120 else ifeq ($(strip $(EEPROM_DRIVER)), transient)
121 OPT_DEFS += -DEEPROM_DRIVER -DEEPROM_TRANSIENT
122 COMMON_VPATH += $(DRIVER_PATH)/eeprom
123 SRC += eeprom_driver.c eeprom_transient.c
124 else ifeq ($(strip $(EEPROM_DRIVER)), vendor)
125 OPT_DEFS += -DEEPROM_VENDOR
126 ifeq ($(PLATFORM),AVR)
127 # Automatically provided by avr-libc, nothing required
128 else ifeq ($(PLATFORM),CHIBIOS)
129 ifeq ($(MCU_SERIES), STM32F3xx)
130 SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
131 SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
132 OPT_DEFS += -DEEPROM_EMU_STM32F303xC
133 OPT_DEFS += -DSTM32_EEPROM_ENABLE
134 else ifeq ($(MCU_SERIES), STM32F1xx)
135 SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
136 SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
137 OPT_DEFS += -DEEPROM_EMU_STM32F103xB
138 OPT_DEFS += -DSTM32_EEPROM_ENABLE
139 else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F072xB)
140 SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
141 SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
142 OPT_DEFS += -DEEPROM_EMU_STM32F072xB
143 OPT_DEFS += -DSTM32_EEPROM_ENABLE
144 else
145 # This will effectively work the same as "transient" if not supported by the chip
146 SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
147 endif
148 else ifeq ($(PLATFORM),ARM_ATSAM)
149 SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
150 else ifeq ($(PLATFORM),TEST)
151 SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
152 endif
153 endif
154endif
155
105ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) 156ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
106 POST_CONFIG_H += $(QUANTUM_DIR)/rgblight_post_config.h 157 POST_CONFIG_H += $(QUANTUM_DIR)/rgblight_post_config.h
107 OPT_DEFS += -DRGBLIGHT_ENABLE 158 OPT_DEFS += -DRGBLIGHT_ENABLE
diff --git a/docs/_summary.md b/docs/_summary.md
index de8148138..08ccdca22 100644
--- a/docs/_summary.md
+++ b/docs/_summary.md
@@ -104,6 +104,7 @@
104 * [ADC Driver](adc_driver.md) 104 * [ADC Driver](adc_driver.md)
105 * [I2C Driver](i2c_driver.md) 105 * [I2C Driver](i2c_driver.md)
106 * [WS2812 Driver](ws2812_driver.md) 106 * [WS2812 Driver](ws2812_driver.md)
107 * [EEPROM Driver](eeprom_driver.md)
107 * [GPIO Controls](internals_gpio_control.md) 108 * [GPIO Controls](internals_gpio_control.md)
108 * [Custom Matrix](custom_matrix.md) 109 * [Custom Matrix](custom_matrix.md)
109 * [Proton C Conversion](proton_c_conversion.md) 110 * [Proton C Conversion](proton_c_conversion.md)
diff --git a/docs/eeprom_driver.md b/docs/eeprom_driver.md
new file mode 100644
index 000000000..dd12d8ec7
--- /dev/null
+++ b/docs/eeprom_driver.md
@@ -0,0 +1,50 @@
1# EEPROM Driver Configuration
2
3The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present.
4
5Driver | Description
6--------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
7`EEPROM_DRIVER = vendor` | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. Other chips will generally act as "transient" below.
8`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below.
9`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost.
10
11## Vendor Driver Configuration
12
13No configurable options are available.
14
15## I2C Driver Configuration
16
17Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h:
18
19`config.h` override | Description | Default Value
20------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------
21`#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS` | Base I2C address for the EEPROM -- shifted left by 1 as per i2c_master requirements | 0b10100000
22`#define EXTERNAL_EEPROM_I2C_ADDRESS(addr)` | Calculated I2C address for the EEPROM | `(EXTERNAL_EEPROM_I2C_BASE_ADDRESS)`
23`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192
24`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
25`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
26`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5
27
28Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
29
30Alternatively, there are pre-defined hardware configurations for available chips/modules:
31
32Module | Equivalent `#define` | Source
33-----------------|---------------------------------|------------------------------------------
34CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | <https://www.sparkfun.com/products/14764>
35RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | <https://www.sparkfun.com/products/14764>
3624LC128 EEPROM | `#define EEPROM_I2C_24LC128` | <https://www.microchip.com/wwwproducts/en/24LC128>
3724LC256 EEPROM | `#define EEPROM_I2C_24LC256` | <https://www.sparkfun.com/products/525>
38MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | <https://www.adafruit.com/product/1895>
39
40?> If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`.
41
42## Transient Driver configuration
43
44The only configurable item for the transient EEPROM driver is its size:
45
46`config.h` override | Description | Default Value
47------------------------------- | ----------------------------------------- | -------------
48`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64
49
50Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`.
diff --git a/docs/hardware_drivers.md b/docs/hardware_drivers.md
index 165187795..7e89c0d2b 100644
--- a/docs/hardware_drivers.md
+++ b/docs/hardware_drivers.md
@@ -33,3 +33,7 @@ Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to in
33## IS31FL3733 33## IS31FL3733
34 34
35Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. 35Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page.
36
37## 24xx series external I2C EEPROM
38
39Support for an external I2C-based EEPROM instead of using the on-chip EEPROM. For more information on how to setup the driver see the [EEPROM Driver](eeprom_driver.md) page.
diff --git a/drivers/eeprom/eeprom_custom.c-template b/drivers/eeprom/eeprom_custom.c-template
new file mode 100644
index 000000000..5f915f7fa
--- /dev/null
+++ b/drivers/eeprom/eeprom_custom.c-template
@@ -0,0 +1,46 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <stdint.h>
18#include <string.h>
19
20#include "eeprom_driver.h"
21
22void eeprom_driver_init(void) {
23 /* Any initialisation code */
24 }
25
26void eeprom_driver_erase(void) {
27 /* Wipe out the EEPROM, setting values to zero */
28}
29
30void eeprom_read_block(void *buf, const void *addr, size_t len) {
31 /*
32 Read a block of data:
33 buf: target buffer
34 addr: 0-based offset within the EEPROM
35 len: length to read
36 */
37}
38
39void eeprom_write_block(const void *buf, void *addr, size_t len) {
40 /*
41 Write a block of data:
42 buf: target buffer
43 addr: 0-based offset within the EEPROM
44 len: length to write
45 */
46}
diff --git a/drivers/eeprom/eeprom_driver.c b/drivers/eeprom/eeprom_driver.c
new file mode 100644
index 000000000..3835e5e9d
--- /dev/null
+++ b/drivers/eeprom/eeprom_driver.c
@@ -0,0 +1,73 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <stdint.h>
18#include <string.h>
19
20#include "eeprom_driver.h"
21
22uint8_t eeprom_read_byte(const uint8_t *addr) {
23 uint8_t ret;
24 eeprom_read_block(&ret, addr, 1);
25 return ret;
26}
27
28uint16_t eeprom_read_word(const uint16_t *addr) {
29 uint16_t ret;
30 eeprom_read_block(&ret, addr, 2);
31 return ret;
32}
33
34uint32_t eeprom_read_dword(const uint32_t *addr) {
35 uint32_t ret;
36 eeprom_read_block(&ret, addr, 4);
37 return ret;
38}
39
40void eeprom_write_byte(uint8_t *addr, uint8_t value) { eeprom_write_block(&value, addr, 1); }
41
42void eeprom_write_word(uint16_t *addr, uint16_t value) { eeprom_write_block(&value, addr, 2); }
43
44void eeprom_write_dword(uint32_t *addr, uint32_t value) { eeprom_write_block(&value, addr, 4); }
45
46void eeprom_update_block(const void *buf, void *addr, size_t len) {
47 uint8_t read_buf[len];
48 eeprom_read_block(read_buf, addr, len);
49 if (memcmp(buf, read_buf, len) != 0) {
50 eeprom_write_block(buf, addr, len);
51 }
52}
53
54void eeprom_update_byte(uint8_t *addr, uint8_t value) {
55 uint8_t orig = eeprom_read_byte(addr);
56 if (orig != value) {
57 eeprom_write_byte(addr, value);
58 }
59}
60
61void eeprom_update_word(uint16_t *addr, uint16_t value) {
62 uint16_t orig = eeprom_read_word(addr);
63 if (orig != value) {
64 eeprom_write_word(addr, value);
65 }
66}
67
68void eeprom_update_dword(uint32_t *addr, uint32_t value) {
69 uint32_t orig = eeprom_read_dword(addr);
70 if (orig != value) {
71 eeprom_write_dword(addr, value);
72 }
73}
diff --git a/drivers/eeprom/eeprom_driver.h b/drivers/eeprom/eeprom_driver.h
new file mode 100644
index 000000000..74592bc8f
--- /dev/null
+++ b/drivers/eeprom/eeprom_driver.h
@@ -0,0 +1,22 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19#include "eeprom.h"
20
21void eeprom_driver_init(void);
22void eeprom_driver_erase(void);
diff --git a/drivers/eeprom/eeprom_i2c.c b/drivers/eeprom/eeprom_i2c.c
new file mode 100644
index 000000000..03dbc5e51
--- /dev/null
+++ b/drivers/eeprom/eeprom_i2c.c
@@ -0,0 +1,120 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <stdint.h>
18#include <string.h>
19
20/*
21 Note that the implementations of eeprom_XXXX_YYYY on AVR are normally
22 provided by avr-libc. The same functions are reimplemented below and are
23 rerouted to the external i2c equivalent.
24
25 Seemingly, as this is compiled from within QMK, the object file generated
26 during the build overrides the avr-libc implementation during the linking
27 stage.
28
29 On other platforms such as ARM, there are no provided implementations, so
30 there is nothing to override during linkage.
31*/
32
33#include "wait.h"
34#include "i2c_master.h"
35#include "eeprom.h"
36#include "eeprom_i2c.h"
37
38// #define DEBUG_EEPROM_OUTPUT
39
40#ifdef DEBUG_EEPROM_OUTPUT
41# include "print.h"
42#endif // DEBUG_EEPROM_OUTPUT
43
44static inline void init_i2c_if_required(void) {
45 static int done = 0;
46 if (!done) {
47 i2c_init();
48 done = 1;
49 }
50}
51
52static inline void fill_target_address(uint8_t *buffer, const void *addr) {
53 intptr_t p = (intptr_t)addr;
54 for (int i = 0; i < EXTERNAL_EEPROM_ADDRESS_SIZE; ++i) {
55 buffer[EXTERNAL_EEPROM_ADDRESS_SIZE - 1 - i] = p & 0xFF;
56 p >>= 8;
57 }
58}
59
60void eeprom_driver_init(void) {}
61
62void eeprom_driver_erase(void) {
63 uint8_t buf[EXTERNAL_EEPROM_PAGE_SIZE];
64 memset(buf, 0x00, EXTERNAL_EEPROM_PAGE_SIZE);
65 for (intptr_t addr = 0; addr < EXTERNAL_EEPROM_BYTE_COUNT; addr += EXTERNAL_EEPROM_PAGE_SIZE) {
66 eeprom_write_block(buf, (void *)addr, EXTERNAL_EEPROM_PAGE_SIZE);
67 }
68}
69
70void eeprom_read_block(void *buf, const void *addr, size_t len) {
71 uint8_t complete_packet[EXTERNAL_EEPROM_ADDRESS_SIZE];
72 fill_target_address(complete_packet, addr);
73
74 init_i2c_if_required();
75 i2c_transmit(EXTERNAL_EEPROM_I2C_ADDRESS((intptr_t)addr), complete_packet, EXTERNAL_EEPROM_ADDRESS_SIZE, 100);
76 i2c_receive(EXTERNAL_EEPROM_I2C_ADDRESS((intptr_t)addr), buf, len, 100);
77
78#ifdef DEBUG_EEPROM_OUTPUT
79 dprintf("[EEPROM R] 0x%04X: ", ((int)addr));
80 for (size_t i = 0; i < len; ++i) {
81 dprintf(" %02X", (int)(((uint8_t *)buf)[i]));
82 }
83 dprintf("\n");
84#endif // DEBUG_EEPROM_OUTPUT
85}
86
87void eeprom_write_block(const void *buf, void *addr, size_t len) {
88 uint8_t complete_packet[EXTERNAL_EEPROM_ADDRESS_SIZE + EXTERNAL_EEPROM_PAGE_SIZE];
89 uint8_t *read_buf = (uint8_t *)buf;
90 intptr_t target_addr = (intptr_t)addr;
91
92 init_i2c_if_required();
93 while (len > 0) {
94 intptr_t page_offset = target_addr % EXTERNAL_EEPROM_PAGE_SIZE;
95 int write_length = EXTERNAL_EEPROM_PAGE_SIZE - page_offset;
96 if (write_length > len) {
97 write_length = len;
98 }
99
100 fill_target_address(complete_packet, (const void *)target_addr);
101 for (uint8_t i = 0; i < write_length; i++) {
102 complete_packet[EXTERNAL_EEPROM_ADDRESS_SIZE + i] = read_buf[i];
103 }
104
105#ifdef DEBUG_EEPROM_OUTPUT
106 dprintf("[EEPROM W] 0x%04X: ", ((int)target_addr));
107 for (uint8_t i = 0; i < write_length; i++) {
108 dprintf(" %02X", (int)(read_buf[i]));
109 }
110 dprintf("\n");
111#endif // DEBUG_EEPROM_OUTPUT
112
113 i2c_transmit(EXTERNAL_EEPROM_I2C_ADDRESS((intptr_t)addr), complete_packet, EXTERNAL_EEPROM_ADDRESS_SIZE + write_length, 100);
114 wait_ms(EXTERNAL_EEPROM_WRITE_TIME);
115
116 read_buf += write_length;
117 target_addr += write_length;
118 len -= write_length;
119 }
120}
diff --git a/drivers/eeprom/eeprom_i2c.h b/drivers/eeprom/eeprom_i2c.h
new file mode 100644
index 000000000..51bce825b
--- /dev/null
+++ b/drivers/eeprom/eeprom_i2c.h
@@ -0,0 +1,115 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19/*
20 Default device configurations:
21
22 For the Sparkfun Qwiic I2C EEPROM module: https://www.sparkfun.com/products/14764
23 #define EEPROM_I2C_CAT24C512 // (part number 24512A)
24 #define EEPROM_I2C_RM24C512C // (part number 24512C)
25
26 For the Sparkfun I2C EEPROM chip: https://www.sparkfun.com/products/525
27 #define EEPROM_I2C_24LC256
28
29 For the Adafruit I2C FRAM chip: https://www.adafruit.com/product/1895
30 #define EEPROM_I2C_MB85RC256V
31*/
32#if defined(EEPROM_I2C_CAT24C512)
33# define EXTERNAL_EEPROM_BYTE_COUNT 65536
34# define EXTERNAL_EEPROM_PAGE_SIZE 128
35# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
36# define EXTERNAL_EEPROM_WRITE_TIME 5
37#elif defined(EEPROM_I2C_RM24C512C)
38# define EXTERNAL_EEPROM_BYTE_COUNT 65536
39# define EXTERNAL_EEPROM_PAGE_SIZE 128
40# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
41# define EXTERNAL_EEPROM_WRITE_TIME 3
42#elif defined(EEPROM_I2C_24LC256)
43# define EXTERNAL_EEPROM_BYTE_COUNT 32768
44# define EXTERNAL_EEPROM_PAGE_SIZE 64
45# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
46# define EXTERNAL_EEPROM_WRITE_TIME 5
47#elif defined(EEPROM_I2C_24LC128)
48# define EXTERNAL_EEPROM_BYTE_COUNT 16384
49# define EXTERNAL_EEPROM_PAGE_SIZE 64
50# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
51# define EXTERNAL_EEPROM_WRITE_TIME 5
52#elif defined(EEPROM_I2C_MB85RC256V)
53# define EXTERNAL_EEPROM_BYTE_COUNT 32768
54# define EXTERNAL_EEPROM_PAGE_SIZE 128
55# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
56# define EXTERNAL_EEPROM_WRITE_TIME 0
57#endif
58
59/*
60 The base I2C address of the EEPROM.
61 This needs to be shifted up by 1, to match i2c_master requirements.
62*/
63#ifndef EXTERNAL_EEPROM_I2C_BASE_ADDRESS
64# define EXTERNAL_EEPROM_I2C_BASE_ADDRESS 0b10100000
65#endif
66
67/*
68 The calculated I2C address based on the input memory location.
69
70 For EEPROM chips that embed part of the memory location in the I2C address
71 such as AT24M02 you can use something similar to the following (ensuring the
72 result is shifted by left by 1):
73
74 #define EXTERNAL_EEPROM_I2C_ADDRESS(loc) \
75 (EXTERNAL_EEPROM_I2C_BASE_ADDRESS | ((((loc) >> 16) & 0x07) << 1))
76
77*/
78#ifndef EXTERNAL_EEPROM_I2C_ADDRESS
79# define EXTERNAL_EEPROM_I2C_ADDRESS(loc) (EXTERNAL_EEPROM_I2C_BASE_ADDRESS)
80#endif
81
82/*
83 The total size of the EEPROM, in bytes. The EEPROM datasheet will usually
84 specify this value in kbits, and will require conversion to bytes.
85*/
86#ifndef EXTERNAL_EEPROM_BYTE_COUNT
87# define EXTERNAL_EEPROM_BYTE_COUNT 8192
88#endif
89
90/*
91 The page size in bytes of the EEPROM, as specified in the datasheet.
92*/
93#ifndef EXTERNAL_EEPROM_PAGE_SIZE
94# define EXTERNAL_EEPROM_PAGE_SIZE 32
95#endif
96
97/*
98 The address size in bytes of the EEPROM. For EEPROMs with <=256 bytes, this
99 will likely be 1. For EEPROMs >256 and <=65536, this will be 2. For EEPROMs
100 >65536, this will likely need to be 2 with the modified variant of
101 EXTERNAL_EEPROM_I2C_ADDRESS above.
102
103 As expected, consult the datasheet for specifics of your EEPROM.
104*/
105#ifndef EXTERNAL_EEPROM_ADDRESS_SIZE
106# define EXTERNAL_EEPROM_ADDRESS_SIZE 2
107#endif
108
109/*
110 The write cycle time of the EEPROM in milliseconds, as specified in the
111 datasheet.
112*/
113#ifndef EXTERNAL_EEPROM_WRITE_TIME
114# define EXTERNAL_EEPROM_WRITE_TIME 5
115#endif
diff --git a/drivers/eeprom/eeprom_transient.c b/drivers/eeprom/eeprom_transient.c
new file mode 100644
index 000000000..b4c78c6f4
--- /dev/null
+++ b/drivers/eeprom/eeprom_transient.c
@@ -0,0 +1,52 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <stdint.h>
18#include <string.h>
19
20#include "eeprom_driver.h"
21#include "eeprom_transient.h"
22
23__attribute__((aligned(4))) static uint8_t transientBuffer[TRANSIENT_EEPROM_SIZE] = {0};
24
25size_t clamp_length(intptr_t offset, size_t len) {
26 if (offset + len > TRANSIENT_EEPROM_SIZE) {
27 len = TRANSIENT_EEPROM_SIZE - offset;
28 }
29
30 return len;
31}
32
33void eeprom_driver_init(void) { eeprom_driver_erase(); }
34
35void eeprom_driver_erase(void) { memset(transientBuffer, 0x00, TRANSIENT_EEPROM_SIZE); }
36
37void eeprom_read_block(void *buf, const void *addr, size_t len) {
38 intptr_t offset = (intptr_t)addr;
39 memset(buf, 0x00, len);
40 len = clamp_length(offset, len);
41 if (len > 0) {
42 memcpy(buf, &transientBuffer[offset], len);
43 }
44}
45
46void eeprom_write_block(const void *buf, void *addr, size_t len) {
47 intptr_t offset = (intptr_t)addr;
48 len = clamp_length(offset, len);
49 if (len > 0) {
50 memcpy(&transientBuffer[offset], buf, len);
51 }
52}
diff --git a/drivers/eeprom/eeprom_transient.h b/drivers/eeprom/eeprom_transient.h
new file mode 100644
index 000000000..ca9d634f0
--- /dev/null
+++ b/drivers/eeprom/eeprom_transient.h
@@ -0,0 +1,25 @@
1/* Copyright 2019 Nick Brassel (tzarc)
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#pragma once
18
19/*
20 The size of the transient EEPROM buffer size.
21*/
22#ifndef TRANSIENT_EEPROM_SIZE
23# include "eeconfig.h"
24# define TRANSIENT_EEPROM_SIZE (((EECONFIG_SIZE+3)/4)*4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
25#endif
diff --git a/quantum/audio/audio_arm.c b/quantum/audio/audio_arm.c
index 87d625301..e4483c302 100644
--- a/quantum/audio/audio_arm.c
+++ b/quantum/audio/audio_arm.c
@@ -258,7 +258,7 @@ void audio_init() {
258 } 258 }
259 259
260// Check EEPROM 260// Check EEPROM
261#if defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) 261#ifdef EEPROM_ENABLE
262 if (!eeconfig_is_enabled()) { 262 if (!eeconfig_is_enabled()) {
263 eeconfig_init(); 263 eeconfig_init();
264 } 264 }
diff --git a/quantum/rgblight.c b/quantum/rgblight.c
index 40de19eac..67d601af7 100644
--- a/quantum/rgblight.c
+++ b/quantum/rgblight.c
@@ -19,9 +19,11 @@
19# include <avr/eeprom.h> 19# include <avr/eeprom.h>
20# include <avr/interrupt.h> 20# include <avr/interrupt.h>
21#endif 21#endif
22#ifdef EEPROM_ENABLE
23# include "eeprom.h"
24#endif
22#ifdef STM32_EEPROM_ENABLE 25#ifdef STM32_EEPROM_ENABLE
23# include "hal.h" 26# include "hal.h"
24# include "eeprom.h"
25# include "eeprom_stm32.h" 27# include "eeprom_stm32.h"
26#endif 28#endif
27#include "wait.h" 29#include "wait.h"
@@ -146,7 +148,7 @@ void rgblight_check_config(void) {
146} 148}
147 149
148uint32_t eeconfig_read_rgblight(void) { 150uint32_t eeconfig_read_rgblight(void) {
149#if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) 151#ifdef EEPROM_ENABLE
150 return eeprom_read_dword(EECONFIG_RGBLIGHT); 152 return eeprom_read_dword(EECONFIG_RGBLIGHT);
151#else 153#else
152 return 0; 154 return 0;
@@ -154,7 +156,7 @@ uint32_t eeconfig_read_rgblight(void) {
154} 156}
155 157
156void eeconfig_update_rgblight(uint32_t val) { 158void eeconfig_update_rgblight(uint32_t val) {
157#if defined(__AVR__) || defined(STM32_EEPROM_ENABLE) || defined(PROTOCOL_ARM_ATSAM) || defined(EEPROM_SIZE) 159#ifdef EEPROM_ENABLE
158 rgblight_check_config(); 160 rgblight_check_config();
159 eeprom_update_dword(EECONFIG_RGBLIGHT, val); 161 eeprom_update_dword(EECONFIG_RGBLIGHT, val);
160#endif 162#endif
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 8f355da12..5f149d8f4 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -26,29 +26,11 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
26 $(PLATFORM_COMMON_DIR)/bootloader.c \ 26 $(PLATFORM_COMMON_DIR)/bootloader.c \
27 27
28ifeq ($(PLATFORM),AVR) 28ifeq ($(PLATFORM),AVR)
29 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S 29 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/xprintf.S
30endif 30endif
31 31
32ifeq ($(PLATFORM),CHIBIOS) 32ifeq ($(PLATFORM),CHIBIOS)
33 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c 33 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
34 ifeq ($(MCU_SERIES), STM32F3xx)
35 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
36 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
37 TMK_COMMON_DEFS += -DEEPROM_EMU_STM32F303xC
38 TMK_COMMON_DEFS += -DSTM32_EEPROM_ENABLE
39 else ifeq ($(MCU_SERIES), STM32F1xx)
40 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
41 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
42 TMK_COMMON_DEFS += -DEEPROM_EMU_STM32F103xB
43 TMK_COMMON_DEFS += -DSTM32_EEPROM_ENABLE
44 else ifeq ($(MCU_SERIES)_$(MCU_LDSCRIPT), STM32F0xx_STM32F072xB)
45 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_stm32.c
46 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/flash_stm32.c
47 TMK_COMMON_DEFS += -DEEPROM_EMU_STM32F072xB
48 TMK_COMMON_DEFS += -DSTM32_EEPROM_ENABLE
49 else
50 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom_teensy.c
51 endif
52 ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes) 34 ifeq ($(strip $(AUTO_SHIFT_ENABLE)), yes)
53 TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c 35 TMK_COMMON_SRC += $(CHIBIOS)/os/various/syscalls.c
54 else ifeq ($(strip $(TERMINAL_ENABLE)), yes) 36 else ifeq ($(strip $(TERMINAL_ENABLE)), yes)
@@ -57,15 +39,9 @@ ifeq ($(PLATFORM),CHIBIOS)
57endif 39endif
58 40
59ifeq ($(PLATFORM),ARM_ATSAM) 41ifeq ($(PLATFORM),ARM_ATSAM)
60 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c 42 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/printf.c
61 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
62endif 43endif
63 44
64ifeq ($(PLATFORM),TEST)
65 TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
66endif
67
68
69 45
70# Option modules 46# Option modules
71BOOTMAGIC_ENABLE ?= no 47BOOTMAGIC_ENABLE ?= no
diff --git a/tmk_core/common/arm_atsam/eeprom.c b/tmk_core/common/arm_atsam/eeprom.c
index 44a0bf4d7..a69f38282 100644
--- a/tmk_core/common/arm_atsam/eeprom.c
+++ b/tmk_core/common/arm_atsam/eeprom.c
@@ -16,9 +16,12 @@
16 16
17#include "eeprom.h" 17#include "eeprom.h"
18 18
19#define EEPROM_SIZE 32 19#ifndef EEPROM_SIZE
20# include "eeconfig.h"
21# define EEPROM_SIZE (((EECONFIG_SIZE+3)/4)*4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
22#endif
20 23
21static uint8_t buffer[EEPROM_SIZE]; 24__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE];
22 25
23uint8_t eeprom_read_byte(const uint8_t *addr) { 26uint8_t eeprom_read_byte(const uint8_t *addr) {
24 uintptr_t offset = (uintptr_t)addr; 27 uintptr_t offset = (uintptr_t)addr;
@@ -40,7 +43,7 @@ uint32_t eeprom_read_dword(const uint32_t *addr) {
40 return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); 43 return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
41} 44}
42 45
43void eeprom_read_block(void *buf, const void *addr, uint32_t len) { 46void eeprom_read_block(void *buf, const void *addr, size_t len) {
44 const uint8_t *p = (const uint8_t *)addr; 47 const uint8_t *p = (const uint8_t *)addr;
45 uint8_t * dest = (uint8_t *)buf; 48 uint8_t * dest = (uint8_t *)buf;
46 while (len--) { 49 while (len--) {
@@ -62,7 +65,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) {
62 eeprom_write_byte(p, value >> 24); 65 eeprom_write_byte(p, value >> 24);
63} 66}
64 67
65void eeprom_write_block(const void *buf, void *addr, uint32_t len) { 68void eeprom_write_block(const void *buf, void *addr, size_t len) {
66 uint8_t * p = (uint8_t *)addr; 69 uint8_t * p = (uint8_t *)addr;
67 const uint8_t *src = (const uint8_t *)buf; 70 const uint8_t *src = (const uint8_t *)buf;
68 while (len--) { 71 while (len--) {
@@ -86,7 +89,7 @@ void eeprom_update_dword(uint32_t *addr, uint32_t value) {
86 eeprom_write_byte(p, value >> 24); 89 eeprom_write_byte(p, value >> 24);
87} 90}
88 91
89void eeprom_update_block(const void *buf, void *addr, uint32_t len) { 92void eeprom_update_block(const void *buf, void *addr, size_t len) {
90 uint8_t * p = (uint8_t *)addr; 93 uint8_t * p = (uint8_t *)addr;
91 const uint8_t *src = (const uint8_t *)buf; 94 const uint8_t *src = (const uint8_t *)buf;
92 while (len--) { 95 while (len--) {
diff --git a/tmk_core/common/chibios/eeprom_stm32.c b/tmk_core/common/chibios/eeprom_stm32.c
index 926b581c6..ea5198972 100644
--- a/tmk_core/common/chibios/eeprom_stm32.c
+++ b/tmk_core/common/chibios/eeprom_stm32.c
@@ -173,7 +173,7 @@ void eeprom_update_dword(uint32_t *Address, uint32_t Value) {
173 } 173 }
174} 174}
175 175
176void eeprom_read_block(void *buf, const void *addr, uint32_t len) { 176void eeprom_read_block(void *buf, const void *addr, size_t len) {
177 const uint8_t *p = (const uint8_t *)addr; 177 const uint8_t *p = (const uint8_t *)addr;
178 uint8_t * dest = (uint8_t *)buf; 178 uint8_t * dest = (uint8_t *)buf;
179 while (len--) { 179 while (len--) {
@@ -181,7 +181,7 @@ void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
181 } 181 }
182} 182}
183 183
184void eeprom_write_block(const void *buf, void *addr, uint32_t len) { 184void eeprom_write_block(const void *buf, void *addr, size_t len) {
185 uint8_t * p = (uint8_t *)addr; 185 uint8_t * p = (uint8_t *)addr;
186 const uint8_t *src = (const uint8_t *)buf; 186 const uint8_t *src = (const uint8_t *)buf;
187 while (len--) { 187 while (len--) {
@@ -189,7 +189,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
189 } 189 }
190} 190}
191 191
192void eeprom_update_block(const void *buf, void *addr, uint32_t len) { 192void eeprom_update_block(const void *buf, void *addr, size_t len) {
193 uint8_t * p = (uint8_t *)addr; 193 uint8_t * p = (uint8_t *)addr;
194 const uint8_t *src = (const uint8_t *)buf; 194 const uint8_t *src = (const uint8_t *)buf;
195 while (len--) { 195 while (len--) {
diff --git a/tmk_core/common/chibios/eeprom_teensy.c b/tmk_core/common/chibios/eeprom_teensy.c
index a4093fb3b..0fab9f73d 100644
--- a/tmk_core/common/chibios/eeprom_teensy.c
+++ b/tmk_core/common/chibios/eeprom_teensy.c
@@ -50,7 +50,17 @@
50// (aligned to 2 or 4 byte boundaries) has twice the endurance 50// (aligned to 2 or 4 byte boundaries) has twice the endurance
51// compared to writing 8 bit bytes. 51// compared to writing 8 bit bytes.
52// 52//
53# define EEPROM_SIZE 32 53# ifndef EEPROM_SIZE
54# define EEPROM_SIZE 32
55# endif
56
57/*
58 ^^^ Here be dragons:
59 NXP AppNote AN4282 section 3.1 states that partitioning must only be done once.
60 Once EEPROM partitioning is done, the size is locked to this initial configuration.
61 Attempts to modify the EEPROM_SIZE setting may brick your board.
62*/
63
54 64
55// Writing unaligned 16 or 32 bit data is handled automatically when 65// Writing unaligned 16 or 32 bit data is handled automatically when
56// this is defined, but at a cost of extra code size. Without this, 66// this is defined, but at a cost of extra code size. Without this,
@@ -517,8 +527,11 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
517#else 527#else
518// No EEPROM supported, so emulate it 528// No EEPROM supported, so emulate it
519 529
520# define EEPROM_SIZE 32 530# ifndef EEPROM_SIZE
521static uint8_t buffer[EEPROM_SIZE]; 531# include "eeconfig.h"
532# define EEPROM_SIZE (((EECONFIG_SIZE+3)/4)*4) // based off eeconfig's current usage, aligned to 4-byte sizes, to deal with LTO
533# endif
534__attribute__((aligned(4))) static uint8_t buffer[EEPROM_SIZE];
522 535
523uint8_t eeprom_read_byte(const uint8_t *addr) { 536uint8_t eeprom_read_byte(const uint8_t *addr) {
524 uint32_t offset = (uint32_t)addr; 537 uint32_t offset = (uint32_t)addr;
@@ -540,7 +553,7 @@ uint32_t eeprom_read_dword(const uint32_t *addr) {
540 return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); 553 return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
541} 554}
542 555
543void eeprom_read_block(void *buf, const void *addr, uint32_t len) { 556void eeprom_read_block(void *buf, const void *addr, size_t len) {
544 const uint8_t *p = (const uint8_t *)addr; 557 const uint8_t *p = (const uint8_t *)addr;
545 uint8_t * dest = (uint8_t *)buf; 558 uint8_t * dest = (uint8_t *)buf;
546 while (len--) { 559 while (len--) {
@@ -562,7 +575,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) {
562 eeprom_write_byte(p, value >> 24); 575 eeprom_write_byte(p, value >> 24);
563} 576}
564 577
565void eeprom_write_block(const void *buf, void *addr, uint32_t len) { 578void eeprom_write_block(const void *buf, void *addr, size_t len) {
566 uint8_t * p = (uint8_t *)addr; 579 uint8_t * p = (uint8_t *)addr;
567 const uint8_t *src = (const uint8_t *)buf; 580 const uint8_t *src = (const uint8_t *)buf;
568 while (len--) { 581 while (len--) {
@@ -589,7 +602,7 @@ void eeprom_update_dword(uint32_t *addr, uint32_t value) {
589 eeprom_write_byte(p, value >> 24); 602 eeprom_write_byte(p, value >> 24);
590} 603}
591 604
592void eeprom_update_block(const void *buf, void *addr, uint32_t len) { 605void eeprom_update_block(const void *buf, void *addr, size_t len) {
593 uint8_t * p = (uint8_t *)addr; 606 uint8_t * p = (uint8_t *)addr;
594 const uint8_t *src = (const uint8_t *)buf; 607 const uint8_t *src = (const uint8_t *)buf;
595 while (len--) { 608 while (len--) {
diff --git a/tmk_core/common/eeconfig.c b/tmk_core/common/eeconfig.c
index 7cec4bd7d..fe56c57d1 100644
--- a/tmk_core/common/eeconfig.c
+++ b/tmk_core/common/eeconfig.c
@@ -9,6 +9,10 @@
9# include "eeprom_stm32.h" 9# include "eeprom_stm32.h"
10#endif 10#endif
11 11
12#if defined(EEPROM_DRIVER)
13# include "eeprom_driver.h"
14#endif
15
12/** \brief eeconfig enable 16/** \brief eeconfig enable
13 * 17 *
14 * FIXME: needs doc 18 * FIXME: needs doc
@@ -32,6 +36,9 @@ void eeconfig_init_quantum(void) {
32#ifdef STM32_EEPROM_ENABLE 36#ifdef STM32_EEPROM_ENABLE
33 EEPROM_Erase(); 37 EEPROM_Erase();
34#endif 38#endif
39#if defined(EEPROM_DRIVER)
40 eeprom_driver_erase();
41#endif
35 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); 42 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
36 eeprom_update_byte(EECONFIG_DEBUG, 0); 43 eeprom_update_byte(EECONFIG_DEBUG, 0);
37 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); 44 eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
@@ -81,6 +88,9 @@ void eeconfig_disable(void) {
81#ifdef STM32_EEPROM_ENABLE 88#ifdef STM32_EEPROM_ENABLE
82 EEPROM_Erase(); 89 EEPROM_Erase();
83#endif 90#endif
91#if defined(EEPROM_DRIVER)
92 eeprom_driver_erase();
93#endif
84 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); 94 eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
85} 95}
86 96
diff --git a/tmk_core/common/eeprom.h b/tmk_core/common/eeprom.h
index fcd1667c0..8a81e7066 100644
--- a/tmk_core/common/eeprom.h
+++ b/tmk_core/common/eeprom.h
@@ -1,23 +1,24 @@
1#ifndef TMK_CORE_COMMON_EEPROM_H_ 1#ifndef TMK_CORE_COMMON_EEPROM_H_
2#define TMK_CORE_COMMON_EEPROM_H_ 2#define TMK_CORE_COMMON_EEPROM_H_
3 3
4#if defined(__AVR__) 4#if defined(__AVR__) && !defined(EEPROM_DRIVER)
5# include <avr/eeprom.h> 5# include <avr/eeprom.h>
6#else 6#else
7# include <stdint.h> 7# include <stdint.h>
8# include <stdlib.h>
8 9
9uint8_t eeprom_read_byte(const uint8_t *__p); 10uint8_t eeprom_read_byte(const uint8_t *__p);
10uint16_t eeprom_read_word(const uint16_t *__p); 11uint16_t eeprom_read_word(const uint16_t *__p);
11uint32_t eeprom_read_dword(const uint32_t *__p); 12uint32_t eeprom_read_dword(const uint32_t *__p);
12void eeprom_read_block(void *__dst, const void *__src, uint32_t __n); 13void eeprom_read_block(void *__dst, const void *__src, size_t __n);
13void eeprom_write_byte(uint8_t *__p, uint8_t __value); 14void eeprom_write_byte(uint8_t *__p, uint8_t __value);
14void eeprom_write_word(uint16_t *__p, uint16_t __value); 15void eeprom_write_word(uint16_t *__p, uint16_t __value);
15void eeprom_write_dword(uint32_t *__p, uint32_t __value); 16void eeprom_write_dword(uint32_t *__p, uint32_t __value);
16void eeprom_write_block(const void *__src, void *__dst, uint32_t __n); 17void eeprom_write_block(const void *__src, void *__dst, size_t __n);
17void eeprom_update_byte(uint8_t *__p, uint8_t __value); 18void eeprom_update_byte(uint8_t *__p, uint8_t __value);
18void eeprom_update_word(uint16_t *__p, uint16_t __value); 19void eeprom_update_word(uint16_t *__p, uint16_t __value);
19void eeprom_update_dword(uint32_t *__p, uint32_t __value); 20void eeprom_update_dword(uint32_t *__p, uint32_t __value);
20void eeprom_update_block(const void *__src, void *__dst, uint32_t __n); 21void eeprom_update_block(const void *__src, void *__dst, size_t __n);
21#endif 22#endif
22 23
23#endif /* TMK_CORE_COMMON_EEPROM_H_ */ 24#endif /* TMK_CORE_COMMON_EEPROM_H_ */
diff --git a/tmk_core/common/test/eeprom.c b/tmk_core/common/test/eeprom.c
index 44a0bf4d7..5c8e69dae 100644
--- a/tmk_core/common/test/eeprom.c
+++ b/tmk_core/common/test/eeprom.c
@@ -40,7 +40,7 @@ uint32_t eeprom_read_dword(const uint32_t *addr) {
40 return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24); 40 return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
41} 41}
42 42
43void eeprom_read_block(void *buf, const void *addr, uint32_t len) { 43void eeprom_read_block(void *buf, const void *addr, size_t len) {
44 const uint8_t *p = (const uint8_t *)addr; 44 const uint8_t *p = (const uint8_t *)addr;
45 uint8_t * dest = (uint8_t *)buf; 45 uint8_t * dest = (uint8_t *)buf;
46 while (len--) { 46 while (len--) {
@@ -62,7 +62,7 @@ void eeprom_write_dword(uint32_t *addr, uint32_t value) {
62 eeprom_write_byte(p, value >> 24); 62 eeprom_write_byte(p, value >> 24);
63} 63}
64 64
65void eeprom_write_block(const void *buf, void *addr, uint32_t len) { 65void eeprom_write_block(const void *buf, void *addr, size_t len) {
66 uint8_t * p = (uint8_t *)addr; 66 uint8_t * p = (uint8_t *)addr;
67 const uint8_t *src = (const uint8_t *)buf; 67 const uint8_t *src = (const uint8_t *)buf;
68 while (len--) { 68 while (len--) {
@@ -86,7 +86,7 @@ void eeprom_update_dword(uint32_t *addr, uint32_t value) {
86 eeprom_write_byte(p, value >> 24); 86 eeprom_write_byte(p, value >> 24);
87} 87}
88 88
89void eeprom_update_block(const void *buf, void *addr, uint32_t len) { 89void eeprom_update_block(const void *buf, void *addr, size_t len) {
90 uint8_t * p = (uint8_t *)addr; 90 uint8_t * p = (uint8_t *)addr;
91 const uint8_t *src = (const uint8_t *)buf; 91 const uint8_t *src = (const uint8_t *)buf;
92 while (len--) { 92 while (len--) {