2016-05-26 21:40:24 +02:00
|
|
|
#include "spi.h"
|
|
|
|
|
2017-09-14 12:06:08 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
InOutPin SPI::sm_cSCK;
|
|
|
|
InOutPin SPI::sm_cMISO;
|
|
|
|
InOutPin SPI::sm_cMOSI;
|
|
|
|
InOutPin SPI::sm_cSS;
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::setCPOL( bool bCPOL )
|
2016-05-26 21:40:24 +02:00
|
|
|
{
|
2016-05-26 23:24:15 +02:00
|
|
|
if( bCPOL )
|
|
|
|
{
|
|
|
|
SPCR |= ( 1 << CPOL );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPCR &= ~( 1 << CPOL );
|
|
|
|
}
|
2016-05-26 21:40:24 +02:00
|
|
|
}
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::setCPHA( bool bCPHA )
|
2016-05-26 21:40:24 +02:00
|
|
|
{
|
2016-05-26 23:24:15 +02:00
|
|
|
if( bCPHA )
|
|
|
|
{
|
|
|
|
SPCR |= ( 1 << CPHA );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPCR &= ~( 1 << CPHA );
|
|
|
|
}
|
2016-05-26 21:40:24 +02:00
|
|
|
}
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
2017-09-17 14:12:05 +02:00
|
|
|
void SPI::init( ClockDiv enmClockDiv /* = ClockDiv::CLKDIV_128 */, Mode enmMode /* = Mode::MODE_0 */, bool bMaster /* = true */, bool bLSBFirst /* = false */, bool bMISOPullup /* = false */ )
|
2016-05-26 21:40:24 +02:00
|
|
|
{
|
2017-09-14 12:06:08 +02:00
|
|
|
sm_cSCK.setPin( sm_enmSCK );
|
|
|
|
sm_cMISO.setPin( sm_enmMISO );
|
|
|
|
sm_cMOSI.setPin( sm_enmMOSI );
|
|
|
|
sm_cSS.setPin( sm_enmSS );
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
if( bMaster )
|
|
|
|
{
|
2017-09-14 12:06:08 +02:00
|
|
|
sm_cSS.write( true );
|
2016-05-26 21:40:24 +02:00
|
|
|
|
2017-09-14 12:06:08 +02:00
|
|
|
sm_cSCK.setDirection( InOut::Dir::D_OUT, false );
|
2017-09-17 14:12:05 +02:00
|
|
|
sm_cMISO.setDirection( InOut::Dir::D_IN, bMISOPullup );
|
2017-09-14 12:06:08 +02:00
|
|
|
sm_cMOSI.setDirection( InOut::Dir::D_OUT, false );
|
|
|
|
sm_cSS.setDirection( InOut::Dir::D_OUT, false );
|
2016-05-26 23:24:15 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-09-14 12:06:08 +02:00
|
|
|
sm_cSCK.setDirection( InOut::Dir::D_IN, false );
|
|
|
|
sm_cMISO.setDirection( InOut::Dir::D_OUT, false );
|
|
|
|
sm_cMOSI.setDirection( InOut::Dir::D_IN, false );
|
|
|
|
sm_cSS.setDirection( InOut::Dir::D_IN, true );
|
2016-05-26 23:24:15 +02:00
|
|
|
}
|
2017-09-14 10:46:27 +02:00
|
|
|
|
|
|
|
setClockDiv( enmClockDiv );
|
|
|
|
setMode( enmMode );
|
|
|
|
setMaster( bMaster );
|
|
|
|
setBitOrder( bLSBFirst );
|
|
|
|
|
|
|
|
SPCR |= ( 1 << SPE );
|
2016-05-26 21:40:24 +02:00
|
|
|
}
|
|
|
|
|
2017-09-15 15:36:16 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::deinit()
|
|
|
|
{
|
|
|
|
SPCR = 0;
|
|
|
|
|
|
|
|
sm_cSCK.setDirection( InOut::Dir::D_IN, false );
|
|
|
|
sm_cMISO.setDirection( InOut::Dir::D_IN, false );
|
|
|
|
sm_cMOSI.setDirection( InOut::Dir::D_IN, false );
|
|
|
|
sm_cSS.setDirection( InOut::Dir::D_IN, false );
|
|
|
|
}
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::setClockDiv( ClockDiv enmClockDiv )
|
2016-05-26 21:40:24 +02:00
|
|
|
{
|
2016-05-26 23:24:15 +02:00
|
|
|
uint8_t ui8ClockDiv = static_cast<uint8_t>( enmClockDiv );
|
|
|
|
|
|
|
|
if( ui8ClockDiv & 1 )
|
|
|
|
{
|
|
|
|
SPCR |= ( 1 << SPR0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPCR &= ~( 1 << SPR0 );
|
|
|
|
}
|
2016-05-26 21:40:24 +02:00
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
if( ui8ClockDiv & ( 1 << 1 ) )
|
|
|
|
{
|
|
|
|
SPCR |= ( 1 << SPR1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPCR &= ~( 1 << SPR1 );
|
|
|
|
}
|
2016-05-26 21:40:24 +02:00
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
if( ui8ClockDiv & ( 1 << 2 ) )
|
|
|
|
{
|
|
|
|
SPSR |= ( 1 << SPI2X );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPSR &= ~( 1 << SPI2X );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::setMode( Mode enmMode )
|
|
|
|
{
|
|
|
|
if( enmMode == Mode::MODE_0 || enmMode == Mode::MODE_1 )
|
|
|
|
{
|
|
|
|
setCPOL( false );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setCPOL( true );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( enmMode == Mode::MODE_0 || enmMode == Mode::MODE_2 )
|
|
|
|
{
|
|
|
|
setCPHA( false );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setCPHA( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::setMaster( bool bMaster )
|
|
|
|
{
|
|
|
|
if( bMaster )
|
|
|
|
{
|
|
|
|
SPCR |= ( 1 << MSTR );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPCR &= ~( 1 << MSTR );
|
|
|
|
}
|
2016-05-26 21:40:24 +02:00
|
|
|
}
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::setBitOrder( bool bLSBFirst )
|
2016-05-26 21:40:24 +02:00
|
|
|
{
|
|
|
|
if( bLSBFirst )
|
|
|
|
{
|
|
|
|
SPCR |= ( 1 << DORD );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SPCR &= ~( 1 << DORD );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-26 23:24:15 +02:00
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
uint8_t SPI::transfer( uint8_t ui8Data )
|
2016-05-26 21:40:24 +02:00
|
|
|
{
|
|
|
|
SPDR = ui8Data;
|
|
|
|
while( !( SPSR & ( 1 << SPIF ) ) );
|
|
|
|
return SPDR;
|
2016-05-26 23:24:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void SPI::select( bool bSelect )
|
|
|
|
{
|
2017-09-14 12:06:08 +02:00
|
|
|
sm_cSS.write( !bSelect );
|
2016-05-26 21:40:24 +02:00
|
|
|
}
|