Source file: /~heha/ewa/Ofen/rauch.zip/rauch.a15

; Rauchmelder mit 3 Zusatzsensoren und USB
	radix	dec
	list	n=0
	include	"p16f1455.inc"
	include "mymacros.i15"
; Hardware
;1	5P
;2	RA5		Zum Rauchmelder — ohne Pullup
;3	RA4		Kontroll-LED, Low = ein
;4	!MCLR		Jumper
;5	RC5	RxD	OneWire DS18B20
;6	RC4		!EN Ganssensor
;7	RC3	PWM2	9-V-Erzeugung für Rauchmelder
;8	RC2	AN6	Analogausgang Gassensor	
;9	RC1	SDA	I²C Pyrosensor
;10	RC0	SCL	I²C Pyrosensor
;11	3P3		Kondensatorstütze für USB
;12		D-	USB
;13		D+	USB
;14	00

; RAM-Variablen (Bank 0 durch USB belegt)
	cblock	0xA0	; Bank 1
ds18b20id0:8		; Vier OneWire-IDs, je 64 bit
ds18b20id1:8
ds18b20id2:8
ds18b20id3:8
rep1:16
rep2:16
rep3:10

	endc
	cblock	0xF0	; Non-Banked
cnt0			; Innerer Schleifenzähler
cnt1			; Äußerer Schleifenzähler
	endc

; Platz für Urlader
	org	0x200
; Initialisierung
	goto	onReset
	return
	return
	return
	retfie
	
	include	"webusb.i15"

onReset:
	call	usbInit	;Setzt Maximale CPU-Taktfrequenz: 12 MHz
; LED ein
	banksel	TRISA
	movlwf	0x2B,TRISA	; Bit 4 löschen
; Kein Pullup zum Rauchmelder
	
; PWM2-Ausgang aktivieren und Wechselspannung ausgeben
	movlwf	0x37,TRISC	; Bit 3 löschen
	banksel	T2CON		; Bank 0
	movlwf	60-1,PR2	; glatt 200 kHz generieren (da reichen 100 nF)
	movlwf	0x4C,T2CON	; 8-bit-Timer2 starten mit 12 MHz, ÷60 = 200 kHz
	banksel	PWM2CON		; Bank 12
	clrf	PWM2DCL
	movlwf	30,PWM2DCH	; Tastverhältnis 1:1
	movlwf	0xC0,PWM2CON	; Ausgang aktivieren
; A/D-Wandler initialisieren
	banksel	FVRCON
	movlwf	0xF3,FVRCON	; 4,096 V auf ADC, Temperatursensor aktivieren
	banksel	ADCON0
	movlwf	0xF0,ADCON1
	movlwf	0x01,ADCON0
	
; Reports initialisieren (wenigstens die Report-ID)
	movlwf2	ds18b20id0,FSR0
	movlw	80		;gesamte Bank 1
	call	ZeroMemory
	banksel	rep1
	movlwf	1,rep1
	movlwf	2,rep2
	movlwf	3,rep3
	
_loop	call	usbPoll		; HID + WebUSB realisieren
	banksel	ADCON0
	btfsc	ADCON0,ADGO
	 bra	_loop
	movlwf	ADRES,FSR0
	movlwf	rep1+4,FSR1	;je nach Kanal: Gassensor = AN6 oder Chiptemperatur
	movlw	2
	call	memcpy
	bra	_loop

; Kopiert Daten von FSR0 nach FSR1 Länge W (1..256 Bytes)
; VR: cnt0 = 0, W = 0
memcpy	movwf	cnt0
mcl	moviw	FSR0++
	movwi	FSR1++
	loop	cnt0,mcl
	retlw	0

;Löscht RAM ab FSR0 Länge W (1..256 Bytes)
;VR: cnt0 = 0
ZeroMemory
	movwf	cnt0
	clrw
;Füllt RAM ab FSR0 Länge cnt0 mit Byte W
;VR: cnt0 = 0
memset	movwi	FSR0++
	loop	cnt0,memset
	return

;Holt DS18B20-ID je nach Index W
;PE: W = Index (0..3), BSR = egal
;PA: FSR0 = Zeiger, BSR = unverändert
;VR: W = 8, cnt0 = 0
get_id_ptr
	movwf	cnt0		;retten
	movlwf	ds18b20id0,FSR0
	movfw	cnt0
	brz	fo3		;nicht versetzen
lo3:	addfsr	FSR0,8
	loop	cnt0,lo3
fo3:	retlw	8

; Aufruf aus webusb.i51: W = Report-ID
; BSR = 0
onEp0SetReport
	xorlw	2
	brz	w2
	xorlw	3^2
	skpz
	 retlw	-1		;Falsche Report-ID
	call	usbEp0Recv
	skpnc
	 retlw	-1
;Der Report enthält nur den gewünschten DS18B20-Index, nicht die DS18B20-Seriennummern
	movfw	E0_BUF+1
	andlw	~3
	skpnz
	 retlw	-1		;Diesen Index mag ich nicht
	movlwf	rep3+1,FSR1
	movfw	E0_BUF+1	;von Bank 0
	movwi	FSR1++		;nach Bank 1
	call	get_id_ptr	;Quellzeiger berechnen
	call	memcpy
	retlw	0
w2:
	call	usbEp0Recv	; warten bis OUT-Daten angekommen sind (passt stets in FIFO)
	skpnc
	 retlw	-1
;TODO: Handle Report!
	retlw	0

; Aufruf aus webusb.i51: W = Report-ID
onEp0GetReport
	decfsz	WREG,w
	 bra	_nr1
;TEST
	banksel	LATA
	movlw	1<<4
	xorwf	LATA,f		;LED schaltet um
	
	movlwf2	rep1,FSR0
	retlw	16		; Datenlänge liefern
_nr1	decfsz	WREG,w
	 bra	_nr2
	movlwf2	rep2,FSR0
	retlw	16
_nr2	decfsz	WREG,w
	 retlw	-1
	movlwf2	rep3,FSR0
	retlw	10

	end
Detected encoding: UTF-80