2399782_en-US

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

2399782_en-US

2399782_en-US

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


Tags (1)
No ratings
Version history
Last update:
3 weeks ago
Updated by: