Proper way to DMA to a control register?

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.
PeWa_3215941
Level 1
Level 1

I'm attempting to learn about the PSoC5LP using the CY8CKIT-059. I'm starting to learn about the DMA peripheral and USB using the USBFS AUDIO PSoC3/5LP Code Example. I made some modifications:

  • Commented out the LCD routines since the CY8CKIT-059 doesn't have an LCD
  • Changed the sampling rate to 48kHz
  • Changed the audio format in the USB descriptor from PCM8 to PCM (since macOS doesn't support PCM8)
  • Added a SW loop to convert all 48 samples after each transfer to the RAM buffer from PCM8 to PCM. I can do this simply by XORing the high bit of each 8-bit sample.

I've tested my changes and they all work fine. I can play music through the PSoC from macOS. Now I'd like to replace my SW loop with a control register which will XOR the high-bit like so:

pastedImage_0.png

Then, to DMA to the control register instead of the VDAC8, I changed the example code here (line 05):

/* DMA Configuration for VDACoutDMA (Memory to VDAC) */

#define VDAC_DMA_BYTES_PER_BURST    (1u)

#define VDAC_DMA_REQUEST_PER_BURST  (1u)

#define VDAC_DMA_TD_TERMOUT_EN      (VdacDma__TD_TERMOUT_EN)

#define VDAC_DMA_DST_BASE           (HI16((uint32) Control_Reg_PCM_Control_PTR))

#define VDAC_DMA_SRC_BASE           (CY_PSOC5LP) ? ((uint32) soundBuffer) : (CYDEV_SRAM_BASE)

#define VDAC_DMA_ENABLE_PRESERVE_TD (1u)

and here (line 05):

    for (i = 0u; i < NUM_OF_BUFFERS; i++)

    {

        /* Set source and destination addresses. */

        CyDmaTdSetAddress(VdacOutDmaTd, LO16((uint32) &soundBuffer[i * TRANSFER_SIZE]),

                                           LO16((uint32) Control_Reg_PCM_Control_PTR));

    }

However, now I get no sound output.

I have a few questions:

  1. Is this the proper way to DMA to a control register?
  2. Can I just feed my control register into my VDAC and strobe the VDAC with the 48kHz clock like I'm doing? Do I need to worry about settling time for the control register, etc.?
  3. Bit 7 is the hight bit, right?
  4. How should I go about debugging this? How can I tell that my DMA samples are getting to the control register? How can I tell if the VDAC is getting the samples appropriately?

I've attached my archived (minimal) project.

0 Likes
1 Solution
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

pewa,

You can check how it was made in this project

DelSig_ADC - Filter - VDAC8 streaming demo using DMA

/odissey1

ADC-Filter-VDAC_01b_B.png

View solution in original post

0 Likes
3 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

pewa,

You can check how it was made in this project

DelSig_ADC - Filter - VDAC8 streaming demo using DMA

/odissey1

ADC-Filter-VDAC_01b_B.png

0 Likes

BoTa,

Thanks for posting--that's pretty much exactly what I want to do, except that the example I'm using has 10 TDs chained together (for buffering, I guess). Why do you run two TD's--one DMAing data into the control register and another DMAing it from the status register into the VDAC? Why couldn't you just wire the control register directly to the VDAC?

-Peter

0 Likes

Peter,

There is only single bus to VDAC, it is valuable resource and I would keep it for some other fast VDAC output. The DMA with chained TDs will take about same amount of clocks as single TD, so it is possible to use single DMA to transfer data to VDAC. The update clock in this example is rather low (~40kHz), so DMA use is appropriate here. On the other hand the bus will work also.

I haven't looked at the project, I suspect that 10 chained TDs are used to transfer data from USB to RAM in a single swipe.

/odissey1

0 Likes