From 370bb9f93cf415cb0d75a6b829dbaef684b132ca Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Tue, 21 Jul 2015 13:26:19 +0200 Subject: [PATCH] Move pin I/O macros from arduino.h to pinio.h. arduino.h is now free of function definitions. --- analog.c | 1 + arduino.h | 63 +++---------------------------------- intercom.c | 1 + pinio.h | 73 +++++++++++++++++++++++++++++++++++++++++-- sd.c | 1 + serial-avr.c | 1 + simulator.h | 14 --------- simulator/simulator.c | 8 ++--- simulator/timer_ext.c | 1 + spi.c | 1 + spi.h | 1 + temp.c | 1 + timer.c | 1 + 13 files changed, 89 insertions(+), 78 deletions(-) diff --git a/analog.c b/analog.c index 5330d4f..ea65d9b 100644 --- a/analog.c +++ b/analog.c @@ -7,6 +7,7 @@ #include "temp.h" #include +#include "pinio.h" #include "memory_barrier.h" /* OR-combined mask of all channels */ diff --git a/arduino.h b/arduino.h index 4224266..e44beef 100644 --- a/arduino.h +++ b/arduino.h @@ -1,67 +1,14 @@ -/*! - \file - \brief pin definitions and I/O macros - why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html +/** \file + \brief Pin definitions supervisor. + + Here we map to the pin definition file of the architecture at hand and also + do some fundamental platform related stuff. */ #ifndef _ARDUINO_H #define _ARDUINO_H -#ifdef __AVR__ -#include -#endif - -/* - utility functions -*/ - -#ifndef MASK -/// MASKING- returns \f$2^PIN\f$ - #define MASK(PIN) (1 << PIN) -#endif - -/* - magic I/O routines - - now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0); -*/ - -/// Read a pin -#define _READ(IO) (IO ## _RPORT & MASK(IO ## _PIN)) -/// write to a pin -#define _WRITE(IO, v) do { if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } else { IO ## _WPORT &= ~MASK(IO ## _PIN); }; } while (0) -/// toggle a pin -#define _TOGGLE(IO) do { IO ## _RPORT = MASK(IO ## _PIN); } while (0) - -/// set pin as input -#define _SET_INPUT(IO) do { IO ## _DDR &= ~MASK(IO ## _PIN); } while (0) -/// set pin as output -#define _SET_OUTPUT(IO) do { IO ## _DDR |= MASK(IO ## _PIN); } while (0) - -/// check if pin is an input -#define _GET_INPUT(IO) ((IO ## _DDR & MASK(IO ## _PIN)) == 0) -/// check if pin is an output -#define _GET_OUTPUT(IO) ((IO ## _DDR & MASK(IO ## _PIN)) != 0) - -// why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html - -/// Read a pin wrapper -#define READ(IO) _READ(IO) -/// Write to a pin wrapper -#define WRITE(IO, v) _WRITE(IO, v) -/// toggle a pin wrapper -#define TOGGLE(IO) _TOGGLE(IO) - -/// set pin as input wrapper -#define SET_INPUT(IO) _SET_INPUT(IO) -/// set pin as output wrapper -#define SET_OUTPUT(IO) _SET_OUTPUT(IO) - -/// check if pin is an input wrapper -#define GET_INPUT(IO) _GET_INPUT(IO) -/// check if pin is an output wrapper -#define GET_OUTPUT(IO) _GET_OUTPUT(IO) /** Only AVRs have a Harvard Architecture, which has distinct address spaces diff --git a/intercom.c b/intercom.c index 6cca1df..e7a0aa6 100644 --- a/intercom.c +++ b/intercom.c @@ -11,6 +11,7 @@ #include "memory_barrier.h" #include "config_wrapper.h" +#include "pinio.h" #include "delay.h" #if (defined TEMP_INTERCOM) || (defined EXTRUDER) diff --git a/pinio.h b/pinio.h index 028fe80..13ee268 100644 --- a/pinio.h +++ b/pinio.h @@ -7,10 +7,79 @@ #include "config_wrapper.h" -#ifdef SIMULATOR - #include "simulator.h" +#ifndef MASK + /// MASKING- returns \f$2^PIN\f$ + #define MASK(PIN) (1 << PIN) #endif +/** Magic I/O routines, also known as "FastIO". + + Now you can simply SET_OUTPUT(STEP); WRITE(STEP, 1); WRITE(STEP, 0);. + + The point here is to move any pin/port mapping calculations into the + preprocessor. This way there is no longer math at runtime neccessary, all + instructions melt into a single one with fixed numbers. + + This makes code for setting a pin small, smaller than calling a subroutine. + It also make code fast, on AVR a pin can be turned on and off in just two + clock cycles. +*/ +#if defined __AVR__ + + #include + + /// Read a pin. + #define _READ(IO) (IO ## _RPORT & MASK(IO ## _PIN)) + /// Write to a pin. + #define _WRITE(IO, v) do { if (v) { IO ## _WPORT |= MASK(IO ## _PIN); } \ + else { IO ## _WPORT &= ~MASK(IO ## _PIN); }; } \ + while (0) + /// Toggle a pin. + #define _TOGGLE(IO) do { IO ## _RPORT = MASK(IO ## _PIN); } while (0) + + /// Set pin as input. + #define _SET_INPUT(IO) do { IO ## _DDR &= ~MASK(IO ## _PIN); } while (0) + /// Set pin as output. + #define _SET_OUTPUT(IO) do { IO ## _DDR |= MASK(IO ## _PIN); } while (0) + + /// Check if pin is an input. + #define _GET_INPUT(IO) ((IO ## _DDR & MASK(IO ## _PIN)) == 0) + /// Check if pin is an output. + #define _GET_OUTPUT(IO) ((IO ## _DDR & MASK(IO ## _PIN)) != 0) + +#elif defined SIMULATOR + + #include "simulator.h" + + bool _READ(pin_t pin); + void _WRITE(pin_t pin, bool on); + void _TOGGLE(pin_t pin); + void _SET_OUTPUT(pin_t pin); + void _SET_INPUT(pin_t pin); + +#endif /* __AVR__, SIMULATOR */ + +/** + Why double up on these macros? + See http://gcc.gnu.org/onlinedocs/cpp/Stringification.html +*/ +/// Read a pin wrapper. +#define READ(IO) _READ(IO) +/// Write to a pin wrapper. +#define WRITE(IO, v) _WRITE(IO, v) +/// Toggle a pin wrapper. +#define TOGGLE(IO) _TOGGLE(IO) + +/// Set pin as input wrapper. +#define SET_INPUT(IO) _SET_INPUT(IO) +/// Set pin as output wrapper. +#define SET_OUTPUT(IO) _SET_OUTPUT(IO) + +/// Check if pin is an input wrapper. +#define GET_INPUT(IO) _GET_INPUT(IO) +/// Check if pin is an output wrapper. +#define GET_OUTPUT(IO) _GET_OUTPUT(IO) + /* Power */ diff --git a/sd.c b/sd.c index 37059b7..3f8c457 100644 --- a/sd.c +++ b/sd.c @@ -7,6 +7,7 @@ #ifdef SD #include "delay.h" +#include "pinio.h" #include "serial.h" #include "sersendf.h" #include "gcode_parse.h" diff --git a/serial-avr.c b/serial-avr.c index a67a54a..86df27d 100644 --- a/serial-avr.c +++ b/serial-avr.c @@ -10,6 +10,7 @@ #include #include "memory_barrier.h" #include "arduino.h" +#include "pinio.h" /** \def BUFSIZE diff --git a/simulator.h b/simulator.h index a364f60..1491a51 100644 --- a/simulator.h +++ b/simulator.h @@ -25,14 +25,6 @@ #undef Y_MAX_PIN #undef Z_MAX_PIN -#undef READ -#undef WRITE -#undef TOGGLE -#undef SET_INPUT -#undef SET_OUTPUT -#undef GET_INPUT -#undef GET_OUTPUT - // Compiler appeasement #undef disable_transmit #undef enable_transmit @@ -54,7 +46,6 @@ #include #include "simulator/data_recorder.h" -#define MASK(PIN) (1 << PIN) #define ACD 7 #define OCIE1A 1 @@ -123,11 +114,6 @@ extern uint8_t ACSR; extern uint8_t TIMSK1; extern volatile bool sim_interrupts; -bool READ(pin_t pin); -void WRITE(pin_t pin, bool on); -void SET_OUTPUT(pin_t pin); -void SET_INPUT(pin_t pin); - // Simulate AVR interrupts. #define ISR(fn) void fn (void) void TIMER1_COMPA_vect(void); diff --git a/simulator/simulator.c b/simulator/simulator.c index 0b9301c..649589a 100644 --- a/simulator/simulator.c +++ b/simulator/simulator.c @@ -300,13 +300,13 @@ static void print_pos(void) { } } -bool READ(pin_t pin) { +bool _READ(pin_t pin) { sim_assert(pin < PIN_NB, "READ: Pin number out of range"); // Add any necessary reactive pin-handlers here. return state[pin]; } -void WRITE(pin_t pin, bool s) { +void _WRITE(pin_t pin, bool s) { bool old_state = state[pin]; uint64_t nseconds = sim_runtime_ns(); sim_assert(pin < PIN_NB, "WRITE: Pin number out of range"); @@ -378,12 +378,12 @@ void WRITE(pin_t pin, bool s) { } } -void SET_OUTPUT(pin_t pin) { +void _SET_OUTPUT(pin_t pin) { sim_assert(pin < PIN_NB, "Pin number out of range"); direction[pin] = out; } -void SET_INPUT(pin_t pin) { +void _SET_INPUT(pin_t pin) { sim_assert(pin < PIN_NB, "Pin number out of range"); direction[pin] = in; } diff --git a/simulator/timer_ext.c b/simulator/timer_ext.c index 3a3a7a8..e0471ad 100644 --- a/simulator/timer_ext.c +++ b/simulator/timer_ext.c @@ -4,6 +4,7 @@ #include "dda_queue.h" #include "timer.h" +#include "pinio.h" #include "simulator.h" #ifdef __MACH__ #include diff --git a/spi.c b/spi.c index e38b1c0..e072b3c 100644 --- a/spi.c +++ b/spi.c @@ -14,6 +14,7 @@ #include "spi.h" #include "arduino.h" +#include "pinio.h" /** Initialise serial subsystem. diff --git a/spi.h b/spi.h index fb5faec..2f37de0 100644 --- a/spi.h +++ b/spi.h @@ -3,6 +3,7 @@ #include "config_wrapper.h" #include "arduino.h" +#include "pinio.h" // Uncomment this to double SPI frequency from (F_CPU / 4) to (F_CPU / 2). //#define SPI_2X diff --git a/temp.c b/temp.c index 02dd2e2..7a1429e 100644 --- a/temp.c +++ b/temp.c @@ -21,6 +21,7 @@ #ifdef TEMP_INTERCOM #include "intercom.h" + #include "pinio.h" #endif #ifdef TEMP_MAX6675 diff --git a/timer.c b/timer.c index b58761b..f766634 100644 --- a/timer.c +++ b/timer.c @@ -17,6 +17,7 @@ #include "arduino.h" #include "config_wrapper.h" +#include "pinio.h" #include "clock.h" #ifdef MOTHERBOARD