welcome: please sign in

Revision 3 as of 2010-08-14 02:57:00

Clear message
location: MicrodecMidi

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.

   1 ; initialize USART for midi transfer and new jump address
   2 ldi r30,$0f ; set new jump address
   3             ; this value will need to be changed if there is more
   4             ; initialization code that follows the USART
   5             ; initialization.     
   6 ldi r17,$00
   7 sts ucsr0a,r17 ; set USART to single speed
   8 sts ubrr0h,r17 ; set USART to 31.25kbps baud rate for midi
   9 ldi r17,$27
  10 sts ubrr0l,r17
  11 ldi r17,$06
  12 sts ucsr0c,r17 ; set USART to 8 bit mode
  13 ldi r17,$10
  14 sts ucsr0b,r17 ; turn on USART reciever
  15 

   1 ; get delay settings
   2 lds r17,ucsr0a ; get USART control register
   3 sbrs r17,rxc0 ; check if byte has been recieved
   4 rjmp shift_000023 ; skip buffer read
   5 lds r17,udr0 ; get data byte
   6 brts update_000023 ; skip if command byte already recieved
   7 andi r17,$f0 ; mask off channel number - recieve all channels for now
   8 cpi r17,$b0 ; check if controller
   9 brne shift_000023 ; do nothing if not correct command byte
  10 set ; set t register to indicate correct command byte recieved
  11 rjmp shift_000023 ; finish off
  12 
  13 update_000023: ; update delay time with pitch bend value
  14 
  15 sbrc r17,$07 ; check if msb is set - command byte
  16 rjmp resetusart_000023 ; dont process data if command byte
  17 tst r14 ; check if first byte
  18 brne secondbyte_000023 ; skip to second byte if not
  19 cpi r17,$47 ; check if controller number 71
  20 brne resetusart_000023
  21 inc r14 ; set byte counter to first byte recieved
  22 rjmp shift_000023 ; finish off
  23 
  24 secondbyte_000023: ; get second byte
  25 
  26 lsl r17 ; shift 14b number to 16b number
  27 ;lsl r0
  28 ;rol r17
  29 mov r27,r17 ; move data to desired delay register
  30 ;mov r26,r0
  31 cpi r27,$03 ; check if desired delay is less than 9ms
  32 brsh resetusart_000023 ; finish off if delay time is greater than 9ms
  33 ldi r27,$03 ; set desired delay to 9ms
  34 clr r26
  35 
  36 resetusart_000023: ; reset usart
  37 
  38 clt ; reset command byte indicator
  39 clr r14 ; reset byte counter
  40