Rewrote SPI library to be more generic and utilize C++ classes

This commit is contained in:
BlackMark 2016-05-26 23:24:15 +02:00
parent 7105380682
commit 035f096156
2 changed files with 164 additions and 44 deletions

136
spi.cpp
View File

@ -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 );
SPSR &= ~( 1 << SPI2X );
SPCR |= ( 1 << SPE );
SPCR |= ( bSPR1 << SPR1 | bSPR0 << SPR0 );
SPSR |= ( bSPI2X << SPI2X );
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 spiSetDataMode( SPIMode enmMode )
//////////////////////////////////////////////////////////////////////////
void SPI::setClockDiv( ClockDiv enmClockDiv )
{
bool bCPOL = ( static_cast<uint8_t>( enmMode ) >> 1 ) & 1;
bool bCPHA = ( static_cast<uint8_t>( enmMode ) >> 0 ) & 1;
uint8_t ui8ClockDiv = static_cast<uint8_t>( enmClockDiv );
SPCR &= ~( 1 << CPOL | 1 << CPHA );
if( ui8ClockDiv & 1 )
{
SPCR |= ( 1 << SPR0 );
}
else
{
SPCR &= ~( 1 << SPR0 );
}
SPCR |= ( bCPOL << CPOL | bCPHA << CPHA );
if( ui8ClockDiv & ( 1 << 1 ) )
{
SPCR |= ( 1 << SPR1 );
}
else
{
SPCR &= ~( 1 << SPR1 );
}
if( ui8ClockDiv & ( 1 << 2 ) )
{
SPSR |= ( 1 << SPI2X );
}
else
{
SPSR &= ~( 1 << SPI2X );
}
}
void spiSetBitOrder( bool bLSBFirst )
//////////////////////////////////////////////////////////////////////////
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 );
}
}
//////////////////////////////////////////////////////////////////////////
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 );
}

72
spi.h
View File

@ -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 Mode
{
MODE_0 = 0,
MODE_1 = 1,
MODE_2 = 2,
MODE_3 = 3
};
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 );
};
enum class SPIMode
{
MODE0 = 0,
MODE1 = 1,
MODE2 = 2,
MODE3 = 3
};
void spiInit();
void spiEnd();
void spiSetClockDiv( SPIClock enmClockDiv );
void spiSetDataMode( SPIMode enmMode );
void spiSetBitOrder( bool bLSBFirst );
uint8_t spiTransfer( uint8_t ui8Data );
#endif