CE218553 DMA-Timer Example Code - Code Bug Causes "Random" Failure

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

cross mob
lock attach
Attachments are accessible only for community members.
Bit-Twiddler
Level 3
Level 3
5 questions asked 10 sign-ins First solution authored

Hi there!

I'm using the CYBLE-416045 module  & PSoC Creator to implement the "CE218553 - PSoC 6 MCU: PWM
Triggering a DMA Channel" project example. Specifically I'm trying to use the CM0 processor instead of the default CM4.

On the CM4, which the example project defaults to, everything works fine. (see attached screenshot)

But once I move the code from the CM4 to the CM0, then the Timer output stays Low and the Compare never triggers. However Overflow does trigger, indicating that the Timer is still running. Presumably the Compare value is not being changed by DMA for some reason, which is why the timer compare isn't happening. (see attached screenshot)

Is the CM0 processor capable of handling DMA?

Is there something special that needs to happen for DMA to run on the CM0 processor?

Let me know if there's any additional information that I can provide to help troubleshoot this problem.

 

 

 

 

#include "project.h"

#define ARRAY_SIZE               (256u)
#define BREATHING_CHANGE         (512u)

uint32 compareVal[ARRAY_SIZE];

void arrayInit(void);

int main(void)
{
    cy_stc_dma_channel_config_t channelConfig;
    __enable_irq(); /* Enable global interrupts. */
    Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR); 

    arrayInit();  /*initialize the compareVal array */
    
    /* Initialize, enable and trigger the  PWM */
    Cy_TCPWM_PWM_Init(       PWM_HW, PWM_TCPWM__CNT_IDX, &PWM_config);
    Cy_TCPWM_Enable_Multiple(PWM_HW, PWM_CNT_MASK);
    Cy_TCPWM_TriggerStart(   PWM_HW, PWM_CNT_MASK);
    
    /* Configure DMA Descriptor to change the PWM compare value per breathingLed array */
    DMA_Descriptor_1_config.srcAddress = &compareVal;
    DMA_Descriptor_1_config.dstAddress = (void *) &(PWM_HW->CNT[PWM_TCPWM__CNT_IDX].CC);
    Cy_DMA_Descriptor_Init(&DMA_Descriptor_1, &DMA_Descriptor_1_config);
    
    /* Configure DMA Channel with the descriptor configured above */
    channelConfig.descriptor        = &DMA_Descriptor_1;
    channelConfig.preemptable       = DMA_PREEMPTABLE;
    channelConfig.priority          = DMA_PRIORITY;
    channelConfig.enable            = 0u;

    Cy_DMA_Channel_Init(  DMA_DW__BLOCK_HW, DMA_DW_CHANNEL, &channelConfig);
    Cy_DMA_Channel_Enable(DMA_DW__BLOCK_HW, DMA_DW__CHANNEL_NUMBER);
   
    /* Enable DMA hardware block */
    Cy_DMA_Enable(DMA_DW__BLOCK_HW);

    Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR); 

    for(;;)
    {
    }
}


void arrayInit(void)
{
    uint32_t i=0u;
    /* Creating the array with increasing and decreasing compare value to generate the breathing */
    compareVal[i] = 0;
    
    for(i=0u; i < ARRAY_SIZE>>1; i++)
    {
        /* Increase compare values */
        compareVal[i] = compareVal[i-1u] + BREATHING_CHANGE;
    }
    for(i=(ARRAY_SIZE>>1); i < ARRAY_SIZE; i++)
    {
        /* Decrease compare value */
        compareVal[i] = compareVal[i-1] - BREATHING_CHANGE;
    }
}

 

 

 

 

 

 

 

0 Likes
1 Solution
Bit-Twiddler
Level 3
Level 3
5 questions asked 10 sign-ins First solution authored

At this point I believe I've tracked it down to a bug in the Example Code. I was lucky that it ran on the CM4 core at all:

 

 

compareVal[i] = 0;

for(i=0u; i < ARRAY_SIZE>>1; i++)
{
    compareVal[i] = compareVal[i-1u] + BREATHING_CHANGE;
}

 

 

At the beginning of the loop i =0.

compareVal[i-1u] either points to compareVal[-1] or compareVal[unsigned -1].

Either way, I would assume that the loop should be looking at the compareVal[0] at the beginning, when it's actually looking at memory completely unrelated to the array...

The good new is changing the first For-Loop from "i = 0u" to "i = 1u" remedied this.

 

So, does anyone know where I can submit this bug to get it fixed? It'd be nice if I was the last person to have to deal with this.

View solution in original post

0 Likes
3 Replies
Bit-Twiddler
Level 3
Level 3
5 questions asked 10 sign-ins First solution authored

If I comment out "Cy_TCPWM_TriggerStart()" then the Overflow signal goes away, confirming that the Timer *is* running normally.

If I comment out "Cy_DMA_Enable()" instead, then the PWM output does have the static duty cycle that it was first programmed with.

So somehow the enabling of the DMA either causes a single write to the Compare counter and doesn't trigger again, or somehow the same static value is written the the Compare Counter each time DMA triggers.

Well, I went into the arrayInit() and changed the "compareVal[i] =" to two different static values, and the waveform came out just fine, alternating between the two values... so somehow something isn't working properly in the values being set? At least the DMA *is* working. It's just that something unexpected is happening with the value assignments, or perhaps compiler optimization? Time will tell.

0 Likes
Bit-Twiddler
Level 3
Level 3
5 questions asked 10 sign-ins First solution authored

Well, the values are being initialized at too high of a value... probably will be obvious why with a little more prodding.

Watch Screenshot.png

0 Likes
Bit-Twiddler
Level 3
Level 3
5 questions asked 10 sign-ins First solution authored

At this point I believe I've tracked it down to a bug in the Example Code. I was lucky that it ran on the CM4 core at all:

 

 

compareVal[i] = 0;

for(i=0u; i < ARRAY_SIZE>>1; i++)
{
    compareVal[i] = compareVal[i-1u] + BREATHING_CHANGE;
}

 

 

At the beginning of the loop i =0.

compareVal[i-1u] either points to compareVal[-1] or compareVal[unsigned -1].

Either way, I would assume that the loop should be looking at the compareVal[0] at the beginning, when it's actually looking at memory completely unrelated to the array...

The good new is changing the first For-Loop from "i = 0u" to "i = 1u" remedied this.

 

So, does anyone know where I can submit this bug to get it fixed? It'd be nice if I was the last person to have to deal with this.

0 Likes