📄 usb90s2313.asm
字号:
breq ComposeSET_ADDRESS ;nastav adresu
cpi temp1,GET_DESCRIPTOR ;ak sa ziada descriptor
breq ComposeGET_DESCRIPTOR ;vygeneruj ho
cpi temp1,SET_DESCRIPTOR ;
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 ;
;ak sa nenasla znama poziadavka
rjmp ZeroDATA1Answer ;ak to bolo nieco nezname, tak priprav nulovu odpoved
ComposeSET_ADDRESS:
lds temp1,InputBufferBegin+4 ;nova adresa do temp1
rcall SetMyNewUSBAddresses ;ENG;and compute NRZI and bitstuffing coded adresses
ldi State,AddressChangeState ;nastav stav pre zmenu adresy
rjmp ZeroDATA1Answer ;posli nulovu odpoved
ComposeSET_CONFIGURATION:
lds ConfigByte,InputBufferBegin+4 ;cislo konfiguracie do premennej ConfigByte
ComposeCLEAR_FEATURE:
ComposeSET_FEATURE:
ComposeSET_INTERFACE:
ZeroStringAnswer:
rjmp ZeroDATA1Answer ;posli nulovu odpoved
ComposeGET_STATUS:
TwoZeroAnswer:
ldi temp0,2 ;pocet mojich bytovych odpovedi do temp0
ComposeGET_STATUS2:
ldi ZH, high(StatusAnswer<<1) ;ROMpointer na odpoved
ldi ZL, low(StatusAnswer<<1)
rjmp ComposeEndXXXDescriptor ;a dokonci
ComposeGET_CONFIGURATION:
and ConfigByte,ConfigByte ;ak som nenakonfigurovany
breq OneZeroAnswer ;tak posli jednu nulu - inak posli moju konfiguraciu
ldi temp0,1 ;pocet mojich bytovych odpovedi do temp0
ldi ZH, high(ConfigAnswerMinus1<<1) ;ROMpointer na odpoved
ldi ZL, low(ConfigAnswerMinus1<<1)+1
rjmp ComposeEndXXXDescriptor ;a dokonci
ComposeGET_INTERFACE:
ldi ZH, high(InterfaceAnswer<<1) ;ROMpointer na odpoved
ldi ZL, low(InterfaceAnswer<<1)
ldi temp0,1 ;pocet mojich bytovych odpovedi do temp0
rjmp ComposeEndXXXDescriptor ;a dokonci
ComposeSYNCH_FRAME:
ComposeSET_DESCRIPTOR:
rcall ComposeSTALL
ret
ComposeGET_DESCRIPTOR:
lds temp1,InputBufferBegin+5 ;DescriptorType do 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 na descriptor
ldi ZL, low(DeviceDescriptor<<1)
ldi temp0,0x12 ;pocet mojich bytovych odpovedi do temp0
rjmp ComposeEndXXXDescriptor ;a dokonci
ComposeConfigDescriptor:
ldi ZH, high(ConfigDescriptor<<1) ;ROMpointer na descriptor
ldi ZL, low(ConfigDescriptor<<1)
ldi temp0,9+9+7 ;pocet mojich bytovych odpovedi do temp0
ComposeEndXXXDescriptor:
lds TotalBytesToSend,InputBufferBegin+8 ;pocet pozadovanych bytov do TotalBytesToSend
cp TotalBytesToSend,temp0 ;ak sa neziada viac ako mozem dodat
brcs HostConfigLength ;vysli tolko kolko sa ziada
mov TotalBytesToSend,temp0 ;inak posli pocet mojich odpovedi
HostConfigLength:
mov temp0,TotalBytesToSend ;
clr TransmitPart ;nuluj pocet 8 bytovych odpovedi
andi temp0,0b00000111 ;ak je dlzka delitelna 8-mimi
breq Length8Multiply ;tak nezapocitaj jednu necelu odpoved (pod 8 bytov)
inc TransmitPart ;inak ju zapocitaj
Length8Multiply:
mov temp0,TotalBytesToSend ;
lsr temp0 ;dlzka 8 bytovych odpovedi sa dosiahne
lsr temp0 ;delenie celociselne 8-mimi
lsr temp0
add TransmitPart,temp0 ;a pripocitanim k poslednej necelej 8-mici do premennej TransmitPart
ldi temp0,DATA0PID ;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora
sts OutputBufferBegin+1,temp0 ;nahraj do vyst buffera
rjmp ComposeNextAnswerPart
ComposeStringDescriptor:
ldi temp1,4+8 ;ak RAMread=4(vkladaj nuly z ROM-koveho citania) + 8(za prvy byte nevkldadaj nulu)
mov RAMread,temp1
lds temp1,InputBufferBegin+4 ;DescriptorIndex do temp1
cpi temp1,0 ;LANGID String
breq ComposeLangIDString ;
cpi temp1,2 ;DevNameString
breq ComposeDevNameString ;
brcc ZeroStringAnswer ;ak je DescriptorIndex vyssi nez 2 - posli nulovu odpoved
;inak to bude VendorString
ComposeVendorString:
ldi ZH, high(VendorStringDescriptor<<1) ;ROMpointer na descriptor
ldi ZL, low(VendorStringDescriptor<<1)
ldi temp0,(VendorStringDescriptorEnd-VendorStringDescriptor)*4-2 ;pocet mojich bytovych odpovedi do temp0
rjmp ComposeEndXXXDescriptor ;a dokonci
ComposeDevNameString:
ldi ZH, high(DevNameStringDescriptor<<1) ;ROMpointer na descriptor
ldi ZL, low(DevNameStringDescriptor<<1)
ldi temp0,(DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2 ;pocet mojich bytovych odpovedi do temp0
rjmp ComposeEndXXXDescriptor ;a dokonci
ComposeLangIDString:
clr RAMread
ldi ZH, high(LangIDStringDescriptor<<1) ;ROMpointer na descriptor
ldi ZL, low(LangIDStringDescriptor<<1)
ldi temp0,(LangIDStringDescriptorEnd-LangIDStringDescriptor)*2;pocet mojich bytovych odpovedi do temp0
rjmp ComposeEndXXXDescriptor ;a dokonci
;------------------------------------------------------------------------------------------
ZeroDATA1Answer:
rcall ComposeZeroDATA1PIDAnswer
ret
;------------------------------------------------------------------------------------------
SetMyNewUSBAddresses: ;nastavi nove USB adresy v NRZI kodovani ;ENG;set new USB addresses in NRZI coded
mov temp2,temp1 ;address to temp2 and temp1 and temp3
mov temp3,temp1 ;
cpi temp1,0b01111111 ;ENG;if address contains less than 6 ones
brne NewAddressNo6ones ;ENG;then don't add bitstuffing
ldi temp1,0b10111111 ;ENG;else insert one zero - bitstuffing
NewAddressNo6ones:
andi temp3,0b00000111 ;ENG;mask 3 low bits of Address
cpi temp3,0b00000111 ;ENG;and if 3 low bits of Address is no all ones
brne NewAddressNo3ones ;ENG;then no change address
;ENG;else insert zero after 3-rd bit (bitstuffing)
sec ;set carry
rol temp2 ;ENG;rotate left
andi temp2,0b11110111 ;ENG;and inserted zero after 3-rd bit
NewAddressNo3ones:
sts MyOutAddressSRAM,temp2 ;ENG;store new non-coded address Out (temp2)
;ENG;and now perform NRZI coding
rcall NRZIforAddress ;ENG;NRZI for AddressIn (in temp1)
sts MyInAddressSRAM,ACC ;ENG;store NRZI coded AddressIn
lds temp1,MyOutAddressSRAM ;ENG;load non-coded address Out (in temp1)
rcall NRZIforAddress ;ENG;NRZI for AddressOut
sts MyOutAddressSRAM,ACC ;ENG;store NRZI coded AddressOut
ret ;ENG;and return
;------------------------------------------------------------------------------------------
NRZIforAddress:
clr ACC ;vychodzi stav odpovede - mojej nNRZI USB adresy ;ENG;original answer state - of my nNRZI USB address
ldi temp2,0b00000001 ;maska na xorovanie ;ENG;mask for xoring
ldi temp3,8 ;pocitadlo bitov ;ENG;bits counter
SetMyNewUSBAddressesLoop:
mov temp0,ACC ;zapamatat si koncovu odpoved ;ENG;remember final answer
ror temp1 ;do carry vysielany bit LSB (v smere naskor LSB a potom MSB) ;ENG;to carry transmitting bit LSB (in direction firstly LSB then MSB)
brcs NoXORBits ;ak je jedna - nemen stav ;ENG;if one - don't change state
eor temp0,temp2 ;inak sa bude stav menit podla posledneho bitu odpovede ;ENG;otherwise state will be changed according to last bit of answer
NoXORBits:
ror temp0 ;posledny bit zmenenej odpovede do carry ;ENG;last bit of changed answer to carry
rol ACC ;a z carry do koncovej odpovede na miesto LSB (a sucasne prehodenie LSB a MSB poradia) ;ENG;and from carry to final answer to the LSB place (and reverse LSB and MSB order)
dec temp3 ;zmensi pocitadlo bitov ;ENG;decrement bits counter
brne SetMyNewUSBAddressesLoop ;ak pocitadlo bitov nie je nulove opakuj vysielanie s dalsim bitom ;ENG;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 ;ak uz je buffer prazdny
rcall ComposeZeroAnswer ;priprav nulovu odpoved
ret
NextAnswerInBuffer:
dec TransmitPart ;znizit celkovu dlzku odpovede
ComposeNextAnswerPart:
mov temp1,TotalBytesToSend ;zniz pocet bytov na vyslanie
subi temp1,8 ;ci je este treba poslat viac ako 8 bytov
ldi temp3,8 ;ak ano - posli iba 8 bytov
brcc Nad8Bytov
mov temp3,TotalBytesToSend ;inak posli iba dany pocet bytov
clr TransmitPart
inc TransmitPart ;a bude to posledna odpoved
Nad8Bytov:
mov TotalBytesToSend,temp1 ;znizeny pocet bytov do TotalBytesToSend
rcall LoadXXXDescriptor
ldi ByteCount,2 ;dlzka vystupneho buffera (iba SOP a PID)
add ByteCount,temp3 ;+ pocet bytov
rcall AddCRCOut ;pridanie CRC do buffera
inc ByteCount ;dlzka vystupneho buffera + CRC16
inc ByteCount
ret ;skonci
;------------------------------------------------------------------------------------------
.equ USBversion =0x0101 ;pre aku verziu USB je to (1.01)
.equ VendorUSBID =0x03EB ;identifikator dodavatela (Atmel=0x03EB)
.equ DeviceUSBID =0x21FE ;identifikator vyrobku (USB to RS232 converter AT90S2313=0x21FE)
.equ DeviceVersion =0x0002 ;cislo verzie vyrobku (verzia=0.02)
.equ MaxUSBCurrent =46 ;prudovy odber z USB (46mA)
;------------------------------------------------------------------------------------------
DeviceDescriptor:
.db 0x12,0x01 ;0 byte - velkost deskriptora v bytoch
;1 byte - typ deskriptora: Deskriptor zariadenia
.dw USBversion ;2,3 byte - verzia USB LSB (1.00)
.db 0x00,0x00 ;4 byte - trieda zariadenia
;5 byte - podtrieda zariadenia
.db 0x00,0x08 ;6 byte - kod protokolu
;7 byte - velkost FIFO v bytoch
.dw VendorUSBID ;8,9 byte - identifikator dodavatela (Cypress=0x04B4)
.dw DeviceUSBID ;10,11 byte - identifikator vyrobku (teplomer=0x0002)
.dw DeviceVersion ;12,13 byte - cislo verzie vyrobku (verzia=0.01)
.db 0x01,0x02 ;14 byte - index stringu "vyrobca"
;15 byte - index stringu "vyrobok"
.db 0x00,0x01 ;16 byte - index stringu "seriove cislo"
;17 byte - pocet moznych konfiguracii
DeviceDescriptorEnd:
;------------------------------------------------------------------------------------------
ConfigDescriptor:
.db 0x9,0x02 ;dlzka,typ deskriptoru
ConfigDescriptorLength:
.dw 9+9+7 ;celkova dlzka vsetkych deskriptorov
ConfigAnswerMinus1: ;pre poslanie cisla congiguration number (pozor je treba este pricitat 1)
.db 1,1 ;numInterfaces,congiguration number
.db 0,0x80 ;popisny index stringu, atributy;bus powered
.db MaxUSBCurrent/2,0x09 ;prudovy odber, interface descriptor length
.db 0x04,0 ;interface descriptor; cislo interface
InterfaceAnswer: ;pre poslanie cisla alternativneho interface
.db 0,1 ;alternativne nastavenie interface; pocet koncovych bodov okrem EP0
StatusAnswer: ;2 nulove odpovede (na usetrenie miestom)
.db 0,0 ;trieda rozhrania; podtrieda rozhrania
.db 0,0 ;kod protokolu; index popisneho stringu
.db 0x07,0x5 ;dlzka,typ deskriptoru - endpoint
.db 0x81,0 ;endpoint address; transfer type
.dw 0x08 ;max packet size
.db 10,0 ;polling interval [ms]; dummy byte (pre vyplnenie)
ConfigDescriptorEnd:
;------------------------------------------------------------------------------------------
LangIDStringDescriptor:
.db (LangIDStringDescriptorEnd-LangIDStringDescriptor)*2,3 ;dlzka, typ: string deskriptor
.dw 0x0409 ;English
LangIDStringDescriptorEnd:
;------------------------------------------------------------------------------------------
VendorStringDescriptor:
.db (VendorStringDescriptorEnd-VendorStringDescriptor)*4-2,3 ;dlzka, typ: string deskriptor
CopyRight:
.db "Ing. Igor Cesko"
CopyRightEnd:
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 ;nacitaj aktualny stav LSB do temp0 (aby sa nezmenili ostatne smery bitov)
in temp1,LEDdirectionMSB ;nacitaj aktualny stav MSB do temp1 (aby sa nezmenili ostatne smery bitov)
rcall MaskPortData
out LEDdirectionLSB,temp0 ;a update smeru LSB datoveho portu
out LEDdirectionMSB,temp1 ;a update smeru MSB datoveho portu
ret
;------------------------------------------------------------------------------------------
SetOutDataPort:
in temp0,LEDPortLSB ;nacitaj aktualny stav LSB do temp0 (aby sa nezmenili ostatne bity)
in temp1,LEDPortMSB ;nacitaj aktualny stav MSB do temp1 (aby sa nezmenili ostatne bity)
rcall MaskPortData
out LEDPortLSB,temp0 ;a update LSB datoveho portu
out LEDPortMSB,temp1 ;a update MSB datoveho portu
ret
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -