我正在使用 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 */ .ini
tialized = (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; }}