USB Host Shield 2.0
usbhost.h
Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 /* MAX3421E-based USB Host Library header file */
18 
19 
20 #if !defined(_usb_h_) || defined(_USBHOST_H_)
21 #error "Never include usbhost.h directly; include Usb.h instead"
22 #else
23 #define _USBHOST_H_
24 
25 #if USING_SPI4TEENSY3
26 #include <spi4teensy3.h>
27 #include <sys/types.h>
28 #endif
29 
30 /* SPI initialization */
31 template< typename SPI_CLK, typename SPI_MOSI, typename SPI_MISO, typename SPI_SS > class SPi {
32 public:
33 #if USING_SPI4TEENSY3
34  static void init() {
35  // spi4teensy3 inits everything for us, except /SS
36  // CLK, MOSI and MISO are hard coded for now.
37  // spi4teensy3::init(0,0,0); // full speed, cpol 0, cpha 0
38  spi4teensy3::init(); // full speed, cpol 0, cpha 0
39  SPI_SS::SetDirWrite();
40  SPI_SS::Set();
41  }
42 #elif SPI_HAS_TRANSACTION
43  static void init() {
44  SPI.begin(); // The SPI library with transaction will take care of setting up the pins - settings is set in beginTransaction()
45  SPI_SS::SetDirWrite();
46  SPI_SS::Set();
47  }
48 #elif defined(STM32F4)
49 #warning "You need to initialize the SPI interface manually when using the STM32F4 platform"
50  static void init() {
51  // Should be initialized by the user manually for now
52  }
53 #elif !defined(SPDR)
54  static void init() {
55  SPI_SS::SetDirWrite();
56  SPI_SS::Set();
57  SPI.begin();
58 #if defined(__MIPSEL__)
59  SPI.setClockDivider(1);
60 #elif defined(__ARDUINO_X86__)
61  #ifdef SPI_CLOCK_1M // Hack used to check if setClockSpeed is available
62  SPI.setClockSpeed(12000000); // The MAX3421E can handle up to 26MHz, but in practice this was the maximum that I could reliably use
63  #else
64  SPI.setClockDivider(SPI_CLOCK_DIV2); // This will set the SPI frequency to 8MHz - it could be higher, but it is not supported in the old API
65  #endif
66 #elif !defined(RBL_NRF51822)
67  SPI.setClockDivider(4); // Set speed to 84MHz/4=21MHz - the MAX3421E can handle up to 26MHz
68 #endif
69  }
70 #else
71  static void init() {
72  //uint8_t tmp;
73  SPI_CLK::SetDirWrite();
74  SPI_MOSI::SetDirWrite();
75  SPI_MISO::SetDirRead();
76  SPI_SS::SetDirWrite();
77  /* mode 00 (CPOL=0, CPHA=0) master, fclk/2. Mode 11 (CPOL=11, CPHA=11) is also supported by MAX3421E */
78  SPCR = 0x50;
79  SPSR = 0x01; // 0x01
80 
81  //tmp = SPSR;
82  //tmp = SPDR;
83  }
84 #endif
85 };
86 
87 /* SPI pin definitions. see avrpins.h */
88 #if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__) || defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
89 typedef SPi< Pb1, Pb2, Pb3, Pb0 > spi;
90 #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
91 typedef SPi< Pb5, Pb3, Pb4, Pb2 > spi;
92 #elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__)
93 typedef SPi< Pb7, Pb5, Pb6, Pb4 > spi;
94 #elif (defined(CORE_TEENSY) && (defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__))) || defined(__ARDUINO_X86__) || defined(__MIPSEL__) || defined(STM32F4)
95 typedef SPi< P13, P11, P12, P10 > spi;
96 #elif defined(ARDUINO_SAM_DUE) && defined(__SAM3X8E__)
97 typedef SPi< P76, P75, P74, P10 > spi;
98 #elif defined(RBL_NRF51822)
99 typedef SPi< P16, P18, P17, P10 > spi;
100 #else
101 #error "No SPI entry in usbhost.h"
102 #endif
103 
104 typedef enum {
105  vbus_on = 0,
107 } VBUS_t;
108 
109 template< typename SPI_SS, typename INTR > class MAX3421e /* : public spi */ {
110  static uint8_t vbusState;
111 
112 public:
113  MAX3421e();
114  void regWr(uint8_t reg, uint8_t data);
115  uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
116  void gpioWr(uint8_t data);
117  uint8_t regRd(uint8_t reg);
118  uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
119  uint8_t gpioRd();
120  uint16_t reset();
121  int8_t Init();
122  int8_t Init(int mseconds);
123 
124  void vbusPower(VBUS_t state) {
125  regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | state));
126  }
127 
128  uint8_t getVbusState(void) {
129  return vbusState;
130  };
131  void busprobe();
132  uint8_t GpxHandler();
133  uint8_t IntHandler();
134  uint8_t Task();
135 };
136 
137 template< typename SPI_SS, typename INTR >
139 
140 /* constructor */
141 template< typename SPI_SS, typename INTR >
143  // Leaving ADK hardware setup in here, for now. This really belongs with the other parts.
144 #ifdef BOARD_MEGA_ADK
145  // For Mega ADK, which has a Max3421e on-board, set MAX_RESET to output mode, and then set it to HIGH
146  P55::SetDirWrite();
147  P55::Set();
148 #endif
149 };
150 
151 /* write single byte into MAX3421 register */
152 template< typename SPI_SS, typename INTR >
153 void MAX3421e< SPI_SS, INTR >::regWr(uint8_t reg, uint8_t data) {
155 #if SPI_HAS_TRANSACTION
156  SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
157 #endif
158  SPI_SS::Clear();
159 
160 #if USING_SPI4TEENSY3
161  uint8_t c[2];
162  c[0] = reg | 0x02;
163  c[1] = data;
164  spi4teensy3::send(c, 2);
165 #elif SPI_HAS_TRANSACTION
166  uint8_t c[2];
167  c[0] = reg | 0x02;
168  c[1] = data;
169  SPI.transfer(c, 2);
170 #elif defined(STM32F4)
171  uint8_t c[2];
172  c[0] = reg | 0x02;
173  c[1] = data;
174  HAL_SPI_Transmit(&SPI_Handle, c, 2, HAL_MAX_DELAY);
175 #elif !defined(SPDR)
176  SPI.transfer(reg | 0x02);
177  SPI.transfer(data);
178 #else
179  SPDR = (reg | 0x02);
180  while(!(SPSR & (1 << SPIF)));
181  SPDR = data;
182  while(!(SPSR & (1 << SPIF)));
183 #endif
184 
185  SPI_SS::Set();
186 #if SPI_HAS_TRANSACTION
187  SPI.endTransaction();
188 #endif
190  return;
191 };
192 /* multiple-byte write */
193 
194 /* returns a pointer to memory position after last written */
195 template< typename SPI_SS, typename INTR >
196 uint8_t* MAX3421e< SPI_SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
198 #if SPI_HAS_TRANSACTION
199  SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
200 #endif
201  SPI_SS::Clear();
202 
203 #if USING_SPI4TEENSY3
204  spi4teensy3::send(reg | 0x02);
205  spi4teensy3::send(data_p, nbytes);
206  data_p += nbytes;
207 #elif SPI_HAS_TRANSACTION
208  SPI.transfer(reg | 0x02);
209  SPI.transfer(data_p, nbytes);
210  data_p += nbytes;
211 #elif defined(__ARDUINO_X86__)
212  SPI.transfer(reg | 0x02);
213  SPI.transferBuffer(data_p, NULL, nbytes);
214  data_p += nbytes;
215 #elif defined(STM32F4)
216  uint8_t data = reg | 0x02;
217  HAL_SPI_Transmit(&SPI_Handle, &data, 1, HAL_MAX_DELAY);
218  HAL_SPI_Transmit(&SPI_Handle, data_p, nbytes, HAL_MAX_DELAY);
219  data_p += nbytes;
220 #elif !defined(SPDR)
221  SPI.transfer(reg | 0x02);
222  while(nbytes) {
223  SPI.transfer(*data_p);
224  nbytes--;
225  data_p++; // advance data pointer
226  }
227 #else
228  SPDR = (reg | 0x02); //set WR bit and send register number
229  while(nbytes) {
230  while(!(SPSR & (1 << SPIF))); //check if previous byte was sent
231  SPDR = (*data_p); // send next data byte
232  nbytes--;
233  data_p++; // advance data pointer
234  }
235  while(!(SPSR & (1 << SPIF)));
236 #endif
237 
238  SPI_SS::Set();
239 #if SPI_HAS_TRANSACTION
240  SPI.endTransaction();
241 #endif
243  return ( data_p);
244 }
245 /* GPIO write */
246 /*GPIO byte is split between 2 registers, so two writes are needed to write one byte */
247 
248 /* GPOUT bits are in the low nibble. 0-3 in IOPINS1, 4-7 in IOPINS2 */
249 template< typename SPI_SS, typename INTR >
251  regWr(rIOPINS1, data);
252  data >>= 4;
253  regWr(rIOPINS2, data);
254  return;
255 }
256 
257 /* single host register read */
258 template< typename SPI_SS, typename INTR >
259 uint8_t MAX3421e< SPI_SS, INTR >::regRd(uint8_t reg) {
261 #if SPI_HAS_TRANSACTION
262  SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
263 #endif
264  SPI_SS::Clear();
265 
266 #if USING_SPI4TEENSY3
267  spi4teensy3::send(reg);
268  uint8_t rv = spi4teensy3::receive();
269  SPI_SS::Set();
270 #elif defined(STM32F4)
271  HAL_SPI_Transmit(&SPI_Handle, &reg, 1, HAL_MAX_DELAY);
272  uint8_t rv = 0;
273  HAL_SPI_Receive(&SPI_Handle, &rv, 1, HAL_MAX_DELAY);
274  SPI_SS::Set();
275 #elif !defined(SPDR) || SPI_HAS_TRANSACTION
276  SPI.transfer(reg);
277  uint8_t rv = SPI.transfer(0); // Send empty byte
278  SPI_SS::Set();
279 #else
280  SPDR = reg;
281  while(!(SPSR & (1 << SPIF)));
282  SPDR = 0; // Send empty byte
283  while(!(SPSR & (1 << SPIF)));
284  SPI_SS::Set();
285  uint8_t rv = SPDR;
286 #endif
287 
288 #if SPI_HAS_TRANSACTION
289  SPI.endTransaction();
290 #endif
292  return (rv);
293 }
294 /* multiple-byte register read */
295 
296 /* returns a pointer to a memory position after last read */
297 template< typename SPI_SS, typename INTR >
298 uint8_t* MAX3421e< SPI_SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
300 #if SPI_HAS_TRANSACTION
301  SPI.beginTransaction(SPISettings(26000000, MSBFIRST, SPI_MODE0)); // The MAX3421E can handle up to 26MHz, use MSB First and SPI mode 0
302 #endif
303  SPI_SS::Clear();
304 
305 #if USING_SPI4TEENSY3
306  spi4teensy3::send(reg);
307  spi4teensy3::receive(data_p, nbytes);
308  data_p += nbytes;
309 #elif SPI_HAS_TRANSACTION
310  SPI.transfer(reg);
311  memset(data_p, 0, nbytes); // Make sure we send out empty bytes
312  SPI.transfer(data_p, nbytes);
313  data_p += nbytes;
314 #elif defined(__ARDUINO_X86__)
315  SPI.transfer(reg);
316  SPI.transferBuffer(NULL, data_p, nbytes);
317  data_p += nbytes;
318 #elif defined(STM32F4)
319  HAL_SPI_Transmit(&SPI_Handle, &reg, 1, HAL_MAX_DELAY);
320  memset(data_p, 0, nbytes); // Make sure we send out empty bytes
321  HAL_SPI_Receive(&SPI_Handle, data_p, nbytes, HAL_MAX_DELAY);
322  data_p += nbytes;
323 #elif !defined(SPDR)
324  SPI.transfer(reg);
325  while(nbytes) {
326  *data_p++ = SPI.transfer(0);
327  nbytes--;
328  }
329 #else
330  SPDR = reg;
331  while(!(SPSR & (1 << SPIF))); //wait
332  while(nbytes) {
333  SPDR = 0; // Send empty byte
334  nbytes--;
335  while(!(SPSR & (1 << SPIF)));
336 #if 0
337  {
338  *data_p = SPDR;
339  printf("%2.2x ", *data_p);
340  }
341  data_p++;
342  }
343  printf("\r\n");
344 #else
345  *data_p++ = SPDR;
346  }
347 #endif
348 #endif
349 
350  SPI_SS::Set();
351 #if SPI_HAS_TRANSACTION
352  SPI.endTransaction();
353 #endif
355  return ( data_p);
356 }
357 /* GPIO read. See gpioWr for explanation */
358 
359 /* GPIN pins are in high nibbles of IOPINS1, IOPINS2 */
360 template< typename SPI_SS, typename INTR >
362  uint8_t gpin = 0;
363  gpin = regRd(rIOPINS2); //pins 4-7
364  gpin &= 0xf0; //clean lower nibble
365  gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation.
366  return ( gpin);
367 }
368 
369 /* reset MAX3421E. Returns number of cycles it took for PLL to stabilize after reset
370  or zero if PLL haven't stabilized in 65535 cycles */
371 template< typename SPI_SS, typename INTR >
373  uint16_t i = 0;
374  regWr(rUSBCTL, bmCHIPRES);
375  regWr(rUSBCTL, 0x00);
376  while(++i) {
377  if((regRd(rUSBIRQ) & bmOSCOKIRQ)) {
378  break;
379  }
380  }
381  return ( i);
382 }
383 
384 /* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
385 template< typename SPI_SS, typename INTR >
388  // Moved here.
389  // you really should not init hardware in the constructor when it involves locks.
390  // Also avoids the vbus flicker issue confusing some devices.
391  /* pin and peripheral setup */
392  SPI_SS::SetDirWrite();
393  SPI_SS::Set();
394  spi::init();
395  INTR::SetDirRead();
397  /* MAX3421E - full-duplex SPI, level interrupt */
398  // GPX pin on. Moved here, otherwise we flicker the vbus.
399  regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
400 
401  if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
402  return ( -1);
403  }
404 
405  regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
406 
407  regWr(rHIEN, bmCONDETIE | bmFRAMEIE); //connection detection
408 
409  /* check if device is connected */
410  regWr(rHCTL, bmSAMPLEBUS); // sample USB bus
411  while(!(regRd(rHCTL) & bmSAMPLEBUS)); //wait for sample operation to finish
412 
413  busprobe(); //check if anything is connected
414 
415  regWr(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt
416  regWr(rCPUCTL, 0x01); //enable interrupt pin
417 
418  return ( 0);
419 }
420 
421 /* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
422 template< typename SPI_SS, typename INTR >
423 int8_t MAX3421e< SPI_SS, INTR >::Init(int mseconds) {
425  // Moved here.
426  // you really should not init hardware in the constructor when it involves locks.
427  // Also avoids the vbus flicker issue confusing some devices.
428  /* pin and peripheral setup */
429  SPI_SS::SetDirWrite();
430  SPI_SS::Set();
431  spi::init();
432  INTR::SetDirRead();
434  /* MAX3421E - full-duplex SPI, level interrupt, vbus off */
435  regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
436 
437  if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
438  return ( -1);
439  }
440 
441  // Delay a minimum of 1 second to ensure any capacitors are drained.
442  // 1 second is required to make sure we do not smoke a Microdrive!
443  if(mseconds < 1000) mseconds = 1000;
444  delay(mseconds);
445 
446  regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
447 
448  regWr(rHIEN, bmCONDETIE | bmFRAMEIE); //connection detection
449 
450  /* check if device is connected */
451  regWr(rHCTL, bmSAMPLEBUS); // sample USB bus
452  while(!(regRd(rHCTL) & bmSAMPLEBUS)); //wait for sample operation to finish
453 
454  busprobe(); //check if anything is connected
455 
456  regWr(rHIRQ, bmCONDETIRQ); //clear connection detect interrupt
457  regWr(rCPUCTL, 0x01); //enable interrupt pin
458 
459  // GPX pin on. This is done here so that busprobe will fail if we have a switch connected.
460  regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
461 
462  return ( 0);
463 }
464 
465 /* probe bus to determine device presence and speed and switch host to this speed */
466 template< typename SPI_SS, typename INTR >
468  uint8_t bus_sample;
469  bus_sample = regRd(rHRSL); //Get J,K status
470  bus_sample &= (bmJSTATUS | bmKSTATUS); //zero the rest of the byte
471  switch(bus_sample) { //start full-speed or low-speed host
472  case( bmJSTATUS):
473  if((regRd(rMODE) & bmLOWSPEED) == 0) {
474  regWr(rMODE, MODE_FS_HOST); //start full-speed host
475  vbusState = FSHOST;
476  } else {
477  regWr(rMODE, MODE_LS_HOST); //start low-speed host
478  vbusState = LSHOST;
479  }
480  break;
481  case( bmKSTATUS):
482  if((regRd(rMODE) & bmLOWSPEED) == 0) {
483  regWr(rMODE, MODE_LS_HOST); //start low-speed host
484  vbusState = LSHOST;
485  } else {
486  regWr(rMODE, MODE_FS_HOST); //start full-speed host
487  vbusState = FSHOST;
488  }
489  break;
490  case( bmSE1): //illegal state
491  vbusState = SE1;
492  break;
493  case( bmSE0): //disconnected state
494  regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST | bmSEPIRQ);
495  vbusState = SE0;
496  break;
497  }//end switch( bus_sample )
498 }
499 
500 /* MAX3421 state change task and interrupt handler */
501 template< typename SPI_SS, typename INTR >
503  uint8_t rcode = 0;
504  uint8_t pinvalue;
505  //USB_HOST_SERIAL.print("Vbus state: ");
506  //USB_HOST_SERIAL.println( vbusState, HEX );
507  pinvalue = INTR::IsSet(); //Read();
508  //pinvalue = digitalRead( MAX_INT );
509  if(pinvalue == 0) {
510  rcode = IntHandler();
511  }
512  // pinvalue = digitalRead( MAX_GPX );
513  // if( pinvalue == LOW ) {
514  // GpxHandler();
515  // }
516  // usbSM(); //USB state machine
517  return ( rcode);
518 }
519 
520 template< typename SPI_SS, typename INTR >
522  uint8_t HIRQ;
523  uint8_t HIRQ_sendback = 0x00;
524  HIRQ = regRd(rHIRQ); //determine interrupt source
525  //if( HIRQ & bmFRAMEIRQ ) { //->1ms SOF interrupt handler
526  // HIRQ_sendback |= bmFRAMEIRQ;
527  //}//end FRAMEIRQ handling
528  if(HIRQ & bmCONDETIRQ) {
529  busprobe();
530  HIRQ_sendback |= bmCONDETIRQ;
531  }
532  /* End HIRQ interrupts handling, clear serviced IRQs */
533  regWr(rHIRQ, HIRQ_sendback);
534  return ( HIRQ_sendback);
535 }
536 //template< typename SPI_SS, typename INTR >
537 //uint8_t MAX3421e< SPI_SS, INTR >::GpxHandler()
538 //{
539 // uint8_t GPINIRQ = regRd( rGPINIRQ ); //read GPIN IRQ register
546 // return( GPINIRQ );
547 //}
548 
549 #endif // _USBHOST_H_
#define GPX_VBDET
Definition: max3421e.h:75
#define rIOPINS1
Definition: max3421e.h:81
void busprobe()
Definition: usbhost.h:467
#define rHIEN
Definition: max3421e.h:148
#define FSHOST
Definition: max3421e.h:30
#define rHCTL
Definition: max3421e.h:174
#define bmCONDETIRQ
Definition: max3421e.h:144
#define bmCONDETIE
Definition: max3421e.h:156
#define bmSE1
Definition: max3421e.h:204
#define bmCHIPRES
Definition: max3421e.h:57
uint8_t getVbusState(void)
Definition: usbhost.h:128
#define rCPUCTL
Definition: max3421e.h:60
#define bmJSTATUS
Definition: max3421e.h:202
uint16_t reset()
Definition: usbhost.h:372
#define MODE_LS_HOST
Definition: max3421e.h:225
#define bmINTLEVEL
Definition: max3421e.h:69
void gpioWr(uint8_t data)
Definition: usbhost.h:250
uint8_t Task()
Definition: usbhost.h:502
#define rUSBCTL
Definition: max3421e.h:55
#define bmSE0
Definition: max3421e.h:203
#define bmHOST
Definition: max3421e.h:163
#define bmSEPIRQ
Definition: max3421e.h:167
uint8_t gpioRd()
Definition: usbhost.h:361
int8_t Init()
Definition: usbhost.h:386
#define LSHOST
Definition: max3421e.h:31
#define rMODE
Definition: max3421e.h:160
#define MODE_FS_HOST
Definition: max3421e.h:224
void vbusPower(VBUS_t state)
Definition: usbhost.h:124
#define bmKSTATUS
Definition: max3421e.h:201
#define rHRSL
Definition: max3421e.h:196
uint8_t * bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p)
Definition: usbhost.h:298
#define XMEM_ACQUIRE_SPI()
Definition: settings.h:121
#define bmLOWSPEED
Definition: max3421e.h:164
uint8_t * bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p)
Definition: usbhost.h:196
Definition: usbhost.h:31
#define rHIRQ
Definition: max3421e.h:137
#define rUSBIRQ
Definition: max3421e.h:43
#define XMEM_RELEASE_SPI()
Definition: settings.h:122
#define bmFDUPSPI
Definition: max3421e.h:68
#define rPINCTL
Definition: max3421e.h:66
VBUS_t
Definition: usbhost.h:104
void regWr(uint8_t reg, uint8_t data)
Definition: usbhost.h:153
#define bmFRAMEIE
Definition: max3421e.h:157
uint8_t IntHandler()
Definition: usbhost.h:521
#define bmOSCOKIRQ
Definition: max3421e.h:47
uint8_t regRd(uint8_t reg)
Definition: usbhost.h:259
MAX3421e()
Definition: usbhost.h:142
#define SE0
Definition: max3421e.h:28
#define rIOPINS2
Definition: max3421e.h:93
#define bmDMPULLDN
Definition: max3421e.h:169
#define SE1
Definition: max3421e.h:29
#define bmSAMPLEBUS
Definition: max3421e.h:178
static void init()
Definition: usbhost.h:54
#define bmDPPULLDN
Definition: max3421e.h:170