eeprom.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* sd2snes - SD card based universal cartridge for the SNES
  2. Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
  3. This file was adapted from sd2iec, written by Ingo Korb.
  4. Original copyright header follows:
  5. */
  6. /* sd2iec - SD/MMC to Commodore serial bus interface/controller
  7. Copyright (C) 2007-2009 Ingo Korb <ingo@akana.de>
  8. Inspiration and low-level SD/MMC access based on code from MMC2IEC
  9. by Lars Pontoppidan et al., see sdcard.c|h and config.h.
  10. FAT filesystem access based on code from ChaN and Jim Brain, see ff.c|h.
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; version 2 of the License only.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with this program; if not, write to the Free Software
  20. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. eeprom.c: Persistent configuration storage
  22. */
  23. #include <avr/eeprom.h>
  24. #include <avr/io.h>
  25. #include "config.h"
  26. #include "diskio.h"
  27. #include "fatops.h"
  28. #include "flags.h"
  29. #include "iec.h"
  30. #include "timer.h"
  31. #include "eeprom.h"
  32. #include "uart.h"
  33. /**
  34. * struct storedconfig - in-eeprom data structure
  35. * @dummy : EEPROM position 0 is unused
  36. * @checksum : Checksum over the EEPROM contents
  37. * @structsize : size of the eeprom structure
  38. * @osccal : stored value of OSCCAL
  39. * @globalflags: subset of the globalflags variable
  40. * @address : device address set by software
  41. * @hardaddress: device address set by jumpers
  42. * @fileexts : file extension mapping mode
  43. * @drvflags0 : 16 bits of drv mappings, organized as 4 nybbles.
  44. * @drvflags1 : 16 bits of drv mappings, organized as 4 nybbles.
  45. *
  46. * This is the data structure for the contents of the EEPROM.
  47. */
  48. static EEMEM struct {
  49. uint8_t dummy;
  50. uint8_t checksum;
  51. uint16_t structsize;
  52. uint8_t osccal;
  53. uint8_t global_flags;
  54. uint8_t address;
  55. uint8_t hardaddress;
  56. uint8_t fileexts;
  57. uint16_t drvconfig0;
  58. uint16_t drvconfig1;
  59. } storedconfig;
  60. /**
  61. * read_configuration - reads configuration from EEPROM
  62. *
  63. * This function reads the stored configuration values from the EEPROM.
  64. * If the stored checksum doesn't match the calculated one nothing will
  65. * be changed.
  66. */
  67. void read_configuration(void) {
  68. uint16_t i,size;
  69. uint8_t checksum, tmp;
  70. /* Set default values */
  71. globalflags |= JIFFY_ENABLED; /* JiffyDos enabled */
  72. globalflags |= POSTMATCH; /* Post-* matching enabled */
  73. globalflags |= FAT32_FREEBLOCKS; /* Calculate the number of free blocks on FAT32 */
  74. file_extension_mode = 1; /* Store x00 extensions except for PRG */
  75. set_drive_config(get_default_driveconfig()); /* Set the default drive configuration */
  76. /* Use the NEXT button to skip reading the EEPROM configuration */
  77. if (!(BUTTON_PIN & BUTTON_NEXT)) {
  78. ignore_keys();
  79. return;
  80. }
  81. size = eeprom_read_word(&storedconfig.structsize);
  82. /* Calculate checksum of EEPROM contents */
  83. checksum = 0;
  84. for (i=2; i<size; i++)
  85. checksum += eeprom_read_byte((uint8_t *)i);
  86. /* Abort if the checksum doesn't match */
  87. if (checksum != eeprom_read_byte(&storedconfig.checksum)) {
  88. EEAR = 0;
  89. return;
  90. }
  91. /* Read data from EEPROM */
  92. OSCCAL = eeprom_read_byte(&storedconfig.osccal);
  93. tmp = eeprom_read_byte(&storedconfig.global_flags);
  94. globalflags &= (uint8_t)~(JIFFY_ENABLED | POSTMATCH |
  95. EXTENSION_HIDING | FAT32_FREEBLOCKS);
  96. globalflags |= tmp;
  97. if (eeprom_read_byte(&storedconfig.hardaddress) == DEVICE_SELECT)
  98. device_address = eeprom_read_byte(&storedconfig.address);
  99. file_extension_mode = eeprom_read_byte(&storedconfig.fileexts);
  100. #ifdef NEED_DISKMUX
  101. if (size > 9) {
  102. uint32_t tmpconfig;
  103. tmpconfig = eeprom_read_word(&storedconfig.drvconfig0);
  104. tmpconfig |= (uint32_t)eeprom_read_word(&storedconfig.drvconfig1) << 16;
  105. set_drive_config(tmpconfig);
  106. }
  107. /* sanity check. If the user has truly turned off all drives, turn the
  108. * defaults back on
  109. */
  110. if(drive_config == 0xffffffff)
  111. set_drive_config(get_default_driveconfig());
  112. #endif
  113. /* Paranoia: Set EEPROM address register to the dummy entry */
  114. EEAR = 0;
  115. }
  116. /**
  117. * write_configuration - stores configuration data to EEPROM
  118. *
  119. * This function stores the current configuration values to the EEPROM.
  120. */
  121. void write_configuration(void) {
  122. uint16_t i;
  123. uint8_t checksum;
  124. /* Write configuration to EEPROM */
  125. eeprom_write_word(&storedconfig.structsize, sizeof(storedconfig));
  126. eeprom_write_byte(&storedconfig.osccal, OSCCAL);
  127. eeprom_write_byte(&storedconfig.global_flags,
  128. globalflags & (JIFFY_ENABLED | POSTMATCH |
  129. EXTENSION_HIDING | FAT32_FREEBLOCKS));
  130. eeprom_write_byte(&storedconfig.address, device_address);
  131. eeprom_write_byte(&storedconfig.hardaddress, DEVICE_SELECT);
  132. eeprom_write_byte(&storedconfig.fileexts, file_extension_mode);
  133. #ifdef NEED_DISKMUX
  134. eeprom_write_word(&storedconfig.drvconfig0, drive_config);
  135. eeprom_write_word(&storedconfig.drvconfig1, drive_config >> 16);
  136. #endif
  137. /* Calculate checksum over EEPROM contents */
  138. checksum = 0;
  139. for (i=2;i<sizeof(storedconfig);i++)
  140. checksum += eeprom_read_byte((uint8_t *) i);
  141. /* Store checksum to EEPROM */
  142. eeprom_write_byte(&storedconfig.checksum, checksum);
  143. /* Paranoia: Set EEPROM address register to the dummy entry */
  144. EEAR = 0;
  145. }