welcome: please sign in
location: MicrodecMidi



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 set 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

Receive Data from the USART

This code only shows how to receive data from the USART, although transmitting data would be much simpler. The first thing that happens is that the code checks to see if any USART data has arrived, and if it has, it checks for a MIDI command byte. If a MIDI command byte is received, it then checks for a MIDI controller byte. After it receives the appropriate controller data, it receives a MIDI data byte and updates a register that the Function program can accesses. It then resets itself to wait for another MIDI command byte. If bytes are received out of order, or the wrong command or controller bytes are received, it also resets itself. A better implementation would include a counter that resets if a certain amount of time has elapsed between bytes.

   1 ; receive MIDI data
   2 lds r17,UCSR0A ; get USART control register
   3 sbrs r17,RXC0 ; check if byte has been received
   4 rjmp done_UID ; finish off if no byte has been received
   5 lds r17,UDR0 ; get data byte if one arrived
   6 brts update_UID ; skip if command byte already received
   7                 ; the t-bit is used to indicate a command byte recieved
   8                 ; although another bit in a register could also be used
   9 andi r17,$f0 ; mask off channel number - receive all channels for now
  10              ; this can be set to look for a particular MIDI channel
  11 cpi r17,$b0 ; check if appropriate MIDI command number
  12             ; can be set to any MIDI command
  13 brne done_UID ; do nothing if not correct command byte
  14 set ; set t register to indicate correct command byte received
  15 rjmp done_UID ; finish off
  17 update_UID: ; update data register with MIDI data
  19 sbrc r17,$07 ; check if msb is set - indicates command byte
  20              ; if command byte is received at this point, it is out
  21              ; of sequence, and the program should reset itself
  22 rjmp resetusart_UID ; dont process data if command byte
  23 tst r14 ; check if first byte - r14 holds the byte counter
  24         ; (0 = first byte, 1 = second byte)
  25 brne secondbyte_UID ; skip to second byte if not
  26 cpi r17,$47 ; if first byte, check if controller number 71
  27             ; can be set to any controller number
  28 brne resetusart_UID ; do not process data if not the correct controller
  29 inc r14 ; set byte counter to first byte received
  30 rjmp done_UID ; finish off
  32 secondbyte_UID: ; get second byte
  34 mov r27,r17 ; move MIDI data to register that the Function program 
  35             ; references
  37 resetusart_UID: ; reset usart
  39 clt ; reset command byte indicator
  40 clr r14 ; reset byte counter
  42 done_UID: ; place for rest of program

MicrodecMidi (last edited 2010-08-21 01:55:47 by guest)