1 /*
2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef _HARDWARE_PIO_INSTRUCTIONS_H
8 #define _HARDWARE_PIO_INSTRUCTIONS_H
9
10 #include "pico.h"
11
12 /** \brief PIO instruction encoding
13 * \defgroup pio_instructions pio_instructions
14 * \ingroup hardware_pio
15 *
16 * Functions for generating PIO instruction encodings programmatically. In debug builds
17 *`PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS` can be set to 1 to enable validation of encoding function
18 * parameters.
19 *
20 * For fuller descriptions of the instructions in question see the "RP2040 Datasheet"
21 */
22
23 // PICO_CONFIG: PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS, Enable/disable assertions in the PIO instructions, type=bool, default=0, group=pio_instructions
24 #ifndef PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS
25 #define PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS 0
26 #endif
27
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31
32 enum pio_instr_bits {
33 pio_instr_bits_jmp = 0x0000,
34 pio_instr_bits_wait = 0x2000,
35 pio_instr_bits_in = 0x4000,
36 pio_instr_bits_out = 0x6000,
37 pio_instr_bits_push = 0x8000,
38 pio_instr_bits_pull = 0x8080,
39 pio_instr_bits_mov = 0xa000,
40 pio_instr_bits_irq = 0xc000,
41 pio_instr_bits_set = 0xe000,
42 };
43
44 #ifndef NDEBUG
45 #define _PIO_INVALID_IN_SRC 0x08u
46 #define _PIO_INVALID_OUT_DEST 0x10u
47 #define _PIO_INVALID_SET_DEST 0x20u
48 #define _PIO_INVALID_MOV_SRC 0x40u
49 #define _PIO_INVALID_MOV_DEST 0x80u
50 #else
51 #define _PIO_INVALID_IN_SRC 0u
52 #define _PIO_INVALID_OUT_DEST 0u
53 #define _PIO_INVALID_SET_DEST 0u
54 #define _PIO_INVALID_MOV_SRC 0u
55 #define _PIO_INVALID_MOV_DEST 0u
56 #endif
57
58 /*! \brief Enumeration of values to pass for source/destination args for instruction encoding functions
59 * \ingroup pio_instructions
60 *
61 * \note Not all values are suitable for all functions. Validity is only checked in debug mode when
62 * `PARAM_ASSERTIONS_ENABLED_PIO_INSTRUCTIONS` is 1
63 */
64 enum pio_src_dest {
65 pio_pins = 0u,
66 pio_x = 1u,
67 pio_y = 2u,
68 pio_null = 3u | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
69 pio_pindirs = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
70 pio_exec_mov = 4u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
71 pio_status = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_DEST,
72 pio_pc = 5u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC,
73 pio_isr = 6u | _PIO_INVALID_SET_DEST,
74 pio_osr = 7u | _PIO_INVALID_OUT_DEST | _PIO_INVALID_SET_DEST,
75 pio_exec_out = 7u | _PIO_INVALID_IN_SRC | _PIO_INVALID_SET_DEST | _PIO_INVALID_MOV_SRC | _PIO_INVALID_MOV_DEST,
76 };
77
_pio_major_instr_bits(uint instr)78 static inline uint _pio_major_instr_bits(uint instr) {
79 return instr & 0xe000u;
80 }
81
_pio_encode_instr_and_args(enum pio_instr_bits instr_bits,uint arg1,uint arg2)82 static inline uint _pio_encode_instr_and_args(enum pio_instr_bits instr_bits, uint arg1, uint arg2) {
83 valid_params_if(PIO_INSTRUCTIONS, arg1 <= 0x7);
84 #if PARAM_ASSERTIONS_ENABLED(PIO_INSTRUCTIONS)
85 uint32_t major = _pio_major_instr_bits(instr_bits);
86 if (major == pio_instr_bits_in || major == pio_instr_bits_out) {
87 assert(arg2 && arg2 <= 32);
88 } else {
89 assert(arg2 <= 31);
90 }
91 #endif
92 return instr_bits | (arg1 << 5u) | (arg2 & 0x1fu);
93 }
94
_pio_encode_instr_and_src_dest(enum pio_instr_bits instr_bits,enum pio_src_dest dest,uint value)95 static inline uint _pio_encode_instr_and_src_dest(enum pio_instr_bits instr_bits, enum pio_src_dest dest, uint value) {
96 return _pio_encode_instr_and_args(instr_bits, dest & 7u, value);
97 }
98
99 /*! \brief Encode just the delay slot bits of an instruction
100 * \ingroup pio_instructions
101 *
102 * \note This function does not return a valid instruction encoding; instead it returns an encoding of the delay
103 * slot suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when
104 * combining the results of this function with the results of \ref pio_encode_sideset and \ref pio_encode_sideset_opt
105 * as they share the same bits within the instruction encoding.
106 *
107 * \param cycles the number of cycles 0-31 (or less if side set is being used)
108 * \return the delay slot bits to be ORed with an instruction encoding
109 */
pio_encode_delay(uint cycles)110 static inline uint pio_encode_delay(uint cycles) {
111 // note that the maximum cycles will be smaller if sideset_bit_count > 0
112 valid_params_if(PIO_INSTRUCTIONS, cycles <= 0x1f);
113 return cycles << 8u;
114 }
115
116 /*! \brief Encode just the side set bits of an instruction (in non optional side set mode)
117 * \ingroup pio_instructions
118 *
119 * \note This function does not return a valid instruction encoding; instead it returns an encoding of the side set bits
120 * suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when
121 * combining the results of this function with the results of \ref pio_encode_delay as they share the same bits
122 * within the instruction encoding.
123 *
124 * \param sideset_bit_count number of side set bits as would be specified via `.sideset` in pioasm
125 * \param value the value to sideset on the pins
126 * \return the side set bits to be ORed with an instruction encoding
127 */
pio_encode_sideset(uint sideset_bit_count,uint value)128 static inline uint pio_encode_sideset(uint sideset_bit_count, uint value) {
129 valid_params_if(PIO_INSTRUCTIONS, sideset_bit_count >= 1 && sideset_bit_count <= 5);
130 valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1));
131 return value << (13u - sideset_bit_count);
132 }
133
134 /*! \brief Encode just the side set bits of an instruction (in optional -`opt` side set mode)
135 * \ingroup pio_instructions
136 *
137 * \note This function does not return a valid instruction encoding; instead it returns an encoding of the side set bits
138 * suitable for `OR`ing with the result of an encoding function for an actual instruction. Care should be taken when
139 * combining the results of this function with the results of \ref pio_encode_delay as they share the same bits
140 * within the instruction encoding.
141 *
142 * \param sideset_bit_count number of side set bits as would be specified via `.sideset <n> opt` in pioasm
143 * \param value the value to sideset on the pins
144 * \return the side set bits to be ORed with an instruction encoding
145 */
pio_encode_sideset_opt(uint sideset_bit_count,uint value)146 static inline uint pio_encode_sideset_opt(uint sideset_bit_count, uint value) {
147 valid_params_if(PIO_INSTRUCTIONS, sideset_bit_count >= 1 && sideset_bit_count <= 4);
148 valid_params_if(PIO_INSTRUCTIONS, value <= ((1u << sideset_bit_count) - 1));
149 return 0x1000u | value << (12u - sideset_bit_count);
150 }
151
152 /*! \brief Encode an unconditional JMP instruction
153 * \ingroup pio_instructions
154 *
155 * This is the equivalent of `JMP <addr>`
156 *
157 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
158 * \return The instruction encoding with 0 delay and no side set value
159 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
160 */
pio_encode_jmp(uint addr)161 static inline uint pio_encode_jmp(uint addr) {
162 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 0, addr);
163 }
164
165 /*! \brief Encode a conditional JMP if scratch X zero instruction
166 * \ingroup pio_instructions
167 *
168 * This is the equivalent of `JMP !X <addr>`
169 *
170 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
171 * \return The instruction encoding with 0 delay and no side set value
172 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
173 */
pio_encode_jmp_not_x(uint addr)174 static inline uint pio_encode_jmp_not_x(uint addr) {
175 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 1, addr);
176 }
177
178 /*! \brief Encode a conditional JMP if scratch X non-zero (and post-decrement X) instruction
179 * \ingroup pio_instructions
180 *
181 * This is the equivalent of `JMP X-- <addr>`
182 *
183 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
184 * \return The instruction encoding with 0 delay and no side set value
185 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
186 */
pio_encode_jmp_x_dec(uint addr)187 static inline uint pio_encode_jmp_x_dec(uint addr) {
188 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 2, addr);
189 }
190
191 /*! \brief Encode a conditional JMP if scratch Y zero instruction
192 * \ingroup pio_instructions
193 *
194 * This is the equivalent of `JMP !Y <addr>`
195 *
196 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
197 * \return The instruction encoding with 0 delay and no side set value
198 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
199 */
pio_encode_jmp_not_y(uint addr)200 static inline uint pio_encode_jmp_not_y(uint addr) {
201 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 3, addr);
202 }
203
204 /*! \brief Encode a conditional JMP if scratch Y non-zero (and post-decrement Y) instruction
205 * \ingroup pio_instructions
206 *
207 * This is the equivalent of `JMP Y-- <addr>`
208 *
209 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
210 * \return The instruction encoding with 0 delay and no side set value
211 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
212 */
pio_encode_jmp_y_dec(uint addr)213 static inline uint pio_encode_jmp_y_dec(uint addr) {
214 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 4, addr);
215 }
216
217 /*! \brief Encode a conditional JMP if scratch X not equal scratch Y instruction
218 * \ingroup pio_instructions
219 *
220 * This is the equivalent of `JMP X!=Y <addr>`
221 *
222 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
223 * \return The instruction encoding with 0 delay and no side set value
224 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
225 */
pio_encode_jmp_x_ne_y(uint addr)226 static inline uint pio_encode_jmp_x_ne_y(uint addr) {
227 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 5, addr);
228 }
229
230 /*! \brief Encode a conditional JMP if input pin high instruction
231 * \ingroup pio_instructions
232 *
233 * This is the equivalent of `JMP PIN <addr>`
234 *
235 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
236 * \return The instruction encoding with 0 delay and no side set value
237 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
238 */
pio_encode_jmp_pin(uint addr)239 static inline uint pio_encode_jmp_pin(uint addr) {
240 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 6, addr);
241 }
242
243 /*! \brief Encode a conditional JMP if output shift register not empty instruction
244 * \ingroup pio_instructions
245 *
246 * This is the equivalent of `JMP !OSRE <addr>`
247 *
248 * \param addr The target address 0-31 (an absolute address within the PIO instruction memory)
249 * \return The instruction encoding with 0 delay and no side set value
250 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
251 */
pio_encode_jmp_not_osre(uint addr)252 static inline uint pio_encode_jmp_not_osre(uint addr) {
253 return _pio_encode_instr_and_args(pio_instr_bits_jmp, 7, addr);
254 }
255
_pio_encode_irq(bool relative,uint irq)256 static inline uint _pio_encode_irq(bool relative, uint irq) {
257 valid_params_if(PIO_INSTRUCTIONS, irq <= 7);
258 return (relative ? 0x10u : 0x0u) | irq;
259 }
260
261 /*! \brief Encode a WAIT for GPIO pin instruction
262 * \ingroup pio_instructions
263 *
264 * This is the equivalent of `WAIT <polarity> GPIO <gpio>`
265 *
266 * \param polarity true for `WAIT 1`, false for `WAIT 0`
267 * \param gpio The real GPIO number 0-31
268 * \return The instruction encoding with 0 delay and no side set value
269 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
270 */
pio_encode_wait_gpio(bool polarity,uint gpio)271 static inline uint pio_encode_wait_gpio(bool polarity, uint gpio) {
272 return _pio_encode_instr_and_args(pio_instr_bits_wait, 0u | (polarity ? 4u : 0u), gpio);
273 }
274
275 /*! \brief Encode a WAIT for pin instruction
276 * \ingroup pio_instructions
277 *
278 * This is the equivalent of `WAIT <polarity> PIN <pin>`
279 *
280 * \param polarity true for `WAIT 1`, false for `WAIT 0`
281 * \param pin The pin number 0-31 relative to the executing SM's input pin mapping
282 * \return The instruction encoding with 0 delay and no side set value
283 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
284 */
pio_encode_wait_pin(bool polarity,uint pin)285 static inline uint pio_encode_wait_pin(bool polarity, uint pin) {
286 return _pio_encode_instr_and_args(pio_instr_bits_wait, 1u | (polarity ? 4u : 0u), pin);
287 }
288
289 /*! \brief Encode a WAIT for IRQ instruction
290 * \ingroup pio_instructions
291 *
292 * This is the equivalent of `WAIT <polarity> IRQ <irq> <relative>`
293 *
294 * \param polarity true for `WAIT 1`, false for `WAIT 0`
295 * \param relative true for a `WAIT IRQ <irq> REL`, false for regular `WAIT IRQ <irq>`
296 * \param irq the irq number 0-7
297 * \return The instruction encoding with 0 delay and no side set value
298 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
299 */
pio_encode_wait_irq(bool polarity,bool relative,uint irq)300 static inline uint pio_encode_wait_irq(bool polarity, bool relative, uint irq) {
301 valid_params_if(PIO_INSTRUCTIONS, irq <= 7);
302 return _pio_encode_instr_and_args(pio_instr_bits_wait, 2u | (polarity ? 4u : 0u), _pio_encode_irq(relative, irq));
303 }
304
305 /*! \brief Encode an IN instruction
306 * \ingroup pio_instructions
307 *
308 * This is the equivalent of `IN <src>, <count>`
309 *
310 * \param src The source to take data from
311 * \param count The number of bits 1-32
312 * \return The instruction encoding with 0 delay and no side set value
313 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
314 */
pio_encode_in(enum pio_src_dest src,uint count)315 static inline uint pio_encode_in(enum pio_src_dest src, uint count) {
316 valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_IN_SRC));
317 return _pio_encode_instr_and_src_dest(pio_instr_bits_in, src, count);
318 }
319
320 /*! \brief Encode an OUT instruction
321 * \ingroup pio_instructions
322 *
323 * This is the equivalent of `OUT <src>, <count>`
324 *
325 * \param dest The destination to write data to
326 * \param count The number of bits 1-32
327 * \return The instruction encoding with 0 delay and no side set value
328 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
329 */
pio_encode_out(enum pio_src_dest dest,uint count)330 static inline uint pio_encode_out(enum pio_src_dest dest, uint count) {
331 valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_OUT_DEST));
332 return _pio_encode_instr_and_src_dest(pio_instr_bits_out, dest, count);
333 }
334
335 /*! \brief Encode a PUSH instruction
336 * \ingroup pio_instructions
337 *
338 * This is the equivalent of `PUSH <if_full>, <block>`
339 *
340 * \param if_full true for `PUSH IF_FULL ...`, false for `PUSH ...`
341 * \param block true for `PUSH ... BLOCK`, false for `PUSH ...`
342 * \return The instruction encoding with 0 delay and no side set value
343 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
344 */
pio_encode_push(bool if_full,bool block)345 static inline uint pio_encode_push(bool if_full, bool block) {
346 return _pio_encode_instr_and_args(pio_instr_bits_push, (if_full ? 2u : 0u) | (block ? 1u : 0u), 0);
347 }
348
349 /*! \brief Encode a PULL instruction
350 * \ingroup pio_instructions
351 *
352 * This is the equivalent of `PULL <if_empty>, <block>`
353 *
354 * \param if_empty true for `PULL IF_EMPTY ...`, false for `PULL ...`
355 * \param block true for `PULL ... BLOCK`, false for `PULL ...`
356 * \return The instruction encoding with 0 delay and no side set value
357 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
358 */
pio_encode_pull(bool if_empty,bool block)359 static inline uint pio_encode_pull(bool if_empty, bool block) {
360 return _pio_encode_instr_and_args(pio_instr_bits_pull, (if_empty ? 2u : 0u) | (block ? 1u : 0u), 0);
361 }
362
363 /*! \brief Encode a MOV instruction
364 * \ingroup pio_instructions
365 *
366 * This is the equivalent of `MOV <dest>, <src>`
367 *
368 * \param dest The destination to write data to
369 * \param src The source to take data from
370 * \return The instruction encoding with 0 delay and no side set value
371 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
372 */
pio_encode_mov(enum pio_src_dest dest,enum pio_src_dest src)373 static inline uint pio_encode_mov(enum pio_src_dest dest, enum pio_src_dest src) {
374 valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
375 valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
376 return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, src & 7u);
377 }
378
379 /*! \brief Encode a MOV instruction with bit invert
380 * \ingroup pio_instructions
381 *
382 * This is the equivalent of `MOV <dest>, ~<src>`
383 *
384 * \param dest The destination to write inverted data to
385 * \param src The source to take data from
386 * \return The instruction encoding with 0 delay and no side set value
387 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
388 */
pio_encode_mov_not(enum pio_src_dest dest,enum pio_src_dest src)389 static inline uint pio_encode_mov_not(enum pio_src_dest dest, enum pio_src_dest src) {
390 valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
391 valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
392 return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, (1u << 3u) | (src & 7u));
393 }
394
395 /*! \brief Encode a MOV instruction with bit reverse
396 * \ingroup pio_instructions
397 *
398 * This is the equivalent of `MOV <dest>, ::<src>`
399 *
400 * \param dest The destination to write bit reversed data to
401 * \param src The source to take data from
402 * \return The instruction encoding with 0 delay and no side set value
403 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
404 */
pio_encode_mov_reverse(enum pio_src_dest dest,enum pio_src_dest src)405 static inline uint pio_encode_mov_reverse(enum pio_src_dest dest, enum pio_src_dest src) {
406 valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_MOV_DEST));
407 valid_params_if(PIO_INSTRUCTIONS, !(src & _PIO_INVALID_MOV_SRC));
408 return _pio_encode_instr_and_src_dest(pio_instr_bits_mov, dest, (2u << 3u) | (src & 7u));
409 }
410
411 /*! \brief Encode a IRQ SET instruction
412 * \ingroup pio_instructions
413 *
414 * This is the equivalent of `IRQ SET <irq> <relative>`
415 *
416 * \param relative true for a `IRQ SET <irq> REL`, false for regular `IRQ SET <irq>`
417 * \param irq the irq number 0-7
418 * \return The instruction encoding with 0 delay and no side set value
419 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
420 */
pio_encode_irq_set(bool relative,uint irq)421 static inline uint pio_encode_irq_set(bool relative, uint irq) {
422 return _pio_encode_instr_and_args(pio_instr_bits_irq, 0, _pio_encode_irq(relative, irq));
423 }
424
425 /*! \brief Encode a IRQ WAIT instruction
426 * \ingroup pio_instructions
427 *
428 * This is the equivalent of `IRQ WAIT <irq> <relative>`
429 *
430 * \param relative true for a `IRQ WAIT <irq> REL`, false for regular `IRQ WAIT <irq>`
431 * \param irq the irq number 0-7
432 * \return The instruction encoding with 0 delay and no side set value
433 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
434 */
pio_encode_irq_wait(bool relative,uint irq)435 static inline uint pio_encode_irq_wait(bool relative, uint irq) {
436 return _pio_encode_instr_and_args(pio_instr_bits_irq, 1, _pio_encode_irq(relative, irq));
437 }
438
439 /*! \brief Encode a IRQ CLEAR instruction
440 * \ingroup pio_instructions
441 *
442 * This is the equivalent of `IRQ CLEAR <irq> <relative>`
443 *
444 * \param relative true for a `IRQ CLEAR <irq> REL`, false for regular `IRQ CLEAR <irq>`
445 * \param irq the irq number 0-7
446 * \return The instruction encoding with 0 delay and no side set value
447 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
448 */
pio_encode_irq_clear(bool relative,uint irq)449 static inline uint pio_encode_irq_clear(bool relative, uint irq) {
450 return _pio_encode_instr_and_args(pio_instr_bits_irq, 2, _pio_encode_irq(relative, irq));
451 }
452
453 /*! \brief Encode a SET instruction
454 * \ingroup pio_instructions
455 *
456 * This is the equivalent of `SET <dest>, <value>`
457 *
458 * \param dest The destination to apply the value to
459 * \param value The value 0-31
460 * \return The instruction encoding with 0 delay and no side set value
461 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
462 */
pio_encode_set(enum pio_src_dest dest,uint value)463 static inline uint pio_encode_set(enum pio_src_dest dest, uint value) {
464 valid_params_if(PIO_INSTRUCTIONS, !(dest & _PIO_INVALID_SET_DEST));
465 return _pio_encode_instr_and_src_dest(pio_instr_bits_set, dest, value);
466 }
467
468 /*! \brief Encode a NOP instruction
469 * \ingroup pio_instructions
470 *
471 * This is the equivalent of `NOP` which is itself encoded as `MOV y, y`
472 *
473 * \return The instruction encoding with 0 delay and no side set value
474 * \see pio_encode_delay, pio_encode_sideset, pio_encode_sideset_opt
475 */
pio_encode_nop(void)476 static inline uint pio_encode_nop(void) {
477 return pio_encode_mov(pio_y, pio_y);
478 }
479
480 #ifdef __cplusplus
481 }
482 #endif
483
484 #endif
485