;-----------------------------------------------------------------------------------------------; ; Program: "support.djb.bas" ; ; Developed by David J. Brown ; ; Copyright (c) April 13, 2004 David J. Brown ; ; Email: davebr@earthlink.net ; ; Web site: http://modularsynthesis.com ; ;-----------------------------------------------------------------------------------------------; ; LICENSE AGREEMENT: ; ; This program is free software. You can redistribute it and/or modify it. ; ; ; ; This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, ; ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ; ;-----------------------------------------------------------------------------------------------; ; ; Revision: 1.1S2 ; Date: Sept 23, 2010 ; History: 1.1S2 modified serial syntax for Studio 2.0 ; 1.0S adapted from PSIM-CVS-CVS4 Template V1.6S ; Written: April 13, 2004 ; ; Description ; This is an #include support program for the PSIM, CVS or CVS4 which provides: ; hardware initialization ; serial hardware initialization (MIDI rate) ; TTS256/speakjet communication support (DJB PSIM) ; TTS256/speakjet hexadecimal phrase support (DJB PSIM) ; 1 mS timer interrupts support ; analog output support ; analog input support including averaged (polled and interrupt) or with hysteresis ; rising edge detect support (for pulse width > 1 mS) ; aux input rising edge interrupt support ; hex to decimal conversion for fixed column width LCD display ; LCD display of all input or output voltages to 1 decimal point (e.g. 8.6) ; AtomPro28 non-volatile memory map ; ;-----------------------------------------------------------------------------------------------; ; AtomPro Pin Definitions ; ;-----------------------------------------------------------------------------------------------; ; P0 - analog in-1 ; ; P1 - analog in-2 ; ; P2 - analog in-3 ; ; P3 - analog in-4 ; ; P4 - start button (no input/default=low, pressed=hi) ; ; P5 - stop button (no input/default=low, pressed=hi) ; ; P6 - I2C data ; ; P7 - I2C clock ; ; P8 - aux in/out (PSIM: no input=hi, CVS: no input=low) ; ; P9 - stop led (low=off, hi=on) ; ; P10 - run led (low=off hi=on) ; ; P11 - DAC loaddacs ; ; P12 - DAC serial data ; ; P13 - DAC clock ; ; P14 - MIDI in ; ; P15 - MIDI out ; ; P16 - analog in-8 (CVS) ; ; P17 - analog in-7 (CVS) ; ; P18 - analog in-5 (CVS) ; ; P19 - analog in-6 (CVS) ; ;-----------------------------------------------------------------------------------------------; ; LCD Commands ; ;-----------------------------------------------------------------------------------------------; ; $08 - (backspace) moves the active display position one backwards ; ; $09 - (tab) moves the active display position one forward ; ; $0a - (line feed) clears the display & sets active display position to beginning of line 1 ; ; $0b - (vertical tab) sets the active display position to beginning of line 2 ; ; $0c - (form feed) clears the display & sets active display position to beginning of line 2 ; ; $0d - (carriage return) Sets the active display position to beginning of line 1 ; ; $0e - (shift out) selects the lower characters set for display ; ; $0f - (shift in) selects the upper characters set for display ; ; $10 - program character0 row7, row6 ... row0 (bottom) ; ; $11 - program character1 row7, row6 ... row0 (bottom) ; ; $12 - program character2 row7, row6 ... row0 (bottom) ; ; $13 - program character3 row7, row6 ... row0 (bottom) ; ; $14 - program character4 row7, row6 ... row0 (bottom) ; ; $15 - program character5 row7, row6 ... row0 (bottom) ; ; $16 - program character6 row7, row6 ... row0 (bottom) ; ; $17 - program character7 row7, row6 ... row0 (bottom) ; ; $18 - sets the display mode to overwrite; new characters overwrite previous ; ; $19 - sets the display mode to scroll; display scrolls for new characters ; ; $1a - sets absolute position data ; ; $1b - sets relative position data ; ; $1c - n/a ; ; $1d - n/a ; ; $1e - n/a ; ; $1f - writes new default message character 1, character 2 ... character 32 ; ; ; LCD Commands (DJB-PSIM) ; ; $1a - n/a ; ; $1b - n/a ; ; $1c - set Out1 data (0=no change, 1=reset to low, 2=set to hi, 3=toggle) ; ; $1d - set Out2 data (0=no change, 1=reset to low, 2=set to hi, 3=toggle) ; ; $1e - set Out3 data (0=no change, 1=reset to low, 2=set to hi, 3=toggle) ; ; $1f - set Out4 data (0=no change, 1=reset to low, 2=set to hi, 3=toggle) ; ;-----------------------------------------------------------------------------------------------; ; TTS-256 Commands (DJB-PSIM) ; ;-----------------------------------------------------------------------------------------------; ; enable TTS256 pass through: i2cout i2c_data,i2c_clk,$0,[($48<<1),"passthruon",$0d] ; ; terminate TTS256 pass through: i2cout i2c_data,i2c_clk,$0,[($48<<1),"X"] ; ;-----------------------------------------------------------------------------------------------; ; SpeakJet Commands (DJB-PSIM) ; ;-----------------------------------------------------------------------------------------------; ; $00 - pause 0 mS ; ; $01 - pause 100 mS ; ; $02 - pause 200 mS ; ; $03 - pause 700 mS ; ; $04 - pause 30 mS ; ; $05 - pause 60 mS ; ; $06 - pause 90 mS ; ; $07 - play next sound fast ; ; $08 - play next sound slow ; ; $0e - play next sound high tone ; ; $0f - play next sound low tone ; ; $15 - speed ; ; $16 - pitch ; ; $17 - pitch ; ; $c8 to $d1 - robot sounds ; ; $d2 to $db - alarm sounds ; ; $dc to $e5 - beep sounds ; ; $e6 to $ef - biological sounds ; ; $f0 to $fb - DTMF sounds (0 - 9, *, #) ; ; $fc - sonar ping ; ; $fd - pistol shot ; ; $fe - wow ; ;-----------------------------------------------------------------------------------------------; ; Non-Volatile Memory Map ; ;-----------------------------------------------------------------------------------------------; nv_step_max con 0 ;adr000 step_max nv_midi_offset con 1 ;adr001 midi_offset nv_gate1_lo con 2 ;adr002 gate1.byte0 nv_gate1_hi con 3 ;adr003 gate1.byte1 nv_gate2_lo con 4 ;adr004 gate2.byte0 nv_gate2_hi con 5 ;adr005 gate2.byte1 nv_patch con 6 ;16 byte patch array ;nv_patch(0) con 6 ;adr006 step 1 patch ;nv_patch(1) con 7 ;adr007 step 2 patch ;nv_patch(2) con 8 ;adr008 step 3 patch ;nv_patch(3) con 9 ;adr009 step 4 patch ;nv_patch(4) con 10 ;adr010 step 5 patch ;nv_patch(5) con 11 ;adr011 step 6 patch ;nv_patch(6) con 12 ;adr012 step 7 patch ;nv_patch(7) con 13 ;adr013 step 8 patch ;nv_patch(8) con 14 ;adr014 step 9 patch ;nv_patch(9) con 15 ;adr015 step 10 patch ;nv_patch(10) con 16 ;adr016 step 11 patch ;nv_patch(11) con 17 ;adr017 step 12 patch ;nv_patch(12) con 18 ;adr018 step 13 patch ;nv_patch(13) con 19 ;adr019 step 14 patch ;nv_patch(14) con 20 ;adr020 step 15 patch ;nv_patch(15) con 21 ;adr021 step 16 patch nv_seq_mode con 22 ;adr022 seq_mode nv_unused con 23 ;unused address ;-----------------------------------------------------------------------------------------------; ; Pin Declarations ; ;-----------------------------------------------------------------------------------------------; pin_j1 con p0 ;in-1 pin pin_j2 con p1 ;in-2 pin pin_j3 con p2 ;in-3 pin pin_j4 con p3 ;in-4 pin #ifdef cvs ;pin definitions redefined for Studio and IDE 8.0.1.7 and later pin_j5 con p18 ;in-5 pin pin_j6 con p19 ;in-6 pin pin_j7 con p17 ;in-7 pin pin_j8 con p16 ;in-8 pin ; #endif start_j var in4 ;start jack and switch stop_j var in5 ;stop jack and switch i2c_data con p6 ;i2c data pin i2c_clk con p7 ;i2c clock pin aux_j con p8 ;aux jack (use for output) aux_in var in8 ;aux jack (use for input) stop_led con p9 ;stop led stop_led_out var out9 ;stop led alias (for use with LET command) run_led con p10 ;run led run_led_out var out10 ;run led alias (for use with LET command) dac_load con p11 ;dac loaddacs pin dac_sdata con p12 ;dac serial data pin dac_clk con p13 ;dac clock pin ;-----------------------------------------------------------------------------------------------; ; I/O Declarations ; ;-----------------------------------------------------------------------------------------------; #ifndef cvs in_jk var word(4) in_j1 var in_jk(0) ;in-1 value: get_inputs, get_inputs_avg, avg1 in_j2 var in_jk(1) ;in-2 value: get_inputs, get_inputs_avg, avc2 in_j3 var in_jk(2) ;in-3 value: get_inputs, get_inputs_avg, avg3 in_j4 var in_jk(3) ;in-4 value: get_inputs, get_inputs_avg, avg4 #else in_jk var word(8) in_j1 var in_jk(0) ;in-1 value: get_inputs, get_inputs_avg, avg1 in_j2 var in_jk(1) ;in-2 value: get_inputs, get_inputs_avg, avc2 in_j3 var in_jk(2) ;in-3 value: get_inputs, get_inputs_avg, avg3 in_j4 var in_jk(3) ;in-4 value: get_inputs, get_inputs_avg, avg4 in_j5 var in_jk(4) ;in-5 value: get_inputs, get_inputs_avg, avg1 in_j6 var in_jk(5) ;in-6 value: get_inputs, get_inputs_avg, avc2 in_j7 var in_jk(6) ;in-7 value: get_inputs, get_inputs_avg, avg3 in_j8 var in_jk(7) ;in-8 value: get_inputs, get_inputs_avg, avg4 #endif out_j1 var word ;out-1 value: load_outputs out_j2 var word ;out-2 value: load_outputs out_j3 var word ;out-3 value: load_outputs out_j4 var word ;out-4 value: load_outputs #ifdef cvs out_j5 var word ;out-5 value: load_outputs out_j6 var word ;out-6 value: load_outputs out_j7 var word ;out-7 value: load_outputs out_j8 var word ;out-8 value: load_outputs #endif #ifndef psim olat var byte ;control output latch: load_outputs ; bit7=dac2 select (hi=enable) ; bit6=dac1 select (hi=enable) ; bit5=n/a ; bit4=n/a ; bit3=n/a ; bit2=offset range (hi=5 volts, low=10 volts) ; bit1=offset voltage enable (hi=enable) ; bit0=control voltage enable (hi=enable) #endif ;-----------------------------------------------------------------------------------------------; ; Timer Declarations ; ;-----------------------------------------------------------------------------------------------; #ifdef timer_int_en time_count var long ;1 mS timer count value: tm_isr turn_off var long ;time value to turn off stop led: tm_isr #endif ;-----------------------------------------------------------------------------------------------; ; Edge Detect Declarations ; ;-----------------------------------------------------------------------------------------------; #ifdef edge_int_en edge_state var byte ;eight samples of edge input: tm_isr edge_flg var byte ;edge flag (1=rising edge, 0=no rising edge): tm_isr #endif #ifdef aux_int_en aux_cnt var word ;aux interrupt count: aux_isr #endif ;-----------------------------------------------------------------------------------------------; ; Input Buffer Declarations ; ;-----------------------------------------------------------------------------------------------; idx var byte ;index pointer: get_inputs_hys b_idx var byte ;buffer index pointer: get_inputs_avg w_idx var byte ;word index pointer: get_inputs_avg in_j1_ptr var byte ;in-1 buffer pointer: avgx, get_inputs_avg #ifdef input_int_en isr_cnt var nib ;timer pass counter: tm_isr in_j2_ptr var byte ;in-2 buffer pointer: avgx in_j3_ptr var byte ;in-3 buffer pointer: avgx in_j4_ptr var byte ;in-4 buffer pointer: avgx in_j5_ptr var byte ;in-5 buffer pointer: avgx in_j6_ptr var byte ;in-6 buffer pointer: avgx in_j7_ptr var byte ;in-7 buffer pointer: avgx in_j8_ptr var byte ;in-8 buffer pointer: avgx #endif #ifndef cvs in_jk_avg var long(8) in_j1_bfr var in_jk_avg(0) ;in-1 last 4 samples buffer: avgx, get_inputs_avg in_j2_bfr var in_jk_avg(2) ;in-2 last 4 samples buffer: avgx, get_inputs_avg in_j3_bfr var in_jk_avg(4) ;in-3 last 4 samples buffer: avgx, get_inputs_avg in_j4_bfr var in_jk_avg(6) ;in-4 last 4 samples buffer: avgx, get_inputs_avg #else in_jk_avg var long(16) in_j1_bfr var in_jk_avg(0) ;in-1 last 4 samples buffer: avgx, get_inputs_avg in_j2_bfr var in_jk_avg(2) ;in-2 last 4 samples buffer: avgx, get_inputs_avg in_j3_bfr var in_jk_avg(4) ;in-3 last 4 samples buffer: avgx, get_inputs_avg in_j4_bfr var in_jk_avg(6) ;in-4 last 4 samples buffer: avgx, get_inputs_avg in_j5_bfr var in_jk_avg(8) ;in-5 last 4 samples buffer: avgx, get_inputs_avg in_j6_bfr var in_jk_avg(10) ;in-6 last 4 samples buffer: avgx, get_inputs_avg in_j7_bfr var in_jk_avg(12) ;in-7 last 4 samples buffer: avgx, get_inputs_avg in_j8_bfr var in_jk_avg(14) ;in-8 last 4 samples buffer: avgx, get_inputs_avg #endif #ifdef psim hys con 3 ;PSIM hysteresis +/- value #else hys con 2 ;CVS hysteresis +/- value #endif #ifndef cvs in_jk_hy var word(8) in_j1_low var in_jk_hy(0) ;in-1 low value: get_inputs_hy in_j1_high var in_jk_hy(1) ;in-1 high value: get_inputs_hy in_j2_low var in_jk_hy(2) ;in-2 low value: get_inputs_hy in_j2_high var in_jk_hy(3) ;in-2 high value: get_inputs_hy in_j3_low var in_jk_hy(4) ;in-3 low value: get_inputs_hy in_j3_high var in_jk_hy(5) ;in-3 high value: get_inputs_hy in_j4_low var in_jk_hy(6) ;in-4 low value: get_inputs_hy in_j4_high var in_jk_hy(7) ;in-4 high value: get_inputs_hy #else in_jk_hy var word(16) in_j1_low var in_jk_hy(0) ;in-1 low value: get_inputs_hy in_j1_high var in_jk_hy(1) ;in-1 high value: get_inputs_hy in_j2_low var in_jk_hy(2) ;in-2 low value: get_inputs_hy in_j2_high var in_jk_hy(3) ;in-2 high value: get_inputs_hy in_j3_low var in_jk_hy(4) ;in-3 low value: get_inputs_hy in_j3_high var in_jk_hy(5) ;in-3 high value: get_inputs_hy in_j4_low var in_jk_hy(6) ;in-4 low value: get_inputs_hy in_j4_high var in_jk_hy(7) ;in-4 high value: get_inputs_hy in_j5_low var in_jk_hy(8) ;in-5 low value: get_inputs_hy in_j5_high var in_jk_hy(9) ;in-5 high value: get_inputs_hy in_j6_low var in_jk_hy(10) ;in-6 low value: get_inputs_hy in_j6_high var in_jk_hy(11) ;in-6 high value: get_inputs_hy in_j7_low var in_jk_hy(12) ;in-7 low value: get_inputs_hy in_j7_high var in_jk_hy(13) ;in-7 high value: get_inputs_hy in_j8_low var in_jk_hy(14) ;in-8 low value: get_inputs_hy in_j8_high var in_jk_hy(15) ;in-8 high value: get_inputs_hy #endif ;-----------------------------------------------------------------------------------------------; ; LCD Declarations ; ;-----------------------------------------------------------------------------------------------; num_data var word ;data for ascii conversion: hex2ascii tths var byte ;ten thousands digit: hex2ascii thos var byte ;thousands digit: hex2ascii huns var byte ;hundreds digit: hex2ascii tens var byte ;tens digit: hex2ascii, display_in, display_out ones var byte ;ones digit: hex2ascii, display_in, display_out ;-----------------------------------------------------------------------------------------------; ; External Controls Declarations ; ;-----------------------------------------------------------------------------------------------; #ifndef psim ext_ctrl var byte ;external control flag (1=present, 0=not present): check_ext key_data var byte ;keypad data: key_keynum key_prev var byte ;previous keypad data: key_keynum key_temp var byte ;temp keypad: key_keynum key_entry var word ;0-999 keypad entry: get_keyentry #endif ;-----------------------------------------------------------------------------------------------; ; Speakjet Declarations ; ;-----------------------------------------------------------------------------------------------; #ifdef spj spkj_data var byte ;data: send_speakjet phrase1 var byte ;temporary variable: hex_speakjet phrase2 var byte ;temporary variable: hex_speakjet data_hex var byte ;hex data: hex_speakjet #endif ;-----------------------------------------------------------------------------------------------; ; Misc Declarations ; ;-----------------------------------------------------------------------------------------------; tempb var byte ;temporary variable tempw var word ;temporary variable templ var long ;temporary variable fivevolts con 1920 ;5 volt output value #ifdef cvs gra_val con 2003 ;measured resonator divisor for 1 mS #endif #ifdef cvs4 gra_val con 2000 ;measured resonator divisor for 1 mS #endif #ifdef psim gra_val con 2005 ;measured resonator divisor for 1 mS #endif ;-----------------------------------------------------------------------------------------------; ; Table Declarations ; ;-----------------------------------------------------------------------------------------------; pin_tbl bytetable 0,1,2,3,18,19,17,16 ;analog input pins phrase bytetable "0123456789ABCDEF" ;tts256 digit phrases for hex output ;------------------------------------------+----------+-----------------------------------------; ; NV Memory Map | address | variable ; ;------------------------------------------+----------+-----------------------------------------; nv_step_max con 0 ;adr000 step_max nv_midi_offset con 1 ;adr001 midi_offset nv_gate1_lo con 2 ;adr002 gate1.byte0 nv_gate1_hi con 3 ;adr003 gate1.byte1 nv_gate2_lo con 4 ;adr004 gate2.byte0 nv_gate2_hi con 5 ;adr005 gate2.byte1 nv_patch con 6 ;adr006 step 1 patch ;nv_patch(1) con 7 ;adr007 step 2 patch ;nv_patch(2) con 8 ;adr008 step 3 patch ;nv_patch(3) con 9 ;adr009 step 4 patch ;nv_patch(4) con 10 ;adr010 step 5 patch ;nv_patch(5) con 11 ;adr011 step 6 patch ;nv_patch(6) con 12 ;adr012 step 7 patch ;nv_patch(7) con 13 ;adr013 step 8 patch ;nv_patch(8) con 14 ;adr014 step 9 patch ;nv_patch(9) con 15 ;adr015 step 10 patch ;nv_patch(10) con 16 ;adr016 step 11 patch ;nv_patch(11) con 17 ;adr017 step 12 patch ;nv_patch(12) con 18 ;adr018 step 13 patch ;nv_patch(13) con 19 ;adr019 step 14 patch ;nv_patch(14) con 20 ;adr020 step 15 patch ;nv_patch(15) con 21 ;adr021 step 16 patch nv_seq_mode con 22 ;adr022 seq_mode ; ;-----------------------------------------------------------------------------------------------; ; Initialization ; ;-----------------------------------------------------------------------------------------------; ; #ifndef psim dires=%0000000000000000 ;configure pin direction (1=output, 0=input) ;inputs: in-7, in-6, in-5, in-4 #endif dirs =%0001011000000000 ;configure pin direction (1=output, 0=input) ;note: setting midi-out, i2c_clock, i2c_data, and dac_load to outputs can glitch so initialize as inputs ;inputs: midi-in, aux, start, stop, in-4, in-3, in-2, in-1 ;initialize as inputs: midi-out, dac_clk, dac_load, ic2_data, ic2_clk ;outputs: dac_sdata, stop led, run led high dac_load ;set dac load high high dac_clk ;set dac clock high so chip select will not clock low run_led ;reset run led low stop_led ;reset stop led ;initialize memory clear ;initialize all memory to 0 ;initialize control hardware #ifndef psim let olat=$ff ;set olat to default i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat];set outputs to olat i2cout i2c_data,i2c_clk,($20<<1),[$00,$00] ;then set iodir to output #endif ;initialize outputs ; let out_j1=0 ;set out-1 low ; let out_j2=0 ;set out-2 low ; let out_j3=0 ;set out-3 low ; let out_j4=0 ;set out-4 low ;#ifdef cvs ; let out_j5=0 ;set out-5 low ; let out_j6=0 ;set out-6 low ; let out_j7=0 ;set out-7 low ; let out_j8=0 ;set out-8 low ;#endif gosub load_outputs ;initialize input variables ; let in_j1_ptr=0 ;reset in-1 pointer ;#ifdef input_int_en ; let in_j2_ptr=0 ;reset in-2 pointer ; let in_j3_ptr=0 ;reset in-3 pointer ; let in_j4_ptr=0 ;reset in-4 pointer ; let in_j5_ptr=0 ;reset in-2 pointer ; let in_j6_ptr=0 ;reset in-2 pointer ; let in_j7_ptr=0 ;reset in-3 pointer ; let in_j8_ptr=0 ;reset in-4 pointer ; let isr_cnt=0 ;reset isr pass counter ;#endif #ifndef cvs for idx=0 to 3 ;initialize in-x hysteresis value #else for idx=0 to 7 #endif let in_jk_hy(idx*2)=0 ;low hysteresis value let in_jk_hy((idx*2)+1)=2*hys ;high hysteresis value next #ifndef cvs for idx=0 to 7 ;initialize in-x buffers #else for idx=0 to 15 #endif let in_jk_avg(idx)=0 next ;define external control variables #ifndef psim let key_prev=255 ;set keypad to all keys up ; let ext_ctrl=0 ;default to external controls not present #endif ;#ifdef edge_int_en ;define edge interrupt variables ; let edge_state=0 ;reset current state ; let edge_flg=0 ;reset edge flag ;#endif #ifdef input_int_en ;enable aux_in rising edge interrupts ; let aux_cnt=0 ;reset count let pmr1=pmr1|%00100000 ;set Port Mode Register to enable irq1 let iegr1=iegr1|%00000010 ;set irq1 to rising edge let irr1=irr1&%11111101 ;clear any pending interrupt oninterrupt irq1int,aux_isr enable irq1int ;enable rising edge interrupts #endif ;initialize timerW hardware for 1 mS #ifdef timer_int_en let tmrw=%10001000 ;set Timer Mode Register to enable count let tcrw=%10110000 ;set Timer Control Register ; clear on compare match A ; 16 MHz clock /8 prescalar S = 2 MHz timer clock let gra=gra_val ;divide 2 MHz for 1 mS interrupt ; let time_count=0 ;initialize real time count ; let turn_off=0 ;initialize turn off time oninterrupt timerwint_imiea, tm_isr enable timerwint_imiea ;enable timer interrupt #endif ;initialize serial hardware sethserial1 h31200,h8databits,hnoparity,h1stopbits ;enables global interrupts ; goto initialize ;start main program ; ;-----------------------------------------------------------------------------------------------; ; SpeakJet Subroutines ; ;-----------------------------------------------------------------------------------------------; ; #ifdef spj ;send spkj_data via i2c ;retransmit on error for flow control send_speakjet: i2cout i2c_data,i2c_clk,send_speakjet,($48<<1),[spkj_data] ;send to TTS256 return ; ;send data_hex to speakjet ;pause 100 mS before first nibble and 60 mS before second nibble ;written by David J. Brown hex_speakjet: let phrase1=data_hex>>4 ;get high nibble let phrase1=phrase(phrase1) ;get first byte let phrase2=data_hex&$0f ;get bottom nibble let phrase2=phrase(phrase2) ;get first byte hex_error: i2cout i2c_data,i2c_clk,hex_error,($48<<1),[$01,phrase1,$05,phrase2,$0d] ;send to TTS256 return #endif ; ;-----------------------------------------------------------------------------------------------; ; Display Subroutines ; ;-----------------------------------------------------------------------------------------------; ; ;program input voltage characters prog_in_chars: hserout [$f0,$7d,$10,$01,$1f,$09,$00,$11,$1f,$11,$f7] ;character0 "I1" hserout [$f0,$7d,$11,$0d,$15,$17,$00,$11,$1f,$11,$f7] ;character1 "I2" hserout [$f0,$7d,$12,$0e,$15,$15,$00,$11,$1f,$11,$f7] ;character2 "I3" hserout [$f0,$7d,$13,$1f,$04,$1c,$00,$11,$1f,$11,$f7] ;character3 "I4" #ifdef cvs hserout [$f0,$7d,$14,$12,$15,$1d,$00,$11,$1f,$11,$f7] ;character4 "I5" hserout [$f0,$7d,$15,$02,$15,$0e,$00,$11,$1f,$11,$f7] ;character5 "I6" hserout [$f0,$7d,$16,$18,$17,$10,$00,$11,$1f,$11,$f7] ;character6 "I7" hserout [$f0,$7d,$17,$0a,$15,$0a,$00,$11,$1f,$11,$f7] ;character7 "I8" #endif return ; ;program output voltage characters prog_out_chars: hserout [$f0,$7d,$10,$01,$1f,$09,$00,$0e,$11,$0e,$f7] ;character0 "O1" hserout [$f0,$7d,$11,$0d,$15,$17,$00,$0e,$11,$0e,$f7] ;character1 "O2" hserout [$f0,$7d,$12,$0e,$15,$15,$00,$0e,$11,$0e,$f7] ;character2 "O3" hserout [$f0,$7d,$13,$1f,$04,$1c,$00,$0e,$11,$0e,$f7] ;character3 "O4" #ifdef cvs hserout [$f0,$7d,$14,$12,$15,$1d,$00,$0e,$11,$0e,$f7] ;character4 "O5" hserout [$f0,$7d,$15,$02,$15,$0e,$00,$0e,$11,$0e,$f7] ;character5 "O6" hserout [$f0,$7d,$16,$18,$17,$10,$00,$0e,$11,$0e,$f7] ;character6 "O7" hserout [$f0,$7d,$17,$0a,$15,$0a,$00,$0e,$11,$0e,$f7] ;character7 "O8" #endif return ; ;convert word num_data to five ascii digits ;updates tths, thos, huns, tens, ones variables ;use to generate leading zeros for fixed column display ;written by David J. Brown hex2ascii: let tempw=num_data ;use temp to save data let tths=(tempw/10000)+$30 ;get ten thousands and convert to ascii let tempw=tempw//10000 ;get thousands remainder let thos=(tempw/1000)+$30 ;get thousands and convert to ascii let tempw=tempw//1000 ;get hundreds remainder let huns=(tempw/100)+$30 ;get hundreds and convert to ascii let tempw=tempw//100 ;get tens remainder let tens=(tempw/10)+$30 ;get tens and convert to ascii let ones=(tempw//10)+$30 ;get ones remainder and convert to ascii return ; ;display input voltages in_jx ;range must be 0 - 1023 ;10 displays as "X" (e.g. X.0 volts) ;written by David J. Brown display_in: let tempw.highbyte=tens ;save tens let tempw.lowbyte=ones ;save ones ;(*33)/337 is divide by 10.23 to convert 1023 to 100 (10.0 volts) let tempb=(in_j1*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$f0,$7d,$0d,$00,ones,".",tens] ;home1 and display in_j1 voltage let tempb=(in_j2*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$01,ones,".",tens] ;display in_j2 voltage let tempb=(in_j3*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$02,ones,".",tens] ;display in_j3 voltage let tempb=(in_j4*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii #ifndef cvs hserout [$03,ones,".",tens,$f7] ;display in_j4 voltage and terminate sysex #else hserout [$03,ones,".",tens] ;display in_j4 voltage let tempb=(in_j5*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$0b,$04,ones,".",tens] ;home2 and display in_j5 voltage let tempb=(in_j6*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$05,ones,".",tens] ;display in_j6 voltage let tempb=(in_j7*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$06,ones,".",tens] ;display in_j7 voltage let tempb=(in_j8*33)/337 ;scale 0 to 100 gosub display_in_sub ;convert to ascii hserout [$07,ones,".",tens,$f7] ;display in_j8 voltage and terminate sysex #endif let tens=tempw.highbyte ;restore tens let ones=tempw.lowbyte ;restore ones return display_in_sub: if tempb=100 then ;check for 10.0 let ones=$58 ;set ones digit to X let tens=$30 ;set tenths digit to 0 else let tempb=bin2bcd tempb ;convert to two digits let ones=(tempb.nib1)+$30 ;get ones digit and convert to ascii let tens=(tempb.nib0)+$30 ;get tenths digit and convert to ascii endif return ; ;display output voltages out_jx ;range must be 0 - 4095 ;10 displays as "X" (e.g. X.3 volts) ;written by David J. Brown display_out: let tempw.highbyte=tens ;save tens let tempw.lowbyte=ones ;save ones ;(/4)*25)/240 is divide by 38.4 to convert 4095 to 106 (10.6 volts) let tempb=((out_j1/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$f0,$7d,$0d,$00,ones,".",tens] ;home1 and display out_j1 voltage let tempb=((out_j2/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$01,ones,".",tens] ;display out_j2 voltage let tempb=((out_j3/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$02,ones,".",tens] ;display out_j2 voltage let tempb=((out_j4/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii #ifndef cvs hserout [$03,ones,".",tens,$f7] ;display out_j4 voltage and terminate sysex #else hserout [$03,ones,".",tens] ;display out_j4 voltage let tempb=((out_j5/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$0b,$04,ones,".",tens] ;home2 and display out_j5 voltage let tempb=((out_j6/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$05,ones,".",tens] ;display out_j6 voltage let tempb=((out_j7/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$06,ones,".",tens] ;display out_j7 voltage let tempb=((out_j8/4)*25)/240 ;scale 0 to 100 gosub display_out_sub ;convert to ascii hserout [$07,ones,".",tens,$f7] ;display out_j8 voltage and terminate sysex #endif let tens=tempw.highbyte ;restore tens let ones=tempw.lowbyte ;restore ones return display_out_sub: if tempb>99 then ;check for 10.0 to 10.6 let ones=$58 ;set ones digit to X let tens=(tempb-100)+$30 ;set tenths digit to remainder else let tempb=bin2bcd tempb ;convert to two digits let ones=(tempb.nib1)+$30 ;get ones digit and convert to ascii let tens=(tempb.nib0)+$30 ;get tenths digit and convert to ascii endif return ; ;-----------------------------------------------------------------------------------------------; ; Input and Output Subroutines ; ;-----------------------------------------------------------------------------------------------; ; ;sample in-1 to in-4 ;in_jx is input value (0 - 1023) ;150 uS execution time for PSIM ;300 uS execution time for CVS get_inputs: adin pin_j1,in_j1 adin pin_j2,in_j2 adin pin_j3,in_j3 adin pin_j4,in_j4 #ifdef cvs adin pin_j5,in_j5 adin pin_j6,in_j6 adin pin_j7,in_j7 adin pin_j8,in_j8 #endif return ; ;sample and average in-1 to in-x ;in_jx is input value averaged over last four samples (0 - 1023) ;1.1 uS execution time for PSIM/CVS4 ;2.2 mS execution time for CVS ;written by David J. Brown ;get_inputs_avg: ;#ifndef cvs ; for idx=0 to 3 ;#else ; for idx=0 to 7 ;#endif ; let b_idx=idx*2 ; adin pin_tbl(idx),in_jk_avg.word1(b_idx+w_idx) ;get new value into buffer ; let templ=in_jk_avg(b_idx)+in_jk_avg(b_idx+1) ;add two high words together and low words together ; let in_jk(idx)=(templ.word1+templ.word0)/4 ; next ; let w_idx=(w_idx+1)&$03 ;increment pointer and wrap at 3 ; return ; ; ;sample and average in-1 to in-x ;in_jx is input value averaged over last four samples (0 - 1023) ;in_jx_bfr(0) & in_jx_bfr(1) are last four word samples ;600 uS execution time for PSIM/CVS4 ;1.2 mS execution time for CVS ;written by David J. Brown get_inputs_avg: adin pin_j1,in_j1_bfr.word1(in_j1_ptr) ;get in-1 into buffer let templ=in_j1_bfr(0)+in_j1_bfr(1) ;add two high words together and low words together let in_j1=(templ.word1+templ.word0)/4 adin pin_j2,in_j2_bfr.word1(in_j1_ptr) ;get in-2 into buffer templ=in_j2_bfr(0)+in_j2_bfr(1) ;add two high words together and low words together let in_j2=(templ.word1+templ.word0)/4 adin pin_j3,in_j3_bfr.word1(in_j1_ptr) ;get in-3 into buffer let templ=in_j3_bfr(0)+in_j3_bfr(1) ;add two high words together and low words together let in_j3=(templ.word1+templ.word0)/4 adin pin_j4,in_j4_bfr.word1(in_j1_ptr) ;get in-4 into buffer let templ=in_j4_bfr(0)+in_j4_bfr(1) ;add two high words together and low words together let in_j4=(templ.word1+templ.word0)/2 #ifdef cvs adin pin_j5,in_j5_bfr.word1(in_j1_ptr) ;get in-5 into buffer let templ=in_j5_bfr(0)+in_j5_bfr(1) ;add two high words together and low words together let in_j5=(templ.word1+templ.word0)/4 adin pin_j6,in_j6_bfr.word1(in_j1_ptr) ;get in-6 into buffer let templ=in_j6_bfr(0)+in_j6_bfr(1) ;add two high words together and low words together let in_j6=(templ.word1+templ.word0)/4 adin pin_j7,in_j7_bfr.word1(in_j1_ptr) ;get in-7 into buffer let templ=in_j7_bfr(0)+in_j7_bfr(1) ;add two high words together and low words together let in_j7=(templ.word1+templ.word0)/4 adin pin_j8,in_j8_bfr.word1(in_j1_ptr) ;get in-8 into buffer let templ=in_j8_bfr(0)+in_j8_bfr(1) ;add two high words together and low words together let in_j8=(templ.word1+templ.word0)/4 #endif let in_j1_ptr=(in_j1_ptr+1)&$03 ;increment pointer and wrap at 3 return ; ;sample in-1 to in-x with hysteresis ;in_jx is input value (0 - 1023) ;1.25 mS execution time for PSIM/CVS4 ;2.5 mS execution time for CVS ;written by David J. Brown get_inputs_hy: #ifndef cvs for idx=0 to 3 #else for idx=0 to 7 #endif adin pin_tbl(idx),in_jk(idx) let in_jk(idx)=in_jk(idx)+hys ;offset for compare at zero if in_jk(idx)>in_jk_hy(idx*2)then ;check lower range if in_jk(idx)key_prev then ;check if state change let key_prev=key_data ;save state pause 20 ;let keys settle goto get_keynum ;scan again endif return ; ;get keypad entry 0 - 999 ;displays digits at current character position ;* or # terminates ;written by David J. Brown get_keyentry gosub get_keynum if key_data<>255 then get_keyentry ;wait for keys up gosub wait_keynum ;wait until key entry if key_data>9 then get_key4 ;must be 0 - 9 let key_entry=key_data ;save digit hserout [$f0,$7d,key_data+$30,$f7] ;display digit get_key1: gosub get_keynum if key_data<>255 then get_key1 ;wait for key up gosub wait_keynum ;wait until key entry if key_data>9 then get_key4 ;done with entry hserout [$f0,$7d,key_data+$30,$f7] ;display digit let key_entry=(key_entry*10)+key_data ;shift and save digit get_key2: gosub get_keynum if key_data<>255 then get_key2 ;wait for key up gosub wait_keynum ;wait until key entry if key_data>9 then get_key4 ;done with entry hserout [$f0,$7d,key_data+$30,$f7] ;display digit let key_entry=(key_entry*10)+key_data ;shift and save digit get_key3: gosub get_keynum if key_data<>255 then get_key3 ;wait for keys up get_key4: return #endif ; #ifndef psim ;set input normal voltage to 10 volts nmlv_10: let olat.bit0=1 ;set for input normal voltage to +10 i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat] ;set olat return ; ;set input normal voltage to 0 nmlv_0: let olat.bit0=0 ;reset for input normal voltage to 0 i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat] ;set olat return ; ;set input reference voltage to 10 volts refv_10: let olat.bit1=1 ;set to enable input reference voltage let olat.bit2=0 ;reset for input reference voltage to +10 i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat] ;set olat return ; ;set input reference voltage to 5 volts refv_5: let olat.bit1=1 ;set to enable input reference voltage let olat.bit2=1 ;set for input reference voltage to +5 i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat] ;set olat return ; ;set input reference voltage to 0 refv_0: let olat.bit1=0 ;reset for input reference voltage to 0 i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat] ;set olat return #endif ; ;-----------------------------------------------------------------------------------------------; ; Interrupt Input Processing Routines ; ;-----------------------------------------------------------------------------------------------; ; #ifdef input_int_en ;sample in-1 avg1: adin pin_j1,in_j1_bfr.word1(in_j1_ptr) ;get in-1 into buffer let templ=in_j1_bfr(0)+in_j1_bfr(1) ;add two high words together and low words together let in_j1=(templ.word1+templ.word0)/4 let in_j1_ptr=(in_j1_ptr+1)&$03 ;increment pointer and wrap at 3 resume ;sample in-2 avg2: adin pin_j2,in_j2_bfr.word1(in_j2_ptr) ;get in-2 into buffer let templ=in_j2_bfr(0)+in_j2_bfr(1) ;add two high words together and low words together let in_j2=(templ.word1+templ.word0)/4 let in_j2_ptr=(in_j2_ptr+1)&$03 ;increment pointer and wrap at 3 resume ;sample in-3 avg3: adin pin_j3,in_j3_bfr.word1(in_j3_ptr) ;get in-3 into buffer let templ=in_j3_bfr(0)+in_j3_bfr(1) ;add two high words together and low words together let in_j3=(templ.word1+templ.word0)/4 let in_j3_ptr=(in_j3_ptr+1)&$03 ;increment pointer and wrap at 3 resume ;sample in-4 avg4: adin pin_j4,in_j4_bfr.word1(in_j4_ptr) ;get in-4 into buffer let templ=in_j4_bfr(0)+in_j4_bfr(1) ;add two high words together and low words together let in_j4=(templ.word1+templ.word0)/4 let in_j4_ptr=(in_j4_ptr+1)&$03 ;increment pointer and wrap at 3 resume #ifdef cvs ;sample in-5 avg5: adin pin_j5,in_j5_bfr.word1(in_j5_ptr) ;get in-5 into buffer let templ=in_j5_bfr(0)+in_j5_bfr(1) ;add two high words together and low words together let in_j5=(templ.word1+templ.word0)/4 let in_j5_ptr=(in_j5_ptr+1)&$03 ;increment pointer and wrap at 3 resume ;sample in-6 avg6: adin pin_j6,in_j6_bfr.word1(in_j6_ptr) ;get in-6 into buffer let templ=in_j6_bfr(0)+in_j6_bfr(1) ;add two high words together and low words together let in_j6=(templ.word1+templ.word0)/4 let in_j6_ptr=(in_j6_ptr+1)&$03 ;increment pointer and wrap at 3 resume ;sample in-7 avg7: adin pin_j7,in_j7_bfr.word1(in_j7_ptr) ;get in-7 into buffer let templ=in_j7_bfr(0)+in_j7_bfr(1) ;add two high words together and low words together let in_j7=(templ.word1+templ.word0)/4 let in_j7_ptr=(in_j7_ptr+1)&$03 ;increment pointer and wrap at 3 resume ;sample in-8 avg8: adin pin_j8,in_j8_bfr.word1(in_j8_ptr) ;get in-8 into buffer let templ=in_j8_bfr(0)+in_j8_bfr(1) ;add two high words together and low words together let in_j8=(templ.word1+templ.word0)/4 let in_j8_ptr=(in_j8_ptr+1)&$03 ;increment pointer and wrap at 3 resume #endif #endif ; ;-----------------------------------------------------------------------------------------------; ; End Of Library ; ;-----------------------------------------------------------------------------------------------;