CON _clkmode = xtal1 + pll16x '80 MHz _xinfreq = 5_000_000 ' The Firecracker header (2 bytes) h1 = $D5 h2 = $AA ' the Firecracker footer (1 byte) foot = $AD ' ------- Pin assigments ------ ' ground DB9 pin 5 on Firecracker dtr = 0 'DB9 pin 4 on Firecracker rts = 1 'DB9 pin 7 on Firecracker VAR byte byt byte house ' 0=A 1=B... byte unit ' 0-15 (must be 0 for bright/dim) byte ucode byte cmd ' 0=off 1=on 2=dim 3=bright 8=all_lights_on 9=all_units_off long useser ' USB serial connection detected T/F long debugsw ' control output to Parallax Terminal byte answer byte dig2[2] OBJ Debug : "FullDuplexSerial" '"SerialMirror" '"Extended_FDSerial" PUB Main dira[dtr..rts]~~ 'set to output useser := false if ina[31] == 1 ' RX (pin 31) is high if USB is connected Debug.start(31, 30, 0, 57600) ' ignore tx echo on rx waitcnt(clkfreq * 3 + cnt) ' Pause for FullDuplexSerial.spin to initialize useser := true ' Debug serial connection is active debugsw := true else outa[30] := 0 ' Force Propeller Tx line LOW if USB not connected if useser == true Debug.tx(16) 'cls Prompt(string("Enter 'y' for interactive mode"),true) answer := Debug.RxTime(5000) if answer <> "y" DemoMode ' Debug.tx(16) 'cls waitcnt(clkfreq / 100 + cnt) repeat Prompt(string(13,"Enter house code: (A thru P)"),false) house := Debug.Rx if house > "Z" house := house-32 'change to uppercase if (house < "A") OR (house > "P") debug.str(string(13,"Invalid house code")) ELSE quit debug.str(string(13,"House: ")) debug.tx(house) debug.tx(" ") house := house - 65 'convert to integer A=0,B=1,...P=15 debug.dec(house) ResetFirecracker repeat getcmd if cmd == 9 'end program quit sendcmd debug.str(string(13,"End Program")) PUB getcmd repeat Prompt(string(13,"Enter command: (0=OFF, 1=ON, 2=DIM, 3=BRIGHT, 7=ALL lights ON, 8=ALL units OFF, 9=QUIT)"),false) cmd := getSerVal(1) if lookdown(cmd : 0,1,2,3,7,8,9) quit debug.str(string(13,"Invalid command")) if cmd <> 9 if cmd < 2 repeat Prompt(string(13,"Enter unit: (1 thru 16)"),false) unit := getSerVal(2) if (unit < 1) OR (unit > 16) debug.str(string(13,"Invalid unit")) else quit else unit := 0 debug.str(string(13,"cmd: ")) debug.dec(cmd) if unit > 0 debug.str(string(" unit: ")) debug.dec(unit) debug.tx(" ") PUB sendcmd sendbyte(h1) 'send 1st byte of header sendbyte(h2) 'send 2nd byte of header byt := byte[@housetbl][house] ' READ housetbl+house,byt ' debug.bin(byt,8) ' debug.tx(13) if unit > 8 byt+=4 '%0100 (unit group code for units 9 thru 16) ' debug.bin(byt,8) ' debug.tx(13) debug.tx("%") debug.bin(byt,8) '1st byte of command debug.tx(" ") sendbyte(byt) 'send 1st byte of command (house & unit group code) IF unit > 0 ucode := byte[@unittbl][(unit-1)//8] ' READ unittbl+((unit-1)//8),ucode 'get unit code from table case cmd 0 : 'off byt := $20 1 : 'on byt := 0 2 : 'dim byt := $98 ucode := 0 3 : 'bright byt := $88 ucode := 0 7 : 'all lights on byt := $90 ucode := 0 8 : 'all units off byt := $80 ucode := 0 byt += ucode debug.tx("%") debug.bin(byt, 8) debug.tx(" ") sendbyte(byt) 'send unit and command sendbyte(foot) 'send footer PUB ResetFirecracker outa[dtr..rts]~ 'dtr & rts low waitcnt(clkfreq / 20 + cnt) 'pause 50ms outa[dtr..rts]~~ 'dtr & rts high waitcnt(clkfreq / 20 + cnt) 'pause 50ms ' waitcnt(clkfreq / 1000 + cnt) 'wait for .001 seconds (1 ms) ' waitcnt(clkfreq / 100 + cnt) 'wait for .01 seconds (10 ms) ' waitcnt(clkfreq / 10 + cnt) 'wait for .1 seconds (100 ms) ' waitcnt(clkfreq / 200 + cnt) 'wait for .005 seconds (5 ms) ' waitcnt(clkfreq / 20 + cnt) 'wait for .05 seconds (50 ms) ' Send 1 raw byte PUB sendbyte(raw) | bcnt debug.tx("$") debug.hex(raw,2) debug.tx(" ") repeat bcnt from 0 to 7 IF (raw & %1000_0000) == %1000_0000 'if bit 7 is set outa[dtr]~ 'send a one (dtr low then high) waitcnt(clkfreq / 1000 + cnt) 'pause 1 ms outa[dtr]~~ ELSE outa[rts]~ 'send a zero (rts low then high) waitcnt(clkfreq / 1000 + cnt) 'pause 1 ms outa[rts]~~ waitcnt(clkfreq / 1000 + cnt) 'pause 1 ms raw <<= 1 'left shift 1 bit PRI Prompt(msg, CR) Debug.str(msg) if CR Debug.tx(13) PUB getSerVal(lim) : value | bytesread, tmp, z, place Debug.RxFlush bytesread := 0 value := 0 place := 1 repeat while bytesread < lim tmp := Debug.Rx if ((tmp == 10) OR (tmp ==13) OR (tmp == "*")) QUIT if (tmp => ("0")) and (tmp =< ("9")) dig2[bytesread] := tmp bytesread++ repeat z from (bytesread - 1) to 0 value := value + ((dig2[z]-"0") * place) place := place * 10 PRI DemoMode | x, y debug.str(string(13,"DemoMode",13)) ResetFirecracker repeat 'repeat indefinitely house := 2 ' "C" repeat x from 2 TO 6 unit := x cmd := 1 ' "on" sendcmd debug.tx(13) waitcnt(clkfreq * 2 + cnt) IF x == 3 'for unit 3, dim repeat y from 0 TO 5 cmd := 2 ' "dim" sendcmd debug.tx(13) waitcnt(clkfreq * 2 + cnt) waitcnt(clkfreq * 2 + cnt) repeat x from 2 TO 6 unit := x cmd := 0 ' "off" sendcmd debug.tx(13) waitcnt(clkfreq * 2 + cnt) DAT ' Data for house codes (A-P) and unit codes (1-16) housetbl byte $60,$70,$40,$50,$80,$90,$A0,$B0,$E0,$F0,$C0,$D0,$00,$10,$20,$30 unittbl byte 0,$10,$8,$18,$40,$50,$48,$58