Shop OBEX P1 Docs P2 Docs Learn Events
How to determine Wakeup Interrupt Pin events... — Parallax Forums

How to determine Wakeup Interrupt Pin events...

dkemppaidkemppai Posts: 315
edited 2005-07-06 20:18 in General Discussion
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


·

Comments

  • dkemppaidkemppai Posts: 315
    edited 2005-06-28 20:55
    Oh, come on guys!
    Anyone ever play with waking an SX up from sleep mode??? [noparse]:)[/noparse]

    -Dan
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2005-06-28 20:58
    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
  • dkemppaidkemppai Posts: 315
    edited 2005-06-29 18:44
    · 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.


    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
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-29 19:39
    OK its been a day + since you posted, I wouldn't consider myself to be the best qualified to answer your questions, but I'll do my best.

    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.
  • dkemppaidkemppai Posts: 315
    edited 2005-06-30 14:32
    Paul Baker said...


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


    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! smilewinkgrin.gif
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-30 15:37
    Sorry, I assumed you were reading and refering to the SX User Manual.

    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.
  • pjvpjv Posts: 1,903
    edited 2005-06-30 15:48
    Hi Dan & Paul;

    Just to make you aware, the SX key debugger software DOES use the FIFO to save some of the global registers.

    Peter (pjv)
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-30 15:51
    Thanks for the clarification.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • dkemppaidkemppai Posts: 315
    edited 2005-06-30 20:26
    Paul Baker said...
    Sorry, I assumed you were reading and refering to the SX User Manual.


    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 abl
    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.
    e to determine which pin received the wakeup signal." This may be where you are getting erroneous interrupt sources.
    Paul,

    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



    ·
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-06-30 20:46
    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.
    Does this statement mean you are setting WKPND_B to $00 both upon power up and after each Wakeup event (after processing but before entering the next sleep cycle)? The register is undefined on powerup, this means the register can contain any value. Since there is no clearing mechanism for the WKPND_B a 1 in a certain position will continue to be propagated until it is explictly cleared with your code. Im not quite sure if this is the issue or the length of the wakeup pulses (or its the natural behavior of the SX). When you post your code I'll load it on my SX with a pushbutton to serve as a MIWU signal and see if I get the same issue you are experiencing.
  • dkemppaidkemppai Posts: 315
    edited 2005-07-01 16:47
    Paul,

    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

    ;---------------Sleep Routine to Power Down the SX Chip----------------------- 
    SX_Sleep 
    BANK BANK6 
    MOV RA_Shadow,RA ;Copy Ports to Shadow Register 
    MOV RC_Shadow,RC ;Copy Ports to Shadow Register 
    
    ;Set Mode (WKED_B) to Allow Edge Configuration 
    MODE $0A ;Mode for Edge Configuration 
    MOV !RB,#%00000000 ;0 = Rising Edge, 1 = Falling 
    
    ;Set Mode (WKEN_B) to Allow Wake Up Configuration. 
    MODE #$0B ;Set Mode for Wakeup Config 
    MOV !RB,#WakeupMask ;1 = No Wakeup, 0 = Wakeup 
    
    ;Set Mode for Direction Register 
    MODE $0F ;0 = Output, 1 = Input 
    MOV !RB,#%11111111 
    
    ;Clear Pending Register to Allow Interrupts. 
    MODE #$0B ;Mode to Set Wakeup Pins 
    MOV !RB,#WakeupMask ;1 = No Wakeup, 0 = Wakeup 
    
    SLEEP 
    ;--------------- End Sleep Routine --------------------------------------------
    
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-07-01 19:34
    Thanks Dan, Ill see what I can do about determining the source of the error (I hope to have an answer before the start of next week). Im really hoping it isn't a systematic error, that would severely limit the functionality of the MIWU functionality on the SX.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-07-05 22:20
    Just a quick note, Dan I haven't forgotten. Your stub code requires me to fill in alot of the fluff, slowing down testing of your code (plus I became much more busy than I expected to over the holiday weekend). But I did immeadiately note that your "Clear Pending Register to Allow Interrupts" section does not do what you think it does. You use the wrong mode value ($0B should be $09) to address the WKPND_B. Plus you need to do a "clr w" followed by "mov !rb, w" because of the "exchange with W" nature of addressing WKPND_B. Also there is a suggested order to follow when setting the various values, this order is outlined here. Let me know if these fix your issue, Ill continue to work up my test of the code until I hear back from you.

    Post Edited (Paul Baker) : 7/5/2005 10:29:18 PM GMT
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-07-05 22:37
    One final addundum, if you are accessing the WKPND_B in your ISR as shown in section 4.4.2 (same page of document cited above) you will need to save the contents of the mode register before changing it, this is because the ISR can interrupt the main code at the end of any clock cycle, so a

    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
  • dkemppaidkemppai Posts: 315
    edited 2005-07-06 12:06
    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.
    Paul,

    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
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2005-07-06 14:45
    FYI,

    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
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-07-06 15:09
    Are you initializing WKPND_B to 0 before you enable the MIWU the first time (ie before the execution of the ISR)? A side issue, are you also running the RTCC interrupt in this program as well, and if so are you aware of the potential of a missed event if you don't properly test for it? I don't remember the docs clearly explaining this potential pitfall.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • dkemppaidkemppai Posts: 315
    edited 2005-07-06 19:56
    Paul Baker said...
    Are you initializing WKPND_B to 0 before you enable the MIWU the first time (ie before the execution of the ISR)? A side issue, are you also running the RTCC interrupt in this program as well, and if so are you aware of the potential of a missed event if you don't properly test for it? I don't remember the docs clearly explaining this potential pitfall.

    Paul,

    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·
  • Paul BakerPaul Baker Posts: 6,351
    edited 2005-07-06 20:18
    ;Clear Pending Register to Allow Interrupts. 
    MODE #$0B ;Mode to Set Wakeup Pins 
    MOV !RB,#WakeupMask ;1 = No Wakeup, 0 = Wakeup
    
    Is this the line you are refering to? Is this a cut and paste of your actual code? because this section should be

    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.
Sign In or Register to comment.