diff --git a/io.hpp b/io.hpp index ccdec66..95dee00 100644 --- a/io.hpp +++ b/io.hpp @@ -127,17 +127,23 @@ enum class Bus { namespace detail { /* -The following works in avr-gcc 5.4.0, but is not legal C++, because ptr's are not legal constexpr's +The following works in avr-gcc 5.4.0, but is not legal C++, because ptr's are not legal constexpr's: constexpr auto *foo = ptr; -Workaround is to store the the address of the ptr in a uintptr_t and reinterpret_cast it at call site -For this the sfr_defs.h provides a macro which returns the address of a register +Workaround is to store the the address of the ptr in a uintptr_t and reinterpret_cast it at call site. +The _SFR_ADDR macro in sfr_defs.h would give the address, but it does that by taking the address of the dereferenced +pointer and casts it to uint16_t, which is still not a legal constexpr. +The workaround therefore is to disable the pointer cast and dereference macro _MMIO_BYTE temporarily. */ +#pragma push_macro("_MMIO_BYTE") +#undef _MMIO_BYTE +#define _MMIO_BYTE + #ifdef PORT_A_AVAILABLE -static constexpr uintptr_t PORT_A_DIR_REG_ADDR = _SFR_ADDR(DDRA); -static constexpr uintptr_t PORT_A_OUTPUT_REG_ADDR = _SFR_ADDR(PORTA); -static constexpr uintptr_t PORT_A_INPUT_REG_ADDR = _SFR_ADDR(PINA); +static constexpr uintptr_t PORT_A_DIR_REG_ADDR = DDRA; +static constexpr uintptr_t PORT_A_OUTPUT_REG_ADDR = PORTA; +static constexpr uintptr_t PORT_A_INPUT_REG_ADDR = PINA; #else static constexpr uintptr_t PORT_A_DIR_REG_ADDR = 0; static constexpr uintptr_t PORT_A_OUTPUT_REG_ADDR = 0; @@ -146,9 +152,9 @@ static constexpr uintptr_t PORT_A_INPUT_REG_ADDR = 0; #ifdef PORT_B_AVAILABLE -static constexpr uintptr_t PORT_B_DIR_REG_ADDR = _SFR_ADDR(DDRB); -static constexpr uintptr_t PORT_B_OUTPUT_REG_ADDR = _SFR_ADDR(PORTB); -static constexpr uintptr_t PORT_B_INPUT_REG_ADDR = _SFR_ADDR(PINB); +static constexpr uintptr_t PORT_B_DIR_REG_ADDR = DDRB; +static constexpr uintptr_t PORT_B_OUTPUT_REG_ADDR = PORTB; +static constexpr uintptr_t PORT_B_INPUT_REG_ADDR = PINB; #else static constexpr uintptr_t PORT_B_DIR_REG_ADDR = 0; static constexpr uintptr_t PORT_B_OUTPUT_REG_ADDR = 0; @@ -156,9 +162,9 @@ static constexpr uintptr_t PORT_B_INPUT_REG_ADDR = 0; #endif #ifdef PORT_C_AVAILABLE -static constexpr uintptr_t PORT_C_DIR_REG_ADDR = _SFR_ADDR(DDRC); -static constexpr uintptr_t PORT_C_OUTPUT_REG_ADDR = _SFR_ADDR(PORTC); -static constexpr uintptr_t PORT_C_INPUT_REG_ADDR = _SFR_ADDR(PINC); +static constexpr uintptr_t PORT_C_DIR_REG_ADDR = DDRC; +static constexpr uintptr_t PORT_C_OUTPUT_REG_ADDR = PORTC; +static constexpr uintptr_t PORT_C_INPUT_REG_ADDR = PINC; #else static constexpr uintptr_t PORT_C_DIR_REG_ADDR = 0; static constexpr uintptr_t PORT_C_OUTPUT_REG_ADDR = 0; @@ -166,15 +172,17 @@ static constexpr uintptr_t PORT_C_INPUT_REG_ADDR = 0; #endif #ifdef PORT_D_AVAILABLE -static constexpr uintptr_t PORT_D_DIR_REG_ADDR = _SFR_ADDR(DDRD); -static constexpr uintptr_t PORT_D_OUTPUT_REG_ADDR = _SFR_ADDR(PORTD); -static constexpr uintptr_t PORT_D_INPUT_REG_ADDR = _SFR_ADDR(PIND); +static constexpr uintptr_t PORT_D_DIR_REG_ADDR = DDRD; +static constexpr uintptr_t PORT_D_OUTPUT_REG_ADDR = PORTD; +static constexpr uintptr_t PORT_D_INPUT_REG_ADDR = PIND; #else static constexpr uintptr_t PORT_D_DIR_REG_ADDR = 0; static constexpr uintptr_t PORT_D_OUTPUT_REG_ADDR = 0; static constexpr uintptr_t PORT_D_INPUT_REG_ADDR = 0; #endif +#pragma pop_macro("_MMIO_BYTE") + static constexpr auto getBus(const P pin) { // Upper 4 bits of pin encode which port this pin is on