Created
September 8, 2018 17:37
-
-
Save branw/480df674a3e243a3f402a0e9dd0c2a23 to your computer and use it in GitHub Desktop.
digitalWrite() but without the overhead
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace detail { | |
template<char port, int pin> | |
constexpr int get_pin() { | |
// In an ideal world, we could do something like this: | |
// return digitalPinToPort(pin) == port ? (1 << digitalPinToBitMask(pin)) : 0; | |
// But alas, C++11's constexpr support is very limited | |
return (port == 'A' && pin == 69) ? (1 << 0) : | |
(port == 'A' && pin == 68) ? (1 << 1) : | |
(port == 'A' && pin == 61) ? (1 << 2) : | |
(port == 'A' && pin == 60) ? (1 << 3) : | |
(port == 'A' && pin == 69) ? (1 << 4) : | |
(port == 'A' && pin == 58) ? (1 << 6) : | |
(port == 'A' && pin == 31) ? (1 << 7) : | |
(port == 'A' && pin == 0) ? (1 << 8) : | |
(port == 'A' && pin == 1) ? (1 << 9) : | |
(port == 'A' && pin == 19) ? (1 << 10) : | |
(port == 'A' && pin == 18) ? (1 << 11) : | |
(port == 'A' && pin == 17) ? (1 << 12) : | |
(port == 'A' && pin == 16) ? (1 << 13) : | |
(port == 'A' && pin == 23) ? (1 << 14) : | |
(port == 'A' && pin == 24) ? (1 << 15) : | |
(port == 'A' && pin == 54) ? (1 << 16) : | |
(port == 'A' && pin == 70) ? (1 << 17) : | |
(port == 'A' && pin == 71) ? (1 << 18) : | |
(port == 'A' && pin == 42) ? (1 << 19) : | |
(port == 'A' && pin == 43) ? (1 << 20) : | |
(port == 'A' && pin == 73) ? (1 << 21) : | |
(port == 'A' && pin == 57) ? (1 << 22) : | |
(port == 'A' && pin == 56) ? (1 << 23) : | |
(port == 'A' && pin == 55) ? (1 << 24) : | |
(port == 'A' && pin == 74) ? (1 << 25) : | |
(port == 'A' && pin == 75) ? (1 << 26) : | |
(port == 'A' && pin == 76) ? (1 << 27) : | |
(port == 'A' && pin == 10) ? (1 << 28) : | |
(port == 'A' && pin == 77) ? (1 << 28) : | |
(port == 'A' && pin == 4) ? (1 << 29) : | |
(port == 'B' && pin == 20) ? (1 << 12) : | |
(port == 'B' && pin == 21) ? (1 << 13) : | |
(port == 'B' && pin == 53) ? (1 << 14) : | |
(port == 'B' && pin == 66) ? (1 << 15) : | |
(port == 'B' && pin == 67) ? (1 << 16) : | |
(port == 'B' && pin == 62) ? (1 << 17) : | |
(port == 'B' && pin == 63) ? (1 << 18) : | |
(port == 'B' && pin == 64) ? (1 << 19) : | |
(port == 'B' && pin == 65) ? (1 << 20) : | |
(port == 'B' && pin == 52) ? (1 << 21) : | |
(port == 'B' && pin == 78) ? (1 << 23) : | |
(port == 'B' && pin == 2) ? (1 << 25) : | |
(port == 'B' && pin == 22) ? (1 << 26) : | |
(port == 'B' && pin == 13) ? (1 << 27) : | |
(port == 'C' && pin == 33) ? (1 << 1) : | |
(port == 'C' && pin == 34) ? (1 << 2) : | |
(port == 'C' && pin == 35) ? (1 << 3) : | |
(port == 'C' && pin == 36) ? (1 << 4) : | |
(port == 'C' && pin == 37) ? (1 << 5) : | |
(port == 'C' && pin == 38) ? (1 << 6) : | |
(port == 'C' && pin == 39) ? (1 << 7) : | |
(port == 'C' && pin == 40) ? (1 << 8) : | |
(port == 'C' && pin == 41) ? (1 << 9) : | |
(port == 'C' && pin == 51) ? (1 << 12) : | |
(port == 'C' && pin == 50) ? (1 << 13) : | |
(port == 'C' && pin == 49) ? (1 << 14) : | |
(port == 'C' && pin == 48) ? (1 << 15) : | |
(port == 'C' && pin == 47) ? (1 << 16) : | |
(port == 'C' && pin == 46) ? (1 << 17) : | |
(port == 'C' && pin == 45) ? (1 << 18) : | |
(port == 'C' && pin == 44) ? (1 << 19) : | |
(port == 'C' && pin == 9) ? (1 << 21) : | |
(port == 'C' && pin == 8) ? (1 << 22) : | |
(port == 'C' && pin == 7) ? (1 << 23) : | |
(port == 'C' && pin == 6) ? (1 << 24) : | |
(port == 'C' && pin == 5) ? (1 << 25) : | |
(port == 'C' && pin == 3) ? (1 << 28) : | |
(port == 'C' && pin == 72) ? (1 << 30) : | |
(port == 'D' && pin == 25) ? (1 << 0) : | |
(port == 'D' && pin == 26) ? (1 << 1) : | |
(port == 'D' && pin == 27) ? (1 << 2) : | |
(port == 'D' && pin == 28) ? (1 << 3) : | |
(port == 'D' && pin == 14) ? (1 << 4) : | |
(port == 'D' && pin == 15) ? (1 << 5) : | |
(port == 'D' && pin == 29) ? (1 << 6) : | |
(port == 'D' && pin == 11) ? (1 << 7) : | |
(port == 'D' && pin == 12) ? (1 << 8) : | |
(port == 'D' && pin == 30) ? (1 << 9) : | |
(port == 'D' && pin == 32) ? (1 << 10) : 0; | |
} | |
template<char port> | |
constexpr int get_pins() { | |
return 0; | |
} | |
template<char port, int pin, int... pins> | |
constexpr int get_pins() { | |
return get_pin<port, pin>() | get_pins<port, pins...>(); | |
} | |
} | |
#define _SET_REG_FOR_PINS(reg, ...) do { \ | |
int a = detail::get_pins<'A', __VA_ARGS__>(); if (a) REG_PIOA_##reg = a;\ | |
int b = detail::get_pins<'B', __VA_ARGS__>(); if (b) REG_PIOB_##reg = b;\ | |
int c = detail::get_pins<'C', __VA_ARGS__>(); if (c) REG_PIOC_##reg = c;\ | |
int d = detail::get_pins<'D', __VA_ARGS__>(); if (d) REG_PIOD_##reg = d;\ | |
} while (0) | |
#define SET_PINS(...) _SET_REG_FOR_PINS(SODR, __VA_ARGS__) | |
#define CLEAR_PINS(...) _SET_REG_FOR_PINS(CODR, __VA_ARGS__) | |
#define SET_ONLY_PINS(...) do { \ | |
REG_PIOA_ODSR = detail::get_pins<'A', __VA_ARGS__>();\ | |
REG_PIOB_ODSR = detail::get_pins<'B', __VA_ARGS__>();\ | |
REG_PIOC_ODSR = detail::get_pins<'C', __VA_ARGS__>();\ | |
REG_PIOD_ODSR = detail::get_pins<'D', __VA_ARGS__>();\ | |
} while (0) | |
#define TOGGLE_PINS(...) do { \ | |
int a = detail::get_pins<'A', __VA_ARGS__>(); if (a) REG_PIOA_ODSR ^= a;\ | |
int b = detail::get_pins<'B', __VA_ARGS__>(); if (b) REG_PIOB_ODSR ^= b;\ | |
int c = detail::get_pins<'C', __VA_ARGS__>(); if (c) REG_PIOC_ODSR ^= c;\ | |
int d = detail::get_pins<'D', __VA_ARGS__>(); if (d) REG_PIOD_ODSR ^= d;\ | |
} while (0) | |
const int PIN_A = 31; | |
const int PIN_B = 33; | |
const int PIN_C = 35; | |
void setup() { | |
// Enable output on all I/O lines | |
REG_PIOA_OER = REG_PIOB_OER = REG_PIOC_OER = REG_PIOD_OER = 0xFFFFFFFF; | |
// Enable writing directly to PIO lines | |
REG_PIOA_OWER = REG_PIOB_OWER = REG_PIOC_OWER = REG_PIOD_OWER = 0xFFFFFFFF; | |
} | |
void loop() { | |
SET_PINS(PIN_A, PIN_B, PIN_C); | |
delay(50); | |
CLEAR_PINS(PIN_A, PIN_B, PIN_C); | |
delay(50); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment