how to count a 1 shot DMA sequence

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

cross mob
SeMu_3557896
Level 1
Level 1
5 replies posted 5 sign-ins First solution authored

Hello,

I'm building a TFT display system that needs a small sequence for each pixel data transmitted:

  1. DATA byte update
  2. WR bit to 0
  3. WR bit to 1

I thought about implementing these 3 steps by using 3 chained TDs configured like that:

	CyDmaTdSetConfiguration(GUI_RX_TD_data,
					1,
					GUI_RX_TD_ctrl1,
					CY_DMA_TD_AUTO_EXEC_NEXT);
	
	CyDmaTdSetConfiguration(GUI_RX_TD_ctrl1,
					1, 
					GUI_RX_TD_ctrl2,
					CY_DMA_TD_AUTO_EXEC_NEXT);
	
	CyDmaTdSetConfiguration(GUI_RX_TD_ctrl2,
					1, 
					GUI_RX_TD_data,
					GUI_RXdma__TD_TERMOUT_EN);

Now the question:

What is the [best|standard] way to count the number of times this sequence will occur knowing that I need a signal telling me the total number of bytes have been transmitted?

NOTE 1: I'm no FPGA specialist and ran into timing violations when trying different counter approaches or coundn't get a clear end of complete signal sequence.

NOTE 2: I even considered a indexed approach: having tables of data/ctrl1/ctrl2/next_TD, going full AUTO_EXEC_NEXT, but that doesn't work because the TDs should not be re-initialized on completion in order to increment throught the tables... and that would set our xfrcnt to 0 after the first sequence 😞

Thanks in advance for your help,

Serge

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
SeMu_3557896
Level 1
Level 1
5 replies posted 5 sign-ins First solution authored

Hello odissey1,

I finally solved my problem differently:

I used a dma to count the number of times the sequence should occur (and to update the data to transfer during the sequence). The problem was to make sure the data is updated before being transfered:

to solve that problem, I reversed part of the sequence:

  1. transfer the data
  2. activate the updating DMA
  3. transfer the ctrl 1 byte
  4. transfer the ctrl 2 byte
  5. restart

Due to the higher priority given to the updating DMA, the data is refreshed before the sequence restarts.

Note: the whole pulse generating flipflops are not really necessary: a simple CPU_REQ on DMA_sequence would suffice but I wanted to keep it as a reminder 😉

Thanks for your help.

Serge

View solution in original post

0 Likes
7 Replies
AlenAn14
Moderator
Moderator
Moderator
500 replies posted 100 solutions authored 250 replies posted

Hi @SeMu_3557896 ,

Can you please let me know the part number of the PSoC device on which you are using DMA?

Since you are using the configuratino paramter 'DMA__TD_TERMOUT_EN' for the last TD, it should generate a pulse on the TERMOUT of the channel.

AlenAn14_0-1647526564826.png

AlenAn14_1-1647526741021.png

 

Have you tried using this interrupt generated on the nrq pin to do the count operation of how many times the specified chain of TD's was executed assuming that the TD's you mentioned above are chained to each other.

Warm Regards
Alen

0 Likes

Hello Alen,

Thank you for your reply. I'm using a PSoC 5LP CY8C5868AXI-LP032.

Using TERMOUT on the last of the 3 TDs is the way I figured out to be sure that when the interrupt fires, I know the last transfer of the sequence is done. This is usefull for synchronizing the global sequence.

My problem (maybe too obvious for experienced devs) is: how exactly are you implementing the counting/disabling of the sequence? how can I be sure that the last fired TERMOUT increments the counter, then disable the channel or terminates the chain or nullifies DRQ before the next burst takes place? (meaning: I'm such a n00b that I don't know any classical DMA + counter implementation...)

I was thinking of having TERMOUT fired after the first TD terminates so that I'm (relatively) sure the DRQ can be reset before we chain back to the first TD. By doing that, I still have the problem that I have to check via interrupt that the chain is not active before starting the next sequence (those sequences being multiple bursts of commands, parameters and data).

Kind Regards,

Serge

0 Likes

Hi @SeMu_3557896 ,

The method of using a counter in the interrupt of the TERMOUT is the best way to know how many times the sequence has fired since there are no other register that keeps track of this.
Make sure to declare the the counter variable as volatile to avoid any optimizations by the compiler leading to misses in count increment in the TERMOUT interrupt.

You can also use the CyDmaChStatus to monitor if the TD chain is active or not :

AlenAn14_0-1647609450067.png

Please refer to the DMA component datasheet to know more about this.

Warm Regards
Alen

0 Likes
lock attach
Attachments are accessible only for community members.
SeMu_3557896
Level 1
Level 1
5 replies posted 5 sign-ins First solution authored

Dear Alen,

Sorry for my late reply. I think I got the idea about using interrrupts. Unfortunately, doing it this way doesn't really fit my needs. I would like to fire and forget the whole sequence: i.e., the solution should be implemented on the TopDesign.cysch level. 

I thought about something like in the attached file. Unfortunately, I got a timing violation when the bus clocks @ 48 MHz.

As I said, I'm looking for a confirmation this is a good way to do it 🙂

Thanks in advance,

Kind regards.

Serge

 

0 Likes

SeMu,

Note, that DMA "nrq" output is asynchronous to the BUS_CLOCK, while the Counter expects synchronous  "count" input. To resolve this issue, put a Sync component on the line between the DMA and Counter.

You may utilize a small Sync component to save space on schematic

Sync32 custom component for PSoC5 and PSoC4

0 Likes
lock attach
Attachments are accessible only for community members.
SeMu_3557896
Level 1
Level 1
5 replies posted 5 sign-ins First solution authored

Hello odissey1,

I finally solved my problem differently:

I used a dma to count the number of times the sequence should occur (and to update the data to transfer during the sequence). The problem was to make sure the data is updated before being transfered:

to solve that problem, I reversed part of the sequence:

  1. transfer the data
  2. activate the updating DMA
  3. transfer the ctrl 1 byte
  4. transfer the ctrl 2 byte
  5. restart

Due to the higher priority given to the updating DMA, the data is refreshed before the sequence restarts.

Note: the whole pulse generating flipflops are not really necessary: a simple CPU_REQ on DMA_sequence would suffice but I wanted to keep it as a reminder 😉

Thanks for your help.

Serge

0 Likes

Hi @SeMu_3557896 ,

Glad your query is resolved and thank you very much for sharing the solution with the community as well !
Please feel free to post any queries or issues you may have on Infineon products in the community and we will be happy to help.

Thanks & Warm Regards
Alen

0 Likes