The mechanics of UART DMA reads from FIFOs...a couple of questions

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

cross mob
Anonymous
Not applicable

All: perhaps it is my limited cranial capacity, but I am unable to understand exactly how the data is processed into the FIFOs by the UART component and subsequently read out by a DMA.

   

1) There are two 4 byte FIFOs in each UDB and the UART is (duh) UDB-based. I assume one FIFO is used for the Rx, the other for Tx. Now, do we have a static 4 FIFO elements only for 8 bits, or can they be concatentated/subdivided (2 FIFO elements for 16 bits, etc.)?

   

2) How do you point the DMA to the correct spot in the FIFO, or is that simply task handled autonomously by the FIFO control logic?

   

3) What happens if you're trying to read data while the FIFO overruns...it the incoming data simply pre-empted or is the read-out data now corrupted.

   

4) What is the correct address to use for setting up the DMA. Is the base address PERIPHERAL _BASE? Or should I use UART_($number)_RXDATA_PTR? I assume the upper 16 bits are the UART_RXDATA_PTR.

   

5) In the UART header file, I notice there is a pointer to the RX_DATA buffer (UART_RXDATA_PTR) and a pointer to a pointer to type reg associated with the buffer (UART_RXDATA_REG). What is the latter used for? Call me dumb by why do you need a pointer to a pointer to the register? Is it used as an argument to some function somewhere?

   

I tried to find this granularity of data in the TRM documents but thus far I've been unable, so pardon me if any of these questions seem ignorant but I just don't know where to find the detailed information.

0 Likes
12 Replies
Anonymous
Not applicable

The title really should be "the mechanics of DMA reads from UART FIFOs". Sorry for the confusion!

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

Answer

   

1: as far as UDBs are concerned: Yes, you may combine them to form 16, 24 or 32bit wide devices having FiFos of the same size.

   

2. It is a FIFO, so you simply read from it and get the actual value

   

3. Nothing rerliable will happen, an overflow will be indicated by the hardware. Its the same as crossing the street having a red light: you cannot reliable forcast what will happen, you just now that this is wrong

   

4. The UART is a peripheral and so the source's address upper word will be PERIPHERAL_BASE and the lower address word (specified in the TD) will be the register.

   

5. Since you need an address here, there is a pounter to the register (which is an address) . To specify a register in C you need some construct that looks like a pointer, but really isn't one, so do not get confused.

   

I'll need a coffee now....

   

To understand UDBs and FIFO implementations there are some videos concerning that theme, showing you how to create "DataPath" components using a small microcodable ALU (Arithmetic and Logical Unit). The videos are each not less than twenty minutes and I watched them some times ago and decided that this would be too complicated for me. Just recently I re-viewed them and I tried some examples which really worked, but you need to learn a lot more: At least basic knowledge of using VeriLog is needed, but just to have a look at the bur5ied capabilitiies of PSoCs is worth watching the vids.

   

 

   

Happy FIFOing

   

Bob

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

Sorry for the typos, but I'm 1.85m (6'2") hight and the size of my figertips doesn't match the size of my laptop keyboard

0 Likes
Anonymous
Not applicable

Bob: thanks for your reply. My question about the two pointers is this: one is a pointer to a reg8, the other is a pointer to a pointer to reg 8. It is this pointer to a pointer that I don't get...why is it needed? There must be some function that requires it for an input argument, but what function(s) would this (those) be?

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

   

 

       

   

#define UART_1_TXDATA_REG (* (reg8 *) UART_1_BUART_sTX_TxShifter_u0__F0_REG)

   

The first asterisk means "What the following points to" and the following is a "reg *":, a pointer 

   

In other words: what the pointer points to, which is a reg(ister) Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

There is an interrupt that indicates overrun, accessed by reading status register. uint8 UART_ReadRxStatus(void)

   

This allows you to decide what to do in this case.

   

 

   

1) There are two 4 byte FIFOs in each UDB and the UART is (duh) UDB-based. I assume one FIFO is used for the Rx, the other for Tx. Now, do we have a static 4 FIFO elements only for 8 bits, or can they be concatentated/subdivided (2 FIFO elements for 16 bits, etc.)?

   

I think Bob is right on this, the FIFO in the UDB is not cascadable to another UDB. But best to file a tech case at

   

https://secure.cypress.com/myaccount/?id=25&techSupport=1&source=header&CFID=1039603&CFTOKEN=3615642...

   

to make sure of this. You could consider a custom module based on vanilla module, but thats clearly some extra work

   

needed.

   

 

   

2) How do you point the DMA to the correct spot in the FIFO, or is that simply task handled autonomously by the FIFO control logic?

   

The FIFO is clearly an SRAM based component, to Bobs point, the register to read must be spelled out in the Register TRM

   

for PSOC 5. You could always look at other FIFO entries, but that does not seem necessary based on your problem

   

description.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

Dana: I think perhaps I gave an incorrect impression. This isn't a problem so much as I want to understand what is going on. I have not been able to get the uber-fine details needed from the documentation thus far. The trouble is, the details matter.

0 Likes
Anonymous
Not applicable

Bob: not to nitpick, but I disagree:

   

#define UART_1_TXDATA_REG (* (reg8 *) UART_1_BUART_sTX_TxShifter_u0__F0_REG)

   

 

   

UART_1_BUART_sTX_TxShifter_u0__F0_REG by my understanding is a pointer to reg 8, in this case what appears to be a FIFO for the Tx data (not the same thing I was referring to but related). I do not think this is the register itself, just a pointer to this register.

   

UART_1_TXDATA_REG should thus be a pointer to this pointer. My question regards why you'd even need a pointer to a pointer to something like this if you can just follow the original pointer.

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

I'd perfectly understand what you meant, but you are not taking into account the first "*".in the definition. It de-references the term following, which is a pointer indeed.

   

Do not mix a declaration with a reference to a variable, this #define will just replace UART_1_TXDATA_REG with the text following and that starts with an asterisk like

   

 

   

void * MyPointer;

   

uint8 ii;

   

ii = (* (uint8 *) MyPointer;

   

Here you do not find a pointer to a pointer as well.

   

 

   

Bob

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

.. and here is the missing ")" :  )

   

Bob

0 Likes
Anonymous
Not applicable

Bob: you are absolutely correct, my mistake. I was thinking about this last night...yep, they are dereferencing a pointer, and casting this pointer as a type pointer to reg 8, just as you say. I think you hit on something as well...they probably DO initially cast the pointer as a type pointer to void and then later recast it to * reg 8.

   

Well, thanks for playing "debate with a dummy". As usual I lost the argument but it was fun anyway.

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

No excuses for asking questions.

   

When I started my career I engaged the programming help-desk of the IBM360 in a nuclear power research centre for half a day: I had written a program that refused to link with the message "Symbol PL0T could not be resolved" with the background that the FORTRAN-Plot routine was commonly used.

   

It took them half a day to find out that I spelled "PL0T" with a "0" (Zero) instead of the letter "O".

   

 

   

I excused myself for beeing so stupid and having taken so much of their time and they answered:

   

"We have to excuse ourselves that it took us so long to find and show you the obvious, but we still learn..."

   

 

   

You are always welcome!

   

Bob

0 Likes