RP2040 + RP2350 HAL: support for PIO units

ChibiOS public support forum for topics related to the Raspberry Pi RP2040 and RP2350 family of micro-controllers.

Moderator: emulator

electronic_eel
Posts: 95
Joined: Sat Mar 19, 2016 8:07 pm
Has thanked: 8 times
Been thanked: 23 times

Re: RP2040 + RP2350 HAL: support for PIO units

Post by electronic_eel »

So as the next step I started writing defines and helper macros in CMSIS style for the PIO assembler instructions. I have currently done this for JMP and WAIT, just to give a feel for how this would look like before investing the time to do this for all instructions.

Here is what I came up with:

Code: Select all

--- a/os/hal/ports/RP/LLD/PIOv1/rp_pio.h
+++ b/os/hal/ports/RP/LLD/PIOv1/rp_pio.h
@@ -173,6 +173,72 @@
 #define PIO_IRQ_SM(n)                   (1U << ((n) + 8U))
 /** @} */
 
+/**
+ * @brief   Do not assume a full Pico SDK is present
+ *
+ * Header files generated by pioasm check this define
+ */
+#ifndef PICO_NO_HARDWARE
+#define PICO_NO_HARDWARE 1
+#endif
+/** @} */
+
+/**
+ * @brief   PIO assembler instruction definitions
+ */
+
+#define PIO_ASM_INSTRUCTION_Pos         13U
+#define PIO_ASM_INSTRUCTION_Msk         (0x07U << PIO_ASM_INSTRUCTION_Pos)
+#define PIO_ASM_DELAY_SIDESET_Pos       8U
+#define PIO_ASM_DELAY_SIDESET_Msk       (0x1FU << PIO_ASM_DELAY_SIDESET_Pos)
+
+#define PIO_ASM_INSTR_JMP               (0U << PIO_ASM_INSTRUCTION_Pos)
+#define PIO_ASM_JMP_CONDITION_Pos       5U
+#define PIO_ASM_JMP_CONDITION_NONE      (0U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_NOT_X     (1U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_X_DEC     (2U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_NOT_Y     (3U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_Y_DEC     (4U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_X_NE_Y    (5U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_PIN       (6U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_CONDITION_OSRE      (7U << PIO_ASM_JMP_CONDITION_Pos)
+#define PIO_ASM_JMP_DST_Pos             0U
+#define PIO_ASM_JMP_DST_Msk             (0x1FU << PIO_ASM_JMP_DST_Pos)
+
+#define PIO_ASM_INSTR_WAIT              (1U << PIO_ASM_INSTRUCTION_Pos)
+#define PIO_ASM_WAIT_POLARITY           (1U << 7U)
+#define PIO_ASM_WAIT_SRC_Pos            5U
+#define PIO_ASM_WAIT_SRC_GPIO           (0U << PIO_ASM_WAIT_SRC_Pos)
+#define PIO_ASM_WAIT_SRC_PIN            (1U << PIO_ASM_WAIT_SRC_Pos)
+#define PIO_ASM_WAIT_SRC_IRQ            (2U << PIO_ASM_WAIT_SRC_Pos)
+#define PIO_ASM_WAIT_SRC_JMPPIN         (3U << PIO_ASM_WAIT_SRC_Pos)
+#define PIO_ASM_WAIT_INDEX_Pos          0U
+#define PIO_ASM_WAIT_INDEX_Msk          (0x1FU << PIO_ASM_WAIT_INDEX_Pos)
+
+// TODO: continue for the other instructions
+
+/** @} */
+
+/**
+ * @brief   PIO assembler instruction helpers
+ */
+#define PIO_ASM_JMP(delay_sideset, condition, destination) \
+       (PIO_ASM_INSTR_JMP | \
+        ((delay_sideset) << PIO_ASM_DELAY_SIDESET_Pos) | \
+        (condition) | (destination))
+
+#define PIO_ASM_WAIT(delay_sideset, polarity, source, index) \
+       (PIO_ASM_INSTR_WAIT | \
+        ((delay_sideset) << PIO_ASM_DELAY_SIDESET_Pos) | \
+        (polarity) | (source) | (index))
+
+
+// TODO: continue for the other instructions
+
+/** @} */
+
This would be used like this:

Code: Select all

    // always jump to offset zero
    pioSmExecX(sm_ptr, PIO_ASM_JMP(0, PIO_ASM_JMP_CONDITION_NONE, 0));
What do you think about this? Should I continue it this way or do you suggest some changes or a completely different approach?
Post Reply