; Does the following things:
; includes the PIC18F458 definitions file (register and bit names)
; switches to decimal by default
-; defines various useful macros
include /usr/share/gputils/header/p18f458.inc
radix dec
+;****************************************************************************
+; 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
+
+;----------------------------------------
+; debug(BYTE)
+; writes BYTE through the serial port
+; serial port hardware must be suitably initialised
+; serial port transmit interrupts must be disabled
+; will spin until the byte is transmitted
+; Before After
+; W any undefined
+; S any undefined
+
+; macro to call subroutine to transmit over serial port for debugging
+; takes 8-bit value, puts in W, invokes debug_serial_transmit
+ ifndef SLOW_VERSION
+debug macro debugvalue
+ endm
+ endif
+
+ ifdef SLOW_VERSION
+debug macro debugvalue
+ movlw debugvalue
+ call polling_serial_transmit
+ endm
+ endif
+
+;----------------------------------------
+; debughf(REGISTER)
+; reads REGISTER once and writes it to the serial port in hex
+; for conditions etc. see "debug", above
+; Before After
+; W any undefined
+; S any undefined
+ ifdef SLOW_VERSION
+DEBUGHF_VALUE equ 0x040 ; getting on towards end of access bank
+ ; FIXME if all of program used udata that
+ ; would be very nice
+
+debughf macro register
+ movff register, DEBUGHF_VALUE
+ call debughf_subroutine
+ endm
+
+debughf_subroutine
+ call debughf_digit
+ call debughf_digit
+ return
+
+;--------------------
+debughf_digit
+; transmits top nybble of DEBUGHF_VALUE in hex
+; through serial port, as above, and swaps nybbles
+; Before After
+; W any undefined
+; DEBUGHF_VALUE BBBBaaaa aaaaBBBB (BBBB was sent)
+
+ swapf DEBUGHF_VALUE,1,0
+ movf DEBUGHF_VALUE,0,0
+ andlw 0x0f
+ sublw 10
+ sublw 0
+ bn debughf_digit_ifnot_ge10
+ addlw 'a'-('0'+10)
+debughf_digit_ifnot_ge10
+ addlw '0'+10
+ goto polling_serial_transmit
+
+ else
+debughf macro register
+ endm
+ endif
+
+
+
+;****************************************************************************
+
--- /dev/null
+ include common.inc
+
+ extern informative_panic
+
+
+;****************************************************************************
+; VECTORS: special locations, where the PIC starts executing
+; after reset and interrupts
+
+ org 0
+ goto vector_reset
+
+ org 000008h
+ goto vector_interrupt_high
+
+ org 000018h
+ goto vector_interrupt_low
+
+;****************************************************************************
+
+ code
+
+;****************************************************************************
+
+ goto informative_panic
+
+;****************************************************************************
+
+ end
+
--- /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
+
+ extern informative_panic
+
+
+;---------------------------------------------------------------------------
+; 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
+
+;****************************************************************************
+
+;----------------------------------------
+readout
+; Flashes the per-pic led red and black in a specified pattern.
+; 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_on
+readout_if_led_off
+ call led_black
+ bra readout_endif_led
+
+readout_if_led_on
+ call led_red
+readout_endif_led
+ incf WREG4,1,0 ; increment loop counter
+ call waiting
+ bra readout_loop
+
+;****************************************************************************
+
+ code
+
+;****************************************************************************
+; this is what happens when we 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
+ 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,0 ; transmit SOS in red
+ movff TESTFLASH,WREG2
+ rcall readout
+; readout BLANK,0 ; transmit blank buffer
+ call led_green
+ call waiting
+ goto panic_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
--- /dev/null
+;**********************************************************************
+; routines-led
+; subroutines for controlling the per-pic LED (pin 21, DS100)
+
+ include common.inc
+
+ global led_green
+ global led_red
+ global led_black
+
+ code
+
+;----------------------------------------
+led_red
+; makes the LED be red (or orange), no matter its previous state
+; no RAM locations used or modified
+; W is unchanged
+ bcf LATD, 2, 0 ; output low
+ bcf TRISD, 2, 0 ; output enabled
+ return
+
+;----------------------------------------
+led_green
+; makes the LED be green (or blue), no matter its previous state
+; no RAM locations used or modified
+; W is unchanged
+ bsf LATD, 2, 0 ; output high
+ bcf TRISD, 2, 0 ; output enabled
+ return
+
+;----------------------------------------
+led_black
+; makes the LED be black (off), no matter its previous state
+; no RAM locations used or modified
+; W is unchanged
+ bsf TRISD, 2, 0 ; disable flasher output
+ return
+
+ end