msc_host_app.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. #include <tusb.h>
  2. #include <string.h>
  3. #include <rtthread.h>
  4. #include <rtdevice.h>
  5. #include <rthw.h>
  6. #include <dfs_fs.h>
  7. #define DBG_TAG "udisk"
  8. #define DBG_LVL DBG_LOG
  9. #include <rtdbg.h>
  10. #define MIN(A, B) ((A) < (B) ? (A) : (B))
  11. #define MAX_PARTITION_COUNT 1
  12. #define SCSI_TIMEOUT PKG_TINYUSB_HOST_MSC_SCSI_TIMEOUT
  13. #define UDISK_MOUNTPOINT PKG_TINYUSB_HOST_MSC_MOUNT_POINT
  14. #define UDISK_EVENT_READ10_CPLT 0x01
  15. #define UDISK_EVENT_WRITE10_CPLT 0x02
  16. typedef struct upart
  17. {
  18. uint32_t block_size;
  19. struct dfs_partition dfs_part;
  20. struct rt_device dev;
  21. } upart_t;
  22. static upart_t _upart[MAX_PARTITION_COUNT];
  23. static uint8_t _dev_count;
  24. static uint8_t _dev_addr;
  25. static rt_mutex_t _lock;
  26. static rt_event_t _udisk_event;
  27. static CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN scsi_inquiry_resp_t inquiry_resp;
  28. static CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t sector_buf[PKG_TINYUSB_HOST_MSC_BUFSIZE];
  29. static const rt_size_t MAX_PACKET_SIZE = sizeof(sector_buf) / SECTOR_SIZE;
  30. static bool read10_complete_cb(uint8_t dev_addr, msc_cbw_t const *cbw, msc_csw_t const *csw)
  31. {
  32. (void)cbw;
  33. if (csw->status != 0)
  34. {
  35. LOG_E("READ10 failed");
  36. return false;
  37. }
  38. rt_event_send(_udisk_event, UDISK_EVENT_READ10_CPLT);
  39. return true;
  40. }
  41. static bool write10_complete_cb(uint8_t dev_addr, msc_cbw_t const *cbw, msc_csw_t const *csw)
  42. {
  43. (void)cbw;
  44. if (csw->status != 0)
  45. {
  46. LOG_E("WRITE10 failed");
  47. return false;
  48. }
  49. rt_event_send(_udisk_event, UDISK_EVENT_WRITE10_CPLT);
  50. return true;
  51. }
  52. static rt_err_t udisk_init(rt_device_t dev)
  53. {
  54. return RT_EOK;
  55. }
  56. static rt_size_t udisk_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  57. {
  58. rt_err_t ret;
  59. upart_t *part;
  60. rt_size_t read_size;
  61. /* check parameter */
  62. RT_ASSERT(dev != RT_NULL);
  63. RT_ASSERT(buffer != RT_NULL);
  64. rt_mutex_take(_lock, RT_WAITING_FOREVER);
  65. part = (upart_t *)dev->user_data;
  66. read_size = 0;
  67. while (size)
  68. {
  69. rt_size_t packet_size = MIN(size, MAX_PACKET_SIZE);
  70. tuh_msc_read10(_dev_addr, 0, sector_buf, pos + part->dfs_part.offset + read_size, packet_size, read10_complete_cb);
  71. ret = rt_event_recv(_udisk_event, UDISK_EVENT_READ10_CPLT, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, SCSI_TIMEOUT, RT_NULL);
  72. if (ret == RT_EOK)
  73. {
  74. rt_memcpy(buffer + read_size * SECTOR_SIZE, sector_buf, SECTOR_SIZE * packet_size);
  75. read_size += packet_size;
  76. size -= packet_size;
  77. }
  78. else
  79. {
  80. break;
  81. }
  82. }
  83. rt_mutex_release(_lock);
  84. return read_size;
  85. }
  86. static rt_size_t udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  87. {
  88. rt_err_t ret;
  89. upart_t *part;
  90. rt_size_t sent_size;
  91. /* check parameter */
  92. RT_ASSERT(dev != RT_NULL);
  93. RT_ASSERT(buffer != RT_NULL);
  94. rt_mutex_take(_lock, RT_WAITING_FOREVER);
  95. part = (upart_t *)dev->user_data;
  96. sent_size = 0;
  97. while (size)
  98. {
  99. rt_size_t packet_size = MIN(size, MAX_PACKET_SIZE);
  100. rt_memcpy(sector_buf, buffer + sent_size * SECTOR_SIZE, packet_size * SECTOR_SIZE);
  101. tuh_msc_write10(_dev_addr, 0, sector_buf, pos + part->dfs_part.offset + sent_size, packet_size, write10_complete_cb);
  102. ret = rt_event_recv(_udisk_event, UDISK_EVENT_WRITE10_CPLT, RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, SCSI_TIMEOUT, RT_NULL);
  103. if (ret == RT_EOK)
  104. {
  105. sent_size += packet_size;
  106. size -= packet_size;
  107. }
  108. else
  109. {
  110. break;
  111. }
  112. }
  113. rt_mutex_release(_lock);
  114. if (ret != RT_EOK)
  115. {
  116. return 0;
  117. }
  118. return sent_size;
  119. }
  120. static rt_err_t udisk_control(rt_device_t dev, int cmd, void *args)
  121. {
  122. rt_err_t ret;
  123. upart_t *part;
  124. /* check parameter */
  125. RT_ASSERT(dev != RT_NULL);
  126. part = (upart_t *)dev->user_data;
  127. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  128. {
  129. struct rt_device_blk_geometry *geometry;
  130. geometry = (struct rt_device_blk_geometry *)args;
  131. if (geometry == RT_NULL)
  132. return -RT_ERROR;
  133. geometry->bytes_per_sector = SECTOR_SIZE;
  134. geometry->block_size = part->block_size;
  135. geometry->sector_count = part->dfs_part.size;
  136. }
  137. return RT_EOK;
  138. }
  139. #ifdef RT_USING_DEVICE_OPS
  140. const static struct rt_device_ops udisk_device_ops =
  141. {
  142. udisk_init,
  143. RT_NULL,
  144. RT_NULL,
  145. udisk_read,
  146. udisk_write,
  147. udisk_control};
  148. #endif
  149. static rt_err_t register_device(upart_t *upart, const char *device_name)
  150. {
  151. upart->block_size = sizeof(sector_buf);
  152. /* register sd card device */
  153. upart->dev.type = RT_Device_Class_Block;
  154. #ifdef RT_USING_DEVICE_OPS
  155. stor->dev[i].ops = &udisk_device_ops;
  156. #else
  157. upart->dev.init = udisk_init;
  158. upart->dev.read = udisk_read;
  159. upart->dev.write = udisk_write;
  160. upart->dev.control = udisk_control;
  161. #endif
  162. upart->dev.user_data = (void *)upart;
  163. return rt_device_register(&upart->dev, device_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  164. }
  165. /**
  166. * This function will run udisk driver when usb disk is detected.
  167. *
  168. * @param intf the usb interface instance.
  169. *
  170. * @return the error code, RT_EOK on successfully.
  171. */
  172. static void udisk_run(void *parameter)
  173. {
  174. rt_err_t ret;
  175. uint32_t block_count;
  176. uint32_t block_size;
  177. char dname[8];
  178. block_count = tuh_msc_get_block_count(_dev_addr, 0);
  179. block_size = tuh_msc_get_block_size(_dev_addr, 0);
  180. LOG_I("capacity %lu MB, block size %d",
  181. block_count / ((1024 * 1024) / block_size),
  182. block_size);
  183. LOG_D("read partition table");
  184. for (int i = 0; i < MAX_PARTITION_COUNT; i++)
  185. {
  186. /* get the partition table */
  187. tuh_msc_read10(_dev_addr, 0, sector_buf, 0, 1, read10_complete_cb);
  188. ret = rt_event_recv(_udisk_event, UDISK_EVENT_READ10_CPLT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, SCSI_TIMEOUT, RT_NULL);
  189. if (ret != RT_EOK)
  190. {
  191. LOG_E("read partition table error");
  192. break;
  193. }
  194. /* get the first partition */
  195. ret = dfs_filesystem_get_partition(&_upart[i].dfs_part, sector_buf, i);
  196. if (ret == RT_EOK)
  197. {
  198. rt_snprintf(dname, 7, "ud%d%d", _dev_addr, i);
  199. ret = register_device(_upart + i, dname);
  200. if (ret == RT_EOK)
  201. {
  202. LOG_I("udisk part %d register successfully", i);
  203. }
  204. else
  205. {
  206. LOG_E("udisk part %d registerfailed: %d", i, ret);
  207. }
  208. _dev_count++;
  209. }
  210. else
  211. {
  212. /* there is no partition */
  213. if (i == 0)
  214. {
  215. rt_snprintf(dname, 8, "ud%d", _dev_addr);
  216. _upart[0].dfs_part.offset = 0;
  217. _upart[0].dfs_part.size = 0;
  218. ret = register_device(_upart, dname);
  219. if (ret == RT_EOK)
  220. {
  221. LOG_I("udisk register successfully", 0);
  222. }
  223. else
  224. {
  225. LOG_E("udisk register failed: %d", 0, rt_get_errno());
  226. }
  227. _dev_count = 1;
  228. }
  229. break;
  230. }
  231. }
  232. return;
  233. }
  234. void tuh_msc_mount_cb(uint8_t dev_addr)
  235. {
  236. rt_thread_t udisk_thread;
  237. LOG_I("A MassStorage device is mounted");
  238. _udisk_event = rt_event_create("udisk", RT_IPC_FLAG_PRIO);
  239. _lock = rt_mutex_create("udisk", RT_IPC_FLAG_PRIO);
  240. if (!_udisk_event || !_lock)
  241. {
  242. LOG_E("init failed: cannot create mutex or event");
  243. return;
  244. }
  245. _dev_addr = dev_addr;
  246. udisk_thread = rt_thread_create("udisk", udisk_run, &_dev_addr, 4096, PKG_TINYUSB_THREAD_PRIORITY, 10);
  247. rt_thread_startup(udisk_thread);
  248. }
  249. void tuh_msc_umount_cb(uint8_t dev_addr)
  250. {
  251. (void)dev_addr;
  252. rt_base_t level = rt_hw_interrupt_disable();
  253. LOG_I("A MassStorage device is unmounted");
  254. if (_udisk_event)
  255. {
  256. rt_event_delete(_udisk_event);
  257. _udisk_event = RT_NULL;
  258. }
  259. if (_lock)
  260. {
  261. rt_mutex_delete(_lock);
  262. _lock = RT_NULL;
  263. }
  264. for (int i = 0; i < _dev_count; i++)
  265. {
  266. rt_device_unregister(&_upart[i].dev);
  267. }
  268. _dev_count = 0;
  269. rt_hw_interrupt_enable(level);
  270. }