- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Team,
I've a situation where execution time is very critical. (branching to ISR - returning & stuff should occur very quickly.) I tried using normal C code,
void PDI(void)
{
peakdetect_EnableInt();
COMP_1_EnableInt();
COMP_2_EnableInt();
PRT1DR ^= 0x01; // just as a test to whether the comparator responds that quick or not.
}
I got a much delayed waveform on a DSO wherein my event occurs much before & even overlaps occur between consecutive events . Is there a wayout in assembly ? Would it decrease execution time ? If so, please provide sample code or snippets
Thanks 🙂
- Labels:
-
PSoC 1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In PSoC1 it is VERY advisable not to call any function from within an ISR. The reason is that not only the A and X register must be pushed onto the stack, but all needed C-pseudo-registers as well when they are used by the ISR. When a function is called, the C-compiler assumes that *ALL* pseudo-registers must be saved onto the stack.
So it might be advisable to shorten the ISR to the very bare code and performing some of the work outsides the ISR in the main-loop.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...and
If you may, you could upload your complete project (or a working excerpt) here, so that we all can have a look at. Sometimes there are overlooked settings or similar things that could be corrected. to do so, use the "Archive Project" function under the "File" menu.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If this is the ISR -
void PDI(void)
{
peakdetect_EnableInt();
COMP_1_EnableInt();
COMP_2_EnableInt();
PRT1DR ^= 0x01; // just as a test to whether the comparator responds that quick or not.
}
Those look like simple register writes, eg. setting flags in a register. So you could
lift ASM code they compile into, or just write the regs yourself, to do the enables.
If this is not the case set a flag in ISR and handle in main() as Bob suggests.
Make sure in Global Resources your CPU clock is is set to SysClk/1, to max
machine MIPS.
What is the rate ISRs are occuring ?
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One other thought, some DSOs adjust their sample rate to trigger characteristics
to maximize buffer depth. Turn that off to make sure you are not aliasing any
channels response.
Occasionally I do a quick check of DSO presentation with a fast analog scope,
they are still quite useful to have around. Great scope is Tek 7104, 1 Ghz fully
analog, with the CIA hated micro-channel plate CRT.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@ Bob,
I'm expecting another interrupt from the same block which caused the interrupt as well as from other comparator blocks while the current ISR is being executed. Suppose say now COMP1's low-high tansition has caused an interrupt, I've to execute another block of code when the same COMP1 undergoes high-low & also similar things from COMP2 & COMP3.
To meet these ends, I'll have to enable all interrupts at the firstplace once I enter an ISR & then perform the task for which it was created. Doing this in assembly will save time, isnt it ?? Temme what is the equivalent M8C instruction for
lcall COMP_1_EnableInt();
If you can think of a quicker way, share the same.
RAM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The comparator ISR will occur in one analog column, depending on where you
place the comparator (these in boot.tpl)
org 08h ;Analog Column 0 Interrupt Vector
reti
org 0Ch ;Analog Column 1 Interrupt Vector
reti
org 10h ;Analog Column 2 Interrupt Vector
reti
org 14h ;Analog Column 3 Interrupt Vector
reti
You will replace the `@INTERRUPT_n`with the name of your
ISR, preceded by '_'
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In boot.asm when using a comparator the jump to the interrupt-routine is already inserted automatically, so there is no need to change that manually, except to save one LJMP instruction, but I am not sure if this will not be overwritten at each new build.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@ Dana,
I tried writing the regs myself & also using ASM. Both didnt workout in terms of time. I have a Yokogawa (1 Ghz) DSO which is fine. Sampling is pretty good - not affected by trigger characteristics.
Thanks for briefing what needs to be done with boot.tpl. But I've already tried those only to get same delayed response. The problem is to how to get thru the ISR quickly even after writing enables for every possible interrupt . I have included assembly code for LED toggle (the most primitive one - bitwise xor) & it does reduce the execution time (ISR's) a bit. So to reduce the tenure even further I need to code the enables in M8C asm. Thinking of a plausible solution as yet.
Regards,
RAM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look in TRM (Technical Reference Manual) for the part you are working
with, Interrupt section. There are registers you can direct write that enable/
disable.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You do not need to enable every possible interrupt. Before an ISR executes a flag in the processor is set disabling further interrups. As soon as you can enable interrupts again, do a M8C_EnableGInt and the next interrupt can be served.
There are a few registers you'll have to save on stack: A and X of course but the data-pointer 0xd0 is usually a candidate as well as the index-page and address-registers 0xd3 to 0xd5.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi friends,
i have a basic question regarding M8C interrrupts in PSoC1 . its related to the way they end and return to normal program execution.
let's say there is a main loop in our program which is made to execute an infinite while loop. now there is an interrupt., lets name it INT_1, once we have entered the ISR of INT_1 lets say we immediately enable all other interrupts including INT_1 itself. If now, another interrupt say some INT_2 has occured (i.e. before even the list of tasks specified in the INT_1 ISR has ended!), if i am correct, the program control is transferred to the INT_2 ISR.
here is my question. where does the program control go once the INT_2 ISR is properly completed? will the control return to the main loop or to the previous ISR (INT_1 ISR) from where we were called ?
please clarify
regards
prasanna
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Of course the control is transfered to the place the processor was at the time the second interrupt occured.
This works as follows: When an interrupt occurs, the current PC (Program Counter = Address of next Instruction to execute) is pushed on the stack, followed by a push of the PS (Program Status). In the PS the Enable Interrupt-bit is cleared and the PC is loaded with the vector-address of the interrupt. When interrupts are now enabled again and a new one occurs, the same happens again just increasing the needed stack space. A reti-instruction (return from interrupt) pops the PS and pops the PC thus executing the instruction after the point where the interrupt has been served.
This principal of operation is not specific for M8C-CPUs this is generally the way isrs are handled within a 8051 or ARM core as well.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note that when the interupt occurs, global interrupt is disabled. If you want the CPU to branch from one ISR (say ISR1) to another ISR (say ISR2), global interrupt should be enabled in ISR1 along with individual interrupt.
Please see "Interrupt Controller" section in Technical Reference manual (TRM) of the device. Here is the link for TRMs-