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.

149 lines
4.1KB

  1. /* Optimized SD Library for Teensy 3.X
  2. * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
  3. *
  4. * Development of this SD library was funded by PJRC.COM, LLC by sales of
  5. * Teensy and Audio Adaptor boards. Please support PJRC's efforts to develop
  6. * open source software by purchasing genuine Teensy or other PJRC products.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice, development funding notice, and this permission
  16. * notice shall be included in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #if defined(__arm__)
  27. #include "SD_t3.h"
  28. #ifdef USE_TEENSY3_OPTIMIZED_CODE
  29. #define sector_t SDClass::sector_t
  30. #define fatdir_t SDClass::fatdir_t
  31. File SDClass::open(const char *path, uint8_t mode)
  32. {
  33. File root = rootDir;
  34. File f;
  35. if (mode > FILE_READ) return f;
  36. // TODO: this needs the path traversal feature
  37. //Serial.println("SDClass::open");
  38. //Serial.printf("rootDir.start_cluster = %d\n", rootDir.start_cluster);
  39. //Serial.printf("root.start_cluster = %d\n", root.start_cluster);
  40. root.find(path, &f);
  41. return f;
  42. }
  43. File File::openNextFile(uint8_t mode)
  44. {
  45. File f;
  46. if (mode > FILE_READ) return f;
  47. return f;
  48. }
  49. bool File::find(const char *filename, File *found)
  50. {
  51. bool find_unused = true;
  52. char name83[11];
  53. uint32_t lba, sector_count;
  54. //Serial.println("File::open");
  55. const char *f = filename;
  56. char *p = name83;
  57. while (p < name83 + 11) {
  58. char c = *f++;
  59. if (c == 0) {
  60. while (p < name83 + 11) *p++ = ' ';
  61. break;
  62. }
  63. if (c == '.') {
  64. while (p < name83 + 8) *p++ = ' ';
  65. continue;
  66. }
  67. if (c > 126) continue;
  68. if (c >= 'a' && c <= 'z') c -= 32;
  69. *p++ = c;
  70. }
  71. //Serial.print("name83 = ");
  72. //for (uint32_t i=0; i < 11; i++) {
  73. //Serial.printf(" %02X", name83[i]);
  74. //}
  75. //Serial.println();
  76. if (type == FILE_DIR_ROOT16) {
  77. lba = start_cluster;
  78. sector_count = length >> 9;
  79. } else if (type == FILE_DIR) {
  80. current_cluster = start_cluster;
  81. lba = custer_to_sector(start_cluster);
  82. sector_count = (1 << SDClass::sector2cluster);
  83. } else {
  84. return false; // not a directory
  85. }
  86. while (1) {
  87. for (uint32_t i=0; i < sector_count; i++) {
  88. SDCache sector;
  89. sector_t *s = sector.read(lba);
  90. if (!s) return false;
  91. fatdir_t *dirent = s->dir;
  92. for (uint32_t j=0; j < 16; j++) {
  93. if (dirent->attrib == ATTR_LONG_NAME) {
  94. // TODO: how to match long names?
  95. }
  96. if (memcmp(dirent->name, name83, 11) == 0) {
  97. //Serial.printf("found 8.3, j=%d\n", j);
  98. found->init(dirent);
  99. return true;
  100. }
  101. uint8_t b0 = dirent->name[0];
  102. if (find_unused && (b0 == 0 || b0 == 0xE5)) {
  103. found->dirent_lba = lba;
  104. found->dirent_index = j;
  105. find_unused = false;
  106. }
  107. if (b0 == 0) return false;
  108. offset += 32;
  109. dirent++;
  110. }
  111. lba++;
  112. }
  113. if (type == FILE_DIR_ROOT16) break;
  114. if (!next_cluster()) break;
  115. lba = custer_to_sector(current_cluster);
  116. //Serial.printf(" next lba = %d\n", lba);
  117. }
  118. return false;
  119. }
  120. void File::init(fatdir_t *dirent)
  121. {
  122. offset = 0;
  123. length = dirent->size;
  124. start_cluster = (dirent->cluster_high << 16) | dirent->cluster_low;
  125. current_cluster = start_cluster;
  126. type = (dirent->attrib & ATTR_DIRECTORY) ? FILE_DIR : FILE_READ;
  127. //Serial.printf("File::init, cluster = %d, length = %d\n", start_cluster, length);
  128. }
  129. #endif
  130. #endif