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.

USB_HOST_SHIELD.h 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. /* Copyright (C) 2015-2016 Andrew J. Kroll
  2. and
  3. Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
  4. This software may be distributed and modified under the terms of the GNU
  5. General Public License version 2 (GPL2) as published by the Free Software
  6. Foundation and appearing in the file GPL2.TXT included in the packaging of
  7. this file. Please note that GPL2 Section 2[b] requires that all works based
  8. on this software must also be made publicly available under the terms of
  9. the GPL2 ("Copyleft").
  10. Contact information
  11. -------------------
  12. Circuits At Home, LTD
  13. Web : https://www.circuitsathome.com
  14. e-mail : support@circuitsathome.com
  15. */
  16. #ifndef USB_HOST_SHIELD_H
  17. #define USB_HOST_SHIELD_H
  18. // uncomment to get 'printf' console debugging. NOT FOR UNO!
  19. //#define DEBUG_PRINTF_EXTRA_HUGE_USB_HOST_SHIELD
  20. #ifdef LOAD_USB_HOST_SHIELD
  21. #include "UHS_max3421e.h"
  22. #include <SPI.h>
  23. #ifndef SPI_HAS_TRANSACTION
  24. #error "Your SPI library installation is too old."
  25. #else
  26. #ifndef SPI_ATOMIC_VERSION
  27. #warning "Your SPI library installation lacks 'SPI_ATOMIC_VERSION'. Please complain to the maintainer."
  28. #elif SPI_ATOMIC_VERSION < 1
  29. #error "Your SPI library installation is too old."
  30. #endif
  31. #endif
  32. #if DEBUG_PRINTF_EXTRA_HUGE
  33. #ifdef DEBUG_PRINTF_EXTRA_HUGE_USB_HOST_SHIELD
  34. #define MAX_HOST_DEBUG(...) printf_P(__VA_ARGS__)
  35. #else
  36. #define MAX_HOST_DEBUG(...) VOID0
  37. #endif
  38. #else
  39. #define MAX_HOST_DEBUG(...) VOID0
  40. #endif
  41. #ifndef USB_HOST_SHIELD_USE_ISR
  42. #ifdef USE_MULTIPLE_APP_API
  43. #define USB_HOST_SHIELD_USE_ISR 0
  44. #else
  45. #define USB_HOST_SHIELD_USE_ISR 1
  46. #endif
  47. #else
  48. #define USB_HOST_SHIELD_USE_ISR 1
  49. #endif
  50. #if !USB_HOST_SHIELD_USE_ISR
  51. #error NOISR Polled mode _NOT SUPPORTED YET_
  52. //
  53. // Polled defaults
  54. //
  55. #ifdef BOARD_BLACK_WIDDOW
  56. #define UHS_MAX3421E_SS_ 6
  57. #define UHS_MAX3421E_INT_ 3
  58. #elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
  59. #if EXT_RAM
  60. // Teensy++ 2.0 with XMEM2
  61. #define UHS_MAX3421E_SS_ 20
  62. #define UHS_MAX3421E_INT_ 7
  63. #else
  64. #define UHS_MAX3421E_SS_ 9
  65. #define UHS_MAX3421E_INT_ 8
  66. #endif
  67. #define UHS_MAX3421E_SPD
  68. #elif defined(ARDUINO_AVR_ADK)
  69. #define UHS_MAX3421E_SS_ 53
  70. #define UHS_MAX3421E_INT_ 54
  71. #elif defined(ARDUINO_AVR_BALANDUINO)
  72. #define UHS_MAX3421E_SS_ 20
  73. #define UHS_MAX3421E_INT_ 19
  74. #else
  75. #define UHS_MAX3421E_SS_ 10
  76. #define UHS_MAX3421E_INT_ 9
  77. #endif
  78. #else
  79. #ifdef ARDUINO_ARCH_PIC32
  80. // PIC32 only allows edge interrupts, isn't that lovely? We'll emulate it...
  81. #if CHANGE < 2
  82. #error core too old.
  83. #endif
  84. #define IRQ_IS_EDGE 0
  85. #ifndef digitalPinToInterrupt
  86. // great, this isn't implemented.
  87. #warning digitalPinToInterrupt is not defined, complain here https://github.com/chipKIT32/chipKIT-core/issues/114
  88. #if defined(_BOARD_UNO_) || defined(_BOARD_UC32_)
  89. #define digitalPinToInterrupt(p) ((p) == 2 ? 1 : ((p) == 7 ? 2 : ((p) == 8 ? 3 : ((p) == 35 ? 4 : ((p) == 38 ? 0 : NOT_AN_INTERRUPT)))))
  90. #warning digitalPinToInterrupt is now defined until this is taken care of.
  91. #else
  92. #error digitalPinToInterrupt not defined for your board, complain here https://github.com/chipKIT32/chipKIT-core/issues/114
  93. #endif
  94. #endif
  95. #else
  96. #define IRQ_IS_EDGE 0
  97. #endif
  98. // More stupidity from our friends @ Sony...
  99. #ifdef ARDUINO_spresense_ast
  100. #ifndef NOT_AN_INTERRUPT
  101. #define NOT_AN_INTERRUPT -1
  102. #endif
  103. #endif
  104. // SAMD uses an enum for this instead of a define. Isn't that just dandy?
  105. #if !defined(NOT_AN_INTERRUPT) && !defined(ARDUINO_ARCH_SAMD)
  106. #warning NOT_AN_INTERRUPT not defined, possible problems ahead.
  107. #warning If NOT_AN_INTERRUPT is an enum or something else, complain to UHS30 developers on github.
  108. #warning Otherwise complain to your board core developer/maintainer.
  109. #define NOT_AN_INTERRUPT -1
  110. #endif
  111. //
  112. // Interrupt defaults. Int0 or Int1
  113. //
  114. #ifdef BOARD_BLACK_WIDDOW
  115. #error "HELP! Please send us an email, I don't know the values for Int0 and Int1 on the Black Widow board!"
  116. #elif defined(ARDUINO_AVR_ADK)
  117. #define UHS_MAX3421E_SS_ 53
  118. #define UHS_MAX3421E_INT_ 54
  119. #elif defined(ARDUINO_spresense_ast)
  120. #define UHS_MAX3421E_SS_ 21
  121. #define UHS_MAX3421E_INT_ 20
  122. #define SPIclass SPI5
  123. //#define UHS_MAX3421E_SPD 100000
  124. #elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
  125. // TO-DO!
  126. #if EXT_RAM
  127. // Teensy++ 2.0 with XMEM2
  128. #define UHS_MAX3421E_SS_ 20
  129. #define UHS_MAX3421E_INT_ 7
  130. #else
  131. #define UHS_MAX3421E_SS_ 9
  132. #define UHS_MAX3421E_INT_ 8
  133. #endif
  134. #elif defined(ARDUINO_AVR_BALANDUINO)
  135. #error "ISR mode is currently not supported on the Balanduino. Please set USB_HOST_SHIELD_USE_ISR to 0."
  136. #else
  137. #define UHS_MAX3421E_SS_ 10
  138. #ifdef __AVR__
  139. #ifdef __AVR_ATmega32U4__
  140. #define INT_FOR_PIN2 1
  141. #define INT_FOR_PIN3 0
  142. #else
  143. // Everybody else???
  144. #define INT_FOR_PIN2 0
  145. #define INT_FOR_PIN3 1
  146. #endif
  147. #define UHS_MAX3421E_INT_ 3
  148. #else
  149. // Non-avr
  150. #ifdef ARDUINO_ARCH_PIC32
  151. // UNO32 External Interrupts:
  152. // Pin 38 (INT0), Pin 2 (INT1), Pin 7 (INT2), Pin 8 (INT3), Pin 35 (INT4)
  153. #define UHS_MAX3421E_INT_ 7
  154. #else
  155. #define UHS_MAX3421E_INT_ 9
  156. #endif
  157. #endif
  158. #endif
  159. #endif
  160. #ifdef NO_AUTO_SPEED
  161. // Ugly details section...
  162. // MAX3421E characteristics
  163. // SPI Serial - Clock Input. An external SPI master supplies SCLK with frequencies up to 26MHz. The
  164. // logic level is referenced to the voltage on VL. Data is clocked into the SPI slave inter face on the
  165. // rising edge of SCLK. Data is clocked out of the SPI slave interface on the falling edge of SCLK.
  166. // Serial Clock (SCLK) Period 38.4ns minimum. 17ns minimum pulse width. VL >2.5V
  167. // SCLK Fall to MISO Propagation Delay 14.2ns
  168. // SCLK Fall to MOSI Propagation Delay 14.2ns
  169. // SCLK Fall to MOSI Drive 3.5ns
  170. // Theoretical deadline for reply 17.7ns
  171. // 26MHz 38.4615ns period <-- MAX3421E theoretical maximum
  172. #ifndef UHS_MAX3421E_SPD
  173. #ifdef ARDUINO_SAMD_ZERO
  174. // Zero violates spec early, needs a long setup time, or doesn't like high latency.
  175. #define UHS_MAX3421E_SPD 10000000
  176. #elif defined(ARDUINO_ARCH_PIC32)
  177. // PIC MX 5/6/7 characteristics
  178. // 25MHZ 40ns period <-- PIC MX 5/6/7 theoretical maximum
  179. // pulse width minimum Tsclk/2ns
  180. // Trise/fall 10ns maximum. 5ns is typical but not guaranteed.
  181. // Tsetup minimum for MISO 10ns.
  182. // We are in violation by 7.7ns @ 25MHz due to latency alone.
  183. // Even reading at end of data cycle, we only have a 2.3ns window.
  184. // This is too narrow to to compensate for capacitance, trace lengths, and noise.
  185. // 17.7ns + 10ns = 27.7ns
  186. // 18MHz fits and has enough slack time to compensate for capacitance, trace lengths, and noise.
  187. // For high speeds the SMP bit is recommended too, which samples at the end instead of the middle.
  188. // 20Mhz seems to work.
  189. #define UHS_MAX3421E_SPD 20000000
  190. #else
  191. #define UHS_MAX3421E_SPD 25000000
  192. #endif
  193. #endif
  194. #else
  195. // We start at 25MHz, and back down until hardware can take it.
  196. // Of course, SPI library can adjust this for us too.
  197. // Why not 26MHz? Because I have not found any MCU board that
  198. // can actually go that fast without problems.
  199. // Could be a shield limitation too.
  200. #ifndef UHS_MAX3421E_SPD
  201. #define UHS_MAX3421E_SPD 25000000
  202. #endif
  203. #endif
  204. #ifndef UHS_MAX3421E_INT
  205. #define UHS_MAX3421E_INT UHS_MAX3421E_INT_
  206. #endif
  207. #ifndef UHS_MAX3421E_SS
  208. #define UHS_MAX3421E_SS UHS_MAX3421E_SS_
  209. #endif
  210. // NOTE: On the max3421e the irq enable and irq bits are in the same position.
  211. // IRQs used if CPU polls
  212. #define ENIBITSPOLLED (bmCONDETIE | bmBUSEVENTIE | bmFRAMEIE)
  213. // IRQs used if CPU is interrupted
  214. #define ENIBITSISR (bmCONDETIE | bmBUSEVENTIE | bmFRAMEIE /* | bmRCVDAVIRQ | bmSNDBAVIRQ | bmHXFRDNIRQ */ )
  215. #if !USB_HOST_SHIELD_USE_ISR
  216. #define IRQ_CHECK_MASK (ENIBITSPOLLED & ICLRALLBITS)
  217. #define IRQ_IS_EDGE 0
  218. #else
  219. #define IRQ_CHECK_MASK (ENIBITSISR & ICLRALLBITS)
  220. #endif
  221. #if IRQ_IS_EDGE
  222. // Note: UNO32 Interrupts can only be RISING, or FALLING.
  223. // This poses an interesting problem, since we want to use a LOW level.
  224. // The MAX3421E provides for pulse width control for an IRQ.
  225. // We do need to watch the timing on this, as a second IRQ could cause
  226. // a missed IRQ, since we read the level of the line to check if the IRQ
  227. // is actually for this chip. The only other alternative is to add a capacitor
  228. // and an NPN transistor, and use two lines. We can try this first, though.
  229. // Worse case, we can ignore reading the pin for verification on UNO32.
  230. // Too bad there is no minimum low width setting.
  231. //
  232. // Single Clear First Second Clear first Clear last
  233. // IRQ Single IRQ IRQ Second active pending IRQ
  234. // | | | | | |
  235. // V V V V V V
  236. // _____ _________ _ _ _______
  237. // |______| |______| |______| |______________|
  238. //
  239. #define IRQ_SENSE FALLING
  240. #ifdef ARDUINO_ARCH_PIC32
  241. //#define bmPULSEWIDTH PULSEWIDTH10_6
  242. #define bmPULSEWIDTH 0
  243. #define bmIRQ_SENSE 0
  244. #else
  245. #define bmPULSEWIDTH PULSEWIDTH1_3
  246. #define bmIRQ_SENSE 0
  247. #endif
  248. #else
  249. #ifndef IRQ_SENSE
  250. #define IRQ_SENSE LOW
  251. #endif
  252. #ifndef bmPULSEWIDTH
  253. #define bmPULSEWIDTH 0
  254. #endif
  255. #ifndef bmIRQ_SENSE
  256. #define bmIRQ_SENSE bmINTLEVEL
  257. #endif
  258. #endif
  259. class MAX3421E_HOST :
  260. public UHS_USB_HOST_BASE
  261. #ifdef SWI_IRQ_NUM
  262. , public dyn_SWI
  263. #endif
  264. {
  265. // TO-DO: move these into the parent class.
  266. volatile uint8_t vbusState;
  267. volatile uint16_t sof_countdown;
  268. // TO-DO: pack into a struct/union and use one byte
  269. volatile bool busevent;
  270. volatile bool sofevent;
  271. volatile bool counted;
  272. volatile bool condet;
  273. volatile bool doingreset;
  274. #ifdef USB_HOST_MANUAL_POLL
  275. volatile bool frame_irq_enabled = false;
  276. bool enable_frame_irq(bool enable) {
  277. const bool prev_state = frame_irq_enabled;
  278. if(prev_state != enable) {
  279. if(enable)
  280. regWr(rHIEN, regRd(rHIEN) | bmFRAMEIE);
  281. else
  282. regWr(rHIEN, regRd(rHIEN) & ~bmFRAMEIE);
  283. frame_irq_enabled = enable;
  284. }
  285. return prev_state;
  286. }
  287. #endif
  288. public:
  289. SPISettings MAX3421E_SPI_Settings;
  290. uint8_t ss_pin;
  291. uint8_t irq_pin;
  292. // Will use the defaults UHS_MAX3421E_SS, UHS_MAX3421E_INT and speed
  293. UHS_NI MAX3421E_HOST() {
  294. sof_countdown = 0;
  295. busevent = false;
  296. doingreset = false;
  297. sofevent = false;
  298. condet = false;
  299. ss_pin = UHS_MAX3421E_SS;
  300. irq_pin = UHS_MAX3421E_INT;
  301. MAX3421E_SPI_Settings = SPISettings(UHS_MAX3421E_SPD, MSBFIRST, SPI_MODE0);
  302. hub_present = 0;
  303. };
  304. // Will use user supplied pins, and UHS_MAX3421E_SPD
  305. UHS_NI MAX3421E_HOST(uint8_t pss, uint8_t pirq) {
  306. sof_countdown = 0;
  307. busevent = false;
  308. doingreset = false;
  309. sofevent = false;
  310. condet = false;
  311. ss_pin = pss;
  312. irq_pin = pirq;
  313. MAX3421E_SPI_Settings = SPISettings(UHS_MAX3421E_SPD, MSBFIRST, SPI_MODE0);
  314. hub_present = 0;
  315. };
  316. // Will use user supplied pins, and speed
  317. UHS_NI MAX3421E_HOST(uint8_t pss, uint8_t pirq, uint32_t pspd) {
  318. sof_countdown = 0;
  319. doingreset = false;
  320. busevent = false;
  321. sofevent = false;
  322. condet = false;
  323. ss_pin = pss;
  324. irq_pin = pirq;
  325. MAX3421E_SPI_Settings = SPISettings(pspd, MSBFIRST, SPI_MODE0);
  326. hub_present = 0;
  327. };
  328. virtual bool UHS_NI sof_delay(uint16_t x) {
  329. #ifdef USB_HOST_MANUAL_POLL
  330. const bool saved_irq_state = enable_frame_irq(true);
  331. #endif
  332. sof_countdown = x;
  333. while((sof_countdown != 0) && !condet) {
  334. SYSTEM_OR_SPECIAL_YIELD();
  335. #if !USB_HOST_SHIELD_USE_ISR
  336. Task();
  337. #endif
  338. }
  339. #ifdef USB_HOST_MANUAL_POLL
  340. enable_frame_irq(saved_irq_state);
  341. #endif
  342. // Serial.println("...Wake");
  343. return (!condet);
  344. };
  345. virtual UHS_EpInfo *ctrlReqOpen(uint8_t addr, uint64_t Request, uint8_t *dataptr);
  346. virtual void UHS_NI vbusPower(VBUS_t state) {
  347. regWr(rPINCTL, (bmFDUPSPI | bmIRQ_SENSE) | (uint8_t)(state));
  348. };
  349. void UHS_NI Task();
  350. virtual uint8_t SetAddress(uint8_t addr, uint8_t ep, UHS_EpInfo **ppep, uint16_t &nak_limit);
  351. virtual uint8_t OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data);
  352. virtual uint8_t InTransfer(UHS_EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data);
  353. virtual uint8_t ctrlReqClose(UHS_EpInfo *pep, uint8_t bmReqType, uint16_t left, uint16_t nbytes, uint8_t *dataptr);
  354. virtual uint8_t ctrlReqRead(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint16_t nbytes, uint8_t *dataptr);
  355. virtual uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit);
  356. void UHS_NI ReleaseChildren() {
  357. for(uint8_t i = 0; i < UHS_HOST_MAX_INTERFACE_DRIVERS; i++)
  358. if(devConfig[i])
  359. devConfig[i]->Release();
  360. hub_present = 0;
  361. };
  362. virtual bool IsHub(uint8_t klass) {
  363. if(klass == UHS_USB_CLASS_HUB) {
  364. hub_present = bmHUBPRE;
  365. return true;
  366. }
  367. return false;
  368. };
  369. virtual void VBUS_changed();
  370. virtual void UHS_NI doHostReset() {
  371. #if USB_HOST_SHIELD_USE_ISR
  372. // Enable interrupts
  373. noInterrupts();
  374. #endif
  375. doingreset = true;
  376. busevent = true;
  377. regWr(rHIRQ, bmBUSEVENTIRQ); // see data sheet.
  378. regWr(rHCTL, bmBUSRST); //issue bus reset
  379. #if USB_HOST_SHIELD_USE_ISR
  380. DDSB();
  381. // Enable interrupts
  382. interrupts();
  383. #endif
  384. while(busevent) {
  385. DDSB();
  386. SYSTEM_OR_SPECIAL_YIELD();
  387. }
  388. #endif
  389. #if USB_HOST_SHIELD_USE_ISR
  390. // Enable interrupts
  391. noInterrupts();
  392. #endif
  393. #ifdef USB_HOST_MANUAL_POLL
  394. enable_frame_irq(true);
  395. #endif
  396. sofevent = true;
  397. #if USB_HOST_SHIELD_USE_ISR
  398. DDSB();
  399. // Enable interrupts
  400. interrupts();
  401. #endif
  402. // Wait for SOF
  403. while(sofevent) {
  404. }
  405. #if USB_HOST_SHIELD_USE_ISR
  406. // Enable interrupts
  407. noInterrupts();
  408. #endif
  409. doingreset = false;
  410. #if USB_HOST_SHIELD_USE_ISR
  411. DDSB();
  412. // Enable interrupts
  413. interrupts();
  414. };
  415. int16_t UHS_NI Init(int16_t mseconds);
  416. int16_t UHS_NI Init() {
  417. return Init(INT16_MIN);
  418. };
  419. void ISRTask();
  420. void ISRbottom();
  421. void busprobe();
  422. uint16_t reset();
  423. // MAX3421e specific
  424. void regWr(uint8_t reg, uint8_t data);
  425. void gpioWr(uint8_t data);
  426. uint8_t regRd(uint8_t reg);
  427. uint8_t gpioRd();
  428. uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p);
  429. uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p);
  430. // ARM/NVIC specific, used to emulate reentrant ISR.
  431. #ifdef SWI_IRQ_NUM
  432. void dyn_SWISR() {
  433. ISRbottom();
  434. };
  435. #endif
  436. virtual void UHS_NI suspend_host() {
  437. // Used on MCU that lack control of IRQ priority (AVR).
  438. // Suspends ISRs, for critical code. IRQ will be serviced after it is resumed.
  439. // NOTE: you must track the state yourself!
  440. #ifdef __AVR__
  441. noInterrupts();
  442. detachInterrupt(UHS_GET_DPI(irq_pin));
  443. interrupts();
  444. #endif
  445. };
  446. virtual void UHS_NI resume_host();
  447. };
  448. #ifndef SPIclass
  449. #define SPIclass SPI
  450. #endif
  451. #ifndef USB_HOST_SHIELD_LOADED
  452. #include "USB_HOST_SHIELD_INLINE.h"
  453. #endif
  454. #else
  455. #error "define LOAD_USB_HOST_SHIELD in your sketch, never include USB_HOST_SHIELD.h in a driver."
  456. #endif
  457. #endif /* USB_HOST_SHIELD_H */