diskio.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2019 Ha Thach (tinyusb.org)
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. *
  24. * This file is part of the TinyUSB stack.
  25. */
  26. #include "tusb.h"
  27. #if CFG_TUH_MSC
  28. //--------------------------------------------------------------------+
  29. // INCLUDE
  30. //--------------------------------------------------------------------+
  31. #include "ffconf.h"
  32. #include "diskio.h"
  33. //--------------------------------------------------------------------+
  34. // MACRO CONSTANT TYPEDEF
  35. //--------------------------------------------------------------------+
  36. // TODO change it to portable init
  37. static DSTATUS disk_state[CFG_TUSB_HOST_DEVICE_MAX];
  38. //--------------------------------------------------------------------+
  39. // INTERNAL OBJECT & FUNCTION DECLARATION
  40. //--------------------------------------------------------------------+
  41. //--------------------------------------------------------------------+
  42. // IMPLEMENTATION
  43. //--------------------------------------------------------------------+
  44. static DRESULT wait_for_io_complete(uint8_t usb_addr)
  45. {
  46. // TODO with RTOS, this should use semaphore instead of blocking
  47. while ( !tuh_msc_ready(usb_addr) )
  48. {
  49. // TODO should have timeout here
  50. #if CFG_TUSB_OS != OPT_OS_NONE
  51. osal_task_delay(10);
  52. #endif
  53. }
  54. return RES_OK;
  55. }
  56. void diskio_init(void)
  57. {
  58. memset(disk_state, STA_NOINIT, CFG_TUSB_HOST_DEVICE_MAX);
  59. }
  60. //pdrv Specifies the physical drive number.
  61. DSTATUS disk_initialize ( BYTE pdrv )
  62. {
  63. disk_state[pdrv] &= (~STA_NOINIT); // clear NOINIT bit
  64. return disk_state[pdrv];
  65. }
  66. void disk_deinitialize ( BYTE pdrv )
  67. {
  68. disk_state[pdrv] |= STA_NOINIT; // set NOINIT bit
  69. }
  70. DSTATUS disk_status (BYTE pdrv)
  71. {
  72. return disk_state[pdrv];
  73. }
  74. //pdrv
  75. // Specifies the physical drive number --> == dev_addr-1
  76. //buff
  77. // Pointer to the byte array to store the read data. The size of buffer must be in sector size * sector count.
  78. //sector
  79. // Specifies the start sector number in logical block address (LBA).
  80. //count
  81. // Specifies number of sectors to read. The value can be 1 to 128. Generally, a multiple sector transfer request
  82. // must not be split into single sector transactions to the device, or you may not get good read performance.
  83. DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, BYTE count)
  84. {
  85. uint8_t usb_addr = pdrv+1;
  86. if ( TUSB_ERROR_NONE != tuh_msc_read10(usb_addr, 0, buff, sector, count) ) return RES_ERROR;
  87. return wait_for_io_complete(usb_addr);
  88. }
  89. DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, BYTE count)
  90. {
  91. uint8_t usb_addr = pdrv+1;
  92. if ( TUSB_ERROR_NONE != tuh_msc_write10(usb_addr, 0, buff, sector, count) ) return RES_ERROR;
  93. return wait_for_io_complete(usb_addr);
  94. }
  95. /* [IN] Drive number */
  96. /* [IN] Control command code */
  97. /* [I/O] Parameter and data buffer */
  98. DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff)
  99. {
  100. (void) buff; (void) pdrv; // compiler warnings
  101. if (cmd != CTRL_SYNC) return RES_ERROR;
  102. return RES_OK;
  103. }
  104. static inline uint8_t month2number(char* p_ch)
  105. {
  106. char const * const month_str[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  107. for(uint8_t i=0; i<12; i++)
  108. {
  109. if ( strncmp(p_ch, month_str[i], 3) == 0 ) return i+1;
  110. }
  111. return 1;
  112. }
  113. static inline uint8_t c2i(char ch)
  114. {
  115. return ch - '0';
  116. }
  117. DWORD get_fattime (void)
  118. {
  119. union {
  120. struct {
  121. DWORD second : 5;
  122. DWORD minute : 6;
  123. DWORD hour : 5;
  124. DWORD day_in_month : 5;
  125. DWORD month : 4;
  126. DWORD year : 7;
  127. };
  128. DWORD value;
  129. } timestamp;
  130. //------------- Date is compiled date-------------//
  131. char compile_date[] = __DATE__; // eg. "Sep 26 2013"
  132. char* p_ch;
  133. p_ch = strtok (compile_date, " ");
  134. timestamp.month = month2number(p_ch);
  135. p_ch = strtok (NULL, " ");
  136. timestamp.day_in_month = 10*c2i(p_ch[0])+ c2i(p_ch[1]);
  137. p_ch = strtok (NULL, " ");
  138. timestamp.year = 1000*c2i(p_ch[0]) + 100*c2i(p_ch[1]) + 10*c2i(p_ch[2]) + c2i(p_ch[3]) - 1980;
  139. //------------- Time each time this function call --> sec ++ -------------//
  140. static uint8_t sec = 0;
  141. static uint8_t min = 0;
  142. static uint8_t hour = 0;
  143. if (++sec >= 60)
  144. {
  145. sec = 0;
  146. if (++min >= 60)
  147. {
  148. min = 0;
  149. if (++hour >= 24)
  150. {
  151. hour = 0; // assume demo wont call this function more than 24*60*60 times
  152. }
  153. }
  154. }
  155. timestamp.hour = hour;
  156. timestamp.minute = min;
  157. timestamp.second = sec;
  158. return timestamp.value;
  159. }
  160. #endif // CFG_TUH_MSC