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)