MicroPython experimental port for the Dabao (Baochip-1x RISC-V) #19580
Replies: 13 comments 5 replies
|
Ah! i was wondering how long this might take! I have a board waiting for me in the studio and I'll give this a test soon! |
|
I received mine today. I willl give it a try |
|
[gear, no idea] I'm probably missing something but after copying firmware.uf2 it didn't reboot here, I tried typing "boot" over the USB serial and I could then see "MicroPython v1.29.0-preview.457.ga7b7409173 on 2026-08-05; DABAO with Baochip-1x" on the new USB serial port after it restarted and from there I was able to see life toggling SPI2_CS. |
|
Just for clarity, development is on this fork/branch: https://github.com/mattytrentini/micropython/tree/baochip-i2c-spi |
|
Regarding these programming instructions:
it looks like those are written for either a board other than the Dabao, or at least a non-standard bootloader setup. Factory configuration is that the Dabao has You can exit that bootloader either by pressing the NOTE: you should Also for anyone just finding this discussion as their first point of contact, (USB ACM) serial console is at 1Mbps ( With those tweaks to putting code on the Dabao, I did get the first build running on my board: Also for completeness the build from about an hour ago (message above mine) also works for me: Ewen |
|
I tried the machine.RTC on a Dabao, but the clock was running quite fast. I'm not sure how to correct that. |
|
I am not familiar with how the RTC is implemented in this but I will say that I do clock the RTC hardware at 1/1024 second per tick and not 1 second per tick, so if the driver assumes 1s/tick then things will indeed run very fast. |
|
Looks like the Micropython RTC is reading the RTC counter via the C SDK, and seems to be assuming it is in seconds. but the so I think that means the RTC divider is "whatever the bootloader set", and definitely faster than real time. Eg, test example, with the last command run maybe 10 seconds after the second command: (values are YYYY, MM, DD, HH, MM, SS, MS, TZ-offset) So my guess is that setting the clock divider via the C API to some plausible value would make it tick at least at "near real time". ETA: this being the function to set the RTC divider in the C API: (there's a Ewen |
|
The RTC divider is the issue. rtc_init() deliberately leaves it at whatever the boot chain set, which is 15, giving about 749 Hz. Call rtc_set_divider() before using it. The complication is that the source is an internal RC oscillator, not a crystal, so there's no fixed correct value. Measured on my board it runs around 11,980 Hz after the fixed /32, and it varies per chip and drifts about 0.25% as the board warms, which is roughly 200 seconds a day. So it needs calibrating against something stable rather than hardcoding a divider.... The relationship is rate = F_raw / (divider + 1), confirmed at five divider values. One special case is that divider 0 gives about 0.70x what the formula predicts, so don't calibrate from it..... For MicroPython, machine.RTC wants seconds, so either divide down to 1 Hz with a calibration pass at init, or take bunnie's 1024 Hz and shift right by 10.... Unrelated but worth knowing since it's easy to conflate, the "32K" reference the ATimer uses is a different clock. That one is 48 kHz, derived from the 48 MHz crystal, and it measured exactly 48,000 on five consecutive runs with no variation... if you need a stable slow clock, that's the one... So for the SDK, Calibration is a single measurement and the RTC tick rate follows a plain relationship: rate = F_raw / (CLK1HZ_FD + 1) So if you set a known divider, measure the resulting tick rate, and multiply back, you recover F_raw. Then the divider for 1 Hz is simply F_raw minus one. You can use this for calibration: |
|
Worth adding that the RTC block itself is an ARM PrimeCell PL031, and PL031 is a 1 Hz seconds counter by design... DR reads seconds and LR sets seconds, and that's the whole contract. So the MicroPython driver reading DR as seconds is correct behaviour, the problem is entirely upstream, PL031 is being fed roughly 749 Hz instead of 1 Hz, and it's faithfully counting what it's given... the fix belongs in whatever configures CLK1HZ_FD before the RTC is used... I'll add the calibration to rtc_init() in the C SDK so callers don't have to deal with this at all.... |
|
Ah right, Dabaos don't have a crystal - so you're correct the RTC is basically not really actually an RTC. This path makes a lot more sense on baosec/baosec-lite targets which have the external 32kHz crystal. |
|
Thanks, I added your rtc_calibrate() and now the RTC is working better. Sorry, I wasn't expecting real time without the hardware for it, but this good enough!
|
|
This is great to see - I just got my hands on a dabao dev board and got this up and running with a bit of help from ewenmcneill's comment - thanks! It would be great to put a LittleFS filesystem in ReRAM - maybe use the top 2MB? Without one Thonny can't connect as it assumes there will be some kind of filesystem present. |
Uh oh!
There was an error while loading. Please reload this page.
Overview
The Dabao is an awesome RISC-V eval board built around the Baochip-1x SoC, both created by @bunnie. @andrewleech and I have been working on a port for MicroPython building on @ArmstrongSubero's daobao-sdk.
This port is still experimental, but if you have a Dabao, I'd love some testers!
[Also, anyone arriving here via DEFCON 34, I think your badge may also work. I'd be very keen to hear if it does/doesn't work!]
Details
Implemented features:
machine.Pin(digital I/O, Pin.board aliases + full Pin.cpu PA0-PF15 access) andmachine.Signalmachine.I2C(hardware, fixed to I2C0_SCL/I2C0_SDA) andmachine.SoftI2C(any pins)machine.SPI(hardware, fixed to the SPI2_* pins) andmachine.SoftSPI(any pins)machine.RTCmachine.WDTmachine.PWM(8 channels: PB0-PB3 and PC0-PC3, two slices of 4 sharing a frequency each)os.urandom()(hardware TRNG)machine.bootloader()Not yet implemented:
machine.UART,machine.ADC, filesystem/storage...Flashing the prebuilt firmware
Unzip and deploy firmware.zip
Building it yourself
Install a recent version of mpbuild.
You'll find the UF2 in
ports/baochip/build-DABAO/firmware.UF2.Any feedback would be very welcome!
All reactions