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

📄 usb2lpt2.a51

📁 无线网络课件,是一份非常好的讲述无线通信领域的资料.
💻 A51
📖 第 1 页 / 共 2 页
字号:
;FX2-Firmware f黵 USB2LPT2, haftmann#software 08/05
;Bis jetzt wird nur ein dptr benutzt (also kein DPS), nur Registerbank 0
;Zu 黚ersetzen mit ASEM51; EEPROM-Datei erstellen mit
;HEX2BIX -F 0xC2 -I -V 0x16C0 -P 0x06B3
;Pro OUT-Befehl werden zwei Bytes in die OUT-Pipe geschrieben.
;F黵 jeden IN-Befehl wird ein Byte [Adresse] in die OUT-Pipe gesetzt,
; als Folge kommt ein Byte [Daten] in die IN-Pipe. Genaueres siehe "upv"!
;Seriennummern-Position: 1 Byte @ FFFFh (alt), 4 Byte @ FFFCh (Intel, neu)
;06xxxx	EEPROM+XRAM-Routinen
;060622	Gekaufte VID+PID eingetragen
;060629	Einzelpin-Richtungsumschaltung
;060630 Open-Collector-Simulation (Daten- und Steuerpins)
;060706	Richtungsbit-Simulation korrigiert (stets 0 bei Mode 0 und 2)
;060710	EPP: allgemeine Fehlerbeseitigung, getestet
;060711	Schattenregister f黵 Steuerport, Code-Erweiterbarkeit f黵 Anwender
;060809	DirectIo, korrigiertes Open-Collector-Verhalten (Steuerport), EEPROM
;060811	Drei ungenutzte PortD-Leitungen auf drei Massepins geroutet
;070128	Richtungsbits ge鋘dert auf 0=Eingang, 1=Ausgang (wie EZUSB und ATmega)
;070128	Steuerport-Richtungsfestlegung 黚er High-Nibble von GpifIdleCfg
;070209	Achtelung der Helligkeit allzu heller blauer LEDs mit Schaltbit
;Zu tun:

	$nopaging
	$nosymbols
	$nomod51
	$nolist
	$include(ezusbfx2.mcu)
	$include(makros.i51)
	$list
	$genonly		;das "Innere" von Makros
	$condonly		;das "Innere" von IFxx

DateYear	equ	2007	;"Versionskennung"
DateMonth	equ	2
DateDay		equ	9
Interfaces	equ	2	;1 = ohne "USB-Druckerunterst黷zung"
				;(so l鋝st es sich besser debuggen)
MyId		equ	1	;0 = Cypress-ID (Debuggen mit Cypress-Tools)
Always_Renum	equ	0	;1: Firmware-Update im Ger鋞emanager versagt
Gpif		equ	0	;Benutze GPIF - oder Handarbeit f黵s Drucken

;###############
;## Schaltung ##
;###############
;Datenport  (Basisadresse+0) = PortB (mit korrekter Bit-Anordnung, = FIFO-Port)
;Statusport (Basisadresse+1) = PortA (Bits 5-4-3 auf Portbits 5-6-1)
;			   und RDYx  (Bits 7-6 auf Portbits 0-1)
;Rev.3:			     = PortD (Bits 7-3 auf Portbits 7-3), RDYx gleich
;Rev.4:			     zus鋞zlich PortD (Bits 2-0 auf Extra-Bits 2-0)
;Steuerport (Basisadresse+2) = PortA (Bit 2 auf Portbit 2)
;			   und CTLx  (Bits 0-1-3 auf Portbits 0-1-2)
;Rev.3:			     = PortA (Bits 3-0 auf Portbits 3-0), CTLx gleich
;Die Zuweisung auf CTLx und RDYx erfolgte f黵 Implementierbarkeit von
;SPP, ECP und EPP mithilfe von GPIF (also sehr schnell!),
;die 黚rige Zuweisung auf PortA nach g黱stigster Leiterbahnf黨rung.
;Problem: Steuerport ist nicht r點klesbar! Korrektur in Revision 3,
;	  durch Routing der CTLx-Leitungen auf PortD
;Die Symbole PE,ONL,ERR,INI werden nur f黵 Rev.2 verwendet.						JTAG		Rev.3
 BSY	EQU	0	;RDY1	(/7)	(ist mit D6 verbunden)	IOD.7
 ACK	EQU	1	;RDY0	( 6)				IOD.6
 PE	EQU	5	;IOA.5	( 5)	(ist mit D6 verbunden)	IOD.5
 ONL	EQU	6	;IOA.6	( 4)	D/P	TDO		IOD.4
 ERR	EQU	1	;IOA.1	( 3)	Ucc	Ucc		IOD.3
 
 SEL	EQU	2	;CTL2	(/3)				IOA.3
 INI	EQU	2	;IOA.2	( 2)				IOA.2
 AF	EQU	1	;CTL1	(/1)				IOA.1
 STB	EQU	0	;CTL0	(/0)				IOA.0
;			;D4		/PROG (zieht TDO auf Low)
;			;D3		/CTRL (aktiviert 2 Ausgangstreiber)
;			;D2		PROG	TMS
;			;D1		CCLK	TCK
;			;D0		DIN	TDI
 Ledr2	equ	IOA.0	;LOW-aktiv				IOA.4
 Led2r2	equ	IOA.7	;LOW-aktiv				IOA.5
Led	equ	IOA.4
Led2	equ	IOA.5


DefIOA	equ	0FFh	;alles High, auch LEDs
 DefOEAr2 equ	10011101b
;IOA.1 und IOA.3 sind noch frei, evtl. Steuerung der Pull-UpWiderst鋘de
;	in Rev. 3 zur Energieeinsparung bei Idle, IOA.1 f黵 ACK-Interrupt
DefOEA equ	10110100b
;###############
;## Endpoints ##
;###############
;Pipe	Funktion				EZUSB	FX2	?
;0	OUT-Adressen, OUT-Daten, IN-Adressen	EP2Out	EP2(Out)EP1
;1	IN-Daten				EP2In	EP6(In)	EP1
;2(=0)	USB-Druckerunterst黷zung Vorw鋜tskanal	EP4Out	EP4(Out)EP2
;3(=1)	USB-Druckerunterst黷zung R點kkanal	EP4In	EP8(In)	EP6
;4(=0)	JTAG Out				EP6		EP4
;5(=1)	JTAG In					EP6		EP8
;-----------
;## DATEN ##	Der Datenbereich wird beim Firmware-Start mit Nullen gel鰏cht
;-----------
DSEG AT 20h	;bitadressierbar
IntReq:		ds	1	;f黵 USB-Interruptrequests, bitadressierbar
Configuration:	ds	1	;hier: Null (adressiert) oder Eins (konfig.)
AltSetting1:	ds	1	;Null, Eins oder Zwei (nur f黵 2. Interface)
bits:		ds	1	;diverse Bits
HighSpeed	BIT	bits.0	;Kopie von UsbIrq.HsGrant
Led_B		BIT	bits.1	;Solange gelbe LED blinkt
Led2_B		BIT	bits.2	;Solange blaue (High-Speed-)LED blinkt
Rev2		BIT	bits.3	;Zur Verzweigung bei dennoch gleicher Firmware
FeatureChanged	BIT	bits.4	;Feature-Byte in EEPROM brennen (persistent)
Led2State	BIT	bits.5	;Eigentlicher Zustand der blauen LED
Data5V		BIT	bits.6	;wie OCData && !direction
Control5V	BIT	bits.7	;wie (SPP && !TPControl) || OCControl
;===Druckerport===
DCR:		ds	1	;Device Control Register (+2)
ackIntEn	BIT	DCR.4	;1=ein, r點klesbar, aber nicht unterst黷zt
direction	BIT	DCR.5	;0=OUT, 1=IN, klebt auf 0 bei Mode=0 oder =2
ECR:		ds	1	;Extended Control Register (ECP 402)
fifoe		BIT	ECR.0	;1 wenn FIFO leer
fifof		BIT	ECR.1	;1 wenn FIFO voll
ECR_Bits:	ds	1	;Mit immer nur einem Bit gesetzt
EPPTimeOut:	ds	1	;Bit0=0: kein TimeOut aufgetreten
				;Bit2=0: Interrupt aufgetreten (zz. ungenutzt)
				;Alle anderen Bits m黶sen =1 sein!
Feature:	ds	1
OCData		BIT	Feature.0 ;Offene-Senke-Simulation f黵 Daten (+0)
TPControl	BIT	Feature.1 ;Totempfahl auch bei SPP (bei Rev.2 immer 1)
OCControl	BIT	Feature.2 ;Offene-Senke-Simulation f黵 Steuerport (+2)
DarkBlue	BIT	Feature.5 ;dunklere blaue LED
DirectIo	BIT	Feature.6 ;keine Invertierungen, kein Datenrichtungsbit
PullUps		BIT	Feature.7 ;Deaktivierung der externen Pullups ab Rev.3
;===I睠===
I2C_ALen:	ds	1	;entspricht etwa wIndexH beim Vendor-Request A2
 I2C_ALen0	BIT	I2C_ALen.0	; 1 = 1 Byte, oder 2 Bytes vertauscht
 I2C_ALen1	BIT	I2C_ALen.1	; 1 = 2 Bytes (sonst 0 oder 1 Byte)
 I2C_NoStop	BIT	I2C_ALen.2
 I2C_NoStart	BIT	I2C_ALen.3
 I2C_Paging	BIT	I2C_ALen.4	; 1 = Paging aktiv (nicht wIndexH)
 I2C_Verify	BIT	I2C_ALen.5	; zusammen mit Paging immer Verify

DSEG AT 30h	;nicht bitadressierbar
FIFOSIZE	equ	16
;===FIFO===... hat hier eine Tiefe von FIFOSIZE W鰎tern zu je 9 Bit
Fifo:		ds	FIFOSIZE*2	;Wegen ECP brauchen wir 9 bit Breite!
fifor:		ds	1	;Fifo-Lesezeiger
fifow:		ds	1	;Fifo-Schreibzeiger
;===allgemein===
Led_T:		ds	1	;"Nachblinkzeit" der LED in ms
Led_F:		ds	1	;"Blinkfrequenz" in ms (halbe Periode)
Led_C:		ds	1	;Blink-Z鋒ler
Led2_T:		ds	1
Led2_F:		ds	1
Led2_C:		ds	1
FrameCnt:	ds	1	;zum Mitz鋒len "ganzer" USB-Rahmen (HighSpeed)
UniIdxL:	ds	1	;Index in OUT4BUF zum byteweisen Lesen
UniIdxH:	ds	1
ep2ll:		ds	1	;L鋘genz鋒ler f黵 EP2-Verarbeitung
ep2lh:		ds	1
;=== Variablen f黵 I睠/EEPROM ===
I2C_Addr:	ds	1	;I睠-Adresse (EEPROM)
I2C_PMask:	ds	1	;F黵 seiten-weises EEPROM-Schreiben,
	;00 = einzelbyteweise, 07 = 8-Byte-Seite, 1F = 32-Byte-Seite usw.
	;07 (8bit), 1F (16bit) oder (1<<High-Nibble von wIndexH)-1 (Request ED)
;Die PMask wird mit dem LOW-Teil der laufenden Adresse geODERt; bei
;Ergebnis Null wird der I睠-Transfer unterbrochen und das Brennen ausgel鰏t.

IF Gpif
 OutB	equ	GpifSglDatLX
 TRISB MACRO v
	STX	GpifIdleCS,v
 ENDM
ELSE
 OutB	equ	IOB
 TRISB MACRO v
  IFNB <v>
	mov	OEB,#v
  ELSE
  	mov	OEB,a
  ENDIF
 ENDM
ENDIF

;--------------
;## PROGRAMM ##
;--------------
CSEG AT 0
	ljmp	main	;am Reset-Vektor
SAVEORG 6,0
	dwi	%(DateYear-1980)*512+DateMonth*32+DateDay
	
SAVEORG 2Eh
Scratch:ds	1	;f黵 EEPROM-Transfer
usr2f:	RETC	;@002F Ansprung bei Ausgabebyte > 20h, ersetzen mit AJMP
usr31:	RETC	;@0031 unbekannter Request 黚er EP0, ersetzen mit AJMP

SAVEORG RESUME	;RESUME-ISR @33h (erforderlich, sonst geht das Wecken nicht)
	clr	EICON.4
	reti
usr36:	ret	;@0036 Zyklischer Ansprung, ersetzen mit AJMP (oder LJMP)
	

ORG 1000h			;4 Kilobyte f黵 User
;--------------------------------------------------------------------
ResetFifos:
	STX	GpifAbort
	SyncDelay
	STX	FifoReset,80h
	SyncDelay
	STX	,2
	SyncDelay
	STX	,4
	SyncDelay
	STX	,6
	SyncDelay
	STX	,8
	SyncDelay
	STX	,0
	SyncDelay
	STX	OutPktEnd,82h
	SyncDelay
	STX
	SyncDelay
	STX	OutPktEnd,84h
	SyncDelay
	STX
	ret

;EEPROM-Adresse (gerade; Schreibadresse) am I睠-Bus
EADDR	equ	0A0h		;f黵 8-bit-EEPROM, 16-bit-EEPROMS haben EADR+2

;EEPROM-Default-"Seitengr鲞e" zum Brennen mehrerer Bytes auf einmal
EPAGE8	equ	8		;f黵 8-bit-EEPROM 24LC01/02
EPAGE16	equ	32		;f黵 16-bit EEPROM 24LC32/64
;Andere EEPROM-Typen m黶sen per wIndex ausgew鋒lt werden.
;Eine "Seitengr鲞e" von 1 f黨rt zum Einzelbyte-Brennen (viel langsamer)

;Die Auswahl 8/16 bit erfolgt automatisch anhand I2CS.4 wie im EZUSB-Kern

;======================
;== Byte-Ein/Ausgabe ==
;======================

i2c_wr:	;Byte auf I睠 schreiben (kann blockieren!)
;PE: A=Ausgabe-Byte
;PA: CY=1 bei Fehler oder NAK, ACC.4=ID1
	STX	I2DAT
	dec	r0		;auf I2CS
i2c_w:	LDX
	mov	c,ACC.2		;BERR-Bit
	jc	i2c_err
	jnb	ACC.0,i2c_w	;DONE-Bit
	orl	c,/ACC.1	;ACK-Bit=0 -> C=1
	ret
	
i2c_rd:	;Byte von I睠 lesen (kann blockieren!)
;PE: R4=Anzahl noch zu lesender Bytes (f黵 LASTRD und STOP)
;PA: A=Eingabe-Byte
	mov	r0,#LOW(I2CS)
i2c_r:	LDX	
	mov	c,ACC.2		;BERR-Bit
	jc	i2c_err
	jnb	ACC.0,i2c_r	;DONE-Bit
i2c_d:	;Dummy-Lesezugriff (Seiteneinstieg mit A=0 und R0=I2CS)
	jb	I2C_NoStop,i2c_b
	cjne	r4,#2,i2c_a
	setb	ACC.5		;LASTRD setzen
i2c_a:	cjne	r4,#1,i2c_b
	setb	ACC.6		;STOP setzen
i2c_b:	STX			;LASTRD bzw. STOP setzen
	LDX	NEXT		;I2DAT lesen
i2c_err:ret

;==============================
;== I睠(EEPROM)-Adressierung ==
;==============================

EAdr:	;I睠 starten und (Adress-)Bytes ausgeben
;PE: DPTR=Adresse (DPL allein, wenn ALEN<2)
;PA: CY=1 bei Fehler
;VR: A,R0,R2
;N: Diese Routine kann bis 10 ms blockieren, bis der EEPROM bereit ist
;   (weil er sich bis zum Fertigschreiben I睠-busseitig tot stellt)
	LDX	I2CS
	jb	ACC.6,EAdr	;Stoppsequenz abwarten
	mov	r2,#0		;max. 256 Versuche, 10 ms = 120000 CPU-Takte
eal:	jb	I2C_NoStart,ea_nostart
	STX	I2CS,80h	;(4) Startsequenz ausgeben
ea_nostart:
	mov	a,I2C_Addr	;(2) I睠-Adresse: Schreiben
	call	i2c_wr		;(>=25)
	jnc	ea1		;(3) EEPROM k鰊nte mit Brennen besch鋐tigt sein
	jb	ACC.2,eae	;(3) wenn BERR nicht noch einmal versuchen
	jnb	I2C_Paging,eae	;(3) raus mit Fehler (nicht neu versuchen)
	mov	r0,#144		;(2)
	djnz	r0,$		;(144*3) warten
	djnz	r2,eal		;(3) ... Adressierung wiederholen!
eae:	ret			;raus (ggf. mit Fehler)
ea1:	;Adressbyte-Ausgabe (Tabelle s.u.)
	jnb	I2C_ALen0,ea_x0
	mov	a,DPL0		;EEPROM-Adresse Low-Teil - oder Low-Teil zuerst
	call	i2c_wr
	jc	i2c_err
	jnb	I2C_ALen1,eae	; kein Fehler: fertig
	mov	a,DPH0		;EEPROM-Adresse High-Teil
	jmp	i2c_wr
ea_x0:
	jnb	I2C_ALen1,eae	; kein Fehler: fertig ohne ein Adressbyte
	mov	a,DPH0		;EEPROM-Adresse High-Teil zuerst
	call	i2c_wr
	jc	i2c_err
	mov	a,DPL0		;EEPROM-Adresse Low-Teil als zweites
	jmp	i2c_wr		;immer schreiben und Ende
;Adressbyte-Ausgabe tabellarisch
; I2C_ALen	wIndexH	!	 I睠-Ausgabe
;ALen1	ALen0	ALEN	!	1.Byte	2.Byte	
;0	0	0	!	-	-
;0	1	1	!	DPL	-		DPL = wValueL
;1	0	2	!	DPL	DPH		DPH = wValueH
;1	1	3	!	DPH	DPL

;=============================
;== I睠(EEPROM)-Ein/Ausgabe ==
;=============================

EWrite:	;(Boot-EEPROM oder beliebiges) I睠-Ger鋞 schreiben
;PE: DPTR=(EEPROM-)Adresse (Ziel)
;    I2C_Addr = I睠-Adresse
;    I2C_ALen = I睠-Adressl鋘ge sowie 黚rige Bits
;    I2C_PMask= Seiten-Maske
;    AutoPtr=Puffer-Adresse (zu schreibende Daten)
;    R4=L鋘ge der Daten (0 = keine Daten)
;PA: CY=1 bei Fehler, dann R4=verbliebene Bytes im Puffer
;    DPTR erh鰄t
;VR: A,DPTR,R0,R2,R4
	call	EAdr
	jc	ewe
	inc	r4
	sjmp	ewf
ewl:	
	LDX1
	call	i2c_wr		;1 Byte schreiben (noch nicht brennen)
	jc	ewe
	inc	dptr		;EEPROM-Adresse mitz鋒len
	jnb	I2C_Paging,ewf
	mov	a,I2C_PMask
	anl	a,DPL0
	jz	ewp		;Seite zu Ende!
ewf:	djnz	r4,ewl		;in Seite, n鋍hstes Byte
	jb	I2C_NoStop,ewr
ewe:	STX	I2CS,40h	;Stoppsequenz
ewr:	ret
ewp:	STX	I2CS,40h	;Stoppsequenz, damit brennen
	djnz	r4,EWrite	;weitermachen, n鋍hster Block
	ret

EE_W:	jnb	I2C_Verify,EWrite	;sofort zum Schreiben gehen!
	push	DPL0		;Adresse zwecks Vergleichen retten
	push	DPH0
	push	AR4
	 call	EWrite
	pop	AR4
	pop	DPH0
	pop	DPL0		;Adresse zur點kstellen
	MOVW	AutoPtr1,Out0Buf;auch Vergleichspuffer zur點k
	setb	F0
	jnc	ERead		;Vergleichen
	ret

ERead:	;Boot-EEPROM lesen oder 黚erpr黤en
;PE: DPTR=EEPROM-Adresse (Quelle)
;    I2C_Addr = I睠-Adresse
;    I2C_ALen = I睠-Adressl鋘ge sowie NoStart und NoStop-Bits
;    AutoPtr=Puffer-Adresse (Lese-Puffer), R1=XAutoDat
;    R4=L鋘ge Daten/Puffer (0 = nicht erlaubt!)
;    F0=0: lesen, F0=1: pr黤en/vergleichen (Verify)
;PA: CY=1 bei Fehler, dann R4=verbliebene Bytes im Puffer
;    DPTR erh鰄t
;VR: A,DPTR,R0,R2,R4
	jb	I2C_NoStart,erns	;Hier: Auch keine Adressbytes ausgeben!
	call	EAdr
	jc	ere
	STX	I2CS,80h	;Noch eine Startsequenz ausgeben
erns:	mov	a,I2C_Addr	;I睠-Adresse
	inc	a		;Leseadresse
	call	i2c_wr
	jc	ere
	inc	r4		;Problem: Klappt nicht mit R4=0
	call	i2c_d		;Dummy-Lesezugriff von I2DAT
	dec	r4
erl:
	call	i2c_rd		;Byte lesen
	jc	ere
	jb	F0,erv		;Vergleichen
	STX1
	sjmp	er1
erv:	mov	r0,a
	LDX1
	xrl	a,r0		;A=0 wenn gleich
	jnz	eru		;raus mit Fehler wenn ungleich
er1:	inc	dptr		;EEPROM-Adresse mitz鋒len
	djnz	r4,erl
	jb	I2C_NoStop,er9	;Stopp-Unterdr點kung nur bei regul鋜em Ende!
	db	0E5h		;mov a,xx
eru:	setb	c
ere:	STX	I2CS,40h	;Stoppsequenz
er9:	ret

;===================================
;== Arbeitszellen-Initialisierung ==
;===================================

EReqInit:	;A2-Request auswerten und drei I睠-Parameter zusammenstellen
;PE: wIndex = USB-Parameter (ACHTUNG bei EZUSB Control Panel [Rindfleisch])
;VR: A,R0,I2C_Addr,I2C_ALen,I2C_PMask
	LDX	SetupDat+4	;wIndexL
	jnz	eri_nBootRom
EReqInitBoot:	;Seiteneinstieg f黵 Startup
	LDX	I2CS		;bei wIndexL=0 Boot-ROM automatisch w鋒len
	mov	c,ACC.4		;ID1-Bit = 1 bei 16-bit-EEPROM
	mov	a,#EADDR
	mov	ACC.1,c		;ggf. aus A0 ein A2 machen
	mov	I2C_Addr,a
	clr	a
	addc	a,#1		;Adressl鋘ge 1 oder 2 Bytes
	mov	I2C_ALen,a

⌨️ 快捷键说明

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