Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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. File::File()
  31. {
  32. type = FILE_INVALID;
  33. namestr[0] = 0;
  34. }
  35. File::~File(void)
  36. {
  37. close();
  38. }
  39. size_t File::write(uint8_t b)
  40. {
  41. return write(&b, 1);
  42. }
  43. size_t File::write(const uint8_t *buf, size_t size)
  44. {
  45. if (type != FILE_WRITE) {
  46. setWriteError();
  47. return 0;
  48. }
  49. // TODO: a lot of work....
  50. return 0;
  51. }
  52. int File::read()
  53. {
  54. uint8_t b;
  55. int ret = read(&b, 1);
  56. if (ret != 1) return -1;
  57. return b;
  58. }
  59. int File::peek()
  60. {
  61. uint32_t save_offset = offset;
  62. uint32_t save_cluster = current_cluster;
  63. uint8_t b;
  64. int ret = read(&b, 1);
  65. if (ret != 1) return -1;
  66. offset = save_offset;
  67. current_cluster = save_cluster;
  68. return b;
  69. }
  70. int File::available()
  71. {
  72. if (type > FILE_WRITE) return 0;
  73. uint32_t maxsize = length - offset;
  74. if (maxsize > 0x7FFFFFFF) maxsize = 0x7FFFFFFF;
  75. return maxsize;
  76. }
  77. void File::flush()
  78. {
  79. }
  80. int File::read(void *buf, uint32_t size)
  81. {
  82. if (type > FILE_WRITE) return 0;
  83. uint32_t maxsize = length - offset;
  84. if (size > maxsize) size = maxsize;
  85. if (size == 0) return 0;
  86. uint32_t count = 0;
  87. uint8_t *dest = (uint8_t *)buf;
  88. uint32_t lba = custer_to_sector(current_cluster);
  89. uint32_t sindex = cluster_offset(offset);
  90. //Serial.printf(" read %u at %u (%X)\n", size, offset, offset);
  91. lba += sindex >> 9;
  92. sindex &= 511;
  93. if (sindex) {
  94. // first read starts in the middle of a sector
  95. do {
  96. SDCache cache;
  97. sector_t *sector = cache.read(lba);
  98. if (!sector) {
  99. //Serial.println(" read err1, unable to read");
  100. return 0;
  101. }
  102. uint32_t n = 512 - sindex;
  103. if (size < n) {
  104. // read does not consume all of the sector
  105. memcpy(dest, sector->u8 + sindex, size);
  106. offset += size;
  107. //cache.priority(+1);
  108. return size;
  109. } else {
  110. // read fully consumes this sector
  111. memcpy(dest, sector->u8 + sindex, n);
  112. dest += n;
  113. count = n;
  114. offset += n;
  115. //cache.priority(-1);
  116. }
  117. } while (0);
  118. if (is_new_cluster(++lba)) {
  119. if (!next_cluster()) {
  120. //Serial.print(" read err1, next cluster");
  121. return count;
  122. }
  123. }
  124. if (count >= size) return count;
  125. }
  126. while (1) {
  127. // every read starts from the beginning of a sector
  128. do {
  129. SDCache cache;
  130. uint32_t n = size - count;
  131. if (n < 512) {
  132. // only part of a sector is needed
  133. sector_t *sector = cache.read(lba);
  134. if (!sector) {
  135. //Serial.println(" read err2, unable to read");
  136. return count;
  137. }
  138. memcpy(dest, sector->u8, n);
  139. offset += n;
  140. count += n;
  141. //cache.priority(+1);
  142. return count;
  143. } else {
  144. // a full sector is required
  145. if (!cache.read(lba, dest)) return count;
  146. dest += 512;
  147. offset += 512;
  148. count += 512;
  149. }
  150. } while (0);
  151. if (is_new_cluster(++lba)) {
  152. if (!next_cluster()) {
  153. //Serial.print(" read err2, next cluster");
  154. return count;
  155. }
  156. }
  157. if (count >= size) return count;
  158. }
  159. }
  160. bool File::seek(uint32_t pos)
  161. {
  162. if (type > FILE_WRITE) return false;
  163. if (pos > length) return false;
  164. //Serial.printf(" seek to %u\n", pos);
  165. uint32_t save_cluster = current_cluster;
  166. uint32_t count;
  167. // TODO: if moving to a new lba, lower cache priority
  168. signed int diff = (int)cluster_number(pos) - (int)cluster_number(offset);
  169. if (diff >= 0) {
  170. // seek fowards, 0 or more clusters from current position
  171. count = diff;
  172. } else {
  173. // seek backwards, need to start from beginning of file
  174. current_cluster = start_cluster;
  175. count = cluster_number(pos);
  176. }
  177. while (count > 0) {
  178. if (!next_cluster()) {
  179. current_cluster = save_cluster;
  180. return false;
  181. }
  182. count--;
  183. }
  184. offset = pos;
  185. return true;
  186. }
  187. void File::close()
  188. {
  189. type = FILE_INVALID;
  190. namestr[0] = 0;
  191. }
  192. #endif
  193. #endif