2

PotatoP | Hackaday.io

 1 year ago
source link: https://hackaday.io/project/184340-potatop
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Project Logs Collapse

  • Snake!

    Andreas Eriksen • 02/10/2023 at 23:20 • 0 comments

    Thankfully, I quickly found a workaround for the (second) SPI bug I complained about last time, so now I have a working setup with both a display and SD card!

    That means I can now _really_ write code on the laptop it self - being able to save to the SD card is very useful - and I managed to hack up a passable version of Snake pretty quickly. No (other) computer involved, programmed exclusively on the PotatoP, using the built-in documentation in the latest version of uLisp for reference! I even hooked up a little speaker to some GPIO pins to make some clicks and bleeps for the game.

    The size of the screen is surprisingly OK, the text is very clearly readable at the default 5x7 font size as long as there is decent light. And 53 characters is wide enough that it seems I can get used to it - I should refactor my code into smaller units anyway :-). The editor is still a bit slow when editing more than a screenful of text, but moving to a better data structure than "just a big string" is likely to help.

    I also splurged on a few more items; most importantly a Nordic Semiconductor Power Profiler Kit II. I've also received another solar controller board by Jasper Sikken, this one using supercapacitors instead of a battery for energy storage. I really want to see if I can make this work well enough instead of a battery, as it has a lot of advantages - such as no toxic materials or worries about degrading battery chemistry.

    Of course I had to unpack and test the power profiler - and wow, this is certainly much better than trying to peep at a multimeter. As I suspected there are some current  spikes, and it quickly becomes clear that there is still much room for improvement, but it's not as bad as I feared. power use at "idle" in the editor or uLisp REPL is currently at 2.64mW, and while running uLisp code to draw a fractal while updating the screen, it's 5mW.

    Unfortunately, even when at idle, holding down all the arrow keys makes power jump up to 16.4 mW. So surprisingly, the greatest source of power consumption is the keyboard scanning - hopefully due to some simple-to-fix misconfiguration of the GPIO. My no-name second hand SD card also sucks down another 30mW once it's been initialized, but according to the datasheet the one I have ordered from Adafruit should do a lot better. So I still have hope to get the active power consumption below 6mW, and much closer to 0 at idle, once I get all that worked out.

    Some concessions to usability must come first though - I need to redesign the editor to handle larger files, as well as add some very basic features like key repeat, faster scrolling, selecting text, copy/paste and so on. My library of lisp functions and little toys and experiments is growing quickly and is becoming unmanageable with the current version!

  • Working editor and data storage

    Andreas Eriksen • 02/05/2023 at 05:12 • 0 comments

    I'm happy to report that moving the keyboard scanning code into uLisp went well! Initially I got some corruption on the display, but this was later fixed by disabling the keyboard interrupt while updating the screen. I also slightly rewired the keyboard to free up another SPI interface. More on that later ...

    A simple text editor and REPL

    It didn't take me too long to write a basic text editor in uLisp - working name "Typo". For now, it's very naive code and starts working poorly after about a screenful of text, so some optimizations along the lines of emacs's "redisplay" will eventually be required. But I can type and edit interactively on the PotatoP, with support for such niceties as the backspace key to undo my mistakes and arrow keys to move around :-)

    So based on that I now have a basic working REPL, and it is suddenly possible to do further development work on the editor/REPL from the PotatoP itself. In celebration, I've tweaked the prototype display protector and reprinted it in glorious yellow:

    Planned future work on this prototype includes replacing the damaged display, adding a second display for side-by-side coding and graphics, and removing cat hair from the keyboard

    Error handling

    At first though, usage was severely hampered by the lack of error checking. If there was any problem at all in the code I input, the REPL crashed and had to be restarted from the serial console. Fortunately I came across an uLisp forum post where Goheeca and mgr had extended an earlier version of uLisp with some basic error handling. This couldn't be directly applied to the current version, but with a few tweaks ... it works! I am immensely grateful. I also extended the "testescape" function to respond to keyboard input, so I can interrupt execution if the runtime of my code exceeds my patience.

    Some types of malformed programs can still cause the interpreter to hang, the most likely of which is forgetting to close a double-quoted string or parenthesized expression, which causes the uLisp reader to go into an infinite loop. It will also hang if the code recurses too deeply and there is a stack overflow.

    For the former issue, I've started writing a basic parser (in uLisp!) that will check the validity of my expressions before submitting them to the reader. I hope that this can also be used to give more helpful error messages, making it trivial to find my mistakes. For the latter, I've no plan yet ...

    Storage options

    In the mean time, the presence of these bugs makes it all the more obvious that there's no easy way yet to save my work. If I define a function in the editor, I have to connect the USB-C cable, exit the REPL by sending the escape char from the serial console, "(pprint <function name>)" to display it there, then copy-paste it and save it in a file on my PC. I could streamline this process, but my goal is a stand-alone computer - so I've begun looking into how to store lisp code and text files on the device itself.

    I've still only used about 1/4 of the 1Mb of flash program memory on the Apollo3, and it would be possible to use the remaining space for storage. But although that would fit quite a bit of code/text, it could be vulnerable to being overwritten by later firmware updates, and I'd have to implement it myself and ensure proper wear leveling - and making a mistake in that could kill the flash chip quickly.

    So instead I soldered some wires to a microSD adapter, uncommented a #define and tried out the SD card support already present in the interpreter - and it works out of the box. It's somewhat slow and doesn't support listing files, but that should be easy enough to add. It even supports "(save-image)" and "(load-image)" to save/restore the entire workspace, although personally I want to be able to work with files more explicitly.

    As usual there's an issue to overcome - updates to the display stop working after I've used the SD...

    Read more »
  • Mini update: power usage halved!

    Andreas Eriksen • 01/21/2023 at 06:24 • 1 comment

    Now got max power usage more than halved, down to ~2 mA - again that's with scanning the keyboard, updating and refreshing the screen, and now also while running some floating point calculations in a loop, so I'm hoping this is near representative of actual usage.

    The big power gain was mostly from shutting down the GPIO lines used for serial, which were backpowering the serial chip on the dev board ... the blue LED (which happens to be on the port I'm using for SPI clock) is still blinking away, and may at this point be a serious contender for reducing power usage with a swipe of the soldering iron.

    Currently working on completing the keyboard routine and integrating it into uLisp so I can have a working REPL!

  • Starting back up, baby steps

    Andreas Eriksen • 01/11/2023 at 21:36 • 0 comments

    Finally, I'm back to getting a little bit done on this project. After getting everything set up again, my first bit of progress is actually figuring out what went wrong with the graphics library and how to fix it. It seems the combination of the adafruit gfx / sharp memory display libraries and the sparkfun artemis arduino core end up doing hw SPI transfers most significant bit first, while the display expects least significant bit first. Not 100% sure where the issue lies, probably in the arduino core, but I was able to hack around it by reversing the bits in each byte before transmitting. Anyway, with that working there's a very nice boost to the screen refresh rate! It was quite distractingly slow.

    Got a good tip on how to reduce power usage too, so looking forward to testing that out next!

  • Falling down rabbit holes

    Andreas Eriksen • 03/20/2022 at 22:07 • 0 comments

    To quickly sum up the progress I've made since last time - I can now type on the keyboard, and the words show up on the screen! Those letters in the picture are pretty chunky - but that is for your easy viewing pleasure. I can comfortably read with the default 5x7 font which lets me display 53x30 characters. Moving it closer and adding another one or two next to it should give me sufficient screen real estate.

    I've measured current consumption from the battery at 6mA, or about 22 mW, while scanning the keyboard and constantly updating the screen. That should give me about 83 days of battery life (given constant use) with the laptop-size battery I've ordered.

    It's certainly better than my standard laptop, but not quite as good as could be hoped for - it's 4x the quoted 5 mW power for the Artemis module. Disconnecting the screen or putting the CPU to sleep didn't seem to make much of a difference either, and that means I won't be able to recharge using only the solar panels, certainly not with indoor light at least.

    I suspect most of the power draw is from other components on the board, like the voltage regulator, power LED and possibly more. I've cut the traces to the PDM microphone earlier, but I don't want to start desoldering the other components just yet.

    The keyboard scanning rabbit hole

    I was able to get the timer driven interrupt working, and posted a simple example in the Sparkfun forums in hope that it might help others. The rest was supposed to be simple! But when I coded up the keyboard scanning routine, using the standard Arduino pinMode and digitalWrite / digitalRead calls, it was slow ... unacceptably slow.

    It took about two milliseconds to scan the whole keyboard matrix, which I had naively been hoping to do tens of thousands of times per seconds - but I could barely scan it 500 times per second, and even then the CPU would have been 100% busy scanning the keyboard and have no time left to do anything else.

    I realized I would have to leave the easy and comfortable world of Arduino tutorials, and started digging into the guts below. Happily I discovered that all the source code for the underlying software is included in my ~/.arduino folder!

    Turns out that Sparkfun's Arduino core for the Artemis boards is based on Mbed OS, and every call to pinMode or digitalWrite will spend some time looking up the right mbed::DigitalInOut object. Keeping references to and calling these directly saved about half of the time, getting it down to 1 ms per scan. Reducing the scan rate to 256 times per second seemed acceptable enough for now - that's 25% of the CPU, but I can fix it later.

    Or so you'd think, but I just couldn't accept that. So I dug down through another layer ... the implementation of Mbed OS for the Apollo3 ends up calling functions from the Ambiq SDK. These have somewhat more arcane names, like am_hal_gpio_input_read, but have even less overhead - calling these directly got me down to about 240 microseconds per scan, or about 6.6% of the total CPU time.

    There is yet another layer I could chip away at - there is a "fast GPIO" function, or I could even directly read and write from the I/O registers - but I spent a whole evening trying without much success, and 240 microseconds at 48Mhz is 11520 clock cycles, about ~103 clock cycles per key scanned, and I think I'll be able to live with that ... for now.

    The hardware SPI rabbit hole

    Once I had come to terms with the keyboard scanning, my next step was to display the results on the screen, and I promptly fell into another hole. Screen updates are just a little too slow with software-driven SPI for typing to be responsive. Using he same shortcuts as for the keyboard helps, but it's not great, and getting hardware SPI to work with the Adafruit library on the Sparkfun board is still giving me trouble.

    After consulting the display data sheet and programming app note I was able to write data to the display using hardware SPI without using the...

    Read more »
  • Prototyping progress

    Andreas Eriksen • 03/12/2022 at 21:33 • 0 comments

    The photo I originally uploaded shows an Adafruit NRF52840 Express board - this worked great for testing the display, but I wanted more GPIOs for scanning the whole keyboard matrix directly (14 column lines + 8 row lines).

    I had previously ordered the Sparkfun Artemis ATP board (48 GPIOS!) in the hope to get close to the extremely low power usage numbers they are quoting (5mW). Probably not if I'm using that many GPIO lines, but if I could get even close it would be amazing. Currently it idles at around [email protected], so 13.2mW ... 

    That board sure took it's sweet time in the mail, but now that I have it I have been able to verify that I can get uLisp running on it, scan the keyboard matrix and read all the keys (from LISP). Success!

    What hasn't gone great is getting the display to work with hardware SPI. I must have tried a hundred different combination of parameters but no luck yet. Are there some assumptions in the Adafruit libraries that don't apply to the Sparkfun board? No idea. For now I'll ignore that display updates are kind of slow, and plod on with the next step ...

     ... which is scanning the keyboard at regular intervals, doing debouncing and turning it in to a nice and neat sequence of keyup/down events. I am lucky to have some code to go by from the uLisp author's own very cool lisp badge project: http://www.technoblogy.com/show?2AEE

    In parallel I'm 3D printing a very simple case for the display and breakout board. I learned the hard way that those FPC connectors are fragile, and ruined one 4.4" display - good thing I ordered extra. And hopefully I've learned my lesson now and the case will keep the next one safe.

View all 6 project logs


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK