From: ian Date: Wed, 30 Nov 2005 21:10:37 +0000 (+0000) Subject: first cut of detection on slaves X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=8a7afbb3c3635d56b796c7442b6f04bda256fff4;p=trains.git first cut of detection on slaves --- diff --git a/cebpic/Makefile b/cebpic/Makefile index 0002a2a..55d481a 100644 --- a/cebpic/Makefile +++ b/cebpic/Makefile @@ -1,6 +1,6 @@ CEBPIC= ./ -PICNOS= 0 1 3 +PICNOS= 0 1 2 PROGRAMS= led-flash send-serial panic reply-serial \ nmra-stream nmra-stream,slow diff --git a/cebpic/README.protocol b/cebpic/README.protocol index 86204e4..1b91e3c 100644 --- a/cebpic/README.protocol +++ b/cebpic/README.protocol @@ -262,7 +262,8 @@ Program memory map (for PIC18F458) looks like this: 0x20 0001 bit 7 = 1 for the main PIC (#0) 0 otherwise - bits 0-6 = currently unused, set to 0 + bit 6 = 1 for Reversers board, 0 for Detectors + bits 0-5 = currently unused, set to 0 0x20 0002- } not currently used, 0x20 0007 } may contain anything diff --git a/cebpic/make-idlocs b/cebpic/make-idlocs index fba3a35..6119f95 100755 --- a/cebpic/make-idlocs +++ b/cebpic/make-idlocs @@ -1,16 +1,37 @@ #!/usr/bin/perl -@ARGV==1 or die; -$_=shift @ARGV; +@ARGV==2 or die; +($wiring,$_) = @ARGV; + m/^\d+$/ or die; $_<32 or die; +$picno= $_; # @a is the ID locations, one byte per array entry, # with $a[0] being the first ID location (ie 0x200000). # Values must be in hex (or otherwise suitable for the assembler). -$a[0]= sprintf "0x%02x", $_; -$a[1]= $_ ? '0x00' : '0x80'; +$a[0]= $picno; +$a[1]= 0; + +$a[1] |= 0x80 if $picno; + +open W, "< $wiring" or die "$wiring: $!"; +while () { + next if m/^\s*\#/; + next unless m/^boards\s+$/...(!m/\S/ || m/^\S/); + next if !m/\S/ || m/^\S/; + die unless m/^\s+(\d+)\s+(\w+)\s*$/; + next unless $1 == $picno; + $board= $2; +} +close W; +die $picno unless defined $board; +die $board unless $board =~ m/^(?:reversers|detectors)$/; + +$a[1] |= 0x40 if $board eq 'detectors'; + +@a= map { sprintf "0x%02x", $_; } @a; printf "; automatically generated - do not edit\n" or die $!; for ($i= 0x200000; diff --git a/cebpic/manypics.make b/cebpic/manypics.make index ce76b8e..1c647eb 100644 --- a/cebpic/manypics.make +++ b/cebpic/manypics.make @@ -43,6 +43,9 @@ ifneq ($(MAKECMDGOALS),clean) include .submakefile endif +INCLUDES += $(addsuffix +vars.fin, $(VARSFILES)) +INCLUDES += $(addsuffix +vars.inc, $(VARSFILES)) + blank0.asm blank2.asm blank4.asm blank6.asm: blank%.asm: $(CEBPIC)manypics.make echo >$@.new " org 0x$*000" echo >>$@.new " nop" @@ -69,14 +72,29 @@ noncode%.hex: idlocs%.hex config.hex morse+auto.inc: $(CEBPIC)morse-generator morse.messages ./$^ inc $o +%+vars.inc: %.asm $(CEBPIC)manypics.make + perl -ne ' \ + BEGIN { print "; autogenerated - do not edit\n"; } \ + next unless m/^\w+\s+equ\s+/; \ + print $$_ or die $$!; \ + ' <$< $o + +%+vars.fin: %.asm $(CEBPIC)manypics.make + perl -ne ' \ + BEGIN { print "; autogenerated - do not edit\n"; } \ + next unless m/^(\w+)\s/; \ + next if m/^\w+\s+equ\s+/; \ + print " extern $$1\n" or die $$!; \ + ' <$< $o + %+morse.asm: $(CEBPIC)morse-generator morse.messages %+program.map ./$^ asm -I$(MORSE_INCLUDE) $o %.map: %.hex @: -idlocs%.asm: $(CEBPIC)make-idlocs - ./$< $* >$@.new && mv -f $@.new $@ +idlocs%.asm: $(CEBPIC)make-idlocs ../layout/ours.wiring + ./$^ $* >$@.new && mv -f $@.new $@ ours-pindata.asm: ../layout/ours-pindata.asm cp $< $@ @@ -85,3 +103,4 @@ manypic-clean: pic-clean rm -f idlocs*.asm *+morse.* morse+auto.inc blank[0246].* .PRECIOUS: idlocs%.asm morse+auto.inc %+morse.asm %+morse.hex %.map +.PRECIOUS: %+vars.inc %+vars.fin diff --git a/detpic/.cvsignore b/detpic/.cvsignore index 043209e..40a7350 100644 --- a/detpic/.cvsignore +++ b/detpic/.cvsignore @@ -3,6 +3,8 @@ *.hex *.lst *.map +variables+*.fin +variables+*.inc .submakefile blank[0246].asm gpsim.log diff --git a/detpic/Makefile b/detpic/Makefile index 87d29ac..2e5ee63 100644 --- a/detpic/Makefile +++ b/detpic/Makefile @@ -3,7 +3,8 @@ CEBPIC= ../cebpic/ PICNOS= 0 1 2 PROGRAMS= test-sofar -OBJS_test-sofar= vectors.o panic.o routines-led.o i2clib.o misc.o +OBJS_test-sofar= vectors.o panic.o routines-led.o i2clib.o \ + misc.o slave.o detect.o variables.o XCODEN_test-sofar= morse XCODE1_test-sofar= blank2 blank6 @@ -15,7 +16,10 @@ INCLUDES= common.inc \ panic.inc \ routines-led.fin \ ../iwjpictest/clockvaries.inc \ - vectors.fin + vectors.fin \ + detect.inc + +VARSFILES= variables include $(CEBPIC)manypics.make diff --git a/detpic/common.inc b/detpic/common.inc index 1796daf..24a6ee2 100644 --- a/detpic/common.inc +++ b/detpic/common.inc @@ -1,9 +1,10 @@ -; common macros & equs etc. - -;********************************************************************** +;====================================================================== ; common.inc -; Generally include this at the top of each file. +; common macros & equs etc. +; generally include this at the top of each file. +;---------------------------------------------------------------------- +; COMMON INCLUDES and BOILERPLATE include /usr/share/gputils/header/p18f458.inc radix dec include panic.inc @@ -11,11 +12,12 @@ include ../iwjpictest/insn-aliases.inc clock equ -1 include ../iwjpictest/clockvaries.inc + include variables+vars.inc -;**************************************************************************** +;---------------------------------------------------------------------- ; MACROS ; debug* and ifbit[01] were here but they're cruft, really, ; so I have removed them -iwj -;**************************************************************************** +;---------------------------------------------------------------------- diff --git a/detpic/detect.asm b/detpic/detect.asm index f4c4ddc..4a4582d 100644 --- a/detpic/detect.asm +++ b/detpic/detect.asm @@ -1,41 +1,102 @@ +;====================================================================== +; DETECTION - -; FSR2 is used as outgoing message buffer pointer (reading), -; ie private to this file -; ; FSR1 is used as pointer to where to add bytes of message; it ; points to previous byte whose top bit must be set before ; adding another bit +; FSR2 is used as readout pointer + + include common.inc + +;====================================================================== +; variables and memory organisation + max_messages equ 4 udata_acs - scana res 1 - scanb res 1 - scanc res 1 - scand res 1 - scane res 1 - buf0 res 1 - message_buffer res max_messages - udata - outgoing_buffer res max_messages+2 +unattended res 1 ; counts down once for each det loop + ; and if it reaches 0, led is set to red + +scana res 1 ; see bit-twiddling below +scanb res 1 +scanc res 1 +scand res 1 +scane res 1 + +last1 res 1 +last2 res 1 + +buf0 res 1 +message_buffer res max_messages +message_buffer_end + +;---------------------------------------------------------------------- +; buf0, message_buffer, and FSR1 look like this: +; +; +--------+--------+--------+--------+--------+ +; | buf0 | message_buffer... | +; +--------+--------+--------+--------+--------+ +; +; |0d0d0000|???????? ???????? ???????? ????????| no extra messages +; ^ +; |1d0d0000|0aaaaaaa ???????? ???????? ????????| one extra byte +; ^ +; |1d0d0000|1aaaaaaa 0bbbbbbb ???????? ????????| two extra bytes +; +; etc. (bits labelled `d' are detection data on reversers boards +; 0 on detectors boards; `a' and `b' are extra message data; +; `^' indicates the byte pointed to by FSR1) +; +;====================================================================== code +;---------- +det_slave_setup + clr_f scana + clr_f scanb + clr_f scanc + clr_f scand + clr_f scane + goto reset_message_buffer + +;---------- slave_add_short_message ; W message unchanged - bc_f INTCON*,GIEH fixme check this works +; GIEH set set + bc_f INTCON,GIEH bs_f POSTINC1,7 mov_wf INDF1 - bs_f INTCON*,GIEH + bs_f INTCON,GIEH return +;---------- +i2csu_read_begin + bt_f_if1 idloc1,idloc1_boarddet + bra det_slave_read_start_detectors + bra det_slave_read_start_reversers -init - set fsr2 - set fsr1 - ram locations see above +;---------- +i2csu_read_another + mov_fw POSTINC2 + call i2cs_read_data + bt_f_if0 FSR2L, outbuf_szln2 + return + ; oops + panic morse_DR + +;---------- +det_scanloop_again macro det_scanloop_whatever + dec_f_ifnz unattended + bra det_scanloop_whatever + call led_red + bra det_scanloop_whatever + endm + +;====================================================================== +; main detection bit-twiddling ; 80 40 20 10 08 04 02 01 ; 7 6 5 4 3 2 1 0 @@ -72,11 +133,11 @@ det_scanloop_detectors mov_fw PORTC ; W xx xx 05 xx xx 10 13 16 (now) ior_wff scanc ; c xx xx 05 xx xx 10 13 16 (cumulative) - - bra det_scanloop_detectors + + det_scanloop_again det_scanloop_detectors ;---------- ; buf0 MM zz zz zz zz zz zz zz -det_read_start_detectors +det_slave_read_start_detectors ; detection byte 1 mov_lw 0xf8 ; W yy yy yy yy yy zz zz zz and_wff scana ; scana 19 09 12 15 18 zz zz zz @@ -86,29 +147,29 @@ det_read_start_detectors ior_wff scana ; scana 19 09 12 15 18 04 20 17 mov_fw scana - cmp_wf_ifne last1 + cmp_fw_ifne last1 bs_f buf0,4 ; buf0 MM zz zz B1 zz zz zz zz ; detection byte 2 mov_lw 0x83 ; W yy zz zz zz zz zz yy yy and_wff scane ; scane 06 zz zz zz zz zz 03 00 - rlc_wf scand ; W xx 01 07 02 11 14 xx xx C=08 + rlc_fw scand ; W xx 01 07 02 11 14 xx xx C=08 and_lw 0x7c ; W zz 01 07 02 11 14 zz zz C=08 ior_wff scane ; scane 06 01 07 02 11 14 03 00 C=08 mov_fw scane - cmp_wf_ifne last2 + cmp_fw_ifne last2 bs_f buf0,5 ; buf0 MM zz B2 B1 zz zz zz zz ; detection and lead byte, 0 - rlc_wf scanc ; W xx 05 xx xx 10 13 16 08 + rlc_fw scanc ; W xx 05 xx xx 10 13 16 08 and_lw 0x4f ; W zz 05 zz zz 10 13 16 08 ior_wfw buf0 ; W MM 05 B2 B1 10 13 16 08 call i2cs_read_data - mov_lfsr outgoing_buffer, 2 + mov_lfsr outbuf, 2 mov_fw scana bt_f_if1 buf0,5 @@ -132,12 +193,17 @@ both_startread_tail clr_f scana clr_f scand + call led_green + set_f unattended + mov_lfsr message_buffer, 1 msg_copy_loop mov_fw POSTINC1 mov_wf POSTINC2 bra_n msg_copy_loop +reset_message_buffer +; FSR1/buf0/message_buffer any set to empty mov_lfsr message_buffer, 1 clr_f buf0 clr_f INDF1 @@ -159,10 +225,10 @@ det_scanloop_reversers bs_f buf0,2 ; buf0 MM zz zz ss zz 00 zz zz (cumulative) bt_f_if1 PORTE,2 ; 02 (now) bs_f buf0,4 ; buf0 MM zz zz 02 zz ss zz zz (cumulative) - bra det_scanloop_reversers + det_scanloop_again det_scanloop_reversers ;---------- ; buf0 MM zz zz 02 zz 00 zz zz -det_read_start_reversers +det_slave_read_start_reversers mov_wf scana ; W xx xx 01 xx 03 xx xx xx and_lw 0x28 ; W zz zz 01 zz 03 zz zz zz ior_wff buf0 ; buf0 MM zz 01 02 03 00 zz zz @@ -173,10 +239,13 @@ det_read_start_reversers call i2cs_read_data - mov_lfsr outgoing_buffer, 2 + mov_lfsr outbuf, 2 bra both_startread_tail +;====================================================================== + include final.inc + ;**************************************************************************** @@ -276,22 +345,3 @@ det_read_start_reversers ; return ; will need to use external i2c send function/buffers, maybe? - - - - - - - - - - -;**************************************************************************** - -vector_reset - goto informative_panic - -;**************************************************************************** - - end - diff --git a/detpic/detect.inc b/detpic/detect.inc new file mode 100644 index 0000000..db1511b --- /dev/null +++ b/detpic/detect.inc @@ -0,0 +1,5 @@ + extern det_slave_setup + extern det_scanloop_reversers + extern det_scanloop_detectors + extern det_read_start_reversers + extern det_read_start_detectors diff --git a/detpic/final.inc b/detpic/final.inc index 93d4721..d39f8ac 100644 --- a/detpic/final.inc +++ b/detpic/final.inc @@ -1,9 +1,13 @@ extern serial_write_char + extern slave + include vectors.fin include i2clib.inc include panic.fin include routines-led.fin include misc.fin + include variables+vars.fin + include detect.inc end diff --git a/detpic/i2clib.asm b/detpic/i2clib.asm index 6f4b037..7467232 100644 --- a/detpic/i2clib.asm +++ b/detpic/i2clib.asm @@ -107,6 +107,7 @@ i2cm_init clr_f SSPCON2 ; nothing going mov_lw 0x80 ; SMP(noslew), !CKE(!smbus) mov_wf SSPSTAT + bc_f IPR1, SSPIP ; low priority bra init_enable ;---------- @@ -383,6 +384,7 @@ i2cs_init mov_wf SSPCON2 mov_lw 0x80 ; SMP(noslew), !CKE(!smbus) mov_wf SSPSTAT + bs_f IPR1, SSPIP ; high priority init_enable ; Actually engages the I2C controller, which must already have ; been set up (all but SSPEN): @@ -390,6 +392,7 @@ init_enable ; SSPSTAT configured correctly unchanged, except: ; SSPSTAT 0 (disabled) 1 (enabled) ; SSPIE 0 (disabled) 1 (enabled) +; SSPIF configured correctly unchanged ; TRISB<1,0> any configured for I2C ; SSPIP any configured correctly ; GIEL 0 (disabled) 0 (disabled) @@ -400,7 +403,6 @@ init_enable set_f st_orig bs_f TRISB, 0 bs_f TRISB, 1 - bc_f IPR1, SSPIP bs_f SSPCON1, SSPEN bs_f PIE1, SSPIE return @@ -435,7 +437,7 @@ chkvals_addrrecv_lastval equ 0x89 ;---------- i2cs_interrupt ; 4cy interrupt latency + 3cy until branch to here bt_f_if0 PIR1, SSPIF - return + bra s_event_bad_intr ; We have an interrupt: ; Firstly, clear the interrupt flag so that if something else happens @@ -461,13 +463,17 @@ s_event_idle s_event_bad panic morse_SS ; slave, interrupt, controller in bad state +s_event_bad_intr + panic morse_IH ; unknown high-priority interrupt + ;======================================== ; SLAVE - READING ;---------- s_event_idle_addrrecvread bs_f st, st_awaiting - goto i2csu_read_begin ; 26cy until 1st insn of read_begin + call i2csu_read_begin ; 26cy until 1st insn of read_begin + retfie_r ;---------- s_event_reading @@ -476,8 +482,9 @@ s_event_reading mov_fw SSPSTAT xor_lw 0xac ; D,!P, S,R,!BF bra_nz s_event_reading_not_another - goto i2csu_read_another + call i2csu_read_another ; 24cy until 1st insn of i2csu_read_another + retfie_r ;... s_event_reading_not_another @@ -504,7 +511,7 @@ i2cs_read_data bc_f st, st_awaiting bs_f st, st_reading s_event_reading_datanack - return + retfie_r ;======================================== ; SLAVE - WRITING @@ -520,7 +527,7 @@ s_write_slurpbyte ; i2c controller waiting due to SEN etc continuing with next byte mov_fw SSPBUF bs_f SSPCON1, CKP - return + retfie_r ;---------- s_event_writing @@ -546,7 +553,7 @@ s_event_writing and_lw 0xc7 ; ?D_A, ?P; ?S xor_lw 0x80 ; SMP, !CKE, !R_W, !UA, !BF bt_f_if1 STATUS, Z - return + retfie_r ; no good bra s_event_bad @@ -556,11 +563,16 @@ s_event_writing_datarecv rcall s_write_slurpbyte bt_f_if1 st, st_subsequent - goto i2csu_write_another - ; not subsequent (yet): + bra s_event_writing_datarecv_subsequent bs_f st, st_subsequent - goto i2csu_write_begin + call i2csu_write_begin + retfie_r + +s_event_writing_datarecv_subsequent + rcall i2csu_write_another + retfie_r + ;====================================================================== diff --git a/detpic/i2clib.inc b/detpic/i2clib.inc index 8d0c1dd..6bcfd73 100644 --- a/detpic/i2clib.inc +++ b/detpic/i2clib.inc @@ -44,8 +44,9 @@ ; and State allows. ; All routines except i2c?_init must be called only: -; * During a low-priority interrupt; -; * From the main loop with low-priority interrupts disabled; or +; * During an appropriate interrupt (high-priority for the slave; +; low-priority for the master). +; * From the main loop with those interrupts disabled; or ; * From within an i2c?u_... routine (which are always called ; from within i2c?_interrupt). ; This is to avoid having one i2c_... routine running in an interrupt @@ -85,12 +86,19 @@ extern i2cm_interrupt extern i2cs_interrupt ; -; Must be called by the main program's low priority interrupt handler. -; The main program's interrupt handler is responsible for saving W and -; the flags register and other interrupt-related administrivia. If -; there is an i2c interrupt, this routine will service it, taking any -; necessary action including calling appropriate i2c?u_... routines, -; and clear the interrupt flag[*]. +; Must be called by the main program's interrupt handler; +; high-priority for the slave or low-priority for the master. +; +; For i2cm_interrupt, the main program's interrupt handler is +; responsible for saving W and the flags register and other +; interrupt-related administrivia. For i2cs_interrupt, it must +; be the only high-priority interrupt source and expects to +; be vectored to directly from the interrupt handler (and it +; will retfie_r). +; +; If there is an i2c interrupt, the i2c?_interrupt will service it, taking +; any necessary action including calling appropriate +; i2c?u_... routines, and clear the interrupt flag[*]. ; ; At call On return ; State any except Not-in-use may change diff --git a/detpic/misc.asm b/detpic/misc.asm index 510ea48..132c569 100644 --- a/detpic/misc.asm +++ b/detpic/misc.asm @@ -1,15 +1,15 @@ ;====================================================================== ; GENERALLY USEFUL ROUTINES - include /usr/share/gputils/header/p18f458.inc - include ../iwjpictest/insn-aliases.inc - radix dec + include common.inc code read_pic_no +; read pic no from ID locations and return it ; W undefined pic number from ID loc 0 ; status Z undefined 1 iff master PIC - ; read pic no from ID locations +; TBLPTR* undefined points to 20001 + mov_lw 0x20 mov_wf TBLPTRU clr_f TBLPTRH @@ -18,8 +18,22 @@ read_pic_no tblrd *+ dw 0xffff ; silicon errata: B4 issue 4 mov_fw TABLAT + return + +init_read_idlocs +; read id locations and store in canonical place +; W undefined undefined +; picno undefined pic number (from 20000) +; idloc1 undefined idloc1 (from 20001) + + rcall read_pic_no + mov_wf picno + + tblrd *+ + dw 0xffff + mov_fw TABLAT + mov_wf idloc1 return - include misc.fin - end + include final.inc diff --git a/detpic/misc.fin b/detpic/misc.fin index 1047d00..b4da5ee 100644 --- a/detpic/misc.fin +++ b/detpic/misc.fin @@ -1 +1,2 @@ extern read_pic_no + extern init_read_idlocs diff --git a/detpic/morse.messages b/detpic/morse.messages index 7dd4d33..3b207a5 100644 --- a/detpic/morse.messages +++ b/detpic/morse.messages @@ -43,3 +43,7 @@ SF i2clib:st ; improper i2cmu_write_next_byte Z SR i2clib:st ; improper i2cm_read_start SA i2clib:st ; improper i2cm_read_another SD i2clib:st ; impr. i2cm_read_done/i2cs_read_data + +# Messages for slave/detection +DW ; slave write (nyi) +DR ; slave read overrun diff --git a/detpic/slave.asm b/detpic/slave.asm new file mode 100644 index 0000000..a69174b --- /dev/null +++ b/detpic/slave.asm @@ -0,0 +1,41 @@ +;====================================================================== +; +; On slave, FSR1 and FSR2 is reserved for i2c/detection routine +; and may not be touched by anything else. + + include common.inc + code + +;---------- +; Program to implement the slave. Does not return. Conditions on entry: +; interrupts INTCON set up but interrupts disabled +; i2c controller not set up / not enabled +; picno, idloc1 containing correct values read from flash + +slave + call det_slave_setup + + mov_fw picno + call i2cs_init + mov_lw (1<