📄 usb90s2313.asm
字号:
dec temp3 ;boli uz vsetky bity v byte
brne CRC16LoopByte ;ak nie, tak chod na dalsi bit
cp USBBufptrY,ByteCount ;bol uz koniec spravy
brne CRC16Loop ;ak nie tak opakuj
CRC16End:
ret ;inak skonci (v temp0 a temp1 je vysledok)
;------------------------------------------------------------------------------------------
LoadDescriptorFromROM:
lpm ;nahraj z pozicie ROM pointra do R0
st Y+,R0 ;R0 uloz do buffera a zvys buffer
adiw ZH:ZL,1 ;zvys ukazovatel do ROM
dec ByteCount ;pokial nie su vsetky byty
brne LoadDescriptorFromROM ;tak nahravaj dalej
rjmp EndFromRAMROM ;inak skonci
;------------------------------------------------------------------------------------------
LoadDescriptorFromROMZeroInsert:
lpm ;nahraj z pozicie ROM pointra do R0
st Y+,R0 ;R0 uloz do buffera a zvys buffer
bst RAMread,3 ;ak je 3 bit jednotkovy - nebude sa vkladat nula
brtc InsertingZero ;inak sa bude vkladat nula
adiw ZH:ZL,1 ;zvys ukazovatel do ROM
lpm ;nahraj z pozicie ROM pointra do R0
st Y+,R0 ;R0 uloz do buffera a zvys buffer
clt ;a znuluj
bld RAMread,3 ;treti bit v RAMread - aby sa v dalsom vkladali nuly
rjmp InsertingZeroEnd ;a pokracuj
InsertingZero:
clr R0 ;na vkladanie nul
st Y+,R0 ;nulu uloz do buffera a zvys buffer
InsertingZeroEnd:
adiw ZH:ZL,1 ;zvys ukazovatel do ROM
subi ByteCount,2 ;pokial nie su vsetky byty
brne LoadDescriptorFromROMZeroInsert ;tak nahravaj dalej
rjmp EndFromRAMROM ;inak skonci
;------------------------------------------------------------------------------------------
LoadDescriptorFromSRAM:
ld R0,Z ;nahraj z pozicie RAM pointra do R0
st Y+,R0 ;R0 uloz do buffera a zvys buffer
inc ZL ;zvys ukazovatel do RAM
dec ByteCount ;pokial nie su vsetky byty
brne LoadDescriptorFromSRAM ;tak nahravaj dalej
rjmp EndFromRAMROM ;inak skonci
;------------------------------------------------------------------------------------------
LoadDescriptorFromEEPROM:
out EEAR,ZL ;nastav adresu EEPROM
sbi EECR,EERE ;vycitaj EEPROM do registra EEDR
in R0,EEDR ;nahraj z EEDR do R0
st Y+,R0 ;R0 uloz do buffera a zvys buffer
inc ZL ;zvys ukazovatel do RAM
dec ByteCount ;pokial nie su vsetky byty
brne LoadDescriptorFromEEPROM;tak nahravaj dalej
rjmp EndFromRAMROM ;inak skonci
;------------------------------------------------------------------------------------------
LoadXXXDescriptor:
ldi temp0,SOPbyte ;SOP byte
sts OutputBufferBegin,temp0 ;na zaciatok vysielacieho buffera dat SOP
ldi ByteCount,8 ;8 bytov nahrat
ldi USBBufptrY,OutputBufferBegin+2 ;do vysielacieho buffera
and RAMread,RAMread ;ci sa bude citat z RAM alebo ROM-ky alebo EEPROM-ky
brne FromRAMorEEPROM ;0=ROM,1=RAM,2=EEPROM,4=ROM s vkladanim nuly
FromROM:
rjmp LoadDescriptorFromROM ;nahrat descriptor z ROM-ky
FromRAMorEEPROM:
sbrc RAMread,2 ;ak RAMread=4
rjmp LoadDescriptorFromROMZeroInsert ;citaj z ROM s vkladanim nuly
sbrc RAMread,0 ;ak RAMread=1
rjmp LoadDescriptorFromSRAM ;nahraj data zo SRAM-ky
rjmp LoadDescriptorFromEEPROM ;inak citaj z EEPROM
EndFromRAMROM:
sbrc RAMread,7 ;ak je najvyssi bit v premennej RAMread=1
clr RAMread ;znuluj RAMread
rcall ToggleDATAPID ;zmenit DATAPID
ldi USBBufptrY,OutputBufferBegin+1 ;do vysielacieho buffera - pozicia DATA PID
ret
;------------------------------------------------------------------------------------------
PrepareUSBOutAnswer: ;pripravenie odpovede do buffera
rcall PrepareUSBAnswer ;pripravenie odpovede do buffera
MakeOutBitStuff:
inc BitStuffInOut ;vysielaci buffer - vkladanie bitstuff bitov
ldi USBBufptrY,OutputBufferBegin ;do vysielacieho buffera
rcall BitStuff
mov OutputBufferLength,ByteCount ;dlzku odpovede zapamatat pre vysielanie
clr BitStuffInOut ;prijimaci buffer - mazanie bitstuff bitov
ret
;------------------------------------------------------------------------------------------
PrepareUSBAnswer: ;pripravenie odpovede do buffera
clr RAMread ;nulu do RAMread premennej - cita sa z ROM-ky
lds temp0,InputBufferBegin+2 ;bmRequestType do temp0
lds temp1,InputBufferBegin+3 ;bRequest do temp1
cbr temp0,0b10011111 ;ak je 5 a 6 bit nulovy
brne VendorRequest ;tak to nie je Vendor Request
rjmp StandardRequest ;ale je to standardny request
;--------------------------
DoSetInfraBufferEmpty:
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
;--------------------------
DoSetRS232Baud:
lds temp0,InputBufferBegin+4 ;prvy parameter - hodnota baudrate na RS232
out UBRR,temp0 ;nastav rychlost UART-u
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
;--------------------------
DoGetRS232Baud:
in R0,UBRR ;vrat rychlost UART-u v R0
rjmp DoGetIn ;a ukonci
;--------------------------
DoRS232Send:
lds temp0,InputBufferBegin+4 ;prvy parameter - hodnota vysielana na RS232
out UDR,temp0 ;vysli data na UART
WaitForRS232Send:
sbis UCR,TXEN ;ak nie je povoleny UART vysielac
rjmp OneZeroAnswer ;tak skonci - ochrana kvoli zacykleniu v AT90S2323/2343
sbis USR,TXC ;pockat na dovysielanie bytu
rjmp WaitForRS232Send
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
;--------------------------
DoRS232Read:
rjmp TwoZeroAnswer ;iba potvrd prijem dvoma nulami
;--------------------------
VendorRequest:
clr ZH ;pre citanie z RAM alebo EEPROM
cpi temp1,1 ;
breq DoSetInfraBufferEmpty ;restartne infra prijimanie (ak bolo zastavene citanim z RAM-ky)
cpi temp1,2 ;
breq DoGetInfraCode ;vysle prijaty infra kod (ak je v bufferi)
cpi temp1,3 ;
breq DoSetDataPortDirection ;nastavi smer toku datovych bitov
cpi temp1,4 ;
breq DoGetDataPortDirection ;zisti smer toku datovych bitov
cpi temp1,5 ;
breq DoSetOutDataPort ;nastavi datove bity (ak su vstupne, tak ich pull-up)
cpi temp1,6 ;
breq DoGetOutDataPort ;zisti nastavenie datovych out bitov (ak su vstupne, tak ich pull-up)
cpi temp1,7 ;
breq DoGetInDataPort ;vrati hodnotu datoveho vstupneho portu
cpi temp1,8 ;
breq DoEEPROMRead ;vrati obsah EEPROM od urcitej adresy
cpi temp1,9 ;
breq DoEEPROMWrite ;zapise EEPROM na urcitu adresu urcite data
cpi temp1,10 ;
breq DoRS232Send ;vysle byte na seriovy linku
cpi temp1,11 ;
breq DoRS232Read ;vrati prijaty byte zo seriovej linky (ak sa nejaky prijal)
cpi temp1,12 ;
breq DoSetRS232Baud ;nastavi prenosovu rychlost seriovej linky
cpi temp1,13 ;
breq DoGetRS232Baud ;vrati prenosovu rychlost seriovej linky
cpi temp1,14 ;
breq DoGetRS232Buffer ;vrati RS232 buffer
cpi temp1,USER_FNC_NUMBER+0 ;
breq DoUserFunction0 ;vykona uzivatelsku rutinu0
cpi temp1,USER_FNC_NUMBER+1 ;
breq DoUserFunction1 ;vykona uzivatelsku rutinu1
cpi temp1,USER_FNC_NUMBER+2 ;
breq DoUserFunction2 ;vykona uzivatelsku rutinu2
rjmp ZeroDATA1Answer ;ak to bolo nieco nezname, tak priprav nulovu odpoved
;----------------------------- USER FUNCTIONS --------------------------------------
;------------------------------TEMPLATE OF YOUR FUNCTION----------------------------
;------------------ BEGIN: This is template how to write own function --------------
;free of use are registers:
;temp0,temp1,temp2,temp3,ACC,ZH,ZL
;registers are destroyed after execution (use push/pop to save content)
;at the end of routine you must correctly set registers:
;RAMread - 0=reading from ROM, 1=reading from RAM, 2=reading from EEPROM
;temp0 - number of transmitted data bytes
;ZH,ZL - pointer to buffer of transmitted data (pointer to ROM/RAM/EEPROM)
;to transmit data (preparing data to buffer) :
;to transmit data you must jump to "ComposeEndXXXDescriptor"
;to transmit one zero byte you can jump to "OneZeroAnswer" (commonly used as confirmation of correct processing)
;to transmit two zero byte you can jump to "TwoZeroAnswer" (commonly used as confirmation of error in processing)
DoUserFunctionX:
DoUserFunction0: ;send byte(s) of RAM starting at position given by first parameter in function
lds temp0,InputBufferBegin+4 ;prvy parameter Lo do temp0
;lds temp1,InputBufferBegin+5 ;prvy parameter Hi do temp1
;lds temp2,InputBufferBegin+6 ;druhy parameter Lo do temp2
;lds temp3,InputBufferBegin+7 ;druhy parameter Hi do temp3
;lds ACC,InputBufferBegin+8 ;pocet pozadovanych bytov do ACC
;Tu si pridajte vlastny kod:
;-------------------------------------------------------------------
nop ;priklad na kod - nic nerobi
nop
nop
nop
nop
;-------------------------------------------------------------------
mov ZL,temp0 ;bude sa posielat hodnota RAM adresy ulozena v temp0 (prvy parameter funkcie)
inc RAMread ;RAMread=1 - cita sa z RAM-ky
ldi temp0,RAMEND+1 ;posli max pocet byte - celu RAM
rjmp ComposeEndXXXDescriptor ;a priprav data
DoUserFunction1:
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
DoUserFunction2:
rjmp TwoZeroAnswer ;potvrd prijem dvoma nulami
;------------------ END: This is template how to write own function ----------------
;----------------------------- USER FUNCTIONS --------------------------------------
DoGetInfraCode:
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
DoEEPROMRead:
lds ZL,InputBufferBegin+4 ;prvy parameter - offset v EEPROM-ke
ldi temp0,2
mov RAMread,temp0 ;RAMread=2 - cita sa z EEPROM-ky
ldi temp0,E2END+1 ;pocet mojich bytovych odpovedi do temp0 - cela dlzka EEPROM
rjmp ComposeEndXXXDescriptor ;inak priprav data
DoEEPROMWrite:
lds ZL,InputBufferBegin+4 ;prvy parameter - offset v EEPROM-ke (adresa)
lds R0,InputBufferBegin+6 ;druhy parameter - data, ktore sa maju zapisat do EEPROM-ky (data)
rjmp EEPROMWrite ;zapis do EEPROM a aj ukonci prikaz
DoSetDataPortDirection:
lds ACC,InputBufferBegin+4 ;prvy parameter - smer datovych bitov
rcall SetDataPortDirection
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
DoGetDataPortDirection:
rcall GetDataPortDirection
rjmp DoGetIn
DoSetOutDataPort:
lds ACC,InputBufferBegin+4 ;prvy parameter - hodnota datovych bitov
rcall SetOutDataPort
rjmp OneZeroAnswer ;potvrd prijem jednou nulou
DoGetOutDataPort:
rcall GetOutDataPort
rjmp DoGetIn
DoGetInDataPort:
rcall GetInDataPort
DoGetIn:
ldi ZL,0 ;posiela sa hodnota v R0
ldi temp0,0x81 ;RAMread=1 - cita sa z RAM-ky
mov RAMread,temp0 ;(najvyssi bit na 1 - aby sa hned premenna RAMread znulovala)
ldi temp0,1 ;posli iba jeden byte
rjmp ComposeEndXXXDescriptor ;a priprav data
DoGetRS232Buffer:
mov temp0,RS232BufferFull ;zisti dlzku buffera RS232 kodu
cpi temp0,0 ;ak je RS232 Buffer prazdny
breq OneZeroAnswer ;tak nic neposli a potvrd prijem jednou nulou
lds ACC,InputBufferBegin+8 ;pocet pozadovanych bytov do ACC
inc temp0 ;pocet moznych dodanych bajtov (plus byte dlzky buffera)
cp ACC,temp0 ;ak sa neziada viac ako mozem dodat
brcc NoShortGetRS232Buffer ;vysli tolko kolko sa ziada
mov temp0,ACC
NoShortGetRS232Buffer:
dec temp0 ;uber byte dlzky
lds temp1,RS232BufferBegin+1 ;zisti ukazovatel citania buffera RS232 kodu : 2.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
add temp1,temp0 ;zisti kde je koniec
cpi temp1,RS232BufferBegin+MAXRS232LENGTH+1 ;ak by mal pretiect
brcs ReadNoOverflow
subi temp1,RS232BufferBegin+MAXRS232LENGTH+1 ;vypocitaj kolko sa neprenesie
sub temp0,temp1 ;a o to skrat dlzku citania
ldi temp1,RS232BufferBegin+4 ;a zacni od nuly
ReadNoOverflow:
lds ZL,RS232BufferBegin+1 ;zisti ukazovatel citania buffera RS232 kodu : 2.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
sts RS232BufferBegin+1,temp1 ;zapis novy ukazovatel citania buffera RS232 kodu : 2.byte hlavicky (dlzka kodu + citanie + zapis + rezerva)
dec ZL ;priestor pre udaj dlky - prenasa sa ako prvy bajt
sub RS232BufferFull,temp0 ;zniz dlzku buffera
st Z,RS232BufferFull ;a uloz skutocnu dlzku do paketu
inc temp0 ;a o tento jeden bajt zvys pocet prenasanych bajtov (dlzka buffera)
inc RAMread ;RAMread=1 - cita sa z RAM-ky
rjmp ComposeEndXXXDescriptor ;a 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -