Basic DMA Help Needed

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.
joeac_1591236
Level 2
Level 2

I am trying to read a status register at regular, short intervals.  To do this I've connected a clock to my DMA drq signal and have set up the status register DMA through the DMA wizard.  I am using all internal clocks just to test the DMA but I have not seen any successful memory transfer.  Could you please look over my code and let me know of any errors?  I have also attached an image of my Top Design.

   

 

   

#include <project.h>
/* Defines for DMA_1 */
#define DMA_1_BYTES_PER_BURST 1
#define DMA_1_REQUEST_PER_BURST 1
#define DMA_1_SRC_BASE (CYDEV_PERIPH_BASE)
#define DMA_1_DST_BASE (CYDEV_SRAM_DATA_MBASE)

   

int main()
{
    uint8 DMA_1_Chan;
    uint8 DMA_1_TD[1];

   

    DMA_1_Chan = DMA_1_DmaInitialize(DMA_1_BYTES_PER_BURST, DMA_1_REQUEST_PER_BURST, 
        HI16(DMA_1_SRC_BASE), HI16(DMA_1_DST_BASE));
    DMA_1_TD[0] = CyDmaTdAllocate();
    CyDmaTdSetConfiguration(DMA_1_TD[0], 1, DMA_1_TD[0], TD_INC_DST_ADR);
    CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)Status_Reg_1_Status_PTR), LO16((uint32)CYDEV_SRAM_DATA_MBASE));
    CyDmaChSetInitialTd(DMA_1_Chan, DMA_1_TD[0]);
    CyDmaChEnable(DMA_1_Chan, 1);
       
    unsigned char* Receive_Data = (unsigned char*) CYDEV_SRAM_DATA_MBASE;
    int i;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    Clock_4_Stop();
    Clock_4_Start();
    CyDelayUs(1500);
    Clock_4_Stop();
    for(;;)
    {
        for(i = 0; i < 200; i++)
        {
            Pin_1_Write(1);
            if((int)Receive_Data)
                CyDelay(500);
                
            CyDelay(100);
            Pin_1_Write(0);
            CyDelay(500);
        }
    }
}

0 Likes
8 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You should use

   

uint8 StatusByte;

   

and later

   

 CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)Status_Reg_1_Status_PTR), LO16((uint32)&StatsByte)));

   

It is easier for us when you post your complete project, so that we all can have a look at all of your settings. To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file, next time. 😉

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.

Thanks for the reply Bob.  Please see the project archive attached.  I made the change to uint8 but that didn't seem to have an effect.  And for further information, I'm using the CY8CKIT-059 (uses CY8C5888LTI-LP097).

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Corrected...

   

 

   

Bob

0 Likes

Fantastic, thank you Bob.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

You are always welcome!

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.

One more question since you're already familiar with my project setup.  I've found that my drq signal only captures properly up to ~7 MHz with a BUS_CLK of 75 MHz.  A faster drq rate seems to cause the DMA to skip edges.  Is there a max drq rate that the DMA can handle relative to the bus clock?  I've looked at the PSoC 5LP Architecture TRM but it's not straightforward how quickly it can accept drq triggers.  I would like to capture the status register data as fast as possible (at regular intervals).

   

See the updated higher speed project attached.  Thanks.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Answering that question could be done best by Cypress directly.

   

At top of this page select "Design Support -> Create a Support Case" and describe your problem. Attach your latest project.

   


Bob

0 Likes
HeLi_263931
Level 8
Level 8
100 solutions authored 50 solutions authored 25 solutions authored

The TRM explains what the actual time needed for a transfer is. Basically its N+6 cycles for an interspoke transfer (e.g. peripheral to sRAM), and 2N+5 for an intraspoke transfer (e.g. sRAM to sRAM). This might be higher when the CPU blocks the sRAM (which always takes 2 cycles). And the the triggering takes another cycle (since it needs to be synced to the clock). That comes up to the 10 cycles for a transfer that you observe.

0 Likes