aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPurdea Andrei <andrei@purdea.ro>2021-06-22 05:34:28 +0300
committerGitHub <noreply@github.com>2021-06-21 19:34:28 -0700
commitdd16d3cc7e427c5256f5d2089d0cc2b6bbc776e1 (patch)
tree7be0f07db5a88c4939354d717e8e600fab6f1ab4
parent0e3ae2cde033969507355abcb85f5f7aba2ae978 (diff)
downloadqmk_firmware-dd16d3cc7e427c5256f5d2089d0cc2b6bbc776e1.tar.gz
qmk_firmware-dd16d3cc7e427c5256f5d2089d0cc2b6bbc776e1.zip
eeprom_i2c driver: added EXTERNAL_EEPROM_WP_PIN configuration option. (#12617)
-rw-r--r--docs/eeprom_driver.md3
-rw-r--r--drivers/eeprom/eeprom_i2c.c23
2 files changed, 25 insertions, 1 deletions
diff --git a/docs/eeprom_driver.md b/docs/eeprom_driver.md
index e2c262546..6dcf10c04 100644
--- a/docs/eeprom_driver.md
+++ b/docs/eeprom_driver.md
@@ -31,6 +31,9 @@ Currently QMK supports 24xx-series chips over I2C. As such, requires a working i
31`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32 31`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32
32`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2 32`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2
33`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5 33`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5
34`#define EXTERNAL_EEPROM_WP_PIN` | If defined the WP pin will be toggled appropriately when writing to the EEPROM. | _none_
35
36Some I2C EEPROM manufacturers explicitly recommend against hardcoding the WP pin to ground. This is in order to protect the eeprom memory content during power-up/power-down/brown-out conditions at low voltage where the eeprom is still operational, but the i2c master output might be unpredictable. If a WP pin is configured, then having an external pull-up on the WP pin is recommended.
34 37
35Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`. 38Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
36 39
diff --git a/drivers/eeprom/eeprom_i2c.c b/drivers/eeprom/eeprom_i2c.c
index 4210f06f9..8e80ff544 100644
--- a/drivers/eeprom/eeprom_i2c.c
+++ b/drivers/eeprom/eeprom_i2c.c
@@ -16,6 +16,9 @@
16 16
17#include <stdint.h> 17#include <stdint.h>
18#include <string.h> 18#include <string.h>
19#if defined(EXTERNAL_EEPROM_WP_PIN)
20# include "gpio.h"
21#endif
19 22
20/* 23/*
21 Note that the implementations of eeprom_XXXX_YYYY on AVR are normally 24 Note that the implementations of eeprom_XXXX_YYYY on AVR are normally
@@ -50,7 +53,14 @@ static inline void fill_target_address(uint8_t *buffer, const void *addr) {
50 } 53 }
51} 54}
52 55
53void eeprom_driver_init(void) { i2c_init(); } 56void eeprom_driver_init(void) {
57 i2c_init();
58#if defined(EXTERNAL_EEPROM_WP_PIN)
59 /* We are setting the WP pin to high in a way that requires at least two bit-flips to change back to 0 */
60 writePin(EXTERNAL_EEPROM_WP_PIN, 1);
61 setPinInputHigh(EXTERNAL_EEPROM_WP_PIN);
62#endif
63}
54 64
55void eeprom_driver_erase(void) { 65void eeprom_driver_erase(void) {
56#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT) 66#if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
@@ -89,6 +99,11 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
89 uint8_t * read_buf = (uint8_t *)buf; 99 uint8_t * read_buf = (uint8_t *)buf;
90 uintptr_t target_addr = (uintptr_t)addr; 100 uintptr_t target_addr = (uintptr_t)addr;
91 101
102#if defined(EXTERNAL_EEPROM_WP_PIN)
103 setPinOutput(EXTERNAL_EEPROM_WP_PIN);
104 writePin(EXTERNAL_EEPROM_WP_PIN, 0);
105#endif
106
92 while (len > 0) { 107 while (len > 0) {
93 uintptr_t page_offset = target_addr % EXTERNAL_EEPROM_PAGE_SIZE; 108 uintptr_t page_offset = target_addr % EXTERNAL_EEPROM_PAGE_SIZE;
94 int write_length = EXTERNAL_EEPROM_PAGE_SIZE - page_offset; 109 int write_length = EXTERNAL_EEPROM_PAGE_SIZE - page_offset;
@@ -116,4 +131,10 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
116 target_addr += write_length; 131 target_addr += write_length;
117 len -= write_length; 132 len -= write_length;
118 } 133 }
134
135#if defined(EXTERNAL_EEPROM_WP_PIN)
136 /* We are setting the WP pin to high in a way that requires at least two bit-flips to change back to 0 */
137 writePin(EXTERNAL_EEPROM_WP_PIN, 1);
138 setPinInputHigh(EXTERNAL_EEPROM_WP_PIN);
139#endif
119} 140}