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

140
spi.cpp
View File

@ -1,40 +1,129 @@
#include "spi.h" #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; if( bCPHA )
SPSR = 0; {
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; setClockDiv( enmClockDiv );
bool bSPR1 = ( static_cast<uint8_t>( enmClockDiv ) >> 1 ) & 1; setMode( enmMode );
bool bSPR0 = ( static_cast<uint8_t>( enmClockDiv ) >> 0 ) & 1; 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 ); 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; if( enmMode == Mode::MODE_0 || enmMode == Mode::MODE_1 )
bool bCPHA = ( static_cast<uint8_t>( enmMode ) >> 0 ) & 1; {
setCPOL( false );
SPCR &= ~( 1 << CPOL | 1 << CPHA ); }
else
SPCR |= ( bCPOL << CPOL | bCPHA << CPHA ); {
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 ) 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; SPDR = ui8Data;
while( !( SPSR & ( 1 << SPIF ) ) ); while( !( SPSR & ( 1 << SPIF ) ) );
return SPDR; return SPDR;
} }
//////////////////////////////////////////////////////////////////////////
void SPI::select( bool bSelect )
{
InOut::writePin( sm_enmSS, !bSelect );
}

64
spi.h
View File

@ -1,34 +1,58 @@
/*
* Copyright (c) by BlackMark 2016
* Date 26/05/2016
* Version 1.0
*/
#ifndef SPI_H #ifndef SPI_H
#define SPI_H #define SPI_H
#include <avr/io.h> #include <avr/io.h>
#include "../inout/inout.h"
enum class SPIClock class SPI
{ {
CLOCKDIV_4 = 0, public:
CLOCKDIV_16 = 1, enum class ClockDiv
CLOCKDIV_64 = 2, {
CLOCKDIV_128 = 3, CLKDIV_4 = 0,
CLKDIV_16 = 1,
CLKDIV_64 = 2,
CLKDIV_128 = 3,
CLOCKDIV2X_2 = 4, CLKDIV_2X_2 = 4,
CLOCKDIV2X_8 = 5, CLKDIV_2X_8 = 5,
CLOCKDIV2X_32 = 6, CLKDIV_2X_32 = 6,
CLOCKDIV2X_64 = 7 CLKDIV_2X_64 = 7
}; };
enum class SPIMode enum class Mode
{ {
MODE0 = 0, MODE_0 = 0,
MODE1 = 1, MODE_1 = 1,
MODE2 = 2, MODE_2 = 2,
MODE3 = 3 MODE_3 = 3
}; };
void spiInit(); private:
void spiEnd(); static void setCPOL( bool bCPOL );
void spiSetClockDiv( SPIClock enmClockDiv ); static void setCPHA( bool bCPHA );
void spiSetDataMode( SPIMode enmMode );
void spiSetBitOrder( bool bLSBFirst ); static constexpr InOut::Pin sm_enmSCK = InOut::Pin::P_B5;
uint8_t spiTransfer( uint8_t ui8Data ); 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 #endif