From: ian Date: Sat, 7 May 2005 17:31:13 +0000 (+0000) Subject: makes ours-pindata.asm X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=37b2cd74a0e82318d14194fc6c5cd57d805f8716;p=trains.git makes ours-pindata.asm --- diff --git a/cebpic/.cvsignore b/cebpic/.cvsignore index d432d53..28b0f22 100644 --- a/cebpic/.cvsignore +++ b/cebpic/.cvsignore @@ -6,3 +6,4 @@ gpsim.log routines.lib morse-auto.asm morse-auto.inc +ours-pindata.asm diff --git a/cebpic/Makefile b/cebpic/Makefile index 3867948..bdcaf11 100644 --- a/cebpic/Makefile +++ b/cebpic/Makefile @@ -24,6 +24,9 @@ routines.lib: $(addsuffix .o, $(ROUTINES)) gplib -c $@.new $^ mv -f $@.new $@ +ours-pindata.asm: ../layout/ours-pindata.asm + cp $< $@ + morse-auto.inc morse-auto.asm: \ morse-auto.%: morse-auto.asm-gen morse-auto.messages ./$^ $* $o diff --git a/cebpic/common.inc b/cebpic/common.inc index 327f512..51b51ed 100644 --- a/cebpic/common.inc +++ b/cebpic/common.inc @@ -12,6 +12,22 @@ morse_messages_start equ 0x4000 morse_messages_end equ 0x4400 +pt_pic_data equ 0x6000 +pt_port_data equ 0x6100 +pt_bit_data equ 0x6200 + +sense_pic_data equ 0x6400 +sense_port_data equ 0x6500 +sense_bit_data equ 0x6600 + +reverse_pic_data equ 0x6800 +reverse_port_data equ 0x6900 +reverse_bit_data equ 0x6a00 + +pt_num_max equ 256 +sense_num_max equ 256 +reverse_num_max equ 256 + ;---------------------------------------- ; ifbit1(REGISTER,BITNUMBER) ; executes the next instruction but only if bit BITNUMBER diff --git a/cebpic/pindata.inc b/cebpic/pindata.inc new file mode 100644 index 0000000..8a59d20 --- /dev/null +++ b/cebpic/pindata.inc @@ -0,0 +1,43 @@ +; This .inc file is included by the autogenerated ours-pindata.asm +; and should define the things that ours-pindata.asm needs. + +; ours-pindata.asm contains data specifying which PIC pins correspond +; to which points (`pt'), section reversers (`reverse') and section +; detections (`sense'). +; +; Objects are numbered starting at 1; object number 0 is always +; unused/undefined. +; +; For each object kind KIND there are three data areas in +; to the flash program memory, starting at +; KIND_pic_data +; KIND_port_data +; KIND_pin_data +; (all of which must be defined by this file, pindata.inc, +; or something it includes - they're in common.inc at the moment). +; +; Each of these data areas is an array of bytes, one per object. The +; first byte (at KIND_pic_data) is for object no.0, the next (at +; KIND_pic_data+1) is for object no.1, etc. (Object no.0 is never +; used.) +; +; The byte values in each section are as follows: +; +; KIND_pic_data PIC number which controls this object (0 for the +; master PIC, etc.). 0xff if this object number is +; undefined/unused. The KIND_pic_data array is +; filled up to but not including KIND_pic_data + +; KIND_num_max. (KIND_num_max must be defined by +; pindata.inc ie in common.inc). +; +; KIND_port_data Low byte of address of the relevant LATx for the +; object. If the object number is unused, the +; value in flash is undefined (ie it may be +; anything). +; +; KIND_pin_data Byte with exactly one bit, being the relevant +; bit of the LATx/PORTx/TRISx. If the object +; number is unused, the value in flash is undefined +; (ie it may be anything). + + include common.inc diff --git a/layout/.cvsignore b/layout/.cvsignore index 721a4c0..82c848f 100644 --- a/layout/.cvsignore +++ b/layout/.cvsignore @@ -23,4 +23,7 @@ ours.redacted.neato.ps ours.redacted.neato ours.redacted.forsafety ours.layout-data.c +detectors.pin-info +reversers.pin-info +ours-pindata.asm *.d diff --git a/layout/Makefile b/layout/Makefile index 0e5d036..a286598 100644 --- a/layout/Makefile +++ b/layout/Makefile @@ -61,8 +61,15 @@ compose-segenco: compose-segenco.o %.redacted.forsafety: %.redactgraph ./$< $(REDACT) consistency printforforsafety $o -%.layout-data.c: data2safety %.wiring %.redacted.forsafety - ./$^ $o +%.layout-data.c: data2safety %.wiring %.redacted.forsafety \ + reversers.pin-info detectors.pin-info + ./$(filter-out %.pin-info, $^) $o + +%-pindata.asm: %.layout-data.c + @: + +%.pin-info: pin-info-gen ../pcb/%.net + ./$< $* $o %.redactgraph: %.graph.o redactgraph.o $(LINK) diff --git a/layout/data2safety b/layout/data2safety index d3b5f71..09feff8 100755 --- a/layout/data2safety +++ b/layout/data2safety @@ -2,6 +2,11 @@ use strict qw(vars); +our ($basename); +$basename= @ARGV ? $ARGV[0] : 'safety'; +die if $basename =~ m/^\-/; +$basename =~ s/\.wiring$//; + our ($mistakes, $currentline); our (%segs); @@ -23,6 +28,16 @@ our (%nodes); # $nodes{$node}[$side]{Seg} # $nodes{$node}[$side]{End} +our ($nextboardnum,@objkinds,@boardobjbase,@boardtype,%pin_used); +# @boardtype[$boardnum] +# $boardobjbase[$boardnum]{$kind} +# %pin_used{$objkind}[$objnum] = [ $boardnum, $pin_info, $objonboard ] +$nextboardnum= 0; +@objkinds= qw(pt sense reverse); +map { $boardobjbase[0]{$_}= 1; } @objkinds; + +our (%kind_count,%pin_info); # from BOARD.pin-info + our ($mode,$invertible); $mode= 'barf'; @@ -94,6 +109,23 @@ sub line_segment () { sub begin_endwiring () { } +sub begin_boards () { +} +sub line_boards () { + my ($num,$type,$k); + m/^\s+(\d+)\s+(\w+)$/ or return syntaxerror(); + ($num,$type)=($1,$2); + mistake("board $num when expected $nextboardnum") + if $num != $nextboardnum; + $nextboardnum++; + require "./$type.pin-info"; + $boardtype[$num]= $type; + foreach $k (@objkinds) { + $boardobjbase[$nextboardnum]{$k}= + $boardobjbase[$num]{$k} + $kind_count{$type}{$k}; + } +} + sub mistake ($) { my ($m) = @_; print STDERR "mistake: $m\n in $mode, \`$currentline'\n"; @@ -175,13 +207,27 @@ sub pa_boob ($) { sub so_boob ($$) { my ($k,$bo) = @_; - return sprintf "%5d /* %d.%-2d*/", $bo->[0] * 1000 + $bo->[1], - $bo->[0], $bo->[1]; + if (defined $bo) { + my ($board,$obj)= @$bo; + my ($objnum,$type,$pi); + mistake("unknown board number $board") + unless defined $boardtype[$board]; + $objnum= $boardobjbase[$board]{$k} + $obj; + $type= $boardtype[$board]; + $pi= $pin_info{$type}{$k}; + mistake("object reference $k $board.$obj out of range for". + " board type $type") + unless defined $pi->[$obj]; + $pin_used{$k}[$objnum]= [ $board, $pi->[$obj], $obj ]; + return sprintf("%4d /* %d.%-2d*/", $objnum, $board, $obj); + } else { + return " 0 /*none*/ "; + } } sub so_oboob ($$) { my ($k,$obj) = @_; - return so_boob($k,$obj->{BoOb}); + return so_boob($k, defined $obj ? $obj->{BoOb} : undef); } sub mainread () { @@ -192,7 +238,7 @@ sub mainread () { s/\s+$//; next unless m/\S/; last if m/^end$/; - if (m/^(invertible|vanilla|points|fixed|endwiring)$/) { + if (m/^(invertible|vanilla|points|fixed|endwiring|boards)$/) { $mode= $1; $invertible= ($mode eq 'invertible'); $mode= 'segment' if $mode =~ m/^(?:vanilla|invertible)$/; @@ -228,7 +274,7 @@ sub writeout () { foreach $seg (@segs) { $segr= $segs{$seg}; - o("static const SegPosCombInfo spci_${seg}[]= {"); + o("static const SegPosCombInfo spci_${seg}"."[]= {"); $delim=''; for ($comb=0; $comb < $segr->{Posns}; $comb++) { $pi=''; @@ -272,7 +318,7 @@ sub writeout () { for $pt (keys %{ $segr->{Feats} }) { $ptv= $segr->{Feats}{$pt}; next if exists $ptv->{Fixed}; - o("static const BoardObject mfbo_${seg}_${pt}[]= {"); + o("static const BoardObject mfbo_${seg}_${pt}"."[]= {"); $delim=' '; foreach $boob (@{ $ptv->{BoOb} }) { o($delim); @@ -282,7 +328,7 @@ sub writeout () { o(" };\n"); } - o("static const MovFeatInfo mfi_${seg}[]= {"); + o("static const MovFeatInfo mfi_${seg}"."[]= {"); $delim=''; for $pt (keys %{ $segr->{Feats} }) { $ptv= $segr->{Feats}{$pt}; @@ -300,15 +346,74 @@ sub writeout () { foreach $seg (@segs) { $segr= $segs{$seg}; o("$delim\n"); - o(sprintf " { %-7s %d, %2d,%-9s %3d,%-10s %-6s }", + o(sprintf " { %-7s %d, %2d,%-9s %3d,%-10s %-6s,%-6s }", "\"$seg\",", $segr->{Inv}, $segr->{FeatCount}, ($segr->{FeatCount} ? "mfi_$seg," : '0,'), $segr->{Posns}, "spci_$seg,", - so_oboob('sense',$segr), so_oboob('reverse',$segr)); + so_oboob('sense',$segr), + so_oboob('reverse', $segr->{Inv} ? $segr : undef)); $delim= ','; } o("\n};\n"); } +sub writeasm () { + my ($k,$w,$i,@d,$or,$p,$portnum,$bit,$each); + close STDOUT or die $!; + open STDOUT, ">$basename-pindata.asm" or die $!; + o("; autogenerated - do not edit\n"); + o(" include pindata.inc\n". + " radix hex\n". + "X equ 0xff\n"); + $each= 10; + for $k (@objkinds) { + for $w (qw(pic port bit)) { + @d=(); + o("\n"); + o("${k}_${w}_data_section org ${k}_${w}_data\n"); + for ($i=0; $i<@{ $pin_used{$k} }; $i++) { + $or= $pin_used{$k}[$i]; + if (defined $or) { + $or->[1] =~ m/^(\d+)\,(\w+)$/; + ($portnum,$bit)= ($1,$2); + $portnum= sprintf "%02x", $portnum + 0x89; # 89=LATA + $bit= sprintf "%02x", hex $bit; + } else { + $portnum=$bit='00'; + } + if ($w eq 'pic') { + if (defined $or) { + push @d, $or->[0]; + } else { + push @d, 'X', + } + } elsif ($w eq 'port') { + push @d, $portnum; + } elsif ($w eq 'bit') { + push @d, $bit; + } else { + die; + } + } + push @d, 'X' if @d^1; + @d= map { s/^[a-f]/0$&/; sprintf "%3s", $_ } @d; + for (;;) { + $d[$each/2] = " $d[$each/2]" if $#d >= $each/2; + last if @d <= $each; + o(" db ". join(',',@d[0..($each-1)]). "\n"); + @d= @d[$each..$#d]; + } + o(" db ".join(',',@d)."\n"); + if ($w eq 'pic') { + o(" if \$ > ${k}_pic_data + ${k}_num_max\n". + " error \"too much ${k}_picdata\"\n". + " endif\n". + " fill 0xffff, ${k}_pic_data + ${k}_num_max - \$\n"); + } + } + } + o("\n end\n"); +} mainread(); writeout(); +writeasm(); diff --git a/layout/ours.wiring b/layout/ours.wiring index b0db1e9..392199c 100644 --- a/layout/ours.wiring +++ b/layout/ours.wiring @@ -38,20 +38,4 @@ fixed A5/J0 A2/P0 -pinoutmap - # 1..20 - - - A 01 02 04 08 10 20 - E 01 02 04 - - - - - A 40 - C 01 02 04 08 - D 01 02 - # 21..40 - D 04 08 - C 10 20 40 80 - D 10 20 40 80 - - - - B 01 02 04 08 10 20 40 80 - endwiring diff --git a/layout/pin-info-gen b/layout/pin-info-gen new file mode 100755 index 0000000..e046dc4 --- /dev/null +++ b/layout/pin-info-gen @@ -0,0 +1,71 @@ +#!/usr/bin/perl +# usage: +# pinout-gen BOARDNAME + +use IO::Handle; + +@ARGV==1 or die $!; +$board= shift @ARGV; + +$cpin=1; $_=''; +for (;;) { + if (!length) { $_= ; last unless length; $_.=' '; s/^\s+//; } + if (m/^\#/) { + $_=''; + } elsif (s/^\-\s+//) { + $cpin++; + } elsif (s/^[ABCDE]\s+//) { + $port= ord($&) - ord('A'); + } elsif (s/^([0-9a-f][0-9a-f])\s+//) { + die unless defined $port; + $pins[$cpin++]= "$port,0x$1"; + } else { + die "$_ ?"; + } +} +die unless $cpin==41; + +print "our (\%pin_info,\%kind_count);\n" + or die $!; + +$kinds= 'pt|sense|reverse'; + +open B, "../pcb/$board.net" or die $!; +while () { + if (s/\\$//) { $_.= ; } + m/^(\w+)\s+[A-Z]\w+\s+([-_A-Z0-9 \t]+)$/; + $net= $1; $pins= $2; $pin= undef; + map { $pin=$1 if m/PIC-(\d+)/; } split /\s+/, $pins; + next unless defined $pin; + next unless $net =~ m/^(?:.*__)?($kinds)(\d+)(?:__.*)?$/; + $kind= $1; $num= $2; + die "$pin $kind $num ?" unless defined $pins[$pin]; + print "\$pin_info{'$board'}{'$kind'}[$num]= '$pins[$pin]';\n" + or die $!; + $count{$kind}= $num+1 if $num>=$count{$kind}; +} +B->error and die $!; + +for $kind (split /\|/, $kinds) { + printf("\$kind_count{'%s'}{'%s'}= %d;\n", + $board, $kind, $count{$kind}) + or die $!; +} +print "1;\n" + or die $!; + +__DATA__ +# 1..20 +- +A 01 02 04 08 10 20 +E 01 02 04 +- - - +A 40 +C 01 02 04 08 +D 01 02 +# 21..40 +D 04 08 +C 10 20 40 80 +D 10 20 40 80 +- - +B 01 02 04 08 10 20 40 80