Description
Edit: for easy reference, the proposed new API is at https://github.com/micropython/micropython/wiki/Hardware-API
Since we have the WiPy TODO list (#1425) Damien and I spent some time today discussing how to do things properly, once and for all, and do it before the WiPy ships. It involves a redefinition of the API in many aspects and it has implications all over the place. I'll do my best to layout all the points we touched:
Use attributes instead of functions when we simply need to get/set things. I am going to quote @dhylands on issue Functions vs attributes in object API #378.
I think that to use attributes then you need to use nouns. If you can't represent it as a noun, then I think it should stay as a function
So for instance, pin.value()
will change to pin.value
to get it and pin.value = x
to set it. This will be the way to go in other peripherals, e.g. timer.frequency, timer.period, etc.
Ruled out becaue attributes have a few drabacks which are a deal breaker.
- The whole
Pin
API will look like this:
# create & init a pin
# id, mode are mandatory and positional (also can be named)
# pull is optional and positional (also can be named)
# rest of args are kwonly
# only "value" is required for a port to implement (initial value if given)
# rest are optional, and a port can define them and also define others
pin = Pin(id, mode, pull=Pin.PULL_NONE, *, value, drive, slew, ...)
# constants
# OPEN_DRAIN is much more descriptive than OD
for mode: Pin.IN, Pin.OUT, Pin.OPEN_DRAIN, Pin.ALT, Pin.ALT_OPEN_DRAIN
for pull: Pin.PULL_UP, Pin.PULL_DOWN, Pin.PULL_NONE
optional pull: Pin.PULL_UP_STRONG, Pin.PULL_DOWN_WEAK, ...
for drive: Pin.LOW_POWER, Pin.MED_POWER, Pin.HIGH_POWER
for slew: Pin.FAST_RISE, Pin.SLOW_RISE
pin.init(...) # re init
pin.high() # set high
pin.low() # set low
pin.value() # get value
pin.value(x) # set value
# toggle
pin.toggle()
# functions to get/set most common settings
# this duplicates a bit what init can already do, but it is useful in the case of pins
# for instance when bit banging like it's done by the one-wire driver,
pin.id() # this one is only a getter
pin.mode()
pin.pull()
pin.drive()
...
- In general then any extensions to a function/method can happen in 3 ways:
- the port provides extra constants for an existing arg (eg Pin.PULL_UP_WEAK).
- the port provides extra keyword args.
- the port provides extra functions/methods.
- A new module called
hardware
will be created to replace thepyb
module.pyb
will still exist in the pyboard in order to provide backwards compatibility and to avoid confusions between the old and the new API. - The new
hardware
module will containPin
,SPI
,UART
,I2C
,Timer
,CAN
, and so on. The new hardware classes will use attributes where applicable.- A new module named
machine
will hold all functions related to reset, interrupt and sleep management. - The
UART
already supports the stream protocol and we would like to bring it toSPI
andI2C
as well. Right now we have the recv functions that accepts either an integer or a buffer object, which is kind of weird and can get confusing. If we makeSPI
andI2C
stream capable, then we haveread/readinto/readchar
,write/writechar
. This will make the API across communication peripherals consistent and homogeneous. One problem of the stream approach is how to select the slave (for SPI) or the destination address (for I2C). We had two ideas:- Simply add kwarg to read/write like
addr
,memaddr
,slave_addr
, etc. This will deviate from the standard stream API. - Create and
endpoint
subclass which is the one actually providing the read/write methods and holds the information relevant to the destination like chip select, i2c address, addres size, etc. Doesn't solve the issue of having to add kwarg to the read/write methods in the case of thememaddr
for I2C (not practical to have an endpoint for each memaddr).
- Simply add kwarg to read/write like
I prefer option 1...
It's a lot to discuss in one ticket, but we think it's better because all things are related and it shows the complete picture.
The idea is to have this new API implemented (for the WiPy at least) in 2 weeks...