Can PSOC 5LP DMA generate a signal after each transfer (not finishing TDs)

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

cross mob
Anonymous
Not applicable

Dear all,

I am wondering Can PSOC 5LP DMA generate a signal after each transfer (not finishing TDs)? I understand that NRQ can generate a signal of two clock cycles after the TDs is finished (I chained 16 TDs). I am asking because there are two DMA channels in parallel sharing the same spoke (DAC). They may or may not be at the same rate. I want to know when each transfer is done so I can align the signal. The master clock is 78MHz.

The signal I am trying to alian is the trigger out signal. So I generate a waveform from flash through dma to DAC and output to a GPIO. I want to generate a trigger signal which is aligned with the waveform to another GPIO. What I did is that I user a counter, and route the drq signal and count of the trigger together. I set the period of the counter to the number of points that DAC will output and compare threshold of the counter to be half of the number of the points in DAC. I then use the compare out as the trigger signal. I can get the trigger aligned when 2 DAC channel are used at maximum speed of 1Msps. When I set the update rate of both channel to 2Msps, the output signal in DAC and trigger are still correct in timing. However, the alignment is lost, and timing difference is keep shifting. In update rate between 1Msps and 2Msps, each time after the sequence is downloaded via USB, there is a chance that the alianment will miss but not each time.

I suspect it will be better if I can have access to the signal that each DMA transfer finishes as that will the be the exact time that I want to count in the counter.

Best,

0 Likes
1 Solution

DMA function:  cystatus CyDmaChStatus(uint8 chHandle, uint8 * currentTd, uint8 * state)

gives such information but it takes some time.

In addition, you can create an additional TD after each TD. (With the same DMA_SRC_BASE, DMA_DST_BASE)

...

CyDmaTdSetAddress( Info_TD,    LO16((uint32)&TDsTable),  LO16((uint32)Your_CONTROL_REG) );

...

TDsTable [] - contains TDs numbers.

Your_CONTROL_REG contains information about the number of the finished TD.

View solution in original post

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

It would be helpful to see entire project. It is my understanding that the goal is to stream data to 2 DACs synchronously at 1Ms/sec. There is solution proposed by <pavloven>, see e.g.

How do I change the phase of a sine wave generated by a DMA?

/odissey1

0 Likes
Anonymous
Not applicable

Thank you for the reply. I will update the project when I get back to office.

I can have dual channel DAC (each channel have two iDAC in parallel) with each update rate of more than 2Msps or 1 single channel DAC of roughly 4Msps with DMA. That part is working. The question lies in the trigger out of a DAC channel and the DAC output itself. Since the DAC output waveform is lead to GPIO, I need to provide a trigger signal to other instruments like the SYNC of traditional signal generator.

As mentioned before, I user a counter to make the trigger signal, and route the drq signal and count of the trigger together. I set the period of the counter to the number of points that DAC will output and compare threshold of the counter to be half of the number of the points in DAC. I then use the compare out as the trigger signal.

In this approach, I can get the trigger signal and its related DAC output aligned up to 2Msps for dual channel or the same 2Msps in single channel. When I keep increase the update rate, the DAC output is still correct. However, the trigger signal lost alignment with the DAC. I am not quiet sure what happened.

I am thinking that if I can have the signal when the DMA finish one tranfer (not finish the whole TDs), and use that to generate the trigger signal will be better as it is the real timing when the DAC is updated.

Do you know if there is a way to get that signal?

Best,

Jie

0 Likes

DMA function:  cystatus CyDmaChStatus(uint8 chHandle, uint8 * currentTd, uint8 * state)

gives such information but it takes some time.

In addition, you can create an additional TD after each TD. (With the same DMA_SRC_BASE, DMA_DST_BASE)

...

CyDmaTdSetAddress( Info_TD,    LO16((uint32)&TDsTable),  LO16((uint32)Your_CONTROL_REG) );

...

TDsTable [] - contains TDs numbers.

Your_CONTROL_REG contains information about the number of the finished TD.

0 Likes
Anonymous
Not applicable

That is a good idea. Do you mean dummy TD to indicate the start of waveform and use nrq signal?

Bes,

Jie

0 Likes

Yes, it will be dummy TD.

The nrq signal can be used to call an interrupt.

Interrupt function - read the TD number from the register Your_CONTROL_REG.

0 Likes

Jie,

Do you need an arbitrary wave output or pre-defined, like sine/ramp?

Re: lost syncronization, this is DMA inherent issue, as it needs some amount of clock to complete transfer, shared among all DMA channels. So once transfer rate reaches it's limit, DMA transffer gets skipped from time to time, leading to dissinchonization of the hardware timer and semi-hardware DMA. The  <pavloven> pointed you possible solution by chaining TDs. I will try to make you some example if time permits.

/odissey1

0 Likes
Anonymous
Not applicable

Hi odissey1,

I am using arbitrary waveform. If I can use pre-defined, I will choose LUT as you mentioned in some topics.

Best.

0 Likes