📄 fw.asm
字号:
;IMPORTANT!!!!!!!!!!!!
;This is a BETA version of Firmware that has not been fully tested.
;PLEASE keep this in mind and use this firmware as REFERENCE.
;=======================================================================================================
; MAIN ASM FILE FOR FRAMEWORKS
;=======================================================================================================
; Change History
; -------------------------
; Revision: 0.1
; Created DGW November 1999
; New Code
; Issue Date: DRAFT
;
;=======================================================================================================
; Framewks.asm
;
; This file contains the Frameworks for:-
; CY7C637xx
;
;
;=======================================================================================================
CPU 63743
include "usb1regs.h"
include "ram.h"
;========================================
;
; Interrupt Vectors
;
;========================================
org 00h
jmp reset ; Reset vector
jmp bus_reset ; USB Reset interrupt
jmp Isr128 ; 128us interrupt
jmp Isr1ms ; 1024ms interrupt
jmp IsrEp0 ; endpoint 0 interrupt
jmp IsrEp1 ; endpoint 1 interrupt
jmp IsrEp2 ; endpoint 2 interrupt
jmp IsrSPI ; SPI interrupt
jmp IsrCaptureA ; Capture timer A interrupt
jmp IsrCaptureB ; Capture timer B interrupt
jmp IsrGpio ; general purpose I/O interrupt
jmp IsrWakeup ; Wakeup_ISR or resume interrupt
;jmp IsrCext ; Wakeup_ISR or resume interrupt
;========================================
;
; reset processing
;
;========================================
;
; Set all SFRs to their initial states
; Clear ram
;
;========================================
reset:
mov A, EP2_FIFO ;move data stack pointer
swap A, dsp ;so it does not write over USB FIFOs
mov a, VREG_EN_B
iowr USB_SCR ; enable USB
mov a, 80h
iowr USB_DA ; enable USB address
mov a, 0Fh
iowr EP0_MODE
mov a, 06h
iowr CLOCK_CONFIG
mov a, ACKIN
iowr EP1_MODE ;initialize endpoint 1 mode to accept in's
mov a, ACKOUT
iowr EP2_MODE
mov a, 01h
iowr GIER
mov a, 07h
iowr EP_IE
ei
iord SCR
and a, LVR_BROUT_B;RESET_MASK
cmp a, LVR_BROUT_B ; test for POR(Low Voltage or Brown out) Reset
jz por_reset
and A, BUS_INT_EVENT ; test for USB Reset
jz bus_reset
jmp wdog_reset
;========================================
;
; 128us Interrupt
;
;========================================
;
; {
; If (the previous 128us interrupt has been missed)
; {make appropriate corrections}
; If (the timer has rolled over)
; {increment timer msb}
; Return from Interrupt
; }
;
;========================================
Isr128:
push a
iord TIMER_LSB ; check that we haven't missed an interrupt
xor a, [timer_sync] ; timer_sync saves the msb of timer as a
and a, BIT7 ; check against missed 128us interrupts.
jnz in_sync ;
or a, [timer_sync] ; missed, so make corrections - note a=0 because of jnz
jz in_sync ; if 0 then we didn't miss an overflow
inc [timer_msb] ; if not we did, so correct missed overflow
in_sync:
iord TIMER_LSB ; check to see if the timer has overflowed
and a, BIT7 ;
mov [timer_sync], a ;
jnz .Reti ;
inc [timer_msb] ; adjust the msb if it has
.Reti:
mov a, (EP0_IE+EP1_IE+EP2_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
ei
reti
;========================================
;
; Isr1ms
;
;========================================
;
; {
; Increment task number
; Check and flag missed 128us interrupts
; If (no bus activity in last 1ms)
; inc inactivity timer
; }
;
;========================================
Isr1ms:
push a
inc [task_number]
mov a, 00h ; flag 1ms event to main code
mov [new_task], a ;
mov a, [timer_msb] ; check that no 128us ISRs have been missed
and a, (BIT0 + BIT1) ; Bits 1 and 2 should always be zero,
jz .CheckActivity ; timer error should be checked and cleared after
mov [timer_error], a ; any time measurement.
.CheckActivity:
iord USB_SCR
and a, ACTIVITY_B
jz .IncCtr
iord USB_SCR
and a, ~ACTIVITY_B
iowr USB_SCR
mov a, 0
mov [suspend_counter], a
jmp .Reti
.IncCtr:
inc [suspend_counter]
.Reti:
mov a, (EP0_IE+EP1_IE+EP2_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
;========================================
;
; IsrEp0
;
;========================================
;
; {
; }
;
;========================================
IsrEp0:
push a
iord USB_DA ; re-enable USB
or a, 80h
iowr USB_DA
iord EP0_MODE ; re-enable mode
or a, 0Fh
iowr EP0_MODE
and a, EP0_SETUP_B ; check if SETUP packet received
jz .NotSetup ;
call DecodeRequest ; parse SETUP packet
jmp .Reti
.NotSetup:
iord EP0_MODE ;
and a, EP0_OUT_B ; ignore null packet interrupts
jnz .Reti
iord EP0_MODE ; do not continue unless xfer of last paket is complete
;and a, EP0_ACK ; note the Input Enable bit is set when the host ACKs
;jz .Reti
; will need to add more checks here when set report and
; get report support is added
call ControlReadDataStage ; continue sending control read data packets
.Reti:
mov a, 0fh
iowr EP0_MODE
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ; enable endpoint zero interrupts
iowr GIER ;
pop a
reti
;========================================
;
; IsrEp1
;
;========================================
;
; {
; invert the data toggle bit
; }
;
;========================================
IsrEp1:
push a
iord EP1_COUNT
xor a, DATA01_B
or a, 01h
iowr EP1_COUNT
iord EP1_MODE
mov a, 0fh
iowr EP1_MODE
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
;========================================
;
; IsrGpio
;
;========================================
;
; {
; }
;
;========================================
IsrGpio:
push a
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
;========================================
;
; process_reset
;
;========================================
;
; {
; }
;
;========================================
por_reset:
mov a, ffh
iowr P0_data ;set all ports to output 1
iowr P1_data
mov a, 00h
iowr P0_interrupt ;disable gpio interrupts on all pins
iowr P1_interrupt ;
iowr P0_Mode0 ;Setup all ports for Resistive
iowr P1_Mode0 ;ie pullup states
mov a, FFh ;
iowr P0_Mode1 ;
iowr P1_Mode1 ;
iowr WDT ; clear wdt timer
mov a, bottom_of_ram
mov x, top_of_ram
ram_clr_loop: ; clear all ram locations
mov [x+0], a
dec x
jnc ram_clr_loop
iord SCR
and a, BUS_INT_EVENT
jnz bus_reset
suspend_reset:
iowr WDT
jmp suspend_reset
mov A, (RUN_B + SUSPEND_B)
iowr SCR ; suspend the mcu
nop
jmp suspend_reset ; wait until real bus reset
wdog_reset:
jmp suspend_reset ;suspend and wait for USB Bus Reset
bus_reset:
mov a, 80h
iowr USB_DA
mov A, RUN_B ; clear all reset bits
iowr SCR
mov a, EP0_IE
iowr EP_IE ; enable EP interrupt here because no longer in GIER ; setup for enumeration
mov A, ENUMERATE_MASK
mov [interrupt_mask],A
iowr GIER
ei
;========================================
;
; project-specific initialisation
;
;========================================
;
; {
; Do project-specific initialisation
; }
;
;========================================
UserReset:
;========================================
;
; main
;
;========================================
;
; {
; reset watchdog timer
; check for USB suspend condition
; if (time to do next task)
; {
; if (device is not enumerated)
; jump to pre-enumeration task
; else if (task number out of range)
; task number := 0
; jump to task
; }
; }
;
;========================================
main:
iowr WDT ; kick the dog
call CheckSuspend
and a, [new_task] ; new_task is active if = 0
jnz main ; wait for next time slice
inc [new_task]
mov a, configuration_status ; for designs intended to power-up when
and a, ffh ; disconnected from the bus, this code
jz NotEnumerated ; may not be appropriate.
mov a, [task_number] ; jump to current tasklet
asl ; x2 because jmp is 2 instructions
cmp a, (end_task_table - task_table) ; check to ensure not out of range
jc .DoTheJump
mov a, 00h
mov [task_number], a ; user may want to add own error recovery code here
.DoTheJump:
jacc task_table ; execute the selected task
XPAGEOFF
task_table:
jmp Task0
jmp Task1
jmp Task2
jmp Task3
jmp Task4
jmp Task5
jmp Task6
jmp Task7
end_task_table:
XPAGEON
;========================================
;
; Check Suspend
;
;========================================
;
; {
; if (time since last usb activity is > suspend time)
; {
; set io ports into suspend state
; set interrupts into suspend state
; while (no bus activity)
; suspend
; restore interrupts
; restore io state
; }
; return
; }
;
;========================================
CheckSuspend:
mov a, [suspend_counter] ; check the suspend timer to see how long since last
sub a, SUSPEND_TIME ; bus activity.
jc .Ret ;
mov a, 00h ; clear the suspend counter to avoid any risk we might
mov [suspend_counter], a ; suspend again before the 1ms isr clears it on wakeup
iord P0_data ; save io port status
push a ;
iord P1_data ;
push a ;
iord P0_Mode0 ;
push a ;
iord P1_Mode0 ;
push a ;
iord P0_Mode1 ;
push a ;
iord P1_Mode1 ;
push a ;
mov a, ffh ; to ensure minimum current drain during suspend
iowr P0_data ; all ports must be logic 1 with pullup on unless
iowr P1_data ; externally driven.
mov a, 00h ;
iowr P0_Mode0 ;
iowr P1_Mode0 ;
mov a, ffh
iowr P1_Mode1 ; user to modify these values depending on circuit
iowr P0_Mode1 ;
iord GIER ; set which interrupts may cause wake from suspend
and a, SUSPEND_MASK ; user may also want to change GPIO interrupt
iowr GIER ; masking here
iord SCR ; put the device into suspend
or a, SUSPEND_B ;
iowr SCR ;
nop ; instruction the code wakes up to
pop a ; Restore io port status
mov a, FFh
iowr P1_Mode1
pop a
mov a, FFh
iowr P0_Mode1
pop a
mov a, 00h
iowr P1_Mode0
pop a
mov a, 00h
iowr P0_Mode0
pop a
mov a, FFh ;
iowr P1_data ;
pop a
mov a, FFh ;
iowr P0_data ;
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
ei
.Ret:
ret
;========================================
;
; Not Enumerated
;
;========================================
;
; This module is run if enumeration is incomplete
;
;========================================
NotEnumerated:
jmp main
;========================================
;
; Task 0
;
;========================================
;
; {
; read Buttons
;
; }
;
;========================================
Task0:
iord Buttons_port
mov [Buttons_debounce], a
jmp main
;========================================
;
; Task 1
;
;========================================
;
; {
; do nothing
; }
;
;========================================
Task1:
jmp main
;========================================
;
; Task 2
;
;========================================
;
; {
; do nothing
; }
;
;========================================
Task2:
jmp main
;========================================
;
; Task 3
;
;========================================
;
; {
; do nothing
; }
;
;========================================
Task3:
jmp main
;========================================
;
; Task 4
;
;========================================
;
; {
; if (Buttons state has been stable for 5ms)
; save Buttons
; }
;
;========================================
Task4:
iord Buttons_port
cmp a, [Buttons_debounce]
jnz main
mov a, [Buttons_debounce]
cpl a
mov [EP1_FIFO], a
mov a, ACKIN
iowr EP1_MODE
jmp main
;========================================
;
; Task 5
;
;========================================
;
; {
; }
;
;========================================
Task5:
jmp main
;========================================
;
; Task 6
;
;========================================
;
; {
; }
;
;========================================
Task6:
jmp main
;========================================
;
; Task 7
;
;========================================
;
; {
; Write Ep2 info to LED's
; And reset Mode of EP2
; }
;
;========================================
Task7:
mov a, [EP2_FIFO]
iowr LEDs_port
mov a, ACKOUT
iowr EP2_MODE
jmp main
include "usbcode.asm"
IsrEp2:
push a
mov a, (EP0_IE+EP1_IE+EP2_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
mov a, ACKOUT
iowr EP2_MODE
pop a
reti
IsrSPI:
push a
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
IsrCaptureA:
push a
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
IsrCaptureB:
push a
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
IsrWakeup:
push a
mov a, (EP0_IE+EP1_IE)
iowr EP_IE ; enable EP interrupt here because no longer in GIER
mov a, [interrupt_mask] ;
iowr GIER ;
pop a
reti
;IMPORTANT!!!!!!!!!!!!
;This is a BETA version of Firmware that has not been
;fully tested. PLEASE keep this in mind and use this
;firmware as REFERENCE.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -