115 lines
4.7 KiB
C
115 lines
4.7 KiB
C
/******************************************************************************
|
|
* File: MCU_PIO_prg.c
|
|
* Component: MCU_PIO
|
|
* Description: Generic PIO driver implementation. Loads PIO programs into
|
|
* instruction memory, calls program-specific init callbacks,
|
|
* claims DMA channels, and provides blocking + async writes.
|
|
*
|
|
* Layer: MCU (hardware abstraction)
|
|
*****************************************************************************/
|
|
|
|
#include "MCU_PIO.h"
|
|
#include "MCU_PIO_priv.h"
|
|
#include "MCU_PIO_cfg.h"
|
|
|
|
#include "hardware/pio.h"
|
|
#include "hardware/dma.h"
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* RUNTIME STATE */
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static MCU_PIO_tstrControl strControl;
|
|
|
|
/* ========================================================================= */
|
|
/* INIT */
|
|
/* ========================================================================= */
|
|
|
|
STD_tenuResult MCU_PIO_enuInit(void)
|
|
{
|
|
STD_tenuResult enuResultLoc = STD_OK;
|
|
u8 u8IndexLoc;
|
|
|
|
for (u8IndexLoc = 0U; u8IndexLoc < (u8)MCU_PIO_NUM_INSTANCES; u8IndexLoc++)
|
|
{
|
|
const MCU_PIO_tstrConfig *pstrCfgLoc = &MCU_PIO_astrConfig[u8IndexLoc];
|
|
|
|
/* Load the PIO program into instruction memory */
|
|
u32 u32OffsetLoc = (u32)pio_add_program(pstrCfgLoc->pstrPio,
|
|
pstrCfgLoc->pstrProgram);
|
|
|
|
/* Call the program-specific init callback to configure the SM */
|
|
pstrCfgLoc->pfProgramInit(pstrCfgLoc->pstrPio,
|
|
pstrCfgLoc->u8Sm,
|
|
pstrCfgLoc->u8Pin,
|
|
u32OffsetLoc);
|
|
|
|
/* Claim a DMA channel for async FIFO writes. Reserved for the
|
|
* lifetime of the application — never released. true = panic
|
|
* if no channels available (misconfiguration, not a runtime error). */
|
|
strControl.as8DmaChannel[u8IndexLoc] = (s8)dma_claim_unused_channel(true);
|
|
}
|
|
|
|
return enuResultLoc;
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
/* PUT BLOCKING (SINGLE WORD) */
|
|
/* ========================================================================= */
|
|
|
|
void MCU_PIO_vPutBlocking(u8 u8Instance, u32 u32Data)
|
|
{
|
|
const MCU_PIO_tstrConfig *pstrCfgLoc = &MCU_PIO_astrConfig[u8Instance];
|
|
|
|
/* Blocks until the TX FIFO has space, then writes the 32-bit word */
|
|
pio_sm_put_blocking(pstrCfgLoc->pstrPio, pstrCfgLoc->u8Sm, u32Data);
|
|
}
|
|
|
|
/* ========================================================================= */
|
|
/* PUT BUFFER ASYNC (DMA, NON-BLOCKING) */
|
|
/* ========================================================================= */
|
|
|
|
STD_tenuResult MCU_PIO_enuPutBufferAsync(u8 u8Instance, const u32 *pu32Data, u16 u16Count)
|
|
{
|
|
STD_tenuResult enuResultLoc = STD_OK;
|
|
|
|
if (pu32Data == STD_NULL)
|
|
{
|
|
enuResultLoc = STD_NULL_POINTER_ERROR;
|
|
}
|
|
else
|
|
{
|
|
const MCU_PIO_tstrConfig *pstrCfgLoc = &MCU_PIO_astrConfig[u8Instance];
|
|
s8 s8ChLoc = strControl.as8DmaChannel[u8Instance];
|
|
|
|
dma_channel_config strCfgLoc = dma_channel_get_default_config((u32)s8ChLoc);
|
|
|
|
/* 32-bit transfers — matches the PIO FIFO word size */
|
|
channel_config_set_transfer_data_size(&strCfgLoc, DMA_SIZE_32);
|
|
|
|
/* Source: increment through the caller's buffer */
|
|
channel_config_set_read_increment(&strCfgLoc, true);
|
|
|
|
/* Destination: PIO TX FIFO register (fixed address) */
|
|
channel_config_set_write_increment(&strCfgLoc, false);
|
|
|
|
/* Pace by PIO TX FIFO DREQ — DMA only pushes when SM can accept */
|
|
channel_config_set_dreq(&strCfgLoc, pio_get_dreq(pstrCfgLoc->pstrPio,
|
|
pstrCfgLoc->u8Sm,
|
|
true));
|
|
|
|
/* Start the DMA transfer. Runs autonomously until u16Count words
|
|
* have been pushed into the FIFO. Caller must keep pu32Data valid
|
|
* until transfer completes. */
|
|
dma_channel_configure(
|
|
(u32)s8ChLoc,
|
|
&strCfgLoc,
|
|
&pstrCfgLoc->pstrPio->txf[pstrCfgLoc->u8Sm], /* dest: PIO TX FIFO */
|
|
pu32Data, /* source: buffer */
|
|
u16Count, /* word count */
|
|
true /* start immediately */
|
|
);
|
|
}
|
|
|
|
return enuResultLoc;
|
|
} |