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.

218 lines
5.4KB

  1. #include <SPI.h>
  2. #include <SdFat.h>
  3. #include <SdFatUtil.h>
  4. const uint8_t SD_CS_PIN = SS;
  5. SdFat sd;
  6. SdFile file;
  7. char name[260];
  8. // Serial output stream
  9. ArduinoOutStream cout(Serial);
  10. // Serial in buffer.
  11. char cinBuf[10];
  12. // Serial input stream
  13. ArduinoInStream cin(Serial, cinBuf, sizeof(cinBuf));
  14. //------------------------------------------------------------------------------
  15. const char* testName[] = {
  16. "low.low",
  17. "low.Mix",
  18. "low.UP",
  19. "Mix.low",
  20. "Mix.Mix",
  21. "Mix.UP",
  22. "UP.low",
  23. "UP.Mix",
  24. "UP.UP",
  25. ".dot",
  26. ".dot.dot",
  27. "A b c . txt",
  28. " Leading space and no extension",
  29. "Trailing dots and space . . .",
  30. "Long extension.extension",
  31. "Space after dot. txt",
  32. "Dot.dot.test.txt",
  33. "Dot.dot.test.seq.txt",
  34. "LOW.LOW",
  35. "MIX.MIX",
  36. "Invalid character *.test"
  37. };
  38. //------------------------------------------------------------------------------
  39. bool checkName(char first, size_t len) {
  40. size_t i;
  41. if (len < 5 || len > sizeof(name)) {
  42. return false;
  43. }
  44. if ( name[0] != first) {
  45. return false;
  46. }
  47. for (i = 1; i < (len - 4); i++) {
  48. if (name[i] != (char)('0' + (i + 1) %10)) {
  49. return false;
  50. }
  51. }
  52. const char* p = ".txt";
  53. while (*p) {
  54. if (name[i++] != *p++) {
  55. return false;
  56. }
  57. }
  58. return name[i] == 0;
  59. }
  60. //------------------------------------------------------------------------------
  61. void makeName(char first, size_t len) {
  62. size_t i;
  63. if (len > sizeof(name)) {
  64. len = 255;
  65. }
  66. if (len < 5) {
  67. len = 5;
  68. }
  69. name[0] = first;
  70. for (i = 1; i < (len - 4); i++) {
  71. name[i] = '0' + (i + 1) %10;
  72. }
  73. const char* p = ".txt";
  74. while (*p) name[i++] = *p++;
  75. name[i] = 0;
  76. }
  77. //------------------------------------------------------------------------------
  78. // test open, remove, getName, and ls.
  79. void basicTest() {
  80. size_t i;
  81. size_t n = sd.vol()->fatType() == 32 ? 255 : 99;
  82. uint16_t maxIndex = 0;
  83. makeName('Z', 256);
  84. if (!file.open(name, O_RDWR | O_CREAT)) {
  85. cout << F("255 limit OK") << endl;
  86. } else {
  87. sd.errorHalt(F("255 limit"));
  88. }
  89. for (i = 5; i <= n; i++) {
  90. makeName('A', i);
  91. if (!file.open(name, O_RDWR | O_CREAT)) {
  92. sd.errorHalt(F("open A"));
  93. }
  94. file.println(name);
  95. cout << setw(3) << i << setw(5) << file.dirIndex() << F(" open A") << endl;
  96. if (file.fileSize() != (i + 2)) {
  97. sd.errorHalt(F("file size A"));
  98. }
  99. if (file.dirIndex() >= maxIndex) {
  100. maxIndex = file.dirIndex();
  101. } else {
  102. sd.errorHalt(F("dirIndex"));
  103. }
  104. file.close();
  105. if (!file.open(sd.vwd(), maxIndex, O_READ)) {
  106. sd.errorHalt(F("open by index"));
  107. }
  108. memset(name, 0, sizeof(name));
  109. if (!file.getName(name, sizeof(name))) {
  110. sd.errorHalt(F("getName"));
  111. }
  112. if (!checkName('A', i)) {
  113. cout << name << endl;
  114. sd.errorHalt(F("checkName"));
  115. }
  116. file.close();
  117. }
  118. for (i = n; i >= 5; i -= 2) {
  119. makeName('A', i);
  120. cout << setw(3) << i << F( " rm A") << endl;
  121. if (!sd.remove(name)) {
  122. sd.errorHalt(F("remove A"));
  123. }
  124. }
  125. for (i = n; i >= 5; i -= 2) {
  126. makeName('B', i);
  127. if (!file.open(name, O_RDWR | O_CREAT)) {
  128. sd.errorHalt(F("open B"));
  129. }
  130. file.println(name);
  131. cout << setw(3) << i << setw(5) << file.dirIndex() << F(" open B") << endl;
  132. if (file.fileSize() != (i + 2)) {
  133. sd.errorHalt(F("file size B"));
  134. }
  135. if (file.dirIndex() > maxIndex) {
  136. sd.errorHalt(F("maxIndex"));
  137. }
  138. file.close();
  139. }
  140. cout << endl << F("----- ls ------") << endl;
  141. sd.ls();
  142. for (i = 5; i <= n; i++) {
  143. char fc = i & 1 ? 'B' : 'A';
  144. makeName(fc, i);
  145. cout << setw(3) << i << F(" rm ") << fc << endl;
  146. if (!sd.remove(name)) {
  147. sd.errorHalt(F("remove A/B"));
  148. }
  149. }
  150. if (file.openNext(sd.vwd())) {
  151. sd.errorHalt(F("remove all"));
  152. }
  153. cout << endl << F("basicTest done") << endl;
  154. }
  155. //------------------------------------------------------------------------------
  156. void nameTest() {
  157. cout << endl;
  158. uint8_t n = sizeof(testName)/sizeof(char*);
  159. for (uint8_t i = 0; i < n; i++) {
  160. cout << F("Name: \"") << testName[i] << '"' << endl;
  161. if(!file.open(testName[i], O_CREAT | O_RDWR)) {
  162. cout <<F("Open failed") << endl;
  163. } else {
  164. file.println(testName[i]);
  165. if (!file.getName(name, sizeof(name))) {
  166. sd.errorHalt(F("getFilemame"));
  167. }
  168. cout << F("LFN: \"") << name << '"' << endl;
  169. cout << F("SFN: \"");
  170. file.printSFN(&Serial);
  171. cout << '"' << endl;
  172. cout <<F("Index: ") << setw(2) << file.dirIndex() << endl;
  173. file.close();
  174. }
  175. cout << endl;
  176. }
  177. cout << F("----- ls ------") << endl;
  178. sd.ls();
  179. cout << endl << F("nameTest done") << endl;
  180. }
  181. //------------------------------------------------------------------------------
  182. void setup() {
  183. Serial.begin(9600);
  184. while(!Serial); // Wait for USB Serial.
  185. cout << endl << F("FreeRam: ") << FreeRam() << endl;
  186. cout << F("Type any character to start.") << endl;
  187. cin.readline();
  188. if (!sd.begin(SD_CS_PIN)) {
  189. sd.initErrorHalt();
  190. }
  191. if (file.openNext(sd.vwd())) {
  192. file.close();
  193. cout << F("Type 'W' to wipe the card: ");
  194. cin.readline();
  195. char c = cin.get();
  196. cout << c << endl;
  197. if (c != 'W') {
  198. sd.errorHalt(F("Invalid"));
  199. }
  200. if (!sd.wipe(&Serial) || !sd.begin(SD_CS_PIN)) {
  201. sd.errorHalt(F("wipe failed"));
  202. }
  203. }
  204. basicTest();
  205. nameTest();
  206. }
  207. //------------------------------------------------------------------------------
  208. void loop() {}