21#ifndef LSH_CORE_INTERNAL_AVR_FAST_IO_HPP
22#define LSH_CORE_INTERNAL_AVR_FAST_IO_HPP
50 volatile const uint8_t *
pinPort =
nullptr;
85#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
86#define LSH_CORE_MEGA_IO_PIN_DESC(input_io_addr, output_io_addr, mode_io_addr, bit_index) \
89 static_cast<uint8_t>(_BV(bit_index)), static_cast<uint16_t>((input_io_addr) + __SFR_OFFSET), \
90 static_cast<uint16_t>((output_io_addr) + __SFR_OFFSET), static_cast<uint16_t>((mode_io_addr) + __SFR_OFFSET) \
93#define LSH_CORE_MEGA_MEM_PIN_DESC(input_mem_addr, output_mem_addr, mode_mem_addr, bit_index) \
96 static_cast<uint8_t>(_BV(bit_index)), static_cast<uint16_t>(input_mem_addr), static_cast<uint16_t>(output_mem_addr), \
97 static_cast<uint16_t>(mode_mem_addr) \
110 LSH_CORE_MEGA_IO_PIN_DESC(0x0CU, 0x0EU, 0x0DU, 0),
111 LSH_CORE_MEGA_IO_PIN_DESC(0x0CU, 0x0EU, 0x0DU, 1),
112 LSH_CORE_MEGA_IO_PIN_DESC(0x0CU, 0x0EU, 0x0DU, 4),
113 LSH_CORE_MEGA_IO_PIN_DESC(0x0CU, 0x0EU, 0x0DU, 5),
114 LSH_CORE_MEGA_IO_PIN_DESC(0x12U, 0x14U, 0x13U, 5),
115 LSH_CORE_MEGA_IO_PIN_DESC(0x0CU, 0x0EU, 0x0DU, 3),
116 LSH_CORE_MEGA_MEM_PIN_DESC(0x100U, 0x102U, 0x101U, 3),
117 LSH_CORE_MEGA_MEM_PIN_DESC(0x100U, 0x102U, 0x101U, 4),
118 LSH_CORE_MEGA_MEM_PIN_DESC(0x100U, 0x102U, 0x101U, 5),
119 LSH_CORE_MEGA_MEM_PIN_DESC(0x100U, 0x102U, 0x101U, 6),
120 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 4),
121 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 5),
122 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 6),
123 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 7),
124 LSH_CORE_MEGA_MEM_PIN_DESC(0x103U, 0x105U, 0x104U, 1),
125 LSH_CORE_MEGA_MEM_PIN_DESC(0x103U, 0x105U, 0x104U, 0),
126 LSH_CORE_MEGA_MEM_PIN_DESC(0x100U, 0x102U, 0x101U, 1),
127 LSH_CORE_MEGA_MEM_PIN_DESC(0x100U, 0x102U, 0x101U, 0),
128 LSH_CORE_MEGA_IO_PIN_DESC(0x09U, 0x0BU, 0x0AU, 3),
129 LSH_CORE_MEGA_IO_PIN_DESC(0x09U, 0x0BU, 0x0AU, 2),
130 LSH_CORE_MEGA_IO_PIN_DESC(0x09U, 0x0BU, 0x0AU, 1),
131 LSH_CORE_MEGA_IO_PIN_DESC(0x09U, 0x0BU, 0x0AU, 0),
132 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 0),
133 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 1),
134 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 2),
135 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 3),
136 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 4),
137 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 5),
138 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 6),
139 LSH_CORE_MEGA_IO_PIN_DESC(0x00U, 0x02U, 0x01U, 7),
140 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 7),
141 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 6),
142 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 5),
143 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 4),
144 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 3),
145 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 2),
146 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 1),
147 LSH_CORE_MEGA_IO_PIN_DESC(0x06U, 0x08U, 0x07U, 0),
148 LSH_CORE_MEGA_IO_PIN_DESC(0x09U, 0x0BU, 0x0AU, 7),
149 LSH_CORE_MEGA_IO_PIN_DESC(0x12U, 0x14U, 0x13U, 2),
150 LSH_CORE_MEGA_IO_PIN_DESC(0x12U, 0x14U, 0x13U, 1),
151 LSH_CORE_MEGA_IO_PIN_DESC(0x12U, 0x14U, 0x13U, 0),
152 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 7),
153 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 6),
154 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 5),
155 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 4),
156 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 3),
157 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 2),
158 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 1),
159 LSH_CORE_MEGA_MEM_PIN_DESC(0x109U, 0x10BU, 0x10AU, 0),
160 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 3),
161 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 2),
162 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 1),
163 LSH_CORE_MEGA_IO_PIN_DESC(0x03U, 0x05U, 0x04U, 0),
164 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 0),
165 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 1),
166 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 2),
167 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 3),
168 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 4),
169 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 5),
170 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 6),
171 LSH_CORE_MEGA_IO_PIN_DESC(0x0FU, 0x11U, 0x10U, 7),
172 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 0),
173 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 1),
174 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 2),
175 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 3),
176 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 4),
177 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 5),
178 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 6),
179 LSH_CORE_MEGA_MEM_PIN_DESC(0x106U, 0x108U, 0x107U, 7),
182#undef LSH_CORE_MEGA_IO_PIN_DESC
183#undef LSH_CORE_MEGA_MEM_PIN_DESC
192[[nodiscard]]
constexpr auto megaPinDescriptor(uint8_t pin)
noexcept -> StaticPinDescriptor
194 return (pin < (
sizeof(kMegaPinDescriptors) /
sizeof(kMegaPinDescriptors[0]))) ? kMegaPinDescriptors[pin] : StaticPinDescriptor{};
200[[nodiscard]]
constexpr auto hasConstexprMegaBinding(uint8_t pin)
noexcept ->
bool
202 return megaPinDescriptor(pin).
mask != 0U;
212 return reinterpret_cast<volatile const uint8_t *
>(address);
221 return reinterpret_cast<volatile uint8_t *
>(address);
230 return reinterpret_cast<volatile uint8_t *
>(address);
239 return pgm_read_byte(digital_pin_to_bit_mask_PGM + pin);
247 return pgm_read_byte(digital_pin_to_port_PGM + pin);
253[[nodiscard]]
inline auto inputRegister(uint8_t port)
noexcept ->
volatile const uint8_t *
256 return reinterpret_cast<volatile const uint8_t *
>(pgm_read_word(port_to_input_PGM + port));
262[[nodiscard]]
inline auto outputRegister(uint8_t port)
noexcept ->
volatile uint8_t *
265 return reinterpret_cast<volatile uint8_t *
>(pgm_read_word(port_to_output_PGM + port));
271[[nodiscard]]
inline auto modeRegister(uint8_t port)
noexcept ->
volatile uint8_t *
274 return reinterpret_cast<volatile uint8_t *
>(pgm_read_word(port_to_mode_PGM + port));
326#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
327 if constexpr (detail::hasConstexprMegaBinding(Pin))
330 return descriptor.
mask;
341#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
342 if constexpr (detail::hasConstexprMegaBinding(Pin))
345 return detail::inputRegisterFromAddress(descriptor.
inputAddress);
356#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
357 if constexpr (detail::hasConstexprMegaBinding(Pin))
360 return detail::outputRegisterFromAddress(descriptor.
outputAddress);
371#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
372 if constexpr (detail::hasConstexprMegaBinding(Pin))
375 return detail::modeRegisterFromAddress(descriptor.
modeAddress);
auto inputRegister(uint8_t port) noexcept -> volatile const uint8_t *
Converts one Arduino core port index to the AVR input register.
Definition avr_fast_io.hpp:253
auto readPinBitMask(uint8_t pin) noexcept -> uint8_t
Reads the fast-I/O bit mask for one runtime Arduino pin.
Definition avr_fast_io.hpp:237
auto inputRegisterFromAddress(uint16_t address) noexcept -> volatile const uint8_t *
Rebuilds a read-only AVR register pointer from a raw MMIO address.
Definition avr_fast_io.hpp:209
auto makeFastOutputPinBinding(uint8_t pin) noexcept -> FastOutputPinBinding
Builds the cached fast-output binding for one runtime pin.
Definition avr_fast_io.hpp:312
auto modeRegisterForPin(uint8_t pin) noexcept -> volatile uint8_t *
Resolves the AVR DDR register for one runtime Arduino pin.
Definition avr_fast_io.hpp:296
auto modeRegister(uint8_t port) noexcept -> volatile uint8_t *
Converts one Arduino core port index to the AVR DDR register.
Definition avr_fast_io.hpp:271
auto inputRegisterForPin(uint8_t pin) noexcept -> volatile const uint8_t *
Resolves the AVR input register for one runtime Arduino pin.
Definition avr_fast_io.hpp:280
auto outputRegisterForPin(uint8_t pin) noexcept -> volatile uint8_t *
Resolves the AVR output register for one runtime Arduino pin.
Definition avr_fast_io.hpp:288
auto makeFastInputPinBinding(uint8_t pin) noexcept -> FastInputPinBinding
Builds the cached fast-input binding for one runtime pin.
Definition avr_fast_io.hpp:304
auto outputRegisterFromAddress(uint16_t address) noexcept -> volatile uint8_t *
Rebuilds a writable AVR register pointer from a raw MMIO address.
Definition avr_fast_io.hpp:218
auto modeRegisterFromAddress(uint16_t address) noexcept -> volatile uint8_t *
Rebuilds a writable AVR DDR register pointer from a raw MMIO address.
Definition avr_fast_io.hpp:227
auto readPinPortIndex(uint8_t pin) noexcept -> uint8_t
Reads the Arduino core port index for one runtime pin.
Definition avr_fast_io.hpp:245
auto outputRegister(uint8_t port) noexcept -> volatile uint8_t *
Converts one Arduino core port index to the AVR output register.
Definition avr_fast_io.hpp:262
Compile-time pin tag used to route peripheral construction through constant pin paths.
Type-level wrapper around one Arduino pin number.
Definition pin_tag.hpp:41
Resolved fast-output binding for one Arduino pin.
Definition avr_fast_io.hpp:62
volatile uint8_t * modePort
Final AVR DDR register used to configure the pin direction.
Definition avr_fast_io.hpp:65
volatile uint8_t * pinPort
Final AVR output register used to drive the pin.
Definition avr_fast_io.hpp:64
uint8_t mask
Final bit mask for the pin inside the AVR port.
Definition avr_fast_io.hpp:63
Compile-time descriptor for one fully resolved AVR pin binding.
Definition avr_fast_io.hpp:76
uint8_t mask
Final bit mask for the pin inside the port.
Definition avr_fast_io.hpp:77
uint16_t inputAddress
Raw MMIO address of the input register.
Definition avr_fast_io.hpp:78
uint16_t modeAddress
Raw MMIO address of the DDR register.
Definition avr_fast_io.hpp:80
uint16_t outputAddress
Raw MMIO address of the output register.
Definition avr_fast_io.hpp:79