1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef _HARDWARE_GPIO_H_
8 #define _HARDWARE_GPIO_H_
9
10 #include "pico.h"
11 #include "hardware/structs/sio.h"
12 #include "hardware/structs/padsbank0.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_GPIO, Enable/disable assertions in the GPIO module, type=bool, default=0, group=hardware_gpio
19 #ifndef PARAM_ASSERTIONS_ENABLED_GPIO
20 #define PARAM_ASSERTIONS_ENABLED_GPIO 0
21 #endif
22
23 /** \file gpio.h
24 * \defgroup hardware_gpio hardware_gpio
25 *
26 * General Purpose Input/Output (GPIO) API
27 *
28 * RP2040 has 36 multi-functional General Purpose Input / Output (GPIO) pins, divided into two banks. In a typical use case,
29 * the pins in the QSPI bank (QSPI_SS, QSPI_SCLK and QSPI_SD0 to QSPI_SD3) are used to execute code from an external
30 * flash device, leaving the User bank (GPIO0 to GPIO29) for the programmer to use. All GPIOs support digital input and
31 * output, but GPIO26 to GPIO29 can also be used as inputs to the chip’s Analogue to Digital Converter (ADC). Each GPIO
32 * can be controlled directly by software running on the processors, or by a number of other functional blocks.
33 *
34 * The function allocated to each GPIO is selected by calling the \ref gpio_set_function function. \note Not all functions
35 * are available on all pins.
36 *
37 * Each GPIO can have one function selected at a time. Likewise, each peripheral input (e.g. UART0 RX) should only be selected on
38 * one _GPIO_ at a time. If the same peripheral input is connected to multiple GPIOs, the peripheral sees the logical OR of these
39 * GPIO inputs. Please refer to the datasheet for more information on GPIO function select.
40 *
41 * ### Function Select Table
42 *
43 * GPIO | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9
44 * -------|----------|-----------|----------|--------|-----|------|------|---------------|----
45 * 0 | SPI0 RX | UART0 TX | I2C0 SDA | PWM0 A | SIO | PIO0 | PIO1 | | USB OVCUR DET
46 * 1 | SPI0 CSn | UART0 RX | I2C0 SCL | PWM0 B | SIO | PIO0 | PIO1 | | USB VBUS DET
47 * 2 | SPI0 SCK | UART0 CTS | I2C1 SDA | PWM1 A | SIO | PIO0 | PIO1 | | USB VBUS EN
48 * 3 | SPI0 TX | UART0 RTS | I2C1 SCL | PWM1 B | SIO | PIO0 | PIO1 | | USB OVCUR DET
49 * 4 | SPI0 RX | UART1 TX | I2C0 SDA | PWM2 A | SIO | PIO0 | PIO1 | | USB VBUS DET
50 * 5 | SPI0 CSn | UART1 RX | I2C0 SCL | PWM2 B | SIO | PIO0 | PIO1 | | USB VBUS EN
51 * 6 | SPI0 SCK | UART1 CTS | I2C1 SDA | PWM3 A | SIO | PIO0 | PIO1 | | USB OVCUR DET
52 * 7 | SPI0 TX | UART1 RTS | I2C1 SCL | PWM3 B | SIO | PIO0 | PIO1 | | USB VBUS DET
53 * 8 | SPI1 RX | UART1 TX | I2C0 SDA | PWM4 A | SIO | PIO0 | PIO1 | | USB VBUS EN
54 * 9 | SPI1 CSn | UART1 RX | I2C0 SCL | PWM4 B | SIO | PIO0 | PIO1 | | USB OVCUR DET
55 * 10 | SPI1 SCK | UART1 CTS | I2C1 SDA | PWM5 A | SIO | PIO0 | PIO1 | | USB VBUS DET
56 * 11 | SPI1 TX | UART1 RTS | I2C1 SCL | PWM5 B | SIO | PIO0 | PIO1 | | USB VBUS EN
57 * 12 | SPI1 RX | UART0 TX | I2C0 SDA | PWM6 A | SIO | PIO0 | PIO1 | | USB OVCUR DET
58 * 13 | SPI1 CSn | UART0 RX | I2C0 SCL | PWM6 B | SIO | PIO0 | PIO1 | | USB VBUS DET
59 * 14 | SPI1 SCK | UART0 CTS | I2C1 SDA | PWM7 A | SIO | PIO0 | PIO1 | | USB VBUS EN
60 * 15 | SPI1 TX | UART0 RTS | I2C1 SCL | PWM7 B | SIO | PIO0 | PIO1 | | USB OVCUR DET
61 * 16 | SPI0 RX | UART0 TX | I2C0 SDA | PWM0 A | SIO | PIO0 | PIO1 | | USB VBUS DET
62 * 17 | SPI0 CSn | UART0 RX | I2C0 SCL | PWM0 B | SIO | PIO0 | PIO1 | | USB VBUS EN
63 * 18 | SPI0 SCK | UART0 CTS | I2C1 SDA | PWM1 A | SIO | PIO0 | PIO1 | | USB OVCUR DET
64 * 19 | SPI0 TX | UART0 RTS | I2C1 SCL | PWM1 B | SIO | PIO0 | PIO1 | | USB VBUS DET
65 * 20 | SPI0 RX | UART1 TX | I2C0 SDA | PWM2 A | SIO | PIO0 | PIO1 | CLOCK GPIN0 | USB VBUS EN
66 * 21 | SPI0 CSn | UART1 RX | I2C0 SCL | PWM2 B | SIO | PIO0 | PIO1 | CLOCK GPOUT0 | USB OVCUR DET
67 * 22 | SPI0 SCK | UART1 CTS | I2C1 SDA | PWM3 A | SIO | PIO0 | PIO1 | CLOCK GPIN1 | USB VBUS DET
68 * 23 | SPI0 TX | UART1 RTS | I2C1 SCL | PWM3 B | SIO | PIO0 | PIO1 | CLOCK GPOUT1 | USB VBUS EN
69 * 24 | SPI1 RX | UART1 TX | I2C0 SDA | PWM4 A | SIO | PIO0 | PIO1 | CLOCK GPOUT2 | USB OVCUR DET
70 * 25 | SPI1 CSn | UART1 RX | I2C0 SCL | PWM4 B | SIO | PIO0 | PIO1 | CLOCK GPOUT3 | USB VBUS DET
71 * 26 | SPI1 SCK | UART1 CTS | I2C1 SDA | PWM5 A | SIO | PIO0 | PIO1 | | USB VBUS EN
72 * 27 | SPI1 TX | UART1 RTS | I2C1 SCL | PWM5 B | SIO | PIO0 | PIO1 | | USB OVCUR DET
73 * 28 | SPI1 RX | UART0 TX | I2C0 SDA | PWM6 A | SIO | PIO0 | PIO1 | | USB VBUS DET
74 * 29 | SPI1 CSn | UART0 RX | I2C0 SCL | PWM6 B | SIO | PIO0 | PIO1 | | USB VBUS EN
75
76 */
77
78 /*! \brief GPIO function definitions for use with function select
79 * \ingroup hardware_gpio
80 * \brief GPIO function selectors
81 *
82 * Each GPIO can have one function selected at a time. Likewise, each peripheral input (e.g. UART0 RX) should only be
83 * selected on one GPIO at a time. If the same peripheral input is connected to multiple GPIOs, the peripheral sees the logical
84 * OR of these GPIO inputs.
85 *
86 * Please refer to the datsheet for more information on GPIO function selection.
87 */
88 enum gpio_function {
89 GPIO_FUNC_XIP = 0,
90 GPIO_FUNC_SPI = 1,
91 GPIO_FUNC_UART = 2,
92 GPIO_FUNC_I2C = 3,
93 GPIO_FUNC_PWM = 4,
94 GPIO_FUNC_SIO = 5,
95 GPIO_FUNC_PIO0 = 6,
96 GPIO_FUNC_PIO1 = 7,
97 GPIO_FUNC_GPCK = 8,
98 GPIO_FUNC_USB = 9,
99 GPIO_FUNC_NULL = 0xf,
100 };
101
102 #define GPIO_OUT 1
103 #define GPIO_IN 0
104
105 /*! \brief GPIO Interrupt level definitions
106 * \ingroup hardware_gpio
107 * \brief GPIO Interrupt levels
108 *
109 * An interrupt can be generated for every GPIO pin in 4 scenarios:
110 *
111 * * Level High: the GPIO pin is a logical 1
112 * * Level Low: the GPIO pin is a logical 0
113 * * Edge High: the GPIO has transitioned from a logical 0 to a logical 1
114 * * Edge Low: the GPIO has transitioned from a logical 1 to a logical 0
115 *
116 * The level interrupts are not latched. This means that if the pin is a logical 1 and the level high interrupt is active, it will
117 * become inactive as soon as the pin changes to a logical 0. The edge interrupts are stored in the INTR register and can be
118 * cleared by writing to the INTR register.
119 */
120 enum gpio_irq_level {
121 GPIO_IRQ_LEVEL_LOW = 0x1u,
122 GPIO_IRQ_LEVEL_HIGH = 0x2u,
123 GPIO_IRQ_EDGE_FALL = 0x4u,
124 GPIO_IRQ_EDGE_RISE = 0x8u,
125 };
126
127 typedef void (*gpio_irq_callback_t)(uint gpio, uint32_t events);
128
129 enum gpio_override {
130 GPIO_OVERRIDE_NORMAL = 0, ///< peripheral signal selected via \ref gpio_set_function
131 GPIO_OVERRIDE_INVERT = 1, ///< invert peripheral signal selected via \ref gpio_set_function
132 GPIO_OVERRIDE_LOW = 2, ///< drive low/disable output
133 GPIO_OVERRIDE_HIGH = 3, ///< drive high/enable output
134 };
135
136 // ----------------------------------------------------------------------------
137 // Pad Controls + IO Muxing
138 // ----------------------------------------------------------------------------
139 // Declarations for gpio.c
140
141 /*! \brief Select GPIO function
142 * \ingroup hardware_gpio
143 *
144 * \param gpio GPIO number
145 * \param fn Which GPIO function select to use from list \ref gpio_function
146 */
147 void gpio_set_function(uint gpio, enum gpio_function fn);
148
149 enum gpio_function gpio_get_function(uint gpio);
150
151 /*! \brief Select up and down pulls on specific GPIO
152 * \ingroup hardware_gpio
153 *
154 * \param gpio GPIO number
155 * \param up If true set a pull up on the GPIO
156 * \param down If true set a pull down on the GPIO
157 *
158 * \note On the RP2040, setting both pulls enables a "bus keep" function,
159 * i.e. a weak pull to whatever is current high/low state of GPIO.
160 */
161 void gpio_set_pulls(uint gpio, bool up, bool down);
162
163 /*! \brief Set specified GPIO to be pulled up.
164 * \ingroup hardware_gpio
165 *
166 * \param gpio GPIO number
167 */
gpio_pull_up(uint gpio)168 static inline void gpio_pull_up(uint gpio) {
169 gpio_set_pulls(gpio, true, false);
170 }
171
172 /*! \brief Determine if the specified GPIO is pulled up.
173 * \ingroup hardware_gpio
174 *
175 * \param gpio GPIO number
176 * \return true if the GPIO is pulled up
177 */
gpio_is_pulled_up(uint gpio)178 static inline bool gpio_is_pulled_up(uint gpio) {
179 return (padsbank0_hw->io[gpio] & PADS_BANK0_GPIO0_PUE_BITS) != 0;
180 }
181
182 /*! \brief Set specified GPIO to be pulled down.
183 * \ingroup hardware_gpio
184 *
185 * \param gpio GPIO number
186 */
gpio_pull_down(uint gpio)187 static inline void gpio_pull_down(uint gpio) {
188 gpio_set_pulls(gpio, false, true);
189 }
190
191 /*! \brief Determine if the specified GPIO is pulled down.
192 * \ingroup hardware_gpio
193 *
194 * \param gpio GPIO number
195 * \return true if the GPIO is pulled down
196 */
gpio_is_pulled_down(uint gpio)197 static inline bool gpio_is_pulled_down(uint gpio) {
198 return (padsbank0_hw->io[gpio] & PADS_BANK0_GPIO0_PDE_BITS) != 0;
199 }
200
201 /*! \brief Disable pulls on specified GPIO
202 * \ingroup hardware_gpio
203 *
204 * \param gpio GPIO number
205 */
gpio_disable_pulls(uint gpio)206 static inline void gpio_disable_pulls(uint gpio) {
207 gpio_set_pulls(gpio, false, false);
208 }
209
210 /*! \brief Set GPIO output override
211 * \ingroup hardware_gpio
212 *
213 * \param gpio GPIO number
214 * \param value See \ref gpio_override
215 */
216 void gpio_set_outover(uint gpio, uint value);
217
218 /*! \brief Select GPIO input override
219 * \ingroup hardware_gpio
220 *
221 * \param gpio GPIO number
222 * \param value See \ref gpio_override
223 */
224 void gpio_set_inover(uint gpio, uint value);
225
226 /*! \brief Select GPIO output enable override
227 * \ingroup hardware_gpio
228 *
229 * \param gpio GPIO number
230 * \param value See \ref gpio_override
231 */
232 void gpio_set_oeover(uint gpio, uint value);
233
234 /*! \brief Enable GPIO input
235 * \ingroup hardware_gpio
236 *
237 * \param gpio GPIO number
238 * \param enabled true to enable input on specified GPIO
239 */
240 void gpio_set_input_enabled(uint gpio, bool enabled);
241
242 /*! \brief Enable or disable interrupts for specified GPIO
243 * \ingroup hardware_gpio
244 *
245 * \note The IO IRQs are independent per-processor. This configures IRQs for
246 * the processor that calls the function.
247 *
248 * \param gpio GPIO number
249 * \param events Which events will cause an interrupt
250 * \param enabled Enable or disable flag
251 *
252 * Events is a bitmask of the following:
253 *
254 * bit | interrupt
255 * ----|----------
256 * 0 | Low level
257 * 1 | High level
258 * 2 | Edge low
259 * 3 | Edge high
260 */
261 void gpio_set_irq_enabled(uint gpio, uint32_t events, bool enabled);
262
263 /*! \brief Enable interrupts for specified GPIO
264 * \ingroup hardware_gpio
265 *
266 * \note The IO IRQs are independent per-processor. This configures IRQs for
267 * the processor that calls the function.
268 *
269 * \param gpio GPIO number
270 * \param events Which events will cause an interrupt See \ref gpio_set_irq_enabled for details.
271 * \param enabled Enable or disable flag
272 * \param callback user function to call on GPIO irq. Note only one of these can be set per processor.
273 *
274 * \note Currently the GPIO parameter is ignored, and this callback will be called for any enabled GPIO IRQ on any pin.
275 *
276 */
277 void gpio_set_irq_enabled_with_callback(uint gpio, uint32_t events, bool enabled, gpio_irq_callback_t callback);
278
279 /*! \brief Enable dormant wake up interrupt for specified GPIO
280 * \ingroup hardware_gpio
281 *
282 * This configures IRQs to restart the XOSC or ROSC when they are
283 * disabled in dormant mode
284 *
285 * \param gpio GPIO number
286 * \param events Which events will cause an interrupt. See \ref gpio_set_irq_enabled for details.
287 * \param enabled Enable/disable flag
288 */
289 void gpio_set_dormant_irq_enabled(uint gpio, uint32_t events, bool enabled);
290
291 /*! \brief Acknowledge a GPIO interrupt
292 * \ingroup hardware_gpio
293 *
294 * \param gpio GPIO number
295 * \param events Bitmask of events to clear. See \ref gpio_set_irq_enabled for details.
296 *
297 */
298 void gpio_acknowledge_irq(uint gpio, uint32_t events);
299
300 /*! \brief Initialise a GPIO for (enabled I/O and set func to GPIO_FUNC_SIO)
301 * \ingroup hardware_gpio
302 *
303 * Clear the output enable (i.e. set to input)
304 * Clear any output value.
305 *
306 * \param gpio GPIO number
307 */
308 void gpio_init(uint gpio);
309
310 /*! \brief Initialise multiple GPIOs (enabled I/O and set func to GPIO_FUNC_SIO)
311 * \ingroup hardware_gpio
312 *
313 * Clear the output enable (i.e. set to input)
314 * Clear any output value.
315 *
316 * \param gpio_mask Mask with 1 bit per GPIO number to initialize
317 */
318 void gpio_init_mask(uint gpio_mask);
319 // ----------------------------------------------------------------------------
320 // Input
321 // ----------------------------------------------------------------------------
322
323 /*! \brief Get state of a single specified GPIO
324 * \ingroup hardware_gpio
325 *
326 * \param gpio GPIO number
327 * \return Current state of the GPIO. 0 for low, non-zero for high
328 */
gpio_get(uint gpio)329 static inline bool gpio_get(uint gpio) {
330 return !!((1ul << gpio) & sio_hw->gpio_in);
331 }
332
333 /*! \brief Get raw value of all GPIOs
334 * \ingroup hardware_gpio
335 *
336 * \return Bitmask of raw GPIO values, as bits 0-29
337 */
gpio_get_all(void)338 static inline uint32_t gpio_get_all(void) {
339 return sio_hw->gpio_in;
340 }
341
342 // ----------------------------------------------------------------------------
343 // Output
344 // ----------------------------------------------------------------------------
345
346 /*! \brief Drive high every GPIO appearing in mask
347 * \ingroup hardware_gpio
348 *
349 * \param mask Bitmask of GPIO values to set, as bits 0-29
350 */
gpio_set_mask(uint32_t mask)351 static inline void gpio_set_mask(uint32_t mask) {
352 sio_hw->gpio_set = mask;
353 }
354
355 /*! \brief Drive low every GPIO appearing in mask
356 * \ingroup hardware_gpio
357 *
358 * \param mask Bitmask of GPIO values to clear, as bits 0-29
359 */
gpio_clr_mask(uint32_t mask)360 static inline void gpio_clr_mask(uint32_t mask) {
361 sio_hw->gpio_clr = mask;
362 }
363
364 /*! \brief Toggle every GPIO appearing in mask
365 * \ingroup hardware_gpio
366 *
367 * \param mask Bitmask of GPIO values to toggle, as bits 0-29
368 */
gpio_xor_mask(uint32_t mask)369 static inline void gpio_xor_mask(uint32_t mask) {
370 sio_hw->gpio_togl = mask;
371 }
372
373 /*! \brief Drive GPIO high/low depending on parameters
374 * \ingroup hardware_gpio
375 *
376 * \param mask Bitmask of GPIO values to change, as bits 0-29
377 * \param value Value to set
378 *
379 * For each 1 bit in \p mask, drive that pin to the value given by
380 * corresponding bit in \p value, leaving other pins unchanged.
381 * Since this uses the TOGL alias, it is concurrency-safe with e.g. an IRQ
382 * bashing different pins from the same core.
383 */
gpio_put_masked(uint32_t mask,uint32_t value)384 static inline void gpio_put_masked(uint32_t mask, uint32_t value) {
385 sio_hw->gpio_togl = (sio_hw->gpio_out ^ value) & mask;
386 }
387
388 /*! \brief Drive all pins simultaneously
389 * \ingroup hardware_gpio
390 *
391 * \param value Bitmask of GPIO values to change, as bits 0-29
392 */
gpio_put_all(uint32_t value)393 static inline void gpio_put_all(uint32_t value) {
394 sio_hw->gpio_out = value;
395 }
396
397 /*! \brief Drive a single GPIO high/low
398 * \ingroup hardware_gpio
399 *
400 * \param gpio GPIO number
401 * \param value If false clear the GPIO, otherwise set it.
402 */
gpio_put(uint gpio,bool value)403 static inline void gpio_put(uint gpio, bool value) {
404 uint32_t mask = 1ul << gpio;
405 if (value)
406 gpio_set_mask(mask);
407 else
408 gpio_clr_mask(mask);
409 }
410
411 // ----------------------------------------------------------------------------
412 // Direction
413 // ----------------------------------------------------------------------------
414
415 /*! \brief Set a number of GPIOs to output
416 * \ingroup hardware_gpio
417 *
418 * Switch all GPIOs in "mask" to output
419 *
420 * \param mask Bitmask of GPIO to set to output, as bits 0-29
421 */
gpio_set_dir_out_masked(uint32_t mask)422 static inline void gpio_set_dir_out_masked(uint32_t mask) {
423 sio_hw->gpio_oe_set = mask;
424 }
425
426 /*! \brief Set a number of GPIOs to input
427 * \ingroup hardware_gpio
428 *
429 * \param mask Bitmask of GPIO to set to input, as bits 0-29
430 */
gpio_set_dir_in_masked(uint32_t mask)431 static inline void gpio_set_dir_in_masked(uint32_t mask) {
432 sio_hw->gpio_oe_clr = mask;
433 }
434
435 /*! \brief Set multiple GPIO directions
436 * \ingroup hardware_gpio
437 *
438 * \param mask Bitmask of GPIO to set to input, as bits 0-29
439 * \param value Values to set
440 *
441 * For each 1 bit in "mask", switch that pin to the direction given by
442 * corresponding bit in "value", leaving other pins unchanged.
443 * E.g. gpio_set_dir_masked(0x3, 0x2); -> set pin 0 to input, pin 1 to output,
444 * simultaneously.
445 */
gpio_set_dir_masked(uint32_t mask,uint32_t value)446 static inline void gpio_set_dir_masked(uint32_t mask, uint32_t value) {
447 sio_hw->gpio_oe_togl = (sio_hw->gpio_oe ^ value) & mask;
448 }
449
450 /*! \brief Set direction of all pins simultaneously.
451 * \ingroup hardware_gpio
452 *
453 * \param values individual settings for each gpio; for GPIO N, bit N is 1 for out, 0 for in
454 */
gpio_set_dir_all_bits(uint32_t values)455 static inline void gpio_set_dir_all_bits(uint32_t values) {
456 sio_hw->gpio_oe = values;
457 }
458
459 /*! \brief Set a single GPIO direction
460 * \ingroup hardware_gpio
461 *
462 * \param gpio GPIO number
463 * \param out true for out, false for in
464 */
gpio_set_dir(uint gpio,bool out)465 static inline void gpio_set_dir(uint gpio, bool out) {
466 uint32_t mask = 1ul << gpio;
467 if (out)
468 gpio_set_dir_out_masked(mask);
469 else
470 gpio_set_dir_in_masked(mask);
471 }
472
473 /*! \brief Check if a specific GPIO direction is OUT
474 * \ingroup hardware_gpio
475 *
476 * \param gpio GPIO number
477 * \return true if the direction for the pin is OUT
478 */
gpio_is_dir_out(uint gpio)479 static inline bool gpio_is_dir_out(uint gpio) {
480 return !!(sio_hw->gpio_oe & (1u << (gpio)));
481 }
482
483 /*! \brief Get a specific GPIO direction
484 * \ingroup hardware_gpio
485 *
486 * \param gpio GPIO number
487 * \return 1 for out, 0 for in
488 */
gpio_get_dir(uint gpio)489 static inline uint gpio_get_dir(uint gpio) {
490 return gpio_is_dir_out(gpio); // note GPIO_OUT is 1/true and GPIO_IN is 0/false anyway
491 }
492
493 extern void gpio_debug_pins_init(void);
494
495 #ifdef __cplusplus
496 }
497 #endif
498
499
500 // PICO_CONFIG: PICO_DEBUG_PIN_BASE, First pin to use for debug output (if enabled), min=0, max=28, default=19, group=hardware_gpio
501 #ifndef PICO_DEBUG_PIN_BASE
502 #define PICO_DEBUG_PIN_BASE 19u
503 #endif
504
505 // PICO_CONFIG: PICO_DEBUG_PIN_COUNT, Number of pins to use for debug output (if enabled), min=1, max=28, default=3, group=hardware_gpio
506 #ifndef PICO_DEBUG_PIN_COUNT
507 #define PICO_DEBUG_PIN_COUNT 3u
508 #endif
509
510 #ifndef __cplusplus
511 // note these two macros may only be used once per and only apply per compilation unit (hence the CU_)
512 #define CU_REGISTER_DEBUG_PINS(...) enum __unused DEBUG_PIN_TYPE { _none = 0, __VA_ARGS__ }; static enum DEBUG_PIN_TYPE __selected_debug_pins;
513 #define CU_SELECT_DEBUG_PINS(x) static enum DEBUG_PIN_TYPE __selected_debug_pins = (x);
514 #define DEBUG_PINS_ENABLED(p) (__selected_debug_pins == (p))
515 #else
516 #define CU_REGISTER_DEBUG_PINS(p...) \
517 enum DEBUG_PIN_TYPE { _none = 0, p }; \
518 template <enum DEBUG_PIN_TYPE> class __debug_pin_settings { \
519 public: \
520 static inline bool enabled() { return false; } \
521 };
522 #define CU_SELECT_DEBUG_PINS(x) template<> inline bool __debug_pin_settings<x>::enabled() { return true; };
523 #define DEBUG_PINS_ENABLED(p) (__debug_pin_settings<p>::enabled())
524 #endif
525 #define DEBUG_PINS_SET(p, v) if (DEBUG_PINS_ENABLED(p)) gpio_set_mask((unsigned)(v)<<PICO_DEBUG_PIN_BASE)
526 #define DEBUG_PINS_CLR(p, v) if (DEBUG_PINS_ENABLED(p)) gpio_clr_mask((unsigned)(v)<<PICO_DEBUG_PIN_BASE)
527 #define DEBUG_PINS_XOR(p, v) if (DEBUG_PINS_ENABLED(p)) gpio_xor_mask((unsigned)(v)<<PICO_DEBUG_PIN_BASE)
528
529 #endif // _GPIO_H_
530