locks and constructor/init fixes

This commit is contained in:
Andrew J. Kroll 2013-10-08 15:52:24 -04:00
parent 272180cf60
commit 42fc48d129

View file

@ -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);
} }