title "PIC16F876A Unilink Interface by Werner Johansson (c) 2004-2005" subtitl "Definitions" list c=132,P=16F876a,R=DEC,F=inhx8m include "p16f876a.inc" ; Standard equates & Macros ERRORLEVEL 1,-302 ; Get rid of those annoying 302 msgs! ;---------------------------------------------------------------- ; The Configuration Word __CONFIG _HS_OSC&_WDT_OFF&_PWRTE_OFF&_BODEN_ON&_LVP_OFF&_CPD_OFF&_WRT_OFF&_DEBUG_OFF&_CP_OFF ;---------------------------------------------------------------- ; HISTORY ;---------------------------------------------------------------- ; Version ; ; 0.0 Very first "Fucking No Work!" version ; 0.1 Some receiving works with the new MCU using HW SPI, yay! ; ;---------------------------------------------------------------- ; Unilink BUSON IN (blue) connected to RA4C2/T0CKI ; Unilink DATA (green) connected to RC4(SDI), RC5(SDO) via open collector driver (HW USART) ; Unilink BUSON OUT (blue) connected to RA5 via 100R resistor (this is for daisy-chaining) ; Unilink CLK (yellow) connected to RC3(SCK) (USART CLK) ; Unilink RST (lilac) connected to RB0(INT) ; RS-232 TX from computer connected to RC7/RX ; RS-232 RX to computer connected to RC6/TX ; RS-232 RTS from computer connected to RC2 ; RS-232 RI and CTS to computer connected to RC1 ; RS-232 INVALID signal from MAX connected to RC0 ; Pin mapping as follows: ; RA0 Voltage sense (A/D in 0) ; RA1 Amp sense 1 (A/D in 1) ; RA2 Early-Startup sense/Blue LED drive (active low) (RA2 and RA3 have been reversed from the PCB layout!) ; RA3 Amp sense 2 (A/D in 3) ; RA4/T0CKI BUSON IN from Head Unit (can trigger interrupt on clocking?) ; RA5 BUSON OUT to cascade ; RB0 UNI RST in (interrupt triggered) ; RB1 Enable-PWR output to SEPIC converter ; RB2 Disable-AMP output ; RB3 Enable-AUX output to trigger analog switch relay ; RB4 Sign output from Amp sense 1/Red LED drive, active low ; RB5 Sign output from Amp sense 2/Green LED drive, active low ; RB6 ICSP/ICD reserved ; RB7 ICSP/ICD reserved ; RC0 INVALID input from MAX3235 ; RC1 CTS and RI output ; RC2 RTS input ; RC3 Unilink clock input ; RC4 Unilink data input ; RC5 Unilink data output (drives inverted!) ; RC6 TX output ; RC7 RX input ;---------------------------------------------------------------- ; File register usage ; Memory from 20h to 7fh (BANK 0 96 bytes) ; a0h to efh (BANK 1 80 bytes) ; 110h to 16fh (BANK 2 96 bytes) ; 190h to 1efh (BANK 3 96 bytes) ; 70-7fh, f0-ffh, 170-17fh and 1f0-1ffh share the same 16 bytes, for ISR!) Dcount equ 20h e_LEN equ 21h Icount equ 2Dh ; Offset of string to print TxTemp equ 2Eh ; blahblah TxTemp2 equ 2Fh ; Blahblah2 org 0 nop ; Leave the first location, just in case ; call Bootstrap ; Call Flash Load routine ; call LCDInit ; Initialize LCD I/F ; call IRQInit ; Set up and start the IRQ handler goto Main ; Run the main program loop (skip the IRQ handler) subtitl "IRQ Handler" ;---------------------------------------------------------------- ; Interrupt handler always starts at addr 4. ; Let the entire handler stay here instead of branching away org 4 ; Must be on Address 4! retfie ; Interrupt return subtitl "Main loop" page org 100h Main clrf PORTA clrf PORTB clrf PORTC bsf STATUS,RP0 ; Hi Bank movlw 04h ; AD mode 4h, 3 ad inputs AN0, 1 and 3, not 2 (!) fix pcb.. :( movwf ADCON1 movlw 0dfh ; RA5 should be outputs... ; movlw 0dbh ; RA2 & RA5 should be outputs... ; movlw 0fbh ; RA2 should be output... movwf TRISA ; Yep. movlw 0c1h ; RB0, 6 & 7 are inputs. movwf TRISB ; Yep movlw 9dh ; RC0, 2, 3, 4, 7 are inputs ; movlw 0bdh ; RC0, 2, 3, 4, 7 are inputs movwf TRISC bcf OPTION_REG,NOT_RBPU ; Turn on port B pull-up bcf STATUS,RP0 ; Restore Lo Bank bsf PORTB,1 ; Turn on SEPIC ; bsf PORTA,5 ; test ss shit bsf STATUS,RP0 ; Access bank 1 bsf TXSTA,TXEN ; Enable UART TX movlw 31 ; Divisor for 9k6 @ 20MHz Fosc movwf SPBRG ; Store bcf STATUS,RP0 ; Back to bank 0 bsf RCSTA,SPEN ; Enable serial port bsf RCSTA,CREN ; Enable UART RX ; movlw 'W' ; movwf TXREG ; Test transmission ;WaitRSTHigh ; call UpdateLEDS ; btfss PORTB,0 ; Test RST bit ; goto WaitRSTHigh ; bsf STATUS,RP0 ; Hi Bank ; bsf TRISA,2 ; RA2 back as input (turn off blue led) ; bcf STATUS,RP0 ; Lo Bank RestartCrap bcf SSPCON,SSPEN ;disable ssp WaitRSTLow call UpdateLEDS ;b WaitRSTLow btfsc PORTB,0 ; Test RST bit goto WaitRSTLow WaitBUSONHigh call UpdateLEDS btfss PORTA,4 ; Test BUSON bit goto WaitBUSONHigh bsf STATUS,RP0 ; movlw 40h ; Latch on active-to-idle edge (needs ss crap?) movlw 00h ; Transfer on idle-to-active edge (and latch on active-to-idle) movwf SSPSTAT bcf STATUS,RP0 WaitCLKLow call UpdateLEDS btfsc PORTC,3 ; SCK input must be low before enabling SSP according to errata sheet (!) goto WaitCLKLow movlw 25h ; movlw 34h ; fuxx0red ss mode crap movwf SSPCON ; Enable SPI slave mode with SCK IDLE low, no _SS control clrw movwf SSPBUF OnceMore WaitForByte call UpdateLEDS btfsc PORTB,0 ; Test RST bit goto RestartCrap btfss PORTA,4 ; Test BUSON bit goto RestartCrap bsf STATUS,RP0 btfss SSPSTAT,BF ; Test for buffer complete goto WaitForByte bcf STATUS,RP0 movf SSPBUF,w xorlw 0ffh ; Invert received data movwf TXREG ; Send it out to Async serial clrw movwf SSPBUF goto OnceMore meck b meck UpdateLEDS ; NOTE!!!! This is wrong, never drive the led outputs high as there are other open-collector drivers on these pins!!! ; This is just for debugging, must be removed when hooking things up to the board!!! bcf STATUS,RP0 ; IO is inverted logic (active low) ; btfsc PORTA,4 ; test buson btfss PORTC,4 ; test IO bcf PORTB,5 ; turn on green led ; btfss PORTA,4 ; test buson clear btfsc PORTC,4 ; test IO bsf PORTB,5 ; turn off green led ; CLK is true logic (active high) ; btfsc PORTB,0 ; Test RST bit btfsc PORTC,3 ; test clk bcf PORTB,4 ; turn on red led if RST high ; btfss PORTB,0 ; Test RST bit btfss PORTC,3 ; test clk bsf PORTB,4 ; turn off red led if RST low return ;---------------------------------------------------------------------- ; EE Data (64 bytes), located at 2100h org 2100h ; data 0ffh, 0ffh, 0ffh, 0ffh, 001h, 023h, 045h, 067h END