Pin Toggle Performance

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
rosenrot
Posts: 30
Joined: Mon Dec 12, 2016 9:39 pm

Pin Toggle Performance

Post by rosenrot » Mon Dec 12, 2016 9:41 pm

Hi everyone,

could someone tell me how to toggle the 0 pin the fastest way? I found this post, but it is mostly talking about the STM uC. Maybe someone could tell me how to switch the 0 pin as fast as possible. Maybe with the help of ASM commands?

http://www.mikrocontroller.net/topic/388161

Thanks,

rose

User avatar
ernitron
Posts: 89
Joined: Fri Jun 03, 2016 5:53 pm
Location: The Netherlands

Re: Pin Toggle Performance

Post by ernitron » Tue Dec 13, 2016 7:35 pm

Check the topic on sound in here and the reply of pythoncoder. There was a contest on how fast a pin could be set. I am on my mobile and cannot get the link but you can easily find there.

Edit: found
http://forum.micropython.org/viewtopic.php?f=2&t=1349

rosenrot
Posts: 30
Joined: Mon Dec 12, 2016 9:39 pm

Re: Pin Toggle Performance

Post by rosenrot » Tue Dec 13, 2016 7:46 pm

Thanks a lot!

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pin Toggle Performance

Post by Roberthh » Tue Dec 13, 2016 8:06 pm

These two links circle around the same contest. More recent for the ESP8266 is the following discussion, even if the title is misleading:
http://forum.micropython.org/viewtopic.php?f=16&t=2678
The answer would be like 21.8 us for a full cycle at 80 MHz, using the native code emitter, with something like:

Code: Select all

@micropython.native
def toggle():
    import machine

    pdsckPin = machine.Pin(4, machine.Pin.OUT, value=0)
    isr = machine.disable_irq()

    for i in range(24):
        pdsckPin.value(1)
        pdsckPin.value(0)

    machine.enable_irq(isr)
Using viper code & direct port access should be much faster.

rosenrot
Posts: 30
Joined: Mon Dec 12, 2016 9:39 pm

Re: Pin Toggle Performance

Post by rosenrot » Tue Dec 13, 2016 10:04 pm

Good, that sounds like there is the possibility to get a full cycle of 250ns. I will try this. Thanks again for linking me further!

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pin Toggle Performance

Post by Roberthh » Wed Dec 14, 2016 6:24 am

It's 21.8 µs for each of the 24 cycles, not for all 24 cycles, and the first cycle always takes longer.

jms
Posts: 108
Joined: Thu May 05, 2016 8:29 pm
Contact:

Re: Pin Toggle Performance

Post by jms » Fri Dec 16, 2016 1:20 pm

Since Micropython on this platform executes not much faster than BASIC on a BBC Micro if you want sub 1uS you'll need to write it in C. You could cheat and pretend it's an SPI device and clock out something using that.

Jon

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Pin Toggle Performance

Post by Roberthh » Sat Dec 17, 2016 3:18 pm

Using viper code and direct register access, you can get a "little bit" faster. The following code example creates a 100 pulse burst with a time of 376 ns between two pulses (or 2.66 MHz) at 80 MHz clock frequency. Using C code or assembler would be a little bit faster

Code: Select all

def toggle():
    import machine
    pdsckPin = machine.Pin(4, machine.Pin.OUT, value=0)
    isr = machine.disable_irq()
    do_toggle()
    machine.enable_irq(isr)

@micropython.viper
def do_toggle():
    GPIO_OUT = ptr32(0x60000300) # GPIO base register
    for i in range(100):
        GPIO_OUT[1] = 0x10 # set bit 4
        GPIO_OUT[2] = 0x10 # clear bit 4
Unrolling the loop results in a period duration of 150ns @ 80MHz.
Update: Setting the CPU clock to 160 MHz does NOT increase the toggle frequency.

poesel
Posts: 22
Joined: Sun Oct 20, 2019 4:58 pm

Re: Pin Toggle Performance

Post by poesel » Sun Jun 21, 2020 10:30 am

Sorry to dig this up.
I failed to find any documentation on this part:
GPIO_OUT = ptr32(0x60000300) # GPIO base register
for i in range(100):
GPIO_OUT[1] = 0x10 # set bit 4
GPIO_OUT[2] = 0x10 # clear bit 4
Is there documentation or is it obsolete by now?

Post Reply