How to determine Wakeup Interrupt Pin events...
dkemppai
Posts: 315
OK, first off, I'm not a newbie. I have bee programming the SX for a while. Please listen closely.
Two problems.
First, I have been fighting an issue with the SX, that appears to be buried in the datasheet. It's not explicitly explained, but appears to be buried in there.·Output register values are lost upon·Reset from Sleep via Wakeup or Watchdog Wakeup. Even though the outputs are correct upon going to sleep, and remain correct during sleep,·they are lost during the 18mS reset event. The only thing I can determine is, this happens because·the direction registers are set to $FF upon reset. Current Values of pins are then read into the port registers, which may or may·not be the values expected. The only workaround I can see is to use ram registers to save the output states before sleep and resore the values upon wakeup along with the direction registers. Any output pins that are supposed to be HI, will have glitch upont reset. This appears to be absoutley unavoidable (Unless any of you know otherwise). My question is, has anyone else run into this???
The second problem is that the WKPND_B register does not display the correct value during reset (The reset is a Sleep, followed by a rising edge wake up event, NOT an·running interrupt event).
·I have enabled wakeup inputs on several pins of the port and they are set to detect the rising edge.·My problem is,·the WKPND_B register displays $FF upon reset, even though some of my pins are·tied·to ground·with a direct short to ground. Wakeup happens as expected, when expected, but the WKPND_B register says all pins had a transition?
What I'm trying to do·is determine the source of the wakeup event, which could be on one of several of the input pins. I cannot simply read the value of the ports, because the event may be gone before the 18mS reset even has completed.
Am·I looking at a glitch of some sort, or some other 'undocumented feature' of the SX?
Everything runs as expected·with the WKPND_B·register when I leave the SX running (Just before my sleep command I place a jump command to itself. When I do this I can determine from WKPND_B the source of the Interrupt. But if I put the SX into Sleep mode, the WKPND_B register displays an rising edge event on every pin, Even pins tied directly to ground which should display no events!
What Am I missing here?·Any Ideas?
-Dan
·
Two problems.
First, I have been fighting an issue with the SX, that appears to be buried in the datasheet. It's not explicitly explained, but appears to be buried in there.·Output register values are lost upon·Reset from Sleep via Wakeup or Watchdog Wakeup. Even though the outputs are correct upon going to sleep, and remain correct during sleep,·they are lost during the 18mS reset event. The only thing I can determine is, this happens because·the direction registers are set to $FF upon reset. Current Values of pins are then read into the port registers, which may or may·not be the values expected. The only workaround I can see is to use ram registers to save the output states before sleep and resore the values upon wakeup along with the direction registers. Any output pins that are supposed to be HI, will have glitch upont reset. This appears to be absoutley unavoidable (Unless any of you know otherwise). My question is, has anyone else run into this???
The second problem is that the WKPND_B register does not display the correct value during reset (The reset is a Sleep, followed by a rising edge wake up event, NOT an·running interrupt event).
·I have enabled wakeup inputs on several pins of the port and they are set to detect the rising edge.·My problem is,·the WKPND_B register displays $FF upon reset, even though some of my pins are·tied·to ground·with a direct short to ground. Wakeup happens as expected, when expected, but the WKPND_B register says all pins had a transition?
What I'm trying to do·is determine the source of the wakeup event, which could be on one of several of the input pins. I cannot simply read the value of the ports, because the event may be gone before the 18mS reset even has completed.
Am·I looking at a glitch of some sort, or some other 'undocumented feature' of the SX?
Everything runs as expected·with the WKPND_B·register when I leave the SX running (Just before my sleep command I place a jump command to itself. When I do this I can determine from WKPND_B the source of the Interrupt. But if I put the SX into Sleep mode, the WKPND_B register displays an rising edge event on every pin, Even pins tied directly to ground which should display no events!
What Am I missing here?·Any Ideas?
-Dan
·
Comments
Anyone ever play with waking an SX up from sleep mode??? [noparse]:)[/noparse]
-Dan
·· Be patient...That's less than a day, not everyone who uses the SX gets on that much.· I'm sure someone has tried it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
Yeah, I'm guess I'm just starting to get impatient...·· ...I posed the following code snippit over a month ago dealing with·my first issue. ·No one·appears to have looked at it since then.
Anyway, I was trying to get someone to try this code·with SOURCING curent to·an LED and oscilloscope on the·RB.0 pin.
Try it...··· ...You'll be confused if you look into the datasheet/app notes for reset conditions.·Then·try it·with the·";··MOV· RB, SHADOW" uncommented.·You would think, that in both cases the LED would flash at about 4 second rate, with a roughtly 50% duty cycle...·· ...anyway. It won't. It only works with the shadow register enabled. As posted, the code will only generate a 3.800uS wide 'glitch' on the output pin. With the shadow move enabled, it works as expected.
Oh, yeah, you can add some nop's around the "READ MODIFY WRITE"'s·to prevent additional glitches...
Also, by adding a command to set RB.1 before going to sleep, you can determine that the glitch happens 15mS after the reset (i.e. after the SX Reset timeout had completed).
-Dan
Code example
·
NOCASE·· ;No Case Sensitive ASM
· DEVICE SX28L· ;28 pin chip
· DEVICE· OSCXT1
· DEVICE BOR22· ;Brownout at 2.2Volts
· IRC_CAL IRC_FAST ;(Faster programming)··
· DEVICE STACKX· ;Use the Extended Stack.
· DEVICE· IFBD· ;Disable Internal Feedback.
· DEVICE· TURBO· ;Turbo Mode
· DEVICE WATCHDOG ;Enable Watchdog timer.
·
· FREQ 4_000_000········· ;START WITH A XXMHz Clock
RESET Main
org $08
counter DS· 3
SHADOW DS 1
Main
;··MOV· RB, SHADOW
· ··MODE $0F·· ;Mode for Direction Registers
· ··MOV· !RA, #%0000· ;0 = output, 1 = input
· ··MOV· !RC, #%00000000··
· ··MOV· !RB, #%00000000
· ··MOV· !option, #%11111111
·
··;Check to see if Start is from WatchDog timeout.
· ··MOV W,status
· ··AND W,#%00011000 ;Bits TO = 0 and PD = 0 on WDT reset.
· ··JZ WDTStart ;Skip Following code on WatchDog Reset
· ··;Place code to be skipped on WDT reset here...
WDTStart ·JB ·RB.0,:clrbit
··SETB ·RB.0
··jmp·:bitdne
:clrbit··clrb ·RB.0
··nop
:bitdne
· ··CLR· !WDT
· ··MOV SHADOW, RB
··SLEEP
Post Edited (dkemppai) : 6/29/2005 6:51:20 PM GMT
Your first question, yes the SX performs exactly how you describe (pins set to input upon reset), there is no internal "work around" other than the shadow registers you describe, but only ports configured for output need the shadow register. An external·work around is to use external latches as a buffered output of the SX (though you'll need to also use the shadow scheme if your code does read/modify/write (RMW) operations on the port registers, if not, no shadowing is nessesary since you can create a fresh output value to update the latch), the latch·will also take care of the glitchy outputs that the shadow scheme does not.
The WKPND_B·issue is a bit more problematic, and I concur that the docs are a bit confusing on expected behavior. But here are a·couple excerpts from the docs:
"In the power down state, a wakeup signal on a Port B pin wakes up and resets the device, causing the program to jump to the highest program memory address (7FFh or FFFh, depending on the SX device type)."
"Upon reset, the WKPND_B register contains unknown data."
Now when a Port B wakeup occurs, it states the SX is woken up·and resets the device. According to the last phrase the WKPND_B is undefined in such an instance, but in contradiction to the above statements Table 4-1 shows that WKPND_B is unchanged during a Wakeup event. My feeling is that the WKPND_B should have the correct value upon reset as shown in Table 4-1. But your indication that the wake-up pulse is shorter in duration than the time it takes to wakeup and reset the SX, makes me think that this is the source of your problem. If the wakeup pulse is long enough in duration to generate the signal "Wake-up: Exit Power Down" (in Figure 4-4) but short enough that the signal transistions back to the inactive state before the SX takes the generated signal and exits itself from sleep mode, the new "non activated" signal gets processed in the SX's sleep mode, thereby changing the state of the WKPND_B and erasing the interrupt's source. The solution to this is to extend the length of the wakeup pulse such that it remains valid until the SX has a chance to exit sleep mode. A simple 555 in a pulse extending configuration can acomplish this.
Paul,
Thanks for the reply.
Which document are the tables you're referring to in? I can't seem to locate them. I've got the SX-Key manual, and SX-Datasheet and other stuff. I've also been using the App note AN-18 from Ubicom (SX Reset Considerations).
OK on the shadow registers being the only workaround to the output pin values. I'm glad that someone was able to verify that for me. I do a lot of dumb things programming... ...so was wondering if it was me or the SX! As for output latches, I don't have any additional room on the board for hardware or in the power budget, for that matter. Imagine 10 IC's on a .5 wide board, with associated passives and interconnects. I'm already into 8LAP's and 8-BGA's with a some SC-70 and SOT23-x stuff... ...I'll keep the latches in mind for projects with more board space.
As for the wakeup, I have some pins on PortB tied directly to ground, and even they register a rising edge on wakeup! With no event, they shouldn't be reset to 1's. The more I think about it, it has to be another 'feature' of the SX architecture. You just can't determine the source of a wakeup interrupt on a rising edge signal. Luckily, I did find a workaround by modifying one of my communications routines and adding an IO pin, but it's not as elegant as I would like.
I want to do some more testing with wakeup on falling edge (default setting), and pins tied both high and low. But, no time now. I really would like to understand what's going on inside that chip!
About the only thing I've learned is that outputs that are low before sleep and have a pulldown load will be the only output pins without glitches on reset after restoring the shadow register values. I think I can trick my hardware into working, if I'm clever about it.
Again, thanks for verifying the Shadow register thing for me! According to AN-18, that had me really miffed.
-Dan
P.S. I have always liked analog more than digital...·· ...even more so as·time goes on!
The shadow Registers will work, but the glitch you noted cannot be eliminated using that method. One thing you may want to consider is using the hidden FIFO in the SX to store your shadow register(s), this way you don't have to use up additional registers. The secret SX instructions are disclosed by Peter (pjv) in this thread. One note of caution, the SX Key uses some of the hidden instructions, so thier use may limit the debugging functionality of the SX-Key (I think the SX-Key does not use the FIFO ($047) instruction). The FIFO has a fixed depth of 8 bytes, so if only 1 byte is pushed on, 8 additional pushes are required to get the value back into W (think of the FIFO as a shift instruction only with byte values instead of bits, and the W register instead of the carry bit).
I notice that you do not clear WKPND_B, the docs state "Upon reset, the WKPND_B register contains unknown data. Therefore, the program should clear this register to zero before it enables the Multi-Input Wakeup function in the WKEN_B register. Otherwise, the program will not be able to determine which pin received the wakeup signal." This may be where you are getting erroneous interrupt sources.
Also after examination of your code, I don't see where your code for MIWU handling is, I only see handling of the WDT. BTW enabling the WDT prevents you from debugging with the SX-Key, you may want to keep it turned off until all your code is proven to work via debugging, then enable it as your last revision.
Just to make you aware, the SX key debugger software DOES use the FIFO to save some of the global registers.
Peter (pjv)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
The code I posted is only my test code to test the WDT wakeup routine. For debugging purposes, I disable the WDT code. I use a Digital scope and output pins to determine code states.
I did not post code for the MIWU routines. I am setting the WKEN_B bits as required. I have two version of my current code, one that runs the ISR and one that runs the sleep mode.
In the ISR version of the program, I check WKPND_B, and determing the source of the interrupt, and run several different routines depending on the pin that generated the interrupt. In the other version, the SX wakes up, and determines the cause of the reset condition (via PD, and T0 bits). On normal powerup, it initializes appropriate registers and puts the SX to sleep. On wakeup, it determines the cause of wakeup, and if it was a pin transition it runs the same code as in the ISR version of the program. The problem lies in the fact that the WKPND_B register shows different values for the same event, depending on if the SX was in sleep mode or running. I have verified this many times...·· ...thus the source of my confusion. Even pins that are tied directly to GND, show a rising edge transition on wakeup! I know those pins physically don't change,·and I've even verified it with·a good scope.
In any case, I still think that the SX is not operating as documented. The Ubicom AN-18 states that the WKPND_B register should be unchanged upon wakeup. I'm starting to think that a Wakeup Reset event which causes the WKED_B register to be reset to $ff is also causing the WKPND_B register to be set to $ff also. This is contrary to the documentation I can find, but a reality when running the software.
I will try to generate some example code demonstrates the problem with WKPND on wakeup, but it may take me a few days.·
-Dan
·
I'm posting the routine that I use to put the SX to sleep.
As for my wakeup routine, I check the Power Down bit, and run the wakeup routine, or initialization routine depending of if the SX was reset from sleep or normal powerup. If the SX was reset from a sleep mode, I read the WKPND_B register, pulse an IO pin several times (Temporary routine), and put the SX to sleep again. On a normal powerup, I initialize some external IC's and then put the SX to sleep.
I'm pretty sure all of my code is correct. The SX wakes up as expected, when expected, just not with the correct value in WKPND_B. If I move my code to the ISR vector, and run the code with the an endless loop in place of the sleep command, my code functions as I would expect it to.
I'm wondering if the resetting of the direction register or Edge configuration register on wakeup is causing the WKPND_B to show that all pins had a transition?
I don't know. At this point, I'm sure it's not my code. However, I can't prove it. I wish I could post my current code, but due to business agreements I cannot.
As time permits I will try to generate and example showing my issues.
Thanks!
-Dan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Paul Baker) : 7/5/2005 10:29:18 PM GMT
MODE $0B
mov !rb, #$ff
sequence can be interrupted in between the two instructions, if this occurs and you don't save and restore the mode register's contents the mode would be $09 (WKPND_B) when mov !rb, #$ff is executed and not $0B as you intended. Due to the asynchronous nature of MIWU, this could cause an infrequent and nearly un-reproducible (and therefore extremely hard) bug to track down and fix. I know from experience the number of sleepless nights such an nasty bug can cause, it took me > 6 months to track down a bug due to an asynchronously occuring interrupt that only presented itself once per full week of execution, turns out someone had forgotten to properly deliniate a critical code section, and only when it was interrupted in those 3 lines of code (of 10k+ lines of code) did the problem rear it's ugly head.
Post Edited (Paul Baker) : 7/5/2005 10:48:51 PM GMT
When the code is utilizing interrupts,·the WKPND_B is reset in the interrupt routine only. If interrupts are not used,·it's reset in the main code. However, I will keep your suggestion in mind. That's a real gotcha! Too bad the mode register isn't shadowed·during an·interrupt·the same way·the W,Status, and FSR are.·What a pain!
As for looking into the issue, by all means let this one fall to the back burner. I appreciate all the help you've given thus far! I'm more or less just glad to have someone to bounce ideas around with.·I'm currently interviewing new individuals to take some load off my back here at work, so things have been progressing very·slowly on this end.
The dumb·part of this·MIUW problem, is that I have a workaround for the time being. I just want to understand what's going on in this chip! I'm going·to continue to beat on this chip, until I fully understand·what's going on.
-Dan
the "big ones", i.e. the SX48/52 devices automatically save and restore the mode register on interrupts - as Paul said, the "small ones" unfortunately don't.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I'm not running an RTCC timer. So missing interrupts are not an issue.·In the non interrupt version of the code where there are·literally no interrupts,·is·where I'm having the trouble. If I keep the SX active (no sleep mode) everything functions as normal.
I do clear the WKPND_B register before sleep mode. It is·the very last thing I do before·entering sleep. (See the·code·routine·attached previously in this thread)
-Dan·
MODE $09
CLR W
MOV !RB, W
to accomplish the stated purpose of the comment. And the doc's code example suggests MODE $0F followed by MODE $0A, MODE $09 then MODE $0B for the order of setting up the MIWU.