📄 usb90s23x3.asm
字号:
rjmp ComposeEndXXXDescriptor ;tak priprav data
;----------------------------- END USER FUNCTIONS ----------------------------------
OneZeroAnswer: ;posle jednu nulu
ldi temp0,1 ;pocet mojich bytovych odpovedi do temp0
rjmp ComposeGET_STATUS2
StandardRequest:
cpi temp1,GET_STATUS ;
breq ComposeGET_STATUS ;
cpi temp1,CLEAR_FEATURE ;
breq ComposeCLEAR_FEATURE ;
cpi temp1,SET_FEATURE ;
breq ComposeSET_FEATURE ;
cpi temp1,SET_ADDRESS ;ak sa ma nastavit adresa
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 MyUpdatedAddress,InputBufferBegin+4 ;nova adresa do MyUpdatedAddress
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
;------------------------------------------------------------------------------------------
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 =0x0100 ;pre aku verziu USB je to (1.00)
.EQU VendorUSBID =0x03EB ;identifikator dodavatela (Atmel0x03EB)
.EQU DeviceUSBID =0x0002 ;identifikator vyrobku (USB dialkove ovladanie=0x0002)
.EQU DeviceVersion =0x0001 ;cislo verzie vyrobku (verzia=0.01)
.EQU MaxUSBCurrent =40 ;prudovy odber z USB (40mA)
;------------------------------------------------------------------------------------------
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, Copyright(c) 2003"
CopyRightEnd:
VendorStringDescriptorEnd:
;------------------------------------------------------------------------------------------
DevNameStringDescriptor:
.db (DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2,3;dlzka, typ: string deskriptor
.db "IgorPlug-USB (AVR)"
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
;------------------------------------------------------------------------------------------
GetInDataPort:
in temp0,LEDPinMSB ;nacitaj aktualny stav MSB do temp0
in temp1,LEDPinLSB ;nacitaj aktualny stav LSB do temp1
MoveLEDin:
bst temp1,LEDlsb0 ;a daj bity LSB na spravne pozicie (z temp1 do temp0)
bld temp0,0 ;(bity MSB su na spravnom mieste)
bst temp1,LEDlsb1
bld temp0,1
bst temp1,LEDlsb2
bld temp0,2
mov R0,temp0 ;a vysledok uloz do R0
ret
;------------------------------------------------------------------------------------------
GetOutDataPort:
in temp0,LEDPortMSB ;nacitaj aktualny stav MSB do temp0
in temp1,LEDPortLSB ;nacitaj aktualny stav LSB do temp1
rjmp MoveLEDin
;------------------------------------------------------------------------------------------
GetDataPortDirection:
in temp0,LEDdirectionMSB ;nacitaj aktualny stav MSB do temp0
in temp1,LEDdirectionLSB ;nacitaj aktualny stav LSB do temp1
rjmp MoveLEDin
;------------------------------------------------------------------------------------------
EEPROMWrite:
out EEAR,ZL ;nastav adresu EEPROM
out EEDR,R0 ;nastav data do EEPROM
cli ;zakaz prerusenie
sbi EECR,EEMWE ;nastav master write enable
sei ;povol p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -