;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-8 | 0
|