- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Russ, you are always welcome!
Bob