drv_usb.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (c) 2022 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #include <rthw.h>
  8. #include <rtdevice.h>
  9. #include <rtdbg.h>
  10. #include "tusb.h"
  11. /* Definition of logic unit number for each drive */
  12. #define LUN_USB (0U) /* lun 0 of usb drive */
  13. static rt_ssize_t hpm_usb_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
  14. static rt_ssize_t hpm_usb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
  15. rt_err_t hpm_usb_control(rt_device_t dev, int cmd, void *args);
  16. rt_uint8_t usb_dev_addr;
  17. static struct rt_device hpm_usb = {
  18. .read = hpm_usb_read,
  19. .write = hpm_usb_write,
  20. .control = hpm_usb_control,
  21. };
  22. static bool usb_disk_wait_for_complete(uint8_t usb_addr)
  23. {
  24. #if CFG_TUSB_OS != OPT_OS_NONE
  25. int32_t retry_cnt = 200;
  26. #else
  27. int32_t retry_cnt = 5000000;
  28. #endif
  29. while (!tuh_msc_idle(usb_addr) && retry_cnt--)
  30. {
  31. #if CFG_TUSB_OS != OPT_OS_NONE
  32. osal_task_delay(5);
  33. #else
  34. tuh_task();
  35. #endif
  36. }
  37. return retry_cnt > 0 ? true : false;
  38. }
  39. void hpm_usb_set_addr(uint8_t dev_addr)
  40. {
  41. usb_dev_addr = dev_addr;
  42. }
  43. static rt_ssize_t hpm_usb_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  44. {
  45. rt_bool_t result;
  46. result = tuh_msc_read10(usb_dev_addr, LUN_USB, buffer, pos, size, NULL);
  47. if (result) {
  48. result = usb_disk_wait_for_complete(usb_dev_addr);
  49. }
  50. return result ? size : 0;
  51. }
  52. static rt_ssize_t hpm_usb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  53. {
  54. bool result;
  55. result = tuh_msc_write10(usb_dev_addr, LUN_USB, buffer, pos, size, NULL);
  56. if (result) {
  57. result = usb_disk_wait_for_complete(usb_dev_addr);
  58. }
  59. return result ? size : 0;
  60. }
  61. rt_err_t hpm_usb_control(rt_device_t dev, int cmd, void *args)
  62. {
  63. rt_err_t ret = RT_EOK;
  64. switch (cmd)
  65. {
  66. case RT_DEVICE_CTRL_BLK_GETGEOME:
  67. struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *)args;
  68. geometry->sector_count = tuh_msc_get_block_count(usb_dev_addr, LUN_USB);
  69. geometry->bytes_per_sector = tuh_msc_get_block_size(usb_dev_addr, LUN_USB);
  70. break;
  71. case RT_DEVICE_CTRL_BLK_SYNC:
  72. break;
  73. case RT_DEVICE_CTRL_BLK_ERASE:
  74. break;
  75. default:
  76. ret = RT_EINVAL;
  77. break;
  78. }
  79. return RT_EOK;
  80. }
  81. int rt_hw_usb_init(void)
  82. {
  83. rt_err_t err = RT_EOK;
  84. hpm_usb.type = RT_Device_Class_Block;
  85. err = rt_device_register(&hpm_usb, "usb0", RT_DEVICE_FLAG_RDWR);
  86. if (err != RT_EOK) {
  87. LOG_E("rt device %s failed, status=%d\n", "usb", err);
  88. return err;
  89. }
  90. return err;
  91. }
  92. INIT_BOARD_EXPORT(rt_hw_usb_init);