usb90s23x3.lst
来自「单片机AT90S系列 制作简易USB接口(软件模拟,无usb硬件)。asm源代码」· LST 代码 · 共 1,250 行 · 第 1/5 页
LST
1,250 行
AnswerToInRequest:
0000e7 932f push temp2 ;zazalohuj dalsie registre a pokracuj
0000e8 931f push temp3
0000e9 93af push InfraBufptrX
0000ea 926f push ACC
0000eb 3004 cpi ActionFlag,DoReadySendAnswer ;ak nie je pripravena odpoved
0000ec f4b9 brne NoReadySend ;tak posli NAK
0000ed d04b rcall SendPreparedUSBAnswer ;poslanie odpovede naspat
0000ee 20ee and MyUpdatedAddress,MyUpdatedAddress ;ak je MyUpdatedAddress nenulova
0000ef f4b1 brne SetMyNewUSBAddress ;tak treba zmenit USB adresu
0000f0 e092 ldi State,InState
0000f1 e003 ldi ActionFlag,DoPrepareOutContinuousBuffer
0000f2 cfab rjmp EndInt0Handler ;a opakuj - cakaj na dalsiu odozvu z USB
ReceiveSetupData:
0000f3 932f push temp2 ;zazalohuj dalsie registre a pokracuj
0000f4 931f push temp3
0000f5 93af push InfraBufptrX
0000f6 926f push ACC
0000f7 d08f rcall SendACK ;akceptovanie Setup Data paketu
0000f8 d01a rcall FinishReceiving ;ukonci prijem
0000f9 e002 ldi ActionFlag,DoReceiveSetupData
0000fa cfa3 rjmp EndInt0Handler
ReceiveOutData:
0000fb 932f push temp2 ;zazalohuj dalsie registre a pokracuj
0000fc 931f push temp3
0000fd 93af push InfraBufptrX
0000fe 926f push ACC
0000ff 3002 cpi ActionFlag,DoReceiveSetupData ;ak sa prave spracovava prikaz Setup
000100 f019 breq NoReadySend ;tak posli NAK
000101 d085 rcall SendACK ;akceptovanie Out paketu
000102 2700 clr ActionFlag
000103 cf9a rjmp EndInt0Handler
NoReadySend:
000104 d094 rcall SendNAK ;este nie som pripraveny s odpovedou
000105 cf98 rjmp EndInt0Handler ;a opakuj - cakaj na dalsiu odozvu z USB
;------------------------------------------------------------------------------------------
SetMyNewUSBAddress: ;nastavi novu USB adresu v NRZI kodovani
000106 24ff clr MyAddress ;vychodzi stav odpovede - mojej nNRZI USB adresy
000107 e021 ldi temp2,0b00000001 ;maska na xorovanie
000108 e018 ldi temp3,8 ;pocitadlo bitov
SetMyNewUSBAddressLoop:
000109 2d4f mov temp0,MyAddress ;zapamatat si koncovu odpoved
00010a 94e7 ror MyUpdatedAddress ;do carry vysielany bit LSB (v smere naskor LSB a potom MSB)
00010b f008 brcs NoXORBit ;ak je jedna - nemen stav
00010c 2742 eor temp0,temp2 ;inak sa bude stav menit podla posledneho bitu odpovede
NoXORBit:
00010d 9547 ror temp0 ;posledny bit zmenenej odpovede do carry
00010e 1cff rol MyAddress ;a z carry do koncovej odpovede na miesto LSB (a sucasne prehodenie LSB a MSB poradia)
00010f 951a dec temp3 ;zmensi pocitadlo bitov
000110 f7c1 brne SetMyNewUSBAddressLoop ;ak pocitadlo bitov nie je nulove opakuj vysielanie s dalsim bitom
000111 24ee clr MyUpdatedAddress ;znulovanie adresy ako priznak jej buduceho nemenenia
000112 cf8b rjmp EndInt0Handler
;------------------------------------------------------------------------------------------
FinishReceiving: ;korekcne akcie na ukoncenie prijmu
000113 3057 cpi bitcount,7 ;prenes do buffera aj posledny necely byte
000114 f029 breq NoRemainingBits ;ak boli vsetky byty prenesene, tak neprenasaj nic
000115 9553 inc bitcount
ShiftRemainingBits:
000116 1f88 rol shiftbuf ;posun ostavajuce necele bity na spravnu poziciu
000117 955a dec bitcount
000118 f7e9 brne ShiftRemainingBits
000119 9389 st Y+,shiftbuf ;a skopiruj shift register bo buffera - necely byte
NoRemainingBits:
00011a 2f6c mov ByteCount,USBBufptrY
00011b 566d subi ByteCount,InputShiftBufferBegin-1 ;v ByteCount je pocet prijatych byte (vratane necelych byte)
00011c 2ec6 mov InputBufferLength,ByteCount ;a uchovat pre pouzitie v hlavnom programe
00011d e6ce ldi USBBufptrY,InputShiftBufferBegin ;pointer na zaciatok prijimacieho shift buffera
00011e e6a1 ldi InfraBufptrX,InputBufferBegin+1 ;data buffer (vynechat SOP)
MoveDataBuffer:
00011f 9149 ld temp0,Y+
000120 934d st X+,temp0
000121 956a dec ByteCount
000122 f7e1 brne MoveDataBuffer
000123 e564 ldi ByteCount,nNRZISOPbyte
000124 9360 0060 sts InputBufferBegin,ByteCount ;ako keby sa prijal SOP - nekopiruje sa zo shift buffera
000126 9508 ret
;------------------------------------------------------------------------------------------
;********************************************************************
;* Other procedures
;********************************************************************
;------------------------------------------------------------------------------------------
USBReset: ;inicializacia USB stavoveho stroja
000127 ea4a ldi temp0,nNRZIADDR0 ;inicializacia USB adresy
000128 2ef4 mov MyAddress,temp0
000129 2799 clr State ;inicializacia stavoveho stroja
00012a 2499 clr BitStuffInOut
00012b 2488 clr OutBitStuffNumber
00012c 2700 clr ActionFlag
00012d 2433 clr RAMread ;bude sa vycitavat z ROM-ky
00012e 2411 clr ConfigByte ;nenakonfiguravany stav
00012f 9508 ret
;------------------------------------------------------------------------------------------
InitCounter: ;inicializacia countera na prijem zmeny z TSOP
000130 e046 ldi temp0,6 ;na zostupnu hranu casovaca - externy pin
000131 bf43 out TCCR0,temp0
000132 ef4f ldi temp0,0xFF ;napln citac naplno - aby hned na nasledujucu hranu pretiekol
000133 bf42 out TCNT0,temp0
000134 e042 ldi temp0,1<<TOV0 ;znuluj pripadny cakajuci flag pretecenia citaca
000135 bf48 out TIFR,temp0
000136 e042 ldi temp0,1<<TOIE0 ;povolit interrupt od casovaca
;cli ;zakaz interrupt kvoli zacykleniu
000137 bf49 out TIMSK,temp0
000138 9508 ret
;------------------------------------------------------------------------------------------
SendPreparedUSBAnswer: ;poslanie kodovanim NRZI OUT buffer s dlzkou OutputBufferLength do USB
000139 2d6d mov ByteCount,OutputBufferLength ;dlzka odpovede
SendUSBAnswer: ;poslanie kodovanim NRZI OUT buffer do USB
00013a eccf ldi USBBufptrY,OutputBufferBegin ;pointer na zaciatok vysielacieho buffera
SendUSBBuffer: ;poslanie kodovanim NRZI dany buffer do USB
00013b e030 ldi temp1,0 ;zvysovanie pointra (pomocna premenna)
00013c 2f16 mov temp3,ByteCount ;pocitadlo bytov: temp3 = ByteCount
00013d e023 ldi temp2,0b00000011 ;maska na xorovanie
00013e 9179 ld inputbuf,Y+ ;nacitanie prveho bytu do inputbuf a zvys pointer do buffera
;USB ako vystup:
00013f 98c1 cbi outputport,DATAplus ;zhodenie DATAplus : kludovy stav portu USB
000140 9ac0 sbi outputport,DATAminus ;nahodenie DATAminus : kludovy stav portu USB
000141 9ab9 sbi USBdirection,DATAplus ;DATAplus ako vystupny
000142 9ab8 sbi USBdirection,DATAminus ;DATAminus ako vystupny
000143 b348 in temp0,outputport ;kludovy stav portu USB do temp0
SendUSBAnswerLoop:
000144 e057 ldi bitcount,7 ;pocitadlo bitov
SendUSBAnswerByteLoop:
000145 0000 nop ;oneskorenie kvoli casovaniu
000146 9577 ror inputbuf ;do carry vysielany bit (v smere naskor LSB a potom MSB)
000147 f008 brcs NoXORSend ;ak je jedna - nemen stav na USB
000148 2742 eor temp0,temp2 ;inak sa bude stav menit
NoXORSend:
000149 bb48 out outputport,temp0 ;vysli von na USB
00014a 955a dec bitcount ;zmensi pocitadlo bitov - podla carry flagu
00014b f7c9 brne SendUSBAnswerByteLoop ;ak pocitadlo bitov nie je nulove - opakuj vysielanie s dalsim bitom
00014c ff70 sbrs inputbuf,0 ;ak je vysielany bit jedna - nemen stav na USB
00014d 2742 eor temp0,temp2 ;inak sa bude stav menit
NoXORSendLSB:
00014e 951a dec temp3 ;zniz pocitadlo bytov
00014f 9179 ld inputbuf,Y+ ;nacitanie dalsieho bytu a zvys pointer do buffera
000150 bb48 out outputport,temp0 ;vysli von na USB
000151 f791 brne SendUSBAnswerLoop ;opakuj pre cely buffer (pokial temp3=0)
000152 2d58 mov bitcount,OutBitStuffNumber ;pocitadlo bitov pre bitstuff
000153 3050 cpi bitcount,0 ;ak nie je potrebny bitstuff
000154 f041 breq ZeroBitStuf
SendUSBAnswerBitstuffLoop:
000155 9577 ror inputbuf ;do carry vysielany bit (v smere naskor LSB a potom MSB)
000156 f008 brcs NoXORBitstuffSend ;ak je jedna - nemen stav na USB
000157 2742 eor temp0,temp2 ;inak sa bude stav menit
NoXORBitstuffSend:
000158 bb48 out outputport,temp0 ;vysli von na USB
000159 0000 nop ;oneskorenie kvoli casovaniu
00015a 955a dec bitcount ;zmensi pocitadlo bitov - podla carry flagu
00015b f7c9 brne SendUSBAnswerBitstuffLoop ;ak pocitadlo bitov nie je nulove - opakuj vysielanie s dalsim bitom
00015c 8178 ld inputbuf,Y ;oneskorenie 2 cykly
ZeroBitStuf:
00015d 0000 nop ;oneskorenie 1 cyklus
00015e 7f4c cbr temp0,3
00015f bb48 out outputport,temp0 ;vysli EOP na USB
000160 e055 ldi bitcount,5 ;pocitadlo oneskorenia: EOP ma trvat 2 bity (16 cyklov pri 12MHz)
SendUSBWaitEOP:
000161 955a dec bitcount
000162 f7f1 brne SendUSBWaitEOP
000163 9ac0 sbi outputport,DATAminus ;nahodenie DATAminus : kludovy stav na port USB
000164 9ac0 sbi outputport,DATAminus ;oneskorenie 2 cykly: Idle ma trvat 1 bit (8 cyklov pri 12MHz)
000165 98b9 cbi USBdirection,DATAplus ;DATAplus ako vstupny
000166 98b8 cbi USBdirection,DATAminus ;DATAminus ako vstupny
000167 98c0 cbi outputport,DATAminus ;zhodenie DATAminus : treti stav na port USB
000168 9508 ret
;------------------------------------------------------------------------------------------
ToggleDATAPID:
000169 9140 00d0 lds temp0,OutputBufferBegin+1 ;nahraj posledne PID
00016b 344b cpi temp0,DATA1PID ;ak bolo posledne DATA1PID byte
00016c ec43 ldi temp0,DATA0PID
00016d f009 breq SendData0PID ;tak posli nulovu odpoved s DATA0PID
00016e e44b ldi temp0,DATA1PID ;inak posli nulovu odpoved s DATA1PID
SendData0PID:
00016f 9340 00d0 sts OutputBufferBegin+1,temp0 ;DATA0PID byte
000171 9508 ret
;------------------------------------------------------------------------------------------
ComposeZeroDATA1PIDAnswer:
000172 ec43 ldi temp0,DATA0PID ;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora
000173 9340 00d0 sts OutputBufferBegin+1,temp0 ;nahraj do vyst buffera
ComposeZeroAnswer:
000175 e840 ldi temp0,SOPbyte
000176 9340 00cf sts OutputBufferBegin+0,temp0 ;SOP byte
000178 dff0 rcall ToggleDATAPID ;zmen DATAPID
000179 e040 ldi temp0,0x00
00017a 9340 00d1 sts OutputBufferBegin+2,temp0 ;CRC byte
00017c 9340 00d2 sts OutputBufferBegin+3,temp0 ;CRC byte
00017e e064 ldi ByteCount,2+2 ;dlzka vystupneho buffera (SOP a PID + CRC16)
00017f 9508 ret
;------------------------------------------------------------------------------------------
InitACKBufffer:
000180 e840 ldi temp0,SOPbyte
000181 9340 00cc sts ACKBufferBegin+0,temp0 ;SOP byte
000183 ed42 ldi temp0,ACKPID
000184 9340 00cd sts ACKBufferBegin+1,temp0 ;ACKPID byte
000186 9508 ret
;------------------------------------------------------------------------------------------
SendACK:
000187 93cf push USBBufptrY
000188 935f push bitcount
000189 928f push OutBitStuffNumber
00018a eccc ldi USBBufptrY,ACKBufferBegin ;pointer na zaciatok ACK buffera
00018b e062 ldi ByteCount,2 ;pocet vyslanych bytov (iba SOP a ACKPID)
00018c 2488 clr OutBitStuffNumber
00018d dfad rcall SendUSBBuffer
00018e 908f pop OutBitStuffNumber
00018f 915f pop bitcount
000190 91cf pop USBBufptrY
000191 9508 ret
;------------------------------------------------------------------------------------------
InitNAKBufffer:
000192 e840 ldi temp0,SOPbyte
000193 9340 00c9 sts NAKBufferBegin+0,temp0 ;SOP byte
000195 e54a ldi temp0,NAKPID
000196 9340 00ca sts NAKBufferBegin+1,temp0 ;NAKPID byte
000198 9508 ret
;------------------------------------------------------------------------------------------
SendNAK:
000199 928f push OutBitStuffNumber
00019a ecc9 ldi USBBufptrY,NAKBufferBegin ;pointer na zaciatok ACK buffera
00019b e062 ldi ByteCount,2 ;pocet vyslanych bytov (iba SOP a NAKPID)
00019c 2488 clr OutBitStuffNumber
00019d df9d rcall SendUSBBuffer
00019e 908f pop OutBitStuffNumber
00019f 9508 ret
;------------------------------------------------------------------------------------------
ComposeSTALL:
0001a0 e840 ldi temp0,SOPbyte
0001a1 9340 00cf sts OutputBufferBegin+0,temp0 ;SOP byte
0001a3 e14e ldi temp0,STALLPID
0001a4 9340 00d0 sts OutputBufferBegin+1,temp0 ;STALLPID byte
0001a6 e062 ldi ByteCount,2 ;dlzka vystupneho buffera (SOP a PID)
0001a7 9508 ret
;------------------------------------------------------------------------------------------
DecodeNRZI: ;enkodovanie buffera z NRZI kodu do binarneho
0001a8 93cf push USBBufptrY ;zalohuj pointer do buffera
0001a9 936f push ByteCount ;zalohuj dlzku buffera
0001aa 0f6c add ByteCount,USBBufptrY ;koniec buffera do ByteCount
0001ab ef4f ser temp0 ;na zabezpecenie jednotkoveho carry (v nasledujucej rotacii)
NRZIloop:
0001ac 9547 ror temp0 ;naplnenie carry z predchadzajuceho byte
0001ad 8148 ld temp0,Y ;nahraj prijaty byte z buffera
0001ae 2f24 mov temp2,temp0 ;posunuty register o jeden bit vpravo a XOR na funkciu NRZI dekodovania
0001af 9527 ror temp2 ;carry do najvyssieho bitu a sucasne posuv
0001b0 2724 eor temp2,temp0 ;samotne dekodovanie NRZI
0001b1 9520 com temp2 ;negovanie
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?