The device supports both internal and external maskable interrupts. The internal interrupt is generated as a result of the RTCC rolling over from 0FFh to 00h. This interrupt source has an associated enable bit located in the OPTION register. There is no pending flag associated with this interrupt.
Port B provide the source for eight external software selectable, edge sensitive interrupts, when the device is not in the SLEEP mode. These interrupt sources share logic with the Multi-Input Wakeup circuitry. The WKEN_B register allows interrupt from Port B to be individually enabled or The WKED_B selects the transition edge to be either positive or negative. The WKEN_B and WKED_B registers are cleared upon reset. The WKPND_B register serves as the external interrupt pending register. Pulses as short as 6 nano seconds will reliably trigger an interrupt.
Figure 8-1. Interrupt Structure
All interrupts are global in nature; that is, no interrupt has priority over another. Interrupts are handled sequentially.
Interrupt Processing:
Once an interrupt is acknowledged, all subsequent global interrupts are disabled until return from servicing the current interrupt. The PC is pushed onto the single level interrupt stack, and the contents of the FSR, STATUS, and W registers are saved in their corresponding shadow registers. The vector for the interrupt service routines is address 0.
Once in the interrupt service routine, the user program must poll all external interrupt pending bits to determine the source of the interrupt. The interrupt service routine should clear the corresponding interrupt pending flag. The user program may also need to read the contents of RTCC to determine any recent RTCC rollover. This is needed since there is no interrupt pending flag associated with the RTCC rollover.
Upon return from the interrupt service routine, the contents of PC, FSR, STATUS, and W registers are restored from their corresponding shadow registers. The interrupt service routine should end with instructions such as RETI and RETIW. RETI pops the interrupt stack and the special shadow registers used for storing FSR, STATUS, and W (preserved during interrupt handling). RETIW behaves like RETI but also adds the value of W to RTCC.
The interrupt return instruction enables the global interrupts.
The device contains an 8-bit Real Time Clock/Counter (RTCC) and an 8-bit Watchdog Timer (WDT). An 8-bit programmable prescaler extends the RTCC to 16 bits. If the prescaler is not used for the RTCC, it can serve as a postscaler for the Watchdog Timer. Figure 10-1 shows the RTCC and WDT block diagram.
Figure 10-1. RTCC and WDT Block Diagram
RTCC is an 8-bit real-time timer that is incremented once each instruction cycle or from a transition on the RTCC pin. The on-board prescaler can be used to extend the RTCC counter to 16 bits.
The RTCC counter can be clocked by the internal instruction cycle clock or by an external clock source presented at the RTCC pin.
To select the internal clock source, bit 5 of the OPTION register should be cleared. In this mode, RTCC is incremented at each instruction cycle unless the prescaler is selected to increment the counter.
Stephen Holland says:
When the RTCC is written, while configured for 1:1 prescaler, it will not start to count {untill} after 3 clock cycles. I believe this is inherent to the SX architecture due to the single instruction cycle pipelined architecture. I believe this was designed this way, because if an RTCC rollover (and subsequent interrupt) occurred while the write-back to the RTCC was still in the pipeline, the RTCC would not be written. So, when a mov RTCC, w is decoded, the RTCC is disabled.
To select the external clock source, bit 5 of the OPTION register must be set. In this mode, the RTCC counter is incremented with each valid signal transition at the RTCC pin. By using bit 4 of the OPTION register, the transition can be programmed to be either a falling edge or rising edge. Setting the control bit selects the falling edge to increment the counter. Resetting the bit selects the rising edge. The RTCC pin can receive a maximum clock that is half the device operation frequency. For example, if the SX device is operating at 50 MHz, the frequency of the signal presented at the RTCC pin must not exceed 25 MHz.
The RTCC generates an interrupt as a result of an RTCC rollover from 0FF to 000. There is no interrupt pending bit to indicate the overflow occurrence. The RTCC register must be sampled by the program to determine any over-flow occurrence. Since the counter always counts up, and continues to run after the interrupt (to avoid jitter) the program must simply test for a RTCC count lower than the original increment (see RETIW below) to see if rollover has occurred. Note: Watch out for interrupt routines that do a buch of other stuff before checking for rollover when the RTCC increment is low and the prescaler is set to a low value. In this condition, the ISR (Interrupt Service Routine) may not detect rollover. Compensate by increasing the prescaler value to slow the RTCC and increasing the increment value to decrease the time to next rollover interrupt.
Eberhard Haug says:
... and don't use any TEST RTCC to check RTCC for zero e.g., because TEST will reset the RTCC prescaler like any MOV to RTCC. As a result it could happen that your 4-byte counter never counts correctly. TEST RTCC is equivalent to MOV RTCC,RTCC. If you like to check RTCC just use a MOV W,RTCC etc.
To provide ISR programatic control of the time between interrupts, use the RETIW instruction to increment the RTCC by a constant value after servicing the roll-over interrupt. This removes any jitter due to interrupt latency when using mutiple interrupt sources (external as well as roll-over) or from variations in ISR excecution path.
Why RETIW is needed to get consistant ISR timing
The watchdog logic consists of a Watchdog Timer which shares the same 8-bit programmable prescaler with the RTCC. The prescaler actually serves as a postscaler if used in conjunction with the WDT, in contrast to its use as a prescaler with the RTCC.
The 8-bit prescaler may be assigned to either the RTCC or the WDT through the PSA bit (bit 3 of the OPTION register). Setting the PSA bit assigns the prescaler to the WDT. If assigned to the WDT, the WTD clocks the pres-caler and the prescaler divide rate is selected by the PS0, PS1, and PS2 bits located in the OPTION register. Resetting the PSA bit assigns the prescaler to the RTCC. Once assigned to the RTCC, the prescaler clocks the RTCC and the divide rate is selected by the PS0, PS1, and PS2 bits in the OPTION register. The prescaler is not mapped into the data memory, so run-time access is not possible.
The prescaler cannot be assigned to both the RTCC and WDT simultaneously.
The following sample code, uses the RTCC-rollover interrupt to toggle one output pin with a regular timed duration while another pin is toggled willy-nilly by the main loop.
; ; Simple program using RTCC-rollover interrupt ; rb.0 toggles via main code and rb.1 toggles via interrupt ; (see sxkey.txt for complete list of instructions) ; device pages4,banks8,turbo,OPTIONx,osc4mhz,bor40 reset start ;goto 'start' on reset org 0 ;3 ;interrupt routine (3 cycles in) xor rb,#%00000010 ;2 ;toggle rb.1 mov w,#-20 ;1 ;interrupt every 20 cycles retiw ;3 ;9 cycles total interrupt time start mov !OPTION,#%00000000 ;start, enable RTCC interrupt mov !rb,#%11111100 ;make rb.0 and rb.1 outputs mov w,#%00000001 ;ready to toggle rb.0 :loop xor rb,w ;1 ;toggle rb.0 jmp :loop ;3 ;4 cycles total loop time
And for the later (long date code) chips:
;The following code makes bit 7 of port C blink on my setup at about ;.25 Hz when clocked by 4 MHz resonator. DEVICE SX28L, OSCXT3, TURBO, STACKX_OPTIONX RESET Start Interrupt ORG 0 inc 7 reti Start mov !option,#%1000_0111 mov !7,#0 Loop JMP Loop
The basic formula is: Clock Speed divided by Prescale times Remaining RTCC Count times Timer Width equals the number of Timer Rollovers per second. Where Timer Width is typically 256 (one byte) or 65536 (two bytes), Prescale is one of 1 (no Prescale), 2, 4, 8, 16, 32, 128, or 256, and Remaining RTCC Count is the number of RTCC counts remaining after the ISR returns before the next RTCC rollover.
For example: At 4mhz, with a goal of one timer rollover per second, a timer width of 65536 is out of the question (4mhz / 65536 is 61 meaning that only approx. 61 instructions could be executed between timer increments). With a timer width of 256, and the remaining RTCC set to a mid point of 128, the formula becomes: 4mhz / x * 128 * 256 = 1 second where x is the unknown desired prescale value. Solving for x gives us a value of 122.07. The nearest available prescale value is 128. Reinserting this into the equation and looking for an exact remaining RTCC value: 4mhz / 128 * x * 256 = 1 second returns a value of 122 for the remaining RTCC count. Subtracting the desired remaining RTCC count from the RTCC rollover point: 256-122=134 as the amount the RTCC should be incremented after leaving the ISR so that an interrupt will occur every 122 clock ticks. Note that 8 * 122 = 760 instruction cycles will be executed between interrupts. A common practice in coding is to express this remaining RTCC count value as a negitive, effectively subtracting it from 256 when setting W prior to the RETIW command. see the sample code above. If the timer count is incremented by the ISR on each interrupt, the timer will rollover almost exactly once per second.
A simular example for a 50mhz clock results in a timer width of 65536, prescale of 8, and remaining RTCC of 95.3 or 95.
See the SXList ISR Calc for an automated version or the ISR Quick Calculator (requires JavaScript) for a basic tool. +
7.0 POWER DOWN MODE
The power down mode is entered through the execution of the SLEEP instruction while the SLEEP mode is enabled.
In SLEEP mode, only the Watchdog Timer (WDT) is active. If the Watchdog Timer is enabled, upon execution of the SLEEP instruction, the Watchdog Timer is cleared, the TO bit is set in the STATUS register, and the PD bit is cleared in the STATUS register.
There are three different ways to exit from the low power sleep mode: a timer overflow signal from the Watchdog Timer (WDT), a valid transition on any of the Multi-Input Wakeup pins (Port B pins), or through an external reset input on the MCLR pin.
To achieve the lowest possible power consumption, the Watchdog Timer should be disabled and the device should exit the SLEEP mode through the MIWU pins or an external reset.
7.1 Multi-Input Wakeup
Multi-Input Wakeup is one way of causing the device to exit the power down mode. Port B is used to support this feature. The WKEN_B register (Wakeup Enable Regis-ter) allows any Port B pin or combination of pins to cause the wakeup. Setting a bit in the WKEN_B register enables the wakeup on the corresponding Port B pin. If multi-input wakeup is selected to cause a wakeup, the trigger condition on the selected pin can be either rising edge (low to high) or falling edge (high to low). The WKED_B register (Wakeup Edge Select) selects the desired transition edge. Setting a bit in the WKED_B register selects the falling edge on the corresponding Port B. Resetting the bit selects the rising edge. The WKEN_B and WKED_B registers are cleared upon reset.
Once a valid transition occurs on the selected pin, the WKPND_B register (Wakeup Pending Register) latches the transition in the corresponding bit position. A logic 1 indicates the occurrence of the selected trigger edge on the corresponding Port B pin.
Note: if you are waiting for a high to low, or a low to high, either one, when it happens, you get a 1 in that bit position in WKPND_B.
Upon exiting the power down mode, the Multi-Input Wakeup logic causes program counter to branch to the maximum program memory address (same as reset). Figure 7-1 shows the Multi-Input Wakeup block diagram.
The following problem was reported on early version chips:
>>We are experiencing a problem when using the port B interrupt on an 18 pin 9818 date device. If another interrupt is received before the first code has cleared and returned, the interrupt system becomes inoperative however non interrupt code keeps running. Is this a known bug or is there something we need to do within or when exiting the interrupt code to stop this happening.>>All current parts in distribution have this bug. All new revisions of the core, including SX48/52 include an extra entry in the state table to go back to the interrupt vector if there is anything in the pending register on return from the interrupt service routine. The current (and all older) parts will not properly return to the interrupt vector if an interrupt came in during the ISR. There are software fixes that seem to work in the code I've tried, and they are as follows:
1. Disable, and then re-enable the RTCC interrupt before returning from the ISR. This resets the internal interrupt, and if currently servicing an external interrupt, an internal interrupt edge can be detected.
2. Clear, and then reload the pending register with its original value prior to the return from the ISR. This resets the external interrupts, so a new edge can be detected. Example code:
mov m,#$09 ;Set up to read wake up pending register
clr w
mov !rb,w ;Swap w with WKPND_B register
mov !rb,w ;Swap w with WKPND_B register again to restore original value
...
retiIf only internal interrupts are being used, only fix 1 needs to be applied. If only external interrupts are being used, only fix 2 needs to be applied.
Stephen Holland says:
If multiple sources of port B interrupt are enabled, always ensure that only the bits for the interrupts that have been serviced are cleared. The SX state machine will check the pending register upon return from the ISR to see if there are any bits set, and if so, will re-enter the ISR. This was a bug in older SX devices (with the old datecodes), where the external interrupts had to be disabled and then reenabled before the RETI or RETIW. Otherwise, any pending bits that were set would never trigger again, as the edge condition would be forever lost. {and since the only way to look at the bits is by swaping them out, you would have to swap them back to avoid clearing the all, and if a new int happens to occur between the swaps, you will miss one again.}
Loren Blaney and Richard Ottosen say:
WKPND should be cleared before enabling WKEN interrupts, otherwise a spurious interrupt will occur.The interrupt service routine must clear WKPND to enable additional interrupts on the MIWU pin.
Alexey Vladimirov [avlad at mailbox.riga.lv] says:
Typical interrupt service routine contain the following code:mov m,#$09 ;Set up to read wake up pending register clr w mov !rb,w ;Read WKPND_B register content and clear it after that ... retiEach SX instruction in turbo mode executed in a 4-stage pipeline, consisting of the following steps: fetch instruction, decode opcode, execute opcode, write result.
In the example mov !rb, w instruction at the second step simultaneously with instruction decode also read WKPND_B register and at the fourth step clear WKPND_B register.
If another external interrupt on different portB pin occurs exactly at this time (at the 2,3,4 steps of the mov !rb, w execution), SX will loose this interrupt (as the WKPND_B register cleared and, therefore, pending bit for this interrupt also cleared without interrupt processing).
It mean, that it is not possible to use 2 or more asynchronous external interrupts on the SX without loosing some interrupts.
This problem related to all current (as of Jan 2001) SX revisions.
[To work around this, check the pins by reading the actual port value after the first interrupt.] If you will use polling instead of interrupts - all will works OK. You can also use one external interrupt and poll other pins. However, if you have two asynchronous signals and you need interrupt on both (bridge application, for example), the only possible workaround we found - add some external glue logic (triggers for each interrupt with separate reset from SX port, as in any typical interrupt controller, like 8259) or change from interrupts to polling.
Also:
Questions:
Comments:
The MIWU edge-detection hardware on port B is active even if the interrupts are disabled. Therefore, you can use it to detect transitions on port B pins while polling. This can be handy for saving a few instructions and possibly some memory -- you don't have to keep track of the current state of the pin in order to detect a transition. Just set up the MIWU circuitry to look for the appropriate type of transition, then poll the WKPND port for latched transitions. It's also handy for polling for pulses that are shorter than the polling interval.+
Archive:
file: /Techref/scenix/sxints.htm, 23KB, , updated: 2007/11/16 14:03, local time: 2024/8/14 20:37,
3.142.195.209:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://ecomorder.com/techref/scenix/sxints.htm"> SX Microcontroller Interrupts</A> |
Did you find what you needed? |
Welcome to ecomorder.com! |
Welcome to ecomorder.com! |
.