Jump to content
43oh

MIDI Monitor


Recommended Posts

As part of my other project, I had to create a simple MIDI receiver. I figured that instead of polluting my other thread, I will create a new one, dedicated to my MIDI adventures.

 

Here is my first MIDI receiver. It displays message type (note on, note off, after touch, control change, program change, channel pressure, pitch wheel,) MIDI channel, note number, and the velocity. Because of the time it takes to update LCD, I am not updating headers so "Note" and "Vel" are not accurate descriptions of the data received for some type of messages.

I will make some improvements later, like changing the clock to 8MHz because current 1MHz seems to be too slow.

 

EDIT: code below runs at 8MHz, still some problems, will have to rewrite it completely.

 

 

Code removed, new version below

Link to post
Share on other sites

Nature, you know what they say: it's not when you use it, it's how you use it :D

 

I wasn't happy with my first version so I rewrote it and here it is, all new and improved. No more missed messages, headers are correct for the type of message, didn't bother to convert pitch bend values though. Still no SysEx but I think I will leave it at that.

 

 

#include "msp430g2553.h"

void send(char data, char registerSelect);
void sendHeader(const char* header);
void setLCDData(char startIndex, char data);
void clearData(char startIndex);
#define sendData(data) send(data, 1)
#define sendFunction(data) send(data, 0)
#define DATA_PIN BIT6
#define CLOCK_PIN BIT5
#define ENABLE_PIN BIT4
#define MIDI_IN_PIN BIT1

char charIndex = 0;
char bitCounter = 0;
char digitCounter = 0;
char rxData = 0;
char rxByte = 1;
char channel = 0;
char status = 0;
char lastStatus = 0;
char lcdData[16] = {0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};

const char headerAddr = 0x87;
const char dataAddr = 0xC0;
const char initSequence[4] = {
                                0x3C,0x0C,0x01,0x06
                            };
const char charMap[10] = {
                            0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39
                        };
const char mainHeader[6] = {
                              0x4D,0x73,0x67,0x20,0x43,0x68
                          };
const char noteHeader[9] = {
                              0x4E,0x6F,0x74,0x65,0x20,0x56,0x65,0x6C,0x20
                          };
const char ctrlHeader[9] = {
                              0x43,0x6F,0x6E,0x74,0x20,0x56,0x61,0x6C,0x20
                          };
const char progHeader[9] = {
                              0x50,0x72,0x6F,0x67,0x20,0x20,0x20,0x20,0x20
                          };
const char presHeader[9] = {
                              0x50,0x72,0x65,0x73,0x20,0x20,0x20,0x20,0x20
                          };
const char pitchHeader[9] = {
                               0x4D,0x53,0x42,0x20,0x20,0x4C,0x53,0x42,0x20
                           };
const char msg[7][3] = { {
                            0x4F,0x46,0x46
                        }
                        ,{ 0x20,0x4F,0x4E},
                        { 0x41,0x46,0x54},
                        { 0x43,0x43,0x48},
                        { 0x50,0x43,0x48},
                        { 0x43,0x48,0x50},
                        { 0x50,0x57,0x48}
                      };

void main(void) {

   WDTCTL = WDTPW + WDTHOLD;
   BCSCTL1 = CALBC1_8MHZ;
   DCOCTL = CALDCO_8MHZ;

   _delay_cycles(100000);

   P1OUT &= ~(CLOCK_PIN + DATA_PIN);
   P1OUT |= ENABLE_PIN;
   P1DIR |= ENABLE_PIN + CLOCK_PIN + DATA_PIN;

   P1SEL = MIDI_IN_PIN;
   P1SEL2 = MIDI_IN_PIN;

   UCA0CTL1 |= UCSSEL_2;
   UCA0BR0 = 0x00;
   UCA0BR1 = 0x01;
   UCA0CTL1 &= ~UCSWRST;
   IE2 |= UCA0RXIE;

   while(charIndex < 4) {
       sendFunction(initSequence[charIndex]);
       charIndex++;
       _delay_cycles(16000);
   }

   charIndex = 0;
   while(charIndex < 6) {
       sendData(mainHeader[charIndex]);
       charIndex++;
   }

   __bis_SR_register(GIE);

   while(1) {
       if(lastStatus != status) {
           sendFunction(headerAddr);
           if(status == 3) {
               sendHeader(ctrlHeader);
           } else if(status == 4) {
               sendHeader(progHeader);
           } else if(status == 5) {
               sendHeader(presHeader);
           } else if(status == 6) {
               sendHeader(pitchHeader);
           } else {
               sendHeader(noteHeader);
           }
           lastStatus = status;
       }
       sendFunction(dataAddr);
       digitCounter = 0;
       while(digitCounter < 16) {
           sendData(lcdData[digitCounter]);
           digitCounter++;
       }
   }
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void) {
   rxData = UCA0RXBUF;
   if(rxData & BIT7) {
       if(rxData < 0xF0) {
           status = (rxData >> 4) - 8;
           channel = (rxData & 0x0F) + 1;
           lcdData[0] = msg[status][0];
           lcdData[1] = msg[status][1];
           lcdData[2] = msg[status][2];
           setLCDData(3, channel);
       }
       return;
   } else {
       if(rxByte == 1) {
           rxByte = 2;
           if(status == 4 || status == 5) {
               clearData(12);
               rxByte = 1;
           } else if (status == 6) {
               setLCDData(12, rxData);
               return;
           }
           setLCDData(8, rxData);
       } else {
           rxByte = 1;
           if(status == 6) {
               setLCDData(8, rxData);
               return;
           }
           setLCDData(12, rxData);
       }
   }
}

void clearData(char startIndex) {
   lcdData[startIndex] = 0x20;
   lcdData[startIndex + 1] = 0x20;
   lcdData[startIndex + 2] = 0x20;
}

void sendHeader(const char* header) {
   char hdrIndex = 0;
   while(hdrIndex < 9) {
       sendData(header[hdrIndex]);
       hdrIndex++;
   }
}

void setLCDData(char startIndex, char data) {
   // int to BCD
   clearData(startIndex);
   charIndex = startIndex + 2;
   lcdData[charIndex] = 0x30;
   while(data > 0) {
       lcdData[charIndex] = charMap[data % 10];
       data /= 10;
       charIndex--;
   }
}

void send(char data, char registerSelect) {
   bitCounter = 0;
   while(bitCounter < 8) {
       (data & BIT7) ? (P1OUT |= DATA_PIN) : (P1OUT &= ~DATA_PIN);
       data <<= 1;
       P1OUT |= CLOCK_PIN;
       P1OUT &= ~CLOCK_PIN;
       bitCounter++;
   }
   registerSelect ? (P1OUT |= DATA_PIN) : (P1OUT &= ~DATA_PIN);
   P1OUT &= ~ENABLE_PIN;
   P1OUT |= ENABLE_PIN;
}

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...