omenie
Posts: 94
Joined: Fri Dec 09, 2011 5:09 pm
Contact: Website

Re: Midi Baud Rate (31250)

Mon Apr 08, 2013 11:13 pm

Tweaking a Pi to get MIDI bitrate out of the UART is dead easy and well-documented - just do this inside config.txt -

#this should bring 38400 to be 31250 ...
init_uart_clock=2441406
#init_uart_clock=3686400
init_uart_baud=38400

Then setting up your UART as 38400 magically makes it be 31250 and MIDI just works once you add the opto, as evidenced by my MIDI PCB - http://www.flickr.com/photos/philatkin/ ... hotostream

SiriusHardware
Posts: 502
Joined: Thu Aug 02, 2012 9:09 pm
Location: UK

Re: Midi Baud Rate (31250)

Fri Oct 04, 2013 5:23 pm

Thanks for quoting those details, but it would still be even better if the Pi just had 31250 as one of its default serial baud rates.

While it's true that anyone can bodge the baud rate generator as you've described to get it to generate 31250 baud, as soon as you do that, the UART is then no good for its conventional asynchronous comms purpose until you undo the bodge again.

What if you have a mixture of MIDI and comms software that you want to be able to run interchangeably on the same SD card?

I would still really appreciate it if the Pi had native support for 31250 in addition to all of the standard communications baudrates.

wollik
Posts: 10
Joined: Thu Dec 20, 2012 7:16 pm

Re: Midi Baud Rate (31250)

Sat Nov 30, 2013 8:52 pm

Hi SiriusHardware,
the RPI can be used to use the 31250 Baudrate with these two options:

1) Use the internal console port /dev/ttyAMA0 (the console functions must be disabled)
or
2) Use a /dev/ttyUSBx interface created when you connect an USB to RS232 Adapter.
! Please be aware, that you need an adaper that uses the FTDI chipset !

The used serial tty port must be configured via setserial to match the needed customer baurate, in your example 31250 Baud for MIDI usage.

I've allready explained how to set the nonstandart baud rate in this post:
http://www.raspberrypi.org/phpBB3/viewt ... ik#p288760

For the /dev/AMA0 interface that uses a Baud_base of 187500 to get the MIDI baud of 31250 we have to set the divisor to 6.

pi@rpi1 ~/tools $ sudo setserial -a /dev/ttyAMA0
/dev/ttyAMA0, Line 0, UART: undefined, Port: 0x0000, IRQ: 83
Baud_base: 187500, close_delay: 50, divisor: 6
closing_wait: 3000
Flags: spd_cus
t

Please be advised that when you use the /dev/ttyAMA0 interface you need a level shifter to use the RPI 3,3 Voltage.

What ever you use, you have to buy an adapter to connect the DB9 (RS232) Interface from the RPI to the MIDI DIN Interface to connect to your MIDI DIN device(s). To build up these adapter by our own you should have a look at: http://www.midi.org/techspecs/electrispec.php to get an idea what is needed to have a safe and secure interface.

I would sugest to buy a USB to MIDI converter (under €10) that pops up as a ttyUSBx interface and hope, that the baud for this USB to MIDI adapter is fixed set to 31250 baud, what ever speed you try to adjust.
I have one from de-lock (uses a Profilic 2303 chipset) and will check it on my RPI to see what speed will be used.

Once again, the standart profilic 2303 adapters can't be changed to a non customer baudrate! So I hope that my USB to MIDI adapter uses a different hardware clock to support 31250 baud when selecting 38400 baud.

Regards
wollik

pfeuh
Posts: 1
Joined: Fri Mar 11, 2016 8:26 am

Re: Midi Baud Rate (31250)

Fri Mar 11, 2016 8:33 am

I'd also like to add a vote for supporting Midi's 31250 baud rate.

One of the reasons is that doing the things from scratch. For instance, if you want to merge 2 midi inputs to a unique midi output with the ready to use libraries, you can send a received message only when the message is totally received... If you read byte per byte, you can react speedier.

Pfeuh

SiriusHardware
Posts: 502
Joined: Thu Aug 02, 2012 9:09 pm
Location: UK

Re: Midi Baud Rate (31250)

Fri Mar 11, 2016 6:07 pm

Since posting my original query a very long time ago I've succeeded in compiling and running Hatari (the Atari ST emulator) and then running Atari ST Cubase 2, using a commonly available USB midi interface / cable on a low end netbook running Linux. It runs beautifully - all the power and functionality of an Atari ST running Cubase 2, but in a very compact form factor.

I never tried it on the Pi so far because the last time I thought of it, the latest Pi was the single-core Raspberry Pi B+ which I felt wouldn't have enough grunt to carry it off. But now, there's the quad-core 1.2Ghz Pi 3...

I don't have a Pi 3 yet but this is one of the first things I'll be trying when one comes my way.

Note that there were long standing problems with Hatari's MIDI implementation which weren't fixed until Hatari V1.9.0, so if the version in the repos is older you'll have to get the newer version from the devs if it is specifically MIDI software which you want to use.

Further, even in the Hatari stable release version V1.9.0 there was an issue which meant that Cubase 2, specifically, hung on entry to certain edit menus, and a patch was put into the dev version some time ago to fix this. The first stable version to incorporate this Cubase 2 fix will presumably be V1.10.0, whenever that eventually comes out, but in the meantime you can obtain a Cubase 2 compatible version by downloading and compiling the latest dev version.

User avatar
TonyD
Posts: 447
Joined: Thu Sep 08, 2011 10:58 am
Location: Newcastle, UK
Contact: Website

Re: Midi Baud Rate (31250)

Mon Mar 14, 2016 1:55 pm

SiriusHardware wrote:...
I don't have a Pi 3 yet but this is one of the first things I'll be trying when one comes my way.
..
You should be aware that on the Pi3 the UART on the expansion pins has been reassigned to the Bluetooth module.

check out this thread for a little more info:

viewtopic.php?t=138223
Last edited by TonyD on Thu Mar 17, 2016 1:06 pm, edited 1 time in total.
Tony

SiriusHardware
Posts: 502
Joined: Thu Aug 02, 2012 9:09 pm
Location: UK

Re: Midi Baud Rate (31250)

Wed Mar 16, 2016 8:56 pm

TonyD wrote:
SiriusHardware wrote:...
I don't have a Pi 3 yet but this is one of the first things I'll be trying when one comes my way.
..
You should be aware that on the Pi3 the UART on the expansion pins has been reassigned to the Bluetooth module.

check out this thread for a little more info:

viewtopic.php?t=138223
If Hatari runs Cubase 2 fast enough on the Pi 3, then it should, as I've found with other Linux versions on PCs, work happily with a USB -> 5-DIN midi lead.

If so, that bypasses the UART baud rate problem.

However, I'm a little shocked that the hardware UART appears to have been lost to the bluetooth feature as I found it very useful. It's been lost altogether? Not just moved to different pins as has sometimes happened with other alternative-function pins?

User avatar
karrika
Posts: 1070
Joined: Mon Oct 19, 2015 6:21 am
Location: Finland

Re: Midi Baud Rate (31250)

Thu Mar 17, 2016 4:21 am

SiriusHardware wrote: However, I'm a little shocked that the hardware UART appears to have been lost to the bluetooth feature as I found it very useful. It's been lost altogether? Not just moved to different pins as has sometimes happened with other alternative-function pins?
There already exists dt blobs for restoring the old behaviour.

I am also experimenting with the HAT eeprom for forcing non-standard baud rates and move the pins back automatically. My DiscoHAT needs 250k speed from the original UART pins for DMX light control. In theory this should work as a plug-and-play solution.

User avatar
TonyD
Posts: 447
Joined: Thu Sep 08, 2011 10:58 am
Location: Newcastle, UK
Contact: Website

Re: Midi Baud Rate (31250)

Thu Mar 17, 2016 1:09 pm

karrika wrote: I am also experimenting with the HAT eeprom for forcing non-standard baud rates and move the pins back automatically. My DiscoHAT needs 250k speed from the original UART pins for DMX light control. In theory this should work as a plug-and-play solution.
I'd been interested in seeing how you get on.

It's a shame 31250 wasn't made a "standard" baud-rate.
Tony

quietone
Posts: 2
Joined: Mon Mar 28, 2016 9:14 am

Re: Midi Baud Rate (31250)

Mon Mar 28, 2016 9:56 am

Hi folks. I've been trying to get my Pi Zero to talk MIDI over serial over the last couple of days and have managed to get it working, so for anyone else who has been trying, here's how I did it:
My first help came from this page http://www.samplerbox.org/article/midiinwithrpi with reference to getting the baud rate correct and the sample code. I then discovered that this method of baud rate setting no longer works due to a change in the kernel, so then I came to this thread viewtopic.php?t=130326&p=870992%20| and StuartF 's C code which directly addresses the UART registers and sets the baud rate to 31250.
As I want to write my code in Python I combined the two...
First I adapted StuartF 's C code so it would compile on the Pi

Code: Select all

    #include <fcntl.h>          //Used for UART
    #include <unistd.h>         //Used for UART
    #include <termios.h>
    #include <sys/mman.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>

    #define UART_BASE   0x20201000 // PL011 USART -->B+ / ZERO - BCM2835
    //#define   UART_BASE   0x3F201000 // PL011 USART (PI2B+)

    #define BLOCK_SIZE      4096

    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;

    unsigned int brd = 0;

    struct termios termios_s; // save for restore
    struct termios termios_p;

int main(int argc, char *argv[])
{
    fd = open( "/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NONBLOCK );

    if( fd > 0 ) // set the configuration for the terminal
    {
       tcgetattr( fd, &termios_s );

       cfmakeraw( &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, TCSADRAIN, &termios_p );

       // enable the mmap
       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 0;
       }
       
       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 ) );
          fprintf( stdout, "error %d %s\n", errsv);
       }
       else
       {
          uart = (volatile unsigned*)uart_map;
          UARTFR = (void*)( (unsigned int)uart + 0x18 );
          IBRD = (void*)( (unsigned int)uart + 0x24 );
          FBRD = (void*)( (unsigned int)uart + 0x28 );
          LCRH = (void*)( (unsigned int)uart + 0x2C );
          UARTCR = (void*)( (unsigned int)uart + 0x30 );

          // first, disable the uart and flush the fifos
          brd = 0x00;
          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 = 0x0301;
          memcpy( UARTCR, &brd, 4 );
       }
    }
    else
    {
       errsv = errno;
       fprintf( stdout,"/dev/ttyAMA0 access failed\n" );
       fprintf( stdout, "error %d %s\n", errsv, strerror( errsv ) );
       fd = 0;
    }

    return 0;
}
Save as SET_UART_MIDI.C and compile with
gcc SET_UART_MIDI.C -o SET_UART_MIDI

Note that this C prog requires SUDO to run.

Then in Python after setting up the UART with tty I call the C prog to correctly set the UART to 31250.

Code: Select all

#!/usr/bin/env python

import subprocess
import serial

ser = serial.Serial('/dev/ttyAMA0', baudrate=31250)

subprocess.call("./SET_UART_MIDI")

message = [0, 0, 0]
while True:
  i = 0
  while i < 3:
    data = ord(ser.read(1)) # read a byte
    if data >> 7 != 0:
      i = 0      # status byte!   this is the beginning of a midi message!
    message[i] = data
    i += 1
    if i == 2 and message[0] >> 4 == 12:  # program change: don't wait for a
      message[2] = 0                      # third byte: it has only 2 bytes
      i = 3

  print (message)
  messagetype = message[0] >> 4
  messagechannel = (message[0] & 15) + 1
  note = message[1] if len(message) > 1 else None
  velocity = message[2] if len(message) > 2 else None

  if messagetype == 9:    # Note on
    print 'Note on'
  elif messagetype == 8:  # Note off
    print 'Note off'
  elif messagetype == 12: # Program change
    print 'Program change'
Save as sermiditest.py and run with
sudo python sermiditest.py

This works on my Pi Zero and should work on an original Pi. Uncommenting the appropriate #define UART_BASE line in the C code should allow it to work on a Pi2. Once a datasheet is availble for the BCM2837 to figure out the UART address then it should work on a Pi3.

I hope that helps!

codeforge
Posts: 9
Joined: Fri May 01, 2015 10:09 pm

Re: Midi Baud Rate (31250)

Tue Mar 29, 2016 8:47 pm

Hi,
someone could say me how to set 125000 baudrate?

quietone
Posts: 2
Joined: Mon Mar 28, 2016 9:14 am

Re: Midi Baud Rate (31250)

Wed Mar 30, 2016 6:20 pm

The register settings for baud rate can be calculated with
IBRD = UART_CLK / (16 * baud)
temp = (((UART_CLK % (16 * baud)) * 8) / baud)
FBRD = (temp >> 1) + (temp & 1)

On the Pi, UART_CLK = 3000000, so for 125000 baud
IBRD = 1
FBRD = 32

If you put these values in the C code I posted you should get what you want
:)

JovianPyx
Posts: 50
Joined: Fri Nov 20, 2015 9:34 pm

Re: Midi Baud Rate (31250)

Thu Apr 21, 2016 1:14 pm

Rasberry Pi 3 B
Arch Linux 4.4.7

I've been able to use UART0 for MIDI (31250 baud) on a pi3. There are a few configuration changes that need to be made.

1) I don't use bluetooth, so I disabled it. (There is supposed to be a method to put bluetooth on the mini-uart - search left to those that desire that). This is done in config.txt with

Code: Select all

dtoverlay=pi3-disable-bt
Make sure that the overlay file (pi3-disable-bt.dtbo) is in /boot/overlays. This disconnects UART0 from the bluetooth hardware and reassigns it to the original (as in rpi2) GPIO pins.

2) The UART clock defaults to 48 MHz for Rpi3, so this needs to be changed to 3 MHz in config.txt with

Code: Select all

init_uart_clock=3000000
3) The UART must be reprogrammed using mmap() functions to allow a divisor of 6 to be used. When the UART0 clock is set to 3 MHz, this provides a receive bit clock rate of 500000 Hz which is precisely what is needed for a baud rate of 31250.

It is possible to modify the ttymidi source code to use UART0 for existing MIDI software. Anyone wanting to do this should become familiar with the PL011 documentation and the use of mmap.

Return to “General discussion”