Midi in problem

Hi, I try to make a midi input on an arduino uno, but without using the arduino library.

I configured the usart for that.

It detects when It gets messages, but the result is not at all what I expected. Instead of lighting the led on note on and shutting it off on note off, it lights it or shuts it depending on the midi note I send to it…

I spent all the afternoon trying to see what is wring ith it, and I’m a bit at a loss of ideas as to where this could come from…

Here is the code:

#define F_CPU 16000000UL

#define BAUD 31250

// MIDI
#define MIDILEN 32
#define NOTEOFF 0x80
#define NOTEON 0x90
#define NOMIDIDATA MIDIin == MIDIout


#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
#include <util/setbaud.h>


volatile uint8_t MIDIbuffer[MIDILEN+1];
volatile int16_t MIDIin;
volatile int16_t MIDIout;


void setupUART()
{
	// Set baud rate
	UBRR0H = UBRRH_VALUE;
	UBRR0L = UBRRL_VALUE;
	
	
	UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8-bit data */
	UCSR0B = (1 << RXEN0) | (1 << RXCIE0);   /* Enable RX and interrupt */
	
}



uint8_t midiMessage;

int main(void)
{
	uint8_t n;
	uint8_t state = 0;
	
	sei();
	
	
	setupUART();
	
	DDRC |= 0b00000001;
	
	while(1)
	{
		
		while (NOMIDIDATA) {}
		
		n = MIDIbuffer[MIDIout];
		MIDIout = (MIDIout+1) & (MIDILEN-1);
		    
		if (n & 0x80) { // If is status byte
			state = n & 0xF0;

			switch (state) {
				case 0x90:
					PORTC = PORTC | 0b00000001;  // lights the led (note on)
				break;
					
				case 0x80:
					PORTC = PORTC & 0b11111110; // turns of the led (note off)
				break;
			}
			
			
		}
				
	}
		
}


ISR(USART_RX_vect) {
	MIDIbuffer[MIDIin] = UDR0;
	MIDIin = (MIDIin+1) & (MIDILEN-1);
}

I configured the usart for that.

Why? Just using Serial.read works well.

See my code at:-
http://www.thebox.myzen.co.uk/Hardware/MIDI_Shield.html

By the way what you posted is not Arduino code.

Thanks, I'll have a look at that !

Serial read would probably work weel as you pointed, but I prefer not to use the arduino library at all.
I'm programming on an arduino uno though, using it as a dev board.
I'm doing that mainly for practice, but also to keep everything as small as possible.

but I prefer not to use the arduino library at all.

Serial read is not a library in the Arduino use of the word.

Well, I should say I prefer doing it without any libs or extentions of any sort. Only interacting with registers and the sort.

Well, I should say I prefer doing it without any libs or extentions of any sort.

So don't use the C language then, most of it is written in C and so is an extension. Just use assembler.

No, C is not an extention. It's a language. And it is a pretty low level language, so it's ok with me.

When I'm talking about extention, I'm mostly talking about set of functions already available. The only ones I'll allow me to use are those included with libc.

In some parts of the synth project, where I'll need it, I do plan to use inline assembler. Though it's not practical to use it only, and doesn't adds much more performance (assembler are pretty well made nowadays, and optimise quite well).

No, C is not an extention. It's a language.

Most of C is written in C, are you disputing that?

Of course c is c. I don't see what's the point you're trying to make...

The point is that you seem to be happy to use C, which itself is full of extensions. You even seem to be happy to use C with non standard extensions, like the fact that it “knows” what all the registers are called in an AVR micro controller. But you are very arbitrarily drawing a line against using a serial read function. It makes no sense at all, their is no logic to it, why do you just not use assembler?

Especially when you don’t seem to have a clue about how to go about doing it, from the look of that code. And you include all those extensions anyway

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
#include <util/setbaud.h>

"like the fact that it "knows" what all the registers are called"
That's simple defines, it is all resolved at compile time. Also, it's from the official headers from libc.

As for delay, it was here for debug purpose, I'll need the timer anyway, so I'll remove it.

These are all official libraries, all come from what was readily available with the libs provided by libc.

IO is standard avr header, as well as delay and interrupt. Math is standard c.

And guess what? setbaud was the one breaking my code, for some reason. I rewrote it, and now everything works perfect.

I don't use pure assemble because I'd gain no real optimisation or additional flexibility by doing this, while using pure c over arduino library makes me gain a huge deal of flexibility.

"you don't seem to have a clue about how to go about doing it, from the look of that code"

Oh? So what's bad in my code?

"you include all those extensions anyway"
Yep, they're all libc. They're not all used here, mainly because they come from the complete project, and from earlier versions. That'll be cleared though.

OK have it your own way but your distinctions about what you will accept and what you won't accept are totally arbitrary and make no sense.