Skip to content

baochip: New port for the Baochip-1x RISC-V SoC (DABAO board).#47

Draft
andrewleech wants to merge 6 commits into
review/baochip-portfrom
dabao
Draft

baochip: New port for the Baochip-1x RISC-V SoC (DABAO board).#47
andrewleech wants to merge 6 commits into
review/baochip-portfrom
dabao

Conversation

@andrewleech
Copy link
Copy Markdown
Owner

Summary

New port for the Baochip-1x, a VexRiscv RISC-V SoC with PULP UDMA peripherals, 4 MiB on-chip RRAM, 2 MiB SRAM, and a native USB controller exposed through the vendor boot1 bootloader. First (and currently only) supported board is the Crowd Supply Dabao evaluation board.

What works now: UART2 REPL at 115200 8N1, machine.Pin for all 96 GPIOs with IN/OUT/OPEN_DRAIN, machine.bootloader() to drop back into the vendor boot1 over USB-CDC, and machine.freq() returning the 350 MHz ACLK. Native USB-CDC, filesystem, and the rest of the peripheral drivers are still to come.

Uses dabao-sdk (Apache-2.0), a new open-source C SDK for this chip, separate from the Rust-based pattern that's also in development. Pinned at lib/dabao-sdk as a submodule. Boot signing uses the SDK's developer Ed25519ph key, so the resulting UF2 has a real signature but no meaningful attestation; the CI workflow installs pure25519 for this.

REPL UART RX is interrupt-driven, copying from the hardware 4-byte FIFO into the standard stdin ringbuf.

Open-drain Pin mode is software-emulated. The chip's GPIO block has no OD bit, so OD pins keep the DATA latch at 0 permanently and toggle direction to switch between drive-low (output) and float (input, relying on the external pull-up). A per-port mask tracks which pins are in OD mode so pin.value(v) knows which path to take; the mask is cleared on every soft reset.

A few things are deliberately stubbed with NotImplementedError and TODO markers: unique_id, set_freq, lightsleep with a timeout argument, and deepsleep. reset_cause() returns 0 until the SCG register mapping is done. MICROPY_CONFIG_ROM_LEVEL is set to EXTRA_FEATURES and the default boards/manifest.py includes asyncio.

Testing

Built and tested on the Dabao via the vendor's boot1 USB-CDC flashing path. Smoke tests cover REPL responsiveness, Pin toggle on PB1 (board pin -> CPU pin PA1), machine.bootloader() actually entering boot1, machine.freq() returning 350000000, time.ticks_ms() accuracy on a 100 ms sleep, and a 166-byte single-write burst into UART2 to verify the RX_CHAR path doesn't drop bytes.

No other ports touched.

Trade-offs and Alternatives

Software open-drain costs a small per-port mask in RAM and an extra branch in pin.value(), but the alternative would be to refuse OD mode entirely on this chip.

machine.bootloader() drives PC13 LOW for 1 ms before triggering the software reset. PC13 is dual-use on Dabao: the boot strap AND the 0.85 V regulator feedback path. Holding it LOW for longer interferes with the regulator, so the brief pulse is deliberate.

Generative AI

I used generative AI tools when creating this PR, but a human has checked the code and is responsible for the description above.

Adds the ports/baochip directory with Makefile, linker script,
mpconfigport.h, and the DABAO board's mpconfigboard.h.  The port
uses the dabao-sdk submodule (Apache-2.0) as its vendor layer,
selecting specific SDK .c and .s files rather than linking a
prebuilt library.  SDK crt0 and the IRQ dispatcher are wired in.
MicroPython core boots and prints the banner via UART2.

Signed-off-by: Andrew Leech <andrew@alelec.net>
Wires mp_hal stdout and stdin through UART2 (115200 8N1).  UART RX
is driven by an IRQ-fed ring buffer; a direct UART_VALID poll is kept
as a fallback for contexts where the IRQ has not yet fired.  Soft-reset
restarts the REPL cleanly.  Ctrl-A enters raw REPL mode.

TickTimer is initialised with CLOCKS_PER_TICK = ACLK/1e6, giving a
1 us tick.  mp_hal_ticks_ms/us/cpu read the 64-bit free-running counter
with a race-safe high/low read; mp_hal_delay_ms/us busy-wait on the
same source.  Enables MICROPY_PY_TIME for time.sleep_ms, ticks_ms,
ticks_diff etc. from the REPL (time.time stays off until a RTC lands).

Signed-off-by: Andrew Leech <andrew@alelec.net>
Adds machine.Pin backed by ROM pin objects generated by boardgen
(boards/make-pins.py), one const struct per pin stored in flash.
The struct packs port+pin into two uint8_t fields and uses
qstr_short_t for the name, keeping each object at 8 bytes with no
padding (96 total pins = 768 bytes flash, no heap).

Pin.board and Pin.cpu sub-namespaces are backed by the generated
locals dict; string lookup searches board then cpu.  Modes IN, OUT,
and OPEN_DRAIN (emulated via direction toggling) are supported.
Pull-up is the only pull option (hardware limitation).

The SDK fork is updated to include gpio_get_dir(), which reads GPIOOE
to determine output-enable state, needed for Pin.__repr__.

Signed-off-by: Andrew Leech <andrew@alelec.net>
Drives PC13 (PROG strap, SW2) low for one reset cycle to signal
boot1, which holds the chip in its CDC flashing REPL until PROG is
released.  BOOTLOADER_PORT and BOOTLOADER_PIN are taken from
mpconfigboard.h so boards can override the strap pin.

Signed-off-by: Andrew Leech <andrew@alelec.net>
Adds board.json (upstream board catalog metadata), pins.csv (every
PB/PC pin on the 32-pin header plus functional aliases for UART2,
I2C0, SPI2, QSPI1, and the PROG strap), and deploy.md (documents
the two flash paths: machine.bootloader() from a running REPL, and
PROG+RESET when the board is in an unknown state).

Signed-off-by: Andrew Leech <andrew@alelec.net>
Adds ports_baochip.yml to build the DABAO board on every push and
PR.  Wires the baochip build into ci.sh alongside the other ports.

Signed-off-by: Andrew Leech <andrew@alelec.net>
@github-actions
Copy link
Copy Markdown

Code size report:

Reference:  github/workflows: Bump actions/github-script from 8 to 9. [1c63211]
Comparison: github/workflows: Add baochip port to CI. [merge of 825f3cc]
  mpy-cross:    +0 +0.000% 
   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
      esp32:    +0 +0.000% ESP32_GENERIC
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.47%. Comparing base (1c63211) to head (825f3cc).
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@                 Coverage Diff                  @@
##           review/baochip-port      #47   +/-   ##
====================================================
  Coverage                98.47%   98.47%           
====================================================
  Files                      176      176           
  Lines                    22845    22845           
====================================================
  Hits                     22497    22497           
  Misses                     348      348           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants