My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

UHS_BULK_STORAGE.h 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* Copyright (C) 2015-2016 Andrew J. Kroll
  2. and
  3. Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. Contact information
  16. -------------------
  17. Circuits At Home, LTD
  18. Web : http://www.circuitsathome.com
  19. e-mail : support@circuitsathome.com
  20. */
  21. #ifndef __UHS_BULK_STORAGE_H__
  22. #define __UHS_BULK_STORAGE_H__
  23. ////////////////////////////////////////////////////////////////////////////////
  24. // Define any of these options at the top of your sketch to override
  25. // the defaults contained herewith. Do NOT do modifications here.
  26. // Macro | Settings and notes | Default
  27. // -----------------------------------------+-----------------------+-----------
  28. // | 1 to 8 |
  29. // | Each LUN needs |
  30. // MASS_MAX_SUPPORTED_LUN | ~13 bytes to be able | 8
  31. // | to track the state of |
  32. // | each unit. |
  33. // -----------------------------------------+-----------------------+-----------
  34. // | Just define to use. |
  35. // DEBUG_PRINTF_EXTRA_HUGE_UHS_BULK_STORAGE | works only if extra |
  36. // | huge debug is on too. |
  37. // -----------------------------------------^-----------------------^-----------
  38. #ifndef MASS_MAX_SUPPORTED_LUN
  39. #define MASS_MAX_SUPPORTED_LUN 8
  40. #endif
  41. #include "UHS_SCSI.h"
  42. #define UHS_BULK_bmREQ_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
  43. #define UHS_BULK_bmREQ_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
  44. // Request Codes
  45. #define UHS_BULK_REQ_ADSC 0x00U
  46. #define UHS_BULK_REQ_GET 0xFCU
  47. #define UHS_BULK_REQ_PUT 0xFDU
  48. #define UHS_BULK_REQ_GET_MAX_LUN 0xFEU
  49. #define UHS_BULK_REQ_BOMSR 0xFFU // Mass Storage Reset
  50. #define UHS_BULK_CBW_SIGNATURE 0x43425355LU
  51. #define UHS_BULK_CSW_SIGNATURE 0x53425355LU
  52. #define UHS_BULK_CMD_DIR_OUT 0x00U
  53. #define UHS_BULK_CMD_DIR_IN 0x80U
  54. /* Bulk error codes */
  55. #define UHS_BULK_ERR_SUCCESS UHS_HOST_ERROR_NONE
  56. #define UHS_BULK_ERR_PHASE_ERROR 0x22U
  57. #define UHS_BULK_ERR_UNIT_NOT_READY 0x23U
  58. #define UHS_BULK_ERR_UNIT_BUSY 0x24U
  59. #define UHS_BULK_ERR_STALL 0x25U
  60. #define UHS_BULK_ERR_CMD_NOT_SUPPORTED 0x26U
  61. #define UHS_BULK_ERR_INVALID_CSW 0x27U
  62. #define UHS_BULK_ERR_NO_MEDIA 0x28U
  63. #define UHS_BULK_ERR_BAD_LBA 0x29U
  64. #define UHS_BULK_ERR_MEDIA_CHANGED 0x2AU
  65. #define UHS_BULK_ERR_DEVICE_DISCONNECTED UHS_HOST_ERROR_UNPLUGGED
  66. #define UHS_BULK_ERR_UNABLE_TO_RECOVER 0x32U // Reset recovery error
  67. #define UHS_BULK_ERR_INVALID_LUN 0x33U
  68. #define UHS_BULK_ERR_WRITE_STALL 0x34U
  69. #define UHS_BULK_ERR_READ_NAKS 0x35U
  70. #define UHS_BULK_ERR_WRITE_NAKS 0x36U
  71. #define UHS_BULK_ERR_WRITE_PROTECTED 0x37U
  72. #define UHS_BULK_ERR_NOT_IMPLEMENTED 0xFDU
  73. #define UHS_BULK_ERR_GENERAL_SCSI_ERROR 0xF0U
  74. #define UHS_BULK_ERR_GENERAL_USB_ERROR 0xFFU
  75. #define UHS_BULK_ERR_USER 0xA0U // For subclasses to define their own error codes
  76. #define MASS_MAX_ENDPOINTS 3
  77. struct UHS_BULK_CommandBlockWrapperBase {
  78. volatile uint32_t dCBWSignature;
  79. volatile uint32_t dCBWTag;
  80. volatile uint32_t dCBWDataTransferLength;
  81. volatile uint8_t bmCBWFlags;
  82. public:
  83. UHS_BULK_CommandBlockWrapperBase() {
  84. }
  85. UHS_BULK_CommandBlockWrapperBase(uint32_t tag, uint32_t xflen, uint8_t flgs) :
  86. dCBWSignature(UHS_BULK_CBW_SIGNATURE), dCBWTag(tag), dCBWDataTransferLength(xflen), bmCBWFlags(flgs) {
  87. }
  88. } __attribute__((packed));
  89. struct UHS_BULK_CommandBlockWrapper : public UHS_BULK_CommandBlockWrapperBase {
  90. struct {
  91. uint8_t bmCBWLUN : 4;
  92. uint8_t bmReserved1 : 4;
  93. };
  94. struct {
  95. uint8_t bmCBWCBLength : 4;
  96. uint8_t bmReserved2 : 4;
  97. };
  98. uint8_t CBWCB[16];
  99. public:
  100. // All zeroed.
  101. UHS_BULK_CommandBlockWrapper() :
  102. UHS_BULK_CommandBlockWrapperBase(0, 0, 0), bmReserved1(0), bmReserved2(0) {
  103. for(int i = 0; i < 16; i++) CBWCB[i] = 0;
  104. }
  105. // Generic Wrap, CDB zeroed.
  106. UHS_BULK_CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
  107. UHS_BULK_CommandBlockWrapperBase(tag, xflen, flgs),
  108. bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) {
  109. for(int i = 0; i < 16; i++) CBWCB[i] = 0;
  110. SCSI_CDB_BASE_t *x = reinterpret_cast<SCSI_CDB_BASE_t *>(CBWCB);
  111. x->LUN = cmd;
  112. }
  113. // Wrap for CDB of 6
  114. UHS_BULK_CommandBlockWrapper(uint32_t tag, uint32_t xflen, SCSI_CDB6_t *cdb, uint8_t dir) :
  115. UHS_BULK_CommandBlockWrapperBase(tag, xflen, dir),
  116. bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) {
  117. memcpy(&CBWCB, cdb, 6);
  118. }
  119. // Wrap for CDB of 10
  120. UHS_BULK_CommandBlockWrapper(uint32_t tag, uint32_t xflen, SCSI_CDB10_t *cdb, uint8_t dir) :
  121. UHS_BULK_CommandBlockWrapperBase(tag, xflen, dir),
  122. bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) {
  123. memcpy(&CBWCB, cdb, 10);
  124. }
  125. } __attribute__((packed));
  126. struct UHS_BULK_CommandStatusWrapper {
  127. uint32_t dCSWSignature;
  128. uint32_t dCSWTag;
  129. uint32_t dCSWDataResidue;
  130. uint8_t bCSWStatus;
  131. } __attribute__((packed));
  132. class UHS_Bulk_Storage : public UHS_USBInterface {
  133. protected:
  134. static const uint8_t epDataInIndex = 1; // DataIn endpoint index
  135. static const uint8_t epDataOutIndex = 2; // DataOUT endpoint index
  136. static const uint8_t epInterruptInIndex = 3; // InterruptIN endpoint index
  137. uint8_t bMaxLUN; // Max LUN
  138. volatile uint32_t dCBWTag; // Tag
  139. volatile uint8_t bTheLUN; // Active LUN
  140. volatile uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]; // Total sectors
  141. volatile uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
  142. volatile bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
  143. volatile bool WriteOk[MASS_MAX_SUPPORTED_LUN];
  144. void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
  145. public:
  146. UHS_Bulk_Storage(UHS_USB_HOST_BASE *p);
  147. volatile UHS_EpInfo epInfo[MASS_MAX_ENDPOINTS];
  148. uint8_t GetbMaxLUN() {
  149. return bMaxLUN; // Max LUN
  150. }
  151. uint8_t GetbTheLUN() {
  152. return bTheLUN; // Active LUN
  153. }
  154. bool WriteProtected(uint8_t lun);
  155. uint8_t MediaCTL(uint8_t lun, uint8_t ctl);
  156. uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf);
  157. uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf);
  158. uint8_t LockMedia(uint8_t lun, uint8_t lock);
  159. bool LUNIsGood(uint8_t lun);
  160. uint32_t GetCapacity(uint8_t lun);
  161. uint16_t GetSectorSize(uint8_t lun);
  162. uint8_t SCSITransaction6(SCSI_CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
  163. uint8_t SCSITransaction10(SCSI_CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
  164. // Configure and internal methods, these should never be called by a user's sketch.
  165. uint8_t Start();
  166. bool OKtoEnumerate(ENUMERATION_INFO *ei);
  167. uint8_t SetInterface(ENUMERATION_INFO *ei);
  168. uint8_t GetAddress() {
  169. return bAddress;
  170. };
  171. void Poll();
  172. void DriverDefaults();
  173. private:
  174. void Reset();
  175. void CheckMedia();
  176. bool IsValidCBW(uint8_t size, uint8_t *pcbw);
  177. bool IsMeaningfulCBW(uint8_t size, uint8_t *pcbw);
  178. bool IsValidCSW(UHS_BULK_CommandStatusWrapper *pcsw, UHS_BULK_CommandBlockWrapperBase *pcbw);
  179. bool CheckLUN(uint8_t lun);
  180. uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
  181. uint8_t TestUnitReady(uint8_t lun);
  182. uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
  183. uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
  184. uint8_t GetMaxLUN(uint8_t *max_lun);
  185. uint8_t SetCurLUN(uint8_t lun);
  186. uint8_t ResetRecovery();
  187. uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
  188. uint8_t Page3F(uint8_t lun);
  189. uint8_t ClearEpHalt(uint8_t index);
  190. uint8_t Transaction(UHS_BULK_CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
  191. uint8_t HandleUsbError(uint8_t error, uint8_t index);
  192. uint8_t HandleSCSIError(uint8_t status);
  193. };
  194. #if defined(LOAD_UHS_BULK_STORAGE) && !defined(UHS_BULK_STORAGE_LOADED)
  195. #include "UHS_BULK_STORAGE_INLINE.h"
  196. #endif
  197. #endif // __MASSTORAGE_H__