From 3933dd20ea2b033b4c02561c2c45d1b9a7793ee4 Mon Sep 17 00:00:00 2001 From: pichenettes Date: Sat, 30 Apr 2011 14:05:17 +0200 Subject: [PATCH] Using numbers to designate I/O pins sucks and I hate arduino --- gpio.h | 116 +++++++++++++++++++++++++++++++++++---------------------- spi.h | 36 ++++++------------ 2 files changed, 82 insertions(+), 70 deletions(-) diff --git a/gpio.h b/gpio.h index e064dfe..83891dc 100755 --- a/gpio.h +++ b/gpio.h @@ -19,13 +19,13 @@ // // Examples of use: // -// Gpio<3>::set_mode(DIGITAL_INPUT) -// Gpio<4>::set_mode(DIGITAL_OUTPUT) -// Gpio<3>::value() -// Gpio<4>::High() -// Gpio<4>::Low() -// Gpio<4>::set_value(1) -// Gpio<4>::set_value(0) +// NumberedGpio<3>::set_mode(DIGITAL_INPUT) +// NumberedGpio<4>::set_mode(DIGITAL_OUTPUT) +// NumberedGpio<3>::value() +// NumberedGpio<4>::High() +// NumberedGpio<4>::Low() +// NumberedGpio<4>::set_value(1) +// NumberedGpio<4>::set_value(0) #ifndef AVRLIB_GPIO_H_ #define AVRLIB_GPIO_H_ @@ -134,14 +134,57 @@ struct GpioImpl { } }; + +template +struct Gpio { + typedef GpioImpl Impl; + static void High() { Impl::High(); } + static void Low() { Impl::Low(); } + static void set_mode(uint8_t mode) { Impl::set_mode(mode); } + static void set_value(uint8_t value) { Impl::set_value(value); } + static void set_analog_value(uint8_t value) { Impl::set_analog_value(value); } + static uint8_t value() { return Impl::value(); } +}; + + +struct DummyGpio { + static void High() { } + static void Low() { } + static void set_mode(uint8_t mode) { } + static void set_value(uint8_t value) { } + static void set_analog_value(uint8_t value) { } + static uint8_t value() { } +}; + + +template +struct DigitalInput { + enum { + buffer_size = 0, + data_size = 1, + }; + static void Init() { + gpio::set_mode(DIGITAL_INPUT); + } + static void EnablePullUpResistor() { + gpio::High(); + } + static void DisablePullUpResistor() { + gpio::Low(); + } + static uint8_t Read() { + return gpio::value(); + } +}; + // A template that will be specialized for each pin, allowing the pin number to // be specified as a template parameter. template -struct NumberedGpio { }; +struct NumberedGpioInternal { }; // Macro to make the pin definitions (template specializations) easier to read. #define SetupGpio(n, port, timer, bit) \ -template struct NumberedGpio { \ +template struct NumberedGpioInternal { \ typedef GpioImpl Impl; }; #ifndef ATMEGA328P @@ -174,10 +217,12 @@ SetupGpio(21, PortC, NoPwmChannel, 5); SetupGpio(22, PortC, NoPwmChannel, 6); SetupGpio(23, PortC, NoPwmChannel, 7); -const uint8_t kSpiSlaveSelectPin = 4; -const uint8_t kSpiMosiPin = 5; -const uint8_t kSpiMisoPin = 6; -const uint8_t kSpiClockPin = 7; +SetupGpio(255, PortB, NoPwmChannel, 0); + +typedef Gpio SpiSCK; +typedef Gpio SpiMISO; +typedef Gpio SpiMOSI; +typedef Gpio SpiSS; #else @@ -203,10 +248,12 @@ SetupGpio(17, PortC, NoPwmChannel, 3); SetupGpio(18, PortC, NoPwmChannel, 4); SetupGpio(19, PortC, NoPwmChannel, 5); -const uint8_t kSpiSlaveSelectPin = 10; -const uint8_t kSpiMosiPin = 11; -const uint8_t kSpiMisoPin = 12; -const uint8_t kSpiClockPin = 13; +SetupGpio(255, PortB, NoPwmChannel, 0); + +typedef Gpio SpiSCK; +typedef Gpio SpiMISO; +typedef Gpio SpiMOSI; +typedef Gpio SpiSS; #endif // ATMEGA328P @@ -214,54 +261,33 @@ const uint8_t kSpiClockPin = 13; // for each access to the PWM pins, as does the original Arduino wire lib, // the other that does not (use with care!). template -struct Gpio { - typedef typename NumberedGpio::Impl Impl; +struct NumberedGpio { + typedef typename NumberedGpioInternal::Impl Impl; static void High() { Impl::High(); } static void Low() { Impl::Low(); } static void set_mode(uint8_t mode) { Impl::set_mode(mode); } static void set_value(uint8_t value) { Impl::set_value(value); } static void set_analog_value(uint8_t value) { Impl::set_analog_value(value); } static uint8_t value() { return Impl::value(); } - static uint8_t number() { return n; } -}; - -template -struct DigitalInput { - enum { - buffer_size = 0, - data_size = 1, - }; - static void Init() { - Gpio::set_mode(DIGITAL_INPUT); - } - static void EnablePullUpResistor() { - Gpio::High(); - } - static void DisablePullUpResistor() { - Gpio::Low(); - } - static uint8_t Read() { - return Gpio::value(); - } }; -template +template struct PwmOutput { enum { buffer_size = 0, data_size = 8, }; static void Init() { - Gpio::set_mode(ANALOG_OUTPUT); + NumberedGpio::set_mode(ANALOG_OUTPUT); } static void Write(uint8_t value) { - return Gpio::set_analog_value(value); + return NumberedGpio::set_analog_value(value); } static void Stop() { - Gpio::Impl::Pwm::Stop(); + NumberedGpio::Impl::Pwm::Stop(); } static void Start() { - Gpio::Impl::Pwm::Start(); + NumberedGpio::Impl::Pwm::Start(); } }; diff --git a/spi.h b/spi.h index 09a2417..9c89fed 100644 --- a/spi.h +++ b/spi.h @@ -38,7 +38,7 @@ IORegister(SPSR); typedef BitInRegister DoubleSpeed; typedef BitInRegister TransferComplete; -template class SPIMaster { @@ -49,13 +49,13 @@ class SPIMaster { }; static void Init() { - Clock::set_mode(DIGITAL_OUTPUT); - DataIn::set_mode(DIGITAL_INPUT); - DataOut::set_mode(DIGITAL_OUTPUT); - GlobalSlaveSelect::set_mode(DIGITAL_OUTPUT); // I'm a master! + SpiSCK::set_mode(DIGITAL_OUTPUT); + SpiMOSI::set_mode(DIGITAL_OUTPUT); + SpiMISO::set_mode(DIGITAL_INPUT); + SpiSS::set_mode(DIGITAL_OUTPUT); // I'm a master! + SpiSS::High(); SlaveSelect::set_mode(DIGITAL_OUTPUT); SlaveSelect::High(); - GlobalSlaveSelect::High(); // SPI enabled, configured as master. uint8_t configuration = _BV(SPE) | _BV(MSTR); @@ -100,16 +100,9 @@ class SPIMaster { while (!TransferComplete::value()); SlaveSelect::High(); } - - private: - typedef Gpio SlaveSelect; - typedef Gpio GlobalSlaveSelect; - typedef Gpio DataOut; - typedef Gpio DataIn; - typedef Gpio Clock; }; -template class SPISlave { @@ -120,10 +113,10 @@ class SPISlave { }; 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! + SpiSCK::set_mode(DIGITAL_INPUT); + SpiMOSI::set_mode(DIGITAL_INPUT); + SpiMISO::set_mode(DIGITAL_OUTPUT); + SpiSS::set_mode(DIGITAL_INPUT); // Ohhh mistress, ohhhh! SlaveSelect::set_mode(DIGITAL_INPUT); // SPI enabled, configured as master. @@ -141,13 +134,6 @@ class SPISlave { while (!TransferComplete::value()); return SPDR; } - - private: - typedef Gpio SlaveSelect; - typedef Gpio GlobalSlaveSelect; - typedef Gpio DataOut; - typedef Gpio DataIn; - typedef Gpio Clock; }; #define SPI_RECEIVE ISR(SPI_STC_vect)