Faster ISRs -possible solutions?

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

cross mob
Anonymous
Not applicable

 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 🙂 

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

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

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

...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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
Anonymous
Not applicable

 @ 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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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

`@INTERRUPT_2`

reti

 

org 0Ch ;Analog Column 1 Interrupt Vector

`@INTERRUPT_3`

reti

 

org 10h ;Analog Column 2 Interrupt Vector

`@INTERRUPT_4`

reti

 

org 14h ;Analog Column 3 Interrupt Vector

`@INTERRUPT_5`

reti

 

You will replace the `@INTERRUPT_n`with the name of your

ISR, preceded by '_'

 

Regards, Dana.

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

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

0 Likes
Anonymous
Not applicable

 @ 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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

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

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

0 Likes
Anonymous
Not applicable

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

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

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

0 Likes
Anonymous
Not applicable

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-

   

http://www.cypress.com/?id=1573&rtID=117

0 Likes