mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
first real commit
This commit is contained in:
parent
b8d67c40e0
commit
c83c43a83e
6 changed files with 1001 additions and 0 deletions
5
README
5
README
|
@ -0,0 +1,5 @@
|
||||||
|
This is Rev.2.0 of MAX3421E-based USB Host Library for Arduino. At the moment, this repo contains current development copy
|
||||||
|
of the code facilitating developer's exchange. For those not involved in the project, the code in its' current state doesn't bear any value.
|
||||||
|
In other words, nothing works yet.
|
||||||
|
|
||||||
|
The code uses slightly modified Konstantin Chizhov's AVR pin templates, see the original here -> https://github.com/KonstantinChizhov/AvrProjects
|
376
avrpins.h
Normal file
376
avrpins.h
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
/* copied from Konstantin Chizhov's AVR port templates */
|
||||||
|
|
||||||
|
#ifndef _avrpins_h_
|
||||||
|
#define _avrpins_h_
|
||||||
|
|
||||||
|
//#include "WProgram.h"
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
#ifdef PORTA
|
||||||
|
#define USE_PORTA
|
||||||
|
#endif
|
||||||
|
#ifdef PORTB
|
||||||
|
#define USE_PORTB
|
||||||
|
#endif
|
||||||
|
#ifdef PORTC
|
||||||
|
#define USE_PORTC
|
||||||
|
#endif
|
||||||
|
#ifdef PORTD
|
||||||
|
#define USE_PORTD
|
||||||
|
#endif
|
||||||
|
#ifdef PORTE
|
||||||
|
#define USE_PORTE
|
||||||
|
#endif
|
||||||
|
#ifdef PORTF
|
||||||
|
#define USE_PORTF
|
||||||
|
#endif
|
||||||
|
#ifdef PORTG
|
||||||
|
#define USE_PORTG
|
||||||
|
#endif
|
||||||
|
#ifdef PORTH
|
||||||
|
#define USE_PORTH
|
||||||
|
#endif
|
||||||
|
#ifdef PORTJ
|
||||||
|
#define USE_PORTJ
|
||||||
|
#endif
|
||||||
|
#ifdef PORTK
|
||||||
|
#define USE_PORTK
|
||||||
|
#endif
|
||||||
|
#ifdef PORTQ
|
||||||
|
#define USE_PORTQ
|
||||||
|
#endif
|
||||||
|
#ifdef PORTR
|
||||||
|
#define USE_PORTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TCCR0A
|
||||||
|
#define USE_TCCR0A
|
||||||
|
#endif
|
||||||
|
#ifdef TCCR1A
|
||||||
|
#define USE_TCCR1A
|
||||||
|
#endif
|
||||||
|
#ifdef TCCR2A
|
||||||
|
#define USE_TCCR2A
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Port definitions for AtTiny, AtMega families.
|
||||||
|
|
||||||
|
#define MAKE_PORT(portName, ddrName, pinName, className, ID) \
|
||||||
|
class className{\
|
||||||
|
public:\
|
||||||
|
typedef uint8_t DataT;\
|
||||||
|
public:\
|
||||||
|
static void Write(DataT value){portName = value;}\
|
||||||
|
static void ClearAndSet(DataT clearMask, DataT value){portName = (portName & ~clearMask) | value;}\
|
||||||
|
static DataT Read(){return portName;}\
|
||||||
|
static void DirWrite(DataT value){ddrName = value;}\
|
||||||
|
static DataT DirRead(){return ddrName;}\
|
||||||
|
static void Set(DataT value){portName |= value;}\
|
||||||
|
static void Clear(DataT value){portName &= ~value;}\
|
||||||
|
static void Toggle(DataT value){portName ^= value;}\
|
||||||
|
static void DirSet(DataT value){ddrName |= value;}\
|
||||||
|
static void DirClear(DataT value){ddrName &= ~value;}\
|
||||||
|
static void DirToggle(DataT value){ddrName ^= value;}\
|
||||||
|
static DataT PinRead(){return pinName;}\
|
||||||
|
enum{Id = ID};\
|
||||||
|
enum{Width=sizeof(DataT)*8};\
|
||||||
|
};
|
||||||
|
|
||||||
|
// TCCR registers to set/clear Arduino PWM
|
||||||
|
#define MAKE_TCCR(TccrName, className) \
|
||||||
|
class className{\
|
||||||
|
public:\
|
||||||
|
typedef uint8_t DataT;\
|
||||||
|
public:\
|
||||||
|
static void Write(DataT value){TccrName = value;}\
|
||||||
|
static void ClearAndSet(DataT clearMask, DataT value){TccrName = (TccrName & ~clearMask) | value;}\
|
||||||
|
static DataT Read(){return TccrName;}\
|
||||||
|
static void Set(DataT value){TccrName |= value;}\
|
||||||
|
static void Clear(DataT value){TccrName &= ~value;}\
|
||||||
|
static void Toggle(DataT value){TccrName ^= value;}\
|
||||||
|
enum{Width=sizeof(DataT)*8};\
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef USE_PORTA
|
||||||
|
MAKE_PORT(PORTA, DDRA, PINA, Porta, 'A')
|
||||||
|
#endif
|
||||||
|
#ifdef USE_PORTB
|
||||||
|
MAKE_PORT(PORTB, DDRB, PINB, Portb, 'B')
|
||||||
|
#endif
|
||||||
|
#ifdef USE_PORTC
|
||||||
|
MAKE_PORT(PORTC, DDRC, PINC, Portc, 'C')
|
||||||
|
#endif
|
||||||
|
#ifdef USE_PORTD
|
||||||
|
MAKE_PORT(PORTD, DDRD, PIND, Portd, 'D')
|
||||||
|
#endif
|
||||||
|
#ifdef USE_PORTE
|
||||||
|
MAKE_PORT(PORTE, DDRE, PINE, Porte, 'E')
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TCCR0A
|
||||||
|
MAKE_TCCR(TCCR0A, Tccr0a)
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TCCR1A
|
||||||
|
MAKE_TCCR(TCCR1A, Tccr1a)
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TCCR2A
|
||||||
|
MAKE_TCCR(TCCR2A, Tccr2a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// this class represents one pin in a IO port.
|
||||||
|
// It is fully static.
|
||||||
|
template<typename PORT, uint8_t PIN>
|
||||||
|
class TPin
|
||||||
|
{
|
||||||
|
// BOOST_STATIC_ASSERT(PIN < PORT::Width);
|
||||||
|
public:
|
||||||
|
typedef PORT Port;
|
||||||
|
enum{Number = PIN};
|
||||||
|
|
||||||
|
static void Set() { PORT::Set(1 << PIN); }
|
||||||
|
|
||||||
|
static void Set(uint8_t val){
|
||||||
|
if(val)
|
||||||
|
Set();
|
||||||
|
else Clear();}
|
||||||
|
|
||||||
|
static void SetDir(uint8_t val){
|
||||||
|
if(val)
|
||||||
|
SetDirWrite();
|
||||||
|
else SetDirRead();}
|
||||||
|
|
||||||
|
static void Clear(){PORT::Clear(1 << PIN);}
|
||||||
|
|
||||||
|
static void Toggle(){PORT::Toggle(1 << PIN);}
|
||||||
|
|
||||||
|
static void SetDirRead(){PORT::DirClear(1 << PIN);}
|
||||||
|
|
||||||
|
static void SetDirWrite(){PORT::DirSet(1 << PIN);}
|
||||||
|
|
||||||
|
static uint8_t IsSet(){return PORT::PinRead() & (uint8_t)(1 << PIN);}
|
||||||
|
|
||||||
|
static void WaiteForSet(){ while(IsSet()==0){} }
|
||||||
|
|
||||||
|
static void WaiteForClear(){ while(IsSet()){} }
|
||||||
|
}; //class TPin...
|
||||||
|
|
||||||
|
// this class represents one bit in TCCR port.
|
||||||
|
// used to set/clear TCCRx bits
|
||||||
|
// It is fully static.
|
||||||
|
template<typename TCCR, uint8_t COM>
|
||||||
|
class TCom
|
||||||
|
{
|
||||||
|
// BOOST_STATIC_ASSERT(PIN < PORT::Width);
|
||||||
|
public:
|
||||||
|
typedef TCCR Tccr;
|
||||||
|
enum{Com = COM};
|
||||||
|
|
||||||
|
static void Set() { TCCR::Set(1 << COM); }
|
||||||
|
|
||||||
|
static void Clear() { TCCR::Clear(1 << COM); }
|
||||||
|
|
||||||
|
static void Toggle() { TCCR::Toggle(1 << COM); }
|
||||||
|
}; //class TCom...
|
||||||
|
|
||||||
|
//Short pin definitions
|
||||||
|
#ifdef USE_PORTA
|
||||||
|
typedef TPin<Porta, 0> Pa0;
|
||||||
|
typedef TPin<Porta, 1> Pa1;
|
||||||
|
typedef TPin<Porta, 2> Pa2;
|
||||||
|
typedef TPin<Porta, 3> Pa3;
|
||||||
|
typedef TPin<Porta, 4> Pa4;
|
||||||
|
typedef TPin<Porta, 5> Pa5;
|
||||||
|
typedef TPin<Porta, 6> Pa6;
|
||||||
|
typedef TPin<Porta, 7> Pa7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTB
|
||||||
|
typedef TPin<Portb, 0> Pb0;
|
||||||
|
typedef TPin<Portb, 1> Pb1;
|
||||||
|
typedef TPin<Portb, 2> Pb2;
|
||||||
|
typedef TPin<Portb, 3> Pb3;
|
||||||
|
typedef TPin<Portb, 4> Pb4;
|
||||||
|
typedef TPin<Portb, 5> Pb5;
|
||||||
|
typedef TPin<Portb, 6> Pb6;
|
||||||
|
typedef TPin<Portb, 7> Pb7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTC
|
||||||
|
typedef TPin<Portc, 0> Pc0;
|
||||||
|
typedef TPin<Portc, 1> Pc1;
|
||||||
|
typedef TPin<Portc, 2> Pc2;
|
||||||
|
typedef TPin<Portc, 3> Pc3;
|
||||||
|
typedef TPin<Portc, 4> Pc4;
|
||||||
|
typedef TPin<Portc, 5> Pc5;
|
||||||
|
typedef TPin<Portc, 6> Pc6;
|
||||||
|
typedef TPin<Portc, 7> Pc7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTD
|
||||||
|
typedef TPin<Portd, 0> Pd0;
|
||||||
|
typedef TPin<Portd, 1> Pd1;
|
||||||
|
typedef TPin<Portd, 2> Pd2;
|
||||||
|
typedef TPin<Portd, 3> Pd3;
|
||||||
|
typedef TPin<Portd, 4> Pd4;
|
||||||
|
typedef TPin<Portd, 5> Pd5;
|
||||||
|
typedef TPin<Portd, 6> Pd6;
|
||||||
|
typedef TPin<Portd, 7> Pd7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTE
|
||||||
|
typedef TPin<Porte, 0> Pe0;
|
||||||
|
typedef TPin<Porte, 1> Pe1;
|
||||||
|
typedef TPin<Porte, 2> Pe2;
|
||||||
|
typedef TPin<Porte, 3> Pe3;
|
||||||
|
typedef TPin<Porte, 4> Pe4;
|
||||||
|
typedef TPin<Porte, 5> Pe5;
|
||||||
|
typedef TPin<Porte, 6> Pe6;
|
||||||
|
typedef TPin<Porte, 7> Pe7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTF
|
||||||
|
typedef TPin<Portf, 0> Pf0;
|
||||||
|
typedef TPin<Portf, 1> Pf1;
|
||||||
|
typedef TPin<Portf, 2> Pf2;
|
||||||
|
typedef TPin<Portf, 3> Pf3;
|
||||||
|
typedef TPin<Portf, 4> Pf4;
|
||||||
|
typedef TPin<Portf, 5> Pf5;
|
||||||
|
typedef TPin<Portf, 6> Pf6;
|
||||||
|
typedef TPin<Portf, 7> Pf7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTG
|
||||||
|
typedef TPin<Portg, 0> Pg0;
|
||||||
|
typedef TPin<Portg, 1> Pg1;
|
||||||
|
typedef TPin<Portg, 2> Pg2;
|
||||||
|
typedef TPin<Portg, 3> Pg3;
|
||||||
|
typedef TPin<Portg, 4> Pg4;
|
||||||
|
typedef TPin<Portg, 5> Pg5;
|
||||||
|
typedef TPin<Portg, 6> Pg6;
|
||||||
|
typedef TPin<Portg, 7> Pg7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTH
|
||||||
|
typedef TPin<Porth, 0> Ph0;
|
||||||
|
typedef TPin<Porth, 1> Ph1;
|
||||||
|
typedef TPin<Porth, 2> Ph2;
|
||||||
|
typedef TPin<Porth, 3> Ph3;
|
||||||
|
typedef TPin<Porth, 4> Ph4;
|
||||||
|
typedef TPin<Porth, 5> Ph5;
|
||||||
|
typedef TPin<Porth, 6> Ph6;
|
||||||
|
typedef TPin<Porth, 7> Ph7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTJ
|
||||||
|
typedef TPin<Portj, 0> Pj0;
|
||||||
|
typedef TPin<Portj, 1> Pj1;
|
||||||
|
typedef TPin<Portj, 2> Pj2;
|
||||||
|
typedef TPin<Portj, 3> Pj3;
|
||||||
|
typedef TPin<Portj, 4> Pj4;
|
||||||
|
typedef TPin<Portj, 5> Pj5;
|
||||||
|
typedef TPin<Portj, 6> Pj6;
|
||||||
|
typedef TPin<Portj, 7> Pj7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTK
|
||||||
|
typedef TPin<Portk, 0> Pk0;
|
||||||
|
typedef TPin<Portk, 1> Pk1;
|
||||||
|
typedef TPin<Portk, 2> Pk2;
|
||||||
|
typedef TPin<Portk, 3> Pk3;
|
||||||
|
typedef TPin<Portk, 4> Pk4;
|
||||||
|
typedef TPin<Portk, 5> Pk5;
|
||||||
|
typedef TPin<Portk, 6> Pk6;
|
||||||
|
typedef TPin<Portk, 7> Pk7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTQ
|
||||||
|
typedef TPin<Portq, 0> Pq0;
|
||||||
|
typedef TPin<Portq, 1> Pq1;
|
||||||
|
typedef TPin<Portq, 2> Pq2;
|
||||||
|
typedef TPin<Portq, 3> Pq3;
|
||||||
|
typedef TPin<Portq, 4> Pq4;
|
||||||
|
typedef TPin<Portq, 5> Pq5;
|
||||||
|
typedef TPin<Portq, 6> Pq6;
|
||||||
|
typedef TPin<Portq, 7> Pq7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_PORTR
|
||||||
|
typedef TPin<Portr, 0> Pr0;
|
||||||
|
typedef TPin<Portr, 1> Pr1;
|
||||||
|
typedef TPin<Portr, 2> Pr2;
|
||||||
|
typedef TPin<Portr, 3> Pr3;
|
||||||
|
typedef TPin<Portr, 4> Pr4;
|
||||||
|
typedef TPin<Portr, 5> Pr5;
|
||||||
|
typedef TPin<Portr, 6> Pr6;
|
||||||
|
typedef TPin<Portr, 7> Pr7;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TCCR0A
|
||||||
|
typedef TCom<Tccr0a, COM0A1> Tc0a; //P6
|
||||||
|
typedef TCom<Tccr0a, COM0B1> Tc0b; //P5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TCCR1A
|
||||||
|
typedef TCom<Tccr1a, COM1A1> Tc1a; //P9
|
||||||
|
typedef TCom<Tccr1a, COM1B1> Tc1b; //P10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TCCR2A
|
||||||
|
typedef TCom<Tccr2a, COM2A1> Tc2a; //P11
|
||||||
|
typedef TCom<Tccr2a, COM2B1> Tc2b; //P3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename Tp_pin, typename Tc_bit>
|
||||||
|
class Tp_Tc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void SetDir(uint8_t val){
|
||||||
|
if(val)
|
||||||
|
SetDirWrite();
|
||||||
|
else SetDirRead();
|
||||||
|
}
|
||||||
|
static void SetDirRead(){
|
||||||
|
Tp_pin::SetDirRead(); //set pin direction
|
||||||
|
Tc_bit::Clear(); //disconnect pin from PWM
|
||||||
|
}
|
||||||
|
static void SetDirWrite(){
|
||||||
|
Tp_pin::SetDirWrite();
|
||||||
|
Tc_bit::Clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* pin definitions for cases where it's necessary to clear compare output mode bits */
|
||||||
|
|
||||||
|
//typedef Tp_Tc<Pd3, Tc2b> P3; //Arduino pin 3
|
||||||
|
//typedef Tp_Tc<Pd5, Tc0b> P5; //Arduino pin 5
|
||||||
|
//typedef Tp_Tc<Pd6, Tc0a> P6; //Arduino pin 6
|
||||||
|
//typedef Tp_Tc<Pb1, Tc1a> P9; //Arduino pin 9
|
||||||
|
//typedef Tp_Tc<Pb2, Tc1b> P10; //Arduino pin 10
|
||||||
|
//typedef Tp_Tc<Pb3, Tc2a> P11; //Arduino pin 11
|
||||||
|
|
||||||
|
//Arduino pin numbers
|
||||||
|
|
||||||
|
#define P0 Pd0
|
||||||
|
#define P1 Pd1
|
||||||
|
#define P2 Pd2
|
||||||
|
#define P3 Pd3
|
||||||
|
#define P4 Pd4
|
||||||
|
#define P5 Pd5
|
||||||
|
#define P6 Pd6
|
||||||
|
#define P7 Pd7
|
||||||
|
|
||||||
|
#define P8 Pb0
|
||||||
|
#define P9 Pb1
|
||||||
|
#define P10 Pb2
|
||||||
|
#define P11 Pb3
|
||||||
|
#define P12 Pb4
|
||||||
|
#define P13 Pb5
|
||||||
|
|
||||||
|
#define P14 Pc0
|
||||||
|
#define P15 Pc1
|
||||||
|
#define P16 Pc2
|
||||||
|
#define P17 Pc3
|
||||||
|
#define P18 Pc4
|
||||||
|
#define P19 Pc5
|
||||||
|
|
||||||
|
#endif //_avrpins_h_
|
223
max3421e.h
Normal file
223
max3421e.h
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/* MAX3421E register/bit names and bitmasks */
|
||||||
|
|
||||||
|
#ifndef _max3421e_h_
|
||||||
|
#define _max3421e_h_
|
||||||
|
|
||||||
|
/* Arduino pin definitions */
|
||||||
|
|
||||||
|
|
||||||
|
/* pin numbers to port numbers */
|
||||||
|
|
||||||
|
//#define MAX_SS 10
|
||||||
|
//#define MAX_INT 9
|
||||||
|
//#define MAX_GPX 8
|
||||||
|
//#define MAX_RESET 7
|
||||||
|
//
|
||||||
|
//#define BPNT_0 3
|
||||||
|
//#define BPNT_1 2
|
||||||
|
//
|
||||||
|
//#define Select_MAX3421E digitalWrite( MAX_SS,LOW )
|
||||||
|
//#define Deselect_MAX3421E digitalWrite( MAX_SS,HIGH )
|
||||||
|
|
||||||
|
/* */
|
||||||
|
|
||||||
|
#define ON true
|
||||||
|
#define OFF false
|
||||||
|
|
||||||
|
#define SE0 0
|
||||||
|
#define SE1 1
|
||||||
|
#define FSHOST 2
|
||||||
|
#define LSHOST 3
|
||||||
|
|
||||||
|
/* MAX3421E command byte format: rrrrr0wa where 'r' is register number */
|
||||||
|
//
|
||||||
|
// MAX3421E Registers in HOST mode.
|
||||||
|
//
|
||||||
|
#define rRCVFIFO 0x08 //1<<3
|
||||||
|
#define rSNDFIFO 0x10 //2<<3
|
||||||
|
#define rSUDFIFO 0x20 //4<<3
|
||||||
|
#define rRCVBC 0x30 //6<<3
|
||||||
|
#define rSNDBC 0x38 //7<<3
|
||||||
|
|
||||||
|
#define rUSBIRQ 0x68 //13<<3
|
||||||
|
/* USBIRQ Bits */
|
||||||
|
#define bmVBUSIRQ 0x40 //b6
|
||||||
|
#define bmNOVBUSIRQ 0x20 //b5
|
||||||
|
#define bmOSCOKIRQ 0x01 //b0
|
||||||
|
|
||||||
|
#define rUSBIEN 0x70 //14<<3
|
||||||
|
/* USBIEN Bits */
|
||||||
|
#define bmVBUSIE 0x40 //b6
|
||||||
|
#define bmNOVBUSIE 0x20 //b5
|
||||||
|
#define bmOSCOKIE 0x01 //b0
|
||||||
|
|
||||||
|
#define rUSBCTL 0x78 //15<<3
|
||||||
|
/* USBCTL Bits */
|
||||||
|
#define bmCHIPRES 0x20 //b5
|
||||||
|
#define bmPWRDOWN 0x10 //b4
|
||||||
|
|
||||||
|
#define rCPUCTL 0x80 //16<<3
|
||||||
|
/* CPUCTL Bits */
|
||||||
|
#define bmPUSLEWID1 0x80 //b7
|
||||||
|
#define bmPULSEWID0 0x40 //b6
|
||||||
|
#define bmIE 0x01 //b0
|
||||||
|
|
||||||
|
#define rPINCTL 0x88 //17<<3
|
||||||
|
/* PINCTL Bits */
|
||||||
|
#define bmFDUPSPI 0x10 //b4
|
||||||
|
#define bmINTLEVEL 0x08 //b3
|
||||||
|
#define bmPOSINT 0x04 //b2
|
||||||
|
#define bmGPXB 0x02 //b1
|
||||||
|
#define bmGPXA 0x01 //b0
|
||||||
|
// GPX pin selections
|
||||||
|
#define GPX_OPERATE 0x00
|
||||||
|
#define GPX_VBDET 0x01
|
||||||
|
#define GPX_BUSACT 0x02
|
||||||
|
#define GPX_SOF 0x03
|
||||||
|
|
||||||
|
#define rREVISION 0x90 //18<<3
|
||||||
|
|
||||||
|
#define rIOPINS1 0xa0 //20<<3
|
||||||
|
|
||||||
|
/* IOPINS1 Bits */
|
||||||
|
#define bmGPOUT0 0x01
|
||||||
|
#define bmGPOUT1 0x02
|
||||||
|
#define bmGPOUT2 0x04
|
||||||
|
#define bmGPOUT3 0x08
|
||||||
|
#define bmGPIN0 0x10
|
||||||
|
#define bmGPIN1 0x20
|
||||||
|
#define bmGPIN2 0x40
|
||||||
|
#define bmGPIN3 0x80
|
||||||
|
|
||||||
|
#define rIOPINS2 0xa8 //21<<3
|
||||||
|
/* IOPINS2 Bits */
|
||||||
|
#define bmGPOUT4 0x01
|
||||||
|
#define bmGPOUT5 0x02
|
||||||
|
#define bmGPOUT6 0x04
|
||||||
|
#define bmGPOUT7 0x08
|
||||||
|
#define bmGPIN4 0x10
|
||||||
|
#define bmGPIN5 0x20
|
||||||
|
#define bmGPIN6 0x40
|
||||||
|
#define bmGPIN7 0x80
|
||||||
|
|
||||||
|
#define rGPINIRQ 0xb0 //22<<3
|
||||||
|
/* GPINIRQ Bits */
|
||||||
|
#define bmGPINIRQ0 0x01
|
||||||
|
#define bmGPINIRQ1 0x02
|
||||||
|
#define bmGPINIRQ2 0x04
|
||||||
|
#define bmGPINIRQ3 0x08
|
||||||
|
#define bmGPINIRQ4 0x10
|
||||||
|
#define bmGPINIRQ5 0x20
|
||||||
|
#define bmGPINIRQ6 0x40
|
||||||
|
#define bmGPINIRQ7 0x80
|
||||||
|
|
||||||
|
#define rGPINIEN 0xb8 //23<<3
|
||||||
|
/* GPINIEN Bits */
|
||||||
|
#define bmGPINIEN0 0x01
|
||||||
|
#define bmGPINIEN1 0x02
|
||||||
|
#define bmGPINIEN2 0x04
|
||||||
|
#define bmGPINIEN3 0x08
|
||||||
|
#define bmGPINIEN4 0x10
|
||||||
|
#define bmGPINIEN5 0x20
|
||||||
|
#define bmGPINIEN6 0x40
|
||||||
|
#define bmGPINIEN7 0x80
|
||||||
|
|
||||||
|
#define rGPINPOL 0xc0 //24<<3
|
||||||
|
/* GPINPOL Bits */
|
||||||
|
#define bmGPINPOL0 0x01
|
||||||
|
#define bmGPINPOL1 0x02
|
||||||
|
#define bmGPINPOL2 0x04
|
||||||
|
#define bmGPINPOL3 0x08
|
||||||
|
#define bmGPINPOL4 0x10
|
||||||
|
#define bmGPINPOL5 0x20
|
||||||
|
#define bmGPINPOL6 0x40
|
||||||
|
#define bmGPINPOL7 0x80
|
||||||
|
|
||||||
|
#define rHIRQ 0xc8 //25<<3
|
||||||
|
/* HIRQ Bits */
|
||||||
|
#define bmBUSEVENTIRQ 0x01 // indicates BUS Reset Done or BUS Resume
|
||||||
|
#define bmRWUIRQ 0x02
|
||||||
|
#define bmRCVDAVIRQ 0x04
|
||||||
|
#define bmSNDBAVIRQ 0x08
|
||||||
|
#define bmSUSDNIRQ 0x10
|
||||||
|
#define bmCONDETIRQ 0x20
|
||||||
|
#define bmFRAMEIRQ 0x40
|
||||||
|
#define bmHXFRDNIRQ 0x80
|
||||||
|
|
||||||
|
#define rHIEN 0xd0 //26<<3
|
||||||
|
/* HIEN Bits */
|
||||||
|
#define bmBUSEVENTIE 0x01
|
||||||
|
#define bmRWUIE 0x02
|
||||||
|
#define bmRCVDAVIE 0x04
|
||||||
|
#define bmSNDBAVIE 0x08
|
||||||
|
#define bmSUSDNIE 0x10
|
||||||
|
#define bmCONDETIE 0x20
|
||||||
|
#define bmFRAMEIE 0x40
|
||||||
|
#define bmHXFRDNIE 0x80
|
||||||
|
|
||||||
|
#define rMODE 0xd8 //27<<3
|
||||||
|
/* MODE Bits */
|
||||||
|
#define bmHOST 0x01
|
||||||
|
#define bmLOWSPEED 0x02
|
||||||
|
#define bmHUBPRE 0x04
|
||||||
|
#define bmSOFKAENAB 0x08
|
||||||
|
#define bmSEPIRQ 0x10
|
||||||
|
#define bmDELAYISO 0x20
|
||||||
|
#define bmDMPULLDN 0x40
|
||||||
|
#define bmDPPULLDN 0x80
|
||||||
|
|
||||||
|
#define rPERADDR 0xe0 //28<<3
|
||||||
|
|
||||||
|
#define rHCTL 0xe8 //29<<3
|
||||||
|
/* HCTL Bits */
|
||||||
|
#define bmBUSRST 0x01
|
||||||
|
#define bmFRMRST 0x02
|
||||||
|
#define bmSAMPLEBUS 0x04
|
||||||
|
#define bmSIGRSM 0x08
|
||||||
|
#define bmRCVTOG0 0x10
|
||||||
|
#define bmRCVTOG1 0x20
|
||||||
|
#define bmSNDTOG0 0x40
|
||||||
|
#define bmSNDTOG1 0x80
|
||||||
|
|
||||||
|
#define rHXFR 0xf0 //30<<3
|
||||||
|
/* Host transfer token values for writing the HXFR register (R30) */
|
||||||
|
/* OR this bit field with the endpoint number in bits 3:0 */
|
||||||
|
#define tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1
|
||||||
|
#define tokIN 0x00 // HS=0, ISO=0, OUTNIN=0, SETUP=0
|
||||||
|
#define tokOUT 0x20 // HS=0, ISO=0, OUTNIN=1, SETUP=0
|
||||||
|
#define tokINHS 0x80 // HS=1, ISO=0, OUTNIN=0, SETUP=0
|
||||||
|
#define tokOUTHS 0xA0 // HS=1, ISO=0, OUTNIN=1, SETUP=0
|
||||||
|
#define tokISOIN 0x40 // HS=0, ISO=1, OUTNIN=0, SETUP=0
|
||||||
|
#define tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0
|
||||||
|
|
||||||
|
#define rHRSL 0xf8 //31<<3
|
||||||
|
/* HRSL Bits */
|
||||||
|
#define bmRCVTOGRD 0x10
|
||||||
|
#define bmSNDTOGRD 0x20
|
||||||
|
#define bmKSTATUS 0x40
|
||||||
|
#define bmJSTATUS 0x80
|
||||||
|
#define bmSE0 0x00 //SE0 - disconnect state
|
||||||
|
#define bmSE1 0xc0 //SE1 - illegal state
|
||||||
|
/* Host error result codes, the 4 LSB's in the HRSL register */
|
||||||
|
#define hrSUCCESS 0x00
|
||||||
|
#define hrBUSY 0x01
|
||||||
|
#define hrBADREQ 0x02
|
||||||
|
#define hrUNDEF 0x03
|
||||||
|
#define hrNAK 0x04
|
||||||
|
#define hrSTALL 0x05
|
||||||
|
#define hrTOGERR 0x06
|
||||||
|
#define hrWRONGPID 0x07
|
||||||
|
#define hrBADBC 0x08
|
||||||
|
#define hrPIDERR 0x09
|
||||||
|
#define hrPKTERR 0x0A
|
||||||
|
#define hrCRCERR 0x0B
|
||||||
|
#define hrKERR 0x0C
|
||||||
|
#define hrJERR 0x0D
|
||||||
|
#define hrTIMEOUT 0x0E
|
||||||
|
#define hrBABBLE 0x0F
|
||||||
|
|
||||||
|
#define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB)
|
||||||
|
#define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB)
|
||||||
|
|
||||||
|
|
||||||
|
#endif //_max3421e_h_
|
59
newusb.pde
Normal file
59
newusb.pde
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* new USB library tests */
|
||||||
|
|
||||||
|
//nclude <digitalWriteFast.h>
|
||||||
|
#include "usbhost.h"
|
||||||
|
|
||||||
|
MAX3421e<P10, P9> Max;
|
||||||
|
uint8_t buf[10] = {0};
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Max.regWr( rPINCTL,( bmFDUPSPI + bmINTLEVEL ));
|
||||||
|
// Max.regWr( rUSBCTL, bmCHIPRES ); //Chip reset. This stops the oscillator
|
||||||
|
// Max.regWr( rUSBCTL, 0x00 ); //Remove the reset
|
||||||
|
// delay( 100 );
|
||||||
|
Serial.begin( 115200 );
|
||||||
|
Serial.println("Start");
|
||||||
|
|
||||||
|
// pinModeFast2( 8, OUTPUT)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// uint16_t i;
|
||||||
|
// Max.regWr( rUSBCTL, bmCHIPRES );
|
||||||
|
// Max.regWr( rUSBCTL, 0x00 );
|
||||||
|
// for( i = 0; i < 65535; i++ ) {
|
||||||
|
// if( ( Max.regRd( rUSBIRQ ) & bmOSCOKIRQ )) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
Serial.println( Max.reset(), DEC );
|
||||||
|
//Max.reset();
|
||||||
|
//delay( 100 );
|
||||||
|
//Max.regRd( rREVISION );
|
||||||
|
//Serial.println( Max.regRd( rREVISION ), HEX );
|
||||||
|
|
||||||
|
//Serial.println("tick");
|
||||||
|
// uint8_t tmp;
|
||||||
|
// for( uint16_t i = 0; i < 256; i++ ) {
|
||||||
|
// tmp = Max.SPIxfer( i );
|
||||||
|
// if( tmp != i ) {
|
||||||
|
// Serial.println("error");
|
||||||
|
// }
|
||||||
|
// if( SPSR & 0x40 ) {
|
||||||
|
// Serial.println("WCOL");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// static bool oldintval = 0;
|
||||||
|
// if( Max.intval() != oldintval ) {
|
||||||
|
// oldintval = Max.intval();
|
||||||
|
// Serial.println( oldintval, DEC );
|
||||||
|
// }
|
||||||
|
// Max.sstoggle();
|
||||||
|
|
||||||
|
//digitalWriteFast2( 8, 0 );
|
||||||
|
//digitalWriteFast2( 8, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
169
usb_ch9.h
Normal file
169
usb_ch9.h
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/* USB chapter 9 structures */
|
||||||
|
#ifndef _ch9_h_
|
||||||
|
#define _ch9_h_
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
/* Misc.USB constants */
|
||||||
|
#define DEV_DESCR_LEN 18 //device descriptor length
|
||||||
|
#define CONF_DESCR_LEN 9 //configuration descriptor length
|
||||||
|
#define INTR_DESCR_LEN 9 //interface descriptor length
|
||||||
|
#define EP_DESCR_LEN 7 //endpoint descriptor length
|
||||||
|
|
||||||
|
/* Standard Device Requests */
|
||||||
|
|
||||||
|
#define USB_REQUEST_GET_STATUS 0 // Standard Device Request - GET STATUS
|
||||||
|
#define USB_REQUEST_CLEAR_FEATURE 1 // Standard Device Request - CLEAR FEATURE
|
||||||
|
#define USB_REQUEST_SET_FEATURE 3 // Standard Device Request - SET FEATURE
|
||||||
|
#define USB_REQUEST_SET_ADDRESS 5 // Standard Device Request - SET ADDRESS
|
||||||
|
#define USB_REQUEST_GET_DESCRIPTOR 6 // Standard Device Request - GET DESCRIPTOR
|
||||||
|
#define USB_REQUEST_SET_DESCRIPTOR 7 // Standard Device Request - SET DESCRIPTOR
|
||||||
|
#define USB_REQUEST_GET_CONFIGURATION 8 // Standard Device Request - GET CONFIGURATION
|
||||||
|
#define USB_REQUEST_SET_CONFIGURATION 9 // Standard Device Request - SET CONFIGURATION
|
||||||
|
#define USB_REQUEST_GET_INTERFACE 10 // Standard Device Request - GET INTERFACE
|
||||||
|
#define USB_REQUEST_SET_INTERFACE 11 // Standard Device Request - SET INTERFACE
|
||||||
|
#define USB_REQUEST_SYNCH_FRAME 12 // Standard Device Request - SYNCH FRAME
|
||||||
|
|
||||||
|
#define USB_FEATURE_ENDPOINT_HALT 0 // CLEAR/SET FEATURE - Endpoint Halt
|
||||||
|
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // CLEAR/SET FEATURE - Device remote wake-up
|
||||||
|
#define USB_FEATURE_TEST_MODE 2 // CLEAR/SET FEATURE - Test mode
|
||||||
|
|
||||||
|
/* Setup Data Constants */
|
||||||
|
|
||||||
|
#define USB_SETUP_HOST_TO_DEVICE 0x00 // Device Request bmRequestType transfer direction - host to device transfer
|
||||||
|
#define USB_SETUP_DEVICE_TO_HOST 0x80 // Device Request bmRequestType transfer direction - device to host transfer
|
||||||
|
#define USB_SETUP_TYPE_STANDARD 0x00 // Device Request bmRequestType type - standard
|
||||||
|
#define USB_SETUP_TYPE_CLASS 0x20 // Device Request bmRequestType type - class
|
||||||
|
#define USB_SETUP_TYPE_VENDOR 0x40 // Device Request bmRequestType type - vendor
|
||||||
|
#define USB_SETUP_RECIPIENT_DEVICE 0x00 // Device Request bmRequestType recipient - device
|
||||||
|
#define USB_SETUP_RECIPIENT_INTERFACE 0x01 // Device Request bmRequestType recipient - interface
|
||||||
|
#define USB_SETUP_RECIPIENT_ENDPOINT 0x02 // Device Request bmRequestType recipient - endpoint
|
||||||
|
#define USB_SETUP_RECIPIENT_OTHER 0x03 // Device Request bmRequestType recipient - other
|
||||||
|
|
||||||
|
/* USB descriptors */
|
||||||
|
|
||||||
|
#define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor.
|
||||||
|
#define USB_DESCRIPTOR_CONFIGURATION 0x02 // bDescriptorType for a Configuration Descriptor.
|
||||||
|
#define USB_DESCRIPTOR_STRING 0x03 // bDescriptorType for a String Descriptor.
|
||||||
|
#define USB_DESCRIPTOR_INTERFACE 0x04 // bDescriptorType for an Interface Descriptor.
|
||||||
|
#define USB_DESCRIPTOR_ENDPOINT 0x05 // bDescriptorType for an Endpoint Descriptor.
|
||||||
|
#define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // bDescriptorType for a Device Qualifier.
|
||||||
|
#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration.
|
||||||
|
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
|
||||||
|
#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor.
|
||||||
|
|
||||||
|
/* OTG SET FEATURE Constants */
|
||||||
|
#define OTG_FEATURE_B_HNP_ENABLE 3 // SET FEATURE OTG - Enable B device to perform HNP
|
||||||
|
#define OTG_FEATURE_A_HNP_SUPPORT 4 // SET FEATURE OTG - A device supports HNP
|
||||||
|
#define OTG_FEATURE_A_ALT_HNP_SUPPORT 5 // SET FEATURE OTG - Another port on the A device supports HNP
|
||||||
|
|
||||||
|
/* USB Endpoint Transfer Types */
|
||||||
|
#define USB_TRANSFER_TYPE_CONTROL 0x00 // Endpoint is a control endpoint.
|
||||||
|
#define USB_TRANSFER_TYPE_ISOCHRONOUS 0x01 // Endpoint is an isochronous endpoint.
|
||||||
|
#define USB_TRANSFER_TYPE_BULK 0x02 // Endpoint is a bulk endpoint.
|
||||||
|
#define USB_TRANSFER_TYPE_INTERRUPT 0x03 // Endpoint is an interrupt endpoint.
|
||||||
|
#define bmUSB_TRANSFER_TYPE 0x03 // bit mask to separate transfer type from ISO attributes
|
||||||
|
|
||||||
|
|
||||||
|
/* Standard Feature Selectors for CLEAR_FEATURE Requests */
|
||||||
|
#define USB_FEATURE_ENDPOINT_STALL 0 // Endpoint recipient
|
||||||
|
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1 // Device recipient
|
||||||
|
#define USB_FEATURE_TEST_MODE 2 // Device recipient
|
||||||
|
|
||||||
|
/* HID constants. Not part of chapter 9 */
|
||||||
|
/* Class-Specific Requests */
|
||||||
|
#define HID_REQUEST_GET_REPORT 0x01
|
||||||
|
#define HID_REQUEST_GET_IDLE 0x02
|
||||||
|
#define HID_REQUEST_GET_PROTOCOL 0x03
|
||||||
|
#define HID_REQUEST_SET_REPORT 0x09
|
||||||
|
#define HID_REQUEST_SET_IDLE 0x0A
|
||||||
|
#define HID_REQUEST_SET_PROTOCOL 0x0B
|
||||||
|
|
||||||
|
/* Class Descriptor Types */
|
||||||
|
#define HID_DESCRIPTOR_HID 0x21
|
||||||
|
#define HID_DESCRIPTOR_REPORT 0x22
|
||||||
|
#define HID_DESRIPTOR_PHY 0x23
|
||||||
|
|
||||||
|
/* Protocol Selection */
|
||||||
|
#define BOOT_PROTOCOL 0x00
|
||||||
|
#define RPT_PROTOCOL 0x01
|
||||||
|
/* HID Interface Class Code */
|
||||||
|
#define HID_INTF 0x03
|
||||||
|
/* HID Interface Class SubClass Codes */
|
||||||
|
#define BOOT_INTF_SUBCLASS 0x01
|
||||||
|
/* HID Interface Class Protocol Codes */
|
||||||
|
#define HID_PROTOCOL_NONE 0x00
|
||||||
|
#define HID_PROTOCOL_KEYBOARD 0x01
|
||||||
|
#define HID_PROTOCOL_MOUSE 0x02
|
||||||
|
|
||||||
|
|
||||||
|
/* descriptor data structures */
|
||||||
|
|
||||||
|
/* Device descriptor structure */
|
||||||
|
typedef struct {
|
||||||
|
uint8_t bLength; // Length of this descriptor.
|
||||||
|
uint8_t bDescriptorType; // DEVICE descriptor type (USB_DESCRIPTOR_DEVICE).
|
||||||
|
uint16_t bcdUSB; // USB Spec Release Number (BCD).
|
||||||
|
uint8_t bDeviceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||||
|
uint8_t bDeviceSubClass; // Subclass code (assigned by the USB-IF).
|
||||||
|
uint8_t bDeviceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||||
|
uint8_t bMaxPacketSize0; // Maximum packet size for endpoint 0.
|
||||||
|
uint16_t idVendor; // Vendor ID (assigned by the USB-IF).
|
||||||
|
uint16_t idProduct; // Product ID (assigned by the manufacturer).
|
||||||
|
uint16_t bcdDevice; // Device release number (BCD).
|
||||||
|
uint8_t iManufacturer; // Index of String Descriptor describing the manufacturer.
|
||||||
|
uint8_t iProduct; // Index of String Descriptor describing the product.
|
||||||
|
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
|
||||||
|
uint8_t bNumConfigurations; // Number of possible configurations.
|
||||||
|
} USB_DEVICE_DESCRIPTOR;
|
||||||
|
|
||||||
|
/* Configuration descriptor structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t bLength; // Length of this descriptor.
|
||||||
|
uint8_t bDescriptorType; // CONFIGURATION descriptor type (USB_DESCRIPTOR_CONFIGURATION).
|
||||||
|
uint16_t wTotalLength; // Total length of all descriptors for this configuration.
|
||||||
|
uint8_t bNumInterfaces; // Number of interfaces in this configuration.
|
||||||
|
uint8_t bConfigurationValue; // Value of this configuration (1 based).
|
||||||
|
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
|
||||||
|
uint8_t bmAttributes; // Configuration characteristics.
|
||||||
|
uint8_t bMaxPower; // Maximum power consumed by this configuration.
|
||||||
|
} USB_CONFIGURATION_DESCRIPTOR;
|
||||||
|
|
||||||
|
/* Interface descriptor structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t bLength; // Length of this descriptor.
|
||||||
|
uint8_t bDescriptorType; // INTERFACE descriptor type (USB_DESCRIPTOR_INTERFACE).
|
||||||
|
uint8_t bInterfaceNumber; // Number of this interface (0 based).
|
||||||
|
uint8_t bAlternateSetting; // Value of this alternate interface setting.
|
||||||
|
uint8_t bNumEndpoints; // Number of endpoints in this interface.
|
||||||
|
uint8_t bInterfaceClass; // Class code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||||
|
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
|
||||||
|
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||||
|
uint8_t iInterface; // Index of String Descriptor describing the interface.
|
||||||
|
} USB_INTERFACE_DESCRIPTOR;
|
||||||
|
|
||||||
|
/* Endpoint descriptor structure */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t bLength; // Length of this descriptor.
|
||||||
|
uint8_t bDescriptorType; // ENDPOINT descriptor type (USB_DESCRIPTOR_ENDPOINT).
|
||||||
|
uint8_t bEndpointAddress; // Endpoint address. Bit 7 indicates direction (0=OUT, 1=IN).
|
||||||
|
uint8_t bmAttributes; // Endpoint transfer type.
|
||||||
|
uint16_t wMaxPacketSize; // Maximum packet size.
|
||||||
|
uint8_t bInterval; // Polling interval in frames.
|
||||||
|
} USB_ENDPOINT_DESCRIPTOR;
|
||||||
|
|
||||||
|
/* HID descriptor */
|
||||||
|
typedef struct {
|
||||||
|
uint8_t bLength;
|
||||||
|
uint8_t bDescriptorType;
|
||||||
|
uint16_t bcdHID;
|
||||||
|
uint8_t bCountryCode;
|
||||||
|
uint8_t bNumDescriptors;
|
||||||
|
uint8_t bDescrType;
|
||||||
|
uint16_t wDescriptorLength;
|
||||||
|
} USB_HID_DESCRIPTOR;
|
||||||
|
|
||||||
|
#endif // _ch9_h_
|
169
usbhost.h
Normal file
169
usbhost.h
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/* MAX3421E-based USB Host Library header file */
|
||||||
|
#ifndef _USBHOST_H_
|
||||||
|
#define _USBHOST_H_
|
||||||
|
|
||||||
|
//#include <WProgram.h>
|
||||||
|
#include "avrpins.h"
|
||||||
|
#include "max3421e.h"
|
||||||
|
#include "usb_ch9.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* SPI initialization */
|
||||||
|
template< typename CLK, typename MOSI, typename MISO > class SPi
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void init() {
|
||||||
|
uint8_t tmp;
|
||||||
|
CLK::SetDirWrite();
|
||||||
|
MOSI::SetDirWrite();
|
||||||
|
MISO::SetDirRead();
|
||||||
|
/* mode 00 (CPOL=0, CPHA=0) master, fclk/2. Mode 11 (CPOL=11, CPHA=11) is also supported by MAX3421E */
|
||||||
|
SPCR = 0x50;
|
||||||
|
SPSR = 0x01;
|
||||||
|
/**/
|
||||||
|
tmp = SPSR;
|
||||||
|
tmp = SPDR;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SPI pin definitions. see avrpins.h */
|
||||||
|
#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__)
|
||||||
|
typedef SPi< Pb1, Pb2, Pb3 > spi;
|
||||||
|
#endif
|
||||||
|
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
|
||||||
|
typedef SPi< Pb5, Pb3, Pb4 > spi;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template< typename SS, typename INTR > class MAX3421e /* : public spi */
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MAX3421e();
|
||||||
|
void regWr( uint8_t reg, uint8_t data );
|
||||||
|
uint8_t* bytesWr( uint8_t reg, uint8_t nbytes, uint8_t* data_p );
|
||||||
|
void gpioWr( uint8_t data );
|
||||||
|
uint8_t regRd( uint8_t reg );
|
||||||
|
uint8_t* bytesRd( uint8_t reg, uint8_t nbytes, uint8_t* data_p );
|
||||||
|
uint8_t gpioRd();
|
||||||
|
uint16_t reset();
|
||||||
|
uint8_t init();
|
||||||
|
};
|
||||||
|
/* constructor */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
MAX3421e< SS, INTR >::MAX3421e()
|
||||||
|
{
|
||||||
|
/* pin and peripheral setup */
|
||||||
|
SS::SetDirWrite();
|
||||||
|
SS::Set();
|
||||||
|
spi::init();
|
||||||
|
INTR::SetDirRead();
|
||||||
|
/* MAX3421E - full-duplex SPI, level interrupt */
|
||||||
|
regWr( rPINCTL,( bmFDUPSPI + bmINTLEVEL ));
|
||||||
|
};
|
||||||
|
/* write single byte into MAX3421 register */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
void MAX3421e< SS, INTR >::regWr( uint8_t reg, uint8_t data )
|
||||||
|
{
|
||||||
|
SS::Clear();
|
||||||
|
SPDR = ( reg | 0x02 );
|
||||||
|
while(!( SPSR & ( 1 << SPIF )));
|
||||||
|
SPDR = data;
|
||||||
|
while(!( SPSR & ( 1 << SPIF )));
|
||||||
|
SS::Set();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
/* multiple-byte write */
|
||||||
|
/* returns a pointer to memory position after last written */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
uint8_t* MAX3421e< SS, INTR >::bytesWr( uint8_t reg, uint8_t nbytes, uint8_t* data_p )
|
||||||
|
{
|
||||||
|
SS::Clear();
|
||||||
|
SPDR = ( reg | 0x02 ); //set WR bit and send register number
|
||||||
|
while( nbytes-- ) {
|
||||||
|
while(!( SPSR & ( 1 << SPIF ))); //check if previous byte was sent
|
||||||
|
SPDR = ( *data_p ); // send next data byte
|
||||||
|
data_p++; // advance data pointer
|
||||||
|
}
|
||||||
|
while(!( SPSR & ( 1 << SPIF )));
|
||||||
|
SS::Set();
|
||||||
|
return( data_p );
|
||||||
|
}
|
||||||
|
/* GPIO write */
|
||||||
|
/*GPIO byte is split between 2 registers, so two writes are needed to write one byte */
|
||||||
|
/* GPOUT bits are in the low nibble. 0-3 in IOPINS1, 4-7 in IOPINS2 */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
void MAX3421e< SS, INTR >::gpioWr( uint8_t data )
|
||||||
|
{
|
||||||
|
regWr( rIOPINS1, data );
|
||||||
|
data >>= 4;
|
||||||
|
regWr( rIOPINS2, data );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* single host register read */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
uint8_t MAX3421e< SS, INTR >::regRd( uint8_t reg )
|
||||||
|
{
|
||||||
|
SS::Clear();
|
||||||
|
SPDR = reg;
|
||||||
|
while(!( SPSR & ( 1 << SPIF )));
|
||||||
|
SPDR = 0; //send empty byte
|
||||||
|
while(!( SPSR & ( 1 << SPIF )));
|
||||||
|
SS::Set();
|
||||||
|
return( SPDR );
|
||||||
|
}
|
||||||
|
/* multiple-byte register read */
|
||||||
|
/* returns a pointer to a memory position after last read */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
uint8_t* MAX3421e< SS, INTR >::bytesRd( uint8_t reg, uint8_t nbytes, uint8_t* data_p )
|
||||||
|
{
|
||||||
|
SS::Clear();
|
||||||
|
SPDR = reg;
|
||||||
|
while(!( SPSR & ( 1 << SPIF ))); //wait
|
||||||
|
while( nbytes ) {
|
||||||
|
SPDR = 0; //send empty byte
|
||||||
|
nbytes--;
|
||||||
|
while(!( SPSR & ( 1 << SPIF )));
|
||||||
|
*data_p = SPDR;
|
||||||
|
data_p++;
|
||||||
|
}
|
||||||
|
SS::Set();
|
||||||
|
return( data_p );
|
||||||
|
}
|
||||||
|
/* GPIO read. See gpioWr for explanation */
|
||||||
|
/* GPIN pins are in high nibbles of IOPINS1, IOPINS2 */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
uint8_t MAX3421e< SS, INTR >::gpioRd()
|
||||||
|
{
|
||||||
|
uint8_t gpin = 0;
|
||||||
|
gpin = regRd( rIOPINS2 ); //pins 4-7
|
||||||
|
gpin &= 0xf0; //clean lower nibble
|
||||||
|
gpin |= ( regRd( rIOPINS1 ) >>4 ) ; //shift low bits and OR with upper from previous operation.
|
||||||
|
return( gpin );
|
||||||
|
}
|
||||||
|
/* reset MAX3421E. Returns number of cycles it took for PLL to stabilize after reset
|
||||||
|
or zero if PLL haven't stabilized in 65535 cycles */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
uint16_t MAX3421e< SS, INTR >::reset()
|
||||||
|
{
|
||||||
|
uint16_t i = 0;
|
||||||
|
regWr( rUSBCTL, bmCHIPRES );
|
||||||
|
regWr( rUSBCTL, 0x00 );
|
||||||
|
while( ++i ) {
|
||||||
|
if(( regRd( rUSBIRQ ) & bmOSCOKIRQ )) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return( i );
|
||||||
|
}
|
||||||
|
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
|
||||||
|
template< typename SS, typename INTR >
|
||||||
|
uint8_t MAX3421e< SS, INTR >::init()
|
||||||
|
{
|
||||||
|
if( reset() == 0 ) { //OSCOKIRQ hasn't asserted in time
|
||||||
|
return ( -1 );
|
||||||
|
}
|
||||||
|
regWr( rMODE, bmDPPULLDN|bmDMPULLDN|bmHOST ); // set pull-downs, Host
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_USBHOST_H_
|
Loading…
Reference in a new issue