CEBPIC= ./
-PICNOS= 0 1 3
+PICNOS= 0 1 2
PROGRAMS= led-flash send-serial panic reply-serial \
nmra-stream nmra-stream,slow
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
#!/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 (<W>) {
+ 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;
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"
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 $< $@
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
*.hex
*.lst
*.map
+variables+*.fin
+variables+*.inc
.submakefile
blank[0246].asm
gpsim.log
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
panic.inc \
routines-led.fin \
../iwjpictest/clockvaries.inc \
- vectors.fin
+ vectors.fin \
+ detect.inc
+
+VARSFILES= variables
include $(CEBPIC)manypics.make
-; 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
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
-;****************************************************************************
+;----------------------------------------------------------------------
+;======================================================================
+; 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
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
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
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
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
call i2cs_read_data
- mov_lfsr outgoing_buffer, 2
+ mov_lfsr outbuf, 2
bra both_startread_tail
+;======================================================================
+ include final.inc
+
;****************************************************************************
; return
; will need to use external i2c send function/buffers, maybe?
-
-
-
-
-
-
-
-
-
-
-;****************************************************************************
-
-vector_reset
- goto informative_panic
-
-;****************************************************************************
-
- end
-
--- /dev/null
+ extern det_slave_setup
+ extern det_scanloop_reversers
+ extern det_scanloop_detectors
+ extern det_read_start_reversers
+ extern det_read_start_detectors
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
clr_f SSPCON2 ; nothing going
mov_lw 0x80 ; SMP(noslew), !CKE(!smbus)
mov_wf SSPSTAT
+ bc_f IPR1, SSPIP ; low priority
bra init_enable
;----------
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):
; SSPSTAT configured correctly unchanged, except:
; SSPSTAT<SSPEN> 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)
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
;----------
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
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
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
bc_f st, st_awaiting
bs_f st, st_reading
s_event_reading_datanack
- return
+ retfie_r
;========================================
; SLAVE - WRITING
; i2c controller waiting due to SEN etc continuing with next byte
mov_fw SSPBUF
bs_f SSPCON1, CKP
- return
+ retfie_r
;----------
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
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
+
;======================================================================
; 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
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
;======================================================================
; 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
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
extern read_pic_no
+ extern init_read_idlocs
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
--- /dev/null
+;======================================================================
+;
+; 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<<GIEH) | (1<<GIEL)
+ mov_wf INTCON
+
+ bt_f_if1 idloc1,idloc1_boarddet
+ goto det_scanloop_detectors
+ goto det_scanloop_reversers
+
+;----------
+i2csu_write_begin
+i2csu_write_another
+ goto led_black
+
+;----------
+i2csu_read_done
+i2csu_write_done
+ return ; fixme make it not call these any more
+
+;----------
+slave_interrupt_low
+ panic morse_IP
+
+ include final.inc
t res 1
ch res 1
-picno res 1
delay_countfast res 1
delay_countmedium res 1
clr_f INTCON
bs_f RCON, IPEN ; interrupt priorities
- call read_pic_no
- mov_wf picno
- bra_z master
+ call init_read_idlocs
+ tst_f_ifnz picno
goto slave
+ bra master
;----------
-vector_interrupt_low
- tst_f_ifnz picno
- bra s_vector_interrupt
- ; Master:
+master_interrupt_low
call i2cm_interrupt
call serial_interrupt
retfie_r
-s_vector_interrupt
- call i2cs_interrupt
- retfie_r
-
;----------
-vector_interrupt_high
+master_interrupt_high
panic morse_IP
;----------------------------------------------------------------------
mov_fw POSTINC2
return
-;----------------------------------------------------------------------
-; SLAVE
-; buffer is at 0x300..0x307
-; FSR0 is write pointer
-; FSR1 is read pointer
-s_bufbit equ 3 ; ln2(buffer size)
-
-slave
- mov_fw picno
- mov_wf t
-
-s_shownum_loop
- call s_delay
- call led_red
- call s_delay
- call led_black
-
- dec_f_ifnz t
- bra s_shownum_loop
- ; OK:
-
- rcall s_buffer_erase
-
- mov_fw picno
- call i2cs_init
- mov_lw (1<<GIEH) | (1<<GIEL)
- mov_wf INTCON
-
-s_infinite
- bra s_infinite
-
-;----------
-i2csu_write_begin
- rcall led_red
-i2csu_write_another
- mov_wf t
-
- mov_fw t
- xor_lw '<'
- bra_z s_buffer_reset
-
- mov_fw t
- xor_lw '!'
- bra_z s_buffer_erase
-
- mov_fw t
- xor_lw '#'
- bra_z s_panic_req
-
- mov_fw t
- mov_wf POSTINC0
- bc_f FSR0L, s_bufbit
- return
-
-;----------
-i2csu_write_done
- mov_lw '$'
- mov_wf INDF0
-i2csu_read_done
- bra led_black
-
-;----------
-i2csu_read_begin
- rcall led_green
-i2csu_read_another
- mov_fw POSTINC1
- bc_f FSR1L, s_bufbit
- goto i2cs_read_data
-
-;----------
-s_buffer_erase
- mov_lfsr 0x300, 0
- mov_lw '0'
-
-;----------
-s_buffer_erase_loop
- mov_wf POSTINC0
- inc_w
- bt_w_if0 s_bufbit
- bra s_buffer_erase_loop
-
-;----------
-s_buffer_reset
- mov_lfsr 0x300, 0
- mov_lfsr 0x300, 1
- return
-
-;----------
-s_panic_req
- clr_f ch
- panic morse_X
-
;======================================================================
m_delay4 rcall m_delay2
--- /dev/null
+;======================================================================
+
+ udata_acs
+picno res 1 ; from first idlocs byte
+idloc1 res 1 ; from 2nd idlocs byte; bit 7 is master:
+idloc1_master equ 7
+idloc1_boarddet equ 6
+
+ udata 0x200
+outbuf_szln2 equ 7
+outbuf_size equ (1<<outbuf_szln2)
+outbuf res outbuf_size
+
+ include final.inc
+
+;======================================================================
; VECTORS: special locations, where the PIC starts executing
; after reset and interrupts
+ include common.inc
+
+;----------
+; reset vector
org 0
goto vector_reset
+;----------
+; high priority interrupt
org 000008h
- goto vector_interrupt_high
+ bt_f_if0 idloc1,idloc1_master
+ goto i2cs_interrupt
+ goto master_interrupt_high
+
+;----------
+; low priority interrupt
org 000018h
- goto vector_interrupt_low
+ bt_f_if1 idloc1,idloc1_master
+ goto master_interrupt_low
+ goto slave_interrupt_low
+
+;======================================================================
- include vectors.fin
- end
+ include final.inc
extern vector_reset
- extern vector_interrupt_low
- extern vector_interrupt_high
+ extern master_interrupt_low
+ extern master_interrupt_high
+ extern slave_interrupt_low