- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am trying to use cy8ckit-064s0s2-4343w to drive WS2812b LED strip.
I have found ws2812 library in iot_expert github repo (1) and it works fine.
But my application is performance critical so I would like to use DMA to output data to SPI.
I have found DMA version of that library (2) and also the article about it
The problem is that it does not work.
I remember using same library on PSoC 4 and it worked ok.
To narrow down the problem i have combined non DMA version (link (1)) with dma configuration from link (2).
The result is as follows:
When cyhal_psi_transfer() is used to output the data everything works fine.
When WS_DMATrigger() is used the LEDs does not light up.
The code can be found here .
I have spent several hours and still was not able to find the problem.
I would greatly appreciate some help.
Thanks.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @BohdanHunko ,
I tried replicating your code at my end. I was also facing the same issue. Most probably its related to DMA Trigger not working. So for that, I created a simple DMA transfer and did all configurations in PDL and connected the Trigger Multiplexer group to right Input and Output. Then it works fine.
I have created a code example to demonstrate this. Take a look and modify the Trigger connections to right peripherals and give it a try:
#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
/* Scenario: Initialize a 1D descriptor */
#define DATACNT (8UL)
cy_stc_dma_descriptor_t descriptor;
int main(void)
{
cy_rslt_t result;
uint32_t src[DATACNT] = {1,2,3,4,5,6,7,8};
uint32_t dst[DATACNT];
/* Initialize the device and board peripherals */
result = cybsp_init() ;
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
__enable_irq();
cy_stc_dma_descriptor_config_t descriptor_cfg =
{
.retrigger = CY_DMA_RETRIG_IM,
.interruptType = CY_DMA_DESCR,
.triggerOutType = CY_DMA_DESCR,
.channelState = CY_DMA_CHANNEL_ENABLED,
.triggerInType = CY_DMA_DESCR,
.dataSize = CY_DMA_WORD,
.srcTransferSize = CY_DMA_TRANSFER_SIZE_WORD,
.dstTransferSize = CY_DMA_TRANSFER_SIZE_WORD,
.descriptorType = CY_DMA_1D_TRANSFER,
.srcAddress = &src,
.dstAddress = &dst,
.srcXincrement = 1U,
.dstXincrement = 1U,
.xCount = DATACNT,
.srcYincrement = 0U,
.dstYincrement = 0U,
.yCount = 1UL,
.nextDescriptor = NULL,
};
if (CY_DMA_SUCCESS != Cy_DMA_Descriptor_Init(&descriptor, &descriptor_cfg))
{
// Insert error handling
}
// Scenario: Setup and enable the DMA channel 0 of block DW0
cy_stc_dma_channel_config_t channelConfig;
channelConfig.preemptable = false;
channelConfig.enable = false;
channelConfig.bufferable = false;
if (CY_DMA_SUCCESS != Cy_DMA_Channel_Init(DW0, 0UL, &channelConfig))
{
// Insert error handling
}
Cy_TrigMux_Connect(TRIG_IN_MUX_0_PDMA0_TR_OUT0 , TRIG_OUT_MUX_0_PDMA0_TR_IN0 , false, TRIGGER_TYPE_EDGE);
Cy_DMA_Channel_SetDescriptor(DW0, 0UL, &descriptor);
Cy_DMA_Channel_SetPriority(DW0, 0UL, 3UL);
Cy_DMA_Channel_Enable(DW0, 0UL);
Cy_DMA_Enable(DW0);
if (CY_TRIGMUX_SUCCESS != Cy_TrigMux_SwTrigger(TRIG_OUT_MUX_0_PDMA0_TR_IN0, CY_TRIGGER_TWO_CYCLES))
{
}
for (;;)
{
}
}
Thanks and regards
Sobhit
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @BohdanHunko ,
I would suggest you to go through Infineon's GitHub repository explaining SPI DMA for PSoC6.
Link - https://github.com/Infineon/mtb-example-psoc6-spi-master-dma
Give it a try and let me know if that helps.
Thanks
Sobhit
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Thanks for quick reply
I have cloned the example and changed SPI_MODE to SPI_MODE_BOTH.
I have also changed target to be cy8ckit-064s0s2-4343w
Everything builds fine, but LED does not blink.
The program is stuck on while(false == tx_dma_complete){}
I have put a breakpoint inside of tx_dma_complete() interrupt handler and this interrupt never happens. This is exactly the results I am seeing in my other projects: dma done event never happens.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @BohdanHunko ,
I tried replicating your code at my end. I was also facing the same issue. Most probably its related to DMA Trigger not working. So for that, I created a simple DMA transfer and did all configurations in PDL and connected the Trigger Multiplexer group to right Input and Output. Then it works fine.
I have created a code example to demonstrate this. Take a look and modify the Trigger connections to right peripherals and give it a try:
#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
/* Scenario: Initialize a 1D descriptor */
#define DATACNT (8UL)
cy_stc_dma_descriptor_t descriptor;
int main(void)
{
cy_rslt_t result;
uint32_t src[DATACNT] = {1,2,3,4,5,6,7,8};
uint32_t dst[DATACNT];
/* Initialize the device and board peripherals */
result = cybsp_init() ;
if (result != CY_RSLT_SUCCESS)
{
CY_ASSERT(0);
}
__enable_irq();
cy_stc_dma_descriptor_config_t descriptor_cfg =
{
.retrigger = CY_DMA_RETRIG_IM,
.interruptType = CY_DMA_DESCR,
.triggerOutType = CY_DMA_DESCR,
.channelState = CY_DMA_CHANNEL_ENABLED,
.triggerInType = CY_DMA_DESCR,
.dataSize = CY_DMA_WORD,
.srcTransferSize = CY_DMA_TRANSFER_SIZE_WORD,
.dstTransferSize = CY_DMA_TRANSFER_SIZE_WORD,
.descriptorType = CY_DMA_1D_TRANSFER,
.srcAddress = &src,
.dstAddress = &dst,
.srcXincrement = 1U,
.dstXincrement = 1U,
.xCount = DATACNT,
.srcYincrement = 0U,
.dstYincrement = 0U,
.yCount = 1UL,
.nextDescriptor = NULL,
};
if (CY_DMA_SUCCESS != Cy_DMA_Descriptor_Init(&descriptor, &descriptor_cfg))
{
// Insert error handling
}
// Scenario: Setup and enable the DMA channel 0 of block DW0
cy_stc_dma_channel_config_t channelConfig;
channelConfig.preemptable = false;
channelConfig.enable = false;
channelConfig.bufferable = false;
if (CY_DMA_SUCCESS != Cy_DMA_Channel_Init(DW0, 0UL, &channelConfig))
{
// Insert error handling
}
Cy_TrigMux_Connect(TRIG_IN_MUX_0_PDMA0_TR_OUT0 , TRIG_OUT_MUX_0_PDMA0_TR_IN0 , false, TRIGGER_TYPE_EDGE);
Cy_DMA_Channel_SetDescriptor(DW0, 0UL, &descriptor);
Cy_DMA_Channel_SetPriority(DW0, 0UL, 3UL);
Cy_DMA_Channel_Enable(DW0, 0UL);
Cy_DMA_Enable(DW0);
if (CY_TRIGMUX_SUCCESS != Cy_TrigMux_SwTrigger(TRIG_OUT_MUX_0_PDMA0_TR_IN0, CY_TRIGGER_TWO_CYCLES))
{
}
for (;;)
{
}
}
Thanks and regards
Sobhit