Code review request for viper timing

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
cabalist
Posts: 7
Joined: Thu Jun 02, 2016 7:37 pm

Code review request for viper timing

Post by cabalist » Tue Feb 07, 2017 7:24 pm

I have a very strong feeling that I am doing this wrong but I've got my code working and was hoping someone could weigh in on this chunk.

The following code is used to time bringing a pin high/low for ~5.3 microseconds. send_command is given a number that is converted to binary pulses. (i.e. 170 -> 10101010 -> -_-_-_-_). So... bit-banging. This is running on the esp8266 but I haven't tried it on other boards. I have been unsuccessful using time.usleep with viper to get accurate timing (it takes too long) but this code "works" and gives me the resolution I need. This seems to abuse assumptions about the cpu cycles but I am curious if there an equivalent that I am missing from not having read enough documentation.

Questions I have:
Is this code portable to other micropython boards? What are the downsides to setting the bit 16 times? Am I missing an obvious viper function that does this already?


disable_irq() is called before this code executes.

Code: Select all

@micropython.viper
def send_command(data:int):
    GPIO_OUT = ptr32(0x60000300) # GPIO base register
    for i in range(8):
        if data & 0x80:
            for _ in range(16):
                GPIO_OUT[1] = 0x10 # set bit 4
        else:
            for _ in range(16):
                GPIO_OUT[2] = 0x10 # clear bit 4
        data <<= 0x1

    GPIO_OUT[2] = 0x10 # clear bit 4 at end    
Thanks in advance for any help or insight. :)

Edit: typos

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Code review request for viper timing

Post by pythoncoder » Wed Feb 08, 2017 7:57 am

It's unlikely to be portable for two reasons. Firstly the GPIO address and method of setting and clearing bits will be platform dependent. Secondly implementing a delay with a loop means that the length of the delay will be dependent on the clock frequency and the underlying machine instruction set. But a loop may well be the only way to achieve a sufficiently precise 5.3us delay.

You could achieve some portability by querying the platform and clock rate and setting parameters to suit.

You might also get better timing granularity by setting the GPIO bit once, then running an empty loop to achieve the delay:

Code: Select all

        if data & 0x80:
            GPIO_OUT[1] = 0x10 # set bit 4
            for _ in range(some_number):
                pass
(Because an empty loop is likely to run faster).
Peter Hinch
Index to my micropython libraries.

Post Reply