⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usb-prog.asm

📁 单片机的USB ISP软件包,不可多得
💻 ASM
📖 第 1 页 / 共 4 页
字号:
		ld	temp1,Y			;nahraj byte ktory este treba posunut od pozicie bitcount		rol	temp1			;a posun vlavo cez Carry (prenos z vyssieho byte a LSB do Carry)		ser	temp2			;FF do masky - temp2HalfInsertPosuvMask:		lsl	temp2			;nula do dalsieho spodneho bitu masky		dec	bitcount		;az pokial sa nedosiahne hranica posuvania v byte		brne	HalfInsertPosuvMask				and	temp1,temp2		;odmaskuj aby zostali iba vrchne posunute bity v temp1		com	temp2			;invertuj masku		lsr	temp2			;posun masku vpravo - na vlozenie nuloveho bitu		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount do temp0		and	temp0,temp2		;odmaskuj aby zostali iba spodne neposunute bity v temp0		or	temp1,temp0		;a zluc posunutu a neposunutu cast		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount		rol	temp0			;a posun ho vlavo cez Carry (aby sa nastavilo spravne Carry pre dalsie prenosy)		st	Y+,temp1		;a nahraj spat upraveny bytePosunInsertBufferLoop:		cpse	USBBufptrY,ByteCount	;ak nie su vsetky cele byty		rjmp	NoEndPosunInsertBuffer	;tak pokracuj		ret				;inak skonciNoEndPosunInsertBuffer:		ld	temp1,Y			;nahraj byte		rol	temp1			;a posun vlavo cez Carry (prenos z nizsieho byte a LSB do Carry)		st	Y+,temp1		;a nahraj spat		rjmp	PosunInsertBufferLoop	;a pokracuj;------------------------------------------------------------------------------------------PosunDeleteBuffer:	;posuv buffera o jeden bit vlavo od konca az po poziciu: byte-USBBufptrY a bit-bitcount		mov	temp0,bitcount		;vypocet: bitcount= 9-bitcount		ldi	bitcount,9		sub	bitcount,temp0		;do bitcount poloha bitu, ktory este treba posunut		mov	temp0,USBBufptrY	;uschovanie pointera do buffera		inc	temp0			;pozicia celych bytov do temp0		mov	USBBufptrY,ByteCount	;maximalna pozicia do pointraPosunDeleteBufferLoop:		ld	temp1,-Y		;zniz buffer a nahraj byte		ror	temp1			;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)		st	Y,temp1			;a nahraj spat		cpse	USBBufptrY,temp0	;ak nie su vsetky cele byty		rjmp	PosunDeleteBufferLoop	;tak pokracuj		ld	temp1,-Y		;zniz buffer a nahraj byte ktory este treba posunut od pozicie bitcount		ror	temp1			;a posun vpravo cez Carry (prenos z vyssieho byte a LSB do Carry)		ser	temp2			;FF do masky - temp2HalfDeletePosuvMask:		dec	bitcount		;az pokial sa nedosiahne hranica posuvania v byte		breq	DoneMask		lsl	temp2			;nula do dalsieho spodneho bitu masky		rjmp	HalfDeletePosuvMaskDoneMask:		and	temp1,temp2		;odmaskuj aby zostali iba vrchne posunute bity v temp1		com	temp2			;invertuj masku		ld	temp0,Y			;nahraj byte ktory este treba posunut od pozicie bitcount do temp0		and	temp0,temp2		;odmaskuj aby zostali iba spodne neposunute bity v temp0		or	temp1,temp0		;a zluc posunutu a neposunutu cast		st	Y,temp1			;a nahraj spat		ret				;a skonci;------------------------------------------------------------------------------------------MirrorInBufferBytes:		push	USBBufptrY		push	ByteCount		ldi	USBBufptrY,InputBufferBegin		rcall	MirrorBufferBytes		pop	ByteCount		pop	USBBufptrY		ret;------------------------------------------------------------------------------------------MirrorBufferBytes:		add	ByteCount,USBBufptrY	;ByteCount ukazuje na koniec spravyMirrorBufferloop:		ld	temp0,Y			;nahraj prijaty byte z buffera		ldi	temp1,8			;pocitadlo bitovMirrorBufferByteLoop:		ror	temp0			;do carry dalsi najnizsi bit		rol	temp2			;z carry dalsi bit na obratene poradie		dec	temp1			;bol uz cely byte		brne	MirrorBufferByteLoop	;ak nie tak opakuj dalsi najnizsi bit		st	Y+,temp2		;ulozenie spat ako obrateny byte  a zvys pointer do buffera		cp	USBBufptrY,ByteCount	;ak este neboli vsetky		brne	MirrorBufferloop	;tak opakuj		ret				;inak skonci;------------------------------------------------------------------------------------------CheckCRCIn:		push	USBBufptrY		push	ByteCount		ldi	USBBufptrY,InputBufferBegin		rcall	CheckCRC		pop	ByteCount		pop	USBBufptrY		ret;------------------------------------------------------------------------------------------AddCRCOut:		push	USBBufptrY		push	ByteCount		ldi	USBBufptrY,OutputBufferBegin		rcall	CheckCRC		com	temp0			;negacia CRC		com	temp1		st	Y+,temp1		;ulozenie CRC na koniec buffera (najskor MSB)		st	Y,temp0			;ulozenie CRC na koniec buffera (potom LSB)		dec	USBBufptrY		;pointer na poziciu CRC		ldi	ByteCount,2		;otocit 2 byty CRC		rcall	MirrorBufferBytes	;opacne poradie bitov CRC (pri vysielani CRC sa posiela naskor MSB)		pop	ByteCount		pop	USBBufptrY		ret;------------------------------------------------------------------------------------------CheckCRC:	;vstup: USBBufptrY = zaciatok spravy	,ByteCount = dlzka spravy		add	ByteCount,USBBufptrY	;ByteCount ukazuje na koniec spravy		inc	USBBufptrY		;nastav pointer na zaciatok spravy - vynechat SOP		ld	temp0,Y+		;nahraj PID do temp0						;a nastav pointer na zaciatok spravy - vynechat aj PID		cpi	temp0,DATA0PID		;ci je DATA0 pole		breq	ComputeDATACRC		;pocitaj CRC16		cpi	temp0,DATA1PID		;ci je DATA1 pole		brne	CRC16End		;ak nie tak skonci ComputeDATACRC:		ser	temp0			;inicializacia zvysku LSB na 0xff		ser	temp1			;inicializacia zvysku MSB na 0xff		CRC16Loop:		ld	temp2,Y+		;nahraj spravu do temp2 a zvys pointer do buffera		ldi	temp3,8			;pocitadlo bitov v byte - temp3CRC16LoopByte:		bst	temp1,7			;do T uloz MSB zvysku (zvysok je iba 16 bitovy - 8 bit vyssieho byte)		bld	bitcount,0		;do bitcount LSB uloz T - MSB zvysku		eor	bitcount,temp2		;XOR bitu spravy a bitu zvysku - v LSB bitcount		rol	temp0			;posun zvysok dolava - nizsi byte (dva byty - cez carry)		rol	temp1			;posun zvysok dolava - vyssi byte (dva byty - cez carry)		cbr	temp0,1			;znuluj LSB zvysku		lsr	temp2			;posun spravu doprava		ror	bitcount		;vysledok XOR-u bitov z LSB do carry		brcc	CRC16NoXOR		;ak je XOR bitu spravy a MSB zvysku = 0 , tak nerob XOR		ldi	bitcount,CRC16poly>>8	;do bitcount CRC polynom - vrchny byte		eor	temp1,bitcount		;a urob XOR zo zvyskom a CRC polynomom - vrchny byte		ldi	bitcount,CRC16poly	;do bitcount CRC polynom - spodny byte		eor	temp0,bitcount		;a urob XOR zo zvyskom a CRC polynomom - spodny byteCRC16NoXOR:		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 opakujCRC16End:		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 pokracujInsertingZero:		clr	R0			;na vkladanie nul		st	Y+,R0			;nulu uloz do buffera a zvys bufferInsertingZeroEnd:		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 nulyFromROM:		rjmp	LoadDescriptorFromROM		;nahrat descriptor z ROM-kyFromRAMorEEPROM:		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 EEPROMEndFromRAMROM:		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 bufferaMakeOutBitStuff:		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;--------------------------VendorRequest:		clr	ZH				;pre citanie z RAM alebo EEPROM		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, 15		breq    DoSPI4		rjmp	ZeroDATA1Answer			;ak to bolo nieco nezname, tak priprav nulovu odpoved;----------------------------- USER FUNCTIONS --------------------------------------DoLcdData:		sbr     ZH, 0x10			        ;commandDoLcdCommand:		lds	ZL,InputBufferBegin+4		;prvy parameter		rcall   LcdWrite		rjmp    OneZeroAnswerDoEEPROMRead:		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 dataDoEEPROMWrite:		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 prikazDoSetDataPortDirection:		lds	ACC,InputBufferBegin+4		;prvy parameter - smer datovych bitov		rcall	SetDataPortDirection		rjmp	OneZeroAnswer			;potvrd prijem jednou nulouDoGetDataPortDirection:		rcall	GetDataPortDirection		rjmp	DoGetInDoSetOutDataPort:		lds	ACC,InputBufferBegin+4		;prvy parameter - hodnota datovych bitov		rcall	SetOutDataPort		rjmp	OneZeroAnswer			;potvrd prijem jednou nulouDoGetOutDataPort:		rcall	GetOutDataPort		rjmp	DoGetInDoGetInDataPort:		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 dataDoSetRS232Baud:		lds	temp0,InputBufferBegin+4	;prvy parameter - hodnota baudrate na RS232		out	UBRR,temp0			;nastav rychlost UART-u		rjmp	OneZeroAnswer			;potvrd prijem jednou nulouDoGetRS232Baud:		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 UARTWaitForRS232Send:		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 nulouDoRS232Read:		sbis	USR,RXC				;ak je prijimaci register prazdny		rjmp	TwoZeroAnswer			;tak iba potvrd prijem dvoma nulami		in	R0,UDR				;inak nacitaj do R0 prijate data z UART-u		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		sbic	USR,OR				;ak bolo pretecenie prijimacieho buffera		ldi	temp0,3				;posli 3 byty :prvy je prijata hodnota (na ostatnych nezalezi)		rjmp	ComposeEndXXXDescriptor		;tak priprav data	DoSPI4:		lds     ZH,InputBufferBegin+4		rcall   SPI1		sts     SPIBuffer, ZL		lds     ZH,InputBufferBegin+5		rcall   SPI1		sts     SPIBuffer+2, ZL		lds     ZH,InputBufferBegin+6		rcall   SPI1		sts     SPIBuffer+2, ZL		lds     ZH,InputBufferBegin+7		rcall   SPI1		sts     SPIBuffer+3, ZL		ldi     ZL, SPIBuffer		ldi     temp0, 0x81		mov     RAMread, temp0		ldi     temp0, 4		rjmp    ComposeEndXXXDescriptor.equ SLAVE_PIN  = PINB.equ SLAVE_PORT = PORTB.equ SLAVE_SCK_MASK = PB7.equ SLAVE_MISO_MASK = PB6.equ SLAVE_MOSI_MASK = PB5.equ SLAVE_RESET_MASK = PB4.equ SLAVE_SCK  = 7.equ SLAVE_MISO = 6.equ SLAVE_MOSI = 5SPI1:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -