Skip to content

Commit

Permalink
Added support for SPI on UART0
Browse files Browse the repository at this point in the history
  • Loading branch information
pichenettes committed May 2, 2011
1 parent 046a1ef commit bfbbda4
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 13 deletions.
13 changes: 5 additions & 8 deletions devices/mcp492x.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ enum DacVoltageReference {
UNBUFFERED_REFERENCE
};

template<typename slave_select,
template<typename Interface,
DacVoltageReference voltage_reference = UNBUFFERED_REFERENCE,
uint8_t gain = 1>
class Dac {
Expand All @@ -46,14 +46,14 @@ class Dac {
Dac() { }

static void Init() {
DacInterface::Init();
Interface::Init();
}

static void Write(uint8_t value) {
static inline void Write(uint8_t value) {
Write(value, 0);
}

static void Write(uint8_t value, uint8_t channel) {
static inline void Write(uint8_t value, uint8_t channel) {
value = Swap4(value);
uint8_t command;
command = (value & 0x0f) | 0x10;
Expand All @@ -66,11 +66,8 @@ class Dac {
if (gain == 1) {
command |= 0x20;
}
DacInterface::WriteWord(command, value & 0xf0);
Interface::WriteWord(command, value & 0xf0);
}

private:
typedef SpiMaster<slave_select, MSB_FIRST, kDacSpeed> DacInterface;
};

} // namespace avrlib
Expand Down
4 changes: 4 additions & 0 deletions gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ typedef Gpio<PortB, 4> SpiMISO;
typedef Gpio<PortB, 3> SpiMOSI;
typedef Gpio<PortB, 2> SpiSS;

typedef Gpio<PortD, 4> UartSpiXCK;
typedef Gpio<PortD, 1> UartSpiTX;
typedef Gpio<PortD, 0> UartSpiRX;

#endif // ATMEGA328P

// Two specializations of the numbered pin template, one which clears the timer
Expand Down
92 changes: 87 additions & 5 deletions spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,39 @@ class SpiMaster {

static inline void Write(uint8_t v) {
SlaveSelect::Low();
SPDR = v;
Overwrite(v);
Wait();
SlaveSelect::High();
}

static inline void Wait() {
while (!TransferComplete::value());
}

static inline void OptimisticWait() {
Wait();
}

static inline void Strobe() {
SlaveSelect::High();
SlaveSelect::Low();
}

static inline void Overwrite(uint8_t v) {
SPDR = v;
}

static inline void WriteWord(uint8_t a, uint8_t b) {
SlaveSelect::Low();
SPDR = a;
while (!TransferComplete::value());
SPDR = b;
while (!TransferComplete::value());
Overwrite(a);
Wait();
Overwrite(b);
Wait();
SlaveSelect::High();
}
};


template<typename SlaveSelect,
DataOrder order = MSB_FIRST,
bool enable_interrupt = false>
Expand Down Expand Up @@ -136,6 +154,70 @@ class SpiSlave {
}
};


template<typename SlaveSelect,
DataOrder order = MSB_FIRST,
uint8_t speed = 2>
class UartSpiMaster {
public:
enum {
buffer_size = 0,
data_size = 8
};

static void Init() {
SlaveSelect::set_mode(DIGITAL_OUTPUT);
SlaveSelect::High();

UBRR0 = 0;

UartSpiXCK::set_mode(DIGITAL_OUTPUT);
UartSpiTX::set_mode(DIGITAL_OUTPUT);
UartSpiRX::set_mode(DIGITAL_INPUT);

// Set UART to SPI Master mode.
UCSR0C = _BV(UMSEL01) | _BV(UMSEL00);

// Enable TX and RX
UCSR0B = _BV(RXEN0) | _BV(TXEN0);

UBRR0 = (speed / 2) - 1;
}

static inline void Write(uint8_t v) {
SlaveSelect::Low();
Overwrite(v);
Wait();
SlaveSelect::High();
}

static inline void Wait() {
while (!UCSR0A & _BV(UDRE0));
}

static inline void OptimisticWait() { }

static inline void Strobe() {
SlaveSelect::High();
SlaveSelect::Low();
}

static inline void Overwrite(uint8_t v) {
UDR0 = v;
}


static inline void WriteWord(uint8_t a, uint8_t b) {
SlaveSelect::Low();
Overwrite(a);
Wait();
Overwrite(b);
Wait();
SlaveSelect::High();
}
};


#define SPI_RECEIVE ISR(SPI_STC_vect)

} // namespace avrlib
Expand Down

0 comments on commit bfbbda4

Please sign in to comment.