📄 ax_enum.asm
字号:
pop PSW
reti
$$END$
;COMMENT *------------------------------------------------------------
;Function name : ProcessOutToken
;Brief Description : Services all OUTs on EP0.
; : This routine checks to see if this is an OUT token oor
; : SETUP token. If a SETUP token then the Control COmmand
; : State machine is initilized to SETUP STAGE
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
ProcessOutToken:
anl FIFLG, #EP0_RX_CLR ; Clear the interrupt bit.
; jmp ProcCommand
ProcCommand:
mov A, RXSTAT
jnb ACC.6, CheckOutStatusPhase ; Is this a setup packet??
; Now Check for Data still in FIFO.
; If this is true then the function
; did not see the ACK form the host.
mov A, TXFLG
anl A, #0C0h
jZ NoEP0Error
setb TXCLR ; Flush the Transmit FIFOS in case
; a null packet is still left.
NoEP0Error:
; Check to see if the stall bit is set.
mov A, EPCON
anl A, #0C0h
jz NoEp0Stall
anl EPCON, #03Fh ; Clear the stalls
orl TXSTAT, #88h ; Set data toggle on TX ep0.
NoEp0Stall:
lCall SetupReceived
sjmp ReturnProcessOutToken
CheckOutStatusPhase:
mov A, gbSetupSeqRX
cjne A, #STATUS_PHASE, CheckDataPhase ; Is this the status phase of a "GET"
; command?
setb RXFFRC ; Update receive FIFO state
mov A, #SETUP_PHASE ; Update the state machine to
; expect a setup packet
mov gbSetupSeqRX, A
mov gbSetupSeqTX, A
sjmp ReturnProcessOutToken
;---------------------------------------------------------------
; - Control Write Data Stage
;---------------------------------------------------------------
; If this is a control write command with a datastage then this
; routine will be called on all data stages of the control write.
; When all the data has been collected(Bytes received=wLength)
; the actual routine is called. The size of data is limited to this
; buffer length.
; THE CALLING CODE MUST THEN CALL SetUpControlWriteStatusStage to allow
; the status stage to continue. The user must NOT do this themselves.
; Later in the life of this code, other features will be added here.
CheckDataPhase:
cjne A, #DATA_PHASE, BadOutToken
; Are we processing a Control Write,
; i.e. Set Descr...
; Added to handle control writes with data stages.
; When a control Write with a data stage is detected
; the data is placed in the buffer 'CntlWriteDataBuffer'
; When all the data
; has been collected(Bytes received=wLength) the actual routine is
; called. The size of data is limited to this buffer length.
;---------------------------------------------------------
;------------------- NOTE --------------------------------
;---------------------------------------------------------
; For this routine to work all the data must be stored below
; 100h as I am using byte addressing. Also, since 80-FF is used
; as SFRs and I don't want to for the user to use indirect
; addressing, the data must ne stored between 20h-7Fh.
; Also, these routines will only work for data sets of less than
; 256. But the above limitations put this the max much ower than
; this. MaxBuffer = (7F-20h-Other varaibles in this region)
push R0
mov A, #CntlWriteDataBuffer ; Get location of buffer
add A, CntlWriteDataPntr ; Add the offset
mov R0, A ; R0 now contains the location to start storing the
; data.
; Update the data stored in memory
mov A, RXCNTL ; Get number of bytes to move
add A, CntlWriteDataPntr ; Add number received
mov CntlWriteDataPntr, A ; update memory variable
mov A, RXCNTL
JZ RdDone ; If no data in the buffer, then exit.
ReadData:
mov @R0, RXDAT ; Get the data and store it.
inc R0
djnz ACC, ReadData
pop R0
RdDone:
setb RXFFRC ; Update receive FIFO state
; Now check to see if this was the last
; read by checking if (Bytes received=wLength)
mov A, CntlWriteDataPntr
cjne A, wLength+1, NeedMoreData ; If this is not equal to the expected, then jmp around.
; When all the data has been received, the
; other routines in this program will
; be called to process it.
ProcessControlWriteData:
push DPX ; Processing the jump table will
; corrupt DPX. Save it here
lcall DoJumpTable ; At this point all data has been
; stored and all we need to do now is to
; process it.
pop DPX ; Restore DPX
sjmp ReturnProcessOutToken
NeedMoreData:
CheckCommand2:
BadOutToken:
orl EPCON, #0C0h ; Who knows what this was. Stall the EP.
ReturnProcessOutToken:
Ret
;COMMENT *------------------------------------------------------------
;Function name : SetupReceived
;Brief Description : Service all Setup Tokens recd. on EP0
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
SetupReceived:
mov A, RXCNTL ; Get the no. of bytes
clr CY
subb A, #8 ; 8 is length of all setup packets.
JNZ ReturnSetup ; If less than 8 bytes recd.
; Return
; Since buffer will reside within the
; the first 255 bytes, I can use
; register indirect addressing
; Move FIFO to command buffer.
; Notice byte swapping of word fields
; For Word Fields make USB Little Endian words->'251 Big Endian words
clr EDOVW
mov COMMAND_BUFFER, RXDAT ; bmRequestType
mov COMMAND_BUFFER+1, RXDAT ; bRequest
mov COMMAND_BUFFER+3, RXDAT ; wValue LSB
mov COMMAND_BUFFER+2, RXDAT ; wValue MSB
mov COMMAND_BUFFER+5, RXDAT ; wIndex LSB
mov COMMAND_BUFFER+4, RXDAT ; wIndex MSB
mov COMMAND_BUFFER+7, RXDAT ; wLength LSB
mov COMMAND_BUFFER+6, RXDAT ; wLength MSB
push DPX ; Processing the jump table will
; corrupt DPX. Save it here
;(KLS)
setb RXFFRC
clr RXSETUP
lCall ProcessSetup
pop DPX ; Restore DPX
ReturnSetup:
Ret
;COMMENT *------------------------------------------------------------
;Function name : ProcessSetup
;Brief Description : Process a Setup token recd. on EP0. Thile some of the
; : code may look sifficult to understand the end result is not.
; : The following simply prepares a byte of data for use in a jump table.
; : The code compresses the 8 byte bmRequestValue into 4 1/2
; : bits by removing bits 2,3 & 4. These bits are never used
; : and it allows the jump table to be signfigantly smaller.
; : By using this jump table, the code size reduces by several
; : hundred bytes over the entire code!
; : THIS FIRMWARE IS ASSUMES BITS 2,3 & 4 are zero!!!!
; : By compressing the byte down, we limit the size
; : of the jump table.
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
ProcessSetup:
; The First step is setting up the Stage tracing variable by examing the
; bmRequest value. This will tell us if this is a control Write
; or control read command. For right now we will assume that this
; is a no data command and will therefore pre-initilize the data
; byte counters used to send data back, to zero.
mov gbFControlBufferBytesLeft, #00h
mov gbFControlBufferBytesLeft + 1, #00h
mov A, bmRequestType
jb ACC.7, SetupGetCommand
SetupSetCommand:
mov gbSetupSeqRX, #DATA_PHASE ; Advance State Machine to next state
mov gbSetupSeqTX, #STATUS_PHASE
; Now check to see if this is a control write with a data stage.
mov A, wLength
orl A, wLength+1
jz DoJumpTable ; If this is a no data command then process it
mov CntlWriteDataPntr, #0 ; Initilize the data pointer for future control write
; data stages.
ret ; If we are expecting data then don't
; process the command yet. Exit and wait
; for the rest of the data to come in.
SetupGetCommand:
mov gbSetupSeqRX, #STATUS_PHASE ; Advance State Machine to next state
mov gbSetupSeqTX, #DATA_PHASE
DoJumpTable:
; This table will jump to the correct subroutine
; to handle the type of command contained in bmRequestType
; The new jmp table will be compressed by shifting and rotating
; out bits, 2,3 & 4.
; Place bmRequestType in the following order and then do the jump table
; on it.
; xx65107x
; if bits 65 == 11, Reserved = Error
; Unless you have time, don't spend a lot of time tracing the algorythm
; It's fancy and it works. If you don't understand it go ask someone for a quarter.
mov A, bmRequestType ; Get the value.
anl A, #0E3h ; Clear out bits 2,3,4 since
; we don't need these
; Reg A now looks like 765xxx10
RL A ; Put bits 1,0,& 7 in new placement
RL A ; Leave LSB cleared so jump is the number of words.
; xxxx1076
CheckBit6: ; 6 is currently in bit 0 position,
jnb ACC.0, CheckBit5 ; Convert it to bit 5 position
setb ACC.5 ; xx6x107x
CheckBit5: ; Bit 5 is currently at 7 position
jnb ACC.7, CheckValidType ; Convert it to bit 4 position
setb ACC.4 ; xx65107x
CheckValidType: ;
jnb ACC.5, GoodCommand ; If this bit (6) is clear we know
; it's a valid value
jb ACC.4, ReservedCommand ; Bit (6) was set, if bit 5 is set it's
; a reserved command.
sjmp GoodCommand
ReservedCommand:
orl EPCON, #0C0h ; Stall EP0.
ret
; THis code will branch to the correct jump statement
; in the bmRequestJumpTable below.
GoodCommand: ; Code added to convert AJMP table to LJMP table.
anl A, #3Eh ; Multiply SJMP offset by 3/2 to get LJMP offsett.
mov B, A ; Save the original
rr A ; Divide origianl by two
anl A, #1fH ;
clr CY ;
ADD A, B ; 2/2 + 1/2 = 3/2
mov DPTR, #bmRequestJumpTable
mov DPXL, #LOW HIGH16(GoodCommand) ; Get Page of Jump Table.
; Is this code in RAM or ROM?
; Low byte of the upper 16 bits of the 32 bit address of the
; jump table.
; Used because I use RISM sometimes
; which places code in RAM
jmp @A+DPTR
;---------------------------------------
;-- bmRequest Jump Table ---------------
;-- The order of these are based on the
;-- compresion algorythm used above.
;-- Each of these instructions occupy two bytes of
;-- ROM. Do not change LJMP to AJMP as the algorytm depends on the
;-- 3 byte length of LJMP. AJMP is 2 bytes long
;-- ------------------------------------
bmRequestJumpTable:
LJMP StandardSetDeviceCommand
LJMP StandardGetDeviceCommand
LJMP StandardSetInterfaceCommand
LJMP StandardGetInterfaceCommand
LJMP StandardSetEndpointCommand
LJMP StandardGetEndpointCommand
LJMP StandardSetOtherCommand
LJMP StandardGetOtherCommand
LJMP ClassSetDeviceCommand
LJMP ClassGetDeviceCommand
LJMP ClassSetInterfaceCommand
LJMP ClassGetInterfaceCommand
LJMP ClassSetEndpointCommand
LJMP ClassGetEndpointCommand
LJMP ClassSetOtherCommand
LJMP ClassGetOtherCommand
LJMP VendorSetDeviceCommand
LJMP VendorGetDeviceCommand
LJMP VendorSetInterfaceCommand
LJMP VendorGetInterfaceCommand
LJMP VendorSetEndpointCommand
LJMP VendorGetEndpointCommand
LJMP VendorSetOtherCommand
LJMP VendorGetOtherCommand
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -