| CODE |
; midi tester ; program by stergio33 (vster@tee.gr) ; this test circuit sends midi notes constantly, just to study the midi protocol ; there are some buttons connected that let you change the channel, pitch and velocity ; designed for ATtiny26. Program the fuse bits so that it runs at 4MHz internal oscilator .NOLIST .INCLUDE "tn26def.inc" .LIST ; Used registers r16 = scratch, timer = r19(MSB), r18, r17 .def Rout = r20; output register to be shifted for midi .def Poa = r21; state of output port A .def cnt = r22; general counter .def key = r23; 1-127 for midi messages .def veloc = r24; 1-127 velocity of note .def channel = r25; 0-15 midi channel .equ midi = 0 ; midi output .equ led = 1 ; led output pin .equ chanSelect = 0; increase channel button .equ VelocDecr = 1; decrease velocity button .equ VelocIncr = 2; increase velocity button .equ KeyInc = 3; increase key button .equ DeChannel = 4; decrease channel .equ KeyDec = 5; decrease key button ; Code starts here .CSEG .ORG $0000 rjmp arxi ; **************** End of interrupt service routines *********** ; ****************** delay routines ************** delay: ldi r19,8 ldi r18,255; delay routine ldi r17,255 del1: dec r17 brne del1 ser r17 dec r18 brne del1 ser r18 dec r19 brne del1 ret sdel: ldi r16,18; short delay at 4Mhz for internal oscilator sdel1: dec r16 brne sdel1 ret ; Rout = r20 output register to be shifted for midi ; Poa = r21 output buffer for port A ; cnt = r22 general counter ; sends a byte (stored in Rout) serially to midi output, starting from LSB send: ldi cnt,10 com Rout sec send2: brcc send3 cbi portA,midi; midi out rjmp send4 send3: sbi portA,midi nop send4: rcall sdel rcall sdel lsr Rout dec cnt brne send2 ret ; ****************** note on ************************************************ ; key = r23 1-127 for midi messages ; veloc = r24 1-127 velocity of note ; channel = r24 0-15 midi channel ; send note on. 1st byte $9n (n=0-f), 2nd:key (0-$7f), 3rd:velocity (0-$7f) ; midi velocity = 31250 bits/sec, so for the duration of a bit is 1/31250 = 32us noteOn: ldi rout,$90; note-on message starts with 9 rjmp note1 noteOf: ldi rout,$80; note-off message starts with 8 note1: sbi porta,led mov r16,channel andi r16,$0f or rout,r16 rcall send rcall sdel mov rout,key rcall send rcall sdel mov rout,veloc rcall send rcall delay cbi porta,led ret ; ************************************************************************ incKey: inc key ; increase key (pitch) andi key,127 sbi porta,led rcall delay cbi porta,led incKe1: ret ; ************************************************************************ decKey: tst key ; decrease key (pitch) breq decKe1 dec key sbi porta,led rcall delay cbi porta,led decKe1: ret ; ************************************************************************ incVeL: ldi r16,10 ; increase velocity add veloc,r16 andi veloc,127 breq incve1 sbi porta,led rcall delay cbi porta,led incVe1: ret ; ************************************************************************ decVeL: ldi veloc,3 ; decrease velocity sbi porta,led rcall delay cbi porta,led ret ; ************************************************************************ inChan: inc channel ; increase channel circular andi channel,15 sbi porta,led rcall delay cbi porta,led inCha1: ret ; ************************************************************************ deChan: tst channel ; decrease channel breq deCha1 dec channel sbi porta,led rcall delay cbi porta,led deCha1: ret ; **************** End of the subroutines section *************** ; ******************** Main program **************************** arxi: ldi r16,RAMEND ; Initiate Stackpointer. out SP,r16 ldi r16,255 out ddra,r16 ; porta is outputs clr r16 out ddrb,r16 ; portb is inputs out porta,r16 ser r16 out portb,r16 ; pull ups for portb clr Poa start: out PortA,Poa ldi channel,0 ldi key,$3c ; start with middle C ldi veloc,30 next: rcall noteOn rcall delay rcall noteOf rcall delay sbis pinB,VelocDecr; decrease velocity button pressed? rcall decVeL sbis pinB,VelocIncr; increase velocity button pressed? rcall IncVel sbis pinB,chanSelect; increase channel button pressed? rcall inChan sbis pinB,KeyInc ; icrease key button pressed? rcall incKey sbis pinB,KeyDec ; decrease key button pressed? rcall decKey sbis pinB,DeChannel; decrease channel button pressed? rcall deChan rjmp next |