英飞凌
直播中

剪刀脚

8年用户 787经验值
私信 关注

GPDMA0至USIC0,第一个DMA启动后下一 DMA启动后就不一样了,为什么?

我正在使用 XMC4700。 我正试图使用 GDMA0 从 spi 通道读取数据。
刚才读取的字节值并不重要。
我需要接收大小为 16 位的字/帧(从双 SPI 读取,因此每个通道都有 16 位),因此从站需要接收 16 个 CS 为低电平的 clks。
我注意到,例如当我要求块传输大小等于 10 时,我想我应该在 16 个时钟下看到 5 个芯片选择为低电平。 但是,在我第一次启动 DMA 时,它总是显示 6 个芯片选择为低电平,16 个时钟,接下来是 5 个芯片选择为低电平,16 个时钟。 如下图所示:

我真的很担心,因为我不太了解 TRANSFER WIDTH、BURST 或写入 TBUF 的字节数。 你知道发生了什么吗?
实现这一目标的代码是

void spi_init(void);/*Transmit ISR*/void SPI_MASTER_DMA_tx_handler(XMC_DMA_CH_EVENT_t event);GLOBAL_DMA_INTERRUPT_CONFIG_t GLOBAL_DMA_0_CONF ={  .priority = 63U, /* Node interrupt priority */  .sub_priority = 0U  /* Node interrupt sub-priority */};GLOBAL_DMA_t GLOBAL_DMA0 ={  .dma = XMC_DMA0, /* Which DMA module? */  .config =  GLOBAL_DMA_0_CONF, /* A reference to interrupt config */  .initialized = (bool)0U, /* Is DMA initialized yet? */  .irq_node = (IRQn_Type)105U /* Allotted DMA IRQ node */};//void GPDMA0_0_IRQHandler(void){        XMC_DMA_IRQHandler(XMC_DMA0);}volatile  __attribute__((aligned(2))) uint32_t src_addr_tx_spi = 0xFFFF;int main(void){spi_init();XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_GPDMA0);XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_GPDMA0);GPDMA0->DMACFGREG = 0x01U;/*Enable DMA event handling*/NVIC_SetPriority(GLOBAL_DMA0.irq_node, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),GLOBAL_DMA0.config->priority,GLOBAL_DMA0.config->sub_priority));NVIC_EnableIRQ(GLOBAL_DMA0.irq_node);//Enable GPDMA in SCUSCU_RESET->PRCLR2 |= SCU_RESET_PRCLR2_DMA0RS_Msk;//SAR and DAR.GPDMA0_CH2->SAR = (uint32_t) src_addr_tx_spi;GPDMA0_CH2->DAR = (uint32_t) XMC_SPI0_CH0->TBUF[XMC_SPI_CH_MODE_STANDARD];//CTLHGPDMA0_CH2->CTLH = 0;GPDMA0_CH2->CTLH = (10CTLL |= (XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA << GPDMA0_CH_CTLL_TT_FC_Pos)|(XMC_DMA_CH_BURST_LENGTH_1CFGL  = (~(GPDMA0_CH_CFGL_CH_PRIOR_Msk)); GPDMA0_CH2->CFGL  = (uint32_t)~GPDMA0_CH_CFGL_HS_SEL_DST_Msk; //DST Hardware handshaking//DMA ENABLE REGUEST LINEXMC_DMA_EnableRequestLine(XMC_DMA0,0,10);//GPDMA0_CH2->CFGL  = (uint32_t)~GPDMA0_CH_CFGL_CH_SUSP_Msk; //Iniciar la transferencia del canal//GPDMA0_CH2->CFGL |= (uint32_t)GPDMA0_CH_CFGL_CH_SUSP_Msk; // Parar la transferencia del canalXMC_DMA_CH_SetEventHandler(XMC_DMA0, 2U, SPI_MASTER_DMA_tx_handler);GPDMA0->MASKTFR = 0x404;GPDMA0->CHENREG = (uint32_t)(0x101UL << 2);XMC_USIC_CH_TriggerServiceRequest(XMC_SPI0_CH0, (uint32_t)SPI_MASTER_SR_ID_0);  while(1U)  {     delay(72UL);     GPDMA0->CHENREG = (uint32_t)(0x101UL << 2);//Donde 2 es el canal     XMC_USIC_CH_TriggerServiceRequest(XMC_SPI0_CH0, (uint32_t)SPI_MASTER_SR_ID_0);     delay(7200UL);  }}void spi_init(void){        /* Initialize USIC channel in SPI mode */        XMC_SPI_CH_Init(XMC_SPI0_CH0,  MASTER_channel_config);        /* Set the frame and word length */        XMC_SPI_CH_SetFrameLength(XMC_SPI0_CH0, 16U);        XMC_SPI_CH_SetWordLength(XMC_SPI0_CH0, 16U);        /* Set LSB data shift direction */        XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI0_CH0);        /* Set input source for input stage dx0 (receive pin) */        XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_DIN0, (uint8_t)6U);        XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_DIN1, (uint8_t)6U);        /* Enable Frame End Mode */        XMC_SPI_CH_EnableFEM(XMC_SPI0_CH0);        /* Configure the clock polarity and clock delay */        XMC_SPI_CH_ConfigureShiftClockOutput(XMC_SPI0_CH0, XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_1_DELAY_DISABLED, XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);        /* Disable all Slave Select lines */        XMC_SPI_CH_DisableSlaveSelect(XMC_SPI0_CH0);        /* Establish Slave Select signal polarity */        XMC_SPI_CH_SetSlaveSelectPolarity(XMC_SPI0_CH0, XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS);        /* Set Select Control */;        XMC_SPI_CH_DisableSlaveSelectCodedMode(XMC_SPI0_CH0);        /* Configure the leading/trailing delay for the MSLS signal */        XMC_SPI_CH_SetSlaveSelectDelay(XMC_SPI0_CH0, 1U);        XMC_SPI_CH_DisableInterwordDelay(XMC_SPI0_CH0);        XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL, 0U);        /* Configure the transmit FIFO */        XMC_USIC_CH_TXFIFO_Configure(XMC_SPI0_CH0, 0U, XMC_USIC_CH_FIFO_DISABLED, 0U);        /* Configure the receive FIFO */        XMC_USIC_CH_RXFIFO_Configure(XMC_SPI0_CH0, 0U, XMC_USIC_CH_FIFO_DISABLED, 0U);        /* Enable the Slave Select 0 Signal */        XMC_SPI_CH_EnableSlaveSelect(XMC_SPI0_CH0, XMC_SPI_CH_SLAVE_SELECT_0);        /* Configure the pin properties */        XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT1_BASE, (uint8_t)5,  port_config_miso0);        XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT1_BASE, (uint8_t)4,  port_config_miso1);        /* Configure the Hardware control mode selected for the pin */        XMC_GPIO_SetHardwareControl((XMC_GPIO_PORT_t *)PORT1_BASE, (uint8_t)5, XMC_GPIO_HWCTRL_PERIPHERAL1);        XMC_GPIO_SetHardwareControl((XMC_GPIO_PORT_t *)PORT1_BASE, (uint8_t)4, XMC_GPIO_HWCTRL_PERIPHERAL1);        /* Initialize SPI SCLK out pin */        XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT1_BASE, (uint8_t)10,  port_config_sclkout);        /* Configure the pin properties */        XMC_GPIO_Init((XMC_GPIO_PORT_t *)PORT1_BASE, (uint8_t)11,  port_config_cs);XMC_SPI0_CH0->CCR = (XMC_SPI0_CH0->CCR   (uint32_t)(~USIC_CH_CCR_HPCEN_Msk)) |(((uint32_t) 2 << USIC_CH_CCR_HPCEN_Pos)   (uint32_t)USIC_CH_CCR_HPCEN_Msk);//Enable DX3, DX0 y DOUT[1:0] Dual SPIXMC_SPI0_CH0->CCR |=   USIC_CH_CCR_RSIEN_Msk | USIC_CH_CCR_TSIEN_Msk;XMC_SPI0_CH0->CCR = (XMC_SPI0_CH0->CCR   (uint32_t)(~USIC_CH_CCR_MODE_Msk)) |(((uint32_t) 1 << USIC_CH_CCR_MODE_Pos)   (uint32_t)USIC_CH_CCR_MODE_Msk);        //Enable SPI Mode 1       XMC_USIC_CH_SetInterruptNodePointer(XMC_SPI0_CH0,XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER,            (uint32_t)SPI_MASTER_SR_ID_0);        return;}/*Transmit ISR*/void SPI_MASTER_DMA_tx_handler(XMC_DMA_CH_EVENT_t event){  if (event == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE )  {          return;  }  else if(event == XMC_DMA_CH_EVENT_TRANSFER_COMPLETE)  {          return;  }}


回帖(1)

李华

2024-5-28 16:05:48
您遇到的问题可能是由于DMA配置不正确或SPI通信设置不正确导致的。以下是一些建议,以帮助您解决问题:

1. 检查DMA配置:
确保GPDMA0的配置正确。检查源地址、目标地址、传输大小、块大小和控制设置。确保传输宽度设置为16位,因为您需要接收16位的字/帧。

2. 检查SPI配置:
确保SPI通道的配置正确。检查时钟极性、时钟相位、数据宽度和数据顺序。由于您需要接收16位的字/帧,因此数据宽度应设置为16位。

3. 检查DMA触发条件:
确保DMA触发条件正确设置。在您的示例中,您提到在第一次启动DMA时,它总是显示6个芯片选择为低电平,16个时钟。这可能是因为DMA触发条件设置不正确,导致DMA在预期之外的时间启动。

4. 检查DMA中断和回调函数:
确保DMA中断和回调函数正确实现。在回调函数中,您可以检查DMA传输的状态,并根据需要调整DMA配置或SPI设置。

5. 使用调试工具:
使用调试工具(如示波器或逻辑分析仪)来监视SPI通信和DMA触发条件。这将帮助您确定问题所在,并确保SPI通信和DMA配置正确。

6. 参考XMC4700文档:
仔细阅读XMC4700的数据手册和参考手册,以了解DMA和SPI的详细配置和工作原理。这将帮助您更好地理解您的系统,并找到可能的问题所在。

通过检查和调整这些设置,您应该能够找到问题所在,并确保GPDMA0从SPI通道正确地读取数据。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分