{"action":"created","issue":{"url":"https://api.github.com/repos/micropython/micropython/issues/1430","labels_url":"https://api.github.com/repos/micropython/micropython/issues/1430/labels{/name}","comments_url":"https://api.github.com/repos/micropython/micropython/issues/1430/comments","events_url":"https://api.github.com/repos/micropython/micropython/issues/1430/events","html_url":"https://github.com/micropython/micropython/issues/1430","id":101275735,"number":1430,"title":"New MicroPython hardware API","user":{"login":"danicampora","id":7749335,"avatar_url":"https://avatars.githubusercontent.com/u/7749335?v=3","gravatar_id":"","url":"https://api.github.com/users/danicampora","html_url":"https://github.com/danicampora","followers_url":"https://api.github.com/users/danicampora/followers","following_url":"https://api.github.com/users/danicampora/following{/other_user}","gists_url":"https://api.github.com/users/danicampora/gists{/gist_id}","starred_url":"https://api.github.com/users/danicampora/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danicampora/subscriptions","organizations_url":"https://api.github.com/users/danicampora/orgs","repos_url":"https://api.github.com/users/danicampora/repos","events_url":"https://api.github.com/users/danicampora/events{/privacy}","received_events_url":"https://api.github.com/users/danicampora/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":27,"created_at":"2015-08-16T15:42:22Z","updated_at":"2015-08-22T21:12:10Z","closed_at":null,"body":"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:\r\n\r\n- ~~Use attributes instead of functions when we simply need to get/set things. I am going to quote @dhylands on issue #378.~~\r\n\r\n> 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\r\n\r\n~~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.~~\r\n\r\nRuled out becaue attributes have a few drabacks which are a deal breaker.\r\n\r\n- The whole `Pin` API will look like this:\r\n\r\n```python\r\n# create & init a pin\r\n# id, mode are mandatory and positional (also can be named)\r\n# pull is optional and positional (also can be named)\r\n# rest of args are kwonly\r\n# only \"value\" is required for a port to implement (initial value if given)\r\n# rest are optional, and a port can define them and also define others\r\npin = Pin(id, mode, pull=Pin.PULL_NONE, *, value, drive, slew, ...)\r\n\r\n# constants\r\n# OPEN_DRAIN is much more descriptive than OD\r\nfor mode: Pin.IN, Pin.OUT, Pin.OPEN_DRAIN, Pin.ALT, Pin.ALT_OPEN_DRAIN\r\nfor pull: Pin.PULL_UP, Pin.PULL_DOWN, Pin.PULL_NONE\r\noptional pull: Pin.PULL_UP_STRONG, Pin.PULL_DOWN_WEAK, ...\r\nfor drive: Pin.LOW_POWER, Pin.MED_POWER, Pin.HIGH_POWER\r\nfor slew: Pin.FAST_RISE, Pin.SLOW_RISE\r\n\r\npin.init(...) # re init\r\n\r\npin.high() # set high\r\npin.low() # set low\r\n\r\npin.value() # get value\r\npin.value(x) # set value\r\n\r\n# toggle\r\npin.toggle()\r\n\r\n# functions to get/set most common settings\r\n# this duplicates a bit what init can already do, but it is useful in the case of pins\r\n# for instance when bit banging like it's done by the one-wire driver,\r\npin.id() # this one is only a getter\r\npin.mode()\r\npin.pull()\r\npin.drive()\r\n...\r\n```\r\n\r\n- In general then any extensions to a function/method can happen in 3 ways:\r\n    1. the port provides extra constants for an existing arg (eg Pin.PULL_UP_WEAK).\r\n    2. the port provides extra keyword args.\r\n    3. the port provides extra functions/methods.\r\n\r\n- A new module called `hardware` will be created to replace the `pyb` 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.\r\n\r\n- The new `hardware` module will contain `Pin`, `SPI`, `UART`, `I2C`, `Timer`, `CAN`,  and so on.\r\n\r\n- ~~The new hardware classes will use attributes where applicable.~~\r\n\r\n- A new module named `machine` will hold all functions related to reset, interrupt and sleep management.\r\n\r\n- The `UART` already supports the stream protocol and we would like to bring it to `SPI` and `I2C` 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 make `SPI` and `I2C` stream capable, then we have `read/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:\r\n\r\n    1. Simply add kwarg to read/write like `addr`, `memaddr`, `slave_addr`, etc. This will deviate from the standard stream API.\r\n\r\n    2. 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 the `memaddr` for I2C (not practical to have an endpoint for each memaddr).\r\n\r\nI prefer option 1...\r\n\r\n\r\nIt'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.\r\n\r\nThe idea is to have this new API implemented (for the WiPy at least) in 2 weeks...\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/micropython/micropython/issues/comments/133755176","html_url":"https://github.com/micropython/micropython/issues/1430#issuecomment-133755176","issue_url":"https://api.github.com/repos/micropython/micropython/issues/1430","id":133755176,"user":{"login":"dhylands","id":127500,"avatar_url":"https://avatars.githubusercontent.com/u/127500?v=3","gravatar_id":"","url":"https://api.github.com/users/dhylands","html_url":"https://github.com/dhylands","followers_url":"https://api.github.com/users/dhylands/followers","following_url":"https://api.github.com/users/dhylands/following{/other_user}","gists_url":"https://api.github.com/users/dhylands/gists{/gist_id}","starred_url":"https://api.github.com/users/dhylands/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dhylands/subscriptions","organizations_url":"https://api.github.com/users/dhylands/orgs","repos_url":"https://api.github.com/users/dhylands/repos","events_url":"https://api.github.com/users/dhylands/events{/privacy}","received_events_url":"https://api.github.com/users/dhylands/received_events","type":"User","site_admin":false},"created_at":"2015-08-22T21:12:10Z","updated_at":"2015-08-22T21:12:10Z","body":"I think that you could still iterate over them, just not by index. You'd instead do something like\r\n```\r\nfor uart in pyb.UART.all():\r\n```\r\nwhich would construct a tuple (or something) of all of the existing UARTs. If we made the UARTs go from 0-N then i think we'd need to add an address or something which corresponds to the peripheral ID (i.e. know that it's UART 6 on the pyboard)."}}