My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

UHS_address.h 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 : https://www.circuitsathome.com
  19. e-mail : support@circuitsathome.com
  20. */
  21. #if !defined(_UHS_host_h_) || defined(__ADDRESS_H__)
  22. #error "Never include UHS_address.h directly; include UHS_Usb.h instead"
  23. #else
  24. #define __ADDRESS_H__
  25. /* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
  26. /* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */
  27. #define UHS_USB_NAK_MAX_POWER 14 // NAK binary order maximum value
  28. #define UHS_USB_NAK_DEFAULT 13 // default 16K-1 NAKs before giving up
  29. #define UHS_USB_NAK_NOWAIT 1 // Single NAK stops transfer
  30. #define UHS_USB_NAK_NONAK 0 // Do not count NAKs, stop retrying after USB Timeout. Try not to use this.
  31. #define bmUSB_DEV_ADDR_PORT 0x07
  32. #define bmUSB_DEV_ADDR_PARENT 0x78
  33. #define bmUSB_DEV_ADDR_HUB 0x40
  34. // TODO: embed parent?
  35. struct UHS_EpInfo {
  36. uint8_t epAddr; // Endpoint address
  37. uint8_t bIface;
  38. uint16_t maxPktSize; // Maximum packet size
  39. union {
  40. uint8_t epAttribs;
  41. struct {
  42. uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
  43. uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
  44. uint8_t bmNeedPing : 1; // 1 == ping protocol needed for next out packet
  45. uint8_t bmNakPower : 5; // Binary order for NAK_LIMIT value
  46. } __attribute__((packed));
  47. };
  48. } __attribute__((packed));
  49. // TODO: embed parent address and port into epinfo struct,
  50. // and nuke this address stupidity.
  51. // This is a compact scheme. Should also support full spec.
  52. // This produces a 7 hub limit, 49 devices + 7 hubs, 56 total.
  53. //
  54. // 7 6 5 4 3 2 1 0
  55. // ---------------------------------
  56. // | | H | P | P | P | A | A | A |
  57. // ---------------------------------
  58. //
  59. // H - if 1 the address is a hub address
  60. // P - parent hub number
  61. // A - port number of parent
  62. //
  63. struct UHS_DeviceAddress {
  64. union {
  65. struct {
  66. uint8_t bmAddress : 3; // port number
  67. uint8_t bmParent : 3; // parent hub address
  68. uint8_t bmHub : 1; // hub flag
  69. uint8_t bmReserved : 1; // reserved, must be zero
  70. } __attribute__((packed));
  71. uint8_t devAddress;
  72. };
  73. } __attribute__((packed));
  74. struct UHS_Device {
  75. volatile UHS_EpInfo *epinfo[UHS_HOST_MAX_INTERFACE_DRIVERS]; // endpoint info pointer
  76. UHS_DeviceAddress address;
  77. uint8_t epcount; // number of endpoints
  78. uint8_t speed; // indicates device speed
  79. } __attribute__((packed));
  80. typedef void (*UsbDeviceHandleFunc)(UHS_Device *pdev);
  81. class AddressPool {
  82. UHS_EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device
  83. // In order to avoid hub address duplication, this should use bits
  84. uint8_t hubCounter; // hub counter
  85. UHS_Device thePool[UHS_HOST_MAX_INTERFACE_DRIVERS];
  86. // Initializes address pool entry
  87. void UHS_NI InitEntry(uint8_t index) {
  88. thePool[index].address.devAddress = 0;
  89. thePool[index].epcount = 1;
  90. thePool[index].speed = 0;
  91. for(uint8_t i = 0; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
  92. thePool[index].epinfo[i] = &dev0ep;
  93. }
  94. };
  95. // Returns thePool index for a given address
  96. uint8_t UHS_NI FindAddressIndex(uint8_t address = 0) {
  97. for(uint8_t i = 1; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
  98. if(thePool[i].address.devAddress == address)
  99. return i;
  100. }
  101. return 0;
  102. };
  103. // Returns thePool child index for a given parent
  104. uint8_t UHS_NI FindChildIndex(UHS_DeviceAddress addr, uint8_t start = 1) {
  105. for(uint8_t i = (start < 1 || start >= UHS_HOST_MAX_INTERFACE_DRIVERS) ? 1 : start; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) {
  106. if(thePool[i].address.bmParent == addr.bmAddress)
  107. return i;
  108. }
  109. return 0;
  110. };
  111. // Frees address entry specified by index parameter
  112. void UHS_NI FreeAddressByIndex(uint8_t index) {
  113. // Zero field is reserved and should not be affected
  114. if(index == 0)
  115. return;
  116. UHS_DeviceAddress uda = thePool[index].address;
  117. // If a hub was switched off all port addresses should be freed
  118. if(uda.bmHub == 1) {
  119. for(uint8_t i = 1; (i = FindChildIndex(uda, i));)
  120. FreeAddressByIndex(i);
  121. // FIXME: use BIT MASKS
  122. // If the hub had the last allocated address, hubCounter should be decremented
  123. if(hubCounter == uda.bmAddress)
  124. hubCounter--;
  125. }
  126. InitEntry(index);
  127. }
  128. void InitAllAddresses() {
  129. for(uint8_t i = 1; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++) InitEntry(i);
  130. hubCounter = 0;
  131. };
  132. public:
  133. AddressPool() {
  134. hubCounter = 0;
  135. // Zero address is reserved
  136. InitEntry(0);
  137. thePool[0].epinfo[0] = &dev0ep;
  138. dev0ep.epAddr = 0;
  139. #if UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE
  140. dev0ep.maxPktSize = 0x40; //starting at 0x40 and work down
  141. #else
  142. dev0ep.maxPktSize = 0x08;
  143. #endif
  144. dev0ep.epAttribs = 0; //set DATA0/1 toggles to 0
  145. dev0ep.bmNakPower = UHS_USB_NAK_MAX_POWER;
  146. InitAllAddresses();
  147. };
  148. // Returns a pointer to a specified address entry
  149. UHS_Device* UHS_NI GetUsbDevicePtr(uint8_t addr) {
  150. if(!addr)
  151. return thePool;
  152. uint8_t index = FindAddressIndex(addr);
  153. return (!index) ? NULL : &thePool[index];
  154. };
  155. // Allocates new address
  156. uint8_t UHS_NI AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 1) {
  157. /* if (parent != 0 && port == 0)
  158. USB_HOST_SERIAL.println("PRT:0"); */
  159. UHS_DeviceAddress _parent;
  160. _parent.devAddress = parent;
  161. if(_parent.bmReserved || port > 7)
  162. //if(parent > 127 || port > 7)
  163. return 0;
  164. // FIXME: use BIT MASKS
  165. if(is_hub && hubCounter == 7)
  166. return 0;
  167. // finds first empty address entry starting from one
  168. uint8_t index = FindAddressIndex(0);
  169. if(!index) // if empty entry is not found
  170. return 0;
  171. UHS_DeviceAddress addr;
  172. addr.devAddress = port;
  173. addr.bmParent = _parent.bmAddress;
  174. // FIXME: use BIT MASKS
  175. if(is_hub) {
  176. hubCounter++;
  177. addr.bmHub = 1;
  178. addr.bmAddress = hubCounter;
  179. }
  180. thePool[index].address = addr;
  181. #if DEBUG_PRINTF_EXTRA_HUGE
  182. #ifdef UHS_DEBUG_USB_ADDRESS
  183. printf("Address: %x (%x.%x.%x)\r\n", addr.devAddress, addr.bmHub, addr.bmParent, addr.bmAddress);
  184. #endif
  185. #endif
  186. return thePool[index].address.devAddress;
  187. };
  188. void UHS_NI FreeAddress(uint8_t addr) {
  189. // if the root hub is disconnected all the addresses should be initialized
  190. if(addr == 0x41) {
  191. InitAllAddresses();
  192. return;
  193. }
  194. uint8_t index = FindAddressIndex(addr);
  195. FreeAddressByIndex(index);
  196. };
  197. };
  198. #endif // __ADDRESS_H__