The switch to common I2C and common definitions for SPI had broken an edge case in Pico Explorer where no backlight pin is used.
The backlight pin was inadvertently set to the front Breakout Garden SPI slot default, which is pin 20- this also happens to be the I2C SDA pin for Pico Explorer, breaking I2C comms.
This fix adds a new special case board "PICO_EXPLORER_ONBOARD" so that ST7789 can be initialised without the backlight pin.
This will be useful for anyone using ST7789 without the rest of the Pico Explorer library, although it feels a little contrived.
Also switches ST7735 over to the common defines.
Rewrites the cursed Pico RGB Keypad code so that it can't hurt anyone else.
Turns out the whole loop could have been a bitwise operator.
The true lesson was the people we met along the way.
This change is specifically intended to avoid a pitfall in MicroPython and will likely have no effect in C++.
When using the REPL in MicroPython it's possible to set up an I2C instance on two pins - ie: 20, 21 - and then subsequently realise these are the wrong pins for your board.
Before this change, these pins would be left hanging even if you created a new I2C instance with new pins - ie: 4, 5 - this would lead to communications failures where they really shouldn't happen. Confusing!
This change appends the list dir and project root dir to CMAKE_MODULE_PATH so that it doesn't need prepended to each "include" directive.
All .mk files have been deleted, since these are completely redundant.
This new workflow will build a separate release of MicroPython that includes Blinka and PlatformDetect for compatibility with Adafruit CircuitPython .py libraries.
This is the final piece of the puzzle.
Prior to this rather considerable change, Pimoroni breakouts were not de-init'ing I2C when they failed to init()
This change adds a __del__ method which cleans up the I2C instance attached to a MicroPython object.
Under the hood this calls i2c_deinit() and resets the associated pins to their default state.
This means that I2C is now cleaned up during a *soft* reset, so running a script with the wrong pins, seeing an error,
changing the pins and running it again will not result in subsequent I2C errors. Previously a hard reset was required.
To recreate on Breakout Garden run the following code:
```
from breakout_potentiometer import BreakoutPotentiometer
from pimoroni_i2c import PimoroniI2C
i2c = PimoroniI2C()
pot = BreakoutPotentiometer(i2c)
```
This will fail correctly with "Potentiometer breakout not found when initialising."
(The default pins are configured for Pico Explorer)
Now change that to the following and run again without hard-resetting:
```
from breakout_potentiometer import BreakoutPotentiometer
from pimoroni_i2c import PimoroniI2C
i2c = PimoroniI2C(4, 5)
pot = BreakoutPotentiometer(i2c)
```
This should now work, since the failed I2C instance was cleaned up.
Without this change, the second attempt would result in an inexplicable failure.
Since most? (many?) Pico users do not have a reset button, this trap requiring a hard-reset is pretty nasty and would likely have resulted in a support nightmare.
Whew.
Removes i2c_inst_t from constructors since it's ignored, and updated the Python bindings not to supply this argument. Instance is inferred from the supplied pins.
Removes all driver-specific SDA/SCL pin definitions and defaults.
Pin type is "uint" everywhere, but "PIN_UNUSED" is *int*_max for MicroPython compat. That's still a lot of pins!
Adds baudrate to the I2C class, and allows a driver (like Trackball) to check the baudrate is supported
This change adds a common I2C class, gathering various I2C functions into a single point of responsibility.
It's necessary for correctly managing the I2C bus pins and state across multiple devices.
* Add a common/pimoroni.hpp to list default pins for various add-ons
* Move the BG SPI Slot enum here for safe keeping
* Switch all GPIO pin references to "uint" to match Pico SDK and bring back PIN_UNUSED as UINT_MAX
Confused myself by plugging this into a BG base. It gave all the appearance of working, but the time was not counting up.
Turns out the library will happily talk to no device whatsoever and when you "set_time" it's stored in an C array and returned as if it came from the RTC.