You are here

UART TX and RX interrupts | Cypress Semiconductor

UART TX and RX interrupts

Summary: 14 Replies, Latest post by odissey1 on 11 Jun 2015 04:15 PM PDT
Verified Answers: 0
Last post
Log in to post new comments.
sstbrg's picture
5 posts

 Hi, I'm new to PSOC and uC in general. I've used Atemga in the distant past but I pretty much forgot many concepts...

I just want to understand the theory here...

I'm implementing a UART in PSOC5 (CY8CKIT 001 dev kit).
I need to send 7-byte long messages to another circuit, which will, after about 100ns, return a 15-byte long answer.
I want to use an interrupt to indicate that a byte has been sent and another interrupt to receive the answer.

I configured the UART like so: buffers set to 16 bytes and 2 ISR components connected to the rx/tx_interrupt pins.

As far as I understand, when I have two interrupts with the same priority, in my case the TX interrupt will be generated at first, then after reading the status and clearing the interrupt, the program should jump to the second interrupt (RX received), read everything from the rx-fifo and return to main()... then if more bytes arrive, it will just jump tp the rx interrupt and repeat the reading process.... what do I need to do to accomplish this? Are there any example projects available with 2 interrupts acting like I described?


I hope my questions are clear, if not I'll be happy to explain myself :-)


user_1377889's picture
9301 posts

The internal structure of the UART - implementation uses interrupts when you specify a buffer larger than 4 bytes (which is the size of the FIFO). These interrupts are called "internal". As you see, the Rx-OnByteReceived and Tx-OnFifoEmpty interrupt sources are greyed out when you use a buffer.

On the Rx-side the only interrupt-sources remain are dealing with errors or addresses

So when using buffered I/O you will have to poll the RX and TX-status to see what's going on

The advantage is that you may transfer your 7-byte message with a single API (UART_PutArray() ) to the UART which will handle the transfer.

There is an API to check the receive-buffer for the number bytes received.


To do-it-yourself:

In Schematic editor

your thoughts about the way the interrupts work looks quite right. To implement your own routines do the following:

Set the buffer-size back to 4 which will disable the internal interrupts

Select your wanted interrupt-source(s)

Connect two ISR-components to Rx/Tx interrupt terminals.

In main()

declare two routines with CY_ISR_PROTO (look into help -> Documentation -> System Reference -> System Ref. Guide)

define the two routines with CY_ISR

In initialization use ISR_StartEx(YourIsrRoutineName)

That's it.

Happy interrupting





user_14586677's picture
7646 posts

You could consider using 4 byte buffer, and 9 bit data, use 9'th bit as

a framing bit on 7 byte xmit and 15 byte reply.


Regards, Dana.

sstbrg's picture
5 posts

Thank you for the fast replies, guys!

Bob, I see what you mean about internal interrupts. I did some reading too before posting this, but for some reason your reply here cleared things up a bit more... What I've noticed during debugging is that the program jumps to the internal interrupt routines first and only after handling those, it jumps to my custom routines.

Now, let's say I'm disabling internal interrupts like you suggested, and declaring my own routines. Let's say the program jumps to my RX routine... I guess I need to tell the CPU that I've handled that interrupt... how do I do that? I could only find the 'clear pending interrupt' function in the ISR.c file... does it do the job or maybe I don't need to do anything? :S

I'm using UART_PutArray()  now... it makes things simpler for sure. However I do want use the tx interrupt for indication purposes only, like so: polling the status, checking that the interrupt was generated because TX is done, and lighting a LED or writing something on the LCD. Am I in the right direction?

Now about the buffers... say I'm setting the number of bytes in a buffer to 16. Can I simply poll the status of the RX buffer and check that there are 15 bytes in there (the packet which I received), then read those bytes one by one using a for loop or something? Another option might be using an interrupt to indicate that the RX buffer has received 15 bytes - is that possible?

Thanks again...



sstbrg's picture
5 posts

Sorry about the formatting of my reply above... it got completely screwed after posting for some reason...

user_1377889's picture
9301 posts

As a general rule-of-thumb the handling of interrups should be as short as possible. As such common practice is just to set a global flag and return while the main() polls the flag, reacts on it and resets it at end-of-operation.

When using the ISR-component you do not have much to do, just take care to set the interrupt-type to "rising edge". The interrupt-controller is cared for.

Do not get irritated when debugging with having ISRs! When a breakpoint is reached, the CPU is halted, but the hardware is still running! So when a byte is transfered and you are at a breakpoint within the isr another int may become pending. when you continue running it will be priorized as usual. This may not show the normal unbreaked flow of control.

Do not write something on LCD within an Isr !!!!! Within the LCD-access there are some hard-coded delay routines which will postpone any other isr-handling. Poll for that in the main-loop.

Here is an untested(!!!) example of an UART project using two interrupts and providing a circular buffer for the received characters.

user_66945721's picture
256 posts


I've written out some Interrupt based UART code tested on the CY8CKIT-030.

Check it out here




sstbrg's picture
5 posts

 Thank you guys, I'll check it out...

If more questions arise, I will reply here.


Thanks again.

user_242978793's picture
973 posts

Bob Marlowe I tried your program and it seems to work.  I cleaned up some text in it to agree with the process.  I have one question it seems that this was written for PSOC 4 and I used a PSOC Pioneer board to try it out.  I had one problem however.  The Uart didn't work at 230400 I had to drop it to 9600 baud to get it to work.  I am running PUTTY on an XP system I was wondering if that combo will not support that high of a baud rate. I was looking for a routine to input data for an RTC clock and needed a way to set the time and the ALARMS. I was also looking at the ASM function for the printf does this save on program size?  Thanks for your program  and I am awaiting your answers to the issues I discussed. Also sorry about opening such an old post.

user_342122993's picture
531 posts
user_342122993's picture
531 posts


Attached is example  project of using UART for receiving commands. It utilizes non-blocking circular buffer to receive characters from UART Rx and split them into command messages when termination characters are found (0x0D and/or 0x0A). Project closely follows code posted by Bob Marlowe before. This demo shows how to change colors of the LED on the PSoC4 PioneerBoard.


Each received message has one "command" byte followed by "value string":

<cmd><value string> <\r> [<\n>], example: R255\n (set red LED to 255).

 If one <cmd> byte is not enough for your commands, change it to 2 (or more).


Note that in this project UART rate was set to 230k to match speed  of my Bluetooth HC-05 dongle. Change it to your own UART rate.



P.S. see file attached in next post
Log in to post new comments.