Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

eeconfig.c 15KB

Squashed 'tmk_core/' changes from 57d27a8..08ce4c3 08ce4c3 Add update for chibios in README 30cac1d Merge remote-tracking branch 'flabbergast-tmk_keyboard/chibios' f218a38 core: Remove unused warning. Fix tmk_keyboard/#293 3e68807 Chibios: add more guards for transmitting (fix a deadlock bug). cecc807 core: Speed up compilation d01d959 Merge remote-tracking branch 'upstream/master' into chibios 8ff12ae Merge pull request #230 from jerryen/master 3afb83d core: Add note about sudo and git 2525d5d Chibios: Update to new USB API. 2fc5cd6 Merge branch 'master' into chibios 6f5511a core: Fix variable initialize 02a15fa core: Fix variable init and header include 1833ca1 Merge pull request #292 from obones/command_warning bc9dc6f Merge pull request #294 from shayneholmes/fix-debug-message c1b891b Merge pull request #295 from doopai/master 1da837c core: Add macro commands SM(), RM() and CM() d9d5a93 Add support for storing, restoring and clearing modifiers in macros 4f371c0 core: Add dfu-programmer example to doc/build.md ba3792e core: Fix doc/build.md 4b99fed remove SERIAL_SOFT_DEBUG macro 984accb Fix typo in bootmagic debug message 67a7ea1 usb_usb: Fix for keymap editor 2fc9ae4 host_driver is only used if KEYBOARD_LOCK_ENABLE is defined a35cdea Chibios: add 'core/protocol' to the makefiles' search path. 5ed2fd6 Merge remote-tracking branch 'upstream/master' into chibios bbc4851 Do timeout when writing to CONSOLE EP queue. 2450559 Remove an errant comma trailing the KC_ERAS macro alias 8465747 Merge pull request #270 from jeffgran/single-tap-toggle a37339a Merge pull request #271 from jeffgran/default-layer-toggle 8e732f7 core: Update doc/build.md and remove other_projects.md e47dc15 Workaround for compiler warnings when console disabled. 4184c52 Add maple mini code. b555238 core: Fix rules.mk for dfu target 26dacf4 add ACTION_DEFAULT_LAYER_TOGGLE to toggle a default layer on/off 83607d9 enable TAPPING_TOGGLE=1 to work correctly bef3089 Merge branch 'master' into chibios f7a55fd core: Fix debug print of usb_hid 1402f7d core: Add keycode KC_JPY for JIS 8e3a460 Chibios: Remove the wait in the main loop. 7d41746 ChibiOS: prettify/document sleep_led code. 235cdee ChibiOS: Update infinity bootloader code to match updated ChibiOS. 807bf1e Chibios: Add breathing sleep LED on Kinetis MCUs. ba3bf7c ChibiOS: make reset request more CMSISy. bf2ffd4 Add correct chibios/bootloader_jump for infinity KB. f5e03fd Chibios/usb_main: rename a variable for clarity. 63a330c Fix drop key stroke d8f5b06 Fix report size of boot protocol. 38abb50 ChibiOS/STM32: send remote wakeup. 6725650 ChibiOS/kinetis: sending remote wakeup. 69f6e54 Chibios: use WFI in idle. WIP suspend stuff. 02f044b Move chibios/cortex selection to local Makefiles. fa59dfa Rename chibios example keyboard. 5c060de Add eeprom support for chibios/kinetis. efd0044 Move declaration of keymap_config. 7196b24 Make bootmagic.c code portable (_delay_ms -> wait_ms). 37b15b2 Add missing #include to keymap.c. 31316e3 Merge branch 'master' into chibios 166f312 Fix chibios/usb_main GET_REPORT handing. 57ac6c2 Add ARM Teensies bootloader code. 1758086 Move STM32 bootloader address config to separate .h file. 03bb026 Rename some Makefile defines. 76ba6ac NKRO fixes. 06498f8 Update chibios README. db0a4f5 Add basic sleep_led for chibios. c3f930e Move AVR specific sleep_led.c into avr. 4069494 Fix bootloader-jump compiling. 9117f7b Small updates. 269cb85 Implement jump-to-bootloader. 7e81b34 Move chibios to tool. 923a892 Make usb_main more USB_DRIVER #define independent. aa054f0 Add ChibiOS support (USB stack + support files). 1e3e282 Modularity and gcc warnings fixes. 2f60ce0 Add KEYBOARD_LOCK_ENABLE to makefile git-subtree-dir: tmk_core git-subtree-split: 08ce4c3021d2ecd446c5b9a137aded65423d241e
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. #include "ch.h"
  2. #include "hal.h"
  3. #include "eeconfig.h"
  4. /*************************************/
  5. /* Hardware backend */
  6. /* */
  7. /* Code from PJRC/Teensyduino */
  8. /*************************************/
  9. /* Teensyduino Core Library
  10. * http://www.pjrc.com/teensy/
  11. * Copyright (c) 2013 PJRC.COM, LLC.
  12. *
  13. * Permission is hereby granted, free of charge, to any person obtaining
  14. * a copy of this software and associated documentation files (the
  15. * "Software"), to deal in the Software without restriction, including
  16. * without limitation the rights to use, copy, modify, merge, publish,
  17. * distribute, sublicense, and/or sell copies of the Software, and to
  18. * permit persons to whom the Software is furnished to do so, subject to
  19. * the following conditions:
  20. *
  21. * 1. The above copyright notice and this permission notice shall be
  22. * included in all copies or substantial portions of the Software.
  23. *
  24. * 2. If the Software is incorporated into a build system that allows
  25. * selection among a list of target devices, then similar target
  26. * devices manufactured by PJRC.COM must be included in the list of
  27. * target devices and selectable in the same manner.
  28. *
  29. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  30. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  31. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  32. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  33. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  34. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  35. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  36. * SOFTWARE.
  37. */
  38. #if defined(K20x) /* chip selection */
  39. /* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
  40. // The EEPROM is really RAM with a hardware-based backup system to
  41. // flash memory. Selecting a smaller size EEPROM allows more wear
  42. // leveling, for higher write endurance. If you edit this file,
  43. // set this to the smallest size your application can use. Also,
  44. // due to Freescale's implementation, writing 16 or 32 bit words
  45. // (aligned to 2 or 4 byte boundaries) has twice the endurance
  46. // compared to writing 8 bit bytes.
  47. //
  48. #define EEPROM_SIZE 32
  49. // Writing unaligned 16 or 32 bit data is handled automatically when
  50. // this is defined, but at a cost of extra code size. Without this,
  51. // any unaligned write will cause a hard fault exception! If you're
  52. // absolutely sure all 16 and 32 bit writes will be aligned, you can
  53. // remove the extra unnecessary code.
  54. //
  55. #define HANDLE_UNALIGNED_WRITES
  56. // Minimum EEPROM Endurance
  57. // ------------------------
  58. #if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
  59. #define EEESIZE 0x33
  60. #elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
  61. #define EEESIZE 0x34
  62. #elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
  63. #define EEESIZE 0x35
  64. #elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
  65. #define EEESIZE 0x36
  66. #elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
  67. #define EEESIZE 0x37
  68. #elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
  69. #define EEESIZE 0x38
  70. #elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
  71. #define EEESIZE 0x39
  72. #endif
  73. void eeprom_initialize(void)
  74. {
  75. uint32_t count=0;
  76. uint16_t do_flash_cmd[] = {
  77. 0xf06f, 0x037f, 0x7003, 0x7803,
  78. 0xf013, 0x0f80, 0xd0fb, 0x4770};
  79. uint8_t status;
  80. if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) {
  81. // FlexRAM is configured as traditional RAM
  82. // We need to reconfigure for EEPROM usage
  83. FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command
  84. FTFL->FCCOB4 = EEESIZE; // EEPROM Size
  85. FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
  86. __disable_irq();
  87. // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
  88. (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT));
  89. __enable_irq();
  90. status = FTFL->FSTAT;
  91. if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) {
  92. FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL));
  93. return; // error
  94. }
  95. }
  96. // wait for eeprom to become ready (is this really necessary?)
  97. while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
  98. if (++count > 20000) break;
  99. }
  100. }
  101. #define FlexRAM ((uint8_t *)0x14000000)
  102. uint8_t eeprom_read_byte(const uint8_t *addr)
  103. {
  104. uint32_t offset = (uint32_t)addr;
  105. if (offset >= EEPROM_SIZE) return 0;
  106. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  107. return FlexRAM[offset];
  108. }
  109. uint16_t eeprom_read_word(const uint16_t *addr)
  110. {
  111. uint32_t offset = (uint32_t)addr;
  112. if (offset >= EEPROM_SIZE-1) return 0;
  113. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  114. return *(uint16_t *)(&FlexRAM[offset]);
  115. }
  116. uint32_t eeprom_read_dword(const uint32_t *addr)
  117. {
  118. uint32_t offset = (uint32_t)addr;
  119. if (offset >= EEPROM_SIZE-3) return 0;
  120. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  121. return *(uint32_t *)(&FlexRAM[offset]);
  122. }
  123. void eeprom_read_block(void *buf, const void *addr, uint32_t len)
  124. {
  125. uint32_t offset = (uint32_t)addr;
  126. uint8_t *dest = (uint8_t *)buf;
  127. uint32_t end = offset + len;
  128. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  129. if (end > EEPROM_SIZE) end = EEPROM_SIZE;
  130. while (offset < end) {
  131. *dest++ = FlexRAM[offset++];
  132. }
  133. }
  134. int eeprom_is_ready(void)
  135. {
  136. return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0;
  137. }
  138. static void flexram_wait(void)
  139. {
  140. while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
  141. // TODO: timeout
  142. }
  143. }
  144. void eeprom_write_byte(uint8_t *addr, uint8_t value)
  145. {
  146. uint32_t offset = (uint32_t)addr;
  147. if (offset >= EEPROM_SIZE) return;
  148. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  149. if (FlexRAM[offset] != value) {
  150. FlexRAM[offset] = value;
  151. flexram_wait();
  152. }
  153. }
  154. void eeprom_write_word(uint16_t *addr, uint16_t value)
  155. {
  156. uint32_t offset = (uint32_t)addr;
  157. if (offset >= EEPROM_SIZE-1) return;
  158. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  159. #ifdef HANDLE_UNALIGNED_WRITES
  160. if ((offset & 1) == 0) {
  161. #endif
  162. if (*(uint16_t *)(&FlexRAM[offset]) != value) {
  163. *(uint16_t *)(&FlexRAM[offset]) = value;
  164. flexram_wait();
  165. }
  166. #ifdef HANDLE_UNALIGNED_WRITES
  167. } else {
  168. if (FlexRAM[offset] != value) {
  169. FlexRAM[offset] = value;
  170. flexram_wait();
  171. }
  172. if (FlexRAM[offset + 1] != (value >> 8)) {
  173. FlexRAM[offset + 1] = value >> 8;
  174. flexram_wait();
  175. }
  176. }
  177. #endif
  178. }
  179. void eeprom_write_dword(uint32_t *addr, uint32_t value)
  180. {
  181. uint32_t offset = (uint32_t)addr;
  182. if (offset >= EEPROM_SIZE-3) return;
  183. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  184. #ifdef HANDLE_UNALIGNED_WRITES
  185. switch (offset & 3) {
  186. case 0:
  187. #endif
  188. if (*(uint32_t *)(&FlexRAM[offset]) != value) {
  189. *(uint32_t *)(&FlexRAM[offset]) = value;
  190. flexram_wait();
  191. }
  192. return;
  193. #ifdef HANDLE_UNALIGNED_WRITES
  194. case 2:
  195. if (*(uint16_t *)(&FlexRAM[offset]) != value) {
  196. *(uint16_t *)(&FlexRAM[offset]) = value;
  197. flexram_wait();
  198. }
  199. if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
  200. *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
  201. flexram_wait();
  202. }
  203. return;
  204. default:
  205. if (FlexRAM[offset] != value) {
  206. FlexRAM[offset] = value;
  207. flexram_wait();
  208. }
  209. if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
  210. *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
  211. flexram_wait();
  212. }
  213. if (FlexRAM[offset + 3] != (value >> 24)) {
  214. FlexRAM[offset + 3] = value >> 24;
  215. flexram_wait();
  216. }
  217. }
  218. #endif
  219. }
  220. void eeprom_write_block(const void *buf, void *addr, uint32_t len)
  221. {
  222. uint32_t offset = (uint32_t)addr;
  223. const uint8_t *src = (const uint8_t *)buf;
  224. if (offset >= EEPROM_SIZE) return;
  225. if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
  226. if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
  227. if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
  228. while (len > 0) {
  229. uint32_t lsb = offset & 3;
  230. if (lsb == 0 && len >= 4) {
  231. // write aligned 32 bits
  232. uint32_t val32;
  233. val32 = *src++;
  234. val32 |= (*src++ << 8);
  235. val32 |= (*src++ << 16);
  236. val32 |= (*src++ << 24);
  237. if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
  238. *(uint32_t *)(&FlexRAM[offset]) = val32;
  239. flexram_wait();
  240. }
  241. offset += 4;
  242. len -= 4;
  243. } else if ((lsb == 0 || lsb == 2) && len >= 2) {
  244. // write aligned 16 bits
  245. uint16_t val16;
  246. val16 = *src++;
  247. val16 |= (*src++ << 8);
  248. if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
  249. *(uint16_t *)(&FlexRAM[offset]) = val16;
  250. flexram_wait();
  251. }
  252. offset += 2;
  253. len -= 2;
  254. } else {
  255. // write 8 bits
  256. uint8_t val8 = *src++;
  257. if (FlexRAM[offset] != val8) {
  258. FlexRAM[offset] = val8;
  259. flexram_wait();
  260. }
  261. offset++;
  262. len--;
  263. }
  264. }
  265. }
  266. /*
  267. void do_flash_cmd(volatile uint8_t *fstat)
  268. {
  269. *fstat = 0x80;
  270. while ((*fstat & 0x80) == 0) ; // wait
  271. }
  272. 00000000 <do_flash_cmd>:
  273. 0: f06f 037f mvn.w r3, #127 ; 0x7f
  274. 4: 7003 strb r3, [r0, #0]
  275. 6: 7803 ldrb r3, [r0, #0]
  276. 8: f013 0f80 tst.w r3, #128 ; 0x80
  277. c: d0fb beq.n 6 <do_flash_cmd+0x6>
  278. e: 4770 bx lr
  279. */
  280. #elif defined(KL2x) /* chip selection */
  281. /* Teensy LC (emulated) */
  282. #define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
  283. extern uint32_t __eeprom_workarea_start__;
  284. extern uint32_t __eeprom_workarea_end__;
  285. #define EEPROM_SIZE 128
  286. static uint32_t flashend = 0;
  287. void eeprom_initialize(void)
  288. {
  289. const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
  290. do {
  291. if (*p++ == 0xFFFF) {
  292. flashend = (uint32_t)(p - 2);
  293. return;
  294. }
  295. } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
  296. flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
  297. }
  298. uint8_t eeprom_read_byte(const uint8_t *addr)
  299. {
  300. uint32_t offset = (uint32_t)addr;
  301. const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
  302. const uint16_t *end = (const uint16_t *)((uint32_t)flashend);
  303. uint16_t val;
  304. uint8_t data=0xFF;
  305. if (!end) {
  306. eeprom_initialize();
  307. end = (const uint16_t *)((uint32_t)flashend);
  308. }
  309. if (offset < EEPROM_SIZE) {
  310. while (p <= end) {
  311. val = *p++;
  312. if ((val & 255) == offset) data = val >> 8;
  313. }
  314. }
  315. return data;
  316. }
  317. static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data)
  318. {
  319. // with great power comes great responsibility....
  320. uint32_t stat;
  321. *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC);
  322. *(uint32_t *)&(FTFA->FCCOB7) = data;
  323. __disable_irq();
  324. (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT));
  325. __enable_irq();
  326. stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);
  327. if (stat) {
  328. FTFA->FSTAT = stat;
  329. }
  330. MCM->PLACR |= MCM_PLACR_CFCC;
  331. }
  332. void eeprom_write_byte(uint8_t *addr, uint8_t data)
  333. {
  334. uint32_t offset = (uint32_t)addr;
  335. const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend);
  336. uint32_t i, val, flashaddr;
  337. uint16_t do_flash_cmd[] = {
  338. 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
  339. uint8_t buf[EEPROM_SIZE];
  340. if (offset >= EEPROM_SIZE) return;
  341. if (!end) {
  342. eeprom_initialize();
  343. end = (const uint16_t *)((uint32_t)flashend);
  344. }
  345. if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) {
  346. val = (data << 8) | offset;
  347. flashaddr = (uint32_t)end;
  348. flashend = flashaddr;
  349. if ((flashaddr & 2) == 0) {
  350. val |= 0xFFFF0000;
  351. } else {
  352. val <<= 16;
  353. val |= 0x0000FFFF;
  354. }
  355. flash_write(do_flash_cmd, flashaddr, val);
  356. } else {
  357. for (i=0; i < EEPROM_SIZE; i++) {
  358. buf[i] = 0xFF;
  359. }
  360. for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) {
  361. val = *p;
  362. if ((val & 255) < EEPROM_SIZE) {
  363. buf[val & 255] = val >> 8;
  364. }
  365. }
  366. buf[offset] = data;
  367. for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) {
  368. *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr;
  369. __disable_irq();
  370. (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT));
  371. __enable_irq();
  372. val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);;
  373. if (val) FTFA->FSTAT = val;
  374. MCM->PLACR |= MCM_PLACR_CFCC;
  375. }
  376. flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__);
  377. for (i=0; i < EEPROM_SIZE; i++) {
  378. if (buf[i] == 0xFF) continue;
  379. if ((flashaddr & 2) == 0) {
  380. val = (buf[i] << 8) | i;
  381. } else {
  382. val = val | (buf[i] << 24) | (i << 16);
  383. flash_write(do_flash_cmd, flashaddr, val);
  384. }
  385. flashaddr += 2;
  386. }
  387. flashend = flashaddr;
  388. if ((flashaddr & 2)) {
  389. val |= 0xFFFF0000;
  390. flash_write(do_flash_cmd, flashaddr, val);
  391. }
  392. }
  393. }
  394. /*
  395. void do_flash_cmd(volatile uint8_t *fstat)
  396. {
  397. *fstat = 0x80;
  398. while ((*fstat & 0x80) == 0) ; // wait
  399. }
  400. 00000000 <do_flash_cmd>:
  401. 0: 2380 movs r3, #128 ; 0x80
  402. 2: 7003 strb r3, [r0, #0]
  403. 4: 7803 ldrb r3, [r0, #0]
  404. 6: b25b sxtb r3, r3
  405. 8: 2b00 cmp r3, #0
  406. a: dafb bge.n 4 <do_flash_cmd+0x4>
  407. c: 4770 bx lr
  408. */
  409. uint16_t eeprom_read_word(const uint16_t *addr)
  410. {
  411. const uint8_t *p = (const uint8_t *)addr;
  412. return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
  413. }
  414. uint32_t eeprom_read_dword(const uint32_t *addr)
  415. {
  416. const uint8_t *p = (const uint8_t *)addr;
  417. return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
  418. | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
  419. }
  420. void eeprom_read_block(void *buf, const void *addr, uint32_t len)
  421. {
  422. const uint8_t *p = (const uint8_t *)addr;
  423. uint8_t *dest = (uint8_t *)buf;
  424. while (len--) {
  425. *dest++ = eeprom_read_byte(p++);
  426. }
  427. }
  428. int eeprom_is_ready(void)
  429. {
  430. return 1;
  431. }
  432. void eeprom_write_word(uint16_t *addr, uint16_t value)
  433. {
  434. uint8_t *p = (uint8_t *)addr;
  435. eeprom_write_byte(p++, value);
  436. eeprom_write_byte(p, value >> 8);
  437. }
  438. void eeprom_write_dword(uint32_t *addr, uint32_t value)
  439. {
  440. uint8_t *p = (uint8_t *)addr;
  441. eeprom_write_byte(p++, value);
  442. eeprom_write_byte(p++, value >> 8);
  443. eeprom_write_byte(p++, value >> 16);
  444. eeprom_write_byte(p, value >> 24);
  445. }
  446. void eeprom_write_block(const void *buf, void *addr, uint32_t len)
  447. {
  448. uint8_t *p = (uint8_t *)addr;
  449. const uint8_t *src = (const uint8_t *)buf;
  450. while (len--) {
  451. eeprom_write_byte(p++, *src++);
  452. }
  453. }
  454. #else
  455. #error EEPROM support not implemented for your chip
  456. #endif /* chip selection */
  457. /*****************/
  458. /* TMK functions */
  459. /*****************/
  460. void eeconfig_init(void)
  461. {
  462. eeprom_write_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
  463. eeprom_write_byte(EECONFIG_DEBUG, 0);
  464. eeprom_write_byte(EECONFIG_DEFAULT_LAYER, 0);
  465. eeprom_write_byte(EECONFIG_KEYMAP, 0);
  466. eeprom_write_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
  467. #ifdef BACKLIGHT_ENABLE
  468. eeprom_write_byte(EECONFIG_BACKLIGHT, 0);
  469. #endif
  470. }
  471. void eeconfig_enable(void)
  472. {
  473. eeprom_write_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
  474. }
  475. void eeconfig_disable(void)
  476. {
  477. eeprom_write_word(EECONFIG_MAGIC, 0xFFFF);
  478. }
  479. bool eeconfig_is_enabled(void)
  480. {
  481. return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
  482. }
  483. uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); }
  484. void eeconfig_write_debug(uint8_t val) { eeprom_write_byte(EECONFIG_DEBUG, val); }
  485. uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); }
  486. void eeconfig_write_default_layer(uint8_t val) { eeprom_write_byte(EECONFIG_DEFAULT_LAYER, val); }
  487. uint8_t eeconfig_read_keymap(void) { return eeprom_read_byte(EECONFIG_KEYMAP); }
  488. void eeconfig_write_keymap(uint8_t val) { eeprom_write_byte(EECONFIG_KEYMAP, val); }
  489. #ifdef BACKLIGHT_ENABLE
  490. uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
  491. void eeconfig_write_backlight(uint8_t val) { eeprom_write_byte(EECONFIG_BACKLIGHT, val); }
  492. #endif