TL;DR micropython go brrr
I got the email notifying me of the PicoCalc’s existence on March 12. There was a brief period where I waffled, but I’d ordered one by the end of the day. It arrived on March 31.
What I’d envisioned from the marketing material was essentially a gameboy with a keyboard running a micropython repl. After fiddling with the stock picomite for a bit, and reading about other folks efforts to port micropython and circuitpython, I figured it was time to take a stab at getting some python running. At this point I’d been working with python since the pandemic started, and micropython on pico w for 3ish years.
The first attempt was based on a post here announcing the user had successfully ported micropython to an esp32 on the picocalc. I was able to remap the pin assignments to the pico w and load micropython, but it was pretty janky. Most of the keyboard worked, so I could type and hit enter, but the arrow keys were inoperative so I couldn’t move the cursor left/right along the line I was typing and I couldn’t scroll through command history via up/down in the repl. The CTRL key also didn’t seem to do anything, so the repl’s functionality was pretty severely limited. There was also an issue where if a line wrapped in the console, it would lose a character where it split the line. This was worked out by futzing with some parameters in the driver that had to do with calculating the number of characters that would fit in the console width. I did figure out changing the colours, and changing the font, but I wasn’t really getting anywhere on the keyboard. Later on I circled back to investigate a little more, and found that keypresses were all being recognized, with the appropriate keycodes being transmitted, but for reasons I didn’t determine many keys did not evoke any kind of response from the repl.
This is where I started with micropython:
https://github.com/jd3096-mpy/PICOCALC-micropython
Next I attempted to run circuitpython. I’ve tinkered with circuitpython a little in the past, but everything I’ve actually succeded in making work has been in micropython. Circuitpython has a thing in I think displayio
called CIRCUITPYTHONTERMINAL
or something to that effect, and it seemed like it should simplify the process for me. Based on another user’s work adapting an ST7789 driver to work with the PicoCalc display (I want to say ILI9488?) in circuitpython, I was soon able to display a repl. At this point the repl presented with black text on a white background, and I set about trying to adjust the colours. Eventually I constructed and applied a ‘palette’, but found the colours displayed were completely different from what had been set, though all of the elements had changed colour. Continuing to hack on the colour setup, I found that the displayed console had 3 distinct ‘TileGrid’ elements, and after some dicking around I got the background to be black and the text to be green. This exercise made it clear that all displayed colours were being inverted. I managed to get the elements’ colours reverted, but there is a small amount of padding between the console and the elements along the top of the screen that remained white. I tried briefly to place a black TileGrid in a layer under the others, but abandoned that in favour of trying to correct the issue in the display driver. Earlier on I’d found a datasheet for this model of display and thought I’d seen something about setting invert mode while skimming through. Prior to this I had zero experience talking to devices of this sort, so it took a bit to figure out how to use the information from the datasheet. I’d eventually hypothesized there must be an invert command somewhere in the init sequence, but didn’t find one, or anything else that seemed related. Through a little trial and error I got the invert mode on command (21h) working in the init sequence. Clearly for whatever reason this display using this driver had its colours inverted when invert mode was set to off. The display had been a journey, but it was sorted and I figured I was nearly done. By now I should probably recognize that as an indication I’m nowhere close. I spent many hours trying to get any response from the keyboard mcu via i2c, and just could not get it to respond. This might have had something to do with being connected to the microusb on the pico, but I couldn’t get the usbc port to work. According to tio I was connected, but there was no repl and no response to any keys. On the microusb port I could connect and see the same repl on picocalc as in my terminal, which worked fine, with the glaring exception of the picocalc keyboard still did nothing and I couldn’t get a rise out of the controller. This is about where I’ve typically arrived with circuitpython, it seems slick and like it’s going to make my life easier, but it gets me like 80-90% of the way before I find myself at an impasse and go back to micropython.
This was the basis of my circuitpython attempt:
https://forum.clockworkpi.com/t/circuitpython-with-pico-2-w/16394
After letting the picocalc languish for a spell, I happened to see a mention of another project based on micropython that seemed complete, and targeted the pico. Of course it had been built and tested on the pico, pico2, and pico2w, and all my picos are picow. I’m not tremendously familiar with building firmware or working with c, but I’d previously worked out building micropython with the repl on uart0 (so I could connect over the usbc port). Unfortunately my initial attempts to follow the instructions precisely did not yield the result the author described, something was missing. Searching around I encountered an individual who had taken the build steps and worked them into a script. Now, I am uncertain if they had tested their script, or if there is something different about my environment, but still no joy. The script clearly assumed by the final steps that a firmware file would have been generated, but I am at a loss as to how that would have come to be. I added a step in the script to issue make
in the appropriate directory after the other build steps were complete, and before trying to copy the nonexistant firmware image. Additionally I incorporated a script to find the line relevant to making uart0 available and change the value from 0 to 1. Finally, it worked.
This is what I based my picow firmware on:
https://github.com/zenodante/PicoCalc-micropython-driver
And this is the script:
https://github.com/seanbutler/PCMP-SCRIPT/blob/main/scripts/runme.sh
At this time I have micropython running on a picow in my PicoCalc. The keyboard and display are fully functional, I can access the repl via usbc, and the repl takes inputs as expected. Wifi was connected without issue, but I have not tested the webrepl. I’m planning to see if I can work out sending and receiving scripts via tftp, but for now I’m mostly playing with the exposed gpio. The last couple weeks have sucked for other reasons, and having the PicoCalc without being able to make use of it was really bumming me out. But now it works as I had hoped, and I am loving it. In retrospect, without all the time I invested in micropython and circuitpython on the picow the last few years, and a collection of other bits and pieces I picked up working other projects, this process would have been substantially longer. There are a number of points where I’m pretty sure I’d have hit a wall without a path forward.
I’ll find links to the projects I mentioned and edit them in (EDIT: done), hopefully my experience will be of use to someone. Please understand, if my account seems critical of any of the projects I cribbed from, that is not my intent. Thank you to everyone working on this, I could not have done it without your work to build on.