ODROID-N2 UART Custom Baud Rate for MIDI

I needed my ODROID-N2’s UART port to operate at a non-standard baud rate so that I could use MIDI. I edited the UART driver code to set baudrate to 31250 when setting baud rate to 38400, then wrote test code using wiringPi, and measured the baud rate.

UART driver after editing

linux/drivers/amlogic/uart/meson_uart.c

static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
{
u32 val;
struct meson_uart_port *mup = to_meson_port(port);
struct platform_device *pdev = to_platform_device(port->dev);

while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_EMPTY))
cpu_relax();

#ifdef UART_TEST_DEBUG
if (port->line != 0)
baud = 115200;
#endif

// this part is added.
// trace_printk() is not neccesarry, it is just for debugging.
trace_printk("Your baudrate: %ld\n", baud);
if(baud == 38400)
{
baud = 31250;
trace_printk("Change to %ld\n", baud);
}
Linux kernel build Ref: https://wiki.odroid.com/odroid-n2/softw ... ing_kernel

Changes of Installation section

  • arch/arm64/boot/Image -> arch/arm64/boot/Image.gz
  • arch/arm64/boot/dts/meson64_odroidn2.dtb -> arch/arm64/boot/dts/amlogic/meson64_odroidn2.dtb

Test code

#include 
#include

int main(void)
{
int fd1, fd2;
fd1 = serialOpen("/dev/ttyS1", 38400);
fd2 = serialOpen("/dev/ttyS2", 38400);

serialPutchar(fd1, 0xAA); // 10101010
serialPutchar(fd1, 0xAA);

int count = 0;
while(1)
{
if(serialDataAvail(fd2))
{
printf("%c", serialGetchar(fd2));
count++;
if(count == 2)
{
break;
}
}
}

serialClose(fd1);
serialClose(fd2);
}
Figure 1 - Before editing - when transmitting 10101010, 1s / pulse-width is baud rate, and 1s/26.088us is 38331 ~= 38400
Figure 1 - Before editing - when transmitting 10101010, 1s / pulse-width is baud rate, and 1s/26.088us is 38331 ~= 38400

Figure 2 - After editing - 1s/32.002us is 31248 ~= 31250
Figure 2 - After editing - 1s/32.002us is 31248 ~= 31250

Debugging with ftrace

root@odroid:/home/odroid# stty -F /dev/ttyS0 38400
root@odroid:/home/odroid# cat /sys/kernel/debug/tracing/trace
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
...
0) | uart_set_termios() {
0) | uart_change_speed.isra.2() {
0) | meson_uart_set_termios() {
0) 0.875 us | uart_get_baud_rate();
0) | /* Your baudrate: 38400 */
0) | /* Change to 31250 */
0) 0.250 us | uart_update_timeout();
If you want to cross compile, the sequence is shown below:

  • Installing required packages
  • Toolchain (6.3.1)
  • Checkout(Linux tab)
  • <- edit driver
  • Compile(Basic tab)
  • Installation(Linux tab)

For comments, questions, and suggestions, please visit the original ODROID forum post at https://forum.odroid.com/viewtopic.php?f=180&t=36540.

Be the first to comment

Leave a Reply