Skip to content

Commit

Permalink
add files
Browse files Browse the repository at this point in the history
  • Loading branch information
anydream committed Aug 5, 2015
1 parent cd2d279 commit 9f79080
Show file tree
Hide file tree
Showing 4 changed files with 482 additions and 0 deletions.
65 changes: 65 additions & 0 deletions TurboSPI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

#ifndef __TurboSPI_h__
#define __TurboSPI_h__

#include <Arduino.h>

class TurboSPI
{
public:
/** Initialize the SPI bus */
void Begin();
/** Set SPI options.
*
* \param[in] divisor SCK clock divider relative to the system clock.
*/
void Init(uint8_t divisor);
/** Receive a byte.
*
* \return The byte.
*/
uint8_t Receive();
/** Receive multiple bytes.
*
* \param[out] buf Buffer to receive the data.
* \param[in] n Number of bytes to receive.
*
* \return Zero for no error or nonzero error code.
*/
uint8_t Receive(uint8_t* buf, size_t n);
/** Send a byte.
*
* \param[in] data Byte to send
*/
void Send(uint8_t data);
/** Send multiple bytes.
*
* \param[in] buf Buffer for data to be sent.
* \param[in] n Number of bytes to send.
*/
void Send(const uint8_t* buf, size_t n);
};

class DigitalPin
{
public:
DigitalPin();

void Begin(uint8_t pinID);
void PinMode(uint8_t dwMode);

void High();
void Low();

private:
uint8_t m_Pin;
#if defined(__SAM3X8E__) || defined(__SAM3X8H__)
Pio *m_Port;
uint32_t m_Mask;
#elif defined(__AVR__)
volatile uint8_t *m_Port;
uint8_t m_Mask;
#endif
};

#endif // __TurboSPI_h__
132 changes: 132 additions & 0 deletions TurboSPI_AVR.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@

#include "TurboSPI.h"

#ifdef __AVR__
//------------------------------------------------------------------------------
void TurboSPI::Begin()
{
#ifdef __AVR_ATmega328P__
// Save a few bytes for 328 CPU - gcc optimizes single bit '|' to sbi.
PORTB |= 1 << 2; // SS high
DDRB |= 1 << 2; // SS output mode
DDRB |= 1 << 3; // MOSI output mode
DDRB |= 1 << 5; // SCK output mode
#else // __AVR_ATmega328P__

// set SS high - may be chip select for another SPI device
digitalWrite(SS, HIGH);

// SS must be in output mode even it is not chip select
pinMode(SS, OUTPUT);
pinMode(MOSI, OUTPUT);
pinMode(SCK, OUTPUT);
#endif // __AVR_ATmega328P__
}
//------------------------------------------------------------------------------
void TurboSPI::Init(uint8_t divisor)
{
uint8_t b = 2;
uint8_t r = 0;

// See AVR processor documentation.
for (; divisor > b && r < 7; b <<= 1, r += r < 5 ? 1 : 2)
{
}
SPCR = (1 << SPE) | (1 << MSTR) | (r >> 1);
SPSR = r & 1 ? 0 : 1 << SPI2X;
}
//------------------------------------------------------------------------------
uint8_t TurboSPI::Receive()
{
SPDR = 0XFF;
while (!(SPSR & (1 << SPIF)))
;
return SPDR;
}
//------------------------------------------------------------------------------
uint8_t TurboSPI::Receive(uint8_t* buf, size_t n)
{
if (n-- == 0)
{
return 0;
}
SPDR = 0XFF;
for (size_t i = 0; i < n; i++)
{
while (!(SPSR & (1 << SPIF)))
;
uint8_t b = SPDR;
SPDR = 0XFF;
buf[i] = b;
}
while (!(SPSR & (1 << SPIF)))
;
buf[n] = SPDR;
return 0;
}
//------------------------------------------------------------------------------
void TurboSPI::Send(uint8_t data)
{
SPDR = data;
while (!(SPSR & (1 << SPIF)))
;
}
//------------------------------------------------------------------------------
void TurboSPI::Send(const uint8_t* buf, size_t n)
{
if (n == 0)
{
return;
}
SPDR = buf[0];
if (n > 1)
{
uint8_t b = buf[1];
size_t i = 2;
while (1)
{
while (!(SPSR & (1 << SPIF)))
;
SPDR = b;
if (i == n)
{
break;
}
b = buf[i++];
}
}
while (!(SPSR & (1 << SPIF)))
;
}

//////////////////////////////////////////////////////////////////////////
DigitalPin::DigitalPin()
: m_Pin(0)
, m_Port(0)
, m_Mask(0)
{
}

void DigitalPin::Begin(uint8_t pinID)
{
m_Pin = pinID;
m_Port = portOutputRegister(digitalPinToPort(pinID));
m_Mask = digitalPinToBitMask(pinID);
}

void DigitalPin::PinMode(uint8_t dwMode)
{
pinMode(m_Pin, dwMode);
}

void DigitalPin::High()
{
*m_Port |= m_Mask;
}

void DigitalPin::Low()
{
*m_Port &= ~m_Mask;
}

#endif // __AVR__
Loading

0 comments on commit 9f79080

Please sign in to comment.