Bladeren bron

eeprom_i2c driver: added EXTERNAL_EEPROM_WP_PIN configuration option. (#12617)

Purdea Andrei 4 jaren geleden
bovenliggende
commit
dd16d3cc7e
2 gewijzigde bestanden met toevoegingen van 25 en 1 verwijderingen
  1. 3 0
      docs/eeprom_driver.md
  2. 22 1
      drivers/eeprom/eeprom_i2c.c

+ 3 - 0
docs/eeprom_driver.md

@@ -31,6 +31,9 @@ Currently QMK supports 24xx-series chips over I2C. As such, requires a working i
 `#define EXTERNAL_EEPROM_PAGE_SIZE`         | Page size of the EEPROM in bytes, as specified in the datasheet                     | 32
 `#define EXTERNAL_EEPROM_PAGE_SIZE`         | Page size of the EEPROM in bytes, as specified in the datasheet                     | 32
 `#define EXTERNAL_EEPROM_ADDRESS_SIZE`      | The number of bytes to transmit for the memory location within the EEPROM           | 2
 `#define EXTERNAL_EEPROM_ADDRESS_SIZE`      | The number of bytes to transmit for the memory location within the EEPROM           | 2
 `#define EXTERNAL_EEPROM_WRITE_TIME`        | Write cycle time of the EEPROM, as specified in the datasheet                       | 5
 `#define EXTERNAL_EEPROM_WRITE_TIME`        | Write cycle time of the EEPROM, as specified in the datasheet                       | 5
+`#define EXTERNAL_EEPROM_WP_PIN`            | If defined the WP pin will be toggled appropriately when writing to the EEPROM.     | _none_
+
+Some 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.
 
 
 Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
 Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`.
 
 

+ 22 - 1
drivers/eeprom/eeprom_i2c.c

@@ -16,6 +16,9 @@
 
 
 #include <stdint.h>
 #include <stdint.h>
 #include <string.h>
 #include <string.h>
+#if defined(EXTERNAL_EEPROM_WP_PIN)
+#    include "gpio.h"
+#endif
 
 
 /*
 /*
     Note that the implementations of eeprom_XXXX_YYYY on AVR are normally
     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) {
     }
     }
 }
 }
 
 
-void eeprom_driver_init(void) { i2c_init(); }
+void eeprom_driver_init(void) {
+    i2c_init();
+#if defined(EXTERNAL_EEPROM_WP_PIN)
+    /* We are setting the WP pin to high in a way that requires at least two bit-flips to change back to 0 */
+    writePin(EXTERNAL_EEPROM_WP_PIN, 1);
+    setPinInputHigh(EXTERNAL_EEPROM_WP_PIN);
+#endif
+}
 
 
 void eeprom_driver_erase(void) {
 void eeprom_driver_erase(void) {
 #if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
 #if defined(CONSOLE_ENABLE) && defined(DEBUG_EEPROM_OUTPUT)
@@ -89,6 +99,11 @@ void eeprom_write_block(const void *buf, void *addr, size_t len) {
     uint8_t * read_buf    = (uint8_t *)buf;
     uint8_t * read_buf    = (uint8_t *)buf;
     uintptr_t target_addr = (uintptr_t)addr;
     uintptr_t target_addr = (uintptr_t)addr;
 
 
+#if defined(EXTERNAL_EEPROM_WP_PIN)
+    setPinOutput(EXTERNAL_EEPROM_WP_PIN);
+    writePin(EXTERNAL_EEPROM_WP_PIN, 0);
+#endif
+
     while (len > 0) {
     while (len > 0) {
         uintptr_t page_offset  = target_addr % EXTERNAL_EEPROM_PAGE_SIZE;
         uintptr_t page_offset  = target_addr % EXTERNAL_EEPROM_PAGE_SIZE;
         int       write_length = EXTERNAL_EEPROM_PAGE_SIZE - page_offset;
         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) {
         target_addr += write_length;
         target_addr += write_length;
         len -= write_length;
         len -= write_length;
     }
     }
+
+#if defined(EXTERNAL_EEPROM_WP_PIN)
+    /* We are setting the WP pin to high in a way that requires at least two bit-flips to change back to 0 */
+    writePin(EXTERNAL_EEPROM_WP_PIN, 1);
+    setPinInputHigh(EXTERNAL_EEPROM_WP_PIN);
+#endif
 }
 }