#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
#include "app.h"
#include "fsl_flexio_spi_edma.h"
#include "board.h"
//#include "app.h"
#include "fsl_debug_console.h"
void BOARD_InitHardware(void);
#include "fsl_debug_console.h"
#include "fsl_flexio.h"
#include "fsl_edma.h"
#include "fsl_inputmux.h"
#include "fsl_common.h"
/* 硬件常数定义 */
#define DEMO_FLEXIO_BASE FLEXIO0
#define DEMO_DMA_BASE DMA0
#define DEMO_DMA_CH 0 /* 使用 DMA 通道 61 */
#define CHANNEL_COUNT 20 /* 20路并行引脚 */
#define BIT_DEPTH 24 /* 24位深度 */
#define SHIFTERS_USED 8 /* 每次 DMA 填充 8 个 Shifter */
/* 数据缓冲区:必须对齐以优化 DMA 性能 */
SDK_ALIGN(uint32_t g_dac_buffer[BIT_DEPTH], 32);
edma_handle_t g_edma_handle;
volatile bool g_transfer_done = false;
/* DMA 完成回调 */
void EDMA_Callback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds)
{
if (transferDone)
{
/* 确保 FlexIO 最后一组数据已从移位寄存器彻底发出 */
while (!(FLEXIO_GetShifterStatusFlags(DEMO_FLEXIO_BASE) & 0x01U));
/* 立即关闭 DMA 请求,防止产生虚假触发 */
FLEXIO_EnableShifterStatusDMA(DEMO_FLEXIO_BASE, 1 << 0, false);
g_transfer_done = true;
}
}
void Init_FlexIO_DAC(void)
{
flexio_config_t fxioConfig;
flexio_shifter_config_t shConfig = {0};
flexio_timer_config_t timConfig = {0};
FLEXIO_GetDefaultConfig(&fxioConfig);
FLEXIO_Init(DEMO_FLEXIO_BASE, &fxioConfig);
FLEXIO_Reset(DEMO_FLEXIO_BASE);
/* 配置 8 个 Shifter 并行输出 */
for (uint8_t i = 0; i < SHIFTERS_USED; i++)
{
shConfig.timerSelect = 0;
shConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
shConfig.pinConfig = kFLEXIO_PinConfigOutput;
shConfig.pinSelect = 0; /* 引脚从 D0 开始 */
shConfig.pinPolarity = kFLEXIO_PinActiveHigh;
shConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
shConfig.inputSource = kFLEXIO_ShifterInputFromPin;
shConfig.shifterStop = kFLEXIO_ShifterStopBitDisable;
shConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
shConfig.parallelWidth = CHANNEL_COUNT - 1U; /* 20路并行宽度 */
FLEXIO_SetShifterConfig(DEMO_FLEXIO_BASE, i, &shConfig);
}
/* 配置 Timer 0 作为 SCLK 时钟源 */
timConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0);
timConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
timConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
timConfig.pinConfig = kFLEXIO_PinConfigOutput;
timConfig.pinSelect = 20; /* 时钟信号输出在 D20 */
timConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
timConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
timConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
/* 8个位 = 16个边沿 (15), 频率分频 = 10 */
timConfig.timerCompare = (15U << 8U) | 10U;
FLEXIO_SetTimerConfig(DEMO_FLEXIO_BASE, 0, &timConfig);
}
void Init_DMA_DAC(void)
{
edma_config_t edmaConfig;
/* 修正后的 MCXN947 InputMux 连接 */
/* 如果 kINPUTMUX_Flexio0Shift0ToDma0Ch61Ena 依然报错,
请尝试 kINPUTMUX_Flexio0Request0ToDma0Ch61Ena */
INPUTMUX_Init(INPUTMUX0);
//INPUTMUX_EnableSignal(INPUTMUX0, kINPUTMUX_Flexio0Shift0ToDma0Ch61Ena, true);
INPUTMUX_EnableSignal(INPUTMUX0, kINPUTMUX_FlexIO0ShiftRegister0RequestToDma0Ch61Ena, true);
EDMA_GetDefaultConfig(&edmaConfig);
EDMA_Init(DEMO_DMA_BASE, &edmaConfig);
EDMA_CreateHandle(&g_edma_handle, DEMO_DMA_BASE, DEMO_DMA_CH);
EDMA_SetCallback(&g_edma_handle, EDMA_Callback, NULL);
}
void DAC_Transmit(void)
{
edma_transfer_config_t xferConfig;
edma_minor_offset_config_t offsetConfig;
g_transfer_done = false;
/*
参数修正说明:
1. bytesEachRequest = 32 (每次触发搬运 8 个 Shifter,每个 4 字节)
2. transferBytes = 96 (总共 24 位数据,每位 4 字节,24 * 4 = 96)
这样 96 % 32 == 0,断言即可通过。
*/
EDMA_PrepareTransferConfig(&xferConfig,
(void *)g_dac_buffer, /* srcAddr */
4, /* srcWidth: 4字节 */
4, /* srcOffset: 4 */
(void *)&(DEMO_FLEXIO_BASE->SHIFTBUF[0]), /* destAddr */
4, /* destWidth: 4字节 */
4, /* destOffset: 4 */
32, /* bytesEachRequest: 32 */
96 /* transferBytes: 96 (!!!修正点) */
);
/* 提交配置 */
EDMA_SubmitTransfer(&g_edma_handle, &xferConfig);
/* 配置地址回退:Minor Loop 结束后,目的地址减去 32 字节回到 SHIFTBUF[0] */
offsetConfig.enableSrcMinorOffset = false;
offsetConfig.enableDestMinorOffset = true;
offsetConfig.minorOffset = -32;
EDMA_SetMinorOffsetConfig(DEMO_DMA_BASE, DEMO_DMA_CH, &offsetConfig);
/* 启动 DMA 和 FlexIO 请求 */
EDMA_StartTransfer(&g_edma_handle);
FLEXIO_EnableShifterStatusDMA(DEMO_FLEXIO_BASE, 1 << 0, true);
}
int main(void)
{
/* 基础硬件初始化 (时钟/引脚) */
BOARD_InitHardware();
Init_FlexIO_DAC();
Init_DMA_DAC();
/* 示例数据填充 */
for(int i=0; i<BIT_DEPTH; i++) g_dac_buffer[i] = 0xAAAAA;
while (1)
{
DAC_Transmit();
/* 等待回调执行 */
while(!g_transfer_done);
/* 间隔 */
SDK_DelayAtLeastUs(1000, SystemCoreClock);
}
}
程序卡死在 while(!g_transfer_done); 没有往下走 。 请问哪里出了问题