Source file: /~heha/ewa/Ofen/8te.zip/Firmware/io.i15

;Initialisiert I/O-Ports, Timer2 + PWM2, SPI
ioInit
	banksel	WPUA		;Bank 4
	bcf	WPUA,4		;Kein Pullup gegen 5 V für MAX31855!
				;Das würde Strom um den Längsregler herumleiten.
	movlwf	0x21,SSP1CON1	;SPI Master, Takt = Fosc/16 = 3 MHz, Portpins zum SPI
	banksel	ANSELA		;Bank 3
	clrf	ANSELA
	clrf	ANSELC
	banksel	LATA		;Bank 2
	clrf	LATA
	clrf	LATC
	bsf	APFCON,2	;PWM2 auf RA5, alles andere belassen
	banksel	TRISA		;Bank 1
	movlwf	0x13,TRISA	;Alles Ausgang außer RA4 = !CE
	movlwf	0x06,TRISC	;Alles Ausgang außer RC1 (SDI) und RC2 (LED)
	banksel	PWM2DCH		;Bank 12
	movlwf	6,PWM2DCH	;Tastverhältnis 50:50 (0,5 µs : 0,5 µs)
	movlwf	0xC0,PWM2CON	;PWM2 + Ausgang aktivieren
	banksel	0
;Timer2 wird mit Fosc/4 also 12 MHz (Befehlstakt) gespeist.
	movlwf	12-1,PR2	;Periodendauer 1 µs
	bsf	T2CON,2		;Timer2 mit Vorteiler 1 aktivieren
	movlwf	0x31,T1CON	;Timer1 mit Vorteiler 8 aktivieren: 1,5 MHz
	banksel	r1p		;Bank 4
	clrf	r1p
	movlwf	0xE8,r1p+1
	clrf	r3p
	movwf	r3p+1
	clrf	wp
	movwf	wp+1
	clrf	lfdnr
	clrf	lfdnr+1		;Laufende Nummer (seit Reset) nullsetzen
	return

ioPoll
	banksel	0
	btfss	PIR1,TMR1IF	;Überlauf Timer1?
	 return
	bcf	PIR1,TMR1IF	;32 Hz
	bcf	T1CON,0		;Zähler (kurz) anhalten (leider kein CTC-Modus)
	addlf2	-46875,TMR1	;korrigieren: 46875 = 1,5 MHz / 32 Hz = 5**6*3
	bsf	T1CON,0		;weiterzählen
	incf	T2H,f
	btfss	T2H,3		;÷8 auf 4 Hz runterteilen
	 return
	bcf	T2H,3
;125 ms sind vergangen: MAX31855 abfragen und Analogmultiplexer weiterschalten
	banksel	TRISA
	bcf	TRISC,2		;LED ein (wird von SDO kontrolliert!)
	bcf	TRISA,4		;!CS aktivieren,
; das sperrt den A/D-Wandler-Ausgang innerhalb des MAX31855, und
;das nächste Ergebnis (welches wegen des Umschaltens des Multiplexers
;Murks ist) wird beim nächsten Mal nochmals überschrieben.
	banksel	LATC		;Bank 2
	movfw	LATC		;derzeitige Multiplexerstellung --XXX---
	addlw	8		;weiterschalten
	movwf	CH		;Überlauf (Bit 6) merken
	andlw	0x3F		;Bit 6 0 belassen
	movwf	LATC
	addlw	-8
	rrf	WREG,w		;---XXX--
	andlw	0x1C		;000XXX00: Kanaladresse zum Abspeichern vorbereiten
	addlwf2	MaxArray+4,FSR0	;Hier ohne 100h-Überlauf
	banksel	SSP1BUF		;Bank 4
	movlwf	4,CL
_spil	movlwf	-1,SSP1BUF	;Bytetransfer auslösen
	banksel	0
_spii	btfss	PIR1,SSP1IF
	 bra	_spii		;warte bis Interrupt anhängig, nach 2,6 µs
	bcf	PIR1,SSP1IF	;Interrupt löschen
	banksel	SSP1BUF		;Bank 4
	movfw	SSP1BUF		;Gelesenes Byte auslesen
	movwi	--FSR0		;Bit31 kommt zuerst
	loop	CL,_spil
	banksel	TRISA		;Bank 1
	bsf	TRISA,4		;!CS auf High
	bsf	TRISC,2		;LED aus
	btfss	CH,6		;Multiplexer Null geworden?
	 return			;nein, weiter A/D-wandeln
;Alle 2 s Werte zum USB, CDC und (TODO) Flash ausspucken
;Mit Debug-LED
	banksel	SSP1CON1	;Bank 4
	bcf	SSP1CON1,5	;SPI-Portpins = Portpins
	banksel	LATA
	bsf	LATA,2
	banksel	TRISA		;Bank 1
	bcf	TRISA,2		;LED ein
	banksel	0
	btfss	E3I_STA,UOWN
	 call	sendToEp3
	banksel	0
	tstf	linefill
	skpnz
	 call	sendToEp1
	banksel	lfdnr
	incf	lfdnr,f		;Laufende Nummer erhöhen
	skpnz
	 incf	lfdnr+1,f
	banksel	TRISA		;Bank 1
	bsf	TRISC,2		;LED aus
	banksel	LATA
	bcf	LATA,2
	banksel	SSP1CON1	;Bank 4
	bsf	SSP1CON1,5	;SPI-Portpins = SPI
	banksel	0
	return

;Daten zum WebUSB-Bulk-Endpoint senden; Puffer ist frei
sendToEp3
	movlwf2	MaxArray,FSR0
	movlwf2	LIN_E3I_BUF,FSR1
	movlwf	4*8,E3I_CNT
	call	memcpyW		;8 4-Byte-Werte „plain“ transferieren
	goto	e3i_tx		;abschicken

sendToEp1
	banksel	lfdnr
	movfwf	lfdnr,DL
	movfwf	lfdnr+1,DH
	banksel	0
	movlwf	10,DIV
	call	putUint
	clrf	TH		;Tabellenspalte
_io9	movlw	9		;Tab als FieldSeparator
	call	putchar
	lslf	TH,w
	lslf	WREG,w		;×4
	addlwf2	MaxArray,FSR1	;Tabellenspalte in MaxArray-Zeiger
	moviw	2[FSR1]
	movwf	DL
	moviw	3[FSR1]
	movwf	DH
	call	putFix
	incf	TH,f
	btfss	TH,3
	 bra	_io9		;Noch nicht 8
	movlw	10		;LF als RecordSeparator
	call	putchar
	movlw	13		;für putty-Standardeinstellung
	call	putchar
;linebuf zum USB EP1In übergeben
	movlwf	1<<E1I_SSH,E1I_CNT
	subwf	linefill,w	;w = linefill - 64 = Bytes für 2. Paket
	skpnb			;Wenn >=0 bleibt es bei 64 Bytes für 1. Paket
	 addwf	E1I_CNT,f	;Reduziertes 1. Paket
	movlwf2	linebuf,FSR0
_e1i2	movlwf2	LIN_E1I_BUF,FSR1
	movlw	E1I_CNT
	call	memcpyW
	goto	e1i_tx		;abschicken, Completion-Routine kümmert sich um den Rest

onE1I	;Completion-Routine
	banksel	0
;Entweder die letzten 0 bis zu 16 Bytes schicken
;oder linebuf als frei melden (linefill=0)
	movlw	1<<E1I_SSH
	subwf	linefill,w
	movwf	E1I_CNT		;0..16
	brb	_e1i1		;linefill<64: 1. Paket genügte: Abschluss
	movlwf	1,linefill	;Bei nächster Completion zum Abschluss kommen
	movlwf2	linebuf+(1<<E1I_SSH),FSR0
	bra	_e1i2		;Speicher kopieren und In-Transfer anstoßen
_e1i1
	clrf	linefill	;Zeile füllbar machen
;Erfolgreich geschickt: Flash-Lesezeiger erhöhen
	banksel	r1p	;Bank 4
	movlw	8
	addwf	r1p,f
	skpz
	 return
	movlw	0xE8
	incf	r1p+1,f
	skpnz
	 movwf	r1p+1
onE2I	return
	
onE3I
	banksel	r3p	;Bank 4
	movlw	8
	addwf	r3p,f
	skpz
	 return
	movlw	0xE8
	incf	r3p+1,f
	skpnz
	 movwf	r3p+1
	return
	
	
;Zeichen in linebuf ablegen
;PE:	w = Byte
;VR:	chr, FSR1, Bank=0
putchar
	movwf	chr		;Zeichen retten
	movfw	linefill
	addlwf2	linebuf,FSR1	;Zielzeiger
	movfwf	chr,INDF1
	incf	linefill,f	;(darf nicht überlaufen)
	return

;Festkommazahl mit 2 Nachkommabits = 2 Dezimalstellen oder „NaN“ ausgeben
;PE:	DH:DL = vzb. 16-Bit-Wert mit Bit 0 = NaN und Bit 3:2 = Nachkomma
;PA:	-
;VR:	DH:DL = 0, E, CL
putFix
	btfsc	DL,0
	 bra	onan
	movfwf	DL,E		;sichern
	movlwf	4,CL
div16	asrf	DH
	rrf	DL
	loop	CL,div16
	movlwf	10,DIV
	call	putInt		;versaut DH:DL und CL
	movlw	'.'		;für Matlab, nicht für Excel
	call	putchar
;Stets 2 Ziffern für die 4 möglichen Fälle generieren: "00","25","50","75"
	btfsc	E,3
	 bra	_e30
	movlw	'0'
	btfsc	E,2
	 movlw	'2'
	bra	_eo
_e30	movlw	'5'
	btfsc	E,2
	 movlw	'7'
_eo	call	putchar
	movlw	'0'
	btfsc	E,2
	 movlw	'5'
	goto	putchar

;16-Bit-Integerzahl via putchar() ausgeben
;PE:	DH:DL = vzb. Integerzahl
;	DIV = Zahlenbasis
;PA:	Maximal 6 Aufrufe von putchar: "-32768"
;VR:	DH:DL = 0, strbuf, TL=0, FSR1, CL=0
putInt
	btfss	DH,7
	 bra	putUint
	movlw	'-'
	call	putchar
	comf	DH,f
	comf	DL,f
	incf	DL,f
	skpnz
	 incf	DH,f
putUint	clrf	TL
_ozif	call	div168
	movfw	TL
	call	w_plus_strbuf_to_FSR1
	movfwf	REM,INDF1	;Stacknachbildung
	incf	TL,f
	movfw	DH
	iorwf	DL
	brnz	_ozif		;Dividend noch nicht 0 geworden
_ochr	decf	TL,w
	call	w_plus_strbuf_to_FSR1
	movfw	INDF1
	addlw	-10
	skpnc
	 addlw	7		;Differenz zwischen 'A' und '9'+1
	addlw	'0'+10
	call	putchar		;mindestens 1 Zeichen: Versaut FSR1!
	loop	TL,_ochr	;Pufferanfang erreicht?
	return
onan
	movlw	'N'
	call	putchar
	movlw	'a'
	call	putchar
	movlw	'N'
	goto	putchar

w_plus_strbuf_to_FSR1
	addlwf2	strbuf,FSR1
	return

;Divisionsroutine für Ziffernausgabe
;PE:	DH:DL = vzl. 16-Bit-Zahl
;	DIV = vzl. Divisor 8 Bit
;PA:	DH:DL = dividierte Zahl
;	REM = Rest
;VR:	CL=0
div168	clrf	REM	;24-Bit-Akku REM:DH:DL
	movlwf	16,CL	;16 Runden
_dl	lslf	DL,f
	rlf	DH,f
	rlf	REM
	brc	_dc	;Bei Übertrag Divisor subtrahieren
	movfw	DIV
	subwf	REM,w	;c = REM >= w oder b = REM < w
	brb	_dn	;Wenn kleiner Divisor nicht subtrahieren
_dc	movfw	DIV
	subwf	REM,f	;REM -= DIV: Divisor subtrahieren
	bsf	DL,0	;Bit im Divisionsergebnis
_dn	loop	CL,_dl
	return
Detected encoding: UTF-80