raspberrypi / firmware

This repository contains pre-compiled binaries of the current Raspberry Pi kernel and modules, userspace libraries, and bootloader/GPU firmware.
5.18k stars 1.68k forks source link

Setting UART clock is not reliable #689

Closed vanvught closed 6 years ago

vanvught commented 7 years ago

I have several DMX/MIDI applications running on baremetal.

DMX works at 250 kbit/s. For supporting this baudrate I set the UART clock to 4Mhz using the mailbox interface. Then set the IBRD=1/FBRD=0 accordingly. The FIQ is used for receiving the packets.

This is all working fine with the firmware until the Raspberry 2 Model B V1.2 support was added. With the latest firmware, the PL011 (GPIO 14/15) FIQ is mostly unreliable. Sometimes it works at once. But mostly I have to restart the Raspberry Pi several times to get it to work.

I have no issues with receiving MIDI. In this case I set the the UART clock to 3Mhz (was the default) using the mailbox, And set IBRD/FBRD accordingly to support the MIDI baudrate (31250 baud). The FeIQ is used for receiving the packets.

Receiving MIDI works with all firmware releases on all Raspberry Pi model. Receiving DMX is unreliable, is broken for the most recent firmware releases.

What is changed in the firmware with respect to the PL011 initialization? How could it be that it sometimes works, mostly not?

I am eager to get this issue solved.

Many thanks in advance, Arjan

P33M commented 7 years ago

In each case (working fw/nonworking fw), what does vcgencmd measure_clock uart return?

vanvught commented 7 years ago

When I query the UART clock using the mailbox facility, then I get back the same value as I have set. So from the ARM side it looks all correct.

I have spent ours debugging this issue. It looks to me that when you set a value greater then 3Mhz, this setting is not honored when you start with receiving. Hence the FIQ is not fired as expected. When you first start with a send, then the clock seems to be persistently set immediately.

To illustrate my findings, the code below works with all firmware releases. Prior Raspberry 2 Model B V1.2 support having a default UART clock with 3Mhz. And afterwards, a default 48Mhz.

    uint32_t ibrd = 12;

    if (bcm2835_vc_get_clock_rate(BCM2835_VC_CLOCK_ID_UART) == 3000000) {
        (void) bcm2835_vc_set_clock_rate(BCM2835_VC_CLOCK_ID_UART, 4000000);// Set UART clock rate to 4000000 (4MHz)
        ibrd = 1;
        }

in another place

BCM2835_PL011->IBRD = ibrd;
BCM2835_PL011->FBRD = 0;
popcornmix commented 7 years ago

Presumably the change happened here: https://github.com/raspberrypi/firmware/commit/d0bc6ce8e2ae7850959fed4edb0695f3cddfb96a

firmware: platform: Make the default UART0 clock 48MHz for all Pis See: raspberrypi/linux#1601 See: #643

pelwell commented 7 years ago

The default UART0 clock rate is now 48000000. Why do you need to change the clock at all?

31250 96 16 = 48000000 250000 12 16 = 48000000

vanvught commented 7 years ago

Why do you need to change the clock at all?

The previous default clock rate of 3Mhz was just to slow for DMX. DMX works at 250 kbit/s. With a clock of 4MHz, I can set IBRD=1/FBRD=0 accordingly.

pelwell commented 7 years ago

Your quote omits the important first sentence of my comment. You should now be able to set IBRD=12/FBRD=0.

You may find it more convenient to use a DT overlay to set up a fake clock which pretends to be some fixed fractional multiple of the real clock and configure the UART to use that as its clock. In that way you can ask for a legal baud rate and actually get 250kHz. Other people are already using a similar trick for MIDI using 38400 as the virtual frequency.

vanvught commented 7 years ago

You should now be able to set IBRD=12/FBRD=0.

That is not the issue. Per default I can set the UART clock to 48Mhz. I have done some major testing with all the RPi models. It works correctly with the latest firmware releases.

Can I be 100% sure that setting the UART clock to 48MHz is reliable for all firmware releases prior d0bc6ce? I cannot do the testing for all the "old" releases. Hence, for a quick fix, I have my code as shown above.

Leaves me with the questions:

  1. What is changed in the firmware with respect to the PL011 initialization?
  2. How could it be that setting the UART clock (>> 3Mhz, in this case 4Mhz) sometimes works, mostly not?

It works for all the time when you start sending with the PL011.

pelwell commented 7 years ago

Rather than use this hack, tell users with old firmware to set init_uart_clock=48000000 in config.txt.

vanvught commented 7 years ago

I am not in favor of external settings. It is error prone. When users are setting this incorrectly, then the application won't work. The application setup should be as simple as possible, just the bootcode.bin, fixup.dat, LICENSE.broadcom, start.elf and the 2 kernel files.

Ruffio commented 7 years ago

@vanvught has this issue been resolved?

vanvught commented 7 years ago

@Ruffio I have created a workaround in my code for the issue. My code is now working correctly for all firmware releases. The firmware issue is not resolved.

Ruffio commented 7 years ago

@vanvught why not 'agree' on a method to do in the official firmware and implement it there so others can benefit from it also?

vanvught commented 7 years ago

@Ruffio Yes, it would be the best option to solve the issue in the official firmware. I agree with that.

jens-maus commented 7 years ago

Sorry for being somewhat slightly off-topic, but I am currently suffering here form a similar issue and I am new to the raspberrypi firmware stuff. Is there a possibility to actually query the current UART clock rate from within the linux kernel facilities? And actually via some C-language linux kernel API and not via /proc fs or similar? Here I need to somehow query (from within a linux-kernel module running in a recent kernel 4.4.x) the current uart0 clock rate and cannot find out how to do that or if this is possible at all. Help would be highly appreciated!

pelwell commented 7 years ago

Please start a new topic for this query or, even better, ask in the Forums. If you create it in the Device Tree section, I'm sure it will be noticed.

JamesH65 commented 6 years ago

Closing due to lack of activity. Please request to be reopened if you feel this issue is still relevant.