UART rx interrupt redirect

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

cross mob
RuPi_283656
Level 4
Level 4
10 sign-ins First solution authored 25 replies posted

How can I redirect the rx interrupt to my own handler code (PSOC5)?  For the timer it is easy, just use TimerInterrupt_SetVector, but a comparable function for the UART interrupts does not seem to exist.

   

I really need to have my own code for the rx interrupt...

   

Thanks, Russ

0 Likes
9 Replies
lock attach
Attachments are accessible only for community members.
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Just attach ISR component to UART and use placeholder file that

   

produces for code or use your own C interrupt.

   

 

   

   

 

   

http://www.cypress.com/documentation/application-notes/an54460-psoc-3-and-psoc-5lp-interrupts     AN54460 - PSoC® 3, PSoC 4, and PSoC 5LP Interrupts

   

 

   

Regards, Dana.

   

0 Likes

Thanks Dana. It is not clear to me how this works.  Currently when the UART receives a byte, it generates an interrupt to the processor and that byte is then placed in the rx buffer.  To do this, there has to be a software interrupt vector that transfers control from the main processor loop to the rx interrupt routine.  What is not clear to me is how adding an interrupt component can change the vector to point to my own code.  I thought the interrupt components were for external interrupts only???

   

Thanks, Russ

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

The interrupt components require a signal (from any other component) to get triggered. When you use the UDB-based UART there are some differences whether you use a buffer or not.

   

When a character is received by the component it is at first transferred into a FiFo. When you use a buffer, an internal interrupt will fetch the FiFo-byte(s) and transfer them into the buffer. No user interrupt should be used for this settings, instead you shpould poll for RxBufferSize() > 0 to see if something went into the buffer.

   

Without the buffer, you can get interrupted and fetch the byte(s) out of the FiFo yourself. Use an isr component connected to the UART-interrupt line and setup the handler using isr_StartEx(). Do not forget to clear the interrupt cause within the handler, usually by reading off the bytes and reading the RxStatus.

   

 

   

Happy coding

   

Bob

0 Likes

Ok that helps, thanks Bob. What I was hoping to do was revector the interrupt, then copy the UART_INT.c code to my own routine and then modify it to allow it to detect certain data and set some flags.  Polling is too slow in this case.  I guess I have to set the uart buffer size to 4 and then use it like you said.  Thanks - Russ

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

Polling might not be too slow, the transmission of a single byte usually takes quite a lot of time compared to the 48MHz the CPU may run.

   

Usually I suggest to write a circular buffer program to retrieve data from FIFO and storing them. Within that process you may detect certain data and act accordingly.

   

 

   

When you are a bit more specific about the problem you work on we could be more specific with our suggestions.

   

 

   

Bob

0 Likes
JiGi_284761
Level 4
Level 4
Welcome!

Using the existing buffer usually works well for me.

   

Set the receive buffer to match your protocol frame size or whatever is convenient for your process.

   

Then you just need to poll and parse the data to your storage structure.

   

You can poll by time or by rx status.

   

uint8 UART_ReadRxStatus(void)

   

This function returns a uint8  1xxxxxxx if data 0xxxxxxx if no data is available.

   

UART_RX_STS_FIFO_NOTEMPTY

   

You will need to give yourself some delay after the FIFO status changes to allow for the entire frame to arrive. This will be based on your baud rate and processor speed.

   

Just remember to disable the rx interrupt first thing in your polling function. Then get your data from the internal buffer like this:

   

for(i=0;i<=10;i++)

   

{

   

Process.DataIn = UART_1_GetChar();

   

Then clear the buffer

   

Then enable the interrupt.

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

You will need to give yourself some delay after the FIFO status changes to allow for the entire frame to arrive. This will be based on your baud rate and processor speed.

   

There is no latency between the FIFO status set and a byte completely received

   

Just remember to disable the rx interrupt first thing in your polling function.

   

No need to do so, the component's APIs care for that

   

Then get your data from the internal buffer like this:

   

for(i=0;i<=10;i++)

   

{

   

Process.DataIn = UART_1_GetChar();// I would suggest to check first whether there are any characters in the buffer before retrieving any data

   

Then clear the buffer No, No need to do so except in the case of an error detected

   

Then enable the interrupt. No need to since you do not need to disable it

   

 

   

Concerning interrupts:

   

When a system/project grows there can be several different places that need to run with interrupts disabled. To avoid side effects i strongly suggest to use the functions CyEnterCriticalSection() and CyExitCriticalSection() which care for the original state of the interrupts enabled at the time called. Look at the "System Reference Guide" from Creator's Help menu.

   

 

   

Bob

0 Likes
RuPi_283656
Level 4
Level 4
10 sign-ins First solution authored 25 replies posted

Thanks Bob and all for your comments.  I got the interrupt routine done and it works perfectly.  Fortunately all my rx data is in a standard format of a short fixed length header followed by variable length data.  Now the entire message is received and then a flag is set to alert the main loop to react.  That part worked ok with the polling routine too, although slower.  But the big fix is that the int routine can now detect a 'stop' command and set a flag that allows the firmware to stop processing.  Now I can simply look for the stop flag in multiple places without taking time to decode the input command strings.

   

Thanks again, Russ

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

Russ, you are always welcome!

   

 

   

Bob

0 Likes