mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
locks and constructor/init fixes
This commit is contained in:
parent
272180cf60
commit
42fc48d129
1 changed files with 38 additions and 12 deletions
50
usbhost.h
50
usbhost.h
|
@ -91,31 +91,26 @@ template< typename SS, typename INTR >
|
||||||
/* constructor */
|
/* constructor */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
MAX3421e< SS, INTR >::MAX3421e() {
|
MAX3421e< SS, INTR >::MAX3421e() {
|
||||||
/* pin and peripheral setup */
|
// Leaving ADK hardware setup in here, for now. This really belongs with the other parts.
|
||||||
SS::SetDirWrite();
|
|
||||||
SS::Set();
|
|
||||||
spi::init();
|
|
||||||
INTR::SetDirRead();
|
|
||||||
#ifdef BOARD_MEGA_ADK
|
#ifdef BOARD_MEGA_ADK
|
||||||
/* For Mega ADK, which has Max3421e on-board, set MAX_RESET to Output mode, and pull Reset to HIGH */
|
/* For Mega ADK, which has Max3421e on-board, set MAX_RESET to Output mode, and pull Reset to HIGH */
|
||||||
DDRJ |= _BV(PJ2);
|
DDRJ |= _BV(PJ2);
|
||||||
PORTJ &= ~_BV(PJ2);
|
PORTJ &= ~_BV(PJ2);
|
||||||
PORTJ |= _BV(PJ2);
|
PORTJ |= _BV(PJ2);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MAX3421E - full-duplex SPI, level interrupt */
|
|
||||||
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* write single byte into MAX3421 register */
|
/* write single byte into MAX3421 register */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
|
void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
|
||||||
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
SPDR = (reg | 0x02);
|
SPDR = (reg | 0x02);
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SPDR = data;
|
SPDR = data;
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SS::Set();
|
SS::Set();
|
||||||
|
XMEM_RELEASE_SPI();
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
/* multiple-byte write */
|
/* multiple-byte write */
|
||||||
|
@ -123,6 +118,7 @@ void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) {
|
||||||
/* returns a pointer to memory position after last written */
|
/* returns a pointer to memory position after last written */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||||
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
SPDR = (reg | 0x02); //set WR bit and send register number
|
SPDR = (reg | 0x02); //set WR bit and send register number
|
||||||
while(nbytes--) {
|
while(nbytes--) {
|
||||||
|
@ -132,6 +128,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||||
}
|
}
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SS::Set();
|
SS::Set();
|
||||||
|
XMEM_RELEASE_SPI();
|
||||||
return( data_p);
|
return( data_p);
|
||||||
}
|
}
|
||||||
/* GPIO write */
|
/* GPIO write */
|
||||||
|
@ -149,19 +146,23 @@ void MAX3421e< SS, INTR >::gpioWr(uint8_t data) {
|
||||||
/* single host register read */
|
/* single host register read */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) {
|
uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) {
|
||||||
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
SPDR = reg;
|
SPDR = reg;
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SPDR = 0; //send empty byte
|
SPDR = 0; //send empty byte
|
||||||
while(!(SPSR & (1 << SPIF)));
|
while(!(SPSR & (1 << SPIF)));
|
||||||
SS::Set();
|
SS::Set();
|
||||||
return( SPDR);
|
uint8_t rv = SPDR;
|
||||||
|
XMEM_RELEASE_SPI();
|
||||||
|
return(rv);
|
||||||
}
|
}
|
||||||
/* multiple-byte register read */
|
/* multiple-byte register read */
|
||||||
|
|
||||||
/* returns a pointer to a memory position after last read */
|
/* returns a pointer to a memory position after last read */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||||
|
XMEM_ACQUIRE_SPI();
|
||||||
SS::Clear();
|
SS::Clear();
|
||||||
SPDR = reg;
|
SPDR = reg;
|
||||||
while(!(SPSR & (1 << SPIF))); //wait
|
while(!(SPSR & (1 << SPIF))); //wait
|
||||||
|
@ -182,6 +183,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
SS::Set();
|
SS::Set();
|
||||||
|
XMEM_RELEASE_SPI();
|
||||||
return( data_p);
|
return( data_p);
|
||||||
}
|
}
|
||||||
/* GPIO read. See gpioWr for explanation */
|
/* GPIO read. See gpioWr for explanation */
|
||||||
|
@ -214,13 +216,24 @@ uint16_t MAX3421e< SS, INTR >::reset() {
|
||||||
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
|
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
int8_t MAX3421e< SS, INTR >::Init() {
|
int8_t MAX3421e< SS, INTR >::Init() {
|
||||||
|
XMEM_ACQUIRE_SPI();
|
||||||
|
// Moved here.
|
||||||
|
// you really should not init hardware in the constructor when it involves locks.
|
||||||
|
// Also avoids the vbus flicker issue confusing some devices.
|
||||||
|
/* pin and peripheral setup */
|
||||||
|
SS::SetDirWrite();
|
||||||
|
SS::Set();
|
||||||
|
spi::init();
|
||||||
|
INTR::SetDirRead();
|
||||||
|
XMEM_RELEASE_SPI();
|
||||||
|
/* MAX3421E - full-duplex SPI, level interrupt */
|
||||||
|
// GPX pin on. Moved here, otherwise we flicker the vbus.
|
||||||
|
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
|
||||||
|
|
||||||
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
||||||
return( -1);
|
return( -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GPX pin on.
|
|
||||||
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL));
|
|
||||||
|
|
||||||
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
|
regWr(rMODE, bmDPPULLDN | bmDMPULLDN | bmHOST); // set pull-downs, Host
|
||||||
|
|
||||||
regWr(rHIEN, bmCONDETIE | bmFRAMEIE); //connection detection
|
regWr(rHIEN, bmCONDETIE | bmFRAMEIE); //connection detection
|
||||||
|
@ -240,6 +253,19 @@ int8_t MAX3421e< SS, INTR >::Init() {
|
||||||
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
|
/* initialize MAX3421E. Set Host mode, pullups, and stuff. Returns 0 if success, -1 if not */
|
||||||
template< typename SS, typename INTR >
|
template< typename SS, typename INTR >
|
||||||
int8_t MAX3421e< SS, INTR >::Init(int mseconds) {
|
int8_t MAX3421e< SS, INTR >::Init(int mseconds) {
|
||||||
|
XMEM_ACQUIRE_SPI();
|
||||||
|
// Moved here.
|
||||||
|
// you really should not init hardware in the constructor when it involves locks.
|
||||||
|
// Also avoids the vbus flicker issue confusing some devices.
|
||||||
|
/* pin and peripheral setup */
|
||||||
|
SS::SetDirWrite();
|
||||||
|
SS::Set();
|
||||||
|
spi::init();
|
||||||
|
INTR::SetDirRead();
|
||||||
|
XMEM_RELEASE_SPI();
|
||||||
|
/* MAX3421E - full-duplex SPI, level interrupt, vbus off */
|
||||||
|
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
|
||||||
|
|
||||||
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
if(reset() == 0) { //OSCOKIRQ hasn't asserted in time
|
||||||
return( -1);
|
return( -1);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue