;-----------------------------------------------------------------------------------------------; ; Program: CVS4 Trapezoid Generator ; ; 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 emulates the EMS-Synthi trapezoid generator with a maximum of 2 seconds ; ramp and delay. It can either be triggered by a gate or loop. The ramp and delay ; times are a fixed cycle time once initiated. ; ; Inputs: ; Start = Gate / Loop select (off=gate, on=loop) ; Stop = Lin / Exp mode (off=linear, on=exponential) ; In-1 = Attack CV (2 mS to 2 sec) ; In-2 = On delay CV (2 mS to 2 sec) ; In-3 = Decay CV (2 mS to 2 sec) ; In-4 = Off delay CV (2 mS to 2 sec, only used in loop mode) ; In-5 = not used ; In-6 = not used ; In-7 = not used ; In-8 = not used ; Aux = Gate in (sampled at beginning and end of attack) ; Midi-In = not used ; ; Outputs: ; Out-1 = Trapezoid Out (0 to 5 volts) ; Out-2 = not used ; Out-3 = not used ; Out-4 = not used ; Out-5 = not used ; Out-6 = not used ; Out-7 = not used ; Out-8 = not used ; Aux = not used ; Midi-Out= not used ; Speakjet= not used ; ; Display = Displays program name ; Run led = Indicates ramp cycle ; Stop led= Indicates delay cycle ; ; Revision: 0.10S2 ; Date Aug 12, 2011 ; History: 0.1S2 added linear / exponential mode ; 0.0S2 initial release of program ; Written: Sept 25, 2010 ; ;-----------------------------------------------------------------------------------------------; ; Conditionals ; ;-----------------------------------------------------------------------------------------------; ; ;---------PSIM, CVS, OR CVS-4 CONDITIONAL COMPILE OPTION----------------------------------------; ; ; ; UNCOMMENT ONE OF NEXT THREE LINES TO SELECT TARGET MODULE ; ;cvs con 1 ;define for CVS module ; cvs4 con 1 ;define for 4 channel CVS module ; ;psim con 1 ;define for PSIM module ; ;-----------------------------------------------------------------------------------------------; ;---------ENABLE AUX_IN RISING EDGE INTERRUPT CONDITIONAL COMPILE OPTION------------------------; ; ; ; COMMENT OUT NEXT LINE TO DISABLE AUX INPUT RISING EDGE INTERRUPTS ; ;aux_int_en con 1 ;define to enable aux_in rising edge interrupts ; ; ;comment to disable aux_in rising edge interrupts ; ;-----------------------------------------------------------------------------------------------; ;---------ENABLE TIMER INTERRUPT CONDITIONAL COMPILE OPTION-------------------------------------; ; Notes: run led will blink to verify timer operation ; ; ; ; COMMENT OUT NEXT LINE TO DISABLE TIMER INTERRUPTS ; ;timer_int_en con 1 ;define to enable timer interrupts ; ; ;comment to disable timer interrupts ; ; ; ; ;------ENABLE AVERAGED ANALOG-IN IN TIMER INTERRUPT CONDITIONAL COMPILE OPTION------------; ; ; ; Note: requires timer_int_en to be defined ; ; ; ; ; ; ; ; COMMENT OUT NEXT LINE TO DISABLE ANALOG-IN ON TIMER INTERRUPTS/ENABLE POLLED ANALOG-IN ; ; ; input_int_en con 1 ;define to enable input interrupt mode ; ; ; ; ;comment to set polled input mode ; ; ; ;-----------------------------------------------------------------------------------------; ; ; ; ; ;------ENABLE RISING EDGE DETECT IN TIMER INTERRUPT CONDITIONAL COMPILE OPTION------------; ; ; ; Note: requires timer_int_en to be defined ; ; ; ; pulse must be > 1 mS and > 8 mS period (7 timer clocks low / 1 timer clock high) ; ; ; ; ; ; ; ; COMMENT OUT NEXT LINE TO DISABLE RISING EDGE DETECT IN TIMER INTERRUPTS ; ; ; edge_int_en con 1 ;define to enable rising edge detect mode ; ; ; ; ;comment to disable rising edge detect mode ; ; ; ; UNCOMMENT ONE OF NEXT THREE LINES TO SELECT INPUT FOR RISING EDGE DETECT ; ; ; edge_in var in4 ;use start jack for rising edge detect input ; ; ; edge_in var in5 ;use stop jack for rising edge detect input ; ; ; edge_in var in8 ;use aux jack for rising edge detect input ; ; ; ;-----------------------------------------------------------------------------------------; ; ;-----------------------------------------------------------------------------------------------; ; ;-----------------------------------------------------------------------------------------------; ; Include Files (locate one level above the program directory) ; ;-----------------------------------------------------------------------------------------------; ; #include "..\support.djb.bas" ;support must be first ;#include "..\midi.djb.bas" ;midi must be after library ; ;-----------------------------------------------------------------------------------------------; ; Program Declarations ; ;-----------------------------------------------------------------------------------------------; ; in_jf var float ;in_jx float value y_val var float ;y value delta_y var float ;lin y increment time_c var float ;exp time constant loop var byte ;free run flag (0=gate, 1=free run) ; ;-----------------------------------------------------------------------------------------------; ; Initialization ; ;-----------------------------------------------------------------------------------------------; ; initialize: ;program specific initialization starts here #ifdef psim pause 250 ;let display initialize hserout [$f0,$7d,$0a,$18,"Trapzoid Genratr",$f7] ;clear, overwrite, name #else 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" hserout [$f0,$7d,$14,$1f,$00,$00,$00,$00,$00,$00,$f7] ;character4 "upper score" hserout [$f0,$7d,$15,$00,$10,$08,$04,$02,$01,$00,$f7] ;character5 "\" hserout [$f0,$7d,$16,$04,$0e,$15,$04,$04,$04,$04,$f7] ;character6 start vertical arrow hserout [$f0,$7d,$17,$04,$04,$04,$04,$15,$0e,$04,$f7] ;character7 stop vertical down arrow hserout [$f0,$7d,$0a,$18,"Trapzoid Genratr",0,"/ ",1,4," ",2,5," ",3,"_ ",6,"L",7,"E",$f7] ;clear, overwrite, name #endif ;speak program name #ifdef psim i2cout i2c_data,i2c_clk,($48<<1),["i am rev 1.0",$02,"i was written by Dave Brown",$03,"ready",$0d] #endif ; ;-----------------------------------------------------------------------------------------------; ; Main Program ; ;-----------------------------------------------------------------------------------------------; ; #ifndef psim let olat.bit6=1 ;select dac1 for performace let olat.bit7=0 ;deselect dac2 i2cout i2c_data,i2c_clk,($20<<1),[$0a,olat] ;set olat #endif let y_val=0.0 ;initialize starting y value ;wait for gate true or loop wait_gate_true: if start_j=1 then ;check loop mode only at beginning of cycle let loop=1 ;set loop mode for end cycle goto attack else let loop=0 ;reset loop mode endif if aux_in=0 then wait_gate_true ;wait for gate true attack: high run_led ;indicate attack gosub get_inputs_hy let in_jf=tofloat (((in_j1*47)/25)+1) ;1 - 1924 range if stop_j=0 then ;check linear or exponential mode ;linear mode let delta_y=1924.0/in_jf ;calculate delta y per loop do let out_j1=toint y_val gosub load_out1 let y_val=y_val+delta_y ;calculate next y value while toint y_val<1924 ;continue until maximum value else ;exponential mode let time_c=8.15/in_jf ;calculate time constant (max 2 sec) do let out_j1=toint y_val gosub load_out1 let y_val=y_val+time_c*(1925.0-y_val);calculate next y value while toint y_val<1924 ;continue until maximum value endif let out_j1=1924 ;set outputs to maximum value let y_val=1924.0 ;set to max value for decay gosub load_out1 low run_led ;indicate end of attack if loop=1 then delay ;check loop mode ;wait for gate false wait_gate_false: if aux_in=1 then wait_gate_false ;wait for gate true ;on delay: high stop_led ;indicate on gosub get_inputs_hy let in_j2=2*(in_j2+1) ;scale 2 - 2048 mS delay pause in_j2 low stop_led ;indicate end of on ;decay high run_led ;indicate decay gosub get_inputs_hy let in_jf=tofloat (((in_j3*47)/25)+1) ;1 - 1924 range if stop_j=0 then ;check linear or exponential mode ;linear mode let delta_y=1924.0/in_jf ;calculate delta y per loop do let out_j1=toint y_val gosub load_out1 let y_val=y_val-delta_y ;calculate next y value while toint y_val>0 ;continue until minimum value else ;exponential mode let time_c=8.15/in_jf ;calculate 2 sec max time constant do let out_j1=toint y_val gosub load_out1 let y_val=y_val-time_c*(1925.0-y_val);calculate next y value while toint y_val>0 ;continue until minimum value endif let out_j1=0 ;set outputs to minimum value let y_val=0.0 ;set to minimum value for attack gosub load_out1 low run_led ;indicate end of decay if loop=0 then wait_gate_true ;check loop mode ;off high stop_led ;indicate off gosub get_inputs_hy let in_j4=2*(in_j4+1) ;scale 2 - 2048 mS delay pause in_j4 low stop_led ;indicate end of off goto wait_gate_true ; ;-----------------------------------------------------------------------------------------------; ; Subroutines ; ;-----------------------------------------------------------------------------------------------; ; load_out1: ;fast performance single channel output ;add dac address to out_jx values and shift 16 bits using mode 4 shiftout dac_sdata,dac_clk,fastmsbpre,[(out_j1|$c000)\16] pulsout dac_load,1 ;pulse loaddacs pauseus 1695 ;keep do loop time ~1 mS per step for 2 second maximum return ; ;-----------------------------------------------------------------------------------------------; ; Interrupt Service Routines ; ;-----------------------------------------------------------------------------------------------; ; #ifdef aux_int_en ;interrupt service routine for aux input rising edge aux_isr: let aux_cnt=aux_cnt+1 ;count number of aux interrupts resume ;ignore overflow #endif ; ; #ifdef timer_int_en ;interrupt service routine for timer ;increments time_count value ;turn off stop led at turn_off value ;toggle run led at 512 mS intervals ;written by David J. Brown tm_isr: let time_count=time_count+1 ;increment real time count if time_count=turn_off then ;value to turn off stop led low stop_led endif let run_led_out=time_count.bit9 ;toggle run led at 512 mS intervals ; #ifdef edge_int_en ;check for trigger rising edge ;pulse width must be > 1 ms timer let edge_state=edge_state<<1 ;shift previous state left let edge_state.bit0=edge_in ;set low bit to current input state if edge_state=$01 then ;edge detect requires 7 previous lows and current high let edge_flg=1 ;set edge flag endif #endif ; #ifndef input_int_en resume ;resume if input polled mode #else ;sample in-1 - in-4 at specific intervals ;injx is input averaged over last 4 samples (0 - 1023) ;injx_bfr(0) & injx_bfr(1) are last 4 word samples ;written by David J. Brown let isr_cnt=isr_cnt+1 #ifdef cvs ;change the following table to modify the scan rate for each CVS input ;175 uS execution time so maximum of one sample and average per interrupt ;currently set for: in-1 to 8 @ 8 mS branch isr_cnt, [avg1,avg2,avg3,avg4,avg5,avg6,avg7,avg8,avg1,avg2,avg3,avg4,avg5,avg6,avg7,avg8] #else ;change the following table to modify the scan rate for each PSIM input ;175 uS execution time so maximum of one sample and average per interrupt ;currently set for: in-1 @ 2 mS, in-2 @ 4 mS, in-3 @ 8 mS, in-4 @ 8 mS branch isr_cnt, [avg1,avg2,avg1,avg3,avg1,avg2,avg1,avg4,avg1,avg2,avg1,avg3,avg1,avg2,avg1,avg4] #endif #endif #endif ;-----------------------------------------------------------------------------------------------; ; End Of Program ; ;-----------------------------------------------------------------------------------------------;