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