CyDelay() not working when UART interrupts enabled

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

cross mob
BigBox
Level 1
Level 1
First question asked Welcome!

Hi,

I have enabled UART interruptes and I am tracking RX FIFO not empty. When I enabled interrupts then CyDelay() stopped working. The program would stop when calling CyDelay() function.

Is this a known issue and what is the solution?

Thank you

 

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

@BigBox ,

I'm making an assumption about your code since you haven't shared it here.

I'm assuming: 

  • The CyDelay() call is in the main-level task
  • The check for Rx FIFO not empty is at the interrupt level.
  • When checking for Rx FIFO not empty, you are looping until it becomes not empty.

As @MotooTanaka and @odissey1 pointed out CyDelay() is a SW-only routine.   If it is at main-level (ie. no interrupts active), then an interrupt that becomes active will jump out of the main-level task and continue running the task once the interrupt code is complete.

If you are looping in the interrupt waiting for the UART Rx FIFO to be not empty this could take a while.  The UART by its very nature is Asynchronous (hence the 'A' in UART).  This means it may be difficult to predict when data is transmitted from the UART device at the other end.   

If you are waiting for the Rx FIFO to be not empty, this interrupt loop will cause potentially significant delays in going back to the main-level task.

It is very possible I didn't identify your issue since I'm making some guesses.

If you are willing to share your project with the forum, there are at least the three of us who have responded to this post who would be willing to review your code.

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

View solution in original post

0 Likes
3 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,
If I remember correctly, CyDelay() was implemented using a software loop.
And it does not guarantee exact time, but it provide delay "longer" than the specified value.
So hardware interrupt such as UART interrupts should have higher priority.

If you want to use a timer which will not be affected by other interrupts,
use SysTick or other Timer Component(s).
I'd prefer SysTick though.

You can find a KBA for SysTick / Using the SysTick Timer in PSoC® 4 – KBA91374
https://community.infineon.com/t5/Knowledge-Base-Articles/Using-the-SysTick-Timer-in-PSoC-4-KBA91374...

And I also posted a sample /  A sample of emulating millis() from arduino in PSoC (CY8CKIT-044/CY8CKIT-059) 
https://community.infineon.com/t5/Code-Examples/A-sample-of-emulating-millis-from-arduino-in-PSoC-CY...

moto

lock attach
Attachments are accessible only for community members.
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

As MotooTanaka said, the CyDelay() and the interrupts don't go along well. There could be all kind of issues when using CyDelay() in the code as it becomes asynchronous. Though it is widely used in Arduino universe, it is not advisable to rely on it.

Attached is a basic demo showing PSoC4 SCB UART Rx strings processing using interrupts. The demo uses SCB UART to receive simple Terminal commands like R255\LF\CR or G127\LF\CR, etc. to control brightness of the RGB LED on the CY8CKIT--044 Pioneer Board. 

The project was last compiled using Creator 4.4

UART_SCB_Rx_01_A.png

Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

@BigBox ,

I'm making an assumption about your code since you haven't shared it here.

I'm assuming: 

  • The CyDelay() call is in the main-level task
  • The check for Rx FIFO not empty is at the interrupt level.
  • When checking for Rx FIFO not empty, you are looping until it becomes not empty.

As @MotooTanaka and @odissey1 pointed out CyDelay() is a SW-only routine.   If it is at main-level (ie. no interrupts active), then an interrupt that becomes active will jump out of the main-level task and continue running the task once the interrupt code is complete.

If you are looping in the interrupt waiting for the UART Rx FIFO to be not empty this could take a while.  The UART by its very nature is Asynchronous (hence the 'A' in UART).  This means it may be difficult to predict when data is transmitted from the UART device at the other end.   

If you are waiting for the Rx FIFO to be not empty, this interrupt loop will cause potentially significant delays in going back to the main-level task.

It is very possible I didn't identify your issue since I'm making some guesses.

If you are willing to share your project with the forum, there are at least the three of us who have responded to this post who would be willing to review your code.

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