Custom PicoCalc BIOS/keyboard firmware

Yes you right.

I didn’t check the battery button again after re-enabling the watchdog.
Probably an issue with it…

I will clear this part asap. I’m on writting some docs/wiki about the added registers and code architecture (I hope releasing this soon with a test program).

Thanks for the feedback!

2 Likes

Quick request: Can you please put MD5sum or equivalent for the release .bin in same folder as the bin for distribution? It’d be nice to be absolutely certain it downloaded intact. Thanks!

BTW, some sort of “cheat-sheet” for BIOS-controlled keyboard shortcuts for things like backlight, and firmware-specific features like reboot, and the thing to get it into bootsel mode, would be really useful as well.

I’m not sure if one exists for the “stock” firmware of any version, if so I couldn’t find it, but it’s also kind of “needle in haystack” w.r.t. clockworkpi’s picocalc docs & code where such a thing might reside. If one already exists, my apologies, I didn’t see it in the release anywhere, nor in the obvious repo files.

@jwiede Thanks for your feedback!

I’ve planned to add digital signature and checksum from version 1.
However, although I would have liked to spend much more time validating the code, this would have delayed this release…
But given the time that has passed since the last version (0.7), I assume that the most significant bugs have already been reported.

So answering your second point at the same time, I’m clean-up some test code/firmware for the pico to test some features (RTC, I2C/SPI speed, sleep, etc.), but some docs in form a wiki page in the git repo (registers descriptions, keyboards shortcuts, like you suggested, and global summary of the keys differences between the official and this one) and push the release v1.

In short: it’s planned/in progress, but I’m running behind schedule :smiley:

1 Like

Hello @JackCarterSmith now that I have gotten most of the Linux drivers separated into and operating in their respective kernel device classes I am planning to add support for features in your custom BIOS. IMO the arduino-based “factory“ code is not super great and I do not feel personally motivated to try to improve it right now given that your firmware project exists and is a better starting point.

RTC support is obviously the first priority, but while I have been up to my elbows in it, I have a small set of additional enhancements that I think are both easy to implement and important for the stm32 firmware to provide. Here are ideas for how they could be implemented, and I hope you will consider them, or consider accepting a patch for them if you are not interested in working on them yourself.

  1. Watchdog timer. (Existing PMC code for delayed reboot might already effectively support this, please let me know if so) Write a byte 1-254 representing number of seconds to the corresponding i2c register will trigger a reboot after that many seconds unless the register is written again before the timeout. Writing 0 should cause immediate reboot or shutdown. Writing 255 (-1 in 2’s compliment) to the register should disable the watchdog

  2. Scheduled wakeup. If you implement this in the RTC, I will implement the corresponding rtc alarm in the linux driver.

  3. Green & Amber LED status and control - Expose state of green and amber leds via an i2c register; STM32 will retain control of these leds after power on until their control register is written at which point the OS will be responsible for controlling the LEDs until reboot. In Linux we can attach various triggers to the LEDs to indicate power, charging, io, network, etc. The additional 2 LED indicators will be welcome to have. Bonus if we can get PWM on them!

  4. Audio control register - A register should expose the state of the audio PA power (PA14) and the headphone detect (PC11) pin and the register should allow control of the PA power which should be ON by default after every reboot. From looking at the schematic, the STM32 should override the PA to disabled whenever HP_DET is asserted

  5. Keyboard IRQ - Repurpose one of the UART1 pins as interrupt? I think this has been a lingering plan for some time. Not sure what the approach would be

Final question is regarding the i2c speed. Your note says “I2C handler have been hardened to allow Standard mode (100 kHz) and auto reset logic in case of malformed/corrupted transaction.” However I cannot seem to communicate with the firmware at 400khz anymore. Is this by design? I didn’t have any particular issues at 400khz before.

Thanks for your work; hope this can make for good discussion!

3 Likes

Thanks for your work too @johnlaur ! I’ll look in your Calculinux project at some time… sound great!

About the questions details:

  1. I see the point of this idea, not originally planned but should be easily added, minus adding the appropriate registry. Kind of “heartbeat” register… Just I propose to init it at 0 (disabled state), so as not to force other operating systems to manage this feature. From the first increment, an internal timer in the STM32 will check that the value is incremented by at least 1 every 1.5 seconds (TBD). If the window is missed, a reset occurs. The counter overflow count as an increment, no worry about that. Unfortunately, disabling this watchdog can only be done from another control register (REG_SYS_CFG could do this job).
  2. For now the RTC alarm over 1 day don’t seem to work… BUT that’s before I found an unexpected behavior related to the STM32 watchdog. There may be hope that this is related and that the RTC is now working properly (to be verified). Can’t say for now.
  3. Appears feasible. It would only be necessary to clearly define the recovery and release of controls on I/O. Maybe simply when the STM32 do a pico reset/pwr-off condition, it regain control of the LED at this moment and do the cycle again.
    Adding PWM on them can be more tricky: I don’t if the pin used by LED are connected on the backlight PWM or not (internally from timers PoV)…
  4. I suppose the same answer as for 3.
  5. The STM32 should send a high signal on the PICO_IRQ_Pin (the original UART_TX to the pico) when an interrupt event is triggered. The signal go low when reading the IRQ status registers.
  6. Firstly I removed the limitation of the 10 kHz of the I2C to get the 400 kHz. But got some communication failure with my latest release… I found that the choice of using 4 MHz as sysclk (because one of the main goal for this alternative firmware was to reduce the power consumption) only allow a 100 kHz I2C max freq from datasheet. So yes, it’s by design but not intentional.
    I don’t plan to change this but I still can indicate that to obtain 400 kHz, you only need to change the sysclk frequency to at least 8 MHz (doubling the power usage in averaga) and set the I2C device frequency to 400.

The sad news is that I didn’t have much time available recently to implements/tests a lot of new features (except the RTC because it’s mandatory for my others project). So I can only promise that I will keep these improvements in mind.
In fact, my priority is to finish the RTC (seem your priority too :P) and documentation so that I can finally announce v1. From there, we can see what else we can add.

I wanted to keep control over the code I use, which is one of the reasons why it is not on GitHub.
It’s just that I don’t feel like maintaining code that is larger than what I initially needed.
But I’ve no problem with anyone using it as a basis, forking it, and helping to explain how it works.

1 Like

About your ‘heartbeat’ (i.e. watchdog) register you are considering putting in the STM32 firmware, how do you plan on accommodating for RP2040/RP2350 resets? As there is no way to guarantee that the STM32 knows something about the RP2040/RP2350 resetting, if the new code running post-reset does not know about the ‘heartbeat’ register, if the ‘heartbeat’ register is enabled wouldn’t it trigger an undesirable power cycle under those conditions?

@tabemann For now, I’ve neither acted nor planned how this feature will be (not in the scope of the v1 release).

But in attempting to answer the question in advance of feasibility, I would say that once a reset by this watchdog has been activated, the STM32 returns to an inactive watchdog state and don’t trigger unexpected reset (in the case you mentioned of a reset to change the OS, for example).
I suppose this approach could work.

What is the purpose of adding a manual watchdog to the stm32? The pico’s all have excellent watchdog peripherals already, and an external one doesn’t appear to bring any additional functionality.

3 Likes

Agreed. In zeptoforth, for instance, there is support for the watchdog on both the RP2040 and the RP2350, and furthermore there is built-in support to have the zeptoforth multitasker pet the dog, so the MCU will automatically reboot if something (e.g. a crash) stops the multitasker from operating for long.

The purpose would be in support of non-pico MCUs, like the Luckfox Lyra. It wouldn’t necessarily need to be used by the RP2040 or RP2350.

I’m curious what the unexpected watchdog behavior was that may have fixed the RTC? Sounds interesting to me..

@benklop About the RTC/watchdog issue, I haven’t had time to check in detail yet, but I discovered that the watchdog was still active during sleep mode (even though I set the bits to halt it during sleep/debug mode).
What happens is that when the watchdog wakes up, it triggers and resets the STM32. I had my doubts a while ago, but now it’s been confirmed.
However, for the RTC to function correctly (rearm the day counter at least once every ~36 hours), we need to wake up to do that and then get sleepy again.
But as long as the watchdog trig at each wake-up, the re-arm I’ve setup don’t occur as planned and the RTC is reset by the internal reset logic of the stm32.