Rewrote SPI library to be more generic and utilize C++ classes
This commit is contained in:
parent
7105380682
commit
035f096156
140
spi.cpp
140
spi.cpp
@ -1,40 +1,129 @@
|
||||
#include "spi.h"
|
||||
|
||||
void spiInit()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::setCPOL( bool bCPOL )
|
||||
{
|
||||
SPCR |= ( 1 << SPE ) | ( 1 << MSTR );
|
||||
if( bCPOL )
|
||||
{
|
||||
SPCR |= ( 1 << CPOL );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPCR &= ~( 1 << CPOL );
|
||||
}
|
||||
}
|
||||
|
||||
void spiEnd()
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::setCPHA( bool bCPHA )
|
||||
{
|
||||
SPCR = 0;
|
||||
SPSR = 0;
|
||||
if( bCPHA )
|
||||
{
|
||||
SPCR |= ( 1 << CPHA );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPCR &= ~( 1 << CPHA );
|
||||
}
|
||||
}
|
||||
|
||||
void spiSetClockDiv( SPIClock enmClockDiv )
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::init( ClockDiv enmClockDiv /* = ClockDiv::CLKDIV_128 */, Mode enmMode /* = Mode::MODE_0 */, bool bMaster /* = true */, bool bLSBFirst /* = false */ )
|
||||
{
|
||||
bool bSPI2X = ( static_cast<uint8_t>( enmClockDiv ) >> 2 ) & 1;
|
||||
bool bSPR1 = ( static_cast<uint8_t>( enmClockDiv ) >> 1 ) & 1;
|
||||
bool bSPR0 = ( static_cast<uint8_t>( enmClockDiv ) >> 0 ) & 1;
|
||||
setClockDiv( enmClockDiv );
|
||||
setMode( enmMode );
|
||||
setMaster( bMaster );
|
||||
setBitOrder( bLSBFirst );
|
||||
|
||||
SPCR &= ~( 1 << SPR1 | 1 << SPR0 );
|
||||
SPCR |= ( 1 << SPE );
|
||||
|
||||
if( bMaster )
|
||||
{
|
||||
InOut::writePin( sm_enmSS, true );
|
||||
|
||||
InOut::setPinDirection( sm_enmSCK, InOut::Dir::D_OUT, false );
|
||||
InOut::setPinDirection( sm_enmMISO, InOut::Dir::D_IN, false );
|
||||
InOut::setPinDirection( sm_enmMOSI, InOut::Dir::D_OUT, false );
|
||||
InOut::setPinDirection( sm_enmSS, InOut::Dir::D_OUT, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
InOut::setPinDirection( sm_enmSCK, InOut::Dir::D_IN, false );
|
||||
InOut::setPinDirection( sm_enmMISO, InOut::Dir::D_OUT, false );
|
||||
InOut::setPinDirection( sm_enmMOSI, InOut::Dir::D_IN, false );
|
||||
InOut::setPinDirection( sm_enmSS, InOut::Dir::D_IN, true );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::setClockDiv( ClockDiv enmClockDiv )
|
||||
{
|
||||
uint8_t ui8ClockDiv = static_cast<uint8_t>( enmClockDiv );
|
||||
|
||||
if( ui8ClockDiv & 1 )
|
||||
{
|
||||
SPCR |= ( 1 << SPR0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPCR &= ~( 1 << SPR0 );
|
||||
}
|
||||
|
||||
if( ui8ClockDiv & ( 1 << 1 ) )
|
||||
{
|
||||
SPCR |= ( 1 << SPR1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPCR &= ~( 1 << SPR1 );
|
||||
}
|
||||
|
||||
if( ui8ClockDiv & ( 1 << 2 ) )
|
||||
{
|
||||
SPSR |= ( 1 << SPI2X );
|
||||
}
|
||||
else
|
||||
{
|
||||
SPSR &= ~( 1 << SPI2X );
|
||||
|
||||
SPCR |= ( bSPR1 << SPR1 | bSPR0 << SPR0 );
|
||||
SPSR |= ( bSPI2X << SPI2X );
|
||||
}
|
||||
}
|
||||
|
||||
void spiSetDataMode( SPIMode enmMode )
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::setMode( Mode enmMode )
|
||||
{
|
||||
bool bCPOL = ( static_cast<uint8_t>( enmMode ) >> 1 ) & 1;
|
||||
bool bCPHA = ( static_cast<uint8_t>( enmMode ) >> 0 ) & 1;
|
||||
|
||||
SPCR &= ~( 1 << CPOL | 1 << CPHA );
|
||||
|
||||
SPCR |= ( bCPOL << CPOL | bCPHA << CPHA );
|
||||
if( enmMode == Mode::MODE_0 || enmMode == Mode::MODE_1 )
|
||||
{
|
||||
setCPOL( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
setCPOL( true );
|
||||
}
|
||||
|
||||
void spiSetBitOrder( bool bLSBFirst )
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::setBitOrder( bool bLSBFirst )
|
||||
{
|
||||
if( bLSBFirst )
|
||||
{
|
||||
@ -46,9 +135,16 @@ void spiSetBitOrder( bool bLSBFirst )
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t spiTransfer( uint8_t ui8Data )
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
uint8_t SPI::transfer( uint8_t ui8Data )
|
||||
{
|
||||
SPDR = ui8Data;
|
||||
while( !( SPSR & ( 1 << SPIF ) ) );
|
||||
return SPDR;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void SPI::select( bool bSelect )
|
||||
{
|
||||
InOut::writePin( sm_enmSS, !bSelect );
|
||||
}
|
64
spi.h
64
spi.h
@ -1,34 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) by BlackMark 2016
|
||||
* Date 26/05/2016
|
||||
* Version 1.0
|
||||
*/
|
||||
|
||||
#ifndef SPI_H
|
||||
#define SPI_H
|
||||
|
||||
#include <avr/io.h>
|
||||
#include "../inout/inout.h"
|
||||
|
||||
enum class SPIClock
|
||||
class SPI
|
||||
{
|
||||
CLOCKDIV_4 = 0,
|
||||
CLOCKDIV_16 = 1,
|
||||
CLOCKDIV_64 = 2,
|
||||
CLOCKDIV_128 = 3,
|
||||
public:
|
||||
enum class ClockDiv
|
||||
{
|
||||
CLKDIV_4 = 0,
|
||||
CLKDIV_16 = 1,
|
||||
CLKDIV_64 = 2,
|
||||
CLKDIV_128 = 3,
|
||||
|
||||
CLOCKDIV2X_2 = 4,
|
||||
CLOCKDIV2X_8 = 5,
|
||||
CLOCKDIV2X_32 = 6,
|
||||
CLOCKDIV2X_64 = 7
|
||||
CLKDIV_2X_2 = 4,
|
||||
CLKDIV_2X_8 = 5,
|
||||
CLKDIV_2X_32 = 6,
|
||||
CLKDIV_2X_64 = 7
|
||||
};
|
||||
|
||||
enum class SPIMode
|
||||
enum class Mode
|
||||
{
|
||||
MODE0 = 0,
|
||||
MODE1 = 1,
|
||||
MODE2 = 2,
|
||||
MODE3 = 3
|
||||
MODE_0 = 0,
|
||||
MODE_1 = 1,
|
||||
MODE_2 = 2,
|
||||
MODE_3 = 3
|
||||
};
|
||||
|
||||
void spiInit();
|
||||
void spiEnd();
|
||||
void spiSetClockDiv( SPIClock enmClockDiv );
|
||||
void spiSetDataMode( SPIMode enmMode );
|
||||
void spiSetBitOrder( bool bLSBFirst );
|
||||
uint8_t spiTransfer( uint8_t ui8Data );
|
||||
private:
|
||||
static void setCPOL( bool bCPOL );
|
||||
static void setCPHA( bool bCPHA );
|
||||
|
||||
static constexpr InOut::Pin sm_enmSCK = InOut::Pin::P_B5;
|
||||
static constexpr InOut::Pin sm_enmMISO = InOut::Pin::P_B4;
|
||||
static constexpr InOut::Pin sm_enmMOSI = InOut::Pin::P_B3;
|
||||
static constexpr InOut::Pin sm_enmSS = InOut::Pin::P_B2;
|
||||
|
||||
public:
|
||||
static void init( ClockDiv enmClockDiv = ClockDiv::CLKDIV_128, Mode enmMode = Mode::MODE_0, bool bMaster = true, bool bLSBFirst = false );
|
||||
static void setClockDiv( ClockDiv enmClockDiv );
|
||||
static void setMode( Mode enmMode );
|
||||
static void setMaster( bool bMaster );
|
||||
static void setBitOrder( bool bLSBFirst );
|
||||
|
||||
static uint8_t transfer( uint8_t ui8Data );
|
||||
|
||||
static void select( bool bSelect );
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user