--- /dev/null
+; 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 common.inc
+
+ extern led_green
+ extern led_red
+ extern led_black
+
+;---------------------------------------------------------------------------
+; 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
+TESTFLASH equ 04h ; test LED flash pattern
+
+
+
+;---------------------------------------------------------------------------
+; 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
+
+err_SOS equ 0 ; msg 0 = SOS
+
+;****************************************************************************
+; VECTORS: special locations, where the PIC starts executing
+; after interrupts
+
+
+ org 0
+ goto vector_reset
+
+
+; high priority interrupt
+;
+; org 000008h
+; goto interrupt_high
+
+; low priority interrupt
+
+ org 000018h
+ goto interrupt_low
+;
+;****************************************************************************
+
+ code
+
+;****************************************************************************
+
+vector_reset
+
+; 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
+
+ movlw 10101100b
+ movwf TESTFLASH
+
+
+; 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
+ bcf T0CON,2,0 ; }
+ bsf T0CON,1,0 ; } prescale value 1:16 (13ms x 16)
+ bsf T0CON,0,0 ; }
+
+ clrf BLANK,0
+panic_loop
+; errmsg err_SOS,0 ; transmit SOS in red
+ movff TESTFLASH,WREG2
+ rcall readout
+; readout BLANK,0 ; transmit blank buffer
+ call led_green
+ call waiting
+ goto panic_loop
+
+;****************************************************************************
+; PANIC SUBROUTINES
+morsemsg
+; wrapper round readout to flash the per-pic led red&blue for an
+; 8-byte msg
+
+
+
+
+
+--------------------------
+readout
+; Flashes the per-pic led red(0) and green(1) in a specified pattern.
+; (black gap between each bit)
+; The pattern is specified as the state for 8 identically-long time
+; periods each as long as a morse `dot', encoded into a byte with
+; most significant bit first.
+; On entry On exit
+; W any undefined
+; WREG2 flash pattern preserved
+; WREG4 any undefined
+;
+ clrf WREG4,0 ; clear loop counter (WREG4)
+ rrncf WREG2,1
+
+readout_loop
+ movlw 8
+ cpfslt WREG4,0 ; if loop counter >=8, return
+ return
+
+ rlncf WREG2,1 ; top bit goes into N flag, ie Negative if 1
+ bn readout_if_led_1
+
+readout_if_led_0
+ call led_red
+ bra readout_endif_led
+
+readout_if_led_1
+ call led_green
+
+readout_endif_led
+ incf WREG4,1,0 ; increment loop counter
+ call waiting
+ call led_black
+ call waiting
+ bra readout_loop
+
+;****************************************************************************
+; GENERAL SUBROUTINES
+
+;----------------------------------------
+waiting
+; waits for a fixed interval, depending on the configuration of TMR0
+
+ bcf INTCON,2,0 ; clear timer0 interrupt bit (p109)
+ clrf TMR0H,0 ; p107 set high byte of timer0 to 0 (buffered,
+ ; only actually set when write to tmr0l occurs)
+ clrf TMR0L,0 ; set timer0 low byte - 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