CircuitPython with Pico 2 W

I’m interested in getting CircuitPython working on the PicoCalc, but I’m struggling to bring up the display. Inspired by @jd3096’s post I’ve pieced together some CircuitPython code, adapted from a ST7789 demo from Adafruit (which I got working on a Pico 2 W w/ Pimoroni Display Pack 2.8).

The code runs without error but I’m not able to get any output on the screen. I’m sure that the pin configuration is correct for the Pico 2 W:

  • CS = GP13
  • DC = GP14
  • RST = GP15
  • SPI MOSI = GP11
  • SPI CLK = GP10

The Pico 2 W shares the same pinout as the original Raspberry Pi Pico, and the above matches what’s in the Fuzix, PicoMite and uLisp examples in the PicoCalc GitHub repo. The display (ILI9488) init code matches jd3096’s init code from their MicroPython example.

Does anyone with any more experience with CircuitPython and SPI displays have any suggestions? Am I missing something obvious?

I appreciate the work done to get MicroPython working on the PicoCalc, but CircuitPython is a really appealing fork - it’s easier to upload code (CircuitPython shows up as a USB Mass Storage device where you can simply copy .py/.mpy files), there’s a great ecosystem of third party code, and the standard library is brilliant (for example, the display library supports rendering a CircuitPython REPL to the display without any extra work)

1 Like

I’ve managed to make it work now, using the CircuitPython_ILI9488 driver.

I’ve uploaded some demo code here, with the relevant pin and SPI setup, etc.

You’ll need to copy the following to your lib folder:

By virtue of CircuitPython magic, this automatically displays the REPL on the screen when you CTRL-C from the serial terminal.

I’ll look at trying to get the keyboard working with CircuitPython next. A handheld CircuitPython REPL device would be pretty cool.

3 Likes

Testing the I2C keyboard with CircuitPython is more difficult. I think I’m suffering from the same issue I had with PicoMite on the Pico 2 W - the USB C port never comes up, but when I connect back to my computer using Micro USB (to use the REPL/serial console), the I2C keyboard can’t be detected (i2c probe() returns no devices).

From the schematic, it looks like I2C1 (GP6/7) on the Pico connects to M_I2C1 (PB8/9) on another microcontroller labelled CKS32F103Rx on the schematic PDF. I can’t find out much about this, but it seems to be the STM32 “south bridge” MCU mentioned in the marketing page for the PicoCalc (which says it controls keyboard I2C, screen and keyboard backlight, power, etc).

The schematic also seems to indicate that the TYPEC-31-M-12 component (USB C interface) is connected to both the STM32 MCU and the Pico MCU (via a series of switches - WAS7227 to CH340C to WAS7227).

UART0 (GP0/1) on the Pico seems to connect ultimately to the USB C port via those same switches. The PicoMite patch in the ClockworkPi repo appears to configure GP0/1 as a PicoMite serial terminal. Getting a CircuitPython REPL on the USB C port looks difficult - MicroPython has a function (os.dupterm()) which duplicates the REPL on a given UART, but CircuitPython doesn’t have this for all boards (it is supported on specific boards by C extension baked into CircuitPython for those boards).

I’m loving the concept of the PicoCalc, and appreciate that it’s “open design”, but official documentation is frustratingly light (e.g. GitHub repo has an empty “PCB” folder and I can’t find detailed information about how the STM32 arbitrates or brings up USB C comms). The marketing page says …

the 3D files of all structures and related materials are released under the GPL v3 license.

… but I can’t find these anywhere (perhaps I’m looking in the wrong place).

The page also mentions that Python, Lua, Rust, GoLang, JavaScript have all been “tested with PicoCalc” but there’s virtually no documentation about getting any of these working, no drivers, and no SDKs/board support. Strategies for getting those things working with the PicoCalc might be obvious to experienced firmware engineers, but I really expected working examples in those languages for all of the PicoCalc hardware (screen, SD card, keyboard, audio, etc) since they were mentioned on the splash page for the product.

Pinging @guu since he maintains the Clockwork github and will likely be the person to share the files and information you’re requesting.

Traditionally with Clockwork releases the hardware ships and then weeks or months later, this sort of information gets posted, perhaps with requests from community members. Sometimes the community works out the details themselves or reverse engineers things. I’m guessing some of the things in the marketing may not have been tested, and are more like theoretically possible things that someone may have gotten working on Pico hardware outside of anything to do with the PicoCalc. Usually the software.and documentation that ships with these devices (Gameshell, Devterm, uConsole, and now PicoCalc) is minimal and incomplete (and sometimes incorrect) on launch, but over the course of months or years it gets figured out. It’s a frustrating part of the process, but Clockwork makes cool hardware and often community members take things on as personal projects to try to work things out. What you get when you buy one is hardware with a lot of potential and software that is minimal and mostly just proves the hardware can work. Then the community usually builds more functional software (and up to date software), be it the customized DEOT for the Gameshell, or the many custom OS builds for the Devterm and uConsole (which is the only way to get a current kernel, etc.)

CircuitPython sounds cool, and likely a better long term choice than MicroPython! Thanks for putting in the effort to try to get it up and running.

1 Like

yes ,that’s true, I2C keyboard only works when the PicoCalc powered on from Type C cable,not the mico usb

CKS32F103Rx is just as same as STM32F103Rx

Thanks - that’s a really useful perspective to understand, if a little disappointing. The marketing definitely seems a bit misleading in that regard - “tested” is doing a lot of heavy lifting there. I had expected out of the box support for those languages.

It seems like CircuitPython board support is pretty standard these days for MCU devices claiming Python support. The M5Stack Cardputer is a great example. See The GitHub repo (particularly board.c and automatic setup of board.DISPLAY and the keyboard) for what I had really hoped for.

In the absence of detailed information (like the STM32 bring up process or how it manages USB C (which seems inoperable on the Pico 2 W) it’s difficult to start to reverse engineer how it works (which I didn’t really expect to have to do for an open design device), especially for someone with less MCU development experience.

It might be helpful if the landing page clarifies that support for the languages listed is actually envisioned for the future, based on community effort, but isn’t ready yet. Likewise with the part that states “the 3D files of all structures and related materials are released under the GPL v3 license. You can find them on our online shop and GitHub to customize your own parts through CNC or 3D printing technology.” (I can’t find them anywhere).

I’ve got hopes that the community will get the PicoCalc over the line in terms of parity with other devices’ support for CircuitPython and TinyGo, and I really do appreciate your perspective on the development process for ClockworkPi devices.

1 Like

Thanks, that’s useful to know.

Can you clarify if it’s safe to connect both Micro USB and USB C at the same time? And is it safe to do this in devices with 18650 batteries installed? Is there any risk of supplying too much power to the batteries or charging circuit?

I ask because I need to use Micro USB to get a serial console on CircuitPython, but can’t test code for keyboard support without USB C connected (and presumably powering the STM32?).

Do you have any pointers about getting USB Mass Storage also working over USB C when using CircuitPython (or MicroPython), or is this something that’s handled by the PicoMite firmware in some way with stock the Pico 1 board?

yeah .of cause ,for every electronic device,supplying too much power will have risks

for now I tested with my 18650 bats and my usb type c cable and my micro-usb cable at the same time, picocalc works

but I won’t recommend you to do like this for every time

I am not familiar with CircuitPython, but accord to my knowledge, the USB C is the default serial port of PICO, so you might not able to get serial output from Micro-USB cable.

I have very little experience in CircuitPython or MicroPython, So no pointers or tips ,sorry for that.

1 Like

From what I’ve seen in the schematics, USB-C is the alternate serial port of the pico. Micro-USB should be the default/console port. The supplied picomite is configured to use the alternate port.

1 Like

Yeah, Clockwork devices have always been a mixed bag. The hardware is well thought out and excellent. (The Devterm and uConsole suffer from one hardware design issue though, that isn’t a problem so much as a “ahead-of-their-time” sort of thing. Since they were designed to support the CM3 and maintain backwards compatibility with it, compromises were made to keep that and the CM4 and CM5 on those devices have some oddities as a result.) Design and unboxing experience are also excellent. And based on my own experience of dealing with a support issue once, and many posts by others on the forum, Alex’s customer service is amazing and given reasonable proof Clockwork always seems to send replacement parts when there are manufacturing defects (my backplate on the uConsole was milled incorrectly), or other hardware issues like a broken screen, etc.

The downsides are, the website looks very professional but always seems to promise things that aren’t true. The big one, that I’m sure has driven plenty of customers away, is the shipping time for most of the devices before the PicoCalc. Granted, COVID delays were a part of that. But I’m not sure there has ever been a consisten time when the devices shipped in “90 days”, and while the website says “90 business days”, I think a lot of people misread that and don’t understand what it means. Realistically, “90 business days” in China seems to be anywhere from 4-6 months. And I’d hazard to guess that probably 75% of the Devterm and uConsole (especially) orders probably weren’t shipped in under 6 months for anyone outside of mainland China. I’ve seen comments and reviewers online who suppose it’s all a scam, but while no one but Clockwork knows what causes the delays, they do eventually ship the devices and make good on them. But they are definitely not a product for anyone on a tight time schedule who can’t wait 6 months or more, or who refuses to pay and not receive anything for that long. It’s unfortunate, unusual, and certainly raises lots of red flags, but they’ve got a consistently good reputation for the devices, even though they have a consistently bad reputation for shipping times and marketing promises. I’ve also noticed that nothing they claim seems to be an outright lie – but it implies thigns are may not be true. Like supported/tested stuff for the PicoCalc… Those things probably will work eventually, but even if someone at Clockwork actually tested them and got them working, it’s unlikely any of that will ever be shared. Or, based on past devices, it might be shared well after the community has gotten it working.

Documentation, board layouts, and 3D models are another thing that eventually gets shared, but usually after lots of asking, begging, whining, and even sometimes threats from the community (since they are often violating licensing agreements by not sharing that info.) I don’t remember exactly how long it took, but I think it was at least a year before all that info got posted for the uConsole, and I know it took a while for the Devterm too. I remember people were already reverse engineering stuff and building add-on modules for the Devterm without it, and even doing multiple hardware revisions for their add-ons because they couldn’t be sure how things actually worked.

A long time ago, when the Gameshell was new, and Clockwork had more employees (or at least people associated with the company) posting on the forums here, they posted some philosophical information which was interesting and also accurate based on how all their devices have been released. They made it very clear that the Gameshell (and presumably future devices) were meant to be hobby projects for tinkerers. It wasn’t meant to be as much as plug-and-play device as a device to dig into, get your hands dirty, customize, and use as a platform to build the device of your dreams. While it would work out of the box, what it offered was more like a model kit, where the user could focus more on software than having to worry about how to customize or fix the hardware (though hardware mods were encouraged too). Weirdly, their marketing doesn’t seem to reflect that philosophy though, as it seems to imply that these are fully functional devices that support all the stuff advertised, rather than being platforms that have the potential to support those things, and more.

So far, the communities for all these devices have done some really incredible things with them. And that’s probably why Clockwork continues to have a following, at least among those who like to tinker, learn, and enjoy customizing a device as much as (or maybe more than!) actually using the device. In a way, these devices are similar to the Flipper Zero – it was deisgned as sold more as a platform, and the people who actually get use out of it are the folks who tinker. Sure, there are kids with Flipper Zeros who “pwn” iPhones around them with spam, and other such nonsense, and there are folks who use the uConsole only to run RetroPie. But I think the real power lies in tinkering, either to build something you want, need, or are interested in, or even just to learn about stuff by doing, even if that just results in lots of projects along the way and a device that is a neverending unfinished project. There are different kinds of fun, and these devices seem to encourage and support fun by doing.

Doesn’t make the ordering/shipping process any less frustrating though. And it requires tempering your own internalizaiton of the hype when a new device is announced. I find thinking about them as platforms for potential projects is a better way to consider them, than as “finished products”. Though to be fair, I think PicoCalc is probably closer to a finished product than anything since the Gameshell. It could be used out of the box to do PicoMite/MMBasic stuff, MicroPython, and Lisp, even if the versions on the SD might be out of date or not support all the features of those things. :wink:

2 Likes

You may want to consider this thread:

It seems no one knows for sure (yet), what these dip switches are for. While it definitely seems like at least one of them has to do with how the device boots (based on labelling), it’s possible one of them selects which USB port will be used for serial output. If it does affect the USB port, then it might be just what you need to get CircuitPython working with the keyboard.

I’m not a hardware person though, so I have no idea what will happen if these switches are changed. And it’s always possible that it could damage something. Hopefully someone who understands hardware better can trace things and decide what, if anything, these might do, and also if it’s safe to change them.

1 Like

the DIP on the back of PicoCalc is the traditional pretty much like in uConsole and DevTerm, also use stm32 for the keyboard

1 ON = for flashing the stm32 keyboard, like to use STM32CubeProgrammer,stm32flash
2 ON = stm32 usb dp/dm

5 Likes

Thanks for clarifying. I only get serial output from Micro USB. As @pkr says - PicoMite seems to specifically configure the Pico pins (GP0/1) connected to the STM32 and then on to USB C as a serial console. CircuitPython doesn’t have that functionality (to replicate the REPL on a separate UART, the way MicroPython does with os.dupterm()).

The reason I ask about supplying too much current to the battery is that it isn’t clearly documented anywhere that attaching power to both USB C and the Pico’s Micro USB would result in power from both potentially being supplied to the charging circuit. I think that’s probably, from a safety perspective, something worth highlighting in the docs (telling people not to connect both USB ports at once, or you risk a dangerous configuration).

I’m not sure if you work for ClockworkPi or are just a very helpful volunteer, but as the device is advertised to support Python it would be helpful if the company published whatever was used in the Python testing advertised on the product page.

Thanks, yeah - mixed bag is definitely my experience so far. Hardware - gorgeous and well design. Software and design docs… well, a little underbaked.

I had read about the shipping woes for other products, so when the PicoCalc appeared and I read that it supported Python and Go (presumably MicroPython/CircuitPython and TinyGo, respectively) and the Pico 2 W, I jumped on it and ordered straight way and was happy to take the risk of a slow delivery. The landing page absolutely makes it look like those things are supported on day one. I’d have felt better informed if the marketing said that those things would be coming at a later date after some community effort.

I get what you mean about it being aimed at tinkerers with some filling in of the blanks to be expected. To be honest, that’s what I wanted. But the lack of detailed information makes it difficult to “draw the rest of the owl” so to speak. Their open design approach feels less like Pimoroni, Adafruit and M5Stack and more like “I found this funky, well built device made with commodity and programmable components; nothing is secret but at the same time very little about the design and configuration is actually documented and you need to know the right questions to ask to get what you want” (a bit like a lot of the legacy systems I’ve inherited at work :slightly_smiling_face:).

Funny you should mention the Flipper Zero - I did back that one on Kickstarter, and was pleased with the result even after waiting the better part of a year for delivery. There wasn’t anything in the product description that I felt that they underdelivered on.

I’m sure there will be enough interest to get it over the line, but I just want my damned handheld Python REPL machine (with working USB C and other component) without having to reverse engineer the hardware :laughing:

2 Likes

I spent some time attempting to get circuitpython working on PicoCalc, no pico 2 though, working on pico w. Bringing up the repl on the display wasn’t too bad, had to set display to inverted during init to display colours as expected (invert command is x21). Also found the bagaloozy driver uses displayio.Display and displayio.FourWire, which have been moved to busdisplay.BusDisplay and fourwire.FourWire respectively (displayio module still works in 9.x, planned deprecation in 10.x). Unfortunately no luck with the keyboard though. Everything I’ve tried, i2c.scan comes up empty. I was able to connect to a repl over usbc, but keystrokes weren’t making it to the console. Tried the circuitpython web workflow which allowed me to interact with the repl without microusb connection, but still nothing on i2c.scan. Local web console in circuitpython sucked to work in compared to micropython webrepl. At this point I’m not really sure where to go with circuitpython on picocalc/pi pico, when i have a little time I’ll see if I can get any further with micropython. Curious if you’ve had any further luck with circuitpython on the pico2?

Nice work getting the display working! (Might be good to share what you did, though with the keyboard lacking it still may not be very useful.) I didn’t know much about MicroPython or CircuitPython before I started messing with the PicoCalc, but after some research I’m leaning more toward MicroPython myself, since it seems to have better support for bluetooth than CircuitPython currently has. (That’s just a thing for my personal projects though.)

I haven’t yet got MicroPython working on the Waveshare ESP32-S3 Pico (someone else with more knowledge sounded like they were likely to get it going on another forum thread), but I played with it on another (non-PicoCalc) ESP32-S3 device and was pretty impressed with it. The web interface does have a hiccup every now and then, but for the most part it works really well, even in terms of updating and editing files in flash. Definitely seems like a much better workflow than what I had been previously used to – building and flashing a new firmware with every change of C++ code with Arduino. I might end up embracing Python more after all. :wink:

Seems like one or both flavors of it could be a really nice thing to have on the PicoCalc.

I keep coming back to circuitpython thinking some feature or convenience will be an improvement over micropython, and finding while some particular thing is easier something else gets harder or I hit a wall doing something I can already do in micropython. The web workflow tools in circuitpython are functional, but the serial console (the local version, not their hosted web tools) sucks. Its a text box and a printout from the console, so you can issue a command but it gets janky fast. Whereas in the micropython webrepl, you are provided with a functional console.

My read on circuitpython so far is that a lot of the benefit is around helper functions for Adafruit hardware and integration with GUI tools, neither of which are generally helpful to me. That said, Adafruit probably has a board that’s pin-compatible with the pi pico, and that might be a better experience for working with circuitpython.

# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries
#
# SPDX-License-Identifier: MIT

"""
`bagaloozy_ili9488`
====================================================

Display driver for ILI9488

* Author(s): Mark Winney

Implementation Notes
--------------------

**Hardware:**

* Buy Display LCD 3.5" 320x480 TFT Display Module,OPTL Touch Screen w/Breakout Board
  <https://www.buydisplay.com/lcd-3-5-inch-320x480-tft-display-module-optl-touch-screen-w-breakout-board>

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases

"""
try:
    # used for typing only
    from typing import Any
except ImportError:
    pass

#import displayio
import busdisplay

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ILI9488.git"

_INIT_SEQUENCE = (
    b"\xE0\x0F\x00\x03\x09\x08\x16\x0A\x3F\x78\x4C\x09\x0A\x08\x16\x1A\x0F"
    b"\xE1\x0F\x00\x16\x19\x03\x0F\x05\x32\x45\x46\x04\x0E\x0D\x35\x37\x0F"
    b"\xC0\x02\x17\x15"  # Power Control 1 Vreg1out Verg2out 
    b"\xC1\x01\x41"  # Power Control 2 VGH,VGL
    b"\xC5\x03\x00\x12\x80"  # Power Control 3 Vcom 
    b"\x36\x01\x48"  # Memory Access 
    b"\x3A\x01\x55"  # Interface Pixel Format 16 bit    
    b"\xB0\x01\x00"  # Interface Mode Control
    b"\xB1\x01\xA0"  # Frame rate 60Hz 
    b"\xB4\x01\x02"  # Display Inversion Control 2-dot 
    b"\xB6\x00"      # Display Function Control  RGB/MCU Interface Control 
    b"\x02\x01\x02"  # MCU Source,Gate scan direction 
    b"\xE9\x01\x00"  # Set Image Function Disable 24 bit data
    b"\xF7\x04\xA9\x51\x2C\x82"  # Adjust Control D7 stream, loose 
    b"\x11\x80\x78"  # Sleep out delay 120ms
    b"\x29\x00"      # Power on display
    b"\x21"          # Set display colour to inverted
)

# pylint: disable=too-few-public-methods
class ILI9488(busdisplay.BusDisplay):
    """
    ILI9488 display driver

    :param fourwire.FourWire bus: bus that the display is connected to
    """

    def __init__(self, bus: fourwire.FourWire, **kwargs: Any):
        super().__init__(bus, _INIT_SEQUENCE, **kwargs)


That is the modified ILI9488 driver. This is my code.py:

import board
import busio
import displayio
import terminalio
from fourwire import FourWire

from bagaloozy_ili9488 import ILI9488

# Release any resources currently in use for the displays
displayio.release_displays()

WIDTH = 320
HEIGHT = 320

tft_cs = board.GP13
tft_dc = board.GP14
tft_reset = board.GP15
spi_mosi = board.GP11
spi_clk = board.GP10
spi = busio.SPI(spi_clk, spi_mosi)

display_bus = FourWire(spi, command=tft_dc, chip_select=tft_cs, reset=tft_reset, baudrate=25000000)

display = ILI9488(
    display_bus,
    rotation=720,
    width=WIDTH,
    height=HEIGHT,
)

repl = displayio.CIRCUITPYTHON_TERMINAL
display.root_group = repl
palette = displayio.Palette(2)
palette[0] = 0x000000 # black background
palette[1] = 0x00ff00 # green text

repl[0].pixel_shader = palette
repl[2].pixel_shader = palette

The repl object here has 3 indices, I forget now but I think 0 was the TileGrid containing the repl and 2 was the top bar (ip, version, etc.). Might have those switched, but index 1 is a circuitpython logo sprite in the top left corner.

1 Like

I finally got MicroPython working on the Waveshare ESP32-S3-Pico. Not sure what I was doing wrong before, but it ended up working with the same firmware as the WalnutPi and pinout changes int he python files.

I haven’t tried this one for the Pico2 W (I kinda want to keep it set up with PicoMite for now), but I put together an archive here:

Setup would be the same as in the WalnutPi thread. Flash the firmware, then transfer the python files with Thonny. If you try it, let me know if it works.

I had issues using webrepl on the Waveshare module though, and I expect the same is true on the Pico2 and the Walnut Pi. Since the repl is running on the device itself, when I try to connect either through Thonny, or via a web browser, it disconnects me and puts an error on the PicoCalc screen. Weirdly, a serial connection with Thonny does work, but it puts a bunch of text on the screen (kinda looks like Thonny’s communication going to the device?), and then the PicoCalc keybaord stops working and the only way to do anything is through Thonny until a reboot. So at present, MicroPython seems to only work on the PicoCalc itself, with the built in keyboard and screen, or sort of remotely over serial if you don’t mind losing the ability to use the keyboard until a reset.