==== MIDI ==== Here is an example of code that will allow the MICrODEC to receive MIDI data over the serial port. Because of the way interrupts are handled, it is difficult to have a generic MIDI interface in the Main loop which communicates with the Function programs. It is possible to do this, but it would cut down on the processing time within the Function programs. Therefore, to accommodate MIDI, each Function must have its own implementation. This has the net effect of maximizing processing time, program by program. == Initialize the USART This first section of code is an initialization routine for talking MIDI, and must be placed at the beginning of the Function program. This sets up the USART for the 31.25kbps data transfer rate, and sets the start bits and stop bits. {{{#!highlight nasm ; initialize USART for midi transfer and new jump address ldi r30,$0f ; set new jump address ; this value will need to be changed if there is more ; initialization code that follows the USART ; initialization. ldi r17,$00 sts ucsr0a,r17 ; set USART to single speed sts ubrr0h,r17 ; set USART to 31.25kbps baud rate for midi ldi r17,$27 sts ubrr0l,r17 ldi r17,$06 sts ucsr0c,r17 ; set USART to 8 bit mode ldi r17,$10 sts ucsr0b,r17 ; turn on USART reciever }}} {{{#!highlight nasm ; get delay settings lds r17,ucsr0a ; get USART control register sbrs r17,rxc0 ; check if byte has been recieved rjmp shift_000023 ; skip buffer read lds r17,udr0 ; get data byte brts update_000023 ; skip if command byte already recieved andi r17,$f0 ; mask off channel number - recieve all channels for now cpi r17,$b0 ; check if controller brne shift_000023 ; do nothing if not correct command byte set ; set t register to indicate correct command byte recieved rjmp shift_000023 ; finish off update_000023: ; update delay time with pitch bend value sbrc r17,$07 ; check if msb is set - command byte rjmp resetusart_000023 ; dont process data if command byte tst r14 ; check if first byte brne secondbyte_000023 ; skip to second byte if not cpi r17,$47 ; check if controller number 71 brne resetusart_000023 inc r14 ; set byte counter to first byte recieved rjmp shift_000023 ; finish off secondbyte_000023: ; get second byte lsl r17 ; shift 14b number to 16b number ;lsl r0 ;rol r17 mov r27,r17 ; move data to desired delay register ;mov r26,r0 cpi r27,$03 ; check if desired delay is less than 9ms brsh resetusart_000023 ; finish off if delay time is greater than 9ms ldi r27,$03 ; set desired delay to 9ms clr r26 resetusart_000023: ; reset usart clt ; reset command byte indicator clr r14 ; reset byte counter }}}