I'm having problems triggering DMA by PWM overflow signal, and then sending data from a sine wave array in memory to IDAC's register to get a sine wave on IDAC's output pin. I'm using a CY8CKIT-048 PSoC Analog Coprocessor Pioneer Kit.
I can't find any info in documentation on how to set up DMA and IDAC properly, what to do with different trigger types and source/destination types etc.
I checked TRM and every component's documentation, but couldn't find anything useful.
In my case I am trying to get DMA to transfer a single element from a 32-point array in memory to IDAC's register. DMA should be triggered on a PWM overflow signal.
DMA's input trigger type is set to a pulse of unknown width, but it looks like it never gets triggered.
I found a similar project (and a case in forum) made for a different PSoC. and tried modifying the code to run on my device, but I can't get it to work.
Attached is a wave DAC generation project for P4M. The DMA transfer to IDAC on P4 is tricky, it has to be 2 bytes, with MSB set to 0x07, and LSB is actual IDAC value (so RAM array must be 16-bit instead of 8-bit). This MSB is configuration setting for IDAC, controlling current output/bit, which has to be set on each DMA transaction. The DMA trigger has to be set to "unknown width". Max frequency achievable is lower than for PSoC5, reaching ~13.4 kHz @256 points/waveform, but the DAC output quality is better (no bit flipping glitches). Unlike PSoC5, on P4 DMA has no "nrq" signaling the end of Buffer transfer, instead the DMA internal irq and a PinLED are used to for that purpose.
In DMA_callback i tried blinking an LED, but it doesn't do anything, so I'm assuming it never transfers anything.
This is a part of DMA initialization code i found.
CyGlobalIntEnable; /* Enable global interrupts. */
DMA_1_Start(sine_wave, (void *) IDAC7_1_IDAC_CONTROL_PTR);
I attached my project so you can check it out.
Any help would be appreciated.
Solved! Go to Solution.
To confirm if DMA transfer is working, can you check the tr_out pin of DMA? Also can you enable the "Generate interrupt request " on the DMA configuration settings and try testing this.
Now it goes into the interrupt procedure only the first time, and then never again.
I tried adding this to DMA callback just to be sure that interrupt gets cleared, but it doesn't help.
source = CyDmaGetInterruptSourceMasked();
Same thing happens when I try debugging. It goes into DMA callback only once and then it gets stuck in an infinite loop in main.
Can you add a pin at tr_out and check if you are getting pulses at the DMA tr_out continuously?
When I add a pin at tr_out and try to build the project, I get a pin placement error.
Can you connect an ISR there and check if it gets triggered, after the first trigger of the DMA interrupt?
Can't do that either.
When I connect an ISR to tr_out i get Failed to place fixed-function blocks error when building.