?? counter.asm
字號:
; Port Usage
; P1.0 -
; .1 -
; .2 - Button (0=pushed) (input)
; .3 - LED (0=on) (output)
;
;*******************************************************************************
;//$PAGE
; Directives
FillROM 0
; Microprocessor definitions
include "63x0x.inc"
;*************************************************
; Data Segment (RAM)
;*************************************************
; Program Stack
gbSysProgramStack :equ 00h ; [00h-1Fh] Stack 0x20h
gbSysDataStack :equ 50h ; [50h-6Fh] Stack 0x70h
gbSysFIFO :equ 70h ; [70h-7Fh] EP0 and EP1 FIFO's
; Global Interrupt
gbSysInterruptMask :equ 20h ; Holds the current interrupt mask
; USB management data
gbUSBSendSequence :equ 28h ; Buffer send data 0/1 line
gbUSBSendBytes :equ 29h ; Buffer bytes left to send
gbUSBSendBuffer :equ 2Ah ; Offset into current buffer
gbSuspendCount :equ 2Bh ; # of msec bus has been IDLE
; Button management
gbButtonDebounce :equ 2Ch ; Debounce count down value
gbButtonClicks :equ 2Dh ; Button count value
Button_Pin :equ 04h ; Pin the switch is on, P12
LED_ON :equ 08h ; P13 is used to indicate Enumeration
;//$PAGE
;*************************************************
; Code Segment (ROM)
;*************************************************
; Vector Table
org 00h
jmp main ; Reset of some type
jmp SysUnUsed ; 128us timer (not used)
jmp SysTimer1024usEvent ; 1024us timer
jmp USBEndPoint0Event ; EP0
jmp USBEndPoint1Event ; EP1 (not used)
jmp SysUnUsed ; Reserved
jmp SysGPIOEvent ; Button
jmp SysUnUsed ; CExt (not used)
;*************************************************
; Unused event
; Do nothing, restore machine to prior state
;*************************************************
SysUnUsed:
push a
mov a,[gbSysInterruptMask]
ipret SysInterrupt
;//$PAGE
;*******************************************************************************
; main()
; @func Entry point after PowerOn, WatchDog timeout or WakeUp from sleeping.
; @comm Never returns
;*******************************************************************************
main:
; This portion of Main is only executed after a RESET (Power-On or USB)
; Setup data stack in high order RAM, just below EP0 FIFO
; It will grow down from here
mov a,70h ; USBEndP0FIFO
swap a,dsp
; Initialize both Ports high
mov a,FFh
iowr SysPort0 ; Port 0 Data reg
iowr SysPort1 ; Port 1 Data reg
; 1 on P13 is needed to make sure enumerate LED is off
; 1 on any port that needs to be an input
; Enable Pullups (0=enable)
mov a,0
iowr SysPort0PullUp
mov a,Button_Pin
iowr SysPort1PullUp ; 1 on P12 is needed to make sure GPIO interrupt
; occurs on LOW to HIGH transistion. This
; disables it's pull up
; Enable or disable interrupts on appropriate pins
mov a,0
iowr SysPort0IntEnable ; All pins irq's are disabled on Port 0
mov a,Button_Pin
iowr SysPort1IntEnable ; Enable P12, the button pin.
; No interrupts will occur until the device
; is enumerated. Then GPIO's will be enabled and
; we will allow P12 to generate interrupts
; Initialize USB variables
mov a,0
mov [gbUSBSendSequence],a ; Start with a 0
; Initialize Counter
mov a,0
mov [gbButtonClicks],a ; Initial state of 0, no button pushed
; Initialize variables
mov a,0
mov [gbUSBSendBytes],a ; No bytes to send in FIFO buffers
mov [gbSuspendCount],a ; Reset bus activity to 0
mov [gbButtonDebounce],a ; We are not debouncing
; Set interrupt mask
mov a,SysIntTimer1024us | SysIntUSBEndP0
mov [gbSysInterruptMask],a
;*********************************************
MainLoop:
; Enable interrupts to current mask
mov a,[gbSysInterruptMask]
iowr SysInterrupt
; Loop
jmp MainLoop
;********************************************************
; SysTimer1024usEvent()
; @func Timer interrupt event ocurring every 1.024 mSec
; using 6Mhz crystal.
;********************************************************
SysTimer1024usEvent:
; Save accumulator
push a
; Clear watchdog timer
; Clearing it here effectively disables the timer
iowr SysWatchDog
; Keep track of length of any IDLE conditions (No bus activity)
iord USBControl ; Read the USB Status and Control Reg
and a,01h ; Check bit 0
cmp a,0h
jz Inc_Counter ; Hmm! No activity. Branch and keep track of it.
iord USBControl ; Ah! There was activity,
; clear the bus activity bit
and a,0feh
iowr USBControl
mov a,0 ; Clear the suspend counter
mov [gbSuspendCount],a
jmp Suspend_End
Inc_Counter: ; Monitor the IDLE count
mov a,[gbSuspendCount] ; Get # of mSec we have been IDLE
inc a ; Increment the count
mov [gbSuspendCount],a
cmp a,03h ; Has it been 3msec yet?
jnz Suspend_End ; Not yet, branch
mov a,0h ; Yes, clear the suspend counter
mov [gbSuspendCount],a
iord SysStatus
or a,08h ; Set the suspend bit to cause a suspend
iowr SysStatus ; We will enter the suspend state during
; the next instruction.
Suspend_End:
; Are we counting down a button debounce
mov a,0
cmp a,[gbButtonDebounce]
jz STimerNoDebounce ; Not debouncing, branch
; Yes, we're debouncing. Let's see if we are timed out.
dec [gbButtonDebounce]
mov a,0
cmp a,[gbButtonDebounce]
; has debounce timed out?
jnz STimerNoDebounce ; No, still debouncing, branch.
; The debounce timer has timed out
; check if the button pin is at a 1. If not, the button is either still
; bouncing or still pushed
iord SysPort1 ; check the port the button is on
and a,Button_Pin ; check the pin
jz STimerNoDebounce ; branch if it is not pushed
; Reset debounce since the button is not yet released or is bouncing
mov a,[gbButtonClicks]
inc a;
mov [gbButtonClicks],a
mov [USBEndP1FIFO_0],a
iord USBEndP1TxConfig
and a,40h
or a,91h
iowr USBEndP1TxConfig
; Debounce must be over
STimerNoDebounce:
; Enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt
;//$PAGE
;********************************************************
; SysGPIOEvent()
; @func General purpose port event
; @comm Which pin?
;********************************************************
SysGPIOEvent:
; Save accumulator
push a
; Reset debounce any time we are here
mov a,50
mov [gbButtonDebounce],a
SysGPIOButtonDebouncing:
; Enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt
USBEndPoint1Event:
; Save accumulator
push a
iord USBEndP1TxConfig
xor a,40h
iowr USBEndP1TxConfig
; Enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt
;*******************************************************************************
;
; This section of code responds to activity on End Point 0 and determines
; what needs to be done.
;
;*******************************************************************************
;//$PAGE
;********************************************************
; USBEndPoint0Event()
; @func End Point zero USB event.
; @comm Default end point.
;********************************************************
USBEndPoint0Event:
; This code checks to see what type of packet was received
; (Setup, Out, or In) and jumps to the correct routine to decode the
; specifics. After the code to which the jump points is through, it jumps
; back to USBEventEP0End.
; Save accumulator
push a
; Is this a SETUP packet?
iord USBEndP0RxStatus
and a,USBEndP0RxSetup ; Check the setup bit
jnz USBEventEP0_SETUP ; Yes it's a setup, branch
USBEventEP0End:
; OK. We're done with the packet.
; Let's enable interrupts and return
mov a,[gbSysInterruptMask]
ipret SysInterrupt ; done with EP0 irq service routine
USBEventEP0Stall:
; Stall any subsequent IN's or OUT's until the
; stall bit (bit 5) is cleard by an I/O write to
; the USB End Point 0 TX Configuration Register (0x10)
; or any SETUP is received.
iord USBEndP0TxConfig
or a,USBEndP0TxStall
iowr USBEndP0TxConfig
; OK. We've set the stall condition for Endpoint 0.
; Now let's complete the routine.
jmp USBEventEP0End
;*******************************************************************************
;
; We know we have received a Setup token. Now we need to parse it to
; determine what command it is.
;
;*******************************************************************************
;//$PAGE
;*******************************************************************************
; USBEventEP0_SETUP()
; @func End point event SETUP packet handler.
; @devnote Runs in interrupt enabled context.
;********************************************************
USBEventEP0_SETUP:
; Well, we have a SETUP packet. Let's find out what to do.
mov A,[gbSysInterruptMask]
iowr SysInterrupt
; If we are here and are and we are processing a previous Setup,
; we need to abort the processing of the previous Setup
mov a,0 ; Clear any indication that we have bytes left to transfer
mov [gbUSBSendBytes],a
; Clear EP0 RxReg (including the Setup flag)
; The Data toggle bit remains unchanged, however.
mov a,0
iowr USBEndP0RxStatus
;*********************************************
; Setup Event
;*********************************************
; Check the request type and branch to the correct location to handle it.
mov a,[USBEndP0FIFO_0]
USBEventEP0SetupTargetDeviceOUT:
; Target Device?
cmp a,USBRqstTargetDevice
jz USBEventEP0SetupIsSetAddress ; Yes
USBEventEP0SetupTargetInterfaceOUT:
cmp a,USBRqstTargetInterface
jz USBEventEP0Stall ; Yes. Oops! We don't have an interface.
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -