?? usbtiny2313.asm
字號:
breq ComposeSET_DESCRIPTOR ;
cpi temp1,GET_CONFIGURATION ;
breq ComposeGET_CONFIGURATION ;
cpi temp1,SET_CONFIGURATION ;
breq ComposeSET_CONFIGURATION ;
cpi temp1,GET_INTERFACE ;
breq ComposeGET_INTERFACE ;
cpi temp1,SET_INTERFACE ;
breq ComposeSET_INTERFACE ;
cpi temp1,SYNCH_FRAME ;
breq ComposeSYNCH_FRAME ;
;if not found known request
rjmp ZeroDATA1Answer ;if that was something unknown, then prepare zero answer
ComposeSET_ADDRESS:
lds temp1,InputBufferBegin+4 ;new address to temp1
rcall SetMyNewUSBAddresses ;and compute NRZI and bitstuffing coded adresses
ldi State,AddressChangeState ;set state for Address changing
rjmp ZeroDATA1Answer ;send zero answer
ComposeSET_CONFIGURATION:
lds ConfigByte,InputBufferBegin+4 ;number of configuration to variable ConfigByte
ComposeCLEAR_FEATURE:
ComposeSET_FEATURE:
ComposeSET_INTERFACE:
ZeroStringAnswer:
rjmp ZeroDATA1Answer ;send zero answer
ComposeGET_STATUS:
TwoZeroAnswer:
ldi temp0,2 ;number of my bytes answers to temp0
ComposeGET_STATUS2:
ldi ZH, high(StatusAnswer<<1) ;ROMpointer to answer
ldi ZL, low(StatusAnswer<<1)
rjmp ComposeEndXXXDescriptor ;and complete
ComposeGET_CONFIGURATION:
and ConfigByte,ConfigByte ;if I am unconfigured
breq OneZeroAnswer ;then send single zero - otherwise send my configuration
ldi temp0,1 ;number of my bytes answers to temp0
ldi ZH, high(ConfigAnswerMinus1<<1) ;ROMpointer to answer
ldi ZL, low(ConfigAnswerMinus1<<1)+1
rjmp ComposeEndXXXDescriptor ;and complete
ComposeGET_INTERFACE:
ldi ZH, high(InterfaceAnswer<<1) ;ROMpointer to answer
ldi ZL, low(InterfaceAnswer<<1)
ldi temp0,1 ;number of my bytes answers to temp0
rjmp ComposeEndXXXDescriptor ;and complete
ComposeSYNCH_FRAME:
ComposeSET_DESCRIPTOR:
rcall ComposeSTALL
ret
ComposeGET_DESCRIPTOR:
lds temp1,InputBufferBegin+5 ;DescriptorType to temp1
cpi temp1,DEVICE ;DeviceDescriptor
breq ComposeDeviceDescriptor ;
cpi temp1,CONFIGURATION ;ConfigurationDescriptor
breq ComposeConfigDescriptor ;
cpi temp1,STRING ;StringDeviceDescriptor
breq ComposeStringDescriptor ;
ret
ComposeDeviceDescriptor:
ldi ZH, high(DeviceDescriptor<<1) ;ROMpointer to descriptor
ldi ZL, low(DeviceDescriptor<<1)
ldi temp0,0x12 ;number of my bytes answers to temp0
rjmp ComposeEndXXXDescriptor ;and complete
ComposeConfigDescriptor:
ldi ZH, high(ConfigDescriptor<<1) ;ROMpointer to descriptor
ldi ZL, low(ConfigDescriptor<<1)
ldi temp0,9+9+7 ;number of my bytes answers to temp0
ComposeEndXXXDescriptor:
lds TotalBytesToSend,InputBufferBegin+8 ;number of requested bytes to TotalBytesToSend
cp TotalBytesToSend,temp0 ;if not requested more than I can send
brcs HostConfigLength ;transmit the requested number
mov TotalBytesToSend,temp0 ;otherwise send number of my answers
HostConfigLength:
mov temp0,TotalBytesToSend ;
clr TransmitPart ;zero the number of 8 bytes answers
andi temp0,0b00000111 ;if is length divisible by 8
breq Length8Multiply ;then not count one answer (under 8 byte)
inc TransmitPart ;otherwise count it
Length8Multiply:
mov temp0,TotalBytesToSend ;
lsr temp0 ;length of 8 bytes answers will reach
lsr temp0 ;integer division by 8
lsr temp0
add TransmitPart,temp0 ;and by addition to last non entire 8-bytes to variable TransmitPart
ldi temp0,DATA0PID ;DATA0 PID - in the next will be toggled to DATA1PID in load descriptor
sts OutputBufferBegin+1,temp0 ;store to output buffer
rjmp ComposeNextAnswerPart
ComposeStringDescriptor:
ldi temp1,4+8 ;if RAMread=4(insert zeros from ROM reading) + 8(behind first byte no load zero)
mov RAMread,temp1
lds temp1,InputBufferBegin+4 ;DescriptorIndex to temp1
cpi temp1,0 ;LANGID String
breq ComposeLangIDString ;
cpi temp1,2 ;DevNameString
breq ComposeDevNameString ;
brcc ZeroStringAnswer ;if is DescriptorIndex higher than 2 - send zero answer
;otherwise is VendorString
ComposeVendorString:
ldi ZH, high(VendorStringDescriptor<<1) ;ROMpointer to descriptor
ldi ZL, low(VendorStringDescriptor<<1)
ldi temp0,(VendorStringDescriptorEnd-VendorStringDescriptor)*4-2 ;number of my bytes answers to temp0
rjmp ComposeEndXXXDescriptor ;and complete
ComposeDevNameString:
ldi ZH, high(DevNameStringDescriptor<<1) ;ROMpointer to descriptor
ldi ZL, low(DevNameStringDescriptor<<1)
ldi temp0,(DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2 ;number of my bytes answers to temp0
rjmp ComposeEndXXXDescriptor ;and complete
ComposeLangIDString:
clr RAMread
ldi ZH, high(LangIDStringDescriptor<<1) ;ROMpointer to descriptor
ldi ZL, low(LangIDStringDescriptor<<1)
ldi temp0,(LangIDStringDescriptorEnd-LangIDStringDescriptor)*2;pocet mojich bytovych odpovedi do temp0
rjmp ComposeEndXXXDescriptor ;and complete
;------------------------------------------------------------------------------------------
ZeroDATA1Answer:
rcall ComposeZeroDATA1PIDAnswer
ret
;------------------------------------------------------------------------------------------
SetMyNewUSBAddresses: ;set new USB addresses in NRZI coded
mov temp2,temp1 ;address to temp2 and temp1 and temp3
mov temp3,temp1 ;
cpi temp1,0b01111111 ;if address contains less than 6 ones
brne NewAddressNo6ones ;then don't add bitstuffing
ldi temp1,0b10111111 ;else insert one zero - bitstuffing
NewAddressNo6ones:
andi temp3,0b00000111 ;mask 3 low bits of Address
cpi temp3,0b00000111 ;and if 3 low bits of Address is no all ones
brne NewAddressNo3ones ;then no change address
;else insert zero after 3-rd bit (bitstuffing)
sec ;set carry
rol temp2 ;rotate left
andi temp2,0b11110111 ;and inserted zero after 3-rd bit
NewAddressNo3ones:
sts MyOutAddressSRAM,temp2 ;store new non-coded address Out (temp2)
;and now perform NRZI coding
rcall NRZIforAddress ;NRZI for AddressIn (in temp1)
sts MyInAddressSRAM,ACC ;store NRZI coded AddressIn
lds temp1,MyOutAddressSRAM ;load non-coded address Out (in temp1)
rcall NRZIforAddress ;NRZI for AddressOut
sts MyOutAddressSRAM,ACC ;store NRZI coded AddressOut
ret ;and return
;------------------------------------------------------------------------------------------
NRZIforAddress:
clr ACC ;original answer state - of my nNRZI USB address
ldi temp2,0b00000001 ;mask for xoring
ldi temp3,8 ;bits counter
SetMyNewUSBAddressesLoop:
mov temp0,ACC ;remember final answer
ror temp1 ;to carry transmitting bit LSB (in direction firstly LSB then MSB)
brcs NoXORBits ;if one - don't change state
eor temp0,temp2 ;otherwise state will be changed according to last bit of answer
NoXORBits:
ror temp0 ;last bit of changed answer to carry
rol ACC ;and from carry to final answer to the LSB place (and reverse LSB and MSB order)
dec temp3 ;decrement bits counter
brne SetMyNewUSBAddressesLoop ;if bits counter isn't zero repeat transmitting with next bit
ret
;------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------
PrepareOutContinuousBuffer:
rcall PrepareContinuousBuffer
rcall MakeOutBitStuff
ret
;------------------------------------------------------------------------------------------
PrepareContinuousBuffer:
mov temp0,TransmitPart
cpi temp0,1
brne NextAnswerInBuffer ;if buffer empty
rcall ComposeZeroAnswer ;prepare zero answer
ret
NextAnswerInBuffer:
dec TransmitPart ;decrement general length of answer
ComposeNextAnswerPart:
mov temp1,TotalBytesToSend ;decrement number of bytes to transmit
subi temp1,8 ;is is necessary to send more as 8 byte
ldi temp3,8 ;if yes - send only 8 byte
brcc Nad8Bytov
mov temp3,TotalBytesToSend ;otherwise send only given number of bytes
clr TransmitPart
inc TransmitPart ;and this will be last answer
Nad8Bytov:
mov TotalBytesToSend,temp1 ;decremented number of bytes to TotalBytesToSend
rcall LoadXXXDescriptor
ldi ByteCount,2 ;length of output buffer (only SOP and PID)
add ByteCount,temp3 ;+ number of bytes
rcall AddCRCOut ;addition of CRC to buffer
inc ByteCount ;length of output buffer + CRC16
inc ByteCount
ret ;finish
;------------------------------------------------------------------------------------------
.equ USBversion =0x0101 ;for what version USB is that (1.01)
.equ VendorUSBID =0x03EB ; vendor identifier (Atmel=0x03EB)
.equ DeviceUSBID =0x21FE ;product identifier (USB to RS232 converter ATmega8=0x21FF)
.equ DeviceVersion =0x0002 ;version number of product (version=0.02)
.equ MaxUSBCurrent =46 ;current consumption from USB (46mA)
;------------------------------------------------------------------------------------------
DeviceDescriptor:
.db 0x12,0x01 ;0 byte - size of descriptor in byte
;1 byte - descriptor type: Device descriptor
.dw USBversion ;2,3 byte - version USB LSB (1.00)
.db 0x00,0x00 ;4 byte - device class
;5 byte - subclass
.db 0x00,0x08 ;6 byte - protocol code
;7 byte - FIFO size in bytes
.dw VendorUSBID ;8,9 byte - vendor identifier (Cypress=0x04B4)
.dw DeviceUSBID ;10,11 byte - product identifier (teplomer=0x0002)
.dw DeviceVersion ;12,13 byte - product version number (verzia=0.01)
.db 0x01,0x02 ;14 byte - index of string "vendor"
;15 byte - index of string "product"
.db 0x00,0x01 ;16 byte - index of string "serial number"
;17 byte - number of possible configurations
DeviceDescriptorEnd:
;------------------------------------------------------------------------------------------
ConfigDescriptor:
.db 0x9,0x02 ;length, descriptor type
ConfigDescriptorLength:
.dw 9+9+7 ;entire length of all descriptors
ConfigAnswerMinus1: ;for sending the number - congiguration number (attention - addition of 1 required)
.db 1,1 ;numInterfaces, congiguration number
.db 0,0x80 ;string index, attributes; bus powered
.db MaxUSBCurrent/2,0x09 ;current consumption, interface descriptor length
.db 0x04,0 ;interface descriptor; number of interface
InterfaceAnswer: ;for sending number of alternatively interface
.db 0,1 ;alternatively interface; number of endpoints except EP0
StatusAnswer: ;2 zero answers (saving ROM place)
.db 0,0 ;interface class; interface subclass
.db 0,0 ;protocol code; string index
.db 0x07,0x5 ;length, descriptor type - endpoint
.db 0x81,0 ;endpoint address; transfer type
.dw 0x08 ;max packet size
.db 10,0 ;polling interval [ms]; dummy byte (for filling)
ConfigDescriptorEnd:
;------------------------------------------------------------------------------------------
LangIDStringDescriptor:
.db (LangIDStringDescriptorEnd-LangIDStringDescriptor)*2,3 ;length, type: string descriptor
.dw 0x0409 ;English
LangIDStringDescriptorEnd:
;------------------------------------------------------------------------------------------
VendorStringDescriptor:
.db (VendorStringDescriptorEnd-VendorStringDescriptor)*4-2,3 ;length, type: string descriptor
VendorStringDescriptorEnd:
;------------------------------------------------------------------------------------------
DevNameStringDescriptor:
.db (DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2,3;dlzka, typ: string deskriptor
.db "AVR309:USB to UART protocol converter (simple)"
DevNameStringDescriptorEnd:
;------------------------------------------------------------------------------------------
MaskPortData:
bst ACC,0
bld temp0,LEDlsb0
bst ACC,1
bld temp0,LEDlsb1
bst ACC,2
bld temp0,LEDlsb2
bst ACC,3
bld temp1,LEDmsb3
bst ACC,4
bld temp1,LEDmsb4
bst ACC,5
bld temp1,LEDmsb5
bst ACC,6
bld temp1,LEDmsb6
bst ACC,7
bld temp1,LEDmsb7
ret
;------------------------------------------------------------------------------------------
SetDataPortDirection:
in temp0,LEDdirectionLSB ;read current LSB state to temp0 (next bit directions will be not changed)
in temp1,LEDdirectionMSB ;read current MSB state to temp1 (next bit directions will be not changed)
rcall MaskPortData
out LEDdirectionLSB,temp0 ;and update LSB port direction
out LEDdirectionMSB,temp1 ;and update MSB port direction
ret
;------------------------------------------------------------------------------------------
SetOutDataPort:
in temp0,LEDPortLSB ;read current LSB state to temp0 (next data bits will be not changed)
in temp1,LEDPortMSB ;read current MSB state to temp1 (next data bits will be not changed)
rcall MaskPortData
out LEDPortLSB,temp0 ;and update LSB data port
out LEDPortMSB,temp1 ;and update MSB data port
ret
;------------------------------------------------------------------------------------------
GetInDataPort:
in temp0,LEDPinMSB ;read current MSB state to temp0
in temp1,LEDPinLSB ;read current LSB state to temp1
MoveLEDin:
bst temp1,LEDlsb0 ;and move LSB bits to correct positions (from temp1 to temp0)
bld temp0,0 ;(MSB bits are in correct place)
bst temp1,LEDlsb1
bld
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -