mcxn947 dma传输开启后没有进入回调 #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); 没有往下走 。 请问哪里出了问题 Communication & Control(I3C | I2C | SPI | FlexCAN | Ethernet | FlexIO) Re: mcxn947 dma传输开启后没有进入回调 The callback was not executed. Which channel should be used for DMA here? Channel 61 won't pass the assertion; it cannot exceed 16. If the DMA channel is set to 0, the DMA callback will not be entered at all. Re: mcxn947 dma传输开启后没有进入回调 Hi @justdomyself
1) Set breakpoints for debugging and check if the eDMA interrupt and callback functions have been entered.
2) Confirm which eDMA channel is being used.
#define DEMO_DMA_CH / * Using DMA channel 61 */ It seems that channel 0 is being used here.
INPUTMUX_EnableSignal(INPUTMUX0, kINPUTMUX_FlexIO0ShiftRegister0RequestToDma0Ch61Ena, true); However, judging from the comments and this line of code, it seems to be using Chaanel 61.
BR
Alice
查看全文