;-----------------------------------------------------------------------------------------------; ; Program: Dedicated CVS PC2 ; ; 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. ; ;-----------------------------------------------------------------------------------------------; ; ; Description: ; This program is a dedicated (embedded) program for the CVS to control a Kurzweil ; PC-2 ribbon controller. This program will output a ribbon control voltage, trigger ; on first contact and gate. The output control voltage range is 0 to 10 volts and the ; priority is the most right ribbon contact. ; ; The output voltage can be continous or quantized. ; COMMENT this next line for continuous output. ; quantize con 1 ; ; The output voltage with no contact will be 5 volts with a fine adjustment by IN-1. ; COMMENT this next line to hold the last position on the ribbon. center con 1 ; ; The variables diode, off_lm, and off_mr may need to be adjusted for various ; ribbon and diode characteristics. ; ; Inputs: ; In-1 = no contact 5 volt adjust (return to center, continuous mode) ; In-2 = ribbon left ; In-3 = ribbon middle ; In-4 = ribbon right ; ; Outputs: ; Out-1 = CV out ; Out-2 = gate (5 volts) ; Out-3 = trigger (15 mS @ 5 volts) ; Out-4 = ribbon power ; ; Revision: 0.2X ; Date June 30,2010 ; History: 0.2X updated diode logic for better limit condition handling ; 0.1X Changed shiftout for Studio ; 0.1 added conditional for center/hold and continuous/quantize ; 0.0 initial release of Dedicated CVS PC2, December 5, 2007 ; Based on the PSIM Template Revision 0.66 March 14, 2006 ; Developed by David J. Brown ; Written: April 13, 2004 ; ;-----------------------------------------------------------------------------------------------; ; BasicMicro AtomPro24 CVS pins ; ;-----------------------------------------------------------------------------------------------; ; P0 - in-1 ; ; P1 - in-2 ; ; P2 - in-3 ; ; P3 - in-4 ; ; P4 - na ; ; P5 - na ; ; P6 - na ; ; P7 - na ; ; P8 - na ; ; P9 - na ; ; P10 - na ; ; P11 - dac load_dacs ; ; P12 - dac ser_data ; ; P13 - dac clock ; ; P14 - na ; ; P15 - na ; ;-----------------------------------------------------------------------------------------------; ;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 load_dacs con p11 ;load dac pin ser_data con p12 ;dac serial data input pin clock con p13 ;dac clock pin ;i/o declarations in_j1 var word ;in-1 value in_j2 var word ;in-2 value in_j3 var word ;in-3 value in_j4 var word ;in-4 value out_j1 var word ;out-1 value out_j2 var word ;out-2 value out_j3 var word ;out-3 value out_j4 var word ;out-4 value ;misc declarations fivevolts con 1920 ;5 volt output value contact var byte ;flag for ribbon contact (0=no contact, 1=contact) trigger var byte ;flag for trigger (1=first contact) out_last var word ;last output value ;ribbon-specific declarations ;you will need to adjust these constants based on your diode and ribbon diode con 61 ;silicon diode drop 0.605 (measured) * 1023/10) = 61 off_lr con 1265 ;offset for left to middle transition ;ribbon cannot get to max voltage of 1280 off_mr con 2530 ;offset for middle to right transition ;ribbon cannot get to max voltage of 1280*2 ; ;-----------------------------------------------------------------------------------------------; ; Start of program ; ;-----------------------------------------------------------------------------------------------; ; ;initialize pins dirs=%0011111000000000 ;configure pin direction (1=output, 0=input) ;inputs: in-4, in-3, in-2, in-1 ;outputs: load_dacs, ser_data, clock high load_dacs ;set dac load-0 high low ser_data ;set dac data low low clock ;set dac clock low gosub get_inputs let out_j1=fivevolts+(in_j1/64)-8 ;set initial voltage to center+offset adjustment let out_j2=0 ;set out-2 low let out_j3=0 ;set out-3 low let out_j4=fivevolts+(diode*15/4)+4 ;set ribbon voltage at 5V + diode + 12mV for roundoff errors gosub load_outputs ;initialize misc variables let trigger=0 ;reset trigger flag let out_last=out_j1 ; ;-----------------------------------------------------------------------------------------------; ; Main program ; ;-----------------------------------------------------------------------------------------------; ; loop: gosub get_inputs let contact=0 ;reset gate #ifdef center ;conditional return to center let out_j1=fivevolts+(in_j1/64)-8 ;set voltage to center+offset adjustment on release #endif if in_j2>(diode/2) then ;check for non-zero input if in_j2>=diode then ;check to see if greater than diode drop let in_j2=in_j2-diode ;subtract diode drop else let in_j2=0 ;set to minimum endif if in_j2>511 then ;check to see if over 5V in_j2=511 ;set to 5V endif let out_j1=in_j2*5/2 ;set output from left ribbon ; change 5V input scale to 3.333V output scale (x0.666 or 2/3) ; scale output range for DAC (x15/4) ; (2/3)*15/4)=5/2 scale factor let contact=1 ;set gate endif if in_j3>(diode/2) then ;check for non-zero input if in_j3>=diode then ;check to see if greater than diode drop let in_j3=in_j3-diode ;subtract diode drop else let in_j3=0 ;set to minimum endif if in_j3>511 then ;check to see if over 5V in_j3=511 ;set to 5V endif let in_j3=511-in_j3 ;reverse middle ribbon let out_j1=(in_j3*5/2)+off_lr ;add offset from lower ribbon let contact=1 ;set gate endif if in_j4>(diode/2) then ;check for non-zero input if in_j4>=diode then ;check to see if greater than diode drop let in_j4=in_j4-diode ;subtract diode drop else let in_j4=0 ;set to minimum endif if in_j4>511 then ;check to see if over 5V in_j4=511 ;set to 5V endif let out_j1=((in_j4*5/2)+off_mr) ;set output from right ribbon let contact=1 ;set gate endif let out_j2=fivevolts*contact ;set gate if contact made if trigger=0 and contact=1 then let out_j3=fivevolts*contact ;set trigger if first contact else let out_j3=0 endif #ifdef quantize ;conditional quantize function if abs(out_j1-out_last) < 8 then ;check if moved at least a quarter semitone let out_j1=out_last ;no so use last value to eliminate jitter endif let out_last=out_j1 ;save new value let out_j1=(out_j1)&$0fe0 ;quantize #endif gosub load_outputs let trigger=contact ;set trigger to contact pause 15 let out_j3=0 ;reset trigger gosub load_outputs goto loop ; ;-----------------------------------------------------------------------------------------------; ; Subroutines ; ;-----------------------------------------------------------------------------------------------; ; ;sample in-1 to in-4 ;in_jx is input value (0 - 1023) ;150 uS execution time get_inputs: adin pin_j1,in_j1 adin pin_j2,in_j2 adin pin_j3,in_j3 adin pin_j4,in_j4 return ; ;output out_jx values to dacs ;750 uS execution time load_outputs: ;add dac address to out_jx values and shift 16 bits using mode 4 shiftout ser_data,clock,fastmsbpre,[(out_j1|$c000)\16] pulsout load_dacs,1 ;clock loaddacs shiftout ser_data,clock,fastmsbpre,[(out_j2|$8000)\16] pulsout load_dacs,1 ;clock loaddacs shiftout ser_data,clock,fastmsbpre,[(out_j3|$4000)\16] pulsout load_dacs,1 ;clock loaddacs shiftout ser_data,clock,fastmsbpre,[out_j4\16] pulsout load_dacs,1 ;clock loaddacs return ;-----------------------------------------------------------------------------------------------; ; End of program ; ;-----------------------------------------------------------------------------------------------;