Source file: /~heha/mb-iwp/USB-RS422-Umsetzer/Firmware.zip/rs422.a90

;RS422-Umsetzer für με-Triangulationssensor „optoNDCT 2200“
.nolist
;Quarzfrequenz: 11,0592 MHz
;Baudrate RS422: 691200 (tatsächlich eine standardisierte RS422-Rate!)
;Mit FT425 (Steckbrett-Schaltung mit Siphec.com FT245 uMod-S)
;100430	Start, Inbetriebnahme
;100503	Zweiter Ansatz: LED-Anzeige für Pufferüberläufe (nur IN-Transfer),
;	interner RAM als Empfangspuffer, PEN-Leitung trennen!
;	Weil Problem: Doppelte Bytes, Fehlermeldung der με-Software
;	Läuft nun einwandfrei! (Warum auch immer sich das Problem mit den
;	doppelt empfangenen Bytes gelöst hatte … Angst-NOPs?)
;********************************************************************
;Hardware:
;	PB (12-19) = Datenport zum FT245	I/O
;	PD0 (2)    = RxD			I
;	PD1 (3)    = TxD			O
;	PD2 (6)    = /TxE = INT0		I
;	PD3 (7)    = /RxF = INT1		I
;	PD4 (8)    = WR				O
;	PD5 (9)    = /RD			O
;	PD6 (11)   = LED (low-aktiv)		O
// Die LED leuchtet auf wenn FIFO (ATtiny2313: 128 Bytes) voll
// und verlischt, wenn FIFO leer (d.h. alles im FT245 oder USB abgeschickt)
#define __SFR_OFFSET 0 
#include <avr/io.h>

#define FIFOSTART  0x60	//Gesamten RAM für FIFO verwenden, keine Interrupts
#define FIFOLENGTH 0x80

.org 0		;Reset-Adresse
;********************************************************************
;*  Mikrocontroller-Programmstart
;********************************************************************
.list
startup:
	ldi	r16,0x62
	out	PORTD,r16	;hier: keine Pull-Ups
	ldi	r16,0x72	;z110zz1z
	out	DDRD,r16	;Ausgänge aktivieren (alle HIGH außer WR)
;Das Baudraten-Register ist schon richtig (nämlich 0)!
	ldi	r16,0x18
	out	UCSRB,r16	;Serielle Schnittstelle (RxD und TxD) aktivieren
;UCSRC ist schon richtig (8-n-1)
	ser	r17		;R17 = ONES
	clr	r1		;R1 = ZERO
	ldi	XH,hi8(FIFOSTART)	;X = Schreibzeiger
	ldi	XL,lo8(FIFOSTART)
	movw	YL,XL		;Y = Lesezeiger
	ldi	r18,0x01	;Flag-Bits für „voll“ (1) und „leer“ (0)
	ldi	r19,hi8(FIFOSTART+FIFOLENGTH)	;für cpc

;********************************************************************
;*  Hauptschleife (pro Byte 160 Takte Zeit, vollduplex)
;********************************************************************
MainLoop:
;=== OUT-Transfer (ohne FIFO, nur wenig Datenaufkommen) ===
	sbic	PIND,3		;/RXF (soviel wie RxE)
	 rjmp	NoTx		;Nichts tun wenn HIGH (FIFO leer)
	sbis	UCSRA,5		;Sendedatenregister frei?
	 rjmp	NoTx		;Nichts tun wenn 0
	cbi	PORTD,5		;Strobe ausgeben (FIFO lesen)
	rjmp	.		;2 Takte (~200 ns) warten
	in	r0,PINB
	out	UDR,r0		;Daten kopieren
	sbi	PORTD,5
NoTx:
;=== IN-Transfer (über FIFO) ===
;--- Vom Seriellen Port zur FIFO ---
	sbis	UCSRA,7		;Empfang komplett?
	 rjmp	NoRx		;Nichts tun wenn 0
	sbrc	r18,1		;FIFO voll?
	 rjmp	FifoFullError
	in	r0,UDR		;Daten kopieren
  ;FIFO-Schreiboperation START
	st	X+,r0
	cpi	XL,lo8(FIFOSTART+FIFOLENGTH)	;(A) Wrap-Around des Zeigers
	cpc	XH,r19
	brne	.+4
	 ldi	XH,hi8(FIFOSTART)
	 ldi	XL,lo8(FIFOSTART)
	cbr	r18,1<<0	;Empty-Flag löschen
	cp	XL,YL		;(B) Füllstand prüfen
	cpc	XH,YH
	brne	.+2
	 sbr	r18,1<<1	;Full-Flag setzen
  ;FIFO-Schreiboperation ENDE
NoRx:
;--- Von FIFO zum FT245 ---	 
	sbic	PIND,2		;/TxE (soviel wie TxF)
	 rjmp	NoFt		;Nichts tun wenn HIGH (FIFO voll)
	sbrc	r18,0		;FIFO leer?
	 rjmp	FifoErrorClear
  ;FIFO-Leseoperation START
	ld	r0,Y+
	cpi	YL,lo8(FIFOSTART+FIFOLENGTH)	;(A) Wrap-Around des Zeigers
	cpc	YH,r19
	brne	.+4
	 ldi	YH,hi8(FIFOSTART)
	 ldi	YL,lo8(FIFOSTART)
	cbr	r18,1<<1	;Full-Flag löschen
	cp	YL,XL		;(B) Füllstand prüfen
	cpc	YH,XH
	brne	.+2
	 sbr	r18,1<<0	;Empty-Flag setzen
  ;FIFO-Leseoperation ENDE
	out	PORTB,r0
	sbi	PORTD,4
	out	DDRB,r17	;Ausgänge aktivieren
	cbi	PORTD,4		;Strobe ausgeben (FIFO schreiben)
	rjmp	.		;2 Takte (~200 ns) warten
	out	DDRB,r1		;Ausgänge hochohmig
	out	PORTB,r1	;ganz hochohmig (200-kΩ-Pullups des FT245 wirken)
NoFt:
	rjmp	MainLoop

FifoFullError:
	cbi	PORTD,6		;LED einschalten, Fehler anzeigen
	rjmp	NoRx
FifoErrorClear:
	sbi	PORTD,6		;LED ausschalten
	rjmp	MainLoop
Detected encoding: UTF-80