大家好,
我正在尝试设置从SDFM到高速SPI接口的DMA,以便通过连接 的FTDI电缆将所有捕获的数据样本通过MPSSE传输到PC。 我认为 DMA的配置可能不好,但 我不熟悉调试此机制。 SDFM已在系统中工作,SPI和DMA已全新实施。 在UC上,我已将SPI信号连接到示波器,以便可视化某些数据是否从处理器中发出。 配置顺序如下:
1.配置 SDFM和SPI的相应GPIO,例如SPI SIMO信号。
GPIO_setDirectionMode (SPI_SIMO_PIN,GPIO_DIR_MODE_OUT); GPIO _setMasterCore (SPI_SIMO_PIN,GPIO _CORE _CPU1); GPIO_setPadConfig (SPI_SIMO_PIN,GPIO PIN_TYPE_PLEUP); GPIO_setQualificationMode (SPI_SIMO_PIN,GPIO_Qual_Async); GPIO_setPinConfig (GPIO _58_SPISIMOA);
2.初始化SDFM模块。
//重置SDFM1模块 sysctl_resetPeripheral (sysctl_Periph_RES_SD1); //配置和启用 Interrupts_clearACKGroup (interrupT_ACK_group5); Interrup_enable (INT_SD1); //输入控制单元 SDFM_setupModulatorClock (SDFM1_base,SDFM_FILTER_1, SDFM_Modulator_CLK_equal_data_rate); SDFM_setupModulatorClock (SDFM1_BASE,SDFM_FILTER_2, SDFM_Modulator CLK_equal_data_rate); //数据过滤器单元 SDFM_configDataFilter (SDFM1_BASE, (SDFM_FILTER_1 | SDFM_FILTER_SINC_3 | SDFM_SET_OSR (200), (SDFM_DATA_format_16_bit | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE (0x0008)); SDFM_configDataFilter (SDFM1_BASE, (SDFM_FILTER_2 | SDFM_FILTER_Sinc_3 | SDFM_SET_OSR (200)), (SDFM_DATA_format_16_bit | SDFM_FILTER_ENABLE | SDFM_SHIFT_VALUE (0x0008)); // 启用主过滤器位SDFM_enableMasterFilter (SDFM1_BASE);//禁用外部中断SDFM_disableExternalReset (SDFM_BASE,SDFM_FILTER_1);SDFM_BASE,SDFM_DIFF_BASE,SDFM_DIFF_RETER1,SDFM_DITERFM_BASE (SDFM_DIFF_RERESTTER 1) SDFM_DATA_FILTER_ACknowledge_interrupt); SDFM_enableInterrupt (SDFM1_BASE,SDFM_FILTER_2, SDFM_DATA_FILTER_ACknowledge _interrupt); SDFM_DisableInterrupt (SDFM1_BASE,SDFM_FILTER_1, (SDFM_HIGH _LEVE_THRESHOLD_INTERRUPT | SDFM_low_lever_threshold_interrupt | SDFM_Modulator Failure_Interrupt); SDFM_DisableInterrupt (SDFM1_BASE,SDFM_FILTER_2, (SDFM_HIGH _LEVE_THRESHOLD_INTERRUPT | SDFM_low_lever_threshold_interrupt | SDFM_Modulator Failure_interrupt); //启用主中断,以便任何过滤器中断都可以通过 SDFM中断触发// CPU SDFM_enableMasterInterrupt (SDFM1_base);
3.初始化DMA模块的中断。
//配置和启用中断 interrupT_clearACKGroup(interrupT_ACK_group7); 中断注册(INT_DMA_CH6,&dmaCh6ISR); INTERRUL_ENABLE (INT_DMA_CH6); //初始化DMA控制器 dma_initController(); dma_setEmulation Mode(DMA_emulation_free run);
4.初始化SPI模块
//重置SPI模块 sysctl_resetPeripheral (sysctl_Periph_RES_SPIA); //配置和启用中断 interrupT_clearACKGroup(interrupT_ACK_group6); 中断注册(INT_SPIA_TX,&spiTxISR); 中断启用(INT_SPIA_TX); //必须在配置SPI模块之前禁用它 SPI_DisableModule (SPIA_base); //硬件配置 SPI_setConfig(SPIA_base,(UINT32_t) DEVICE_LSPCLK_FREQ, SPI_PROT_POL0PHA0,SPI_MODE_MASTER, (UINT32_t) SPI_BAUD_RATE,(uint16_t) SPI_WORD_WIDTH); SPI_enableHighSpeedMode(SPIA_base); SPI_setEmulation Mode(SPIA_base, SPI_emulation_free run); SPI_DisableTriWire (SPIA_BASE); SPI_DisableLoopback (SPIA_base); // FIFO和中断配置 SPI_enableFIFO (SPIA_BASE); SPI_resetTxFIFO (SPIA_BASE); SPI_resetRxFIFO (SPIA_BASE); SPI_setFIFO InterruptLevel (SPIA_BASE,SPI_TX_FIFO,INTLEV,SPI_FIFO,RXDEFAULT); SPI_clearInterruptStatus (SPIA_BASE,SPI_INT_TXFF); SPI_enableInterrupt (SPIA_BASE,SPI_INT_TXFF); SPI_DisableInterrupt (SPIA_BASE,SPI_INT_RXFF); //启用SPI模块 SPI_enableModule (SPIA_base);
完成这些步骤后,UC将进入命令解析器正在运行的无限循环。 通过 PC的终端程序 ,我可以设置要采集的样本数量和SDFM频道。 使用单独的命令触发 函数hsdlStart(void) 参数化DMA通道后,开始传输并等待完成。 这是因为这项工作从未完成而让它变得很不好! 所述的代码如下:
#define SPI_BAUD_RATE (DEVICE_LSPCLK_FREQ / 4) #define SPI_WORD_WIDTH 16 #define SPI_TX_FIFO_INTLEV SPI_FIFO和TX4
void hsdlStart (void)
{
uINT16_t dmaBurstSize;
uINT32_t dmaTransferSize;
const void *srcAddr;
const void *destAddr;
//确保DMA连接到外设帧1和2的网桥
EALLOW;
HWREG (CPUSYS_BASE + SYS_SECMSEL)= 0x5;
EDIS;
//计算DMA突发和传输大小
dmaBurstSize =16 - SPI_TX_FIFO_INTLEV;
dmaTransferSize = hsdlParams.n样本/ SPI_TX_FIFO_INTLEV;
//设置DMA突发和传输大小
dma_configBurst (dma_ch6_base,dmaBurstSize,1,1);
dma_configTransfer (dma_ch6_base,dmaTransferSize,1,1);
//将指针设置为目标地址
destAddr =(const void *)(SPIA_BASE + SPI_O_TXBUF);
//配置DMA通道6.
IF (hsdlParams.dataSel == 0)
{
//将指针设置为源地址
srcAddr =(const void *)(SDFM1_base + SDFM_O_SDDATA1 + 0x1U); //+1设置指向16位以下的指针
//配置DMA模式
DMA_configMode (DMA_CH6_BASE,DMA_TRIGG_SDFM1FLT1,
DMA_CFG_OneShot_enable | DMA_CFG_CONTINIENT_ENABLE | DMA_CFG_Size_16BIT);
}
否则,如果(hsdlParams.dataSel == 1)
{
//将指针设置为源地址
srcAddr =(const void *)(SDFM1_base + SDFM_O_SDDATA2 + 0x1U); //+1设置指向16位以下的指针
//配置DMA模式
DMA_configMode (DMA_CH6_BASE,DMA_TRIGG_SDFM1FLT2,
DMA_CFG_OneShot_enable | DMA_CFG_CONTINIENT_ENABLE | DMA_CFG_Size_16BIT);
}
dma_configAddresses(DMA_CH6_base, destAddr,srcAddr);
DMA_setInterruptMode (DMA_CH6_BASE,DMA_INT_AT_END);
dma_enableTrigger (dma_ch6_base);
dma_enableInterrupt (dma_ch6_base);
//启动DMA通道6
dma_startChannel(DMA_CH6_base);
dma_forceTrigger (dma_ch6_base);
//显示调试输出和HSDL传输已开始的LED
printf ("*** HSDL传输已启动***\n");
GPIO写入引脚(GPIO_PIN_STATUS_LED_3, 0);
//启用标记以指示HSDL传输已启动
//-->在"__interrupt void dmaCh6ISR(void)"中禁用
hsdlParams.running = 1;
//等待HSDL传输完成
同时(hsdlParams.running ==1){}
//显示调试输出和HSDL传输已完成的LED
printf ("*** HSDL传输已完成***\n");
GPIO写入引脚(GPIO_PIN_STATUS_LED_3, 1);
//确保CLA连接到外设帧1和2的网桥
EALLOW;
HWREG (CPUSYS_BASE + SYS_SECMSEL)= 0x0;
EDIS;
}
__interrupt void dmaCh6ISR(void)
{
//停止DMA通道6
dma_stopChannel(DMA_CH6_base);
//禁用标志,表示HSDL传输已完成
hsdlParams.running = 0;
//确认此中断以接收来自组7的更多中断
interrupT_clearACKGroup(interrupT_ACK_group7);
}
__interrupt void spiTxISR(void){
//清除中断标志
SPI_clearInterruptStatus (SPIA_BASE,SPI_INT_TXFF);
//确认此中断以接收来自组6的更多中断
interrupT_clearACKGroup(interrupT_ACK_group6);
}
在hsdlStart()中调试代码时,它永远不会从while循环中退出,因此我猜 这与未正确配置中断有关,因为从未输入ISR。 如果有人知道我的设置中出现了什么问题,那就很好了。
此致
Steffen