;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; (c) Fredrik Olofsson 2002 version 1.4 020825 ; rev. 040127, 040220, 071126 ; released under gnu gpl license ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .nolist .include "2313def.inc" .list ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .equ clock=4000000 .equ baudrate=31250 .equ baudkonstant=(clock/(16*baudrate))-1 .equ base=100 ;midi note for toggles = base+switchNo (100-103) .equ base2=110 ;midi note for bangs = base2+switchNo (110-103) .equ velocity=80 ;for midi note on msg .equ chout=0 ;main channel for sending .equ chin=0 ;main channel for receiving .equ ctrlindexout=0 ;ctrl for sending index (0-15) .equ ctrladcout=1 ;ctrl for sending adc result (0-127) .equ ctrlbypassout=2 ;ctrl for sending bypass (0/1) .equ ctrlin0=0 ;ctrl for receiving maxindex .equ ctrlin1=1 ;ctrl for receiving index .equ ctrlin2=2 ;ctrl directly to led display (0-127) .equ ctrlin3=3 ;ctrl directly to led display (128-255) .equ adcpreset=192 ;adc timing .def statusreg=R1 .def temp=R16 .def maxindex=R17 .def note=R18 .def index=R19 .def delay=R20 .def delay2=R21 .def laststatus=R22 .def lastbyte=R23 .def bytecounter=R24 .def counter=R25 .def adcresult=R26 .def lastadcresult=R27 .def startupbutton=R28 ;startup button flags .def currentbutton=R29 ;current button status flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .cseg .org 0 rjmp reset rjmp ext_int0 ;irq0 rjmp ext_int1 ;irq1 rjmp tim_capt1 ;timer1 capture rjmp tim_comp1 ;timer1 compare rjmp tim_ovf1 ;timer1 overflow rjmp ana_comp ;timer0 overflow rjmp uart_rxc ;uart receive rjmp uart_dre ;uart empty rjmp uart_txc ;uart transmit rjmp ana_comp ;analog comparator ;--------------- ext_int0: ext_int1: tim_capt1: tim_comp1: tim_ovf1: tim_ovf0: rjmp ana_comp uart_rxc: in statusreg,SREG rcall midiin out SREG,statusreg reti uart_dre: uart_txc: ana_comp: push temp in adcresult,TCNT0 ;load timer value clr temp out TCCR0,temp ;stop timer0 subi adcresult,adcpreset+1 ;rescale a/d output cbi PORTD,PD6 ;start discharge set ;set conversion complete flag(t) pop temp reti ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; midiin: push temp in temp,UDR ;read byte sbrs temp,7 ;skip if statusbyte rjmp runningstatus ;jump to runningstatus cpi temp,240 brge return ;skip other midi cmd (clock etc.) mov laststatus,temp ;save new statusbyte ldi bytecounter,1 rjmp return runningstatus: cpi laststatus,176+(chin*16) ;check status byte brne return midibyte1: cpi bytecounter,1 brne midibyte2 inc bytecounter mov lastbyte,temp rjmp return midibyte2: cpi bytecounter,2 brne return dec bytecounter cpi lastbyte,ctrlin0 ;check if receiving maxindex ctrl brne midibyte2next1 mov maxindex,temp rjmp return midibyte2next1: cpi lastbyte,ctrlin1 ;check if receiving index ctrl brne midibyte2next2 mov index,temp rcall translateindex rcall toleds rjmp return midibyte2next2: cpi lastbyte,ctrlin2 ;check if directly to led 0-127 brne midibyte2next3 rcall toleds rjmp return midibyte2next3: cpi lastbyte,ctrlin3 ;check if directly to led 128-255 brne return ori temp,0b10000000 ;add 128 to incoming ctrl value rcall toleds return: pop temp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; reset: cli ldi temp,low(RAMEND) ;stack out spl,temp ldi temp,baudkonstant out UBRR,temp ldi temp,0b10011000 ;set tx and rx output out UCR,temp ldi temp,0b00001011 out ACSR,temp ;init & enable comparator interrupt ldi temp,0b00000010 out TIMSK,temp ;enable timer interrupt ldi temp,0b01000000 ;set portD pin 6 as charge/discharge output out DDRD,temp sbi PORTD,PD6 ;pullup on charge/discharge pin ldi temp,0b01110100 out DDRB,temp ;set portB bits 6,5,4,2 as output in startupbutton,pinD ;save startup button status mov currentbutton,startupbutton ;copy to current cbi portB,2 ;bypass off rcall stupidflashintro ldi laststatus,176+(chin*16) ldi bytecounter,1 ldi maxindex,3 ;default maxindex clr index rcall translateindex rcall toleds sei ;--------------- main: in temp,pinD eor temp,currentbutton ;check if any button changed sbrc temp,2 ;test bit2 rcall button0 in temp,pinD eor temp,currentbutton ;check if any button changed sbrc temp,3 ;test bit3 rcall button1 in temp,pinD eor temp,currentbutton ;check if any button changed sbrc temp,4 ;test bit4 rcall button2 in temp,pinD eor temp,currentbutton ;check if any button changed sbrc temp,5 ;test bit5 rcall button3 rcall adccheck rjmp main ;--------------- button0: rcall increaseindex ;increase index rcall translateindex rcall toleds rcall sendctrlindex ;send control change index ldi note,base2+0 ;send bang noteOn rcall sendnoteon in currentbutton,pinD ;check+send toggle noteOn or noteOff mov temp,currentbutton eor temp,startupbutton sbrs temp,2 ; ! rjmp play0noteoff ; ! play0noteon: ldi note,base+0 ; ! rcall sendnoteon ret play0noteoff: ldi note,base+0 ; ! rcall sendnoteoff ret button1: ldi note,base2+1 ;send bang noteOn rcall sendnoteon in currentbutton,pinD ;check+send toggle noteOn or noteOff mov temp,currentbutton eor temp,startupbutton sbrs temp,3 ; ! rjmp play1noteoff ; ! play1noteon: ldi note,base+1 ; ! rcall sendnoteon ret play1noteoff: ldi note,base+1 ; ! rcall sendnoteoff ret button2: ldi note,base2+2 ;send bang noteOn rcall sendnoteon in currentbutton,pinD ;check+send toggle noteOn or noteOff mov temp,currentbutton eor temp,startupbutton sbrs temp,4 ; ! rjmp play2noteoff ; ! play2noteon: ldi note,base+2 ; ! rcall sendnoteon ret play2noteoff: ldi note,base+2 ; ! rcall sendnoteoff ret button3: rcall flipbypass ;flip bypass ldi note,base2+3 ;send bang noteOn rcall sendnoteon in currentbutton,pinD ;check+send toggle noteOn or noteOff mov temp,currentbutton eor temp,startupbutton sbrs temp,5 ; ! rjmp play3noteoff ; ! play3noteon: ldi note,base+3 ; ! rcall sendnoteon ret play3noteoff: ldi note,base+3 ; ! rcall sendnoteoff ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; adccheck: clr adcresult ;clear temp counter1 ldi temp,240 ;reset temp counter2 adcloop: inc adcresult ;increase counter1 brne adcloop inc temp ;increase counter2 brne adcloop ;check if delay finished ldi adcresult,adcpreset out TCNT0,adcresult ;clear counter and load offset clt ;clear conversion complete flag(t) ldi adcresult,2 out TCCR0,adcresult ;start timer0 with prescaling f/8 sbi PORTD,PD6 ;start charging of capacitor adcwait: brtc adcwait ;wait until conversion finished cp adcresult,lastadcresult ;check if any change breq dontsendadc rcall sendctrladc ;send midi controller mov lastadcresult,adcresult ;store result dontsendadc: ret ;--------------- sendctrladc: ldi temp,176+(chout*16) sendctrladc1: sbis USR,UDRE rjmp sendctrladc1 out UDR,temp ldi temp,ctrladcout sendctrladc2: sbis USR,UDRE rjmp sendctrladc2 out UDR,temp sendctrladc3: sbis USR,UDRE rjmp sendctrladc3 out UDR,adcresult ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; flipbypass: sbis pinB,2 ;skip if bypass is on rjmp bypasson rjmp bypassoff bypasson: rcall sendctrlbypasson ;send control change bypass sbi portB,2 rcall toleds ret bypassoff: rcall sendctrlbypassoff ;send control change bypass cbi portB,2 rcall translateindex rcall toleds ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;PB4 = ser = DS = shift data ;PB6 = clock = SHCP = shift register clock ;PB5 = latch = STCP = output latch store toleds: sbic pinB,2 ;skip if bypass is off ldi temp,1 ;override with special bypass char nop clr counter shiftloop: sbi portB,4 rol temp brcc carrycleared cbi portB,4 carrycleared: cbi portB,6 nop nop sbi portB,6 inc counter cpi counter,8 brne shiftloop cbi portB,5 nop nop sbi portB,5 ret ;--------------- translateindex: ldi ZH,high(table*2) ldi ZL,low(table*2) mov temp,index findaddress: dec temp cpi temp,$ff breq foundaddress adiw ZL,1 rjmp findaddress foundaddress: lpm mov temp,R0 ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; sendnoteon: ldi temp,144+(chout*16) sendnoteon1: sbis USR,UDRE rjmp sendnoteon1 out UDR,temp mov temp,note sendnoteon2: sbis USR,UDRE rjmp sendnoteon2 out UDR,temp ldi temp,velocity ;add temp,index ;(add index to velocity) sendnoteon3: sbis USR,UDRE rjmp sendnoteon3 out UDR,temp rcall longdelay ret sendnoteoff: ldi temp,144+(chout*16) sendnoteoff1: sbis USR,UDRE rjmp sendnoteoff1 out UDR,temp mov temp,note sendnoteoff2: sbis USR,UDRE rjmp sendnoteoff2 out UDR,temp ldi temp,0 sendnoteoff3: sbis USR,UDRE rjmp sendnoteoff3 out UDR,temp rcall longdelay ret ;--------------- increaseindex: cp index,maxindex ;check limit brlo increaseindex2 ;branch if lower clr index ;wrap back ret increaseindex2: inc index ;increase index ret ;--------------- sendctrlindex: ldi temp,176+(chout*16) sendctrl1: sbis USR,UDRE rjmp sendctrl1 out UDR,temp ldi temp,ctrlindexout sendctrl2: sbis USR,UDRE rjmp sendctrl2 out UDR,temp sendctrl3: sbis USR,UDRE rjmp sendctrl3 out UDR,index ret ;--------------- sendctrlbypasson: ldi temp,176+(chout*16) sendctrl1bypasson: sbis USR,UDRE rjmp sendctrl1bypasson out UDR,temp ldi temp,ctrlbypassout sendctrl2bypasson: sbis USR,UDRE rjmp sendctrl2bypasson out UDR,temp ldi temp, 1 ;the ctrl value sendctrl3bypasson: sbis USR,UDRE rjmp sendctrl3bypasson out UDR,temp ret sendctrlbypassoff: ldi temp,176+(chout*16) sendctrl1bypassoff: sbis USR,UDRE rjmp sendctrl1bypassoff out UDR,temp ldi temp,ctrlbypassout sendctrl2bypassoff: sbis USR,UDRE rjmp sendctrl2bypassoff out UDR,temp ldi temp, 0 ;the ctrl value sendctrl3bypassoff: sbis USR,UDRE rjmp sendctrl3bypassoff out UDR,temp ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; stupidflashintro: ser index stupidloop: mov temp,index rcall shortdelay rcall shortdelay rcall shortdelay rcall shortdelay rcall toleds dec index brne stupidloop ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; shortdelay: dec delay brne shortdelay ret longdelay: dec delay brne longdelay dec delay2 brne longdelay ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; table: .db 254, 56, 221, 125, 59, 119, 247, 60, 255, 127, 175, 239, 198, 238, 199, 135 ;254 ;0. ; 56 ;1. ;221 ;2. ;125 ;3. ; 59 ;4. ;119 ;5. ;247 ;6. ; 60 ;7. ;255 ;8. ;127 ;9. ;175 ;A ;239 ;B ;198 ;C ;238 ;D ;199 ;E ;135 ;F ;;;;;;;;;;;;; ctrlin1 ; = 0 ; .= 16 ; l = 40 ; 1.= 56 ; 4.= 59 ; 7.= 60 ; 9.= 63 ; S = 103 ; Y = 107 ; 5.= 119 ; 3.= 125 ; 9.= 127 ;;;;;;;;;;;;; ctrlin2 ; F = 7 ; P = 15 ; h = 35 ; H = 43 ; A = 47 ; L = 66 ; C = 70 ; E = 71 ; 2.= 93 ; o = 97 ; d = 105 ; a = 109 ; O = 110 ; D = 110 ; B = 111 ; 6.= 119 ; 0.= 126 ; 8.= 127