2004-07-14 12:23 AM
2004-07-12 08:13 PM
Hello !
I am designing and application for the ST7FLITE29. The micro has to handle the RS 485 bus and some I/O. Since the ST7FLITE29 does not provide a SCI (hopefully ST7FLITE39 will do...), I am plannig to follow the sw UART route. The key problem in a software implementation of an async receiver is the syncronization with the internal timer(s): a up-to-down level transition interrupt is triggered at the beginning of the start bit and from this event all receiving timing must be syncronized therefore interrupt latency is the main source of phase errors. The ST7 documentation says that the latency is between 10 and 21 clock cycles. 10 cycles are needed to save registers onto the stack, while 11 cycles are the longest instruction completion time (MUL). In my application this statement is not always true: there is a small probability (1/250) that the timebase interrupt is serviced while the external interrupt is fired. This means that the maximum latency is given by the length of my timebase service routine plus 10 clock cycles. Is this true? As far as I can understand from the documentation, why 19 cycles are wasted (IRET + register saving on stack) while there is no need to restore and save anythig? Why not check for pending interrupts at the beginning of IRET ? Thanks everybody for your opinions and answers!2004-07-13 12:16 AM
If you want to enable the interrupt even when you are in the timebase interrupt routine you can do so by using the RIM instruction in the ISR. In this case if any of your interrupt flag is set in the ISR then the corresponding ISR will be executed. IRET from that ISR will bring the execution to the first ISR and the IRET of the first ISR will again take the execution back to the main program. It will be kind of nested interrupt.
2004-07-13 01:38 AM
You are true!
Anyway, here is my planned RTC1 interrupt handler: RTC1_HNDLR INC SOME_COUNTER IRET If I follow your hint it would be: RTC1_HNDLR2 RIM INC SOME_COUNTER IRET In the worst case the maximum latency is: 4 + 9 + 10 cycles in my original RTC1 handler 8 + 10 cycles in the modified one. NOTE: INC needs 5 cycles to complete; IRET 9; register save 10. In your solution an important thing is missing: data coherence! If an Input Capture event must be handled (as in my application), the LTICR value is related to the one of the timebase counter. In RTC1_HNDLR2 every interrupt handler can suspend RTC1_HANDLER. If LTIC interrupt is fired between RIM and INC, SOME_COUNTER is not updated, so the user of LTIC makes a 1ms error! The ST7 interrupt priorites are designed to avoid such errors if there is no RIM inside an handler!2004-07-13 03:48 AM
What if you write your routine like below
RTC1_HNDLR2 INC SOME_COUNTER RIM IRET In this case you will not make 1msec error as you are incrementing your counter. Here you are just saving the 9 cycles taken by IRET.2004-07-13 08:04 PM
Aina,
your replies are helpful! In your example, the maximum latency drops to 17 (5 + 2 + 10) and data coherence is preserved. I started this thread to show a silicon limitation: the silly IRET + register save operation that the ST7FLITEx core has. It would be nice if I have not to bother of RIM and other workarounds: 5 cycles are always fewer that 17! Thank you again!2004-07-13 10:54 PM
This register saving is done even in HC908GP32. This is done so that the registers are free to be used in the routine. If the saving is done by LD instructions then the time required will be much more.
2004-07-14 12:23 AM
Aina,
from your reply I realize that my previous statement was not clear. Think about what happen in any interrupt service routine without a RIM opcode. The core executes each instruction and finally the IRET. The micro-operations of IRET are: POP CC POP A POP X POP PC.h POP PC.l Since there is a pending interrupt, what happens ? The answer is in the figure 20 at page 35 of ST7FLITE2x datasheet: PUSH PC.l PUSH PC.h PUSH X PUSH A PUSH CC JP INTERRUPT_HANDLER Do you see the wasted cycles ? Would it be better if the core checked for a pending interrupt at the beginning of IRET, and jumped to the interrupt handler when the test is satisfied ?