Using a full duplex UART in a PSoC5 design.
I don't understand how the interrupts work when the RX Buffer Size is > 4.
From the data sheet:
When the (Rx/Tx) Buffer size is set to a value greater than 4, the UART component uses the internal interrupts to move the data from Hardware FIFO to a software FIFO. In this case, use the internal ISR to add custom code to process the data in the "User Code" regions.
Note External interrupts are generated only with respect to the Hardware FIFO.
Does the ISR_UART_RX (auto-generated) fire when the received data overflows the RX Buffer Size that I have specified? Or does it fire after each byte is received?
I have looked at the example projects and it's not clear.
Does the internal interrupt work in the background to transfer the bytes into the buffer, or does it trigger the ISR_UART_RX auto-generated code?
In my application, the RX will received data from another internal board, so I know exactly how many bytes to expect (46 bytes). So if I can fire the ISR when that many bytes are received that's fine.
Does the ISR_UART_RX (auto-generated) fire when the received data overflows the RX Buffer
No, it fires when there is at least one byte in the receive FIFO and transfers the data into the buffer.
Easiest would be to poll using UART_GetBufferSize() API which returns the number of bytes actually in the buffer (not the size of the buffer)
Thanks Bob -
So tell me if this is correct: each received byte triggers the ISR, and also transfers that byte into a software buffer. When I read athe data using UART_ReadRxData(), I get the most recent byte in that buffer?
Is there a way to read the receive buffer as a character array? I want to wait for 46 bytes to be received, then process those bytes, then clear the buffer and wait for the next 46 bytes.
In the data sheet for the UART I do not see a way to access the buffer as an array.
The buffer is arranged as a circular buffer. So, although it is a byte array, it is difficult to access the data as array.
When you do not want to poll as I described before, you need to write your own interrupt handler This is not too difficult when triggering on FIFO not empty.
Thanks, yes I've been modifying an example project on a DVK and I see that it works great if I just load up my own array as the data comes in. Set the UART RX buffer to 4, enable the "On Byte Received" interrupt, and then just fill up my array and keep track of how much data is in there. That's working fine so I'll stick with it.
Better use the "FIFO not empty" interrupt. Transfer from receiver to FIFO is done in hardware, so some heavy CPU usage will not cause data to be overwritten with the next byte.
So what is the purpose of increasing the buffer size >4 bytes and using RAM, then? It seems like you have to write an ISR to read out the bytes one-by-one either way? And either way it interrupts after a single byte is received?
There is little advantage of using an Rx buffer >4 bytes. As you noted, either you use the internal Rx ISR or an external ISR. No real savings.
On the other hand, using the internal Tx ISR for a buffer size > 4 byes can be a simplicity.
Let's say you always transmit 40 bytes at a time. You can allocate the 40 byte buffer and use the internal Tx ISR. All you have to do is use the _PutArray(forty_bytes, 40) call for the 40 bytes and call the _ReadTxStatus() for a UART_TX_STS_COMPLETE to know it is done.
"Engineering is an Art. The Art of Compromise."
Ah, OK. So TX buffer allows us to dump things into it without blocking and check that they got sent later, while RX buffer isn't really useful? (Maybe if you have a higher priority interrupt that is preventing the RX interrupt from firing and so you need a longer amount of data cached or something?)