diff --git a/firmware/README.md b/firmware/README.md new file mode 100644 index 0000000..3b46f9b --- /dev/null +++ b/firmware/README.md @@ -0,0 +1,7 @@ +This is the firmware for the SPIDriver. +It uses the [MyForth](http://www.kiblerelectronics.com/myf/myf.shtml) compiler written by +Charley Shattuck and Bob Nash. + +To compile the fonts go into ``st7735s`` +and unpack the [IBM Plex OpenType](https://github.com/IBM/plex/releases) font set. +then run ``mkfont.py``. This builds the font sources in ``fonts.fs`` diff --git a/firmware/assets/IBMPlexSans-SemiBold.otf b/firmware/assets/IBMPlexSans-SemiBold.otf new file mode 100644 index 0000000..c0a3f53 Binary files /dev/null and b/firmware/assets/IBMPlexSans-SemiBold.otf differ diff --git a/firmware/assets/arrow.png b/firmware/assets/arrow.png new file mode 100644 index 0000000..4c106c5 Binary files /dev/null and b/firmware/assets/arrow.png differ diff --git a/firmware/assets/dot.png b/firmware/assets/dot.png new file mode 100644 index 0000000..bf63333 Binary files /dev/null and b/firmware/assets/dot.png differ diff --git a/firmware/assets/go b/firmware/assets/go new file mode 100755 index 0000000..1effea9 --- /dev/null +++ b/firmware/assets/go @@ -0,0 +1,3 @@ +set -e + +python2 mkfont.py diff --git a/firmware/assets/hex4x5.png b/firmware/assets/hex4x5.png new file mode 100644 index 0000000..2e67716 Binary files /dev/null and b/firmware/assets/hex4x5.png differ diff --git a/firmware/assets/label-scl.png b/firmware/assets/label-scl.png new file mode 100644 index 0000000..c6b30e0 Binary files /dev/null and b/firmware/assets/label-scl.png differ diff --git a/firmware/assets/label-sda.png b/firmware/assets/label-sda.png new file mode 100644 index 0000000..3285ca8 Binary files /dev/null and b/firmware/assets/label-sda.png differ diff --git a/firmware/assets/larrow.png b/firmware/assets/larrow.png new file mode 100644 index 0000000..11ae0fc Binary files /dev/null and b/firmware/assets/larrow.png differ diff --git a/firmware/assets/mkfont.py b/firmware/assets/mkfont.py new file mode 100755 index 0000000..1f89b33 --- /dev/null +++ b/firmware/assets/mkfont.py @@ -0,0 +1,131 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import sys +from PIL import Image, ImageDraw, ImageFont +import numpy as np +import struct +import random + +def rand(n): + return random.randrange(n) + +def as565(im): + """ Return RGB565 of im """ + (r,g,b) = [np.array(c).astype(np.uint16) for c in im.split()] + def s(x, n): + return x * (2 ** n - 1) / 255 + return (s(b, 5) << 11) | (s(g, 6) << 5) | s(r, 5) + +def c3(rgb): + return (16 * (0xf & (rgb >> 8)), + 16 * (0xf & (rgb >> 4)), + 16 * (0xf & (rgb >> 0))) + +font2 = ImageFont.truetype("IBMPlexSans-SemiBold.otf", 13) +fontSP = ImageFont.truetype("pf_ronda_seven_bold.ttf", 8) + +def pad2(s): + if len(s) % 2: + s.append(s[0]) + return s + +def rfont2(c): + im = Image.new("L", (128, 160)) + dr = ImageDraw.Draw(im) + dr.text((10,40), c, font=font2, fill=255) + # im.save("out.png") + extents = im.getbbox() + assert 10 <= extents[0] + assert 45 <= extents[1] + if c in "0123456789": + extents = (0, 0, 10 + 8, 45 + 9) + im = im.crop((10, 45) + extents[2:]) + (w,h) = im.size + nyb = pad2((np.array(im).astype(int).flatten() * 15 / 255).tolist()) + return [w,h] + nyb + +def rf(c, font): + im = Image.new("L", (128, 160)) + dr = ImageDraw.Draw(im) + dr.text((10,40), c, font=font, fill=255) + # im.save("out.png") + extents = im.getbbox() + im = im.crop(extents) + (w,h) = im.size + nyb = (np.array(im).astype(int).flatten() * 15 / 255).tolist() + return [w,h] + nyb + +fs = open("../font.fs", "wt") +fb = 0 + +if __name__ == '__main__': + fs.write('here constant tplan\n') + fs.write('%d , %d , $%x%x , $%x , ," %s"\n' % (60, 0, 0xf, 0xf, 0xf, "V")) + fb += 5 + len("V") + # fs.write("[ %d ]\n" % fb) + fs.write('%d , %d , $%x%x , $%x , ," %s"\n' % (108, 0, 0xf, 0xf, 0xf, "mA")) + fb += 5 + len("mA") + # fs.write("[ %d ]\n" % fb) + + fs.write('0 ,\n') + fb += 1 + # im.save("out.png") + +uniq = "".join(sorted(set("0123456789.mAVDMCS"))) +f2 = sum([rfont2(c) for c in uniq], []) +print "font2 %s takes %d bytes" % (uniq, len(f2) / 2) +def nybbles(nn): + s = len(nn) + assert s % 2 == 0 + b = ["$%x%x ," % tuple(nn[i:i+2]) for i in range(0, s, 2)] + return b +fs.write('here constant font\n') +for c in uniq: + bb = nybbles(rfont2(c)) + print >>fs, "'%s' , " % c, " ".join(bb) + fb += 1 + len(bb) + +# See http://angband.pl/font/tinyfont.html +fs.write("\nhere constant micro\n") +if 1: + tiny = Image.open("hex4x5.png").convert("L") + for i in range(16): + x = 5 * i + im = tiny.crop((x, 0, x + 4, 5)) + rim = im.transpose(Image.ROTATE_90) + ch = ((np.array(rim)).flatten() * 15.99 / 255).astype(np.uint8).tolist() + fs.write(" ".join(nybbles(ch)) + "\n") + fb += len(ch) / 2 + +if 1: + # Image.open("arrow.png").transpose(Image.FLIP_LEFT_RIGHT).save("larrow.png") + for n in ("symbol-s", "symbol-p", "symbol-b", "arrow", "larrow", "dot", "label-sda", "label-scl"): + im = Image.open(n + ".png").convert("L") + if n.startswith("label-"): + im = im.point([0] + 254 * [64] + [255]) + rim = im.transpose(Image.ROTATE_90) + (w,h) = rim.size + ch = [w,h] + pad2(((np.array(rim)).flatten() * 15.99 / 255).astype(np.uint8).tolist()) + fs.write("here constant %s \n" % n) + fs.write(" ".join(nybbles(ch)) + "\n") + fb += len(ch) / 2 + +if 1: + w = 72 + gpng = "plasma.png" + grad = Image.open(gpng).convert("RGB").resize((w, 1), Image.BILINEAR).load() + fs.write("\nHERE constant grad\n") + for x in range(w): + (r,g,b) = grad[x,0] + r = (r * 15) // 255 + g = (g * 15) // 255 + b = (b * 15) // 255 + fs.write('$%x%x , $%x ,\n' % (r, g, b)) + fb += 2 * w + +fs.close() + +fs = open("../fontsize.fs", "wt") +fs.write("&%d constant FONTDATA_SIZE\n" % fb) +fs.close() diff --git a/firmware/assets/pf_ronda_seven_bold.ttf b/firmware/assets/pf_ronda_seven_bold.ttf new file mode 100644 index 0000000..3d3ae5f Binary files /dev/null and b/firmware/assets/pf_ronda_seven_bold.ttf differ diff --git a/firmware/assets/plasma.png b/firmware/assets/plasma.png new file mode 100644 index 0000000..51e4ebb Binary files /dev/null and b/firmware/assets/plasma.png differ diff --git a/firmware/assets/symbol-b.png b/firmware/assets/symbol-b.png new file mode 100644 index 0000000..8a2d45a Binary files /dev/null and b/firmware/assets/symbol-b.png differ diff --git a/firmware/assets/symbol-p.png b/firmware/assets/symbol-p.png new file mode 100644 index 0000000..9a3528a Binary files /dev/null and b/firmware/assets/symbol-p.png differ diff --git a/firmware/assets/symbol-s.png b/firmware/assets/symbol-s.png new file mode 100644 index 0000000..87b7127 Binary files /dev/null and b/firmware/assets/symbol-s.png differ diff --git a/firmware/capture.fs b/firmware/capture.fs new file mode 100644 index 0000000..80e06b4 --- /dev/null +++ b/firmware/capture.fs @@ -0,0 +1,259 @@ + +here constant CAPTURE-START + +[ +: fake ( a - u ) + dup 0= ] here [ and or ; +] + +:m :: ( - ) + [ >in @ label >in ! + create ] here [ , hide + does> @ ] m; + +\ jump if bit is 0 or 1 ( addr bit ) +:m j1 ( addr bit ) [ swap fake swap ] 0=until. m; +:m j0 ( addr bit ) [ swap fake swap ] until. m; +:m j ( addr ) fake again m; + +:m tx SBUF0 (#!) clra TMR3H (#!) m; +:m SDA0 ( a ) SDA j0 m; +:m SDA1 ( a ) SDA j1 m; + +fwd L00.0 +fwd L00.1 +fwd L00.2 +fwd H00.0 +fwd H00.1 +fwd H00.2 +fwd HS +fwd HP +fwd LP +fwd LS + +:m escape RI0 if. RI0 clr ; then m; + +:: L11 begin LS SDA0 SCL 0=until. +:: Lidle begin begin SDA until. SCL until. + L11 j + +:: L10.0 3 .t set + begin L00.0 SDA0 SCL until. begin LS SDA0 SCL 0=until. 2 .t set +:: L10.1 begin L00.1 SDA0 SCL until. begin LS SDA0 SCL 0=until. 1 .t set +:: L10.2 begin L00.2 SDA0 SCL until. begin LS SDA0 SCL 0=until. 0 .t set + tx +:: H10.0 7 .t set +:: klak begin H00.0 SDA0 SCL until. begin HS SDA0 SCL 0=until. 6 .t set +:: H10.1 begin H00.1 SDA0 SCL until. begin HS SDA0 SCL 0=until. 5 .t set +:: H10.2 begin H00.2 SDA0 SCL until. begin HS SDA0 SCL 0=until. 4 .t set + L10.0 j + +:: LS $f0 # and $01 # ior tx ( start ) +:: LS2 begin HP SDA1 SCL 0=until. + H00.0 j + +:: HS $10 (#) ( start ) +:: HS2 begin LP SDA1 SCL 0=until. +:: L00.0 3 .t set + begin L10.0 SDA1 SCL until. begin LP SDA1 SCL 0=until. +:: L00.1 begin L10.1 SDA1 SCL until. begin LP SDA1 SCL 0=until. +:: L00.2 begin L10.2 SDA1 SCL until. begin LP SDA1 SCL 0=until. + tx +:: H00.0 7 .t set + begin H10.0 SDA1 SCL until. begin HP SDA1 SCL 0=until. +:: H00.1 begin H10.1 SDA1 SCL until. begin HP SDA1 SCL 0=until. +:: H00.2 begin H10.2 SDA1 SCL until. begin HP SDA1 SCL 0=until. + L00.0 j + +:: HP $20 (#) + \ L11 j + begin SDA 0=until. + escape + HS2 j + +: (warm) +:: H11 begin HS SDA0 SCL 0=until. +:: Hidle begin begin SDA until. SCL until. + H11 j + +:: LP $f0 # and $02 # ior tx + \ H11 j + begin SDA 0=until. + escape + LS2 j + +: /timer3 + $80 # EIE1 ior! \ Timer 3 interrupt enable +; +: timer3\ + $80 ~# EIE1 and! \ Timer 3 interrupt disable +; + +:m timer3 + SBUF0 (#!) clra + $7f # TMR3CN and! + RI0 if. + RI0 clr + [ sp dec ] + [ sp dec ] + then + [ reti ] m; + +: capture + [ IE push ] + [ ET2 clr ] \ Timer 2 interrupt disable + [ ES0 clr ] \ UART interrupt disable + \i2chw + + [ clra ] + [ FL1 set ] t3+ + (warm) + t3- [ FL1 clr ] + /i2chw + [ IE pop ] + ; + +\ This code all runs in register bank 1: +\ 0 scratch for heatmap +\ 1 log +\ 2 +\ 3 prev cmd +\ 4 constant 72, for heatmap +\ 5 +\ 6 +\ 7 caller acc save +\ +\ FL0 set means this is an address byte + +fwd M00.0 +fwd M10.0 +fwd M10.1 +fwd M10.2 +fwd M10.3 +fwd M10.4 +fwd M10.5 +fwd M10.6 +fwd M10.7 +fwd M10.8 +fwd Mt +fwd MP + +:m (l!) $f3 , m; + +:m (log!) + $f3 , a+ m; + +:m wrap + $7f # 9 and! m; + +:m heat + \ byte is in t + FL0 if. + setc 2/' + 0 (#!) + 4 (#@) $f2 , + then +m; + +:m escape + 7 (#@) + [ + dirty set + PSW pop + reti + ] +m; + +:: MP + $00 (#) (log!) + $01 (#) (log!) + wrap + escape + begin SDA 0=until. +: (mismatch) +:: Mt + begin MP SDA1 SCL 0=until. + $82 # 3 #! FL0 set + M00.0 j + +:: M00.6 begin M10.6 SDA1 SCL until. begin MP SDA1 SCL 0=until. +:: M00.7 begin M10.7 SDA1 SCL until. begin MP SDA1 SCL 0=until. (l!) +:: M00.8 begin M10.8 SDA1 SCL until. begin MP SDA1 SCL 0=until. heat + a+ 3 (#@) (l!) a+ wrap + $83 # 3 #! FL0 clr + M00.0 j + +:: M10.6 begin M00.6 SDA0 SCL until. begin Mt SDA0 SCL 0=until. 1 .t set +:: M10.7 begin M00.7 SDA0 SCL until. begin Mt SDA0 SCL 0=until. 1+ (l!) +:: M10.8 begin M00.8 SDA0 SCL until. begin Mt SDA0 SCL 0=until. + a+ 3 (#@) $7f # and (l!) a+ wrap + $83 # 3 #! FL0 clr + M10.0 j + +:: MP3 MP j +:: Mt3 Mt j +:: M00.3 begin M10.3 SDA1 SCL until. begin MP3 SDA1 SCL 0=until. +:: M00.4 begin M10.4 SDA1 SCL until. begin MP3 SDA1 SCL 0=until. +:: M00.5 begin M10.5 SDA1 SCL until. begin MP3 SDA1 SCL 0=until. + M00.6 j +:: M10.3 begin M00.3 SDA0 SCL until. begin Mt3 SDA0 SCL 0=until. 4 .t set +:: M10.4 begin M00.4 SDA0 SCL until. begin Mt3 SDA0 SCL 0=until. 3 .t set +:: M10.5 begin M00.5 SDA0 SCL until. begin Mt3 SDA0 SCL 0=until. 2 .t set + M10.6 j + +:: MP0 MP j +:: Mt0 Mt j + +: (warm) +:: M00.0 clra + begin M10.0 SDA1 SCL until. begin MP0 SDA1 SCL 0=until. +:: M00.1 begin M10.1 SDA1 SCL until. begin MP0 SDA1 SCL 0=until. +:: M00.2 begin M10.2 SDA1 SCL until. begin MP0 SDA1 SCL 0=until. + M00.3 j +:: M10.0 clra + begin M00.0 SDA0 SCL until. begin Mt0 SDA0 SCL 0=until. 7 .t set +:: M10.1 begin M00.1 SDA0 SCL until. begin Mt0 SDA0 SCL 0=until. 6 .t set +:: M10.2 begin M00.2 SDA0 SCL until. begin Mt0 SDA0 SCL 0=until. 5 .t set + M10.3 j + +: /monitor + [ ET2 clr ] \ Timer 2 interrupt disable + [ ES0 clr ] \ UART interrupt disable + \i2chw + t3i- t3+ \ Timer3 running, no intr + + %00000100 # P0MASK #! + %00000100 # P0MAT #! \ SDA high + + %00010000 # P1MASK #! + %00010000 # P1MAT #! \ SCL high + + \ constants in registers + 72 # [ 4 8 + ] #! + $02 # EIE1 ior! \ EMAT + ; + +: \monitor + $02 ~# EIE1 and! \ EMAT off + [ ET2 set ] \ Timer 2 interrupt enable + [ ES0 set ] \ UART interrupt enable + t3i+ t3- \ Timer3 stopped, intr + /i2chw + ; + +:m mismatch + [ + PSW push + RS0 set + ] + 7 (#!) + Mt j +m; + +here [ +CAPTURE-START xor 11 rshift 0<> +[IF] +cr .( Capture block cannot cross a 2K boundary) +abort +[THEN] +] diff --git a/firmware/font.fs b/firmware/font.fs new file mode 100644 index 0000000..9c10255 --- /dev/null +++ b/firmware/font.fs @@ -0,0 +1,131 @@ +here constant tplan +60 , 0 , $ff , $f , ," V" +108 , 0 , $ff , $f , ," mA" +0 , +here constant font +'.' , $49 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $03 , $20 , $2f , $e0 , $0c , $b0 , +'0' , $89 , $01 , $9d , $d8 , $00 , $0c , $fc , $df , $90 , $4f , $b0 , $0d , $e1 , $7f , $70 , $0b , $f4 , $9f , $70 , $0a , $f5 , $7f , $70 , $0b , $f4 , $4f , $a0 , $0d , $e1 , $0c , $fb , $cf , $90 , $01 , $ad , $d8 , $00 , +'1' , $89 , $00 , $af , $f7 , $00 , $09 , $fd , $f7 , $00 , $6f , $a7 , $f7 , $00 , $07 , $07 , $f7 , $00 , $00 , $07 , $f7 , $00 , $00 , $07 , $f7 , $00 , $00 , $07 , $f7 , $00 , $09 , $9c , $fc , $95 , $0e , $ff , $ff , $f8 , +'2' , $89 , $02 , $ae , $d8 , $00 , $1d , $fc , $ef , $90 , $3b , $70 , $3f , $e0 , $00 , $00 , $4f , $c0 , $00 , $02 , $de , $40 , $00 , $4d , $e4 , $00 , $06 , $ed , $30 , $00 , $4f , $fb , $aa , $a2 , $5f , $ff , $ff , $f3 , +'3' , $89 , $04 , $ce , $d7 , $00 , $3e , $eb , $df , $80 , $05 , $10 , $5f , $b0 , $00 , $6b , $dd , $30 , $00 , $9f , $fc , $20 , $00 , $00 , $6f , $c0 , $2a , $10 , $2f , $e0 , $8f , $eb , $df , $80 , $07 , $ce , $c7 , $00 , +'4' , $89 , $00 , $05 , $ff , $40 , $00 , $1d , $ff , $40 , $00 , $8e , $cf , $40 , $03 , $e8 , $9f , $40 , $0c , $d0 , $9f , $40 , $6f , $50 , $9f , $40 , $bf , $ff , $ff , $f7 , $69 , $99 , $cf , $a4 , $00 , $00 , $9f , $40 , +'5' , $89 , $0c , $ff , $ff , $c0 , $0d , $eb , $bb , $90 , $0e , $a0 , $00 , $00 , $0f , $aa , $eb , $20 , $1f , $fb , $df , $d0 , $02 , $20 , $0d , $f3 , $07 , $40 , $0d , $f2 , $2e , $eb , $df , $b0 , $03 , $be , $d8 , $10 , +'6' , $89 , $00 , $1a , $fc , $10 , $00 , $cf , $90 , $00 , $09 , $f8 , $00 , $00 , $1e , $da , $eb , $30 , $5f , $fb , $bf , $d0 , $7f , $a0 , $0c , $f4 , $5f , $a0 , $0c , $f3 , $0c , $eb , $bf , $b0 , $01 , $ad , $d9 , $10 , +'7' , $89 , $5f , $ff , $ff , $f2 , $5f , $ba , $ae , $f2 , $5f , $50 , $3f , $c0 , $14 , $10 , $9f , $50 , $00 , $01 , $ee , $00 , $00 , $07 , $f8 , $00 , $00 , $0d , $e2 , $00 , $00 , $5f , $a0 , $00 , $00 , $bf , $40 , $00 , +'8' , $89 , $03 , $be , $d9 , $10 , $1e , $ea , $bf , $c0 , $2f , $a0 , $0d , $e0 , $09 , $e9 , $ae , $60 , $06 , $ef , $fd , $40 , $5f , $b1 , $2d , $e2 , $7f , $80 , $0c , $f4 , $2e , $ea , $bf , $d0 , $03 , $be , $da , $20 , +'9' , $89 , $02 , $ae , $d8 , $00 , $1d , $eb , $cf , $90 , $6f , $90 , $0d , $f1 , $7f , $80 , $0d , $f3 , $3e , $ea , $bf , $f2 , $05 , $ce , $af , $d0 , $00 , $00 , $af , $50 , $00 , $1b , $f9 , $00 , $02 , $df , $80 , $00 , +'A' , $99 , $00 , $0e , $fa , $00 , $00 , $04 , $ff , $e1 , $00 , $00 , $9f , $9f , $50 , $00 , $0e , $c2 , $fb , $00 , $05 , $f7 , $0c , $e1 , $00 , $af , $ff , $ff , $60 , $1e , $eb , $bb , $fb , $06 , $f8 , $00 , $0d , $f1 , $bf , $40 , $00 , $8f , $70 , +'C' , $99 , $00 , $5b , $ec , $70 , $00 , $6f , $ec , $ef , $80 , $1e , $e2 , $01 , $c7 , $04 , $fa , $00 , $00 , $00 , $6f , $90 , $00 , $00 , $04 , $fa , $00 , $00 , $00 , $1e , $e1 , $01 , $d8 , $00 , $7f , $ec , $ef , $80 , $00 , $6c , $ec , $60 , $00 , +'D' , $99 , $1f , $ff , $eb , $50 , $01 , $fe , $cc , $ef , $60 , $1f , $d0 , $02 , $ee , $01 , $fd , $00 , $0b , $f3 , $1f , $d0 , $00 , $af , $51 , $fd , $00 , $0b , $f3 , $1f , $d0 , $01 , $ee , $11 , $fe , $bc , $ef , $60 , $1f , $ff , $eb , $50 , $01 , +'M' , $a9 , $1f , $f5 , $00 , $0a , $fa , $1f , $fc , $00 , $3f , $fa , $1f , $ff , $60 , $bf , $fa , $1f , $dd , $d5 , $fb , $fa , $1f , $c6 , $fe , $e4 , $fa , $1f , $c0 , $cf , $63 , $fa , $1f , $c0 , $4d , $03 , $fa , $1f , $c0 , $02 , $03 , $fa , $1f , $c0 , $00 , $03 , $fa , +'S' , $89 , $02 , $ad , $da , $20 , $0d , $fd , $df , $e1 , $4f , $b0 , $04 , $30 , $2e , $e8 , $51 , $00 , $05 , $df , $ff , $80 , $00 , $02 , $5d , $f4 , $08 , $30 , $0a , $f5 , $5f , $fd , $df , $d1 , $04 , $be , $da , $20 , +'V' , $99 , $cf , $30 , $00 , $de , $17 , $f8 , $00 , $3f , $b0 , $2f , $d0 , $08 , $f6 , $00 , $cf , $20 , $de , $10 , $06 , $f7 , $2f , $b0 , $00 , $1f , $b6 , $f6 , $00 , $00 , $be , $ce , $10 , $00 , $06 , $ff , $a0 , $00 , $00 , $1e , $f5 , $00 , $0c , +'m' , $b9 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $00 , $2f , $ba , $ea , $1a , $ea , $12 , $ff , $bd , $fe , $bd , $f8 , $2f , $c0 , $3f , $c0 , $3f , $b2 , $fb , $02 , $fb , $02 , $fc , $2f , $b0 , $2f , $b0 , $2f , $c2 , $fb , $02 , $fb , $02 , $fc , $2f , $b0 , $2f , $b0 , $2f , $c0 , + +here constant micro +$4f , $ff , $4f , $00 , $0f , $f0 , $00 , $f4 , $ff , $f4 , +$00 , $00 , $0f , $ff , $ff , $f0 , $00 , $00 , $00 , $00 , +$4f , $40 , $ff , $0f , $0f , $f0 , $f0 , $ff , $04 , $ff , +$4f , $4f , $4f , $0f , $0f , $f0 , $f0 , $ff , $04 , $0f , +$ff , $ff , $f0 , $0f , $00 , $00 , $f0 , $0f , $ff , $00 , +$f0 , $4f , $4f , $0f , $0f , $f0 , $f0 , $ff , $ff , $0f , +$40 , $4f , $4f , $0f , $0f , $f0 , $f0 , $f4 , $ff , $f4 , +$ff , $00 , $0f , $0f , $00 , $f0 , $0f , $ff , $00 , $00 , +$4f , $4f , $4f , $0f , $0f , $f0 , $f0 , $f4 , $f4 , $f4 , +$4f , $ff , $4f , $0f , $0f , $f0 , $f0 , $f4 , $f4 , $04 , +$4f , $ff , $ff , $0f , $00 , $f0 , $f0 , $04 , $ff , $ff , +$4f , $4f , $4f , $0f , $0f , $f0 , $f0 , $ff , $ff , $ff , +$4f , $0f , $4f , $00 , $0f , $f0 , $00 , $f4 , $ff , $f4 , +$4f , $ff , $4f , $00 , $0f , $f0 , $00 , $ff , $ff , $ff , +$00 , $00 , $0f , $0f , $0f , $f0 , $f0 , $ff , $ff , $ff , +$00 , $00 , $0f , $0f , $00 , $f0 , $f0 , $0f , $ff , $ff , +here constant symbol-s +$bc , $00 , $17 , $ce , $d8 , $20 , $00 , $2b , $ff , $ff , $fc , $30 , $0a , $ff , $ff , $ff , $fb , $15 , $fd , $0f , $d0 , $0d , $f6 , $af , $00 , $f0 , $00 , $0f , $cc , $f0 , $ff , $0f , $f0 , $fe , $cf , $0f , $f0 , $ff , $0f , $e9 , $f0 , $00 , $0f , $00 , $fb , $4e , $d0 , $0d , $f0 , $df , $60 , $9f , $ff , $ff , $ff , $a1 , $01 , $9f , $ff , $ff , $b2 , $00 , $00 , $5b , $db , $61 , $00 , +here constant symbol-p +$bc , $00 , $17 , $ce , $d8 , $20 , $00 , $2b , $ff , $ff , $fc , $30 , $0a , $ff , $ff , $ff , $fb , $15 , $fd , $00 , $df , $ff , $f6 , $af , $00 , $00 , $ff , $ff , $cc , $f0 , $ff , $0f , $ff , $fe , $cf , $0f , $f0 , $ff , $ff , $e9 , $f0 , $00 , $00 , $00 , $fb , $4e , $00 , $00 , $00 , $0f , $60 , $9f , $ff , $ff , $ff , $a1 , $01 , $9f , $ff , $ff , $b2 , $00 , $00 , $5b , $db , $61 , $00 , +here constant symbol-b +$bc , $00 , $17 , $ce , $d8 , $20 , $00 , $2b , $ff , $ff , $fc , $30 , $0a , $ff , $ff , $ff , $fb , $15 , $ff , $ff , $ff , $ff , $f6 , $af , $ff , $ff , $ff , $ff , $cc , $f0 , $00 , $00 , $f0 , $fe , $cf , $00 , $00 , $0f , $0f , $e9 , $ff , $ff , $ff , $ff , $fb , $4e , $ff , $ff , $ff , $ff , $60 , $9f , $ff , $ff , $ff , $a1 , $01 , $9f , $ff , $ff , $b2 , $00 , $00 , $5b , $db , $61 , $00 , +here constant arrow +$35 , $08 , $03 , $b3 , $8f , $8b , $fb , $ef , $e0 , +here constant larrow +$35 , $ef , $eb , $fb , $8f , $83 , $b3 , $08 , $0e , +here constant dot +$44 , $4c , $d5 , $bf , $fd , $bf , $fc , $3b , $b4 , +here constant label-sda +$810 , $f0 , $00 , $00 , $00 , $f0 , $00 , $00 , $00 , $f0 , $4f , $ff , $f0 , $f0 , $f0 , $f0 , $00 , $f0 , $f0 , $f0 , $00 , $f0 , $4f , $ff , $f0 , $f0 , $00 , $00 , $00 , $f0 , $4f , $ff , $40 , $f0 , $f0 , $00 , $f0 , $f0 , $f0 , $00 , $f0 , $f0 , $ff , $ff , $f0 , $f0 , $00 , $00 , $00 , $f0 , $f0 , $4f , $40 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $4f , $40 , $f0 , +here constant label-scl +$810 , $f0 , $00 , $00 , $00 , $f0 , $00 , $00 , $00 , $f0 , $00 , $00 , $00 , $f0 , $00 , $00 , $f0 , $f0 , $00 , $00 , $f0 , $f0 , $ff , $ff , $f0 , $f0 , $00 , $00 , $00 , $f0 , $4f , $0f , $40 , $f0 , $f0 , $00 , $f0 , $f0 , $f0 , $00 , $f0 , $f0 , $4f , $ff , $40 , $f0 , $00 , $00 , $00 , $f0 , $f0 , $4f , $40 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $f0 , $4f , $40 , $f0 , + +HERE constant grad +$00 , $7 , +$10 , $8 , +$10 , $8 , +$20 , $8 , +$20 , $8 , +$30 , $8 , +$30 , $9 , +$30 , $9 , +$40 , $9 , +$40 , $9 , +$40 , $9 , +$50 , $9 , +$50 , $9 , +$50 , $9 , +$60 , $9 , +$60 , $9 , +$60 , $9 , +$70 , $9 , +$70 , $9 , +$70 , $9 , +$70 , $9 , +$80 , $9 , +$80 , $9 , +$81 , $9 , +$91 , $9 , +$91 , $9 , +$91 , $8 , +$92 , $8 , +$a2 , $8 , +$a2 , $8 , +$a2 , $8 , +$a2 , $8 , +$b3 , $7 , +$b3 , $7 , +$b3 , $7 , +$b3 , $7 , +$b4 , $7 , +$c4 , $6 , +$c4 , $6 , +$c4 , $6 , +$c5 , $6 , +$c5 , $6 , +$d5 , $5 , +$d5 , $5 , +$d6 , $5 , +$d6 , $5 , +$d6 , $5 , +$d6 , $5 , +$d7 , $4 , +$e7 , $4 , +$e7 , $4 , +$e7 , $4 , +$e8 , $4 , +$e8 , $3 , +$e8 , $3 , +$e9 , $3 , +$e9 , $3 , +$e9 , $3 , +$e9 , $3 , +$ea , $2 , +$ea , $2 , +$ea , $2 , +$eb , $2 , +$eb , $2 , +$eb , $2 , +$ec , $2 , +$ec , $2 , +$ec , $2 , +$ed , $2 , +$ed , $2 , +$ed , $2 , +$ee , $2 , diff --git a/firmware/fontsize.fs b/firmware/fontsize.fs new file mode 100644 index 0000000..69d92e3 --- /dev/null +++ b/firmware/fontsize.fs @@ -0,0 +1 @@ +&1385 constant FONTDATA_SIZE diff --git a/firmware/main.fs b/firmware/main.fs new file mode 100644 index 0000000..86035d8 --- /dev/null +++ b/firmware/main.fs @@ -0,0 +1,1010 @@ +24500000 constant SYSCLK + +0 constant CLOSEUP + +\ P0.0 SDA 2K2 +\ P0.1 SDA 4K3 +\ P0.2 SDA +\ P0.3 SDA 4K7 +\ P0.4 RX +\ P0.5 TX +\ P0.6 A.V +\ P0.7 A.C + +\ P1.0 RS/DC +\ P1.1 DATA +\ P1.2 CLOCK +\ P1.3 RESET +\ P1.4 SCL +\ P1.5 SCL 2K2 +\ P1.6 SCL 4K3 + +\ P2.0 SCL 4K7 + +0 [if] +There are 3 threads: + + 1000Hz tick. Increments the BCD milliscond timer. + Timer 2 interrupt. + + UART/SPI service. Runs the transport. + UART and SPI interrupts. + [DPTR, R0] + + graphics. renders the main image. + Main thread. + [DPTR, R0-7] + ADC drive. Runs ADC conversions, stores results in adc-. + ADC end of conversion interrupt. + +[then] +[ : ," '"' parse dup ] , [ + bounds do + i c@ ] , [ + loop +; +] + +:m t3+ %00000100 # TMR3CN #! m; \ Timer 3 enable +:m t3- %00000000 # TMR3CN #! m; \ Timer 3 enable +:m t3i+ $80 # EIE1 ior! m; \ Timer 3 interrupt enable +:m t3i- $80 ~# EIE1 and! m; \ Timer 3 interrupt disable + +$0090 org +: 2dup |over +: over |over ; +: tuck swap over ; +:m p>r [ dpl push dph push ] m; +: r>p [ dph pop dpl pop ] ; \ MUST be followed by ; +: @p |@p ; +: @p+ |@p+ ; +: * |* ; +: um* |um* ; +:m #+! [ dup add ] #! m; +: dnegate + swap invert swap invert +: d1+ + swap 1 # + swap 0 # +' ; +: d+ push swap push + pop pop +' ; +:m d2/ clrc 2/' swap 2/' swap m; +: - negate + ; + +: twist ( a b c d -- a c b d ) + push swap pop ; + +:m /uart + REN0 set \ Receive enable + + TR1 set + $20 # TMOD #! + $18 # CKCON #! \ Use system clock (T1,T2) + [ SYSCLK 2/ 1000000 / negate ] # + TH1 #! \ speed + ES0 set +m; + +[ : array create , does> @ + ; ] + +$10 cpuORG + +$09 constant log \ logging ring pointer + +cpuHERE constant tempr 2 cpuALLOT \ temperature ADC +cpuHERE constant currr 2 cpuALLOT \ current ADC +cpuHERE constant currd 2 cpuALLOT \ decimal +cpuHERE constant slowc 1 cpuALLOT \ slow refresh counter +cpuHERE constant charc 1 cpuALLOT \ character counter +cpuHERE constant convs 1 cpuALLOT \ converter state (2 bit) +cpuHERE constant other 1 cpuALLOT \ context SP save +cpuHERE array clock 6 cpuALLOT + +cpuHERE $20 <> throw + +cpuHERE constant flags 1 cpuALLOT $00 constant dirty + $01 constant prev. + $02 constant talked. + $03 constant ptalked. + $04 constant fade. + $05 constant risen. + $06 constant modechange. + $07 constant timeout +cpuHERE constant ftemp 1 cpuALLOT $08 constant f.0 + $09 constant f.1 + $0a constant f.2 + $0b constant f.3 + $0c constant f.4 + $0d constant f.5 + $0e constant f.6 + $0f constant f.7 +cpuHERE constant flags2 1 cpuALLOT $10 constant weighing + +cpuHERE constant mode 1 cpuALLOT +cpuHERE constant tempd 2 cpuALLOT \ decimal +cpuHERE constant vbusr 2 cpuALLOT \ voltage ADC +cpuHERE constant vbusd 2 cpuALLOT \ decimal + +cpuHERE constant talk0 1 cpuALLOT +cpuHERE constant talk1 1 cpuALLOT +cpuHERE constant talker 1 cpuALLOT +cpuHERE constant ptalker 1 cpuALLOT +cpuHERE constant slashx 1 cpuALLOT +cpuHERE constant story 16 cpuALLOT +cpuHERE constant guard 2 cpuALLOT + +[ +cpuHERE constant red 1 cpuALLOT +cpuHERE constant grn 1 cpuALLOT +cpuHERE constant blu 1 cpuALLOT +] +3 constant x \ graphics x coordinate +4 constant y \ graphics y coordinate +cpuHERE constant i2cb 64 cpuALLOT + +cr .( RAM used ) cpuHERE . .( bytes ) + +: swapctx [ + 0 push + 1 push + t push + psw push + dph push + dpl push + ] + SP (#@) + [ other xch ] + SP (#!) + [ + dpl pop + dph pop + psw pop + t pop + 1 pop + 0 pop + ] + ; + +: 0# dup [ clra ] ; +: key begin TI0 clr RI0 0=while. swapctx repeat RI0 clr SBUF0 #@ ; \ XXX compare with spidriver +: emit SBUF0 (#!) begin swapctx RI0 clr TI0 until. TI0 clr [ charc dec ] +: _drop drop ; + +:m drop; _drop ; m; + +: umax + clrc $96 , $26 , \ C set if u>t + if' drop; then nip ; +: umin + clrc $96 , $26 , \ C set if u>t + 0=if' drop; then nip ; + +: depth S #@ invert ; +0 [if] +include debug.fs +[then] +: 1ms + 1 # +: ms + slowc (#!) + begin slowc (#@) 0=until drop; + +: 5µs + 5 # +: µs + 1 #for + nop nop nop nop + nop nop nop nop + 1 #next + ; + +\ ---------------------------------------- DECIMAL +5 constant d.l \ decimal accumulator +6 constant d.h + +: decimal ( u. -- d. ) \ d is the BCD of u + 0 # d.l #! + 0 # d.h #! + 16 # 7 #for + swap 2*' swap 2*' + d.l #@ [ d.l addc da ] d.l #! + d.h #@ [ d.h addc da ] d.h #! + 7 #next + 2drop d.l #@ d.h #@ ; + +: 10trunc + swap $f0 # and swap ; +: 5trunc + swap + dup $f # and 5 # crc) CRC0IN (#!) m; + +: hdigit + dup +: (hdigit) + [swap] +: digit + $f # and + -10 # + -if -39 # + then 97 # + emit ; +: dd hdigit digit ; + +: >i2c + MASTER 0=if. drop; then + (>crc) + SMB0DAT #! +: i2c + [ SI clr ] +: (i2c) + [ timeout clr ] +: i2c-wait + $01 # EIE1 ior! \ ESMB0 + t3+ + begin swapctx SI until. + t3- + $01 ~# EIE1 and! \ ESMB0 + ; +: i2c-start + [ STA set ] + i2c + [ STA clr ] ; +: i2c-stop + [ STO set SI clr ] ; +: i2c> + MASTER 0=if. $ff # ; then + i2c SMB0DAT #@ (>crc) ; + +: i2c-leave + SMB0CF #@ + 7 .t 0=if. drop; then \ already turned off + 5 .t if. i2c-stop 10 # µs then + \i2chw + $04 ~# XBR0 and! drop; + +: setport ( u ) \ SCL SCL_DIR SDA SDA_DIR + + P0MDOUT ftemp mov + 2/' f.2 movcb + ftemp P0MDOUT mov + 2/' P0.2 movcb + P1MDOUT ftemp mov + 2/' f.4 movcb + ftemp P1MDOUT mov + 2/' P1.4 movcb ; + +: i2c-restore + %1010 # setport drop + /i2chw + $04 # XBR0 ior! ; + +: i2c-reset + i2c-leave + [ SDA set SCL clr ] + 10 # 2 #for + [ SCL set ] 5µs + [ SCL clr ] 5µs + 2 #next + \ a STOP signal (SDA from low to high while CLK is high) + [ SDA clr ] 5µs + [ SCL set ] 2 # µs + [ SDA set ] 2 # µs + i2c-restore + STO clr ; + +: bitbang + i2c-leave + begin + key + '@' # =if drop; then + setport + + 2/' if' + 0# + P1.4 movbc 2*' + P0.2 movbc 2*' + emit + then + drop + again + +: doconv + startconv + begin AD0INT until. AD0INT clr ; +: measure ( - ) \ + doconv + ADC0H #@ emit ; + +: startweigh ( u ) + weighing set + i2c-leave + [ SCL set SDA set ] + %00000100 ~# P0MDIN and! + %00010000 ~# P1MDIN and! +: pulldir ( u ) [ \ Set pullup/down direction (1=up, 0=down) + 2/' P0.0 movcb + 2/' P0.1 movcb + 2/' P0.3 movcb + 2/' P1.5 movcb + 2/' P1.6 movcb + 2/' P2.0 movcb + ] drop; + +: weigh + 0# [ weighing movbc ] 2*' \ 1=pending, 0=ready + dup emit + 0=if + 0# µs + + 3.3v + %0010 # ADC0MX #! measure + %1100 # ADC0MX #! measure + + %00000100 # P0MDIN ior! + %00010000 # P1MDIN ior! + + dup /converter convs #! + %111111 # pulldir + i2c-restore + then drop; + +\ ---------------------------------------- timer service + +: timer2 + [ psw push t push ] + [ + slowc dec + setc + clra 0 clock dup addc da (#!) + clra 1 clock dup addc da (#!) + clra 2 clock dup addc da (#!) + clra 3 clock dup addc da (#!) + clra 4 clock dup addc da (#!) + clra 5 clock dup addc da (#!) + ] [ t pop psw pop ] ; + +: timer3a + \i2chw + timeout set + SI set + /i2chw + [ reti ] + + +\ ---------------------------------------- CRC16 +:m /crc + %1100 # CRC0CN0 #! + m; + +:m crc16 + CRC0DAT #@ + CRC0DAT #@ m; + +\ ---------------------------------------- pullups + +\ P0.0 SDA 2K2 +\ P0.1 SDA 4K3 +\ P0.2 SDA +\ P0.3 SDA 4K7 + +\ P1.4 SCL +\ P1.5 SCL 2K2 +\ P1.6 SCL 4K3 + +\ P2.0 SCL 4K7 + +: SDA_2k2 %00000001 # P0MDOUT ior! ; +: SDA_4k3 %00000010 # P0MDOUT ior! ; +: SDA_4k7 %00001000 # P0MDOUT ior! ; + +: SCL_2k2 %00100000 # P1MDOUT ior! ; +: SCL_4k3 %01000000 # P1MDOUT ior! ; +: SCL_4k7 %00000001 # P2MDOUT ior! ; + +\ 5 4 3 2 1 0 +\ SCL_4k7 SCL_4k3 SCL_2k2 SDA_4k7 SDA_4k3 SDA_2k2 +: pull@ ( - u ) + 0# [ + P2MDOUT ftemp mov + f.0 movbc 2*' + P1MDOUT ftemp mov + f.6 movbc 2*' + f.5 movbc 2*' + P0MDOUT ftemp mov + f.3 movbc 2*' + f.1 movbc 2*' + f.0 movbc 2*' ] ; +: pull! ( u ) [ + P0MDOUT ftemp mov + 2/' f.0 movcb + 2/' f.1 movcb + 2/' f.3 movcb + ftemp P0MDOUT mov + P1MDOUT ftemp mov + 2/' f.5 movcb + 2/' f.6 movcb + ftemp P1MDOUT mov + P2MDOUT ftemp mov + 2/' f.0 movcb + ftemp P2MDOUT mov + ] drop; + +: release + %00001011 ~# P0MDOUT and! + %01100000 ~# P1MDOUT and! + %00000001 ~# P2MDOUT and! +; +: weak + release + %00001000 # P0MDOUT ior! + %00000001 # P2MDOUT ior! + ; + +here constant "devname ," i2cdriver1" + +: heatmap ( u - ) \ heatmap address in x + $80 # + dpl #! ; + +: ishot ( u ) + heatmap 72 # !x ; + +: snap + [ log dpl mov ] + story # a! + dup + 16 # 7 #for + [ dpl dec ] + $7f # dpl and! + (@x) + (!+) + 7 #next + drop; + +: type + @p+ 2 #for @p+ emit 2 #next ; + +: hdigit + dup +: (hdigit) + [swap] +: digit + $f # and + -10 # + -if -39 # + then 97 # + emit ; +: dd hdigit digit ; +: dh. dd +: h. dd +: space + 32 # emit ; +: point + '.' # emit ; +: d.d + hdigit point digit ; + +: .' \ print carry + [ '0' 2/ ] # 2*' +: emit_ + emit space ; + +: i2c-speed + TH0 #@ + I2C_400 # =if 4 (#) ; then + 1 (#) ; + +: modechar + 'I' # + SMB0CF ftemp mov + f.7 if. ; then + 'B' (#) ; + +: bracket + 79 # charc #! + '[' # emit ; +: info + bracket + "devname ##p! type space + "serial ##p! type space + + 5 clock #@ dd + 4 clock #@ dd + 3 clock #@ dd + 2 clock #@ dd + 1 clock #@ (hdigit) + space + + vbusd #2@ d.d dd space + currd #2@ digit dd space + tempd #2@ digit d.d space + + modechar emit_ + + [ SDA movbc ] .' + [ SCL movbc ] .' + + i2c-speed digit $00 # dd space + + pull@ dd space + + crc16 dd dd +: pad + charc #@ begin + space 1- + 0=until + drop + ']' # emit + ; + +: introspect + bracket + + $93 # h. + 0 #@ h. + SP #@ h. + SMB0CF #@ h. + SMB0CN #@ h. + TMR2L #2@ dh. + TMR3L #2@ dh. + IE #@ h. + EIE1 #@ h. + + P0 #@ h. P0MDIN #@ h. P0MDOUT #@ h. + P1 #@ h. P1MDIN #@ h. P1MDOUT #@ h. + P2 #@ h. P2MDOUT #@ h. + + convs #@ h. + + pad ; + +\ Commands are: +\ e echo next byte +\ s select +\ u unselect +\ 80-bf read 1-64 bytes +\ c0-ff write 1-64 bytes + +: count ( u -- u) + 63 # and 1+ ; + +CLOSEUP [IF] +:m acmd \ Copy ACK into T.7 for a command byte + [ 7 .t set ] m; +[ELSE] +:m acmd \ Copy ACK into T.7 for a command byte + [ ACK movbc 7 .t movcb ] m; +[THEN] + +: b>log ( arg - arg ) + 3 # acmd over +: >log ( cmd arg ) + [ dirty set ] + [ log dpl mov ] + !x+ !x+ + $7f # dpl and! + [ dpl log mov ] + ; + +: alert ( u ) + [ timeout set ] + drop 4 # 0 # >log ; + +: rdN ( n -- ) + [ ACK set ] + 2 #for + [ $b8 2 + ] , [ 1 cond ] \ Clear ACK on final byte when R2 is 1 + [ ACK clr ] + then + i2c> + (>crc) b>log emit + 2 #next ; + +: rdNA ( n -- ) \ don't NACK final byte + [ ACK set ] + 2 #for + i2c> b>log emit + 2 #next ; + +: report + [ '0' 2/ 2/ 2/ ] # + [ ARBLOST movbc ] 2*' + [ timeout movbc ] 2*' + [ ACK movbc ] 2*' emit ; + +: flame ( u - u ) + dup clrc 2/' ishot ; + +: do-start + key +: log-start ( u ) + SDA 0=if. alert ; then + i2c-start + dup >i2c + timeout if. alert ; then + ACK if. + flame + then + 2 # acmd + swap >log ; + +: log-stop + 1 # 0# >log i2c-stop ; + +: i2c-regrd \ expect (dev, reg, len) + key 2* key key push ( dev reg R: len ) + over log-start \ S/W + b>log >i2c \ reg + 1+ log-start \ S/R + pop rdN + log-stop ; + +: dmode + 'D' # +: newmode + mode #! modechange. set ; + +here constant WIP +: device-scan + 8 # + 112 # 2 #for + i2c-start dup 2* >i2c + ACK if. dup ishot then + report + i2c-stop + 1+ + 2 #next drop ; + +: service + key + -if + 6 .t if. + count dup + i2cb # a! 2 #for + key + b>log + !+ + 2 #next + i2cb # a! 2 #for + @+ >i2c + 2 #next + report + ; + then + count rdN ; + then + '?' # =if info then + '1' # =if 100Khz then + '4' # =if 400Khz then + 'a' # =if key rdNA then + 'b' # =if bitbang then + 'c' # =if 'C' # newmode then + 'd' # =if device-scan then + 'e' # =if key emit then + 'f' # =if fade. set 'X' # emit then + '_' # =if $10 # RSTSRC #! then + 'i' # =if i2c-restore then + 'm' # =if 'M' # newmode then + 'p' # =if log-stop then + 'r' # =if i2c-regrd then + 's' # =if do-start report then + 'u' # =if key pull! then + 'v' # =if key startweigh then + 'w' # =if weigh then + 'x' # =if + i2c-reset + [ '0' 2/ 2/ ] # + [ SDA movbc ] 2*' + [ SCL movbc ] 2*' + emit + then + 'J' # =if introspect then + drop ; + +: thread2 + 0 # 2 #for + 0# !x+ + 2 #next + \ '@' # emit + begin + service + again ; + +here constant _cap +[ : fwd 0 constant ; ] +include capture.fs +_cap org +[ : fwd bl word find 0= throw execute 0= throw ; ] +include capture.fs + +0 constant Y_V +29 constant X_V +80 constant X_MA + +include st7735.fs + +: hdigit dup [swap] +: digit $f # and '0' # + ch ; +: dd hdigit digit ; +: d3 ( d. ) \ 3-digit space padded + if digit dd ; then \ ### + drop blch + 10 # body @ ] ##p! + [ + dpl push + dph push + 0 push + ] + [ STACKS 8 + ] # other #! + + $100 SP! $c0 RP! + + %11001011 # P0SKIP #! \ TX,RX,SDA + %00010000 # P0MDOUT #! \ + %00111111 # P0MDIN #! \ analog P0.6 P0.7 + + %11101111 # P1SKIP #! \ SCL + %00001111 # P1MDOUT #! + /uart + /adc + /crc + + [ ticks/ms negate ] # TMR2RLL #! + [ ticks/ms negate 8 rshift ] # TMR2RLH #! + + dmode + + [ ET2 set ] \ Timer 2 interrupt enable + [ TR2 set ] \ Timer 2 enable + [ EA set ] + t3i+ + + release + weak + \ SDA_2k2 + \ SDA_4k3 + \ SDA_4k7 + + \ SCL_2k2 + \ SCL_4k3 + \ SCL_4k7 + + /i2c 100Khz + + [ dirty set ] + swapctx + + /st7735 fixed + 25 # slowc #! + + /converter + + begin + conversions + + dirty if. + snap + [ dirty clr ] + waves + then + AD0INT if. + AD0INT clr + convs #@ converter convs #! + then + modechange. if. + [ modechange. clr ] + drawmode + mode #@ + 'C' # =if + capture + dmode + then + 'M' # =if + /monitor + then + drop + then + + mode #@ + 'M' # =if + TMR3CN #@ -if + $7f # TMR3CN and! + cool + then drop + RI0 if. + RI0 clr + \monitor + dmode + then + then + drop + + slowc #@ \ 4 Hz + 0=if + results + then +CLOSEUP [IF] + fade. if. + cool [ fade. clr ] + then +[ELSE] + $1f # and 0=if \ 32 Hz + cool + then +[THEN] + drop + again +here + +\ Reset +$000 org go ; + +\ UART interrupt +$023 org + swapctx [ reti ] + +\ Timer 2 overflow +$02b org [ + ] timer2 [ + TF2H clr + reti +] + +\ I2C +$03b org + swapctx [ reti ] + +\ Port mismatch +$043 org + mismatch + +\ Timer 3 overflow +$073 org + FL1 if. timer3 then + timer3a ; + +org diff --git a/firmware/st7735.fs b/firmware/st7735.fs new file mode 100644 index 0000000..dd389f7 --- /dev/null +++ b/firmware/st7735.fs @@ -0,0 +1,698 @@ +$00 constant NOP $2B constant RASET $C2 constant PWCTR3 +$01 constant SWRESET $2C constant RAMWR $C3 constant PWCTR4 +$04 constant RDDID $2E constant RAMRD $C4 constant PWCTR5 +$09 constant RDDST $30 constant PTLAR $C5 constant VMCTR1 +$10 constant SLPIN $36 constant MADCTL $DA constant RDID1 +$11 constant SLPOUT $3A constant COLMOD $DB constant RDID2 +$12 constant PTLON $B1 constant FRMCTR1 $DC constant RDID3 +$13 constant NORON $B2 constant FRMCTR2 $DD constant RDID4 +$20 constant INVOFF $B3 constant FRMCTR3 $E0 constant GMCTRP1 +$21 constant INVON $B4 constant INVCTR $E1 constant GMCTRN1 +$28 constant DISPOFF $B6 constant DISSET5 $FC constant PWCTR6 +$29 constant DISPON $C0 constant PWCTR1 +$2A constant CASET $C1 constant PWCTR2 +$80 constant DELAY + +here constant init-table + SWRESET , DELAY , \ Software reset, 0 args, w/delay + 60 , + SLPOUT , DELAY , \ Out of sleep mode, 0 args, w/delay + 60 , + FRMCTR1 , 3 , \ Frame rate ctrl - normal mode, 3 args: + 0x01 , 0x2C , 0x2D , \ Rate = fosc/(1x2+40) * (LINE+2C+2D) + FRMCTR2 , 3 , \ Frame rate control - idle mode, 3 args: + 0x01 , 0x2C , 0x2D , \ Rate = fosc/(1x2+40) * (LINE+2C+2D) + FRMCTR3 , 6 , \ Frame rate ctrl - partial mode, 6 args: + 0x01 , 0x2C , 0x2D , \ Dot inversion mode + 0x01 , 0x2C , 0x2D , \ Line inversion mode + PWCTR1 , 3 , \ Power control, 3 args: + 0xA2 , + 0x02 , \ -4.6V + 0x84 , \ AUTO mode + PWCTR2 , 1 , \ Power control, 1 arg: + 0xC5 , \ VGH25 = 2.4C VGSEL = -10 VGH = 3 * AVDD + PWCTR3 , 2 , \ Power control, 2 args: + 0x0A , \ Opamp current small + 0x00 , \ Boost frequency + PWCTR4 , 2 , \ Power control, 2 args: + 0x8A , \ BCLK/2, Opamp current small & Medium low + 0x2A , + PWCTR5 , 2 , \ Power control, 2 args: + 0x8A , 0xEE , + VMCTR1 , 1 , \ Power control, 1 arg: + 0x0E , + MADCTL , 1 , \ Memory access control (directions), 1 arg: + 0xC8 , \ row addr/col addr, bottom to top refresh + COLMOD , 1 , \ set color mode, 1 arg: + 0x03 , \ 12-bit color + GMCTRP1 , 16 , \ Gamma + polarity Correction Characterstics + 0x02 , 0x1c , 0x07 , 0x12 , + 0x37 , 0x32 , 0x29 , 0x2d , + 0x29 , 0x25 , 0x2B , 0x39 , + 0x00 , 0x01 , 0x03 , 0x10 , + GMCTRN1 , 16 , \ Gamma - polarity Correction Characterstics + 0x03 , 0x1d , 0x07 , 0x06 , + 0x2E , 0x2C , 0x29 , 0x2D , + 0x2E , 0x2E , 0x37 , 0x3F , + 0x00 , 0x00 , 0x02 , 0x10 , + NORON , 0 , \ Normal display on + 0 , + +:m clk [ 2 .p1 set 2 .p1 clr ] m; +:m 1bit 2*' 1 .p1 movcb clk m; +:m /C/ [ 0 .p1 clr ] m; +:m /D/ [ 0 .p1 set ] m; + +: (>st) 1bit 1bit 1bit 1bit +: _4 1bit 1bit 1bit 1bit 2*' ; +: (4>st) 2*' 2*' 2*' 2*' _4 ; +: 4>st (4>st) drop ; + +: write-cmd ( b ) /C/ +: 1>st ( b ) 1bit 1bit 1bit 1bit 1bit 1bit 1bit 1bit drop ; +: write-data ( b ) /D/ 1>st ; +: data16 ( b ) 0# write-data write-data ; + +: args + begin + 0=if drop; then + @p+ write-data + 1- + again + +: coldregs + init-table ##p! + begin + @p+ + 0=if drop; then + write-cmd + @p+ + dup $7f # and args + -if @p+ ms then + drop + again + +here [ $1000 > throw ] +$1000 org +: dim ( x w ) + over data16 + 1- data16 ; +: rect ( x y w h ) + twist ( x w y h ) + RASET # write-cmd dim + CASET # write-cmd dim +: writing + RAMWR # write-cmd + /D/ +; + +: full + blu #@ (4>st) + grn (#@) (4>st) red (#@) 4>st ; + +:m |4>st 1bit 1bit 1bit 1bit m; + +: half 10 # +: gray + 0=if + drop +: dark + 1 .p1 clr + clk clk clk clk + clk clk clk clk + clk clk clk clk ; + then + 5 (#!) [ blu b mov mul ] $f # + |4>st + 5 (#@) [ grn b mov mul ] $f # + |4>st + 5 (#@) [ red b mov mul ] $f # + |4>st drop ; + +: ndark + 7 #for dark 7 #next ; + +: cls ( ) + 0# 0# 128 # 160 # + rect + + 160 # 6 #for + 128 # ndark + 6 #next ; + +: /st7735 + [ 3 .p1 clr ] + 1 # ms + [ 3 .p1 set ] + coldregs + + cls +: white + $f # +: setgray + red (#!) grn (#!) blu #! ; +: black + 0# setgray ; + +$1fff constant TOPMEM +947 here +include fontsize.fs +[ TOPMEM FONTDATA_SIZE - ] org +include font.fs +here TOPMEM <> throw +org 947 <> throw + + +:m 4.4r ( - l h ) + dup clra + dup $93 , $a3 , \ |@p+ + xchd [swap] m; + +: 4.4 ( - h l ) + 4.4r swap ; + +: skip + 4.4 * 1+ clrc 2/' +: +p + [ dpl add ] dpl (#!) + [ clra dph addc ] dph (#!) + drop; + +: seek ( c - ) \ p points to the data for character c + font ##p! + begin + dup @p+ xor 0=if 2drop ; then + drop skip + again + +: xy! y #! x #! ; +: xy@ x #@ y #@ ; +: adv x #+! ; \ advance cursor + +: preloop ( l h - i j ) + swap if 1u+ then ; + +\ Fill rect with current color +: wash ( x y w h ) + 2dup um* d1+ d2/ preloop 7 #! 6 #! + rect + begin begin + full full + 7 #next 6 #next ; + +: ch ( c - ) + p>r + seek + xy@ + 4.4 ( w h ) + over adv + 2dup * push ( w h r: w*h ) + rect + pop 1+ 2/ 7 #for + 4.4r gray gray + 7 #next + + r>p ; + +: blch + black + xy@ 8 # 9 # wash + 8 # adv white ; + +: str + @p+ 6 #for + @p+ + ch + 6 #next ; + +: setcolor + 4.4 grn #! red #! @p+ blu #! ; + +: hex1 ( h - ) + x #@ 3 # + $7f # xor 4 # + RASET # write-cmd dim + + RAMWR # write-cmd + /D/ + + micro ##p! + $f # and 10 # b #! [ mul ] +p + 10 # 7 #for 4.4r gray gray 7 #next + 5 # x #+! ; + +: drawhex ( hh - ) + y #@ 5 # + CASET # write-cmd dim + + dup [swap] hex1 hex1 ; + +:m gap [ y inc ] m; + +: clip + y #@ +: (clip) + -if + $7f # and negate + ; + then + drop; + +: preblank ( w ) + dup y #@ + (clip) + dup push x #@ -4 # + y #@ + 16 # pop rect + 6 #for 16 # ndark 6 #next ; + +: bitmap + 0 # +: +bitmap ( o ) + x #@ + y #@ + -if 2drop ; then + 4.4 ( w h ) +: (bitmap) ( x y w h ) + dup y #+! + clip + 2dup * push ( w h r: w*h ) + rect + pop 1+ clrc 2/' 7 #for + 4.4r gray gray + 7 #next ; + +: (hex2) + micro ##p! + $f # and 10 # * +p + y #@ -if drop; then drop + x #@ 3 # + y #@ + 5 # 4 # + (bitmap) ; + +: hex2 ( u - ) + dup (hex2) + gap + [swap] (hex2) + ; + +: acknak + 0=if' + $c # red #! + $2 # grn #! + $2 # blu #! ; + then + $2 # red #! + $c # grn #! + $2 # blu #! ; + +: d-byte-ack + acknak + 18 # preblank + gap + dot ##p! + 7 # +bitmap + + gap + + white + hex2 + gap gap gap ; + +: barpoint ( u - ) \ update the slash bar bounds + -if drop; then + dup + talk0 #@ umin talk0 #! + talk1 #@ umax talk1 #! ; + +: slashcolor 8 # setgray ; + +here constant DRAW-SEGMENT \ This block must all be in the same 2K segment + +: startwave + 128 # 7 #! + 0 # 8 # 128 # rect + story # a! + [ + SP x mov + x dec + x dec + 0 y mov + ] ; + +: column + $df cond +: bail + [ + x SP mov + y 0 mov + ] then ; + +: hi full dark dark dark dark dark dark dark column ; +: lo dark dark dark dark dark dark dark full column ; +: change + full full full full full full full full column ; +: undef + half half half half half half half half column ; + +: d-stop + drop a+ + 0 # red #! + 7 # grn #! + 7 # blu #! + symbol-p ##p! +: (d-stop) + 12 # preblank + bitmap ; + +:m y; \ return if y>127 + $bc , 128 , 0 , \ CJNE R4,#128,+0 + 0=if' ; then m; + +: d-direction + arrow ##p! + if' + larrow ##p! + then + $f # red #! + $e # grn #! + $2 # blu #! + -5 # y #+! + bitmap ; + +: slashv ( u - ) \ draw the bottom slash segment + $08 # madctl + MADCTL # write-cmd write-data ; +: ltr + %11001000 # >madctl ; + +: drawmode + black + 0# 0# 2dup 10 # 9 # wash + white xy! mode #@ ch ; + +: fixed + rtl + 3 # setgray + $08 # + 112 # 6 #for + dup d-addr + 1+ + 6 #next + + ltr + + drawmode + + tplan ##p! + begin + @p+ 0=if drop; then + @p+ xy! + setcolor + str + again + +: d-slash + talked. if. + ptalked. if. + ptalker #@ talker @=if drop; then + unslash + then + talker #@ slash ; + then + ptalker #@ unslash ; + +: cool1 ( addr - ) + \ talker @=if talked. if. drop; then then + dup heatmap @x if ( addr h ) + 1- (!x) ingrad + d-addr ; + then + 2drop ; + +: cool + rtl + $08 # + 112 # 6 #for + dup cool1 + 1+ + 6 #next + drop + ltr ; + +\ talked. is true when talker is valid +\ ptalked. and ptalker hold previous values +\ slashx is set to the X of the slash line + +: waves + \ pinkwash + + rtl + + 122 # 0 # xy! + + $ff # talk0 #! + $00 # talk1 #! + talked. clr + + story # a! + l-dispatch + + d-sda + d-scl + + ltr + + d-slash + d-slashbar + + talker #@ ptalker #! + [ talked. movbc ptalked. movcb ] + + DISPON # write-cmd + ;