Let's discuss something. I wonder if I'm the only one who ever wondered why there's no LED class in Hardware API?
And here's the question - do we want to deal with inverted signals? And using word "signal" actually suggests the right way to deal with it from OO perspective:
LED = machine.Signal(machine.Pin(A0), inverted=True)
+1 on adding an LED API.
So, question of supporting configurable inversion on the Pin level is very decisive actually - by answering that we'll know whether we want to support: 1) really lightweight and close to the actual hardware (as in: "least common denominator hardware") interface, or 2) more involved interface with more functionality (including "emulated" functionality) and internal state.
I'm the vocal proponent of approach #1. But the issue of inverted signals is important user-facing issue which needs to be addressed somehow, and then if it's decided that it needs to be addressed on Pin level, many of my arguments would lose their value.
I was involved in the lengthy discussion about the original machine API development. My recollection was that machine would provide low level support for the MCU hardware, but not for on board or off board peripherals. So -1 for adding LED API to machine. Where do you draw the line at adding peripheral drivers to machine? Every board will have different on board peripherals so every port will have a different machine API. I think it will be too hard define a standard peripheral API that won't be broken by the next more feature packed version of that peripheral. For example if LED class were copied from pyb how do we support a future board with RGB LEDs? There is no LED.colour defined.
@pfalcon I tend towards your approach #1 but I think it is a bit restrictive by not permitting "emulated functionality". That would preclude software emulation of I2C in ESP8266. May I suggest a slightly more liberal, but still low level definition.
machine API should include
1. support for MCU core functions such as Reset, Power Management.
2. support for all non peripheral specific on chip hardware, eg Timer, PWM, IRQ.
3. all generic busses, including pin.
4. When the MCU does not implement a common bus function in hardware it can be emulated, eg I2C, one-wire.
5. I think USB should be in machine.
6. I think SD card goes in periph. But should there be an underlying SDIO interface in machine? Many W-Fi chips use SDIO interface.
machine should not support any specific peripherals. These should be supported by libraries that use the cross platform compatible machine API.
1. no LED, SERVO, ACCEL, BUTTON, etc
2. no INVERT for pins. This is not a built in function of the MCU GPIO hardware and is only needed for certain peripherals, eg LED and can be implemented in the peripheral libraries that need it. Also using invert with pins leads to pin.value(0) setting the pin to a logic 1 which is confusing. Inverted pins should use assert and deassert.
3. even though some MCU's have built in busses for LCD, CAMERA , etc I don't think they should be in machine for two reasons (a) they are not on all MCU's and we don't want to emulate them, and (b) LCD and CAMERA interfaces are for specific peripherals, they are not generic.
4. One may argue that I2S is like LCD and CAMERA, ie a specific interface for an audio codec. However the interface is not audio specific and I use I2S with TI industrial ADC's to measure non audio things, so I think the basic functions of I2S, ie streaming data, should be in machine.
To satisfy existing users of pyb, and to provide an easy way to get started with on board peripherals I think there should be a periph API for things like LED SERVO, ACCEL.This keeps machine clean and allows pyb to be deprecated. The advantage of pyb is its device drivers don't need port assignments. LED(1) is the RED LED on all boards, irrespective of what GPIO is it connected to. The periph API should use the same syntax as an off board peripheral driver would, but without the need to specify hardware mapping.
Where should Neopixel go? Not in machine, its very specific to one type of LED and other LEDs will need modified support. In periph? Its not usually an on board device and needs hardware assignments. Maybe there should be a third (common devices) library?
It's not a priority now as it doesn't affect the existing functions in the hardware API, but it would be useful to read and write parallel data to LCD,s, FPGA registers, etc with the efficiency of byte or word transfers without having to write your own MCU specific driver, eg PA<7..0> connected to an external ADC, DAC or LCD. Due to MCU or pin usage limitations it's not always possible to memory map them with RDn, Rn and CSn bus controls. Writing data in parallel and just bit banging a strobe is much more efficient than bit banging the whole data port. Some devices, like parallel ADC's don't even need a strobe. You either just read whenever you want a value and get the last conversion, or you wait for an interrupt and just read the data.
I summary I am not proposing any changes to machine except to formally allow emulation of common interfaces if they are missing from the MCU hardware. At the same time I think if machine needs changing then now is the time to do it, before v2.0. It's more about what to do with all the higher level peripheral drivers that I think should be kept out of machine.
My personal preference is to include pin toggle and open drain for both coding and efficiency reasons. I won't vote on them. I'll leave the details of the API to the experts.
Regards, Chris