StuartF
Posts: 30
Joined: Sun Feb 02, 2014 5:41 pm

Solid 31250 UART Midi

Mon Mar 02, 2015 11:56 pm

Here is a solution for SOLID 31250 uart midi rate for raspian.

Do the Dom suggested removal of ttyAMA0 from cmdline.txt and add the 'bcm2708.uart_clock=3000000'

However, do nothing to the config.txt (remove references if you already have the uart stuff in).

The #includes are for this code, other #includes may be required....

Code: Select all


#include <termios.h>
#include <sys/mman.h>
#include <errno.h>

#define	 UART_BASE	0x20201000 // PL011 USART -->B+





int fd = 0;	
int mem_fd = 0;
int errsv = 0;

volatile unsigned* uart = NULL;
void* uart_map = NULL;
void* IBRD = NULL;
void* FBRD = NULL;
void* LCRH = NULL;
void* UARTCR = NULL;
void* UARTFR = NULL;

uint32_t brd = 0;

struct termios termios_p;
	
fd = open( "/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK );

if( fd > 0 ) // set the baud rate and other configurations
{
	tcgetattr( fd, &termios_p );

	termios_p.c_lflag &= ~ISIG;		// no signals 
	termios_p.c_lflag &= ~ICANON;	// no canonical mode
	termios_p.c_lflag &= ~ECHO;	// no echo input
	termios_p.c_lflag &= ~NOFLSH;	// no flushing on SIGINT
	termios_p.c_lflag &= ~IEXTEN;	// no input processing
	
	termios_p.c_cc[VMIN] = 0;
	termios_p.c_cc[VTIME] = 0;
		
	tcsetattr( fd, TCSANOW, &termios_p );

	// Now set the uart baud rate divisors
	if( ( mem_fd = open( "/dev/mem", O_RDWR | O_SYNC ) ) < 0 )
	{
		fprintf( stdout, "can't open /dev/mem for mmap(). Did you use 'sudo' ?\n" );
		return;
	}

	uart_map = mmap( NULL, BLOCK_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, UART_BASE );

	close( mem_fd );

	if( uart_map == MAP_FAILED )
	{
		errsv = errno;
		fprintf( stdout,"uart mmap failed\n" );
		fprintf( stdout, "error %d %s\n", errsv, strerror( errsv ) );
	}
	else
	{
		uart = (volatile unsigned*)uart_map;
		UARTFR = (void*)( (uint32_t)uart + 0x18 );
		IBRD = (void*)( (uint32_t)uart + 0x24 );
		FBRD = (void*)( (uint32_t)uart + 0x28 );
		LCRH = (void*)( (uint32_t)uart + 0x2C );
		UARTCR = (void*)( (uint32_t)uart + 0x30 );

		// first, disable the uart and flush the fifos
		brd = 0x0B00;
		memcpy( UARTCR, &brd, 4 );

		// check for completion of any tx/rx
		memcpy( &brd, UARTFR, 4 );
		while( brd & 0x08 )
		{
			usleep( 1 ); // wait a bit
			memcpy( &brd, UARTFR, 4 );
		}

		brd = 6; // 3000000 / ( 16 * 31250 ) = 6.0
		memcpy( IBRD, &brd, 4 );
		brd = 0;
		memcpy( FBRD, &brd, 4 );
		brd = 0x70; // 8 bit data, FIFO enabled
		memcpy( LCRH, &brd, 4 );

		// enable uart, tex, rex etc.
		brd = 0x0B01;
		memcpy( UARTCR, &brd, 4 );

		// close mmap once done here
		munmap( uart_map, BLOCK_SIZE );
	}
}
else
{	
	errsv = errno;
	fprintf( stdout,"/dev/ttyAMA0 access failed\n" );
	fprintf( stdout, "error %d %s\n", errsv, strerror( errsv ) );
	fd = 0;
}


Setting the uart_clock to 2441406 sets to an actual of 2441000. This introduces an error rate
that in turn causes, well, errors every n bits. In my case it was every 6th bit.

That in turn led to a RTFM moment :o (ARM PL011) to get to this solution.

Stu.

toxibunny
Posts: 1382
Joined: Thu Aug 18, 2011 9:21 pm

Re: Solid 31250 UART Midi

Tue Mar 03, 2015 6:20 am

Bookmarked, thanks!
note: I may or may not know what I'm talking about...

jablo
Posts: 1
Joined: Sat Apr 04, 2015 7:26 pm

Re: Solid 31250 UART Midi

Sat Apr 04, 2015 7:28 pm

Just got a Raspberry pi as a birthday present, and thought "hey, a nice midi soft synth for my home studio". And ended up here... midi and raspberry pi apparently aren't that easy. Oh well, more time for fun, then.

Thanks for this interesting solution, bookmarked!

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 12125
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Solid 31250 UART Midi

Sat Apr 04, 2015 10:51 pm

Setting the uart_clock to 2441406 sets to an actual of 2441000. This introduces an error rate
that in turn causes, well, errors every n bits. In my case it was every 6th bit.
serial not synchronous interfaces synchronize on each start bit, so the baud rate doesn't have to be exact, in fact for an eight bit word, where after all ten bits a stop bit (of undetermined length) and then a start bit occurs, a rate deviation of even 3 percent is acceptable, and no bit errors will ever occur. The PI's approximation of the MIDI baudrate is well within such limits, so transmission errors should NOT occur. also baud rate deviations should have no influence on the "speed of the music", as MIDI is designed so that the actual absolute baud rate has no influence on the music played. in this cate the rate deviation is 0.1066 % far to small to cause problems.

https://en.wikipedia.org/wiki/Asynchron ... munication

StuartF
Posts: 30
Joined: Sun Feb 02, 2014 5:41 pm

Re: Solid 31250 UART Midi

Sun Apr 05, 2015 9:16 pm

In theory I agree, and yet in practice there it was...

For the record the uart was running from the pi through an old Roland sampler midi pcb ( photodiode, DIN sockets ) to one of those cheap usb->midi DIN convertors to a PC running midi/ox as the receiver/transmitter.
Maybe there was some sync problem in the connection rig, but when I implemented the exact rate, the problem went away.

This is a way of getting 0% deviation (in theory) using mmap.

The manual used can be found here...
http://infocenter.arm.com/help/topic/co ... p5_trm.pdf
Sections 3.3.5 & 3.3.6 cover the baud rate registers, including the calculation.

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 12125
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Solid 31250 UART Midi

Mon Apr 06, 2015 1:58 am

(rant mode =on) Even if you find a case where the practice seems different, it does not magically overrule the theory, the theory stays valid. The fact that you simply don't understand what happened doesn't invalidate the theory. :roll:
If we al started believing valid theories are sometimes just wrong, (for no explained scientific reason) we couldn't have evolved science to the degree we have. If you don't understand what happened, please don't make such absolute claims as that "the theory is untrue", the real answer is probably elsewhere perhaps in the fact that baudrate and and system response are somehow dependent although as designed they should not be. (rant mode = off)

in any normal case an normally precise approximation of the baud rate should suffice.
I do believe a more precise baud rate setting is possible, but that is another point altogether, and it will still always be an approximation.

StuartF
Posts: 30
Joined: Sun Feb 02, 2014 5:41 pm

Re: Solid 31250 UART Midi

Tue Apr 07, 2015 6:18 pm

This thread was about a solution to a known problem. i.e. setting a 31250 baud rate for old style 5 pin DIN midi using mmap in C. It was dormant for about a month. Now it has been turned into a rant concerning your opinion of what consitutes 'theory'.

I would expect better of someone who carries the moderator tag.

As I have a right to reply, I will address each point you raise.

You say : "Even if you find a case where the practice seems different, it does not magically overrule the theory, the theory stays valid."

So the sun and planets rotate around the earth then?

You say : "The fact that you simply don't understand what happened doesn't invalidate the theory."

That is an assumption on your part, and is a statement designed to re-enforce your argument.

You say : "If we al(sic) started believing valid theories are sometimes just wrong, (for no explained scientific reason) we couldn't have evolved science to the degree we have."

the interesting part of this statement is the use of 'we'. Attempting to third person yourself into an association with scientific achievements perhaps?. Also, it is worth pointing out that scientific history is littered with theories that have subsequently been found to be false.

You say : "If you don't understand what happened, please don't make such absolute claims as that "the theory is untrue" "

Here, I think you go too far, as you are attibuting a statement which never appears. I am taking advice on this...

You say: "the real answer is probably elsewhere perhaps in the fact that baudrate and and system response are somehow dependent although as designed they should not be."

That will be the part where I detail the connections and all the devices inbetween then.

You say: "I do believe a more precise baud rate setting is possible,"

In the case of 31250, I can confirm it for you, as evidenced by the original post.

and then go on to add "but that is another point altogether"

Actually, that is the point of this thread.

and then finish with: "and it will still always be an approximation"

which is the only thing you got right, but I imagine for the wrong reasons.
The real reason is that of precision, as any real engineer knows well.

As an observation, I see that this is not the first time you have posted such comments in midi and uart related threads. Would you care to explain this particular habit?

Return to “C/C++”