DMA is 8 bit only, have 12 bit ADC data, want to write to 8 bit DAC

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

cross mob
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

    I would like to write Data buffered into memory from the  ADC 150,000 sps  rate out the 8 bit dac, capturing a 20khz waveform.  I understand I would either loose the upper 4 bits or the lower 8 bits to do this, unless some extra logic was thrown into the mix.

   

   However, it appears the DMA unit is 8 bits only, and the DAC is 8 bits only.  I would get the upper 4 bits inter-mixed with the lower 8 bits.  Strange dac signals would result.

   

   If I use Dithered dac, I can only to 7,000 sps.

   

   So, any way to get DAC to skip a byte (increment by 2)?

   

   Any work arounds or suggestions?   I guess I could verilog up something, just don't want to go there yet.

   

   I prefer not to use cpu resources, but I'm open to any suggestion at this point.

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

I am afraid you have to think over how to put an M12 bolt into an M8 nut. When you figured out that, apply that to your digital problem.

   

I would try to use an M8 bolt.

   

 

   

Bob

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

You can configure the ADC to return 8 bits only, then you can do a direct transfer.

   

When you want to know how to properly read the 12 bits from the ADC, look at AN61102: http://www.cypress.com/?rID=44335

0 Likes
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

   But I *love* M12 bolts!

   

   point taken.   Actually hadn't thought like that.  Will work for a test.

   

   I realize space is at a premium on a Die, but it would be nice to have a 16 or 32 bit DMA unit, and a 16 bit DAC at full speed.

   

  If wishes were PSoCs, everyone would have a $1,000.00 a month electric bill .

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

FYI: The spokewidth of the DMA is 4 bytes max (mem-to-mem) and 2 or 1 byte wide for peripherals-

   

And btw: Your bill can be dramatically lower when using the CY8CKIT-059

   

 

   

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

  That 059 kit will be great!

   

  I am past *some* of my stupid user tricks.  I now am having issues with nrq from my dma unit.  Attached is my schematic, nrq.png.

   

  The problem I'm having is I'm getting NRQ signals when I should not be getting them, as the DMA unit should not be running, there are no edges to trigger a transfer.  Does anyone have any suggestions?  I've re-read the documentation, and I believe I'm setting the flags properly.

   

  Note that I *know* that only the first two TD's have DMA_1__TD_TERMOUT_EN.  I did that on purpose to see if the pattern on the scope changed.  it did.  The NRQ signals are now grouped.  (I also understand I'll possibly have to synchronize the AND gate logic with a FF later on.)

   

 

   

  Any suggestions from anyone?   Thanks ahead of time!

   

  Brief description follows of settings:

   

  When ReceiveGateEnable goes high, Pin_DMA_REQUESTED shows pulses 6.8us apart (147,000HZ).  When low, nothing.  0 volts, as it should be with the "AND" gate macro in there.

   

  DMA_DONE is showing 75ns pulses 1.12ms apart, even whenPin_ ReceiveGateEnable is LOW, and DMA_REQUESTED is LOW.

   

 DMA_1 is set for Rising Edge, Hardware Termination disabled.

   

 ADC is set for 150,000 sps, continuous.

   

  The dma configure code follows:

   

 

   

#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_BASE)
 

   

 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();
    DMA_1_TD[1] = CyDmaTdAllocate();
    DMA_1_TD[2] = CyDmaTdAllocate();
    DMA_1_TD[3] = CyDmaTdAllocate();

    CyDmaTdSetConfiguration(DMA_1_TD[0], NUM_SAMPLES_TO_TRANSFER, DMA_1_TD[1], DMA_1__TD_TERMOUT_EN | TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
    CyDmaTdSetConfiguration(DMA_1_TD[1], NUM_SAMPLES_TO_TRANSFER, DMA_1_TD[2], DMA_1__TD_TERMOUT_EN | TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
    CyDmaTdSetConfiguration(DMA_1_TD[2], NUM_SAMPLES_TO_TRANSFER, DMA_1_TD[3], TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);
    CyDmaTdSetConfiguration(DMA_1_TD[3], NUM_SAMPLES_TO_TRANSFER, DMA_1_TD[0],  TD_INC_DST_ADR | TD_AUTO_EXEC_NEXT);

    CyDmaTdSetAddress(DMA_1_TD[0], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)SonicBuff[0]));
    CyDmaTdSetAddress(DMA_1_TD[1], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)SonicBuff[1]));
    CyDmaTdSetAddress(DMA_1_TD[2], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)SonicBuff[2]));
    CyDmaTdSetAddress(DMA_1_TD[3], LO16((uint32)ADC_DelSig_DEC_SAMP_PTR), LO16((uint32)SonicBuff[3]));
   
    CyDmaChSetInitialTd(DMA_1_Chan, DMA_1_TD[0]);

    CyDmaChEnable(DMA_1_Chan, 1);

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

It is hard work to search your code without help of the IDE. Can't you upload your complete project? To do so, use
Creator->File->Create Workspace Bundle (minimal)
and attach the resulting file.



Bob
PS: I'll be back in 10hrs

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

I just see: AUTOEXEC_NEXT means: Transmit the next chunk (in your case 1 byte) without a new drq signal. In your case an ADC value will be transmitted but is not ready yet, so you'll get garbage.

   

 

   

Bob

0 Likes
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

  Hmm.  I thought AUTO_NEXT meant that the chain would continue automatically without me having to start the DMA unit.

   

.

   

  I'll give it a try.  Thanks!

0 Likes
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

  I guess I don't understand the DMA unit at all.

   

  It only puts out an NRQ once every 25 or so transfer sets of 3,750 bytes each.

   

  Assuming the signal is operating properly, the DMA unit is missing most of the drq transitions.

0 Likes
lock attach
Attachments are accessible only for community members.
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

 here is the project

0 Likes
lock attach
Attachments are accessible only for community members.
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

This is probably a stretch but you could use a 16 bit PWM as a  12 or 16 bit DAC.

   

The issue you will have is settling time of the integrating filter needed for the PWM

   

output. You basically tradeoff ripple depending on filter chosen.

   

 

   

Attached some useful info to help.

   

 

   

Regards, Dana.

0 Likes
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

Thanks, Dana.

0 Likes
WaMa_286156
Level 5
Level 5
First comment on blog 100 replies posted 50 replies posted

    I have a final comment on this thread.

   

   Basically the user is unable to place any logic between the ADC EOC and the DMA unit DRQ and have the DMA unit reliably operate. 

   

.

   

  From what I can tell, internal timing gets skewed to the point that DMA silently fails a large part of the time (over 70% of the time).  You can usually transfer 10 to 100 samples total before issues, but not much more.  1,000 samples and above fail silently.  You still get DMA transfers, but random number of transfers fail between successful transfers.

   

.

   

   By fail, I mean that the DMA transactions never take place.

   

.

   

   In addition, it is nearly impossible to snoop on the EOC to DRQ signal data path using logic (i.e. a NOT gate, ANDgate, OR gate ) going out to a pin.  The logic elements will place and route, but not show activity on an oscilloscope, even with peak detect acquisition.  I was able to see transactions using logic, but it took several tries, and screwed up the timing when I finally was able to peek at the signal path.

   

.

   

  The AUTO_EXEC parameter is not needed for the *next*TD to pick up and work. I'm not sure what it really is for, except possibly to bridge between "third" samples from an unit, for example. (Although even that is suspect, except in single DMA Packet triggers where you don't know how many bytes you will exactly get and you need to keep reading regardless.)

   

.

   

  If you connect the ADC EOC directly to the DMA DRQ, then the transfers happen reliably.  However, this means you loose almost all ability to have real time hardware control over DMA transfer patterns from the ADC.  You can control from the CPU using the API, I would suspect, but that is near real time, and will vary depending upon IRQ execution and other firmware execution patterns.

   

.

   

  Just be aware of this significant limitation in the PSoC combined logic/hardware architecture.

0 Likes