From bfbbda4f9e534348f1df6f06f151c2b20b60327a Mon Sep 17 00:00:00 2001
From: pichenettes
Date: Mon, 2 May 2011 02:38:56 +0200
Subject: [PATCH] Added support for SPI on UART0
---
devices/mcp492x.h | 13 +++----
gpio.h | 4 +++
spi.h | 92 ++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 96 insertions(+), 13 deletions(-)
diff --git a/devices/mcp492x.h b/devices/mcp492x.h
index 44fcc68..1b16ee1 100755
--- a/devices/mcp492x.h
+++ b/devices/mcp492x.h
@@ -34,7 +34,7 @@ enum DacVoltageReference {
UNBUFFERED_REFERENCE
};
-template
class Dac {
@@ -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;
@@ -66,11 +66,8 @@ class Dac {
if (gain == 1) {
command |= 0x20;
}
- DacInterface::WriteWord(command, value & 0xf0);
+ Interface::WriteWord(command, value & 0xf0);
}
-
- private:
- typedef SpiMaster DacInterface;
};
} // namespace avrlib
diff --git a/gpio.h b/gpio.h
index 83891dc..254f830 100755
--- a/gpio.h
+++ b/gpio.h
@@ -255,6 +255,10 @@ typedef Gpio SpiMISO;
typedef Gpio SpiMOSI;
typedef Gpio SpiSS;
+typedef Gpio UartSpiXCK;
+typedef Gpio UartSpiTX;
+typedef Gpio UartSpiRX;
+
#endif // ATMEGA328P
// Two specializations of the numbered pin template, one which clears the timer
diff --git a/spi.h b/spi.h
index c5563da..7902279 100644
--- a/spi.h
+++ b/spi.h
@@ -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
@@ -136,6 +154,70 @@ class SpiSlave {
}
};
+
+template
+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