Porting drivers to ESP8266 port of MicroPython

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Porting drivers to ESP8266 port of MicroPython

Post by deshipu » Mon Aug 22, 2016 11:51 pm

There are many drivers and libraries already written for MicroPython on the PyBoard, and some of them will even work out of the box. However, most will not, as the ESP8266 port got creative with the API and its standard library, and renamed everything. Below I'm trying to list the most common changes you will need to perform to get the code to run on ESP8266.

Code: Select all

import pyb → import machine
pyb.delay(x) → time.sleep_ms(x)
pyb.udelay(x) → time.sleep_us(x)
pyb.millis() → time.ticks_ms()
pyb.micros() → time.ticks_us()
pyb.Pin('X1', pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE) → machine.Pin(1, machine.Pin.OUT, pull=None)
pyb.SPI(1, SPI.MASTER, baudrate=600000, polarity=1, phase=0, crc=0x7, bits=8, firstbit=SPI.MSB, ti=False) → machine.SPI(baudrate=600000, polarity=1, phase=0)
spi.init(SPI.MASTER, baudrate=600000, polarity=1, phase=0, crc=0x7, bits=8, firstbit=SPI.MSB, ti=False)  → spi.init(baudrate=600000, polarity=1, phase=0)
spi.recv(10) → spi.read(10)
spi.send(0xff) → spi.write(bytearray([0xff]))
spi.send_recv(0xff) → spi.read(1, 0xff)
pyb.I2C(1, pyb.I2C.MASTER, baudrate=400000) → machine.I2C(Pin(5), Pin(4), baudrate=400000)
i2c.send(0xff, 0x42) → i2c.writeto(0x42, bytearray([0xff]))
i2c.recv(3, 0x42) → i2c.readfrom(0x42, 3)
i2c.recv(buffer, 0x42) → i2c.readfrom_into(0x42, buffer)
Those are the ones I encountered most often so far. There are more, of course, and sometimes you will have to rewrite whole fragments to be able to follow the changed logic. But these should get you started.

I wonder if it would make sense to make a library similar to "six", that would let us write the same code for all the ports, no matter which person made decisions for the API of the particular port.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Porting drivers to ESP8266 port of MicroPython

Post by dhylands » Tue Aug 23, 2016 3:02 am

In this case, I think its the pyboard which is "behind".

I know I'll be working on the teensy port in the upcoming weeks and I'll be targeting this API:
https://github.com/micropython/micropyt ... rdware-API

which I believe is what the ESP8266 was targeting (and the WiPy was I believe also targeting at least an early version of that).

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Porting drivers to ESP8266 port of MicroPython

Post by deshipu » Tue Aug 23, 2016 6:19 am

dhylands wrote:In this case, I think its the pyboard which is "behind".
You mean those programs will stop working even on PyBoard?

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

Re: Porting drivers to ESP8266 port of MicroPython

Post by pythoncoder » Tue Aug 23, 2016 6:27 am

There is a long term aim to deprecate pyb in favour of machine. However progress in providing machine on the Pyboard with the same level of functionality seems slow so I suspect that pyb will be with us for a while yet. In the meantime a porting guide is very useful.
Peter Hinch
Index to my micropython libraries.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Porting drivers to ESP8266 port of MicroPython

Post by dhylands » Tue Aug 23, 2016 7:16 am

So looking at the examples, the pyboard has a machine modiule.
The pyboard has a time module and it has sleep_us, sleep_ms, ticks_ms, and ticks_us.
The pyboard Pin has OUT, so you can use machine.Pin.OUT and you can specify pull=None.

I haven't looked into the SPI and I2C modules yet.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Porting drivers to ESP8266 port of MicroPython

Post by deshipu » Tue Aug 23, 2016 7:30 am

The big problem with SPI for me is that you *have* to specify SPI.MASTER (it's a required positional argument), and there is no such thing on the esp8266. So if you call spi.init anywhere in your drivers, they won't be portable.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Porting drivers to ESP8266 port of MicroPython

Post by dhylands » Tue Aug 23, 2016 8:33 am

Ideally, the drivers shouldn't be calling SPI.init anyways. You should be passing in a SPI object. Similarly with I2C.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Porting drivers to ESP8266 port of MicroPython

Post by deshipu » Tue Aug 23, 2016 10:02 am

dhylands wrote:Ideally, the drivers shouldn't be calling SPI.init anyways. You should be passing in a SPI object. Similarly with I2C.
Then how do you make sure that you get the right baud rate, phase and polarity every time you try to send something? Remember, that you can have multiple devices on the same bus, with different cs pins, and each of them can change the parameters at any moment, so you have to call init before every operation to make sure it's correct.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Porting drivers to ESP8266 port of MicroPython

Post by dhylands » Tue Aug 23, 2016 4:23 pm

Yeah - I think that the SPI (and perhaps I2C) needs to be split into a bus and a device, where the bus represents the peripheral on the MCU and the device represents the device that you're communicating with.

The bus object would know whether its HW or SW, which peripheral number, and which pins for MOSI, MISO, SCK.
The device object should know the chip-select pin, baud rate, polarity, etc.

You would call send/recv methods on the device object which would then get the bus to reconfigure itself, if needed.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Porting drivers to ESP8266 port of MicroPython

Post by deshipu » Tue Aug 23, 2016 4:53 pm

Yeah, and on i2c, the device would also know its address.

Then the user would create the bus, and the driver would create the device.

Post Reply