/****************************************************************************** * File: MCU_PIO.h * Component: MCU_PIO * Description: Public interface for the generic PIO driver component. * Abstracts the RP2040's Programmable I/O hardware — loading * PIO programs into instruction memory, configuring state * machines, and pushing data through the TX FIFO. * * The driver is program-agnostic: each config entry holds a * pointer to a compiled PIO program and a function pointer * for the program-specific state machine init. WS2812 is one * such program; future PIO uses (custom protocols, etc.) * plug in the same way with zero driver code changes. * * Layer: MCU (hardware abstraction) *****************************************************************************/ #ifndef MCU_PIO_H #define MCU_PIO_H #include "STD_TYPES.h" #include "hardware/pio.h" /* ------------------------------------------------------------------------ */ /* PROGRAM INIT FUNCTION POINTER TYPE */ /* ------------------------------------------------------------------------ */ /** * @brief Callback type for program-specific state machine configuration. * * Each PIO program has its own pin mapping, shift config, clock divider, * etc. The generic MCU_PIO driver calls this function after loading the * program into instruction memory. The function must fully configure and * enable the state machine. * * @param pstrPio PIO instance (pio0 or pio1). * @param u8Sm State machine index (0-3) within that PIO instance. * @param u8Pin GPIO pin from the config struct. * @param u32Offset Instruction memory offset where the program was loaded. */ typedef void (*MCU_PIO_tpfProgramInit)(PIO pstrPio, u8 u8Sm, u8 u8Pin, u32 u32Offset); /* ------------------------------------------------------------------------ */ /* CONFIGURATION STRUCTURE */ /* ------------------------------------------------------------------------ */ /** * @brief Per-instance PIO configuration. * * One entry per PIO program/state-machine pair, stored in * MCU_PIO_astrConfig[]. The array index is used as the instance * parameter in all public API calls. */ typedef struct { PIO pstrPio; /**< PIO block: pio0 or pio1 */ u8 u8Sm; /**< State machine index (0-3) */ u8 u8Pin; /**< GPIO pin used by this program */ const pio_program_t *pstrProgram; /**< Pointer to compiled PIO program */ MCU_PIO_tpfProgramInit pfProgramInit; /**< Program-specific SM config callback */ } MCU_PIO_tstrConfig; /* ------------------------------------------------------------------------ */ /* PUBLIC API */ /* ------------------------------------------------------------------------ */ /** * @brief Initialize all configured PIO instances. * * For each config entry: loads the PIO program into the instruction * memory of the selected PIO block, then calls the program-specific * init callback to configure the state machine (pins, shift, clock). * * SYS_ECU calls this once during the init sequence. * * @return STD_OK on success, STD_NOK if any instance fails. */ STD_tenuResult MCU_PIO_enuInit(void); /** * @brief Push a 32-bit word into a PIO state machine's TX FIFO (blocking). * * Blocks until the FIFO has space, then writes the data. For WS2812, * each call sends one pixel (24-bit GRB left-justified in the 32-bit word). * * @param u8Instance Config array index (MCU_PIO_tenuInstance). * @param u32Data The 32-bit value to push. */ void MCU_PIO_vPutBlocking(u8 u8Instance, u32 u32Data); /** * @brief Push a buffer of 32-bit words to the TX FIFO via DMA (non-blocking). * * Starts a DMA transfer from pu32Data into the PIO TX FIFO. Returns * immediately. The DMA channel was pre-claimed during Init. * * The caller MUST keep pu32Data valid until the transfer completes. * * @param u8Instance Config array index. * @param pu32Data Pointer to array of 32-bit words. Must not be NULL. * @param u16Count Number of 32-bit words to transfer. * @return STD_OK transfer started, * STD_NULL_POINTER_ERROR if pu32Data is NULL. */ STD_tenuResult MCU_PIO_enuPutBufferAsync(u8 u8Instance, const u32 *pu32Data, u16 u16Count); #endif /* MCU_PIO_H */