From: ian Date: Mon, 19 Dec 2005 02:46:57 +0000 (+0000) Subject: new make-clocks program and some initial work for it X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=2c39bb9ef7fa97d4813c8aeb3bdec8817d0aa634;p=trains.git new make-clocks program and some initial work for it --- diff --git a/detpic/.cvsignore b/detpic/.cvsignore index fa24f63..f9c4ae6 100644 --- a/detpic/.cvsignore +++ b/detpic/.cvsignore @@ -1,4 +1,5 @@ *+morse.asm +*+clocks.inc *.cod *.hex *.lst diff --git a/detpic/make-clocks b/detpic/make-clocks new file mode 100755 index 0000000..a121e62 --- /dev/null +++ b/detpic/make-clocks @@ -0,0 +1,109 @@ +#!/usr/bin/perl -w + +use strict qw(vars); +use POSIX; + +our ($name,$ms,$interval,$msclock); +# $interval is in seconds +# mclock or sclock is in kHz +# ourtimerclock is mclock or sclock * 250 (for Fosc/4) +# call 250 foscscale +# basically interval = cycles / clock +# adjusted for units interval = cycles * prescale / (foscscale * msclock) +# ie cycles = interval * foscscale * msclock / prescale +# or msclock = cycles * prescale / (foscscale * interval) + +sub p ($) { print $_[0] or die $!; } + +sub scaleable ($$$$$) { + my ($width, $foscscale, $scalebitnums, $scales, $deadcycles) = @_; + my ($maxcycles, $scalespec, $scalebits, $maxmsclock); + my ($lastmaxmsclock, $cycles_per_msclock, $cyclesexpr, @scalebits); + my ($prescale, $shift); + $maxcycles = (1 << $width) - $deadcycles; + foreach $scalespec (@$scales) { + $scalespec =~ m/^(\d+)\:([01]+)$/; + ($prescale,$scalebits) = ($1,$2); + length($scalebits) == @$scalebitnums + or die "$scalespec @$scalebitnums"; + $maxmsclock= floor($maxcycles * $prescale / ($foscscale * $interval)); + p(" if"); + p(" $msclock > $lastmaxmsclock &&") if defined $lastmaxmsclock; + p(" $msclock <= $maxmsclock\n"); + if (length($scalebits)) { + p("${name}scale equ "); + @scalebits = (map { "(1<<$_)" } + grep { $scalebits =~ s/^.// or die; $&; } + @$scalebitnums); + push @scalebits, '0' unless @scalebits; + p(join '|', @scalebits); + p("; $prescale:1\n"); + } + $cycles_per_msclock = $interval * $foscscale / $prescale; + $shift = 31 - ceil(log($maxmsclock * $cycles_per_msclock) / log(2.0)); + p(sprintf "%scycles equ (%s * %d) >> %d\n", + $name, $msclock, $cycles_per_msclock * (1<<$shift), $shift); + $cyclesexpr= sprintf("(%d - %scycles)", + (1<<$width) - $deadcycles, $name); + if ($width == 16) { + p("${name}inith equ $cyclesexpr / 256\n"); + p("${name}initl equ $cyclesexpr & 255\n"); + } elsif ($width == 8) { + p("${name}init equ $cyclesexpr\n"); + } else { + die "$width"; + } + p(" endif\n"); + $lastmaxmsclock= $maxmsclock; + } + p(" if $msclock > $lastmaxmsclock\n"); + p(" error \"clock speed too high for $name\"\n"); + p(" endif\n"); +} + +sub do_T13ov ($) { + my ($n) = @_; + local ($name) = "${name}_t${n}"; + scaleable(16, 250.0, ["T${n}CKPS1","T${n}CKPS0"], + [qw(1:00 2:01 4:10 8:11)], 1); +} + +sub do_T0ov ($) { + my ($w) = @_; + local ($name) = "${name}_t0"; + scaleable($w, 250.0, ["PSA","T0PS2","T0PS1","T0PS0"], + [qw(1:1000 2:0000 4:0001 8:0010 16:0011 + 32:0100 64:0101 128:0110 256:0111)], 1); +} + +sub do_T0ov8 { do_T0ov(8); } +sub do_T0ov16 { do_T0ov(16); } +sub do_T1ov { do_T13ov(1); } +sub do_T3ov { do_T13ov(3); } + +sub doline () { + my ($orgname,$mswant,$unit,$how); + chomp; + s/[;\#].*//; + return unless m/^\S/; + die "$_ ?" unless + m/^(\w+)\s+(M|S|MS)\s+(\w+)\s+([0-9.]+)(s|ms|us|ns|Hz|kHz|MHz)$/; + ($orgname,$mswant,$how,$interval,$unit) = ($1,$2,$3,$4,$5); + if ($unit =~ m/M/) { $interval *= 1.e6; } + if ($unit =~ m/k/) { $interval *= 1.e3; } + if ($unit =~ m/m/) { $interval *= 1.e-3; } + if ($unit =~ m/u/) { $interval *= 1.e-6; } + if ($unit =~ m/n/) { $interval *= 1.e-9; } + if ($unit =~ s/Hz//) { $interval = 1.0 / $interval; } + foreach $ms (qw(m s)) { + next unless $mswant =~ m/$ms/i; + $msclock= "${ms}clock"; + $name = $orgname.'_'.($ms eq 'm' ? 'master' : 'slave'); + p(";---------- $name ----------\n"); + &{ "do_$how" }; + } +} + +while (<>) { + doline(); +} diff --git a/detpic/program.clocks b/detpic/program.clocks new file mode 100644 index 0000000..073a9f3 --- /dev/null +++ b/detpic/program.clocks @@ -0,0 +1,12 @@ +# Each line is: +# M|S|MS how interval +# where how is one of +# T1ov T3ov +# set T[13]CON to | _{master,slave}_t[13]scale +# load TMR[13][HL] with _{master,slave}_t[13]init[hl] +# or to put it another way, TMR[13] with +# 65535 - _{master,slave}_t[13]cycles +# then time to overflow will be specified time + +#morse MS T0ov16 66ms +points MS T3ov 20ms