psoc6 dma 链接描述符位于同一个信道上

公告

大中华汽车电子生态圈社区并入开发者社区- 更多资讯点击此

Tip / 登入 to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Translation_Bot
Community Manager
Community Manager
Community Manager

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

 

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/td-p/662509

0 点赞
1 解答
lock attach
Attachments are accessible only for community members.
Translation_Bot
Community Manager
Community Manager
Community Manager

@MiladMrad

请参阅随附的简单 DMA 代码示例。 如果您需要任何帮助,请告诉我们。

热烈的问候,

Gautami J

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/m-p/663133

在原帖中查看解决方案

0 点赞
5 回复数
lock attach
Attachments are accessible only for community members.
Translation_Bot
Community Manager
Community Manager
Community Manager

@MiladMrad

请参阅随附的简单 DMA 代码示例。 如果您需要任何帮助,请告诉我们。

热烈的问候,

Gautami J

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/m-p/663133

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

@Gautami_12,谢谢你的回复。
我检查了您的示例代码 TESTBOARD_150PC_OUT 。看起来它正在执行两次相同的描述符。 (但我可能错了)我正在寻找
的是利用链接功能。 即在第一个描述符完成后立即启动描述符。
亲切的问候,
米拉德

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/m-p/663298

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

@MiladMrad

对于延迟回复,我们深表歉意。

我在这个回复中附上了一个正确的项目。

该项目是一个演示如何使用 DMA 通过 SPI 传输更大字节数据的实现。 请仔细阅读这个项目,如果您还有其他问题,请告诉我们。

热烈的问候,
Gautami J

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/m-p/672221

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

@Gautami_12
感谢你为我的回答制作了一个新项目。
我已将项目移至使用 HAL 库。 值得庆幸的是,它会自动设置 DMA、中断等等。
但是,如果有空闲时间,我会尝试这个,因为我需要了解幕后情况是如何运作的。
我已经下载了它并浏览了一下,它看起来像一个看起来有效的新解决方案。 但是,它需要更多的时间和更好的学习。
亲切的问候,
米拉德。

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/m-p/672603

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

@MiladMrad

很高兴听到使用 HAL 库解决了你的问题。

如果您还有其他疑问,请告诉我们。

热烈的问候,
Gautami J

smartconx_target@Q!w2e3r4t5y6u7i8o9p0||/t5/PSoC-6/psoc6-dma-chaining-descriptor-on-the-same-channel/m-p/672854

0 点赞