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.

222 lines
5.9KB

  1. /*
  2. * This program is a simple binary write/read benchmark.
  3. */
  4. #include <SPI.h>
  5. #include "SdFat.h"
  6. #include "sdios.h"
  7. #include "FreeStack.h"
  8. // Set USE_SDIO to zero for SPI card access.
  9. #define USE_SDIO 0
  10. // SD chip select pin
  11. const uint8_t chipSelect = SS;
  12. // Size of read/write.
  13. const size_t BUF_SIZE = 512;
  14. // File size in MB where MB = 1,000,000 bytes.
  15. const uint32_t FILE_SIZE_MB = 5;
  16. // Write pass count.
  17. const uint8_t WRITE_COUNT = 2;
  18. // Read pass count.
  19. const uint8_t READ_COUNT = 2;
  20. //==============================================================================
  21. // End of configuration constants.
  22. //------------------------------------------------------------------------------
  23. // File size in bytes.
  24. const uint32_t FILE_SIZE = 1000000UL*FILE_SIZE_MB;
  25. uint8_t buf[BUF_SIZE];
  26. // file system
  27. #if USE_SDIO
  28. // Traditional DMA version.
  29. // SdFatSdio sd;
  30. // Faster version.
  31. SdFatSdioEX sd;
  32. #else // USE_SDIO
  33. SdFat sd;
  34. #endif // USE_SDIO
  35. // Set ENABLE_EXTENDED_TRANSFER_CLASS to use extended SD I/O.
  36. // Requires dedicated use of the SPI bus.
  37. // SdFatEX sd;
  38. // Set ENABLE_SOFTWARE_SPI_CLASS to use software SPI.
  39. // Args are misoPin, mosiPin, sckPin.
  40. // SdFatSoftSpi<6, 7, 5> sd;
  41. // test file
  42. SdFile file;
  43. // Serial output stream
  44. ArduinoOutStream cout(Serial);
  45. //------------------------------------------------------------------------------
  46. // Store error strings in flash to save RAM.
  47. #define error(s) sd.errorHalt(F(s))
  48. //------------------------------------------------------------------------------
  49. void cidDmp() {
  50. cid_t cid;
  51. if (!sd.card()->readCID(&cid)) {
  52. error("readCID failed");
  53. }
  54. cout << F("\nManufacturer ID: ");
  55. cout << hex << int(cid.mid) << dec << endl;
  56. cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
  57. cout << F("Product: ");
  58. for (uint8_t i = 0; i < 5; i++) {
  59. cout << cid.pnm[i];
  60. }
  61. cout << F("\nVersion: ");
  62. cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
  63. cout << F("Serial number: ") << hex << cid.psn << dec << endl;
  64. cout << F("Manufacturing date: ");
  65. cout << int(cid.mdt_month) << '/';
  66. cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
  67. cout << endl;
  68. }
  69. //------------------------------------------------------------------------------
  70. void setup() {
  71. Serial.begin(9600);
  72. // Wait for USB Serial
  73. while (!Serial) {
  74. SysCall::yield();
  75. }
  76. delay(1000);
  77. cout << F("\nUse a freshly formatted SD for best performance.\n");
  78. // use uppercase in hex and use 0X base prefix
  79. cout << uppercase << showbase << endl;
  80. }
  81. //------------------------------------------------------------------------------
  82. void loop() {
  83. float s;
  84. uint32_t t;
  85. uint32_t maxLatency;
  86. uint32_t minLatency;
  87. uint32_t totalLatency;
  88. // Discard any input.
  89. do {
  90. delay(10);
  91. } while (Serial.available() && Serial.read() >= 0);
  92. // F( stores strings in flash to save RAM
  93. cout << F("Type any character to start\n");
  94. while (!Serial.available()) {
  95. SysCall::yield();
  96. }
  97. cout << F("chipSelect: ") << int(chipSelect) << endl;
  98. cout << F("FreeStack: ") << FreeStack() << endl;
  99. #if USE_SDIO
  100. if (!sd.begin()) {
  101. sd.initErrorHalt();
  102. }
  103. #else // USE_SDIO
  104. // Initialize at the highest speed supported by the board that is
  105. // not over 50 MHz. Try a lower speed if SPI errors occur.
  106. if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
  107. sd.initErrorHalt();
  108. }
  109. #endif // USE_SDIO
  110. cout << F("Type is FAT") << int(sd.vol()->fatType()) << endl;
  111. cout << F("Card size: ") << sd.card()->cardSize()*512E-9;
  112. cout << F(" GB (GB = 1E9 bytes)") << endl;
  113. cidDmp();
  114. // open or create file - truncate existing file.
  115. if (!file.open("bench.dat", O_RDWR | O_CREAT | O_TRUNC)) {
  116. error("open failed");
  117. }
  118. // fill buf with known data
  119. for (size_t i = 0; i < (BUF_SIZE-2); i++) {
  120. buf[i] = 'A' + (i % 26);
  121. }
  122. buf[BUF_SIZE-2] = '\r';
  123. buf[BUF_SIZE-1] = '\n';
  124. cout << F("File size ") << FILE_SIZE_MB << F(" MB\n");
  125. cout << F("Buffer size ") << BUF_SIZE << F(" bytes\n");
  126. cout << F("Starting write test, please wait.") << endl << endl;
  127. // do write test
  128. uint32_t n = FILE_SIZE/sizeof(buf);
  129. cout <<F("write speed and latency") << endl;
  130. cout << F("speed,max,min,avg") << endl;
  131. cout << F("KB/Sec,usec,usec,usec") << endl;
  132. for (uint8_t nTest = 0; nTest < WRITE_COUNT; nTest++) {
  133. file.truncate(0);
  134. maxLatency = 0;
  135. minLatency = 9999999;
  136. totalLatency = 0;
  137. t = millis();
  138. for (uint32_t i = 0; i < n; i++) {
  139. uint32_t m = micros();
  140. if (file.write(buf, sizeof(buf)) != sizeof(buf)) {
  141. sd.errorPrint("write failed");
  142. file.close();
  143. return;
  144. }
  145. m = micros() - m;
  146. if (maxLatency < m) {
  147. maxLatency = m;
  148. }
  149. if (minLatency > m) {
  150. minLatency = m;
  151. }
  152. totalLatency += m;
  153. }
  154. file.sync();
  155. t = millis() - t;
  156. s = file.fileSize();
  157. cout << s/t <<',' << maxLatency << ',' << minLatency;
  158. cout << ',' << totalLatency/n << endl;
  159. }
  160. cout << endl << F("Starting read test, please wait.") << endl;
  161. cout << endl <<F("read speed and latency") << endl;
  162. cout << F("speed,max,min,avg") << endl;
  163. cout << F("KB/Sec,usec,usec,usec") << endl;
  164. // do read test
  165. for (uint8_t nTest = 0; nTest < READ_COUNT; nTest++) {
  166. file.rewind();
  167. maxLatency = 0;
  168. minLatency = 9999999;
  169. totalLatency = 0;
  170. t = millis();
  171. for (uint32_t i = 0; i < n; i++) {
  172. buf[BUF_SIZE-1] = 0;
  173. uint32_t m = micros();
  174. int32_t nr = file.read(buf, sizeof(buf));
  175. if (nr != sizeof(buf)) {
  176. sd.errorPrint("read failed");
  177. file.close();
  178. return;
  179. }
  180. m = micros() - m;
  181. if (maxLatency < m) {
  182. maxLatency = m;
  183. }
  184. if (minLatency > m) {
  185. minLatency = m;
  186. }
  187. totalLatency += m;
  188. if (buf[BUF_SIZE-1] != '\n') {
  189. error("data check");
  190. }
  191. }
  192. s = file.fileSize();
  193. t = millis() - t;
  194. cout << s/t <<',' << maxLatency << ',' << minLatency;
  195. cout << ',' << totalLatency/n << endl;
  196. }
  197. cout << endl << F("Done") << endl;
  198. file.close();
  199. }