这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 在psco6上使用DMA将阵列传输到SPI外围设备,为什么无法启动第二个描述符?

共2条 1/1 1 跳转至

在psco6上使用DMA将阵列传输到SPI外围设备,为什么无法启动第二个描述符?

工程师
2024-07-17 11:10:33     打赏

你好。我正在尝试在 psco6 (CY8CKIT-062-BT-WIFI) 上使用 DMA 将阵列传输到 SPI 外围设备。
数组长度是一个很大的任意数字,不适合 2D 传输。比方说 643 字节。
我的想法是将其分成两个描述符并将它们链接起来。即第一个描述符传输 10x64 字节,第二个描述符传输 3 字节。(我不确定是否有其他方法。)
我遇到的问题是它无法启动第二个描述符。这是我正在尝试使用的代码:
#define txDma_ENABLED 1U#define txDma_HW DW0#define txDma_CHANNEL 2U#define txDma_IRQ cpuss_interrupts_dw0_2_IRQn/* Interrupt priority for TXDMA */#define TXDMA_INTERRUPT_PRIORITY (7u)volatile bool tx_dma_done = false;cy_stc_dma_descriptor_t txDma_Descriptor_1 = {    .ctl = 0UL,    .src=0UL,    .dst = 0UL,    .xCtl = 0UL,    .yCtl = 0UL,    .nextPtr = 0UL,};cy_stc_dma_descriptor_t txDma_Descriptor_0 = {    .ctl = 0UL,    .src=0UL,    .dst = 0UL,    .xCtl = 0UL,    .yCtl = 0UL,    .nextPtr = 0UL,};const cy_stc_dma_descriptor_config_t txDma_Descriptor_0_config = {    .retrigger = CY_DMA_RETRIG_IM,    .interruptType = CY_DMA_DESCR_CHAIN,    .triggerOutType = CY_DMA_1ELEMENT,    .channelState = CY_DMA_CHANNEL_DISABLED,    .triggerInType = CY_DMA_1ELEMENT,    .dataSize = CY_DMA_BYTE,    .srcTransferSize = CY_DMA_TRANSFER_SIZE_DATA,    .dstTransferSize = CY_DMA_TRANSFER_SIZE_WORD,    .descriptorType = CY_DMA_2D_TRANSFER,    .srcAddress = NULL,    .dstAddress = NULL,    .srcXincrement = 1,    .dstXincrement = 0,    .xCount = 1,    .srcYincrement = 0,    .dstYincrement = 0,    .yCount = 1,    .nextDescriptor = 0UL,};const cy_stc_dma_channel_config_t txDma_channelConfig = {    .descriptor =  txDma_Descriptor_0,    .preemptable = false,    .priority = 3,    .enable = false,    .bufferable = false,};const uint8_t small_buffer[10]={0xA1,0xB2,0xC3};uint32_t configure_tx_dma(uint8_t* tx_buffer){     cy_en_dma_status_t dma_init_status;     const cy_stc_sysint_t intTxDma_cfg =     {         .intrsrc=txDma_IRQ,         .intrPriority = 7u     };     /* Initialize descriptor */     dma_init_status = Cy_DMA_Descriptor_Init( txDma_Descriptor_0,  txDma_Descriptor_0_config);     Cy_DMA_Descriptor_SetXloopSrcIncrement( txDma_Descriptor_0, 1);     Cy_DMA_Descriptor_SetYloopSrcIncrement( txDma_Descriptor_0, 64);     Cy_DMA_Descriptor_SetXloopDataCount( txDma_Descriptor_0, 64);     Cy_DMA_Descriptor_SetYloopDataCount( txDma_Descriptor_0, 10);     Cy_DMA_Descriptor_SetNextDescriptor( txDma_Descriptor_0,  txDma_Descriptor_1);     dma_init_status = Cy_DMA_Descriptor_Init( txDma_Descriptor_1,  txDma_Descriptor_0_config);     Cy_DMA_Descriptor_SetXloopSrcIncrement( txDma_Descriptor_1, 1);     Cy_DMA_Descriptor_SetYloopSrcIncrement( txDma_Descriptor_1, 3);     Cy_DMA_Descriptor_SetXloopDataCount( txDma_Descriptor_1, 3);     Cy_DMA_Descriptor_SetYloopDataCount( txDma_Descriptor_1, 1);     Cy_DMA_Descriptor_SetNextDescriptor( txDma_Descriptor_1, 0UL);     if (dma_init_status!=CY_DMA_SUCCESS)     {         return INIT_FAILURE;     }     dma_init_status = Cy_DMA_Channel_Init(txDma_HW, txDma_CHANNEL,  txDma_channelConfig);     if (dma_init_status!=CY_DMA_SUCCESS)     {         return INIT_FAILURE;     }     /* Set source and destination for descriptor 1 */     Cy_DMA_Descriptor_SetSrcAddress( txDma_Descriptor_0, tx_buffer);     Cy_DMA_Descriptor_SetDstAddress( txDma_Descriptor_0, (void *) SCB6->TX_FIFO_WR);     Cy_DMA_Descriptor_SetSrcAddress( txDma_Descriptor_1, small_buffer);     Cy_DMA_Descriptor_SetDstAddress( txDma_Descriptor_1, (void *) SCB6->TX_FIFO_WR);      /* Initialize and enable the interrupt from TxDma */     Cy_SysInt_Init( intTxDma_cfg,  tx_dma_complete);     NVIC_EnableIRQ((IRQn_Type)intTxDma_cfg.intrSrc);      /* Enable DMA interrupt source. */     Cy_DMA_Channel_SetInterruptMask(txDma_HW, txDma_CHANNEL, CY_DMA_INTR_MASK);     /* Enable DMA block to start descriptor execution process */     Cy_DMA_Enable(txDma_HW);     return INIT_SUCCESS;}void tx_dma_complete(void){     /* Check tx DMA status */     if ((CY_DMA_INTR_CAUSE_COMPLETION    != Cy_DMA_Channel_GetStatus(txDma_HW, txDma_CHANNEL))            (CY_DMA_INTR_CAUSE_CURR_PTR_NULL != Cy_DMA_Channel_GetStatus(txDma_HW, txDma_CHANNEL)))     {         /* DMA error occurred while TX operations */         //handle_error();     }     tx_dma_done = true;     /* Clear tx DMA interrupt */     Cy_DMA_Channel_ClearInterrupt(txDma_HW, txDma_CHANNEL);}void spi_dma_transfer(){    Cy_DMA_Channel_SetDescriptor(txDma_HW, txDma_CHANNEL, txDma_Descriptor_0);    Cy_DMA_Channel_Enable(txDma_HW, txDma_CHANNEL);}




关键词: psco6     SPI     描述符     阵列    

助工
2024-07-17 11:10:56     打赏
2楼

1. 描述符链配置问题:请确保第一个描述符的链结束符(bit[15])设置为0,而第二个描述符的链结束符设置为1。

2. 描述符的有效性问题:请确保每个描述符的有效位(bit[31])都被设置为1,以确保DMA引擎可以正确处理它们。

3. DMA配置问题:请确保正确配置了DMA引擎相关的寄存器,包括描述符地址、描述符数目和DMA通道。

此外,您还可以尝试使用中断方式来处理每个描述符的传输完成事件,以便及时处理第二个描述符的传输。

对于您提到的不适合2D传输的问题,您可以尝试使用多个描述符来传输数据,如您所示的将数组分成两个描述符。另外,您还可以使用循环模式来重复传输同一个描述符,从而实现大数组的传输。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]