- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have read the data sheets on the ISR component and its API, and section 7 in the PSOC 5 TRM.
I still have some questions, partly because of inexperience. I need to handle an interrupt, send a pulse out with as little latency as possible, and then compute the time for the next interrupt. Best empirical data currently indicates worst case around 50 microseconds to do the computations. I am controlling 2 devices, so one device could be controlled 50 microseconds later than the other device if the ISR must run to completion. This is not ideal. (10 microseconds lag time would be better)
Other things are happening in the CPU (using FreeRTOS), and the device control pulses can come as close as 150 to 200 microseconds apart, so this needs to be as efficient as possible; posting to queues and allowing higher priority tasks to compute may be too slow, so I am investigating this possibility.
1) Does the PSOC5 default only use the MSP (Main Stack Pointer) (TRM: 7.4.2) ? (If it does, all interrupts stack info on that pointer, based on the reading.)
2) There is an ACTIVE register for interrupts. (TRM: 7.4.1) If I wish to allow *all* other interrupts to occur while I am still in an ISR, it appears from the text that I have to clear the bit for that interrupt in the ACTIVE register. Based on inferential reading, that will allow another interrupt to occur (or the same one) if the global interrupt mask is also cleared. I have looked, but have not found any API or documentation regarding accessing this register.
Conclusion:
Based on what I read, is the following correct? If so, where do I get the info to implement the ACTIVE_REGISTER_CLEAR_BIT(myISRBit)?
CY_ISR(ISR_function) {
sendPulse();
ACTIVE_REGISTER_CLEAR_BIT(MyISRBit);
CyGlobalIntEnable;
....more code...
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am not exactly sure I completely understood the question, especially the following part " I am controlling 2 devices, so one device could be controlled 50 microseconds later than the other device if the ISR must run to completion. This is not ideal. " Could you please elaborate the requirement.
Best Regards,
Vasanth
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
WaMa,
Wow. It appears you are trying to be very accurate in timing using ISRs.
I might be able to provide some good suggestions.
Allow Any Other Interrupts while still inside IRQ?
Although it is possible to nest interrupts, it is generally not advisable if you can avoid it. This is due to a possibility of creating a stack overflow if not designed properly.
Here is a discussion post I submitted about general rules of using interrupts. Hopefully there are insights useful to you.
If you're trying to measure two signals with usec accuracy, the best way is to use a HW Timer with input capture. Input capture allows the count value to be store in a FIFO at the time of the signal change. In this case you don't need super-fast CPU processing and low-latency ISR processing to achieve a high degree of accuracy.
For example, let's say you want to measure the time between a signal going low to the same signal going high.
- Place this signal on the capture input of a timer
- Set an input clock of 24MHz.
- Select that you want the capture on either edge.
- You can set that you want ONE ISR after two capture events. (isr_2_edges)
- In the ISR, read the first capture value (first edge) from the 4 capture FIFO and substract the second capture value (second edge).
With a little math that takes into count the wrapping of the counter value at the end of the period, you have a timing value with 1/24MHz (=41.7 nsec) accuracy. If that's too accurate, you can lower the input clock to 1MHz. This will give you 1usec accuracy.
Len
"Engineering is an Art. The Art of Compromise."