Energy Meter IC Family Software Instruction Manual

71M652X Software User’s Guide
Revision 1.7 TERIDIAN Proprietary 51 of 138
© Copyright 2005-2007 TERIDIAN Semiconductor Corporation
the interrupt of the EEPROM (external interrupt 5), currently unused (code is available in Io\eeprom.c). Timer 0 shares
its interrupt priority bits with FWCOL, the flash write timing interrupt, also unused (flash code is in Util\flash.c).
The lowest priority is xfer_busy_isr() (Meter\ce.c) and the rtc_isr() interrupts (Io\rtc.c; both share external interrupt 6,
Meter\io652x.c). These can usually wait up to half a second. The XFER_BUSY interrupt, in particular, takes up to 4
milliseconds to copy data from the CE, so though it is very important, it needs to be low priority in order to let other
interrupts run.
The RTC can be calibrated by using the RTC-1-Second interrupt to toggle a DIO pin, and measuring the external
square wave against a traceable time standard. In this case, a calibration mode must temporarily turn off the CE (it
shares the interrupt) set external interrupt 6 to the highest priority and the code leading from the vector to the RTC's
DIO-toggle should have an unchanging execution time.
Although the demo code does not do this, it is possible to run preemptive code at the same interrupt priority as the
main loop. This creates a fifth priority below the lowest priority. To do this, set an interrupt to the lowest priority. This
interrupt's service routine must push the address of the fifth-priority code on the stack, and run RTI. RTI clears the
fourth-priority hardware, and then returns into the fifth-priority code, running it at the same interrupt level as the main
loop. For example, this permits preemptive software timers that run at the same priority as the main loop.
All interrupt service routines (ISRs) must be declared “small reentrant”. Also, all routines called by ISRs must be re-
entrant as well. Priorities are set using the IP0 and IP1 SFRs, as follows:
IP0 (SFR 0xA9) = 0x1A = 0001 1010
IP1 (SFR 0xB9) = 0x2C = 0000 1100
This results in the priority assignment shown in Table 5-11.
Group IP1 Bit IP0 Bit Priority Affected Interrupts
0 0 0 0 External interrupt
0 (DIO)
UART 1 interrupt -
1 0 1 1 Timer 0 interrupt - Ext 2 (comparators)
2 1 0 2 External interrupt
1 (DIO)
- Ext 3 (CE_BUSY)
3 1 1 3 Timer 1 interrupt - Ext 4 (comparators)
4 0 1 1 UART 0 interrupt - Ext 5 (EEPROM)
5 0 0 0 - - Ext 6 (XFER_BUSY,
RTC_1S
Table 5-11: Interrupt Priority Assignment
Timer Interrupt
timer0 of the MPU is the main system timer, and it is used to generate a 10ms timer tick, which is adjusted for MPU
clock speed. The timer tick (variable tick_count) is used to control the software timers. The software timers are updated
by the stm_run() function in the main loop of the background task. Eight software timers can be simultaneously running.
If it is desired to change the system timer to timer1, the include file called out in stm.c has to be changed to tmr1.h.
timer1 is used for delay functions, e.g. for EEPROM or RTC access control. Timer 1 is enabled and starts functioning
by calling the “Add_Delay_Func()” function as defined in the timer.c module.
Various macros are available to control the timers:
tmr_start(A, B, C) has three parameters: A is the timer time, the number of ticks to reload on each interrupt. B
is true if the timer should restart itself when it expires. C is a pointer to a reentrant function.
tmr_stop() stops the timer.
tmr_running() returns TRUE if the timer is running.
These routines are very similar to the software timer commands, in stm.h.