fastmapper
Posts: 27
Joined: Wed Mar 27, 2013 3:54 am

GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 12:27 am

I've been trying to use the GPIO pins at high rates using assembly language. Through the course of development I have stumbled upon a problem reading and writing the GPIO pins.

If I set or clear a GPIO pin, then read the state of the GPIO pins on the next assembly instruction, it generally but not always reflects the set or clear operation performed on the previous instruction. I have not observed an instance where the second read of the GPIO pins does not reflect a set or clear.

So my question is: what is the minimum requirement to ensure a set or clear has completed before a GPIO pin read?

User avatar
joan
Posts: 14472
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 8:00 am

How long is a piece of string, or in your case wire?

It won't be successfully set or cleared until the device on the other end of the gpio recognises the state. I'd guess that will vary.

techpaul
Posts: 1512
Joined: Sat Jul 14, 2012 6:40 pm
Location: Reading, UK
Contact: Website

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 11:34 am

Sounds to me like you need to look in detail at what system clock divsion drives the GPIO section of the SOC and ensure access are not cached in some way.

Also be sure what you are reading is correct i.e. is the software reporting one thing but the hardware doing something else?

I would put a square wave out on the GPIO (toggle GPIO pin) and measure on a scope, and change state of another GPIO if you read back something not as expected to trigger a scope.
Just another techie on the net - For GPIO boards see http:///www.facebook.com/pcservicesreading
or http://www.pcserviceselectronics.co.uk/pi/

feverish
Posts: 486
Joined: Wed Jun 27, 2012 2:29 pm

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 12:42 pm

fastmapper wrote:I've been trying to use the GPIO pins at high rates using assembly language. Through the course of development I have stumbled upon a problem reading and writing the GPIO pins.

If I set or clear a GPIO pin, then read the state of the GPIO pins on the next assembly instruction, it generally but not always reflects the set or clear operation performed on the previous instruction. I have not observed an instance where the second read of the GPIO pins does not reflect a set or clear.

So my question is: what is the minimum requirement to ensure a set or clear has completed before a GPIO pin read?
I have no idea about other high-level languages, but thread-completion time is an occasional but reasonably well-known problem in Delphi or Lazarus. In order to ensure the completion of one instruction before the application proceeds to the following one, the instruction 'application.ProcessMessages;' can be used, but care is needed, as over-use tends markedly to slow down total progress.
If discrimination is not challenged then we are effectively in collusion with the perpetrators of such behaviour:-Oxford dictionaries

fastmapper
Posts: 27
Joined: Wed Mar 27, 2013 3:54 am

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 2:35 pm

Since I'm reading the state of the pin within the Broadcom BCM2835, I suspect the wire length would be only a few microns.

For the experiments I've done: what I'm reading is correct after two reads even if it is incorrect after one.

I have checked the signal on an oscilloscope, but I cannot see when the GPIO pin read takes place.

Here is a code snippet:

Code: Select all

1:
        str     r4, [r0, 28]            // set GPIO pin 7

        ldr     r7, [r0, 52]            // read GPIO pins 0 .. 31
        ldr     r8, [r0, 52]            // read GPIO pins 0 .. 31
        ldr     r9, [r0, 52]            // read GPIO pins 0 .. 31

        str     r4, [r0, 40]            // clear GPIO pin 7

        ldr     r10, [r0, 52]           // read GPIO pins 0 .. 31
        ldr     r11, [r0, 52]           // read GPIO pins 0 .. 31
        ldr     r12, [r0, 52]           // read GPIO pins 0 .. 31

        stmia   r1!, { r7 - r12 }    // store the captured states of GPIO pins 0 .. 31

        subs    r2, 1
        bne     1b
At the beginning of this code, the registers are set as follows:
r0 holds the GPIO peripheral address (0x7e200000)
r1 holds the address of a memory buffer to hold GPIO pin samples
r2 holds the count of the number of samples to take

When I review the results, I can see the expected values on the second capture of the GPIO pin state. Unfortunately, the first capture of the GPIO pin state does not always do that. I have estimated the failure rate to be only about 1 in a thousand. This may sound low until it is needed for long sequences (millions).

User avatar
joan
Posts: 14472
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 3:54 pm

If you have a particular circuit in mind you can determine the "settle" time by experiment. I don't think there is an answer in the general sense.

For instance if the gpio is connected to ground or 3.3V it will never show high or low respectively.

User avatar
aTao
Posts: 1087
Joined: Wed Dec 12, 2012 10:41 am
Location: Howlin Eigg

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 4:08 pm

I have seen mentioned in Broadcom information, probably the GPIO datasheet we have that you really ought to use a memory barrier to prevent problems when switching between 2 different GPIOs.
Due to the bus structure it is possible that bytes from 2 consecutively read locations arrive out of order. Likewise that bytes written to 2 consecutively written locations may arrive out of order. To prevent problems arising from this the advice is to write the same data twice or read twice when switching between different GPIOs.
Not quite the same as the problem here but it sure sounds darned similar, possibly the same problem, especially given that the second read always presents the correct value.
>)))'><'(((<

fastmapper
Posts: 27
Joined: Wed Mar 27, 2013 3:54 am

Re: GPIO Set / Clear Latency Problem

Sun Apr 07, 2013 10:18 pm

Here is what the BCM2835 ARM Peripherals document says:
Accesses to the same peripheral will always arrive and return in-order.
and
It is not required to put a memory barrier instruction after each read or write access. Only at
those places in the code where it is possible that a peripheral read or write may be followed
by a read or write of a different peripheral.
Since I am working with only one peripheral (GPIO), I don't think this applies. But maybe the documentation is incorrect and a memory barrier is needed even for the same peripheral.

I did perform a test with a data memory barrier (DMB) instruction after set and before read. Although the problem appears to be less frequent, I still have instances where the first GPIO read does not reflect the result of the GPIO set.

I'm starting to get the idea that there are latencies in the GPIO peripheral that have not been described.

Return to “Interfacing (DSI, CSI, I2C, etc.)”