你好。我正在尝试在 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)vola
tile 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);}