Access DMA internat registers

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

cross mob
YaLe_3489106
Level 2
Level 2
10 replies posted 5 replies posted Welcome!

I'm using a DMA to receive data from an UART and store them to RAM. It works correctly. I need to use the preserveTds option. At a given time, I'd like to know how many bytes are received. To know that, I'd like to know where (the address in RAM) the DMA destination pointer points.

The CyDmaTdGetAddress function returns the adresse of the original (preserved) TD, not the intermediate one.

I see in the CyDma.c file, in the CyDmaChEnable function, a comment saying:

Store intermediate TD states separately in CHn_SEP_TD0/1 to preserve original TD chain

I guess the information I'm looking for is in this intermediate TD state. So my question is: is there a way to access those registers to know the current addresse where the destination pointer points?

0 Likes
1 Solution
Hari
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hello YaLe_3489106

LePo_1062026​ is correct. Since DMA is implemented as a hardware block, a register cannot be read to find the location of the transmit buffer. The counter would be the only method to keep a count of the number of transfers.

Thanks and regards

Hari

View solution in original post

0 Likes
9 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

YaLe,

I was involved in a discussion on this forum with a similar question.  Here is the link to that discussion.  Hopefully it will help.

UART RX DMA loop

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Yes, I'm the same poster. The answer there is a solution, but I have a lot of setup time violation, or I need to lower master clock too much because of the counter. I'd like to find another approach, by looking at the current destination address.

0 Likes

YaLe,

I see this problem differently - UART is inherently asynchronous and slow protocol, this it is ok to process incoming data using interrupts on time of arrival. If this, otherwise, continuous stream at Max speed, the DMA is ok, but actual position in the RAM is not very important.

/odissey1

0 Likes

Right, I could do a RX_buffer[index++] = received_char; in the rx interrupt, but I don't like the idea to be interrupted at 115200 / 10 = 11kHz. There may be another interrupt running, so I have to be careful on priorities. I could have a try, but DMA is a nicer way to get data in the background.

Position in the RAM is needed to know how many bytes has been received. My DMA is configured to be a circular buffer that run continuously, and I need to know if data are received, how many, to treat them.

0 Likes

YaLe,

At 115k by time  UART_Rx interrupt fires, there will be several chars in the buffer already, so actual isr rate will be in ~1kHz rate, which isn't that bad. I suggest to try existing demo to see if this works for your project, like this one:

UART string reception garbage value

/odissey1

0 Likes

Thanks for your suggestion.

115200 / 10bits per byte = 11520 bytes per seconds. The buffer can have 4 bytes max, so if buffer is full before interrupt is raised (I don't see why it would ...) then the minimum interrupt frequency is 11520 / 4 = 2,88kHz, and maximum frequency is 11,52kHz.

I'll test if that can fit my needs, even if I don't find this workaround very nice.

My first question remain, is it possible to access internal DMA registers.

0 Likes

YaLe,

I've looked at the PSoC5LP TRM (001-82120_PSoC5LP_Registers_TRM.pdf).  There does not appear to be an interface register to read the current transfer count of the DMA.  If I am correct, the DMA is implemented as a SPC interface which can be the equivalent of a HW state-machine interface to internal HW.

Unless Cypress can shred more light on your question, the suggestion of a parallel counter to DRQ signal may be your only means of determining approximately where the DMA transfer has progressed.

Question to the forum:  Is it possible to create a 2 TD implementation where the first TD reads the comm byte memory and the second TD increments the a count in memory?  The DMA configuration loops back to the first TD.

Len

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
Hari
Moderator
Moderator
Moderator
750 replies posted 500 replies posted 250 solutions authored

Hello YaLe_3489106

LePo_1062026​ is correct. Since DMA is implemented as a hardware block, a register cannot be read to find the location of the transmit buffer. The counter would be the only method to keep a count of the number of transfers.

Thanks and regards

Hari

0 Likes

Thanks for clarification!

0 Likes