📄 usbasm.txt
字号:
;*******************************************************
; Interrupt handler: bus_reset
; Purpose: The program jumps to this routine when
; the microcontroller has a bus reset.
;*******************************************************
bus_reset:
push A
iord CPU_ctl
and A, 0DFh ; clean BUS reset bit[5],[1101,1111]
iowr CPU_ctl
mov A, 05h ; enable 1-ms interrupt and bus reset interrupt only,[0000,0101]
iowr Global_int
mov A, 01h ; enable endpoint 0 interrupt only
iowr EP_int
iord EP0_mode ; unlock EP0 mode register
bus_reset_stall:
mov A, stall ; stall=03h , set EP0 stall in/out mode, accept setup
; mov A, ignore ; ignore=04h, set EP0 ignore in/out mode, accept setup
iowr EP0_mode
; iord EP0_mode
; and A, 0fh
; cmp A, 00h
; jz bus_reset_stall
mov A, 80h ; enable USB address=0
iowr USB_address
mov A, disabled ; disable endpoint1
iowr EP1_mode ; disable endpoint2
iowr EP2_mode
; mov A, 00h
; mov psp, A
iord Global_int
or A, 20h ; re-enable HAPI_int interrupt [0010,0000]
iowr Global_int
mov A, 01h
mov [bus_reset_flag], A
pop A
; jmp reset
reti
;*******************************************************
; Interrupt handler: unused_int
; 128us_int, endpoint3_int,
; endpoint4_int, DAC_int,
; I2C_int
; Purpose: If the all above interrupt is enabled, the
; program will jump to here. In this program
; the all above interrupt is not used.
;*******************************************************
unused_int:
; do nothing
reti
;*******************************************************
; Interrupt handler: 1ms_int
; Purpose: Every 1ms this interrupt handler clears
; the watchdog timer.
;*******************************************************
1ms_int:
push A
mov A, 41h
iowr WDT ; clear watchdog timer
pop A
reti
;*******************************************************
; Interrupt handler: HAPI_int
; Purpose: This interrupt generated every time when
; HC12 write data to PORT 0&1, and when HC12
; read data from PORT 0&1
;*******************************************************
HAPI_int:
push A
push X
iord HAPI_I2C_cfg
and A, 08h ; [0000,1000], check bit[3]Latch Empty,[Empty=1, Full=0]
jnz write_data ; check interrupt caused by sending or receiving
iord Port1 ; interrupt caused by HC12 write CY port, Full=0
and A, 07h ; check Port1.bit[2:0],A[2:0], [0000,0111]
mov [byte_type], A
cmp A, HAPI_CTRL ; check BYTE 3
jz byte_3
cmp A, HAPI_PDOUT ; check BYTE 0
jz byte_0
cmp A, HAPI_UDOUT ; check BYTE 1
jz byte_1
cmp A, HAPI_STAT ; check BYTE 4
jz byte_4
cmp A, HAPI_UDIN ; check BYTE 2
jz byte_2
jmp HAPI_int_done ; invalid data
byte_3: ; HC12 sets CTRL Control Register
iord Port0
mov [HAPI_CTRL_reg], A
and A, HAPI_ULAST ; check ULAST bit
jz no_ULAST ; no PTIE, no UTIE, no URIE, no ULAST - invalid data
call end_trans ; HC12 ends USB data transmission
no_ULAST:
call get_printer_status
; mov A, [printer_RDY]
; cmp A, 01h
; jz HAPI_int_done
mov A, [HAPI_STAT_reg] ; return STAT
iowr Port0
jmp HAPI_int_done
byte_0: ; HC12 sets PDOUT Printer data-out Data Register
iord Port0
mov [temp_print_data], A
call send_to_printer ; sends to printer
call get_printer_status ; get device status
mov A, [printer_RDY]
cmp A, 01h
jz HAPI_int_done
mov A, [HAPI_STAT_reg] ; returns device status
; or A, HAPI_PTDRE ; sets PTDRE
; mov [HAPI_STAT_reg], A
iowr Port0 ; returns STAT
jmp HAPI_int_done
byte_1: ; HC12 sets UDOUT USB data-out Data Register
iord Port0
call put_send_buffer ; receiving HC12's USB data
call get_printer_status
mov A, [HAPI_STAT_reg] ; return STAT
iowr Port0
jmp HAPI_int_done
byte_4: ; HC12 sets STAT Device Status Register
call get_printer_status ; get printer status
mov A, [HAPI_STAT_reg] ; CY returns Device Status
iowr Port0
jmp HAPI_int_done
byte_2: ; HC12 sets UDIN USB data-in Data Register
call send_to_HC12 ; send data to HC12
mov A, [HAPI_UDIN_reg]
iowr Port0
jmp HAPI_int_done
write_data: ; interrupt caused by HC12 read from CY port, IGNORE
; nop ; interrupt caused by HC12 read from CY port, IGNORE
HAPI_int_done:
pop X
pop A
reti
;*******************************************************
; HAPI Function:
;*******************************************************
;*******************************************************
; Function: get_device_status
; Purpose: Get printer status,
; Put result to [HAPI_STAT_reg]
;*******************************************************
get_printer_status:
push A
get_error:
iord DAC_data ; check error bit set or not, DAC.bit[0]
and A, 01h ; [0000,0001], check DAC.bit[0]ERR
jnz check_printer_busy ; if DAC.bit[0]ERR=1, no error
mov A, [perror_counter]
inc A
mov [perror_counter], A
cmp A, 0ffh
jz printer_error
jmp get_error
check_printer_busy: ; DAC.bit[0]ERR=1, no error
iord DAC_data ; check BSY bit set or not, DAC.bit[1]
and A, 02h ; [0000,0010]
jz printer_ready ; DAC.bit[1]BSY=0, no busy
mov A, 0ffh
mov [delay_time], A
call delay
mov A, [pbusy_counter]
inc A
mov [pbusy_counter], A
cmp A, 0ffh ; 390usx255=100ms(almost)
jz printer_busy
jmp check_printer_busy
printer_error:
mov A, 00h
mov [perror_counter], A
mov A, [HAPI_STAT_reg]
or A, HAPI_PERROR ; set bit5 printer error (offline or out of paper)
; and A, 0feh ; [1111,1110] clear PTDRE
mov [HAPI_STAT_reg], A
jmp printer_wrong
printer_busy:
mov A, 00h
mov [pbusy_counter], A
mov A, [HAPI_STAT_reg]
or A, HAPI_PBUSY ; set bit3 printer busy
; and A, 0feh ; clear PTDRE
mov [HAPI_STAT_reg], A
printer_wrong:
mov A, 01h
mov [printer_RDY], A
mov A, [HAPI_STAT_reg]
and A, 0feh ; clear bit0 PTDRE, [1111,1110]
mov [HAPI_STAT_reg], A
jmp get_printer_status_done
printer_ready:
mov A, 00h
mov [printer_RDY], A
mov [pbusy_counter], A
mov [perror_counter], A
mov A, [HAPI_STAT_reg]
and A, HAPI_PRDY ; clear bit5 and bit3, [1101,0111]
or A, HAPI_PTDRE
mov [HAPI_STAT_reg], A
get_printer_status_done:
pop A
ret
;*******************************************************
; Function: put_send_buffer
; Purpose: Receiving 1 byte UDOUT data from HC12 and
; put it into send_data buffers
;*******************************************************
put_send_buffer:
mov X, [send_data_counter] ;init of send_data_counter=0
mov [X + EP1_buffer0], A
inc X
mov A, X
mov [send_data_counter], A
mov A, [HAPI_STAT_reg] ; set bit1 UTDRE,
or A, HAPI_UTDRE
mov [HAPI_STAT_reg], A
mov A, X
cmp A, 20h ; 32 bytes
jnz put_send_buffer_done
mov A, 00h ; 32 byte EP1 buffers was full
mov [send_data_counter], A
mov A, [HAPI_STAT_reg]
and A, 0fdh ; clear bit1 UTDRE, x[1111,1101]
mov [HAPI_STAT_reg], A
iord EP_int
or A, 02h ; enable EP1 interrupt +[0000,0010]
iowr EP_int ; prepare to send data to PC (EP1)
mov A, 20h ; data length
or A, [EP1_data_toggle]
iowr EP1_counter
mov A, in_ack ; set ACK-IN mode
iowr EP1_mode
; iord Global_int
; and A, 0dfh ; disable HAPI_int interrupt [1101,1111]
; iowr Global_int ;(will be enabled in MainLoop after calling send_data)
put_send_buffer_done:
ret
;*******************************************************
; Function: end_trans
; Purpose: Fill send_data buffer with 0,
; combine 32 bytes data for EP2
;*******************************************************
end_trans:
mov X, [send_data_counter]
mov A, X ; HC12 sends multiple of 32 bytes data
; cmp A, 20h
jz end_trans_done
fill_send_buffer:
mov A, 80h ; fill send_data_buffer with "80h" to combine 32 bytes
mov [ X + EP1_buffer0], A ; 80h - Command Terminator
inc X
mov A, X
cmp A, 20h ; total 32 bytes
jnz fill_send_buffer
mov A, 00h ; 32 byte EP1 buffers was full
mov [send_data_counter], A
mov A, [HAPI_STAT_reg]
and A, 0fdh ; clear bit1 UTDRE, x[1111,1101]
mov [HAPI_STAT_reg], A
iord EP_int
or A, 02h ; enable EP1 interrupt +[0000,0010]
iowr EP_int ; prepare to send data to PC (EP1)
mov A, 20h ; data length
or A, [EP1_data_toggle]
iowr EP1_counter
mov A, in_ack ; set ACK-IN mode
iowr EP1_mode
; iord Global_int
; and A, 0dfh ; disable HAPI_int interrupt [1101,1111]
; iowr Global_int ; (will be enabled in Main after calling send_data)
end_trans_done:
ret
;*******************************************************
; Function: send_to_HC12
; Purpose: Send 1 byte data to HC12
;*******************************************************
send_to_HC12:
mov A, [HC12_data_counter]
mov X, A
mov A, [X + recvpc_data0]
mov [HAPI_UDIN_reg], A
cmp A, COMM_END ; COMM_END = 80h, Command Terminator(send by PC)
jz send_over
inc X
mov A, X
mov [HC12_data_counter], A
cmp A, 20h
jnz send_to_HC12_done
send_over: ; all data with Command Terminator already was sent to HC12
mov A, [HAPI_STAT_reg] ; 32 bytes data was sent to HC12 already
and A, 0fbh ; clear URDRF bit [1111,1011]
mov [HAPI_STAT_reg], A
;--------- mod at Aug,09 2001 ----------------------
iord EP_int ; enable EP2 interrupt +[0000,0100]
or A, 04h
iowr EP_int
mov A, out_ack ; enable EP2, prepare to receive next 32 bytes
iowr EP2_mode ; prepare to receive next 32 byte data
;--------- mod end at Aug,09 2001 ----------------------
; mov A, 00h
; mov [HC12_data_counter], A
send_to_HC12_done:
ret
;*******************************************************
; HAPI Function End
;*******************************************************
;*******************************************************
; Function: get_USB_status
; Purpose: Get USB bus status,
; Put result to [HAPI_STAT_reg]
;*******************************************************
get_USB_status:
push A
iord USB_ctl
and A, BUS_activity_clean ; clean bus_activity
iowr USB_ctl
mov A, 0ffh
mov [delay_time], A
call delay ; delay 3x390us = 1.2ms (almost)
call delay ; waitting for SIE set the USB_ctl.bit3
call delay
iord USB_ctl
and A, 08h ; check USB_ctl.bit3,[0000,1000]
jz no_usb_connect
mov A, [HAPI_STAT_reg]
and A, 0afh ; clear STAT.bit4 UBUSY and STAT.bit6 UERROR [1010,1111]
; or A, UREADY ; set UREADY bit ;;(add at Aug,20 2001)
mov [HAPI_STAT_reg], A ; USB ready
jmp get_USB_status_done
no_usb_connect: ; no connection with USB Host
mov A, [HAPI_STAT_reg]
or A, HAPI_UBUSY
or A, HAPI_UERROR
; and A, 7fh ; clear UREADY x[0111,1111];;(add at Aug,20 2001)
mov [HAPI_STAT_reg], A
get_USB_status_done:
pop A
ret
;*******************************************************
; get_USB_status Function End
;*******************************************************
;*******************************************************
; Interrupt handler: endpoint_zero
; Purpose: This interrupt routine handles the specially
; reserved control endpoint 0 and parses setup
; packets. If a IN or OUT is received, this
; handler returns to the control_read
; or no_data_control routines to send more data.
;*******************************************************
;*******************************************************
; step 0: Check setup bit and data valid
;*******************************************************
endpoint_zero:
push A
iord EP0_mode
and A, 80h ; check if SETUP packet received, setup bit[7]
jz no_setup
iord EP0_mode
and A, 9fh ; [1001,1111]
cmp A, 91h ; [1001,0001]
jnz still_in_out
iord EP0_counter
and A, 0cfh ; check data length=10 [1100,1111] and
cmp A, 4ah ; data_toggle bit[7]=0, data_valid bit[6]=1,[0100,1010]
jnz still_in_out
iord EP_int
and A, 0feh ; disable endpoint0 interrupt bit[1], [1111,1110]
iowr EP_int
ei ; enable other interrupt
call parse ; SETUP ...goto parsing
di
iord EP_int
or A, 01h ;(01h); enable endpoint0 interrupt bit[1], [0000,0001]
iowr EP_int
; call prepare_EP ; enable endpoint1, endpoint2
no_setup:
; iord EP_int
pop A
reti ; IN or OUT, or SETUP completed
still_in_out:
mov A, stall ; set ep0 mode register STALL mode stall=03h
iowr EP0_mode
jmp no_setup
;************* start parsing packet ********************
;*******************************************************
; step 1: Determine type of transfer (bmRequestType)
;*******************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -