Skip to content

Commit

Permalink
Added support for SPI slave mode
Browse files Browse the repository at this point in the history
  • Loading branch information
pichenettes committed Apr 24, 2011
1 parent aa1a2a8 commit 78b6a8f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 8 deletions.
8 changes: 4 additions & 4 deletions gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ SetupGpio(22, PortC, NoPwmChannel, 6);
SetupGpio(23, PortC, NoPwmChannel, 7);

const uint8_t kSpiSlaveSelectPin = 4;
const uint8_t kSpiDataOutPin = 5;
const uint8_t kSpiDataInPin = 6;
const uint8_t kSpiMosiPin = 5;
const uint8_t kSpiMisoPin = 6;
const uint8_t kSpiClockPin = 7;

#else
Expand Down Expand Up @@ -204,8 +204,8 @@ SetupGpio(18, PortC, NoPwmChannel, 4);
SetupGpio(19, PortC, NoPwmChannel, 5);

const uint8_t kSpiSlaveSelectPin = 10;
const uint8_t kSpiDataOutPin = 11;
const uint8_t kSpiDataInPin = 12;
const uint8_t kSpiMosiPin = 11;
const uint8_t kSpiMisoPin = 12;
const uint8_t kSpiClockPin = 13;

#endif // ATMEGA328P
Expand Down
50 changes: 46 additions & 4 deletions spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
// around 15 cycles (not including the interrupt prelude/postlude), which is
// close to the transmission time at the fastest speed.
// - the atmega is always configured as a master.
// - no support for reading back from the slave.

#ifndef AVRLIB_SPI_H_
#define AVRLIB_SPI_H_
Expand All @@ -42,7 +41,7 @@ typedef BitInRegister<SPSRRegister, SPIF> TransferComplete;
template<uint8_t slave_select_pin = 10,
DataOrder order = MSB_FIRST,
uint8_t speed = 4>
class Spi {
class SPIMaster {
public:
enum {
buffer_size = 0,
Expand Down Expand Up @@ -105,11 +104,54 @@ class Spi {
private:
typedef Gpio<slave_select_pin> SlaveSelect;
typedef Gpio<kSpiSlaveSelectPin> GlobalSlaveSelect;
typedef Gpio<kSpiDataOutPin> DataOut;
typedef Gpio<kSpiDataInPin> DataIn;
typedef Gpio<kSpiMosiPin> DataOut;
typedef Gpio<kSpiMisoPin> DataIn;
typedef Gpio<kSpiClockPin> Clock;
};

template<uint8_t slave_select_pin = 10,
DataOrder order = MSB_FIRST,
bool enable_interrupt = false>
class SPISlave {
public:
enum {
buffer_size = 128,
data_size = 8
};

static void Init() {
Clock::set_mode(DIGITAL_INPUT);
DataIn::set_mode(DIGITAL_INPUT);
DataOut::set_mode(DIGITAL_OUTPUT);
GlobalSlaveSelect::set_mode(DIGITAL_INPUT); // Ohhh mistress, ohhhh!
SlaveSelect::set_mode(DIGITAL_INPUT);

// SPI enabled, configured as master.
uint8_t configuration = _BV(SPE);
if (order == LSB_FIRST) {
configuration |= _BV(DORD);
}
if (enable_interrupt) {
configuration |= _BV(SPIE);
}
SPCR = configuration;
}

static inline uint8_t Read(uint8_t v) {
while (!TransferComplete::value());
return SPDR;
}

private:
typedef Gpio<slave_select_pin> SlaveSelect;
typedef Gpio<kSpiSlaveSelectPin> GlobalSlaveSelect;
typedef Gpio<kSpiMisoPin> DataOut;
typedef Gpio<kSpiMosiPin> DataIn;
typedef Gpio<kSpiClockPin> Clock;
};

#define SPI_RECEIVE ISR(SPI_STC_vect)

} // namespace avrlib

#endif AVRLIB_SPI_H_

0 comments on commit 78b6a8f

Please sign in to comment.