From: ceb Date: Sun, 17 Apr 2005 21:14:02 +0000 (+0000) Subject: morsepanic - small changes from panic so far, X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=10a99982f4ab22522a10b7c3052de04b2873aeb0;p=trains.git morsepanic - small changes from panic so far, flashes red+green rather than just red --- diff --git a/cebpic/morsepanic.asm b/cebpic/morsepanic.asm new file mode 100644 index 0000000..d878a7d --- /dev/null +++ b/cebpic/morsepanic.asm @@ -0,0 +1,239 @@ +; 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