Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;-------------------------------------------------------------------------------
- ; Shutter release / latching switch
- ;
- ; Author: Daniel Neville (Blancmange)
- ; Platform: PIC10F200/202/204/206
- ; Modified: 16 June 2010
- ; Licence: Public domain
- ;
- ; This program causes one output pin to mirror an input pin (debounced) for
- ; short pulses but to latch high when a long pulse is received. Once latched,
- ; the leading edge of the next pulse releases the latch and if that pulse is
- ; short, the output will go low on the trailing edge of that pulse.
- ;
- ; If an input pulse that releases the latch is long, the latch will be
- ; reactivated and the output will remain high.
- ;
- ; As a bonus, two other outputs are provided. One output indicates that the
- ; latch is active, This could be wired to an LED to indicate to the user that
- ; it's no longer necessary to continue to hold down the button. The lit state
- ; of the LED would remind the user that the output is latched high even though
- ; the button is not pressed.
- ;
- ; The other output also indicates the latched state but when wired to an LED,
- ; causes the LED to blink rapidly from the moment the latch is activated to
- ; the time the button is released. Upon release, the LED remains steady to
- ; indicate that the latch is in effect even though the button is released.
- ;
- ; A tri-colour LED with a red LED and a green LED in the same package would
- ; provide nice visual feedback. One LED would be wired to mirror the state
- ; of the button, another would be wired to the blinker output.
- ;
- ; An example
- ;
- ; __ ___ ______________:___________ ______
- ; In: ToggleIn _| |_| |__| : |________| |____
- ; __ ___ :______________:___________________________
- ; Out: ToggleOut _| |_| |__| : |____
- ; : :____________________
- ; Out: Latched _____________:______________| |___________
- ; : :_ _ _ ________
- ; Out: Blinker _____________:______________| |_| |_| |_| |___________
- ; : :
- ; :<-- "Long" -->:
- ;
- ;-------------------------------------------------------------------------------
- ;-------------------------------------------------------------------------------
- ; Index
- ;-------------------------------------------------------------------------------
- ; Listing Options
- ; Includes
- ; Chip configuration
- ; I/O Pin assignment
- ; Constants
- ; State names
- ;
- ; Subtraction and comparison on the PIC
- ;
- ; Reset
- ; SetOptionAndTriStateRegs
- ; ResetSWTimers
- ; UpdateSWTimers
- ; On_MillisecondTick
- ; On_CentisecondTick
- ; Do_DebounceTIn
- ; Do_Blinker
- ; Do_Toggle
- ; Main and WakeUp
- ;
- ; Unitialised variables
- ; Overlapping temporary variables
- ;-------------------------------------------------------------------------------
- ; Listing options
- ;-------------------------------------------------------------------------------
- ; The p10f200.inc file requires the processor type to be declared in advance.
- list p=p10f200
- ; All numbers in this listing are to be interpreted as decimal except when
- ; the radix is given.
- list r=dec
- ;-------------------------------------------------------------------------------
- ; Includes
- ;-------------------------------------------------------------------------------
- #include <p10f200.inc>
- ;-------------------------------------------------------------------------------
- ; Chip configuration
- ;-------------------------------------------------------------------------------
- ; Internal oscillator used
- ; Watchdog timer on
- ; Content protection off
- ; Master clear-reset off
- __CONFIG _IntRC_OSC & _WDT_ON & _CP_OFF & _MCLRE_OFF
- ;-------------------------------------------------------------------------------
- ; I/O Pin assignment
- ;-------------------------------------------------------------------------------
- ; Bit positions
- bToggleOut equ 0 ; Mirrors ToggleIn except when Latched is high
- bLatched equ 1 ; Long pulse sets Latched, short pulse resets it.
- bBlinker equ 2 ; Blinks rapidly when latched mode is activated
- bToggleIn equ 3
- ; Masks
- mToggleOut equ 1 << bToggleOut
- mLatched equ 1 << bLatched
- mBlinker equ 1 << bBlinker
- mToggleIn equ 1 << bToggleIn
- ; GPIO masks
- mInputs equ mToggleIn
- mOutputs equ mBlinker | mLatched | mToggleOut
- ; Inverted inputs and outputs. If ToggleIn, say, is wired active low (perhaps
- ; with the help of the optional weak pull-ups feature of the PIC), mInverted
- ; should include the mToggleIn mask.
- mInvertedIO equ 0
- ;-------------------------------------------------------------------------------
- ; Constants
- ;-------------------------------------------------------------------------------
- ; By default, the prescaler is set to 1:2 so that TMR0 runs at half the rate
- ; of the instruction clock, which is a quarter of the rate of the internal
- ; 4MHz oscillator. HFTicksIn1ms is the value by which TMR0 would increase in
- ; an interval of one millisecond if TMR0 were unrestricted by the tiny word
- ; size of the register in which it is kept.
- ;
- ; HFTicksIn1ms must be less than 4096 and large enough so that the main loop
- ; of the program has no chance of allowing the unsigned 12-bit high frequency
- ; software counter to overflow or even reach twice the value of HFTicksIn1ms.
- HFTicksIn1ms equ 500 ; TMR0 counts
- ; The ToggleOut pin mirrors the ToggleIn pin except when Latched mode is
- ; activated, in which case ToggleOut is held high. Latched mode is activated
- ; by a long pulse on ToggleIn and deactivated by the rising edge of a
- ; a subsequent pulse. (If that pulse turns out to be a long one, Latched
- ; mode will be reactivated without disturbance to high state of ToggleOut.)
- ToggleLatchTime equ 100 ; centiseconds
- ; The ToggleIn pin is debounced by this program. The debounced version of the
- ; input is kept high for a very shirt interval after the trailing edge of the
- ; original input. Good switches finish bouncing entirely in about 1ms. Most
- ; settle down in under 6ms. A maximum notch time of 3ms for each bounce should
- ; be ample for all but the very worst switches.
- ;
- ; See http://www.ganssle.com/debouncing.htm
- ;
- ; If an input is logically inverted because a normally closed switch is
- ; used or pull-ups are used and the input switch grounds the input pin,
- ; it's important to invert the logic again as soon as it's read from the
- ; GPIO word and cached in the idealised representation in which 0 means
- ; released and 1 means pushed.
- DebounceTime equ 3 ; milliseconds (max. time of open state in bounce)
- ; A pretty feature is the Blinker output, which rapidly flashes when ToggleIn
- ; is held high long enough to activate the latch feature, alerting the user
- ; that continued pressure on the button is no longer necessary. When the
- ; buttin is released (and ToggleIn goes low), the Blinker output stays high
- ; until the moment the user presses the button again.
- ;
- ; An excellent way to indicate the latched condition is with a tri-colour LED
- ; consisting of a red LED and and a green LED in the same package. The red LED
- ; is wired to be on when the button is pressed and the green LED is wired to
- ; the Blinker output pin.
- ;
- ; For a short button press, the LED lights red for the duration of the pressing.
- ; When the button is depressed long enough for the latch to activate, the LED
- ; rapidly flashes yellow and red. When the button is released, the LED changes
- ; to green. A subsequent momentary press will cause the LED to light up red and
- ; then go out. (If that press is long, the LED will start blinking again.)
- ;
- ; An alternative arrangement is to have two LEDs (perhaps of differing colour
- ; side by side. As with the tri-colour LED, that any LED is lit means the
- ; output pin is set high. The colour or the position of the lit LED indicates
- ; the cause.
- ;
- ; The mark (lit) and space (unlit) times are independently adjustable.
- BlinkMarkTime equ 34 ; miliiseconds
- BlinkSpaceTime equ 34 ; miliiseconds
- ; Set to 1 if weak pull-ups on input pins are desired, 0 otherwise.
- UseWeakPullUps equ 0
- ;-------------------------------------------------------------------------------
- ; State names
- ;
- ; Apart from the housekeeping code, the behaviour of this program is coded
- ; in the form of finite state machines.
- ;
- ;-------------------------------------------------------------------------------
- ; DebounceTIn, the debounce timer for the ToggleIn pin
- DebounceTIn_Low equ 0
- DebounceTIn_High equ 1
- DebounceTIn_Sustained equ 2
- ; Toggle, the latching switch feature
- Toggle_Idle equ 0
- Toggle_Short equ 1
- Toggle_Long equ 2
- Toggle_Latched equ 3
- ; Blinker, a substate of Toggle
- Blinker_Space equ 0
- Blinker_Mark equ 1
- ;-------------------------------------------------------------------------------
- ; Subtraction and comparison on the PIC
- ;
- ; Like the 6502, the PIC uses the Borrow Convention when it comes to
- ; subtraction or comparison, clearing an initially set carry flag when
- ; the unsigned result underflows. This is in contrast to the Z80 and
- ; the AVR chips, which set an initially cleared carry flag when an
- ; unsigned result underflows.
- ;
- ; Result of Operand - W
- ;
- ; * C=1 Z=0 => Positive (Operand > W)
- ; * C=1 Z=1 => Zero (Operand = W)
- ; * C=0 Z=0 => Negative (Operand < W)
- ; * C=0 Z=1 Cannot occur
- ;
- ; Note that on the PIC, the W register is always the one that is subtracted
- ; from the other operand. Instead of thinking of W as the accumulator, it may
- ; be helpful to think of the File Registers as accumulators and the W register
- ; merely a storage register. If W is 20, "SUBLW 3" will cause W to become 239
- ; (unsigned) or -17 (signed).
- ;
- ;-------------------------------------------------------------------------------
- ;-------------------------------------------------------------------------------
- code h'000'
- ;-------------------------------------------------------------------------------
- ; Reset
- ; On powering up, the PIC10 starts executing code at the last program address,
- ; the content of which is factory set to contain the MOVLW instruction that
- ; loads the W register with the oscillator calibration constant. The constant
- ; is a two's complement signed 8-bit word that indicates the deviation required
- ; to make the built-in oscillator accurate.
- ;
- ; When programming the PIC10, care must be taken not to overwrite the word
- ; at last address of program memory, as it is set at the factory for the
- ; individual chip. It's a good idea to read it first so it can be restored
- ; in the event it gets overwritten.
- Reset
- ; W is loaded by the factory-set MOVLW instruction at the end of
- ; of program memory. Bits 7..1 contain the oscillator calibration.
- ; Bit 0, if set, causes the instruction clock to appear on pin GPIO2.
- ; Make sure GPIO2 is free for general I/O.
- andlw ~(1 << FOSC4)
- movwf OSCCAL
- ; Identify the cause of the reset.
- btfsc STATUS, GPWUF
- goto WakeUp ; Wake-up on I/O pin change
- ;btfsc STATUS, CWUF ; pic10f202/206 feature
- ; goto WakeUp ; Wake-up on comparator change
- btfsc STATUS, NOT_TO
- goto Main ; Power-up or NOT_MCLR pulled low
- btfss STATUS, NOT_PD
- goto WakeUp ; Watchdog time-out during sleep
- goto Main ; Watchdog time-out (not during sleep)
- ;-------------------------------------------------------------------------------
- ; SetOptionAndTriStateRegs
- ;
- ; The OPTION and TRIS registers are altered on wake-up and must be restored.
- SetOptionAndTriStateRegs
- ; Enable wake-up on I/O pin change (NOT_GPWU = 0)
- ; UseWeakPullUps decides if weak pull-up on I/O pins are used (NOT_GPPU)
- ; Use internal oscillator (T0CS = 0)
- ; [Not relevant] Use rising edge (T0SE = 0)
- ; Prescaler assigned to Timer 0 (PSA = 0)
- ; Prescaler set to 1:2 (PS2-0 = 000)
- SOTR_mNotGPPU equ ((!UseWeakPullUps) & 1) << NOT_GPPU
- SOTR_mHardCoded equ (0<<NOT_GPWU) | (0<<T0CS) | (0<<T0SE) | (b'000'<<PS0)
- movlw SOTR_mHardCoded | SOTR_mNotGPPU
- option
- ; Set the I/O direction bits. (0 = output, 1 = input)
- movlw mInputs
- tris GPIO
- retlw 0
- ;-------------------------------------------------------------------------------
- ; ResetSWTimers
- ;
- ; Clears all the software timers.
- ResetSWTimers
- movf TMR0, W
- movwf LastTMR0
- clrf HFTimer_H
- clrf HFTimer_L
- clrf Timer_DebounceTIn
- clrf Timer_ToggleIn
- clrf Timer_Blinker
- retlw 0
- ;-------------------------------------------------------------------------------
- ; UpdateSWTimers
- ;
- ; Reads the 8-bit TMR0 register and updates the high frequency software
- ; timer used to determine when to call the millisecond and centisecond
- ; event handlers On_MillisecondTick and On_CentisecondTick.
- UpdateSWTimers
- ; Find the delta time for this cycle.
- movf LastTMR0, W
- movwf TV_DeltaTMR0
- movf TMR0, W
- movwf LastTMR0
- subwf TV_DeltaTMR0, f
- comf TV_DeltaTMR0, f
- incf TV_DeltaTMR0, f
- movf TV_DeltaTMR0, W
- ; Increment the high frequency counter by this delta time.
- addwf HFTimer_L, f
- btfsc STATUS, C
- incf HFTimer_H, f
- USWT_TestHFT
- ; if HF_Timer:11-0 >= HFTicksIn1ms, a millisecond tick must occur.
- USWT_TestHFTH
- ; Extract the high four bits of the 12-bit sub-ms timer field.
- movf HFTimer_H, W
- andlw h'0F'
- movwf TV_SMTimer_H
- movlw high(HFTicksIn1ms)
- subwf TV_SMTimer_H, W
- btfsc STATUS, Z
- goto USWT_TestHFTL
- btfsc STATUS, C
- goto USWT_MillisecondTick
- goto USWT_Done
- USWT_TestHFTL
- movlw low(HFTicksIn1ms)
- subwf HFTimer_L, W
- btfsc STATUS, Z
- goto USWT_MillisecondTick
- btfss STATUS, C
- goto USWT_Done
- USWT_MillisecondTick
- ; Subtract HFTicksIn1ms from HF_Timer.
- movlw low(HFTicksIn1ms)
- subwf HFTimer_L, f
- btfsc STATUS, Z
- goto USWT_DoneMSLow
- btfss STATUS, C
- decf HFTimer_H, f
- USWT_DoneMSLow
- movlw high(HFTicksIn1ms)
- subwf HFTimer_H, f
- ; Increment the millisecond digit field of HFTimer.
- movlw 1 << 4
- addwf HFTimer_H, f
- movlw 10 << 4
- subwf HFTimer_H, W
- movlw h'0F'
- btfsc STATUS, C
- andwf HFTimer_H, f
- call On_MillisecondTick
- ; Call the centisecond event handler if the millisecond digit is zero.
- movlw h'F0'
- andwf HFTimer_H, W
- btfsc STATUS, Z
- call On_CentisecondTick
- incf Timer_ToggleIn, f
- USWT_Done
- retlw 0
- ;-------------------------------------------------------------------------------
- ; On_MillisecondTick
- On_MillisecondTick:
- ; Advance the debounce timer for the ToggleIn pin
- incf Timer_DebounceTIn, f
- ; The blinker timer counts downward.
- movf Timer_Blinker, W
- btfss STATUS, Z
- decf Timer_Blinker, f
- retlw 0
- ;-------------------------------------------------------------------------------
- ; On_CentisecondTick
- On_CentisecondTick:
- ; Update the state timer for Toggle FSM, in which states are timed in
- ; the order of a few centiseconds to 2.5 seconds.
- incf Timer_ToggleIn, f
- retlw 0
- ;-------------------------------------------------------------------------------
- ; Do_DebounceTIn
- ; The input fetched from GPIO is read once every program cycle and kept
- ; in CachedInput. For reliable operation, whatever input recorded in
- ; CachedInput is debounced and recorded in DebouncedInput.
- ;
- ; The debouncing of the signal at ToggleIn pin is performed by this
- ; subroutine, the behaviour of which can be described by the following
- ; Finite State Machine of the Moore kind.
- ;
- ; FSM DebounceTIn:
- ; Low (initial):
- ; E: Debounced := 0
- ; Input = 1 --> High
- ; High:
- ; E: Debounced := 1
- ; Input = 0 --> Sustained
- ; Sustained:
- ; E: Debounced := 1, Timer := 0
- ; A: Timer increases by one for each millisecond that passes
- ; Timer >= DebounceTime --> Low
- ; Input = 1 --> High
- ; End
- ;
- ; "E:", "A:" and "X:" indicate entry actions, state activity and exit actions.
- Do_DebounceTIn
- movf SV_DebounceTIn, W
- addwf PCL, f
- goto Do_DebounceTIn_Low
- goto Do_DebounceTIn_High
- goto Do_DebounceTIn_Sustained
- Do_DebounceTIn_Outputs_Lookup
- movf SV_DebounceTIn, W
- addwf PCL, f
- retlw 0
- retlw mToggleIn
- retlw mToggleIn
- Go_DebounceTIn_Low
- movlw DebounceTIn_Low
- movwf SV_DebounceTIn
- goto Do_DebounceTIn_End
- Do_DebounceTIn_Low
- movlw DebounceTIn_High
- btfsc CachedInput, bToggleIn
- movwf SV_DebounceTIn ; ToggleIn = 1 --> High
- goto Do_DebounceTIn_End
- Do_DebounceTIn_High
- btfss CachedInput, bToggleIn
- goto Go_DebounceTIn_Sustained ; ToggleIn = 0 --> Sustained
- goto Do_DebounceTIn_End
- Go_DebounceTIn_Sustained
- movlw DebounceTIn_Sustained
- movwf SV_DebounceTIn
- clrf Timer_DebounceTIn
- goto Do_DebounceTIn_End
- Do_DebounceTIn_Sustained
- ; Change back to DebounceTIn_High if the notch was not very long.
- movlw DebounceTIn_High
- btfsc CachedInput, bToggleIn
- movwf SV_DebounceTIn ; ToggleIn = 1 --> High
- movlw DebounceTime
- subwf Timer_DebounceTIn, W
- btfsc STATUS, C
- goto Go_DebounceTIn_Low ; Timer >= DebounceTime --> Low
- ;goto Do_DebounceTIn_End
- Do_DebounceTIn_End
- call Do_DebounceTIn_Outputs_Lookup
- movwf DebouncedInput
- retlw 0
- ;-------------------------------------------------------------------------------
- ; Do_Blinker
- ; This sub-FSM of Toggle is performed by a simple routine that makes no
- ; extra demands of the stack, which on the Pic10f200, can holds only two
- ; return addresses.
- Do_Blinker
- movf Timer_Blinker, W
- btfss STATUS, Z
- goto Do_Blinker_End
- ; Flip the Mark/Space state
- movlw Blinker_Mark ^ Blinker_Space
- xorwf SV_Blinker, f
- ; Find the new value for the blinker's countdown timer.
- movlw Blinker_Space
- xorwf SV_Blinker, W
- movlw BlinkMarkTime
- btfsc STATUS, Z
- movlw BlinkSpaceTime
- movwf Timer_Blinker
- Do_Blinker_End
- retlw 0
- ;-------------------------------------------------------------------------------
- ; Do_Toggle
- ; The basic function the PIC10 is required to perform is expressed in
- ; this subroutine. The rest of the program is mostly just housekeeping.
- ; The function is described roughly by the following Finite State Machine
- ; of the Moore kind.
- ;
- ; FSM Toggle:
- ; Idle (initial):
- ; E: ToggleOut := 0
- ; ToggleIn = 1 --> Short
- ; Short:
- ; E: ToggleOut := 1, Timer := 0
- ; A: Timer increases by one for each centisecond that passes
- ; Timer >= ToggleLatchTime --> Long
- ; ToggleIn = 0 --> Idle
- ; Long:
- ; E: ToggleOut := 1
- ; ToggleIn = 0 --> Latched
- ; FSM Blinker:
- ; Blinker_Space:
- ; E: Blinker := 0, Timer_BlinkTimer := BlinkSpaceTime
- ; Timer_BlinkTimer = 0 --> Blinker_Mark
- ; Blinker_Mark (initial):
- ; E: Blinker := 1, Timer_BlinkTimer := BlinkMarkTime
- ; A: Timer_BlinkTimer counts down by the millisecond
- ; X: Blinker := 0
- ; Timer_BlinkTimer = 0 --> Blinker_Space
- ; End
- ; Latched:
- ; E: ToggleOut := 1
- ; ToggleIn = 1 --> Short
- ; End
- ;
- ; "E:", "A:" and "X:" indicate entry actions, state activity and exit actions.
- Do_Toggle
- movf SV_Toggle, W
- addwf PCL, f
- goto Do_Toggle_Idle
- goto Do_Toggle_Short
- goto Do_Toggle_Long
- goto Do_Toggle_Latched
- Do_Toggle_Outputs_Lookup
- movf SV_Toggle, W
- addwf SV_Toggle, W
- addwf SV_Blinker, W
- addwf PCL, f
- retlw 0 ; Idle, Space
- retlw 0 ; Idle, Mark
- retlw mToggleOut ; Short, Space
- retlw mToggleOut ; Short, Mark
- retlw mLatched | mToggleOut ; Long, Space
- retlw mBlinker | mLatched | mToggleOut ; Long, Mark
- retlw mBlinker | mLatched | mToggleOut ; Latched, Space
- retlw mBlinker | mLatched | mToggleOut ; Latched, Mark
- Go_Toggle_Idle
- movlw Toggle_Idle
- movwf SV_Toggle
- goto Do_Toggle_End
- Do_Toggle_Idle
- ; Change to Toggle_Short when ToggleIn goes high (and start the timer).
- btfsc DebouncedInput, bToggleIn
- goto Go_Toggle_Short ; ToggleIn = 1 --> Short
- goto Do_Toggle_End
- Go_Toggle_Short
- movlw Toggle_Short
- movwf SV_Toggle
- clrf Timer_ToggleIn
- goto Do_Toggle_End
- Do_Toggle_Short
- ; Change back to Toggle_Idle if the pulse was not very long.
- movlw ToggleLatchTime
- subwf Timer_ToggleIn, W
- btfsc STATUS, C
- goto Go_Toggle_Long ; Timer >= ToggleLatchTime --> Long
- btfss DebouncedInput, bToggleIn
- goto Go_Toggle_Idle ; ToggleIn = 0 --> Idle
- goto Do_Toggle_End
- Go_Toggle_Long
- movlw Toggle_Long
- movwf SV_Toggle
- movlw Blinker_Mark
- movwf SV_Blinker
- movlw BlinkMarkTime
- movwf Timer_Blinker
- call Do_Blinker
- goto Do_Toggle_End
- Do_Toggle_Long
- ; Change to Toggle_Latched when ToggleIn goes low.
- btfss DebouncedInput, bToggleIn
- goto Go_Toggle_Latched ; ToggleIn = 0 --> Latched
- call Do_Blinker
- goto Do_Toggle_End
- Go_Toggle_Latched
- movlw Toggle_Latched
- movwf SV_Toggle
- goto Do_Toggle_End
- Do_Toggle_Latched
- ; Change to Toggle_Short when ToggleIn goes high. ToggleOut will
- ; fall when ToggleIn does, unless ToggleIn is held high for another
- ; long interval, activating the latch feature again.
- btfsc DebouncedInput, bToggleIn
- goto Go_Toggle_Short ; ToggleIn = 1 --> Short
- goto Do_Toggle_End
- Do_Toggle_End
- call Do_Toggle_Outputs_Lookup
- movwf ToggleOutputs
- retlw 0
- ;-------------------------------------------------------------------------------
- ; Main
- ; This part of the program as two entry points:
- ;
- ; * Main - for power-up and true reset conditions and
- ; * WakeUp - for continued operation after sleeping, preserving state.
- ;
- ; Except during sleep, the Finite State Machines are executed as fast as they
- ; possibly can while monitoring the inputs and the millisecond and centisecond
- ; software timers. The upshot of this is that the FSMs get to respond to input
- ; events very quickly, in the order of tens of microseconds. (The FSMs are not
- ; called from the millisecond and centisecond event handlers, but by the busy
- ; loop of the main program.)
- Main
- ; Reset output variables.
- clrf ToggleOutputs
- ; Set the toggle output to match the input.
- movf GPIO, W
- xorlw mInvertedIO
- andlw mInputs
- movwf TV_Input
- btfsc TV_Input, bToggleIn
- bsf TV_Input, bToggleOut
- movf TV_Input, W
- andlw mInputs
- movwf CachedInput
- movwf DebouncedInput
- movf TV_Input, W
- ; Set the output latches. Their states will appear
- ; on the I/O pins when the tri-state IO direction
- ; bits are reset.
- xorlw mInvertedIO
- movwf GPIO
- ; Determine the initial state of the DebounceTIn FSM, the machine
- ; responsible for debouncing the ToggleIn input pin.
- movlw DebounceTIn_Low
- btfsc DebouncedInput, bToggleIn
- movlw DebounceTIn_High
- movwf SV_DebounceTIn
- ; Determine the initial state of the Toggle FSM.
- ; This is to minimise the risk of a spurious change
- ; in state of the output pin when the PIC10 resets.
- movlw Toggle_Idle
- btfsc DebouncedInput, bToggleIn
- movlw Toggle_Short
- movwf SV_Toggle
- ; The blinker state variable must be initialised in case the
- ; implementation uses a jumptable.
- movlw Blinker_Space
- movwf SV_Blinker
- WakeUp
- call SetOptionAndTriStateRegs
- call ResetSWTimers
- MainLoop
- clrwdt
- call UpdateSWTimers
- ; Iterate the finite state machines.
- call Do_DebounceTIn
- call Do_Toggle
- iorwf ToggleOutputs, W
- xorlw mInvertedIO
- movwf GPIO
- ; Read the inputs. Sleep if they haven't changed since last time.
- clrwdt
- movf CachedInput, W
- movwf TV_Input
- movf GPIO, W
- xorlw mInvertedIO
- andlw mInputs
- movwf CachedInput
- xorwf TV_Input, W
- btfss STATUS, Z
- goto MainLoop ; The input has changed. Do something about it!
- ; Are we in a state that requires timing?
- movf SV_Toggle, W
- xorlw Toggle_Short
- btfsc STATUS, Z
- goto MainLoop ; Yes, Toggle is Deciding between Short & Long.
- movf SV_Toggle, W
- xorlw Toggle_Long
- btfsc STATUS, Z
- goto MainLoop ; Yes, Toggle is in Long, running Blinker
- movf SV_DebounceTIn, W
- xorlw DebounceTIn_Sustained
- btfsc STATUS, Z
- goto MainLoop ; Yes, Debouncing in progress
- ; There's nothing to do but wait for the input to change state.
- ; Be careful how you interpret the advice given in section 9.9.2 of
- ; the datasheet about reading the GPIO register just before the SLEEP
- ; instruction. What is not stated is that you should something with
- ; the information read from that register.
- ;
- ; If you just blindly read the GPIO before sleeping, any change of
- ; input state between that reading and a previous reading will not
- ; be noticed, and the PIC will sleep right through it until another
- ; change occurs or the watchdog time resets the PIC. That would be
- ; sure to be a cause of unreliable behaviour.
- sleep ; Sleep until I/O wake-up resets the PIC.
- ;-------------------------------------------------------------------------------
- ; Unitialised variables
- ;-------------------------------------------------------------------------------
- ;-------------------------------------------------------------------------------
- udata
- ;-------------------------------------------------------------------------------
- ; Finite State Machine variables
- SV_Toggle res 1
- SV_DebounceTIn res 1
- SV_Blinker res 1
- ; Input cached to avoid disturbing the I/O wake-up function
- CachedInput res 1
- DebouncedInput res 1
- LastTMR0 res 1
- HFTimer ; Milliseconds digit (bits 15-12), HF timer (bits 11-0)
- HFTimer_H res 1 ; Bits 7-4: Millisecond digit, Bits 3-0: HF bits 11-8
- HFTimer_L res 1 ; HF bits 7-0
- Timer_DebounceTIn res 1 ; Debounce timer for ToggleIn (in milliseconds)
- Timer_ToggleIn res 1 ; State timer for ToggleIn (in centiseconds)
- Timer_Blinker res 1 ; Timer for Blinker (in milliseconds)
- ToggleOutputs res 1
- ;-------------------------------------------------------------------------------
- ; Overlapping temporary variables
- ;-------------------------------------------------------------------------------
- udata_ovr
- TV_Input res 1
- udata_ovr
- TV_DeltaTMR0 res 1
- udata_ovr
- TV_SMTimer_H res 1
- ;-------------------------------------------------------------------------------
- end
- ;-------------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement