eeprom.c 5.4 KB

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