v2.0.0
gpio_coproc.h
1/*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef _HARDWARE_GPIO_COPROC_H
8#define _HARDWARE_GPIO_COPROC_H
9
10#ifdef __riscv
11#error "GPIO coprocessor port is not available on RISC-V"
12#endif
13
14#if PICO_RP2040
15#error "GPIO coprocessor is not available on RP2040"
16#endif
17
18#if !HAS_GPIO_COPROCESSOR
19#error "GPIO coprocessor is not available"
20#endif
21
22#include "pico.h"
23
24// ----------------------------------------------------------------------------
25// OUT mask write instructions
26
27// Equivalent to sio_hw->gpio_out = x;
28__force_inline static void gpioc_lo_out_put(uint32_t x) {
29 pico_default_asm_volatile ("mcr p0, #0, %0, c0, c0" : : "r" (x));
30}
31
32// Equivalent to sio_hw->gpio_togl = x;
33__force_inline static void gpioc_lo_out_xor(uint32_t x) {
34 pico_default_asm_volatile ("mcr p0, #1, %0, c0, c0" : : "r" (x));
35}
36
37// Equivalent to sio_hw->gpio_set = x;
38__force_inline static void gpioc_lo_out_set(uint32_t x) {
39 pico_default_asm_volatile ("mcr p0, #2, %0, c0, c0" : : "r" (x));
40}
41
42// Equivalent to sio_hw->gpio_clr = x;
43__force_inline static void gpioc_lo_out_clr(uint32_t x) {
44 pico_default_asm_volatile ("mcr p0, #3, %0, c0, c0" : : "r" (x));
45}
46
47// Equivalent to sio_hw->gpio_hi_out = x;
48__force_inline static void gpioc_hi_out_put(uint32_t x) {
49 pico_default_asm_volatile ("mcr p0, #0, %0, c0, c1" : : "r" (x));
50}
51
52// Equivalent to sio_hw->gpio_hi_togl = x;
53__force_inline static void gpioc_hi_out_xor(uint32_t x) {
54 pico_default_asm_volatile ("mcr p0, #1, %0, c0, c1" : : "r" (x));
55}
56
57// Equivalent to sio_hw->gpio_hi_set = x;
58__force_inline static void gpioc_hi_out_set(uint32_t x) {
59 pico_default_asm_volatile ("mcr p0, #2, %0, c0, c1" : : "r" (x));
60}
61
62// Equivalent to sio_hw->gpio_hi_clr = x;
63__force_inline static void gpioc_hi_out_clr(uint32_t x) {
64 pico_default_asm_volatile ("mcr p0, #3, %0, c0, c1" : : "r" (x));
65}
66
67// Equivalent to these two operations performed on the same cycle:
68// - sio_hw->gpio_out = x & 0xffffffff;
69// - sio_hw->gpio_hi_out = x >> 32;
70__force_inline static void gpioc_hilo_out_put(uint64_t x) {
71 pico_default_asm_volatile ("mcrr p0, #0, %0, %1, c0" : : "r" (x & 0xffffffffu), "r" (x >> 32));
72}
73
74// Equivalent to these two operations performed on the same cycle:
75// - sio_hw->gpio_togl = x & 0xffffffff;
76// - sio_hw->gpio_hi_togl = x >> 32;
77__force_inline static void gpioc_hilo_out_xor(uint64_t x) {
78 pico_default_asm_volatile ("mcrr p0, #1, %0, %1, c0" : : "r" (x & 0xffffffffu), "r" (x >> 32));
79}
80
81// Equivalent to these two operations performed on the same cycle:
82// - sio_hw->gpio_set = x & 0xffffffff;
83// - sio_hw->gpio_hi_set = x >> 32;
84__force_inline static void gpioc_hilo_out_set(uint64_t x) {
85 pico_default_asm_volatile ("mcrr p0, #2, %0, %1, c0" : : "r" (x & 0xffffffffu), "r" (x >> 32));
86}
87
88// Equivalent to these two operations performed on the same cycle:
89// - sio_hw->gpio_clr = x & 0xffffffff;
90// - sio_hw->gpio_hi_clr = x >> 32;
91__force_inline static void gpioc_hilo_out_clr(uint64_t x) {
92 pico_default_asm_volatile ("mcrr p0, #3, %0, %1, c0" : : "r" (x & 0xffffffffu), "r" (x >> 32));
93}
94
95// ----------------------------------------------------------------------------
96// OE mask write instructions
97
98// Equivalent to sio_hw->gpio_oe = x;
99__force_inline static void gpioc_lo_oe_put(uint32_t x) {
100 pico_default_asm_volatile ("mcr p0, #0, %0, c0, c4" : : "r" (x));
101}
102
103// Equivalent to sio_hw->gpio_oe_togl = x;
104__force_inline static void gpioc_lo_oe_xor(uint32_t x) {
105 pico_default_asm_volatile ("mcr p0, #1, %0, c0, c4" : : "r" (x));
106}
107
108// Equivalent to sio_hw->gpio_oe_set = x;
109__force_inline static void gpioc_lo_oe_set(uint32_t x) {
110 pico_default_asm_volatile ("mcr p0, #2, %0, c0, c4" : : "r" (x));
111}
112
113// Equivalent to sio_hw->gpio_oe_clr = x;
114__force_inline static void gpioc_lo_oe_clr(uint32_t x) {
115 pico_default_asm_volatile ("mcr p0, #3, %0, c0, c4" : : "r" (x));
116}
117
118// Equivalent to sio_hw->gpio_hi_oe = x;
119__force_inline static void gpioc_hi_oe_put(uint32_t x) {
120 pico_default_asm_volatile ("mcr p0, #0, %0, c0, c5" : : "r" (x));
121}
122
123// Equivalent to sio_hw->gpio_hi_oe_togl = x;
124__force_inline static void gpioc_hi_oe_xor(uint32_t x) {
125 pico_default_asm_volatile ("mcr p0, #1, %0, c0, c5" : : "r" (x));
126}
127
128// Equivalent to sio_hw->gpio_hi_oe_set = x;
129__force_inline static void gpioc_hi_oe_set(uint32_t x) {
130 pico_default_asm_volatile ("mcr p0, #2, %0, c0, c5" : : "r" (x));
131}
132
133// Equivalent to sio_hw->gpio_hi_oe_clr = x;
134__force_inline static void gpioc_hi_oe_clr(uint32_t x) {
135 pico_default_asm_volatile ("mcr p0, #3, %0, c0, c5" : : "r" (x));
136}
137
138// Equivalent to these two operations performed on the same cycle:
139// - sio_hw->gpio_oe = x & 0xffffffff;
140// - sio_hw->gpio_hi_oe = x >> 32;
141__force_inline static void gpioc_hilo_oe_put(uint64_t x) {
142 pico_default_asm_volatile ("mcrr p0, #0, %0, %1, c4" : : "r" (x & 0xffffffffu), "r" (x >> 32));
143}
144
145// Equivalent to these two operations performed on the same cycle:
146// - sio_hw->gpio_oe_togl = x & 0xffffffff;
147// - sio_hw->gpio_hi_oe_togl = x >> 32;
148__force_inline static void gpioc_hilo_oe_xor(uint64_t x) {
149 pico_default_asm_volatile ("mcrr p0, #1, %0, %1, c4" : : "r" (x & 0xffffffffu), "r" (x >> 32));
150}
151
152// Equivalent to these two operations performed on the same cycle:
153// - sio_hw->gpio_oe_set = x & 0xffffffff;
154// - sio_hw->gpio_hi_oe_set = x >> 32;
155__force_inline static void gpioc_hilo_oe_set(uint64_t x) {
156 pico_default_asm_volatile ("mcrr p0, #2, %0, %1, c4" : : "r" (x & 0xffffffffu), "r" (x >> 32));
157}
158
159// Equivalent to these two operations performed on the same cycle:
160// - sio_hw->gpio_oe_clr = x & 0xffffffff;
161// - sio_hw->gpio_hi_oe_clr = x >> 32;
162__force_inline static void gpioc_hilo_oe_clr(uint64_t x) {
163 pico_default_asm_volatile ("mcrr p0, #3, %0, %1, c4" : : "r" (x & 0xffffffffu), "r" (x >> 32));
164}
165
166// ----------------------------------------------------------------------------
167// Single-bit write instructions
168
169// Write a 1-bit value to any output. Equivalent to:
170//
171// if (val)
172// gpioc_hilo_out_set(1ull << pin);
173// else
174// gpioc_hilo_out_clr(1ull << pin);
175__force_inline static void gpioc_bit_out_put(uint pin, bool val) {
176 pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c0" : : "r" (pin), "r" (val));
177}
178
179// Unconditionally toggle any single output. Equivalent to:
180//
181// gpioc_hilo_out_xor(1ull << pin);
182__force_inline static void gpioc_bit_out_xor(uint pin) {
183 pico_default_asm_volatile ("mcr p0, #5, %0, c0, c0" : : "r" (pin));
184}
185
186// Unconditionally set any single output. Equivalent to:
187//
188// gpioc_hilo_out_set(1ull << pin);
189__force_inline static void gpioc_bit_out_set(uint pin) {
190 pico_default_asm_volatile ("mcr p0, #6, %0, c0, c0" : : "r" (pin));
191}
192
193// Unconditionally clear any single output. Equivalent to:
194//
195// gpioc_hilo_out_clr(1ull << pin);
196__force_inline static void gpioc_bit_out_clr(uint pin) {
197 pico_default_asm_volatile ("mcr p0, #7, %0, c0, c0" : : "r" (pin));
198}
199
200// Conditionally toggle any single output. Equivalent to:
201//
202// gpioc_hilo_out_xor((uint64_t)val << pin);
203__force_inline static void gpioc_bit_out_xor2(uint pin, bool val) {
204 pico_default_asm_volatile ("mcrr p0, #5, %0, %1, c0" : : "r" (pin), "r" (val));
205}
206
207// Conditionally set any single output. Equivalent to:
208//
209// gpioc_hilo_out_set((uint64_t)val << pin);
210__force_inline static void gpioc_bit_out_set2(uint pin, bool val) {
211 pico_default_asm_volatile ("mcrr p0, #6, %0, %1, c0" : : "r" (pin), "r" (val));
212}
213
214// Conditionally clear any single output. Equivalent to:
215//
216// gpioc_hilo_out_clr((uint64_t)val << pin);
217__force_inline static void gpioc_bit_out_clr2(uint pin, bool val) {
218 pico_default_asm_volatile ("mcrr p0, #7, %0, %1, c0" : : "r" (pin), "r" (val));
219}
220
221// Write a 1-bit value to any output enable. Equivalent to:
222//
223// if (val)
224// gpioc_hilo_oe_set(1ull << pin);
225// else
226// gpioc_hilo_oe_clr(1ull << pin);
227__force_inline static void gpioc_bit_oe_put(uint pin, bool val) {
228 pico_default_asm_volatile ("mcrr p0, #4, %0, %1, c4" : : "r" (pin), "r" (val));
229}
230
231// Unconditionally toggle any output enable. Equivalent to:
232//
233// gpioc_hilo_oe_xor(1ull << pin);
234__force_inline static void gpioc_bit_oe_xor(uint pin) {
235 pico_default_asm_volatile ("mcr p0, #5, %0, c0, c4" : : "r" (pin));
236}
237
238// Unconditionally set any output enable (set to output). Equivalent to:
239//
240// gpioc_hilo_oe_set(1ull << pin);
241__force_inline static void gpioc_bit_oe_set(uint pin) {
242 pico_default_asm_volatile ("mcr p0, #6, %0, c0, c4" : : "r" (pin));
243}
244
245// Unconditionally clear any output enable (set to input). Equivalent to:
246//
247// gpioc_hilo_oe_clr(1ull << pin);
248__force_inline static void gpioc_bit_oe_clr(uint pin) {
249 pico_default_asm_volatile ("mcr p0, #7, %0, c0, c4" : : "r" (pin));
250}
251
252// Conditionally toggle any output enable. Equivalent to:
253//
254// gpioc_hilo_oe_xor((uint64_t)val << pin);
255__force_inline static void gpioc_bit_oe_xor2(uint pin, bool val) {
256 pico_default_asm_volatile ("mcrr p0, #5, %0, %1, c4" : : "r" (pin), "r" (val));
257}
258
259// Conditionally set any output enable (set to output). Equivalent to:
260//
261// gpioc_hilo_oe_set((uint64_t)val << pin);
262__force_inline static void gpioc_bit_oe_set2(uint pin, bool val) {
263 pico_default_asm_volatile ("mcrr p0, #6, %0, %1, c4" : : "r" (pin), "r" (val));
264}
265
266// Conditionally clear any output enable (set to input). Equivalent to:
267//
268// gpioc_hilo_oe_clr((uint64_t)val << pin);
269__force_inline static void gpioc_bit_oe_clr2(uint pin, bool val) {
270 pico_default_asm_volatile ("mcrr p0, #7, %0, %1, c4" : : "r" (pin), "r" (val));
271}
272
273// ----------------------------------------------------------------------------
274// Indexed mask write instructions -- write to a dynamically selected 32-bit
275// GPIO register
276
277// Write to a selected GPIO output register. Equivalent to:
278//
279// if (reg_index == 0) {
280// gpioc_lo_out_put(val);
281// } else if (reg_index == 1) {
282// gpioc_hi_out_put(val);
283// } else {
284// // undefined
285// }
286__force_inline static void gpioc_index_out_put(uint reg_index, uint32_t val) {
287 pico_default_asm_volatile ("mcrr p0, #8, %1, %0, c0" : : "r" (reg_index), "r" (val));
288}
289
290// Toggle bits in a selected GPIO output register. Equivalent to:
291//
292// if (reg_index == 0) {
293// gpioc_lo_out_xor(val);
294// } else if (reg_index == 1) {
295// gpioc_hi_out_xor(val);
296// } else {
297// // undefined
298// }
299__force_inline static void gpioc_index_out_xor(uint reg_index, uint32_t mask) {
300 pico_default_asm_volatile ("mcrr p0, #9, %1, %0, c0" : : "r" (reg_index), "r" (mask));
301}
302
303// Set bits in a selected GPIO output register. Equivalent to:
304//
305// if (reg_index == 0) {
306// gpioc_lo_out_set(val);
307// } else if (reg_index == 1) {
308// gpioc_hi_out_set(val);
309// } else {
310// // undefined
311// }
312__force_inline static void gpioc_index_out_set(uint reg_index, uint32_t mask) {
313 pico_default_asm_volatile ("mcrr p0, #10, %1, %0, c0" : : "r" (reg_index), "r" (mask));
314}
315
316// Clear bits in a selected GPIO output register. Equivalent to:
317//
318// if (reg_index == 0) {
319// gpioc_lo_out_clr(val);
320// } else if (reg_index == 1) {
321// gpioc_hi_out_clr(val);
322// } else {
323// // undefined
324// }
325__force_inline static void gpioc_index_out_clr(uint reg_index, uint32_t mask) {
326 pico_default_asm_volatile ("mcrr p0, #11, %1, %0, c0" : : "r" (reg_index), "r" (mask));
327}
328
329// Write to a selected GPIO output enable register. Equivalent to:
330//
331// if (reg_index == 0) {
332// gpioc_lo_oe_put(val);
333// } else if (reg_index == 1) {
334// gpioc_hi_oe_put(val);
335// } else {
336// // undefined
337// }
338__force_inline static void gpioc_index_oe_put(uint reg_index, uint32_t val) {
339 pico_default_asm_volatile ("mcrr p0, #8, %1, %0, c4" : : "r" (reg_index), "r" (val));
340}
341
342// Toggle bits in a selected GPIO output enable register. Equivalent to:
343//
344// if (reg_index == 0) {
345// gpioc_lo_oe_xor(val);
346// } else if (reg_index == 1) {
347// gpioc_hi_oe_xor(val);
348// } else {
349// // undefined
350// }
351__force_inline static void gpioc_index_oe_xor(uint reg_index, uint32_t mask) {
352 pico_default_asm_volatile ("mcrr p0, #9, %1, %0, c4" : : "r" (reg_index), "r" (mask));
353}
354
355// Set bits in a selected GPIO output enable register (set to output). Equivalent to:
356//
357// if (reg_index == 0) {
358// gpioc_lo_oe_set(val);
359// } else if (reg_index == 1) {
360// gpioc_hi_oe_set(val);
361// } else {
362// // undefined
363// }
364__force_inline static void gpioc_index_oe_set(uint reg_index, uint32_t mask) {
365 pico_default_asm_volatile ("mcrr p0, #10, %1, %0, c4" : : "r" (reg_index), "r" (mask));
366}
367
368// Clear bits in a selected GPIO output enable register (set to input). Equivalent to:
369//
370// if (reg_index == 0) {
371// gpioc_lo_oe_clr(val);
372// } else if (reg_index == 1) {
373// gpioc_hi_oe_clr(val);
374// } else {
375// // undefined
376// }
377__force_inline static void gpioc_index_oe_clr(uint reg_index, uint32_t mask) {
378 pico_default_asm_volatile ("mcrr p0, #11, %1, %0, c4" : : "r" (reg_index), "r" (mask));
379}
380
381// ----------------------------------------------------------------------------
382// Read instructions
383
384// Read back the lower 32-bit output register. Equivalent to:
385//
386// return sio_hw->gpio_out;
387__force_inline static uint32_t gpioc_lo_out_get(void) {
388 uint32_t lo;
389 pico_default_asm_volatile ("mrc p0, #0, %0, c0, c0" : "=r" (lo));
390 return lo;
391}
392
393// Read back the upper 32-bit output register. Equivalent to:
394//
395// return sio_hw->gpio_hi_out;
396__force_inline static uint32_t gpioc_hi_out_get(void) {
397 uint32_t hi;
398 pico_default_asm_volatile ("mrc p0, #0, %0, c0, c1" : "=r" (hi));
399 return hi;
400}
401
402// Read back two 32-bit output registers in a single operation. Equivalent to:
403//
404// return sio_hw->gpio_out | ((uint64_t)sio_hw->gpio_hi_out << 32);
405__force_inline static uint64_t gpioc_hilo_out_get(void) {
406 uint32_t hi, lo;
407 pico_default_asm_volatile ("mrrc p0, #0, %0, %1, c0" : "=r" (lo), "=r" (hi));
408 return ((uint64_t)hi << 32) | lo;
409}
410
411// Read back the lower 32-bit output enable register. Equivalent to:
412//
413// return sio_hw->gpio_oe;
414__force_inline static uint32_t gpioc_lo_oe_get(void) {
415 uint32_t lo;
416 pico_default_asm_volatile ("mrc p0, #0, %0, c0, c4" : "=r" (lo));
417 return lo;
418}
419
420// Read back the upper 32-bit output enable register. Equivalent to:
421//
422// return sio_hw->gpio_hi_oe;
423__force_inline static uint32_t gpioc_hi_oe_get(void) {
424 uint32_t hi;
425 pico_default_asm_volatile ("mrc p0, #0, %0, c0, c5" : "=r" (hi));
426 return hi;
427}
428
429// Read back two 32-bit output enable registers in a single operation. Equivalent to:
430//
431// return sio_hw->gpio_oe | ((uint64_t)sio_hw->gpio_hi_oe << 32);
432__force_inline static uint64_t gpioc_hilo_oe_get(void) {
433 uint32_t hi, lo;
434 pico_default_asm_volatile ("mrrc p0, #0, %0, %1, c4" : "=r" (lo), "=r" (hi));
435 return ((uint64_t)hi << 32) | lo;
436}
437
438// Sample the lower 32 GPIOs. Equivalent to:
439//
440// return sio_hw->gpio_in;
441__force_inline static uint32_t gpioc_lo_in_get(void) {
442 uint32_t lo;
443 pico_default_asm_volatile ("mrc p0, #0, %0, c0, c8" : "=r" (lo));
444 return lo;
445}
446
447// Sample the upper 32 GPIOs. Equivalent to:
448//
449// return sio_hw->gpio_hi_in;
450__force_inline static uint32_t gpioc_hi_in_get(void) {
451 uint32_t hi;
452 pico_default_asm_volatile ("mrc p0, #0, %0, c0, c9" : "=r" (hi));
453 return hi;
454}
455
456// Sample 64 GPIOs on the same cycle. Equivalent to:
457//
458// return sio_hw->gpio_in | ((uint64_t)sio_hw->gpio_hi_in << 32);
459__force_inline static uint64_t gpioc_hilo_in_get(void) {
460 uint32_t hi, lo;
461 pico_default_asm_volatile ("mrrc p0, #0, %0, %1, c8" : "=r" (lo), "=r" (hi));
462 return ((uint64_t)hi << 32) | lo;
463}
464
465#endif
__force_inline
#define __force_inline
Attribute to force inlining of a function regardless of optimization level.
Definition: compiler.h:125
pico.h