[sdiy] bizarre pic-midi issues

Karl Ekdahl elektrodwarf at yahoo.se
Fri Apr 16 20:19:38 CEST 2010


Hi

> How are you getting the data from the UART?  Are you
> polling or using interrupts?
> 
> If you're polling, there's the possibility that the byte
> you were expecting has been overwritten by another one by
> the time you go to look for it.

I'm polling, tried it in a closed loop that's doing *nothing* except for polling RCIF and then immediately taking out the data out of RCREG, i also tried manually resetting RCIF even tho it's supposed to be doing it itself.
 
> Have you implemented running status and Note On w/ velocity
> == 0?  Are you handling active sensing and real-time
> messages?

Haven't gotten that far yet since i mostly get garbage.

> Have you looked at the incoming data with a scope, to make
> sure it's got good levels and clean edges?  It could be
> a signal integrity problem.

The signals look very clean to me, it's normally HIGH and then having the data go LOW.

> Can you verify the content of the MIDI data you're
> receiving with MIDI Ox or the like?  If the
> transmitting hardware beyond reproach?

I'm sending the data from my Juno 2 to my computer which monitors the data and then outputs it to my hardware - looks fine. The very interesting bit is that my hardware somehow completely fails at getting the 0xFE active sensing messages half the time, when they do show up they mostly become 0xFF instead.

The hardware i'm using is a PIC18F4550 connected with it's RX pin tied to pin 6 of a 6N136 via a 2.7K pull-up resistor, pin 5 on the 6N136 goes to ground, pin 2 & 3 are connected to pin 4 & 5 respectively of a DIN MIDI IN jack and i've got a diode with it's anode connected to pin 2 and the cathode to pin 3. 

The initialization sequence is:

	TRISCbits.TRISC7 = 1;
	TRISCbits.TRISC6 = 1;
	RCSTAbits.SPEN = 1;
	
	TXSTAbits.TX9 = 0;
	TXSTAbits.TXEN = 1;
	TXSTAbits.SYNC = 0;
	TXSTAbits.SENDB = 0;
	TXSTAbits.BRGH = 0;
	
	RCSTAbits.SPEN = 1;
	RCSTAbits.RX9 = 0;
	RCSTAbits.CREN = 1;
	RCSTAbits.ADDEN = 0;
	
	BAUDCONbits.ABDOVF = 0;
	BAUDCONbits.RCIDL = 0;
	BAUDCONbits.RXDTP = 0;
	BAUDCONbits.TXCKP = 0;
	BAUDCONbits.BRG16 = 0;
	BAUDCONbits.WUE = 0;
	BAUDCONbits.ABDEN = 0;
	
	SPBRGH = 0;
	SPBRG = 11;

Running a 12MHZ crystal to the PIC with the following division attributes:
#pragma config PLLDIV = 3 
#pragma config CPUDIV = OSC3_PLL4
#pragma config USBDIV = 2

and the fetching routine is simply (very unfinished):

void midiAddData() {
	char a;

//	
	if (midiReadBufferWritePointer == midiReadBufferSize) {
		a = RCREG;
		return;
	}
	midiReadBuffer[midiReadBufferWritePointer] = RCREG;
	midiReadBufferWritePointer++;
}

void midiParseData() {
	if (midiReadBufferWritePointer == 0) { return; }

// Check if we've got a real time message as the last thing in the que
	if ((midiReadBuffer[midiReadBufferWritePointer - 1] & 0xF8) == 0xF8) {
		midiStatus = midiReadBuffer[midiReadBufferWritePointer - 1];
		midiReadBufferWritePointer--;
	} else {
		switch(midiReadBuffer[midiReadBufferReadPointer] & 0xF0) {
			case 0x80:
			case 0x90:
			case 0xA0:
			case 0xB0:
			case 0xE0:
// check so we got enough data
				if (midiReadBufferReadPointer + 3 <= midiReadBufferWritePointer) {
				//	message = 1;
					midiStatus = midiReadBuffer[midiReadBufferReadPointer];
					midiData1 = midiReadBuffer[midiReadBufferReadPointer + 1];
					midiData2 = midiReadBuffer[midiReadBufferReadPointer + 2];
					midiReadBufferReadPointer += 3;
				}
				break;
			case 0xC0:
				if (midiReadBufferReadPointer + 2 <= midiReadBufferWritePointer) {
					break;
				}
				break;
			case 0xFE:
				break;
			default:
				midiStatus = 0;
				midiReadBufferReadPointer = 0;
				midiReadBufferWritePointer = 0;
		}
	}

	if (midiReadBufferReadPointer >= midiReadBufferWritePointer) {
		midiReadBufferReadPointer = 0;
		midiReadBufferWritePointer = 0;
	}
}

and then i loop it:
	char error;
do {
	if (PIR1bits.RCIF) {
		midiAddData();
		midiParseData();
	}

	if ((RCSTAbits.FERR == 1) | (RCSTAbits.OERR == 1)) {
		error = RCSTA;
		RCSTAbits.CREN = 0;
		RCSTAbits.CREN = 1;
	}
} while (1 == 1);






More information about the Synth-diy mailing list