logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

nvm_eeconfig.c (10244B)


  1. // Copyright 2024 Nick Brassel (@tzarc)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <string.h>
  4. #include "nvm_eeconfig.h"
  5. #include "nvm_eeprom_eeconfig_internal.h"
  6. #include "util.h"
  7. #include "eeconfig.h"
  8. #include "debug.h"
  9. #include "eeprom.h"
  10. #include "keycode_config.h"
  11. #ifdef EEPROM_DRIVER
  12. # include "eeprom_driver.h"
  13. #endif
  14. #ifdef AUDIO_ENABLE
  15. # include "audio.h"
  16. #endif
  17. #ifdef BACKLIGHT_ENABLE
  18. # include "backlight.h"
  19. #endif
  20. #ifdef RGBLIGHT_ENABLE
  21. # include "rgblight.h"
  22. #endif
  23. #ifdef RGB_MATRIX_ENABLE
  24. # include "rgb_matrix_types.h"
  25. #endif
  26. #ifdef LED_MATRIX_ENABLE
  27. # include "led_matrix_types.h"
  28. #endif
  29. #ifdef UNICODE_COMMON_ENABLE
  30. # include "unicode.h"
  31. #endif
  32. #ifdef HAPTIC_ENABLE
  33. # include "haptic.h"
  34. #endif
  35. #ifdef CONNECTION_ENABLE
  36. # include "connection.h"
  37. #endif
  38. void nvm_eeconfig_erase(void) {
  39. #ifdef EEPROM_DRIVER
  40. eeprom_driver_format(false);
  41. #endif // EEPROM_DRIVER
  42. }
  43. bool nvm_eeconfig_is_enabled(void) {
  44. return eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER;
  45. }
  46. bool nvm_eeconfig_is_disabled(void) {
  47. return eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF;
  48. }
  49. void nvm_eeconfig_enable(void) {
  50. eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
  51. }
  52. void nvm_eeconfig_disable(void) {
  53. #if defined(EEPROM_DRIVER)
  54. eeprom_driver_format(false);
  55. #endif
  56. eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF);
  57. }
  58. void nvm_eeconfig_read_debug(debug_config_t *debug_config) {
  59. debug_config->raw = eeprom_read_byte(EECONFIG_DEBUG);
  60. }
  61. void nvm_eeconfig_update_debug(const debug_config_t *debug_config) {
  62. eeprom_update_byte(EECONFIG_DEBUG, debug_config->raw);
  63. }
  64. layer_state_t nvm_eeconfig_read_default_layer(void) {
  65. uint8_t val = eeprom_read_byte(EECONFIG_DEFAULT_LAYER);
  66. #ifdef DEFAULT_LAYER_STATE_IS_VALUE_NOT_BITMASK
  67. // stored as a layer number, so convert back to bitmask
  68. return (layer_state_t)1 << val;
  69. #else
  70. // stored as 8-bit-wide bitmask, so read the value directly - handling padding to 16/32 bit layer_state_t
  71. return (layer_state_t)val;
  72. #endif
  73. }
  74. void nvm_eeconfig_update_default_layer(layer_state_t state) {
  75. #ifdef DEFAULT_LAYER_STATE_IS_VALUE_NOT_BITMASK
  76. // stored as a layer number, so only store the highest layer
  77. uint8_t val = get_highest_layer(state);
  78. #else
  79. // stored as 8-bit-wide bitmask, so write the value directly - handling truncation from 16/32 bit layer_state_t
  80. uint8_t val = (uint8_t)state;
  81. #endif
  82. eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val);
  83. }
  84. void nvm_eeconfig_read_keymap(keymap_config_t *keymap_config) {
  85. keymap_config->raw = eeprom_read_word(EECONFIG_KEYMAP);
  86. }
  87. void nvm_eeconfig_update_keymap(const keymap_config_t *keymap_config) {
  88. eeprom_update_word(EECONFIG_KEYMAP, keymap_config->raw);
  89. }
  90. #ifdef AUDIO_ENABLE
  91. void nvm_eeconfig_read_audio(audio_config_t *audio_config) {
  92. audio_config->raw = eeprom_read_byte(EECONFIG_AUDIO);
  93. }
  94. void nvm_eeconfig_update_audio(const audio_config_t *audio_config) {
  95. eeprom_update_byte(EECONFIG_AUDIO, audio_config->raw);
  96. }
  97. #endif // AUDIO_ENABLE
  98. #ifdef UNICODE_COMMON_ENABLE
  99. void nvm_eeconfig_read_unicode_mode(unicode_config_t *unicode_config) {
  100. unicode_config->raw = eeprom_read_byte(EECONFIG_UNICODEMODE);
  101. }
  102. void nvm_eeconfig_update_unicode_mode(const unicode_config_t *unicode_config) {
  103. eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config->raw);
  104. }
  105. #endif // UNICODE_COMMON_ENABLE
  106. #ifdef BACKLIGHT_ENABLE
  107. void nvm_eeconfig_read_backlight(backlight_config_t *backlight_config) {
  108. backlight_config->raw = eeprom_read_byte(EECONFIG_BACKLIGHT);
  109. }
  110. void nvm_eeconfig_update_backlight(const backlight_config_t *backlight_config) {
  111. eeprom_update_byte(EECONFIG_BACKLIGHT, backlight_config->raw);
  112. }
  113. #endif // BACKLIGHT_ENABLE
  114. #ifdef STENO_ENABLE
  115. uint8_t nvm_eeconfig_read_steno_mode(void) {
  116. return eeprom_read_byte(EECONFIG_STENOMODE);
  117. }
  118. void nvm_eeconfig_update_steno_mode(uint8_t val) {
  119. eeprom_update_byte(EECONFIG_STENOMODE, val);
  120. }
  121. #endif // STENO_ENABLE
  122. #ifdef RGBLIGHT_ENABLE
  123. #endif // RGBLIGHT_ENABLE
  124. #ifdef RGB_MATRIX_ENABLE
  125. void nvm_eeconfig_read_rgb_matrix(rgb_config_t *rgb_matrix_config) {
  126. eeprom_read_block(rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_config_t));
  127. }
  128. void nvm_eeconfig_update_rgb_matrix(const rgb_config_t *rgb_matrix_config) {
  129. eeprom_update_block(rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_config_t));
  130. }
  131. #endif // RGB_MATRIX_ENABLE
  132. #ifdef LED_MATRIX_ENABLE
  133. void nvm_eeconfig_read_led_matrix(led_eeconfig_t *led_matrix_config) {
  134. eeprom_read_block(led_matrix_config, EECONFIG_LED_MATRIX, sizeof(led_eeconfig_t));
  135. }
  136. void nvm_eeconfig_update_led_matrix(const led_eeconfig_t *led_matrix_config) {
  137. eeprom_update_block(led_matrix_config, EECONFIG_LED_MATRIX, sizeof(led_eeconfig_t));
  138. }
  139. #endif // LED_MATRIX_ENABLE
  140. #ifdef RGBLIGHT_ENABLE
  141. void nvm_eeconfig_read_rgblight(rgblight_config_t *rgblight_config) {
  142. rgblight_config->raw = eeprom_read_dword(EECONFIG_RGBLIGHT);
  143. rgblight_config->raw |= ((uint64_t)eeprom_read_byte(EECONFIG_RGBLIGHT_EXTENDED) << 32);
  144. }
  145. void nvm_eeconfig_update_rgblight(const rgblight_config_t *rgblight_config) {
  146. eeprom_update_dword(EECONFIG_RGBLIGHT, rgblight_config->raw & 0xFFFFFFFF);
  147. eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, (rgblight_config->raw >> 32) & 0xFF);
  148. }
  149. #endif // RGBLIGHT_ENABLE
  150. #if (EECONFIG_KB_DATA_SIZE) == 0
  151. uint32_t nvm_eeconfig_read_kb(void) {
  152. return eeprom_read_dword(EECONFIG_KEYBOARD);
  153. }
  154. void nvm_eeconfig_update_kb(uint32_t val) {
  155. eeprom_update_dword(EECONFIG_KEYBOARD, val);
  156. }
  157. #endif // (EECONFIG_KB_DATA_SIZE) == 0
  158. #if (EECONFIG_USER_DATA_SIZE) == 0
  159. uint32_t nvm_eeconfig_read_user(void) {
  160. return eeprom_read_dword(EECONFIG_USER);
  161. }
  162. void nvm_eeconfig_update_user(uint32_t val) {
  163. eeprom_update_dword(EECONFIG_USER, val);
  164. }
  165. #endif // (EECONFIG_USER_DATA_SIZE) == 0
  166. #ifdef HAPTIC_ENABLE
  167. void nvm_eeconfig_read_haptic(haptic_config_t *haptic_config) {
  168. haptic_config->raw = eeprom_read_dword(EECONFIG_HAPTIC);
  169. }
  170. void nvm_eeconfig_update_haptic(const haptic_config_t *haptic_config) {
  171. eeprom_update_dword(EECONFIG_HAPTIC, haptic_config->raw);
  172. }
  173. #endif // HAPTIC_ENABLE
  174. #ifdef CONNECTION_ENABLE
  175. void nvm_eeconfig_read_connection(connection_config_t *config) {
  176. config->raw = eeprom_read_byte(EECONFIG_CONNECTION);
  177. }
  178. void nvm_eeconfig_update_connection(const connection_config_t *config) {
  179. eeprom_update_byte(EECONFIG_CONNECTION, config->raw);
  180. }
  181. #endif // CONNECTION_ENABLE
  182. bool nvm_eeconfig_read_handedness(void) {
  183. return !!eeprom_read_byte(EECONFIG_HANDEDNESS);
  184. }
  185. void nvm_eeconfig_update_handedness(bool val) {
  186. eeprom_update_byte(EECONFIG_HANDEDNESS, !!val);
  187. }
  188. #if (EECONFIG_KB_DATA_SIZE) > 0
  189. bool nvm_eeconfig_is_kb_datablock_valid(void) {
  190. return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION);
  191. }
  192. uint32_t nvm_eeconfig_read_kb_datablock(void *data, uint32_t offset, uint32_t length) {
  193. if (eeconfig_is_kb_datablock_valid()) {
  194. void *ee_start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + offset);
  195. void *ee_end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + MIN(EECONFIG_KB_DATA_SIZE, offset + length));
  196. eeprom_read_block(data, ee_start, ee_end - ee_start);
  197. return ee_end - ee_start;
  198. } else {
  199. memset(data, 0, length);
  200. return length;
  201. }
  202. }
  203. uint32_t nvm_eeconfig_update_kb_datablock(const void *data, uint32_t offset, uint32_t length) {
  204. eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
  205. void *ee_start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + offset);
  206. void *ee_end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + MIN(EECONFIG_KB_DATA_SIZE, offset + length));
  207. eeprom_update_block(data, ee_start, ee_end - ee_start);
  208. return ee_end - ee_start;
  209. }
  210. void nvm_eeconfig_init_kb_datablock(void) {
  211. eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION));
  212. void * start = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK);
  213. void * end = (void *)(uintptr_t)(EECONFIG_KB_DATABLOCK + EECONFIG_KB_DATA_SIZE);
  214. long remaining = end - start;
  215. uint8_t dummy[16] = {0};
  216. for (int i = 0; i < EECONFIG_KB_DATA_SIZE; i += sizeof(dummy)) {
  217. int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
  218. eeprom_update_block(dummy, start, this_loop);
  219. start += this_loop;
  220. remaining -= this_loop;
  221. }
  222. }
  223. #endif // (EECONFIG_KB_DATA_SIZE) > 0
  224. #if (EECONFIG_USER_DATA_SIZE) > 0
  225. bool nvm_eeconfig_is_user_datablock_valid(void) {
  226. return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION);
  227. }
  228. uint32_t nvm_eeconfig_read_user_datablock(void *data, uint32_t offset, uint32_t length) {
  229. if (eeconfig_is_user_datablock_valid()) {
  230. void *ee_start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + offset);
  231. void *ee_end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + MIN(EECONFIG_USER_DATA_SIZE, offset + length));
  232. eeprom_read_block(data, ee_start, ee_end - ee_start);
  233. return ee_end - ee_start;
  234. } else {
  235. memset(data, 0, length);
  236. return length;
  237. }
  238. }
  239. uint32_t nvm_eeconfig_update_user_datablock(const void *data, uint32_t offset, uint32_t length) {
  240. eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
  241. void *ee_start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + offset);
  242. void *ee_end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + MIN(EECONFIG_USER_DATA_SIZE, offset + length));
  243. eeprom_update_block(data, ee_start, ee_end - ee_start);
  244. return ee_end - ee_start;
  245. }
  246. void nvm_eeconfig_init_user_datablock(void) {
  247. eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
  248. void * start = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK);
  249. void * end = (void *)(uintptr_t)(EECONFIG_USER_DATABLOCK + EECONFIG_USER_DATA_SIZE);
  250. long remaining = end - start;
  251. uint8_t dummy[16] = {0};
  252. for (int i = 0; i < EECONFIG_USER_DATA_SIZE; i += sizeof(dummy)) {
  253. int this_loop = remaining < sizeof(dummy) ? remaining : sizeof(dummy);
  254. eeprom_update_block(dummy, start, this_loop);
  255. start += this_loop;
  256. remaining -= this_loop;
  257. }
  258. }
  259. #endif // (EECONFIG_USER_DATA_SIZE) > 0