+; program writes SOS msg into flash then turns LED green
+; when serial interrupt received, turns off interrupts, turns off
+; power, transmits contents of SSPCON1 by flashing LED red, repeats
+; (next version will transmit SOS code first, then contents of
+; SSPCON1)
+
+
; to start, need to write into flash, starting at 30 0000h:
; 10 10 10 00 | 1110 1110 | 1110 00 10 | 10 10
include /usr/share/gputils/header/p18f458.inc
radix dec
+;---------------------------------------------------------------------------
+; reserved access bank locations
+
+WREG2 equ 00h ; a 2nd working reg :-)
+WREG3 equ 01h ; a 3rd working reg :-)
+WREG4 equ 02h ; a 4th working reg :-)
+BLANK equ 03h ; register full of zeros
+
+
+
+;---------------------------------------------------------------------------
+; LED colours
+
+RED equ 0
+GREEN equ 1
+
+;---------------------------------------------------------------------------
+; memory location definitions
+
+ERROR_BUF_PAGE equ 3 ; error codes on flash p3
+F_ERROR_U equ 30h ; upper part of error memory locations
+F_SOS_H equ 00h ; high (middle) part of SOS error memory loc.
+F_SOS_L equ 00h ; lower part of SOS error memory loc.
+
+
;---------------------------------------------------------------------------
; error messages
-error_SOS equ 0 ; msg 0 = SOS
+err_SOS equ 0 ; msg 0 = SOS
+
+;****************************************************************************
+; VECTORS: special locations, where the PIC starts executing
+; after interrupts
+
+; high priority interrupt
+
+ org 000008h
+ goto interrupt_high
+
+; low priority interrupt
+
+ org 000018h
+ goto interrupt_low
+
+;****************************************************************************
+; MACROS
+
+;----------------------------------------
+; ifbit1(REGISTER,BITNUMBER)
+; executes the next instruction but only if bit BITNUMBER
+; in REGISTER (which must be in the access bank) is set
+ifbit1 macro REGISTER, BITNUMBER
+ btfsc REGISTER, BITNUMBER, 0
+ endm
+
+;----------------------------------------
+; ifbit0(REGISTER,BITNUMBER)
+; executes the next instruction but only if bit BITNUMBER
+; in REGISTER (which must be in the access bank) is clear
+ifbit0 macro REGISTER, BITNUMBER
+ btfss REGISTER, BITNUMBER, 0
+ endm
+
+;----------------------------------------
+; errmsg(ERRCODE,COLOUR)
+; reads the chosen error msg out of flash and transmits by
+; flashing LED in chosen colour [1 = blue (=green), 0 = orange (=red)]
+;
+;
+;errmsg macro ERRCODE, COLOUR
+;
+;
+;
+;
+;
+;
+; endm
+
+;----------------------------------------
+; readout(READOUTREG,COLOUR)
+; transmits the contents of the chosen byte by flashing LED
+; in chosen colour [1 = blue (=green), 0 = orange (=red)]
+
+; NB using WREG2 as copy of READOUTREG contents
+; using WREG3 as COLOUR store
+; using WREG4 as counter
+
+
+readout macro ERRCODE, COLOUR
+ movlw COLOUR
+ movwf WREG3,0 ; copy COLOUR into WREG3
+ clrf WREG4,0 ; clear loop counter (WREG4)
+ movff ERRCODE,WREG2 ; copy ERRCODE into WREG2
+
+readout_loop
+ movlw 8
+ cpfslt WREG4,0 ; if loop counter >=8, return
+ return
+ rlcf WREG2,1
+ bc readout_led_off
+ bra readout_led_on
+
+readout_led_on
+ bcf TRISD,2,0 ; make pin RD2 an output (DS100)
+ ifbit0 WREG3,0
+ bcf LATD,2,0 ; set LED red
+ ifbit1 WREG3,0
+ bsf LATD,2,0 ; set LED green
+ incf WREG4,1,0 ; increment loop counter
+ call waiting
+ goto readout_loop
+
+
+readout_led_off
+ bsf TRISD,2,0 ; make pin RD2 an input (i.e. set Z, black)
+
+
+
+
+
+
+ endm
+
+
+;****************************************************************************
+
+ code
+
+;****************************************************************************
+; serial set-up
+; enable interrupts so that this can be used as a trigger for the
+; panic routine
+
+; initial config - TXSTA register p181
+ bcf TXSTA,6,0 ; p181, set 8-bit mode
+ bsf TXSTA,5,0 ; transmit enable
+ bcf TXSTA,4,0 ; asynchronous mode
+ bsf TXSTA,2,0 ; set high baud rate
+
+; initial config - RCSTA register p182
+ bsf RCSTA,7,0 ; serial port enable (p182)
+ bcf RCSTA,6,0 ; 8-bit reception
+ bsf RCSTA,4,0 ; enable continuous receive
+
+; set SPBRG to get correct baud rate according to table top right p186
+; (Tosc = 20MHz, desired baud rate = 9600)
+ bsf SPBRG,7,0
+ bsf SPBRG,0,0
+
+; interrupt set-up for serial receive
+ bcf IPR1,5,0 ; set to low-priority interrupt
;---------------------------------------------------------------------------
+; interrupt set-up
+
+; globally enable interrupts - p77
+ bsf RCON,7,0 ; enable priority levels
+ bsf INTCON,7,0 ; enable high-priority interrupts
+ bsf INTCON,6,0 ; enable low-priority interrupts
+ bsf PIE1,5,0 ; enable USART receive interrupt (p85)
+
+;---------------------------------------------------------------------------
+
+; write error code for SOS into flash memory (starting at 30 0000h)
+ movlw F_ERROR_H ; set table pointer to point to
+ movwf TBLPTRU ; start of flash p3
+ movlw F_SOS_H
+ movwf TBLPTRH
+ movlw F_SOS_L
+ movwf TBLPTRL
+
+; write message into memory, incrementing tbl pointer each time
+
+ movlw 10101000b
+ movwf TABLAT
+ tblwt*+
+
+ movlw 11101110b
+ movwf TABLAT
+ tblwt*+
+
+ movlw 11100010b
+ movwf TABLAT
+ tblwt*+
+
+ movlw 10100000b
+ movwf TABLAT
+ tblwt*+
+
+;---------------------------------------------------------------------------
+; turn LED green if we have made it this far....
+
+ call led_green
+main_loop_led
+ goto main_loop_led
+
+
+;****************************************************************************
+; INTERRUPT SUBROUTINES
+
+interrupt_low
+ goto informative_panic
+
+informative_panic
+; switch off interrupts and power
+; reconfigure timer0 for writing diagnostic msg to the LED
+
+ clrf INTCON,0 ; disable all interrupts EVER
+ bcf PORTC,1,0 ; switch off booster
+
+; re-initialise timer0 config
+ bcf T0CON,6,0 ; p107 Timer0 -> 16bit mode
+ bcf T0CON,5,0 ; timer0 use internal clock
+ bcf T0CON,3,0 ; use prescaler
+ bsf T0CON,2,0 ; }
+ bcf T0CON,1,0 ; } prescale value 1:32 (13ms x 32)
+ bcf T0CON,0,0 ; }
+
+ clrf BLANK,0
+panic_loop
+; errmsg err_SOS,RED ; transmit SOS in red
+ readout SSPCON1,RED ; transmit contents of SSPCON1 in red
+ readout BLANK,RED ; transmit blank buffer
+ goto panic_loop
+
+;****************************************************************************
+; GENERAL SUBROUTINES
+; subroutine for turning LED green
+
+led_green
+ bcf TRISD,2,0 ; make pin RD2 an output (DS100)
+ bsf LATD,2,0 ; set pin RD2 H (green)
+ return
+
+;----------------------------------------
+; wait for timer0 interrupt
+
+waiting
+ bcf INTCON,2,0 ; clear timer0 interrupt bit (p109)
+ clrf TMR0H,0 ; p107 set high bit of timer0 to 0 (buffered,
+ ; only actually set when write to tmr0l occurs)
+ clrf TMR0L,0 ; set low bit o timer0 - timer now set to 0000h
+loop
+ btfss INTCON,2,0 ; check whether timer0 interrupt has been set -
+ ; skip next instruction if so
+ bra loop
+ return
+
+
+;****************************************************************************
+ end