From ae200e58df5d975bce8c3874ab9e3ae58d57c2a5 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 21 Nov 2025 18:29:44 +0800 Subject: [PATCH 1/6] feat: Add machine package validation workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add validate-machine-packages job to workflow - Add MACHINE_VALIDATION_TARGETS with 90+ board targets - Update LLGO commit hash to 2d80951 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/scripts/validate_embed_packages.sh | 151 ++++++++++++++++++ .github/workflows/validate-embed-packages.yml | 16 ++ 2 files changed, 167 insertions(+) diff --git a/.github/scripts/validate_embed_packages.sh b/.github/scripts/validate_embed_packages.sh index efdade7..2c413c9 100755 --- a/.github/scripts/validate_embed_packages.sh +++ b/.github/scripts/validate_embed_packages.sh @@ -65,6 +65,146 @@ DEVICE_VALIDATION_TARGETS=( # Machine validation targets MACHINE_VALIDATION_TARGETS=( + "pca10040-s132v6" + "microbit" + "microbit-s110v8" + "microbit-v2" + "microbit-v2-s113v7" + "microbit-v2-s140v7" + "nrf52840-mdk" + "btt-skr-pico" + "pca10031" + "reelboard" + "pca10056" + "pca10059" + "bluemicro840" + "itsybitsy-m0" + "feather-m0" + "trinket-m0" + "gemma-m0" + "circuitplay-express" + "circuitplay-bluefruit" + "clue-alpha" + # "gameboy-advance" + # some picolibc symbol missed + + "grandcentral-m4" + "itsybitsy-m4" + "feather-m4" + "matrixportal-m4" + "pybadge" + "metro-m4-airlift" + "pyportal" + "particle-argon" + "particle-boron" + "particle-xenon" + "pinetime" + "x9pro" + "pca10056-s140v7" + "pca10059-s140v7" + "reelboard-s140v7" + "wioterminal" + "pygamer" + "xiao" + "rak4631" + "feather-nrf52840" + "feather-nrf52840-sense" + "itsybitsy-nrf52840" + "qtpy" + "teensy41" + "teensy40" + "teensy36" + "p1am-100" + "atsame54-xpro" + "feather-m4-can" + "arduino-nano33" + "arduino-mkrwifi1010" + "pico" + "nano-33-ble" + "nano-rp2040" + "feather-rp2040" + "qtpy-rp2040" + "kb2040" + "macropad-rp2040" + "badger2040" + "badger2040-w" + "tufty2040" + "thingplus-rp2040" + "xiao-rp2040" + "waveshare-rp2040-zero" + "challenger-rp2040" + "trinkey-qt2040" + "gopher-badge" + "ae-rp2040" + "thumby" + "pico2" + "tiny2350" + "pico-plus2" + # "metro-rp2350" + # TODO: llgo sync this 0.39.0 target + "waveshare-rp2040-tiny" + "nrf52840-s140v6-uf2-generic" + "bluepill" + "feather-stm32f405" + "lgt92" + "nucleo-f103rb" + "nucleo-f722ze" + "nucleo-l031k6" + "nucleo-l432kc" + "nucleo-l476rg" + "nucleo-l552ze" + "nucleo-wl55jc" + "stm32f4disco" + "stm32f4disco-1" + "stm32f469disco" + "lorae5" + "swan" + "mksnanov3" + # "stm32l0x1" + # TODO: llgo sync this 0.39.0 target + + # "atmega328pb" + # "atmega1284p" + # "arduino" + # "arduino-leonardo" + # "arduino-mega1280" + # "arduino-nano" + # "attiny1616" + # "digispark" + # error: ran out of registers during register allocation + # 2 errors generated. + # panic: export object of internal/abi failed: exit status 1 + + # "esp32-mini32" + # ld.lld: error: section 'text' will not fit in region 'iram_seg': overflowed by 13157 bytes + # binaray too large https://github.com/goplus/llgo/issues/1317 + + # "esp32c3-supermini" + # ld.lld: error: region DRAM overflowed by .data and .bss sections + + + # "nodemcu" + # compile picolibcnewlib/libc/tinystdio/puts.c fail + + "esp-c3-32s-kit" + "qtpy-esp32c3" + "m5stamp-c3" + "xiao-esp32c3" + "esp32-c3-devkit-rust-1" + "esp32c3-12f" + "makerfabs-esp32c3spi35" + + # "hifive1b" + # "maixbit" + # "tkey" + # picolibc symbol notfound like vfprintf,stdout,srandom ... + + "elecrow-rp2040" + "elecrow-rp2350" + "hw-651" + "hw-651-s110v8" + "wasm" + "wasm-unknown" ) # Global variables @@ -96,13 +236,18 @@ create_device_test_file() { cat > "$filename" << EOF package main + import _ "github.com/goplus/emb/$device_package" + //export handleHardFault func handleHardFault() {} + //export handleInterrupt func handleInterrupt() {} + //export Reset_Handler func Reset_Handler() {} + func main() {} EOF @@ -136,16 +281,22 @@ create_machine_test_file() { mkdir -p "$test_dir" cat > "$test_file" << 'EOF' package main + import ( _ "github.com/goplus/emb/machine" ) + //export handleHardFault func handleHardFault() {} + //export handleInterrupt func handleInterrupt() {} + //export Reset_Handler func Reset_Handler() {} + func main(){ + } EOF log_info "Created test file: $test_file" >&2 diff --git a/.github/workflows/validate-embed-packages.yml b/.github/workflows/validate-embed-packages.yml index e8c376c..38d4b26 100644 --- a/.github/workflows/validate-embed-packages.yml +++ b/.github/workflows/validate-embed-packages.yml @@ -26,3 +26,19 @@ jobs: - name: Run Device Package Validation run: | ./.github/scripts/validate_embed_packages.sh device + + validate-machine-packages: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: "1.21" + - name: Setup LLGO + uses: ./.github/actions/setup-llgo + with: + commit-hash: 2d80951e7d8f5823c1fa92c8a7cb5dd351a10e6a + - name: Run Machine Package Validation + run: | + ./.github/scripts/validate_embed_packages.sh machine From eb0bfd524c6c6a151024fde6aefe6e19c154f3a5 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 21 Nov 2025 18:43:18 +0800 Subject: [PATCH 2/6] feat: Update machine package with LLGO adaptations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sync machine package from goplus/lib PR #19 - Update import paths from github.com/goplus/lib/emb to github.com/goplus/emb - Add _wrap directory for LLGO wrapper functions - Update all board and architecture specific files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- machine/_usb/adc/midi/buffer.go | 2 +- machine/_usb/adc/midi/midi.go | 6 +- machine/_usb/cdc/buffer.go | 2 +- machine/_usb/cdc/usbcdc.go | 6 +- machine/_usb/descriptor/configuration.go | 2 +- machine/_usb/descriptor/descriptor.go | 2 +- machine/_usb/descriptor/device.go | 2 +- machine/_usb/descriptor/endpoint.go | 2 +- machine/_usb/descriptor/hid.go | 4 +- machine/_usb/hid/buffer.go | 2 +- machine/_usb/hid/hid.go | 6 +- machine/_usb/hid/joystick/joystick.go | 8 +- machine/_usb/hid/joystick/state.go | 2 +- machine/_usb/hid/keyboard/keyboard.go | 4 +- machine/_usb/hid/mouse/mouse.go | 4 +- machine/_usb/msc/cbw.go | 4 +- machine/_usb/msc/disk.go | 2 +- machine/_usb/msc/msc.go | 10 +- machine/_usb/msc/scsi.go | 6 +- machine/_usb/msc/scsi_inquiry.go | 4 +- machine/_usb/msc/scsi_readwrite.go | 4 +- machine/_usb/msc/scsi_unmap.go | 4 +- machine/_usb/msc/setup.go | 6 +- machine/_wrap/machine_rp2040_rom.c | 186 ++++++ machine/_wrap/machine_rp2050_rom.c | 492 ++++++++++++++++ machine/board_arduino_mega2560.go | 4 +- machine/board_atsame54-xpro.go | 2 +- machine/board_bluepill.go | 4 +- machine/board_feather-m4-can.go | 2 +- machine/board_feather-stm32f405.go | 4 +- machine/board_gnse.go | 4 +- machine/board_hifive1b_baremetal.go | 2 +- machine/board_lgt92.go | 4 +- machine/board_lorae5.go | 4 +- machine/board_maixbit_baremetal.go | 2 +- machine/board_mksnanov3.go | 4 +- machine/board_nucleof103rb.go | 4 +- machine/board_nucleof722ze.go | 4 +- machine/board_nucleol031k6.go | 4 +- machine/board_nucleol432kc.go | 4 +- machine/board_nucleol476rg.go | 4 +- machine/board_nucleol552ze.go | 4 +- machine/board_nucleowl55jc.go | 4 +- machine/board_stm32f469disco.go | 4 +- machine/board_stm32f4disco.go | 4 +- machine/board_swan.go | 4 +- machine/board_teensy40.go | 4 +- machine/board_teensy41.go | 4 +- machine/buffer.go | 2 +- machine/machine_atmega.go | 6 +- machine/machine_atmega1280.go | 6 +- machine/machine_atmega1284p.go | 4 +- machine/machine_atmega2560.go | 4 +- machine/machine_atmega328.go | 6 +- machine/machine_atmega328p.go | 4 +- machine/machine_atmega328pb.go | 6 +- machine/machine_atmega32u4.go | 4 +- machine/machine_atsam.go | 2 +- machine/machine_atsamd21.go | 8 +- machine/machine_atsamd21_usb.go | 6 +- machine/machine_atsamd21e18.go | 4 +- machine/machine_atsamd21g18.go | 4 +- machine/machine_atsamd51.go | 8 +- machine/machine_atsamd51_usb.go | 6 +- machine/machine_atsamd51g19.go | 2 +- machine/machine_atsamd51j19.go | 2 +- machine/machine_atsamd51j20.go | 2 +- machine/machine_atsamd51p19.go | 2 +- machine/machine_atsamd51p20.go | 2 +- machine/machine_atsame51j19.go | 2 +- machine/machine_atsame54p20.go | 2 +- machine/machine_atsame5x_can.go | 4 +- machine/machine_attiny1616.go | 2 +- machine/machine_attiny85.go | 4 +- machine/machine_avr.go | 11 +- machine/machine_avrtiny.go | 4 +- machine/machine_cortexm.go | 2 +- machine/machine_esp32.go | 4 +- machine/machine_esp32_i2c.go | 4 +- machine/machine_esp32c3.go | 8 +- machine/machine_esp32c3_i2c.go | 4 +- machine/machine_esp32c3_spi.go | 4 +- machine/machine_esp8266.go | 4 +- machine/machine_fe310.go | 4 +- machine/machine_gameboyadvance.go | 4 +- machine/machine_k210.go | 6 +- machine/machine_mimxrt1062.go | 6 +- machine/machine_mimxrt1062_i2c.go | 2 +- machine/machine_mimxrt1062_spi.go | 2 +- machine/machine_mimxrt1062_uart.go | 6 +- machine/machine_nrf.go | 6 +- machine/machine_nrf51.go | 2 +- machine/machine_nrf52.go | 2 +- machine/machine_nrf52833.go | 2 +- machine/machine_nrf52840.go | 2 +- machine/machine_nrf52840_enter_bootloader.go | 4 +- machine/machine_nrf52840_usb.go | 10 +- machine/machine_nrf528xx.go | 2 +- machine/machine_nrf52xxx.go | 4 +- machine/machine_nrf5x.go | 2 +- machine/machine_nrf_sd.go | 4 +- machine/machine_nxpmk66f18.go | 4 +- machine/machine_nxpmk66f18_uart.go | 8 +- machine/machine_rp2.go | 6 +- machine/machine_rp2040_rom.go | 241 ++------ machine/machine_rp2040_rtc.go | 4 +- machine/machine_rp2040_usb.go | 6 +- ...e_rp2040_usb_fix_usb_device_enumeration.go | 4 +- machine/machine_rp2350_rom.go | 547 ++---------------- machine/machine_rp2350_usb.go | 6 +- machine/machine_rp2_2040.go | 4 +- machine/machine_rp2_2350.go | 4 +- machine/machine_rp2_adc.go | 2 +- machine/machine_rp2_clocks.go | 6 +- machine/machine_rp2_gpio.go | 6 +- machine/machine_rp2_i2c.go | 5 +- machine/machine_rp2_pll.go | 4 +- machine/machine_rp2_pwm.go | 4 +- machine/machine_rp2_resets.go | 2 +- machine/machine_rp2_rng.go | 2 +- machine/machine_rp2_spi.go | 2 +- machine/machine_rp2_timer.go | 6 +- machine/machine_rp2_uart.go | 14 +- machine/machine_rp2_usb.go | 4 +- machine/machine_rp2_watchdog.go | 2 +- machine/machine_rp2_xosc.go | 4 +- machine/machine_stm32.go | 4 +- machine/machine_stm32_adc_f1.go | 2 +- machine/machine_stm32_adc_f4.go | 2 +- machine/machine_stm32_exti_afio.go | 4 +- machine/machine_stm32_exti_exti.go | 4 +- machine/machine_stm32_exti_syscfg.go | 4 +- machine/machine_stm32_exti_syscfg_noenable.go | 4 +- machine/machine_stm32_flash.go | 2 +- machine/machine_stm32_gpio_reva.go | 2 +- machine/machine_stm32_gpio_revb.go | 2 +- machine/machine_stm32_gpio_revb_mp.go | 2 +- machine/machine_stm32_i2c_reva.go | 2 +- machine/machine_stm32_i2c_revb.go | 2 +- machine/machine_stm32_iwdg.go | 2 +- machine/machine_stm32_moder_gpio.go | 2 +- machine/machine_stm32_rng.go | 2 +- machine/machine_stm32_spi.go | 4 +- machine/machine_stm32_tim.go | 6 +- machine/machine_stm32_uart.go | 6 +- machine/machine_stm32f103.go | 6 +- machine/machine_stm32f4.go | 8 +- machine/machine_stm32f7.go | 6 +- machine/machine_stm32f7x2.go | 2 +- machine/machine_stm32l0.go | 4 +- machine/machine_stm32l0x1.go | 6 +- machine/machine_stm32l0x2.go | 6 +- machine/machine_stm32l4.go | 8 +- machine/machine_stm32l5.go | 6 +- machine/machine_stm32l5x2.go | 2 +- machine/machine_stm32wlx.go | 8 +- machine/machine_tkey.go | 2 +- machine/serial-rtt.go | 4 +- machine/usb.go | 4 +- machine/virt.go | 2 +- 160 files changed, 1082 insertions(+), 1022 deletions(-) create mode 100644 machine/_wrap/machine_rp2040_rom.c create mode 100644 machine/_wrap/machine_rp2050_rom.c diff --git a/machine/_usb/adc/midi/buffer.go b/machine/_usb/adc/midi/buffer.go index 39cab2c..28defd7 100644 --- a/machine/_usb/adc/midi/buffer.go +++ b/machine/_usb/adc/midi/buffer.go @@ -1,7 +1,7 @@ package midi import ( - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" ) const bufferSize = 128 diff --git a/machine/_usb/adc/midi/midi.go b/machine/_usb/adc/midi/midi.go index 8ead2e9..4189e84 100644 --- a/machine/_usb/adc/midi/midi.go +++ b/machine/_usb/adc/midi/midi.go @@ -1,9 +1,9 @@ package midi import ( - "machine" - "machine/usb" - "machine/usb/descriptor" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/descriptor" ) const ( diff --git a/machine/_usb/cdc/buffer.go b/machine/_usb/cdc/buffer.go index ad5eb36..f9d7d90 100644 --- a/machine/_usb/cdc/buffer.go +++ b/machine/_usb/cdc/buffer.go @@ -1,7 +1,7 @@ package cdc import ( - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" ) const rxRingBufferSize = 128 diff --git a/machine/_usb/cdc/usbcdc.go b/machine/_usb/cdc/usbcdc.go index 5b5ffbf..3132fc4 100644 --- a/machine/_usb/cdc/usbcdc.go +++ b/machine/_usb/cdc/usbcdc.go @@ -2,9 +2,9 @@ package cdc import ( "errors" - "machine" - "machine/usb" - "runtime/interrupt" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/interrupt" ) var ( diff --git a/machine/_usb/descriptor/configuration.go b/machine/_usb/descriptor/configuration.go index efb9ab1..b7febb5 100644 --- a/machine/_usb/descriptor/configuration.go +++ b/machine/_usb/descriptor/configuration.go @@ -1,7 +1,7 @@ package descriptor import ( - "internal/binary" + "github.com/goplus/emb/internal/binary" ) const ( diff --git a/machine/_usb/descriptor/descriptor.go b/machine/_usb/descriptor/descriptor.go index 852ddab..c519291 100644 --- a/machine/_usb/descriptor/descriptor.go +++ b/machine/_usb/descriptor/descriptor.go @@ -1,7 +1,7 @@ package descriptor import ( - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" ) const ( diff --git a/machine/_usb/descriptor/device.go b/machine/_usb/descriptor/device.go index 0c3ee92..c2ee32f 100644 --- a/machine/_usb/descriptor/device.go +++ b/machine/_usb/descriptor/device.go @@ -1,7 +1,7 @@ package descriptor import ( - "internal/binary" + "github.com/goplus/emb/internal/binary" ) const ( diff --git a/machine/_usb/descriptor/endpoint.go b/machine/_usb/descriptor/endpoint.go index 57a1706..b7d2c0e 100644 --- a/machine/_usb/descriptor/endpoint.go +++ b/machine/_usb/descriptor/endpoint.go @@ -1,7 +1,7 @@ package descriptor import ( - "internal/binary" + "github.com/goplus/emb/internal/binary" ) /* Endpoint Descriptor diff --git a/machine/_usb/descriptor/hid.go b/machine/_usb/descriptor/hid.go index 06b9801..2e8a6b6 100644 --- a/machine/_usb/descriptor/hid.go +++ b/machine/_usb/descriptor/hid.go @@ -2,8 +2,8 @@ package descriptor import ( "errors" - "internal/binary" - "internal/bytealg" + "github.com/goplus/emb/internal/binary" + "github.com/goplus/emb/internal/bytealg" ) var configurationCDCHID = [configurationTypeLen]byte{ diff --git a/machine/_usb/hid/buffer.go b/machine/_usb/hid/buffer.go index 2674bbd..a4ffa6f 100644 --- a/machine/_usb/hid/buffer.go +++ b/machine/_usb/hid/buffer.go @@ -1,7 +1,7 @@ package hid import ( - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" ) const bufferSize = 128 diff --git a/machine/_usb/hid/hid.go b/machine/_usb/hid/hid.go index 791fd06..7342cd3 100644 --- a/machine/_usb/hid/hid.go +++ b/machine/_usb/hid/hid.go @@ -2,9 +2,9 @@ package hid import ( "errors" - "machine" - "machine/usb" - "machine/usb/descriptor" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/descriptor" ) // from usb-hid.go diff --git a/machine/_usb/hid/joystick/joystick.go b/machine/_usb/hid/joystick/joystick.go index 2c2f719..03fc3e0 100644 --- a/machine/_usb/hid/joystick/joystick.go +++ b/machine/_usb/hid/joystick/joystick.go @@ -1,10 +1,10 @@ package joystick import ( - "machine" - "machine/usb" - "machine/usb/descriptor" - "machine/usb/hid" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/descriptor" + "github.com/goplus/emb/machine/_usb/hid" ) var Joystick *joystick diff --git a/machine/_usb/hid/joystick/state.go b/machine/_usb/hid/joystick/state.go index 08265ab..00fba76 100644 --- a/machine/_usb/hid/joystick/state.go +++ b/machine/_usb/hid/joystick/state.go @@ -1,7 +1,7 @@ package joystick import ( - "machine/usb/descriptor" + "github.com/goplus/emb/machine/_usb/descriptor" "encoding/binary" ) diff --git a/machine/_usb/hid/keyboard/keyboard.go b/machine/_usb/hid/keyboard/keyboard.go index 9f5f420..d041bc1 100644 --- a/machine/_usb/hid/keyboard/keyboard.go +++ b/machine/_usb/hid/keyboard/keyboard.go @@ -2,8 +2,8 @@ package keyboard import ( "errors" - "machine" - "machine/usb/hid" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb/hid" ) // from usb-hid-keyboard.go diff --git a/machine/_usb/hid/mouse/mouse.go b/machine/_usb/hid/mouse/mouse.go index d790bdb..2c61844 100644 --- a/machine/_usb/hid/mouse/mouse.go +++ b/machine/_usb/hid/mouse/mouse.go @@ -1,8 +1,8 @@ package mouse import ( - "machine" - "machine/usb/hid" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb/hid" ) var Mouse *mouse diff --git a/machine/_usb/msc/cbw.go b/machine/_usb/msc/cbw.go index 7ebf346..5ec0695 100644 --- a/machine/_usb/msc/cbw.go +++ b/machine/_usb/msc/cbw.go @@ -2,8 +2,8 @@ package msc import ( "encoding/binary" - "machine/usb/msc/csw" - "machine/usb/msc/scsi" + "github.com/goplus/emb/machine/_usb/msc/csw" + "github.com/goplus/emb/machine/_usb/msc/scsi" ) const ( diff --git a/machine/_usb/msc/disk.go b/machine/_usb/msc/disk.go index 6624d38..9c036d5 100644 --- a/machine/_usb/msc/disk.go +++ b/machine/_usb/msc/disk.go @@ -4,7 +4,7 @@ import ( "encoding/binary" "errors" "fmt" - "machine" + "github.com/goplus/emb/machine" "time" ) diff --git a/machine/_usb/msc/msc.go b/machine/_usb/msc/msc.go index d3bf8d6..dc708fb 100644 --- a/machine/_usb/msc/msc.go +++ b/machine/_usb/msc/msc.go @@ -1,11 +1,11 @@ package msc import ( - "machine" - "machine/usb" - "machine/usb/descriptor" - "machine/usb/msc/csw" - "machine/usb/msc/scsi" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/descriptor" + "github.com/goplus/emb/machine/_usb/msc/csw" + "github.com/goplus/emb/machine/_usb/msc/scsi" "time" ) diff --git a/machine/_usb/msc/scsi.go b/machine/_usb/msc/scsi.go index d7266ed..21468af 100644 --- a/machine/_usb/msc/scsi.go +++ b/machine/_usb/msc/scsi.go @@ -2,9 +2,9 @@ package msc import ( "encoding/binary" - "machine/usb" - "machine/usb/msc/csw" - "machine/usb/msc/scsi" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/msc/csw" + "github.com/goplus/emb/machine/_usb/msc/scsi" ) func (m *msc) scsiCmdBegin() { diff --git a/machine/_usb/msc/scsi_inquiry.go b/machine/_usb/msc/scsi_inquiry.go index ae7028f..6858c6b 100644 --- a/machine/_usb/msc/scsi_inquiry.go +++ b/machine/_usb/msc/scsi_inquiry.go @@ -2,8 +2,8 @@ package msc import ( "encoding/binary" - "machine/usb/msc/csw" - "machine/usb/msc/scsi" + "github.com/goplus/emb/machine/_usb/msc/csw" + "github.com/goplus/emb/machine/_usb/msc/scsi" ) type vpdPage struct { diff --git a/machine/_usb/msc/scsi_readwrite.go b/machine/_usb/msc/scsi_readwrite.go index 1b09e13..415351a 100644 --- a/machine/_usb/msc/scsi_readwrite.go +++ b/machine/_usb/msc/scsi_readwrite.go @@ -2,8 +2,8 @@ package msc import ( "errors" - "machine/usb/msc/csw" - "machine/usb/msc/scsi" + "github.com/goplus/emb/machine/_usb/msc/csw" + "github.com/goplus/emb/machine/_usb/msc/scsi" ) var invalidWriteError = errors.New("invalid write offset or length") diff --git a/machine/_usb/msc/scsi_unmap.go b/machine/_usb/msc/scsi_unmap.go index 79c2426..c88d0a2 100644 --- a/machine/_usb/msc/scsi_unmap.go +++ b/machine/_usb/msc/scsi_unmap.go @@ -2,8 +2,8 @@ package msc import ( "encoding/binary" - "machine/usb/msc/csw" - "machine/usb/msc/scsi" + "github.com/goplus/emb/machine/_usb/msc/csw" + "github.com/goplus/emb/machine/_usb/msc/scsi" ) type Error int diff --git a/machine/_usb/msc/setup.go b/machine/_usb/msc/setup.go index 3d5bef2..9024d47 100644 --- a/machine/_usb/msc/setup.go +++ b/machine/_usb/msc/setup.go @@ -1,9 +1,9 @@ package msc import ( - "machine" - "machine/usb" - "machine/usb/msc/csw" + "github.com/goplus/emb/machine" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/msc/csw" ) func setupPacketHandler(setup usb.Setup) bool { diff --git a/machine/_wrap/machine_rp2040_rom.c b/machine/_wrap/machine_rp2040_rom.c new file mode 100644 index 0000000..92dcda8 --- /dev/null +++ b/machine/_wrap/machine_rp2040_rom.c @@ -0,0 +1,186 @@ +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/pico_bootrom/include/pico/bootrom.h + +#define ROM_FUNC_POPCOUNT32 ROM_TABLE_CODE('P', '3') +#define ROM_FUNC_REVERSE32 ROM_TABLE_CODE('R', '3') +#define ROM_FUNC_CLZ32 ROM_TABLE_CODE('L', '3') +#define ROM_FUNC_CTZ32 ROM_TABLE_CODE('T', '3') +#define ROM_FUNC_MEMSET ROM_TABLE_CODE('M', 'S') +#define ROM_FUNC_MEMSET4 ROM_TABLE_CODE('S', '4') +#define ROM_FUNC_MEMCPY ROM_TABLE_CODE('M', 'C') +#define ROM_FUNC_MEMCPY44 ROM_TABLE_CODE('C', '4') +#define ROM_FUNC_RESET_USB_BOOT ROM_TABLE_CODE('U', 'B') +#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F') +#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X') +#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E') +#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P') +#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C') +#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X') + +#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8)) + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef unsigned long size_t; +typedef unsigned long uintptr_t; + +#define false 0 +#define true 1 +typedef int bool; + +#define ram_func __attribute__((section(".ramfuncs"),noinline)) + +typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); +typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t); +typedef void (*flash_init_boot2_copyout_fn)(void); +typedef void (*flash_enable_xip_via_boot2_fn)(void); +typedef void (*flash_exit_xip_fn)(void); +typedef void (*flash_flush_cache_fn)(void); +typedef void (*flash_connect_internal_fn)(void); +typedef void (*flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint16_t); +typedef void (*flash_range_program_fn)(uint32_t, const uint8_t*, size_t); + +static inline __attribute__((always_inline)) void __compiler_memory_barrier(void) { + __asm__ volatile ("" : : : "memory"); +} + +#define rom_hword_as_ptr(rom_address) (void *)(uintptr_t)(*(uint16_t *)(uintptr_t)(rom_address)) + +void *rom_func_lookup(uint32_t code) { + rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(0x18); + uint16_t *func_table = (uint16_t *) rom_hword_as_ptr(0x14); + return rom_table_lookup(func_table, code); +} + +void reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) { + rom_reset_usb_boot_fn func = (rom_reset_usb_boot_fn) rom_func_lookup(ROM_FUNC_RESET_USB_BOOT); + func(usb_activity_gpio_pin_mask, disable_interface_mask); +} + +#define FLASH_BLOCK_ERASE_CMD 0xd8 + +#define FLASH_PAGE_SIZE (1u << 8) +#define FLASH_SECTOR_SIZE (1u << 12) +#define FLASH_BLOCK_SIZE (1u << 16) + +#define BOOT2_SIZE_WORDS 64 +#define XIP_BASE 0x10000000 + +static uint32_t boot2_copyout[BOOT2_SIZE_WORDS]; +static bool boot2_copyout_valid = false; + +static ram_func void flash_init_boot2_copyout() { + if (boot2_copyout_valid) + return; + for (int i = 0; i < BOOT2_SIZE_WORDS; ++i) + boot2_copyout[i] = ((uint32_t *)XIP_BASE)[i]; + __compiler_memory_barrier(); + boot2_copyout_valid = true; +} + +static ram_func void flash_enable_xip_via_boot2() { + ((void (*)(void))boot2_copyout+1)(); +} + +#define IO_QSPI_BASE 0x40018000 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS 0x00000300 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_MSB 9 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB 8 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW 0x2 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH 0x3 + +#define XIP_SSI_BASE 0x18000000 +#define ssi_hw ((ssi_hw_t *)XIP_SSI_BASE) +#define SSI_SR_OFFSET 0x00000028 +#define SSI_DR0_OFFSET 0x00000060 +#define SSI_SR_TFNF_BITS 0x00000002 +#define SSI_SR_RFNE_BITS 0x00000008 + +void ram_func flash_cs_force(bool high) { + uint32_t field_val = high ? + IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH : + IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW; + + // &ioqspi_hw->io[1].ctrl + uint32_t *addr = (uint32_t*)(IO_QSPI_BASE + (1 * 8) + 4); + + *addr = ((*addr) & !IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS) + | (field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB); + +} + +// See https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_flash/flash.c#L86 +void ram_func flash_range_write(uint32_t offset, const uint8_t *data, size_t count) +{ + flash_range_program_fn flash_range_program_func = (flash_range_program_fn) rom_func_lookup(ROM_FUNC_FLASH_RANGE_PROGRAM); + flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH); + flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP); + flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE); + + flash_init_boot2_copyout(); + + __compiler_memory_barrier(); + + flash_connect_internal_func(); + flash_exit_xip_func(); + + flash_range_program_func(offset, data, count); + flash_flush_cache_func(); + flash_enable_xip_via_boot2(); +} + +void ram_func flash_erase_blocks(uint32_t offset, size_t count) +{ + flash_range_erase_fn flash_range_erase_func = (flash_range_erase_fn) rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE); + flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH); + flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP); + flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE); + + flash_init_boot2_copyout(); + + __compiler_memory_barrier(); + + flash_connect_internal_func(); + flash_exit_xip_func(); + + flash_range_erase_func(offset, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD); + flash_flush_cache_func(); + flash_enable_xip_via_boot2(); +} + +void ram_func flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) { + flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH); + flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP); + flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE); + + flash_init_boot2_copyout(); + + __compiler_memory_barrier(); + + flash_connect_internal_func(); + flash_exit_xip_func(); + + flash_cs_force(0); + size_t tx_remaining = count; + size_t rx_remaining = count; + // We may be interrupted -- don't want FIFO to overflow if we're distracted. + const size_t max_in_flight = 16 - 2; + while (tx_remaining || rx_remaining) { + uint32_t flags = *(uint32_t*)(XIP_SSI_BASE + SSI_SR_OFFSET); + bool can_put = !!(flags & SSI_SR_TFNF_BITS); + bool can_get = !!(flags & SSI_SR_RFNE_BITS); + if (can_put && tx_remaining && rx_remaining - tx_remaining < max_in_flight) { + *(uint32_t*)(XIP_SSI_BASE + SSI_DR0_OFFSET) = *txbuf++; + --tx_remaining; + } + if (can_get && rx_remaining) { + *rxbuf++ = (uint8_t)*(uint32_t*)(XIP_SSI_BASE + SSI_DR0_OFFSET); + --rx_remaining; + } + } + flash_cs_force(1); + + flash_flush_cache_func(); + flash_enable_xip_via_boot2(); +} \ No newline at end of file diff --git a/machine/_wrap/machine_rp2050_rom.c b/machine/_wrap/machine_rp2050_rom.c new file mode 100644 index 0000000..a767bb2 --- /dev/null +++ b/machine/_wrap/machine_rp2050_rom.c @@ -0,0 +1,492 @@ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +typedef unsigned long size_t; +typedef unsigned long uintptr_t; +typedef long int intptr_t; + +typedef const volatile uint16_t io_ro_16; +typedef const volatile uint32_t io_ro_32; +typedef volatile uint16_t io_rw_16; +typedef volatile uint32_t io_rw_32; +typedef volatile uint32_t io_wo_32; + +#define false 0 +#define true 1 +typedef int bool; + +#define ram_func __attribute__((section(".ramfuncs"),noinline)) + +typedef void (*flash_exit_xip_fn)(void); +typedef void (*flash_flush_cache_fn)(void); +typedef void (*flash_connect_internal_fn)(void); +typedef void (*flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint16_t); +typedef void (*flash_range_program_fn)(uint32_t, const uint8_t*, size_t); +static inline __attribute__((always_inline)) void __compiler_memory_barrier(void) { + __asm__ volatile ("" : : : "memory"); +} + +// https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf +// 13.9. Predefined OTP Data Locations +// OTP_DATA: FLASH_DEVINFO Register + +#define OTP_DATA_FLASH_DEVINFO_CS0_SIZE_BITS 0x0F00 +#define OTP_DATA_FLASH_DEVINFO_CS0_SIZE_LSB 8 +#define OTP_DATA_FLASH_DEVINFO_CS1_SIZE_BITS 0xF000 +#define OTP_DATA_FLASH_DEVINFO_CS1_SIZE_LSB 12 + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2350/hardware_regs/include/hardware/regs/addressmap.h + +#define REG_ALIAS_RW_BITS (0x0 << 12) +#define REG_ALIAS_XOR_BITS (0x1 << 12) +#define REG_ALIAS_SET_BITS (0x2 << 12) +#define REG_ALIAS_CLR_BITS (0x3 << 12) + +#define XIP_BASE 0x10000000 +#define XIP_QMI_BASE 0x400d0000 +#define IO_QSPI_BASE 0x40030000 +#define BOOTRAM_BASE 0x400e0000 + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/hardware_base/include/hardware/address_mapped.h + +#define hw_alias_check_addr(addr) ((uintptr_t)(addr)) +#define hw_set_alias_untyped(addr) ((void *)(REG_ALIAS_SET_BITS + hw_alias_check_addr(addr))) +#define hw_clear_alias_untyped(addr) ((void *)(REG_ALIAS_CLR_BITS + hw_alias_check_addr(addr))) +#define hw_xor_alias_untyped(addr) ((void *)(REG_ALIAS_XOR_BITS + hw_alias_check_addr(addr))) + +__attribute__((always_inline)) +static void hw_set_bits(io_rw_32 *addr, uint32_t mask) { + *(io_rw_32 *) hw_set_alias_untyped((volatile void *) addr) = mask; +} + +__attribute__((always_inline)) +static void hw_clear_bits(io_rw_32 *addr, uint32_t mask) { + *(io_rw_32 *) hw_clear_alias_untyped((volatile void *) addr) = mask; +} + +__attribute__((always_inline)) +static void hw_xor_bits(io_rw_32 *addr, uint32_t mask) { + *(io_rw_32 *) hw_xor_alias_untyped((volatile void *) addr) = mask; +} + +__attribute__((always_inline)) +static void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask) { + hw_xor_bits(addr, (*addr ^ values) & write_mask); +} + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h + +#define pico_default_asm_volatile(...) __asm volatile (".syntax unified\n" __VA_ARGS__) + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2350/pico_platform/include/pico/platform.h + +static bool pico_processor_state_is_nonsecure(void) { +// // todo add a define to disable NS checking at all? +// // IDAU-Exempt addresses return S=1 when tested in the Secure state, +// // whereas executing a tt in the NonSecure state will always return S=0. +// uint32_t tt; +// pico_default_asm_volatile ( +// "movs %0, #0\n" +// "tt %0, %0\n" +// : "=r" (tt) : : "cc" +// ); +// return !(tt & (1u << 22)); + + return false; +} + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/pico_bootrom/include/pico/bootrom_constants.h + +// RP2040 & RP2350 +#define ROM_DATA_SOFTWARE_GIT_REVISION ROM_TABLE_CODE('G', 'R') +#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X') +#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X') +#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C') +#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F') +#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E') +#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P') + +// RP2350 only +#define ROM_FUNC_PICK_AB_PARTITION ROM_TABLE_CODE('A', 'B') +#define ROM_FUNC_CHAIN_IMAGE ROM_TABLE_CODE('C', 'I') +#define ROM_FUNC_EXPLICIT_BUY ROM_TABLE_CODE('E', 'B') +#define ROM_FUNC_FLASH_RUNTIME_TO_STORAGE_ADDR ROM_TABLE_CODE('F', 'A') +#define ROM_DATA_FLASH_DEVINFO16_PTR ROM_TABLE_CODE('F', 'D') +#define ROM_FUNC_FLASH_OP ROM_TABLE_CODE('F', 'O') +#define ROM_FUNC_GET_B_PARTITION ROM_TABLE_CODE('G', 'B') +#define ROM_FUNC_GET_PARTITION_TABLE_INFO ROM_TABLE_CODE('G', 'P') +#define ROM_FUNC_GET_SYS_INFO ROM_TABLE_CODE('G', 'S') +#define ROM_FUNC_GET_UF2_TARGET_PARTITION ROM_TABLE_CODE('G', 'U') +#define ROM_FUNC_LOAD_PARTITION_TABLE ROM_TABLE_CODE('L', 'P') +#define ROM_FUNC_OTP_ACCESS ROM_TABLE_CODE('O', 'A') +#define ROM_DATA_PARTITION_TABLE_PTR ROM_TABLE_CODE('P', 'T') +#define ROM_FUNC_FLASH_RESET_ADDRESS_TRANS ROM_TABLE_CODE('R', 'A') +#define ROM_FUNC_REBOOT ROM_TABLE_CODE('R', 'B') +#define ROM_FUNC_SET_ROM_CALLBACK ROM_TABLE_CODE('R', 'C') +#define ROM_FUNC_SECURE_CALL ROM_TABLE_CODE('S', 'C') +#define ROM_FUNC_SET_NS_API_PERMISSION ROM_TABLE_CODE('S', 'P') +#define ROM_FUNC_BOOTROM_STATE_RESET ROM_TABLE_CODE('S', 'R') +#define ROM_FUNC_SET_BOOTROM_STACK ROM_TABLE_CODE('S', 'S') +#define ROM_DATA_SAVED_XIP_SETUP_FUNC_PTR ROM_TABLE_CODE('X', 'F') +#define ROM_FUNC_FLASH_SELECT_XIP_READ_MODE ROM_TABLE_CODE('X', 'M') +#define ROM_FUNC_VALIDATE_NS_BUFFER ROM_TABLE_CODE('V', 'B') + +#define BOOTSEL_FLAG_GPIO_PIN_SPECIFIED 0x20 + +#define BOOTROM_FUNC_TABLE_OFFSET 0x14 + +// todo remove this (or #ifdef it for A1/A2) +#define BOOTROM_IS_A2() ((*(volatile uint8_t *)0x13) == 2) +#define BOOTROM_WELL_KNOWN_PTR_SIZE (BOOTROM_IS_A2() ? 2 : 4) + +#define BOOTROM_VTABLE_OFFSET 0x00 +#define BOOTROM_TABLE_LOOKUP_OFFSET (BOOTROM_FUNC_TABLE_OFFSET + BOOTROM_WELL_KNOWN_PTR_SIZE) + + +// https://github.com/raspberrypi/pico-sdk +// src/common/boot_picoboot_headers/include/boot/picoboot_constants.h + +// values 0-7 are secure/non-secure +#define REBOOT2_FLAG_REBOOT_TYPE_NORMAL 0x0 // param0 = diagnostic partition +#define REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL 0x2 // param0 = bootsel_flags, param1 = gpio_config +#define REBOOT2_FLAG_REBOOT_TYPE_RAM_IMAGE 0x3 // param0 = image_base, param1 = image_end +#define REBOOT2_FLAG_REBOOT_TYPE_FLASH_UPDATE 0x4 // param0 = update_base + +#define REBOOT2_FLAG_NO_RETURN_ON_SUCCESS 0x100 + +#define RT_FLAG_FUNC_ARM_SEC 0x0004 +#define RT_FLAG_FUNC_ARM_NONSEC 0x0010 +#define RT_FLAG_DATA 0x0040 + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/pico_bootrom/include/pico/bootrom.h + +#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8)) + +typedef void *(*rom_table_lookup_fn)(uint32_t code, uint32_t mask); + +__attribute__((always_inline)) +static void *rom_func_lookup_inline(uint32_t code) { + rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET); + if (pico_processor_state_is_nonsecure()) { + return rom_table_lookup(code, RT_FLAG_FUNC_ARM_NONSEC); + } else { + return rom_table_lookup(code, RT_FLAG_FUNC_ARM_SEC); + } +} + +__attribute__((always_inline)) +static void *rom_data_lookup_inline(uint32_t code) { + rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET); + return rom_table_lookup(code, RT_FLAG_DATA); +} + +typedef int (*rom_reboot_fn)(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1); + +__attribute__((always_inline)) +int rom_reboot(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1) { + rom_reboot_fn func = (rom_reboot_fn) rom_func_lookup_inline(ROM_FUNC_REBOOT); + return func(flags, delay_ms, p0, p1); +} + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/pico_bootrom/bootrom.c + +void reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) { + uint32_t flags = disable_interface_mask; + if (usb_activity_gpio_pin_mask) { + flags |= BOOTSEL_FLAG_GPIO_PIN_SPECIFIED; + // the parameter is actually the gpio number, but we only care if BOOTSEL_FLAG_GPIO_PIN_SPECIFIED + usb_activity_gpio_pin_mask = (uint32_t)__builtin_ctz(usb_activity_gpio_pin_mask); + } + rom_reboot(REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL | REBOOT2_FLAG_NO_RETURN_ON_SUCCESS, 10, flags, usb_activity_gpio_pin_mask); + __builtin_unreachable(); +} + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2350/hardware_regs/include/hardware/regs/qmi.h + +#define QMI_DIRECT_CSR_EN_BITS 0x00000001 +#define QMI_DIRECT_CSR_RXEMPTY_BITS 0x00010000 +#define QMI_DIRECT_CSR_TXFULL_BITS 0x00000400 +#define QMI_M1_WFMT_RESET 0x00001000 +#define QMI_M1_WCMD_RESET 0x0000a002 + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2350/hardware_regs/include/hardware/regs/io_qspi.h + +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS 0x00003000 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB 12 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW 0x2 +#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH 0x3 + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2350/hardware_structs/include/hardware/structs/io_qspi.h + +typedef struct { + io_rw_32 inte; // IO_QSPI_PROC0_INTE + io_rw_32 intf; // IO_QSPI_PROC0_INTF + io_ro_32 ints; // IO_QSPI_PROC0_INTS +} io_qspi_irq_ctrl_hw_t; + +typedef struct { + io_ro_32 status; // IO_QSPI_GPIO_QSPI_SCLK_STATUS + io_rw_32 ctrl; // IO_QSPI_GPIO_QSPI_SCLK_CTRL +} io_qspi_status_ctrl_hw_t; + +typedef struct { + io_ro_32 usbphy_dp_status; // IO_QSPI_USBPHY_DP_STATUS + io_rw_32 usbphy_dp_ctrl; // IO_QSPI_USBPHY_DP_CTRL + io_ro_32 usbphy_dm_status; // IO_QSPI_USBPHY_DM_STATUS + io_rw_32 usbphy_dm_ctrl; // IO_QSPI_USBPHY_DM_CTRL + io_qspi_status_ctrl_hw_t io[6]; + uint32_t _pad0[112]; + io_ro_32 irqsummary_proc0_secure; // IO_QSPI_IRQSUMMARY_PROC0_SECURE + io_ro_32 irqsummary_proc0_nonsecure; // IO_QSPI_IRQSUMMARY_PROC0_NONSECURE + io_ro_32 irqsummary_proc1_secure; // IO_QSPI_IRQSUMMARY_PROC1_SECURE + io_ro_32 irqsummary_proc1_nonsecure; // IO_QSPI_IRQSUMMARY_PROC1_NONSECURE + io_ro_32 irqsummary_dormant_wake_secure; // IO_QSPI_IRQSUMMARY_DORMANT_WAKE_SECURE + io_ro_32 irqsummary_dormant_wake_nonsecure; // IO_QSPI_IRQSUMMARY_DORMANT_WAKE_NONSECURE + io_rw_32 intr; // IO_QSPI_INTR + + union { + struct { + io_qspi_irq_ctrl_hw_t proc0_irq_ctrl; + io_qspi_irq_ctrl_hw_t proc1_irq_ctrl; + io_qspi_irq_ctrl_hw_t dormant_wake_irq_ctrl; + }; + io_qspi_irq_ctrl_hw_t irq_ctrl[3]; + }; +} io_qspi_hw_t; + +#define io_qspi_hw ((io_qspi_hw_t *)IO_QSPI_BASE) + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2350/hardware_structs/include/hardware/structs/qmi.h + +typedef struct { + io_rw_32 timing; // QMI_M0_TIMING + io_rw_32 rfmt; // QMI_M0_RFMT + io_rw_32 rcmd; // QMI_M0_RCMD + io_rw_32 wfmt; // QMI_M0_WFMT + io_rw_32 wcmd; // QMI_M0_WCMD +} qmi_mem_hw_t; + +typedef struct { + io_rw_32 direct_csr; // QMI_DIRECT_CSR + io_wo_32 direct_tx; // QMI_DIRECT_TX + io_ro_32 direct_rx; // QMI_DIRECT_RX + qmi_mem_hw_t m[2]; + io_rw_32 atrans[8]; // QMI_ATRANS0 +} qmi_hw_t; + +#define qmi_hw ((qmi_hw_t *)XIP_QMI_BASE) + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h + +// Noop unless using XIP Cache-as-SRAM +// Non-noop version in src/rp2_common/hardware_xip_cache/xip_cache.c +static inline void xip_cache_clean_all(void) {} + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/hardware_flash/include/hardware/flash.h + +#define FLASH_PAGE_SIZE (1u << 8) +#define FLASH_SECTOR_SIZE (1u << 12) +#define FLASH_BLOCK_SIZE (1u << 16) + + +// https://github.com/raspberrypi/pico-sdk +// src/rp2_common/hardware_flash/flash.c + +#define BOOT2_SIZE_WORDS 64 +#define FLASH_BLOCK_ERASE_CMD 0xd8 + +static uint32_t boot2_copyout[BOOT2_SIZE_WORDS]; +static bool boot2_copyout_valid = false; + +static ram_func void flash_init_boot2_copyout(void) { + if (boot2_copyout_valid) + return; + for (int i = 0; i < BOOT2_SIZE_WORDS; ++i) + boot2_copyout[i] = ((uint32_t *)BOOTRAM_BASE)[i]; + __compiler_memory_barrier(); + boot2_copyout_valid = true; +} + +static ram_func void flash_enable_xip_via_boot2(void) { + ((void (*)(void))((intptr_t)boot2_copyout+1))(); +} + +// This is a static symbol because the layout of FLASH_DEVINFO is liable to change from device to +// device, so fields must have getters/setters. +static io_rw_16 * ram_func flash_devinfo_ptr(void) { + // Note the lookup returns a pointer to a 32-bit pointer literal in the ROM + io_rw_16 **p = (io_rw_16 **) rom_data_lookup_inline(ROM_DATA_FLASH_DEVINFO16_PTR); + return *p; +} + +// This is a RAM function because may be called during flash programming to enable save/restore of +// QMI window 1 registers on RP2350: +uint8_t ram_func flash_devinfo_get_cs_size(uint8_t cs) { + io_ro_16 *devinfo = (io_ro_16 *) flash_devinfo_ptr(); + if (cs == 0u) { + return (uint8_t) ( + (*devinfo & OTP_DATA_FLASH_DEVINFO_CS0_SIZE_BITS) >> OTP_DATA_FLASH_DEVINFO_CS0_SIZE_LSB + ); + } else { + return (uint8_t) ( + (*devinfo & OTP_DATA_FLASH_DEVINFO_CS1_SIZE_BITS) >> OTP_DATA_FLASH_DEVINFO_CS1_SIZE_LSB + ); + } +} + +// This is specifically for saving/restoring the registers modified by RP2350 +// flash_exit_xip() ROM func, not the entirety of the QMI window state. +typedef struct flash_rp2350_qmi_save_state { + uint32_t timing; + uint32_t rcmd; + uint32_t rfmt; +} flash_rp2350_qmi_save_state_t; + +static ram_func void flash_rp2350_save_qmi_cs1(flash_rp2350_qmi_save_state_t *state) { + state->timing = qmi_hw->m[1].timing; + state->rcmd = qmi_hw->m[1].rcmd; + state->rfmt = qmi_hw->m[1].rfmt; +} + +static ram_func void flash_rp2350_restore_qmi_cs1(const flash_rp2350_qmi_save_state_t *state) { + if (flash_devinfo_get_cs_size(1) == 0) { + // Case 1: The RP2350 ROM sets QMI to a clean (03h read) configuration + // during flash_exit_xip(), even though when CS1 is not enabled via + // FLASH_DEVINFO it does not issue an XIP exit sequence to CS1. In + // this case, restore the original register config for CS1 as it is + // still the correct config. + qmi_hw->m[1].timing = state->timing; + qmi_hw->m[1].rcmd = state->rcmd; + qmi_hw->m[1].rfmt = state->rfmt; + } else { + // Case 2: If RAM is attached to CS1, and the ROM has issued an XIP + // exit sequence to it, then the ROM re-initialisation of the QMI + // registers has actually not gone far enough. The old XIP write mode + // is no longer valid when the QSPI RAM is returned to a serial + // command state. Restore the default 02h serial write command config. + qmi_hw->m[1].wfmt = QMI_M1_WFMT_RESET; + qmi_hw->m[1].wcmd = QMI_M1_WCMD_RESET; + } +} + +void ram_func flash_cs_force(bool high) { + uint32_t field_val = high ? + IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH : + IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW; + hw_write_masked(&io_qspi_hw->io[1].ctrl, + field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS + ); +} + +// Adapted from flash_range_program() +void ram_func flash_range_write(uint32_t offset, const uint8_t *data, size_t count) { + flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); + flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); + flash_range_program_fn flash_range_program_func = (flash_range_program_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_PROGRAM); + flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); + flash_init_boot2_copyout(); + xip_cache_clean_all(); + flash_rp2350_qmi_save_state_t qmi_save; + flash_rp2350_save_qmi_cs1(&qmi_save); + + __compiler_memory_barrier(); + + flash_connect_internal_func(); + flash_exit_xip_func(); + flash_range_program_func(offset, data, count); + flash_flush_cache_func(); // Note this is needed to remove CSn IO force as well as cache flushing + flash_enable_xip_via_boot2(); + flash_rp2350_restore_qmi_cs1(&qmi_save); +} + +// Adapted from flash_range_erase() +void ram_func flash_erase_blocks(uint32_t offset, size_t count) { + flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); + flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); + flash_range_erase_fn flash_range_erase_func = (flash_range_erase_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_ERASE); + flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); + flash_init_boot2_copyout(); + // Commit any pending writes to external RAM, to avoid losing them in the subsequent flush: + xip_cache_clean_all(); + flash_rp2350_qmi_save_state_t qmi_save; + flash_rp2350_save_qmi_cs1(&qmi_save); + + // No flash accesses after this point + __compiler_memory_barrier(); + + flash_connect_internal_func(); + flash_exit_xip_func(); + flash_range_erase_func(offset, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD); + flash_flush_cache_func(); // Note this is needed to remove CSn IO force as well as cache flushing + flash_enable_xip_via_boot2(); + flash_rp2350_restore_qmi_cs1(&qmi_save); +} + +void ram_func flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) { + flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); + flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); + flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); + flash_init_boot2_copyout(); + xip_cache_clean_all(); + + flash_rp2350_qmi_save_state_t qmi_save; + flash_rp2350_save_qmi_cs1(&qmi_save); + + __compiler_memory_barrier(); + flash_connect_internal_func(); + flash_exit_xip_func(); + + flash_cs_force(0); + size_t tx_remaining = count; + size_t rx_remaining = count; + + // QMI version -- no need to bound FIFO contents as QMI stalls on full DIRECT_RX. + hw_set_bits(&qmi_hw->direct_csr, QMI_DIRECT_CSR_EN_BITS); + while (tx_remaining || rx_remaining) { + uint32_t flags = qmi_hw->direct_csr; + bool can_put = !(flags & QMI_DIRECT_CSR_TXFULL_BITS); + bool can_get = !(flags & QMI_DIRECT_CSR_RXEMPTY_BITS); + if (can_put && tx_remaining) { + qmi_hw->direct_tx = *txbuf++; + --tx_remaining; + } + if (can_get && rx_remaining) { + *rxbuf++ = (uint8_t)qmi_hw->direct_rx; + --rx_remaining; + } + } + hw_clear_bits(&qmi_hw->direct_csr, QMI_DIRECT_CSR_EN_BITS); + + flash_cs_force(1); + + flash_flush_cache_func(); + flash_enable_xip_via_boot2(); + flash_rp2350_restore_qmi_cs1(&qmi_save); +} diff --git a/machine/board_arduino_mega2560.go b/machine/board_arduino_mega2560.go index 2e4aefd..898bcce 100644 --- a/machine/board_arduino_mega2560.go +++ b/machine/board_arduino_mega2560.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/interrupt" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/interrupt" ) // Return the current CPU frequency in hertz. diff --git a/machine/board_atsame54-xpro.go b/machine/board_atsame54-xpro.go index ae1086d..a19f18f 100644 --- a/machine/board_atsame54-xpro.go +++ b/machine/board_atsame54-xpro.go @@ -3,7 +3,7 @@ package machine import ( - "device/sam" + "github.com/goplus/emb/device/sam" ) // Definition for compatibility, but not used diff --git a/machine/board_bluepill.go b/machine/board_bluepill.go index 83f527d..e97d8b5 100644 --- a/machine/board_bluepill.go +++ b/machine/board_bluepill.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) // Pins printed on the silkscreen diff --git a/machine/board_feather-m4-can.go b/machine/board_feather-m4-can.go index 6a39506..899351a 100644 --- a/machine/board_feather-m4-can.go +++ b/machine/board_feather-m4-can.go @@ -3,7 +3,7 @@ package machine import ( - "device/sam" + "github.com/goplus/emb/device/sam" ) // used to reset into bootloader diff --git a/machine/board_feather-stm32f405.go b/machine/board_feather-stm32f405.go index 4a184ba..4c9577f 100644 --- a/machine/board_feather-stm32f405.go +++ b/machine/board_feather-stm32f405.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_gnse.go b/machine/board_gnse.go index 8e78b43..7d34396 100644 --- a/machine/board_gnse.go +++ b/machine/board_gnse.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_hifive1b_baremetal.go b/machine/board_hifive1b_baremetal.go index f621d3b..d0e3992 100644 --- a/machine/board_hifive1b_baremetal.go +++ b/machine/board_hifive1b_baremetal.go @@ -2,7 +2,7 @@ package machine -import "device/sifive" +import "github.com/goplus/emb/device/sifive" // SPI on the HiFive1. var ( diff --git a/machine/board_lgt92.go b/machine/board_lgt92.go index 71b0508..f14f8de 100644 --- a/machine/board_lgt92.go +++ b/machine/board_lgt92.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_lorae5.go b/machine/board_lorae5.go index 18b5d8e..076ca6f 100644 --- a/machine/board_lorae5.go +++ b/machine/board_lorae5.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_maixbit_baremetal.go b/machine/board_maixbit_baremetal.go index f5a7e8d..fdbc470 100644 --- a/machine/board_maixbit_baremetal.go +++ b/machine/board_maixbit_baremetal.go @@ -2,7 +2,7 @@ package machine -import "device/kendryte" +import "github.com/goplus/emb/device/kendryte" // SPI on the MAix Bit. var ( diff --git a/machine/board_mksnanov3.go b/machine/board_mksnanov3.go index 35fef68..b9e22b1 100644 --- a/machine/board_mksnanov3.go +++ b/machine/board_mksnanov3.go @@ -6,8 +6,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) // LED is also wired to the SD card card detect (CD) pin. diff --git a/machine/board_nucleof103rb.go b/machine/board_nucleof103rb.go index af7a99e..7359c99 100644 --- a/machine/board_nucleof103rb.go +++ b/machine/board_nucleof103rb.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_nucleof722ze.go b/machine/board_nucleof722ze.go index c9a0b01..5e7ca8f 100644 --- a/machine/board_nucleof722ze.go +++ b/machine/board_nucleof722ze.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_nucleol031k6.go b/machine/board_nucleol031k6.go index aea92d8..8dc0116 100644 --- a/machine/board_nucleol031k6.go +++ b/machine/board_nucleol031k6.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_nucleol432kc.go b/machine/board_nucleol432kc.go index 3d09b6c..7b316ec 100644 --- a/machine/board_nucleol432kc.go +++ b/machine/board_nucleol432kc.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_nucleol476rg.go b/machine/board_nucleol476rg.go index 0a173af..d687301 100644 --- a/machine/board_nucleol476rg.go +++ b/machine/board_nucleol476rg.go @@ -6,8 +6,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_nucleol552ze.go b/machine/board_nucleol552ze.go index 6a13d9f..9bab259 100644 --- a/machine/board_nucleol552ze.go +++ b/machine/board_nucleol552ze.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_nucleowl55jc.go b/machine/board_nucleowl55jc.go index a8e88dd..453bab8 100644 --- a/machine/board_nucleowl55jc.go +++ b/machine/board_nucleowl55jc.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_stm32f469disco.go b/machine/board_stm32f469disco.go index 8fb5cde..dab48a3 100644 --- a/machine/board_stm32f469disco.go +++ b/machine/board_stm32f469disco.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_stm32f4disco.go b/machine/board_stm32f4disco.go index d048fca..e6a97aa 100644 --- a/machine/board_stm32f4disco.go +++ b/machine/board_stm32f4disco.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_swan.go b/machine/board_swan.go index 7502dd6..28e2e6d 100644 --- a/machine/board_swan.go +++ b/machine/board_swan.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) const ( diff --git a/machine/board_teensy40.go b/machine/board_teensy40.go index 22529a8..3ba024c 100644 --- a/machine/board_teensy40.go +++ b/machine/board_teensy40.go @@ -3,8 +3,8 @@ package machine import ( - "device/nxp" - "runtime/interrupt" + "github.com/goplus/emb/device/nxp" + "github.com/goplus/emb/runtime/interrupt" ) // Digital pins diff --git a/machine/board_teensy41.go b/machine/board_teensy41.go index 9f168c5..289ae79 100644 --- a/machine/board_teensy41.go +++ b/machine/board_teensy41.go @@ -3,8 +3,8 @@ package machine import ( - "device/nxp" - "runtime/interrupt" + "github.com/goplus/emb/device/nxp" + "github.com/goplus/emb/runtime/interrupt" ) // Digital pins diff --git a/machine/buffer.go b/machine/buffer.go index ff79157..1251197 100644 --- a/machine/buffer.go +++ b/machine/buffer.go @@ -1,7 +1,7 @@ package machine import ( - "github.com/goplus/lib/emb/runtime/volatile" + "github.com/goplus/emb/runtime/volatile" ) // RingBuffer is ring buffer implementation inspired by post at diff --git a/machine/machine_atmega.go b/machine/machine_atmega.go index 7a59e5e..4eefe34 100644 --- a/machine/machine_atmega.go +++ b/machine/machine_atmega.go @@ -3,9 +3,9 @@ package machine import ( - "device/avr" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_atmega1280.go b/machine/machine_atmega1280.go index 3973f75..f0b503c 100644 --- a/machine/machine_atmega1280.go +++ b/machine/machine_atmega1280.go @@ -3,9 +3,9 @@ package machine import ( - "device/avr" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) const irq_USART0_RX = avr.IRQ_USART0_RX diff --git a/machine/machine_atmega1284p.go b/machine/machine_atmega1284p.go index db8fd65..ff4444e 100644 --- a/machine/machine_atmega1284p.go +++ b/machine/machine_atmega1284p.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" ) const irq_USART0_RX = avr.IRQ_USART0_RX diff --git a/machine/machine_atmega2560.go b/machine/machine_atmega2560.go index ede862a..3275dec 100644 --- a/machine/machine_atmega2560.go +++ b/machine/machine_atmega2560.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" ) const irq_USART0_RX = avr.IRQ_USART0_RX diff --git a/machine/machine_atmega328.go b/machine/machine_atmega328.go index c354ccb..093f06a 100644 --- a/machine/machine_atmega328.go +++ b/machine/machine_atmega328.go @@ -3,9 +3,9 @@ package machine import ( - "device/avr" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) // PWM is one PWM peripheral, which consists of a counter and two output diff --git a/machine/machine_atmega328p.go b/machine/machine_atmega328p.go index 5bacfb8..d208874 100644 --- a/machine/machine_atmega328p.go +++ b/machine/machine_atmega328p.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" ) const irq_USART0_RX = avr.IRQ_USART_RX diff --git a/machine/machine_atmega328pb.go b/machine/machine_atmega328pb.go index 935c581..9c2de72 100644 --- a/machine/machine_atmega328pb.go +++ b/machine/machine_atmega328pb.go @@ -3,9 +3,9 @@ package machine import ( - "device/avr" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) const irq_USART0_RX = avr.IRQ_USART0_RX diff --git a/machine/machine_atmega32u4.go b/machine/machine_atmega32u4.go index 8b3faab..38f1c27 100644 --- a/machine/machine_atmega32u4.go +++ b/machine/machine_atmega32u4.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" ) const ( diff --git a/machine/machine_atsam.go b/machine/machine_atsam.go index ad2f073..8efe03e 100644 --- a/machine/machine_atsam.go +++ b/machine/machine_atsam.go @@ -3,7 +3,7 @@ package machine import ( - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_atsamd21.go b/machine/machine_atsamd21.go index b46dcef..eeda152 100644 --- a/machine/machine_atsamd21.go +++ b/machine/machine_atsamd21.go @@ -7,11 +7,11 @@ package machine import ( - "device/arm" - "device/sam" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/sam" "errors" - "internal/binary" - "runtime/interrupt" + "github.com/goplus/emb/internal/binary" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_atsamd21_usb.go b/machine/machine_atsamd21_usb.go index 7b9d2e1..16b9f75 100644 --- a/machine/machine_atsamd21_usb.go +++ b/machine/machine_atsamd21_usb.go @@ -3,9 +3,9 @@ package machine import ( - "device/sam" - "machine/usb" - "runtime/interrupt" + "github.com/goplus/emb/device/sam" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_atsamd21e18.go b/machine/machine_atsamd21e18.go index 85d6853..13d2950 100644 --- a/machine/machine_atsamd21e18.go +++ b/machine/machine_atsamd21e18.go @@ -7,8 +7,8 @@ package machine import ( - "device/sam" - "runtime/interrupt" + "github.com/goplus/emb/device/sam" + "github.com/goplus/emb/runtime/interrupt" ) var ( diff --git a/machine/machine_atsamd21g18.go b/machine/machine_atsamd21g18.go index 9e845cf..2cdaa8b 100644 --- a/machine/machine_atsamd21g18.go +++ b/machine/machine_atsamd21g18.go @@ -7,8 +7,8 @@ package machine import ( - "device/sam" - "runtime/interrupt" + "github.com/goplus/emb/device/sam" + "github.com/goplus/emb/runtime/interrupt" ) var ( diff --git a/machine/machine_atsamd51.go b/machine/machine_atsamd51.go index 20dc41b..9635efe 100644 --- a/machine/machine_atsamd51.go +++ b/machine/machine_atsamd51.go @@ -7,11 +7,11 @@ package machine import ( - "device/arm" - "device/sam" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/sam" "errors" - "internal/binary" - "runtime/interrupt" + "github.com/goplus/emb/internal/binary" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_atsamd51_usb.go b/machine/machine_atsamd51_usb.go index a95089f..8799bc3 100644 --- a/machine/machine_atsamd51_usb.go +++ b/machine/machine_atsamd51_usb.go @@ -3,9 +3,9 @@ package machine import ( - "device/sam" - "machine/usb" - "runtime/interrupt" + "github.com/goplus/emb/device/sam" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_atsamd51g19.go b/machine/machine_atsamd51g19.go index f223f6e..88da5e4 100644 --- a/machine/machine_atsamd51g19.go +++ b/machine/machine_atsamd51g19.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00030000 diff --git a/machine/machine_atsamd51j19.go b/machine/machine_atsamd51j19.go index 640e1ef..d6c07e8 100644 --- a/machine/machine_atsamd51j19.go +++ b/machine/machine_atsamd51j19.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00030000 diff --git a/machine/machine_atsamd51j20.go b/machine/machine_atsamd51j20.go index d582278..3a196f3 100644 --- a/machine/machine_atsamd51j20.go +++ b/machine/machine_atsamd51j20.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00040000 diff --git a/machine/machine_atsamd51p19.go b/machine/machine_atsamd51p19.go index bcd66a9..28032f9 100644 --- a/machine/machine_atsamd51p19.go +++ b/machine/machine_atsamd51p19.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00030000 diff --git a/machine/machine_atsamd51p20.go b/machine/machine_atsamd51p20.go index 40e435f..e935bb5 100644 --- a/machine/machine_atsamd51p20.go +++ b/machine/machine_atsamd51p20.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00040000 diff --git a/machine/machine_atsame51j19.go b/machine/machine_atsame51j19.go index 29ea411..54840fa 100644 --- a/machine/machine_atsame51j19.go +++ b/machine/machine_atsame51j19.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00030000 diff --git a/machine/machine_atsame54p20.go b/machine/machine_atsame54p20.go index d7cc31f..b675f8c 100644 --- a/machine/machine_atsame54p20.go +++ b/machine/machine_atsame54p20.go @@ -6,7 +6,7 @@ // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf package machine -import "device/sam" +import "github.com/goplus/emb/device/sam" const HSRAM_SIZE = 0x00040000 diff --git a/machine/machine_atsame5x_can.go b/machine/machine_atsame5x_can.go index bf38cd8..61e4900 100644 --- a/machine/machine_atsame5x_can.go +++ b/machine/machine_atsame5x_can.go @@ -3,9 +3,9 @@ package machine import ( - "device/sam" + "github.com/goplus/emb/device/sam" "errors" - "runtime/interrupt" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_attiny1616.go b/machine/machine_attiny1616.go index 55007ab..db8bf35 100644 --- a/machine/machine_attiny1616.go +++ b/machine/machine_attiny1616.go @@ -3,7 +3,7 @@ package machine import ( - "device/avr" + "github.com/goplus/emb/device/avr" ) const ( diff --git a/machine/machine_attiny85.go b/machine/machine_attiny85.go index 33424c6..11b85e2 100644 --- a/machine/machine_attiny85.go +++ b/machine/machine_attiny85.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" ) const ( diff --git a/machine/machine_avr.go b/machine/machine_avr.go index 75252c3..e2f4467 100644 --- a/machine/machine_avr.go +++ b/machine/machine_avr.go @@ -3,9 +3,10 @@ package machine import ( - "device/avr" - "runtime/volatile" "unsafe" + + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" ) const deviceName = avr.DEVICE @@ -144,7 +145,9 @@ func (a ADC) Get() uint16 { } // linked from runtime.adjustMonotonicTimer -func adjustMonotonicTimer() +// TODO(zzy): implement at runtime +func adjustMonotonicTimer() {} +// TODO(zzy): implement at runtime // linked from runtime.initMonotonicTimer -func initMonotonicTimer() +func initMonotonicTimer() {} diff --git a/machine/machine_avrtiny.go b/machine/machine_avrtiny.go index 78168f4..eef5ef5 100644 --- a/machine/machine_avrtiny.go +++ b/machine/machine_avrtiny.go @@ -3,8 +3,8 @@ package machine import ( - "device/avr" - "runtime/volatile" + "github.com/goplus/emb/device/avr" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_cortexm.go b/machine/machine_cortexm.go index 0f8f264..6f25b7c 100644 --- a/machine/machine_cortexm.go +++ b/machine/machine_cortexm.go @@ -2,7 +2,7 @@ package machine -import "device/arm" +import "github.com/goplus/emb/device/arm" // CPUReset performs a hard system reset. func CPUReset() { diff --git a/machine/machine_esp32.go b/machine/machine_esp32.go index 237a129..b4f0f06 100644 --- a/machine/machine_esp32.go +++ b/machine/machine_esp32.go @@ -3,9 +3,9 @@ package machine import ( - "device/esp" + "github.com/goplus/emb/device/esp" "errors" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_esp32_i2c.go b/machine/machine_esp32_i2c.go index 746e722..d92a06c 100644 --- a/machine/machine_esp32_i2c.go +++ b/machine/machine_esp32_i2c.go @@ -3,8 +3,8 @@ package machine import ( - "device/esp" - "runtime/volatile" + "github.com/goplus/emb/device/esp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_esp32c3.go b/machine/machine_esp32c3.go index 727fcc1..eb3e8a0 100644 --- a/machine/machine_esp32c3.go +++ b/machine/machine_esp32c3.go @@ -3,11 +3,11 @@ package machine import ( - "device/esp" - "device/riscv" + "github.com/goplus/emb/device/esp" + "github.com/goplus/emb/device/riscv" "errors" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "sync" "unsafe" ) diff --git a/machine/machine_esp32c3_i2c.go b/machine/machine_esp32c3_i2c.go index dd334b0..7b2692b 100644 --- a/machine/machine_esp32c3_i2c.go +++ b/machine/machine_esp32c3_i2c.go @@ -3,8 +3,8 @@ package machine import ( - "device/esp" - "runtime/volatile" + "github.com/goplus/emb/device/esp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_esp32c3_spi.go b/machine/machine_esp32c3_spi.go index aec3ca7..f65fff5 100644 --- a/machine/machine_esp32c3_spi.go +++ b/machine/machine_esp32c3_spi.go @@ -9,9 +9,9 @@ package machine // https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-reference/peripherals/spi_master.html import ( - "device/esp" + "github.com/goplus/emb/device/esp" "errors" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_esp8266.go b/machine/machine_esp8266.go index 4edd4a5..b7505fe 100644 --- a/machine/machine_esp8266.go +++ b/machine/machine_esp8266.go @@ -3,8 +3,8 @@ package machine import ( - "device/esp" - "runtime/volatile" + "github.com/goplus/emb/device/esp" + "github.com/goplus/emb/runtime/volatile" ) const deviceName = esp.Device diff --git a/machine/machine_fe310.go b/machine/machine_fe310.go index 2f716d6..5e4162e 100644 --- a/machine/machine_fe310.go +++ b/machine/machine_fe310.go @@ -3,8 +3,8 @@ package machine import ( - "device/sifive" - "runtime/interrupt" + "github.com/goplus/emb/device/sifive" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_gameboyadvance.go b/machine/machine_gameboyadvance.go index a5c0c06..70bcbff 100644 --- a/machine/machine_gameboyadvance.go +++ b/machine/machine_gameboyadvance.go @@ -3,10 +3,10 @@ package machine import ( - "device/gba" + "github.com/goplus/emb/device/gba" "image/color" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_k210.go b/machine/machine_k210.go index d83576a..4d15d7b 100644 --- a/machine/machine_k210.go +++ b/machine/machine_k210.go @@ -3,10 +3,10 @@ package machine import ( - "device/kendryte" - "device/riscv" + "github.com/goplus/emb/device/kendryte" + "github.com/goplus/emb/device/riscv" "errors" - "runtime/interrupt" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_mimxrt1062.go b/machine/machine_mimxrt1062.go index 74d01c7..3bf1cab 100644 --- a/machine/machine_mimxrt1062.go +++ b/machine/machine_mimxrt1062.go @@ -3,10 +3,10 @@ package machine import ( - "device/nxp" + "github.com/goplus/emb/device/nxp" "math/bits" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) // Peripheral abstraction layer for the MIMXRT1062 diff --git a/machine/machine_mimxrt1062_i2c.go b/machine/machine_mimxrt1062_i2c.go index f3c4636..d73cedb 100644 --- a/machine/machine_mimxrt1062_i2c.go +++ b/machine/machine_mimxrt1062_i2c.go @@ -5,7 +5,7 @@ package machine // I2C peripheral abstraction layer for the MIMXRT1062 import ( - "device/nxp" + "github.com/goplus/emb/device/nxp" ) // I2CConfig is used to store config info for I2C. diff --git a/machine/machine_mimxrt1062_spi.go b/machine/machine_mimxrt1062_spi.go index d982eea..ce1cd0a 100644 --- a/machine/machine_mimxrt1062_spi.go +++ b/machine/machine_mimxrt1062_spi.go @@ -5,7 +5,7 @@ package machine // SPI peripheral abstraction layer for the MIMXRT1062 import ( - "device/nxp" + "github.com/goplus/emb/device/nxp" "errors" "unsafe" ) diff --git a/machine/machine_mimxrt1062_uart.go b/machine/machine_mimxrt1062_uart.go index 6265b85..0a9ee0c 100644 --- a/machine/machine_mimxrt1062_uart.go +++ b/machine/machine_mimxrt1062_uart.go @@ -3,9 +3,9 @@ package machine import ( - "device/nxp" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/nxp" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) // UART peripheral abstraction layer for the MIMXRT1062 diff --git a/machine/machine_nrf.go b/machine/machine_nrf.go index d6d6349..efa71a4 100644 --- a/machine/machine_nrf.go +++ b/machine/machine_nrf.go @@ -3,9 +3,9 @@ package machine import ( - "device/nrf" - "internal/binary" - "runtime/interrupt" + "github.com/goplus/emb/device/nrf" + "github.com/goplus/emb/internal/binary" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_nrf51.go b/machine/machine_nrf51.go index d627d63..84cf44a 100644 --- a/machine/machine_nrf51.go +++ b/machine/machine_nrf51.go @@ -3,7 +3,7 @@ package machine import ( - "device/nrf" + "github.com/goplus/emb/device/nrf" ) const eraseBlockSizeValue = 1024 diff --git a/machine/machine_nrf52.go b/machine/machine_nrf52.go index 71c5343..1808f23 100644 --- a/machine/machine_nrf52.go +++ b/machine/machine_nrf52.go @@ -3,7 +3,7 @@ package machine import ( - "device/nrf" + "github.com/goplus/emb/device/nrf" ) // Hardware pins diff --git a/machine/machine_nrf52833.go b/machine/machine_nrf52833.go index 60558eb..468ac02 100644 --- a/machine/machine_nrf52833.go +++ b/machine/machine_nrf52833.go @@ -3,7 +3,7 @@ package machine import ( - "device/nrf" + "github.com/goplus/emb/device/nrf" ) // Hardware pins diff --git a/machine/machine_nrf52840.go b/machine/machine_nrf52840.go index 21a4367..63cc5de 100644 --- a/machine/machine_nrf52840.go +++ b/machine/machine_nrf52840.go @@ -3,7 +3,7 @@ package machine import ( - "device/nrf" + "github.com/goplus/emb/device/nrf" "errors" "unsafe" ) diff --git a/machine/machine_nrf52840_enter_bootloader.go b/machine/machine_nrf52840_enter_bootloader.go index d24152a..0ffb097 100644 --- a/machine/machine_nrf52840_enter_bootloader.go +++ b/machine/machine_nrf52840_enter_bootloader.go @@ -3,8 +3,8 @@ package machine import ( - "device/arm" - "device/nrf" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/nrf" ) const ( diff --git a/machine/machine_nrf52840_usb.go b/machine/machine_nrf52840_usb.go index 1fa4694..87a4f8c 100644 --- a/machine/machine_nrf52840_usb.go +++ b/machine/machine_nrf52840_usb.go @@ -3,11 +3,11 @@ package machine import ( - "device/arm" - "device/nrf" - "machine/usb" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/nrf" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_nrf528xx.go b/machine/machine_nrf528xx.go index f8937ae..d6fab54 100644 --- a/machine/machine_nrf528xx.go +++ b/machine/machine_nrf528xx.go @@ -3,7 +3,7 @@ package machine import ( - "device/nrf" + "github.com/goplus/emb/device/nrf" "unsafe" ) diff --git a/machine/machine_nrf52xxx.go b/machine/machine_nrf52xxx.go index a582a7a..2dd37b6 100644 --- a/machine/machine_nrf52xxx.go +++ b/machine/machine_nrf52xxx.go @@ -3,8 +3,8 @@ package machine import ( - "device/nrf" - "runtime/volatile" + "github.com/goplus/emb/device/nrf" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_nrf5x.go b/machine/machine_nrf5x.go index 4c73103..ec337d3 100644 --- a/machine/machine_nrf5x.go +++ b/machine/machine_nrf5x.go @@ -2,7 +2,7 @@ package machine -import "device/nrf" +import "github.com/goplus/emb/device/nrf" // I2C on the NRF51 and NRF52. type I2C struct { diff --git a/machine/machine_nrf_sd.go b/machine/machine_nrf_sd.go index b816e62..2015001 100644 --- a/machine/machine_nrf_sd.go +++ b/machine/machine_nrf_sd.go @@ -3,8 +3,8 @@ package machine import ( - "device/arm" - "device/nrf" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/nrf" "errors" ) diff --git a/machine/machine_nxpmk66f18.go b/machine/machine_nxpmk66f18.go index 5dd54d9..64e9cf1 100644 --- a/machine/machine_nxpmk66f18.go +++ b/machine/machine_nxpmk66f18.go @@ -32,8 +32,8 @@ package machine import ( - "device/nxp" - "runtime/volatile" + "github.com/goplus/emb/device/nxp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_nxpmk66f18_uart.go b/machine/machine_nxpmk66f18_uart.go index a14d18f..a295fbb 100644 --- a/machine/machine_nxpmk66f18_uart.go +++ b/machine/machine_nxpmk66f18_uart.go @@ -32,11 +32,11 @@ package machine import ( - "device/arm" - "device/nxp" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/nxp" "errors" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" _ "unsafe" // for go:linkname ) diff --git a/machine/machine_rp2.go b/machine/machine_rp2.go index 9afefa5..a873871 100644 --- a/machine/machine_rp2.go +++ b/machine/machine_rp2.go @@ -3,9 +3,9 @@ package machine import ( - "device/rp" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2040_rom.go b/machine/machine_rp2040_rom.go index 5541e2a..a6f2c42 100644 --- a/machine/machine_rp2040_rom.go +++ b/machine/machine_rp2040_rom.go @@ -1,205 +1,32 @@ -//go:build tinygo && rp2040 +//go:build llgo && rp2040 package machine import ( - "runtime/interrupt" "unsafe" -) - -/* -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/pico_bootrom/include/pico/bootrom.h - -#define ROM_FUNC_POPCOUNT32 ROM_TABLE_CODE('P', '3') -#define ROM_FUNC_REVERSE32 ROM_TABLE_CODE('R', '3') -#define ROM_FUNC_CLZ32 ROM_TABLE_CODE('L', '3') -#define ROM_FUNC_CTZ32 ROM_TABLE_CODE('T', '3') -#define ROM_FUNC_MEMSET ROM_TABLE_CODE('M', 'S') -#define ROM_FUNC_MEMSET4 ROM_TABLE_CODE('S', '4') -#define ROM_FUNC_MEMCPY ROM_TABLE_CODE('M', 'C') -#define ROM_FUNC_MEMCPY44 ROM_TABLE_CODE('C', '4') -#define ROM_FUNC_RESET_USB_BOOT ROM_TABLE_CODE('U', 'B') -#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F') -#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X') -#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E') -#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P') -#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C') -#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X') - -#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8)) - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned long uint32_t; -typedef unsigned long size_t; -typedef unsigned long uintptr_t; - -#define false 0 -#define true 1 -typedef int bool; - -#define ram_func __attribute__((section(".ramfuncs"),noinline)) - -typedef void *(*rom_table_lookup_fn)(uint16_t *table, uint32_t code); -typedef void __attribute__((noreturn)) (*rom_reset_usb_boot_fn)(uint32_t, uint32_t); -typedef void (*flash_init_boot2_copyout_fn)(void); -typedef void (*flash_enable_xip_via_boot2_fn)(void); -typedef void (*flash_exit_xip_fn)(void); -typedef void (*flash_flush_cache_fn)(void); -typedef void (*flash_connect_internal_fn)(void); -typedef void (*flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint16_t); -typedef void (*flash_range_program_fn)(uint32_t, const uint8_t*, size_t); - -static inline __attribute__((always_inline)) void __compiler_memory_barrier(void) { - __asm__ volatile ("" : : : "memory"); -} - -#define rom_hword_as_ptr(rom_address) (void *)(uintptr_t)(*(uint16_t *)(uintptr_t)(rom_address)) - -void *rom_func_lookup(uint32_t code) { - rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) rom_hword_as_ptr(0x18); - uint16_t *func_table = (uint16_t *) rom_hword_as_ptr(0x14); - return rom_table_lookup(func_table, code); -} - -void reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) { - rom_reset_usb_boot_fn func = (rom_reset_usb_boot_fn) rom_func_lookup(ROM_FUNC_RESET_USB_BOOT); - func(usb_activity_gpio_pin_mask, disable_interface_mask); -} - -#define FLASH_BLOCK_ERASE_CMD 0xd8 - -#define FLASH_PAGE_SIZE (1u << 8) -#define FLASH_SECTOR_SIZE (1u << 12) -#define FLASH_BLOCK_SIZE (1u << 16) - -#define BOOT2_SIZE_WORDS 64 -#define XIP_BASE 0x10000000 - -static uint32_t boot2_copyout[BOOT2_SIZE_WORDS]; -static bool boot2_copyout_valid = false; - -static ram_func void flash_init_boot2_copyout() { - if (boot2_copyout_valid) - return; - for (int i = 0; i < BOOT2_SIZE_WORDS; ++i) - boot2_copyout[i] = ((uint32_t *)XIP_BASE)[i]; - __compiler_memory_barrier(); - boot2_copyout_valid = true; -} - -static ram_func void flash_enable_xip_via_boot2() { - ((void (*)(void))boot2_copyout+1)(); -} - -#define IO_QSPI_BASE 0x40018000 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS 0x00000300 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_MSB 9 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB 8 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW 0x2 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH 0x3 - -#define XIP_SSI_BASE 0x18000000 -#define ssi_hw ((ssi_hw_t *)XIP_SSI_BASE) -#define SSI_SR_OFFSET 0x00000028 -#define SSI_DR0_OFFSET 0x00000060 -#define SSI_SR_TFNF_BITS 0x00000002 -#define SSI_SR_RFNE_BITS 0x00000008 - -void ram_func flash_cs_force(bool high) { - uint32_t field_val = high ? - IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH : - IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW; - // &ioqspi_hw->io[1].ctrl - uint32_t *addr = (uint32_t*)(IO_QSPI_BASE + (1 * 8) + 4); - - *addr = ((*addr) & !IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS) - | (field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB); - -} - -// See https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_flash/flash.c#L86 -void ram_func flash_range_write(uint32_t offset, const uint8_t *data, size_t count) -{ - flash_range_program_fn flash_range_program_func = (flash_range_program_fn) rom_func_lookup(ROM_FUNC_FLASH_RANGE_PROGRAM); - flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH); - flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP); - flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE); - - flash_init_boot2_copyout(); - - __compiler_memory_barrier(); - - flash_connect_internal_func(); - flash_exit_xip_func(); - - flash_range_program_func(offset, data, count); - flash_flush_cache_func(); - flash_enable_xip_via_boot2(); -} + "github.com/goplus/lib/c" + "github.com/goplus/emb/runtime/interrupt" +) -void ram_func flash_erase_blocks(uint32_t offset, size_t count) -{ - flash_range_erase_fn flash_range_erase_func = (flash_range_erase_fn) rom_func_lookup(ROM_FUNC_FLASH_RANGE_ERASE); - flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH); - flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP); - flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE); +const ( + LLGoFiles = "_wrap/machine_rp2040_rom.c" +) - flash_init_boot2_copyout(); +//go:linkname reset_usb_boot C.reset_usb_boot +func reset_usb_boot(c.Uint32T, c.Uint32T) - __compiler_memory_barrier(); +//go:linkname flash_do_cmd C.flash_do_cmd +func flash_do_cmd(*c.Uint8T, *c.Uint8T, c.SizeT) - flash_connect_internal_func(); - flash_exit_xip_func(); +//go:linkname flash_range_write C.flash_range_write +func flash_range_write(c.Uint32T, *c.Uint8T, c.SizeT) - flash_range_erase_func(offset, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD); - flash_flush_cache_func(); - flash_enable_xip_via_boot2(); -} - -void ram_func flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) { - flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn) rom_func_lookup(ROM_FUNC_CONNECT_INTERNAL_FLASH); - flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn) rom_func_lookup(ROM_FUNC_FLASH_EXIT_XIP); - flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn) rom_func_lookup(ROM_FUNC_FLASH_FLUSH_CACHE); - - flash_init_boot2_copyout(); - - __compiler_memory_barrier(); - - flash_connect_internal_func(); - flash_exit_xip_func(); - - flash_cs_force(0); - size_t tx_remaining = count; - size_t rx_remaining = count; - // We may be interrupted -- don't want FIFO to overflow if we're distracted. - const size_t max_in_flight = 16 - 2; - while (tx_remaining || rx_remaining) { - uint32_t flags = *(uint32_t*)(XIP_SSI_BASE + SSI_SR_OFFSET); - bool can_put = !!(flags & SSI_SR_TFNF_BITS); - bool can_get = !!(flags & SSI_SR_RFNE_BITS); - if (can_put && tx_remaining && rx_remaining - tx_remaining < max_in_flight) { - *(uint32_t*)(XIP_SSI_BASE + SSI_DR0_OFFSET) = *txbuf++; - --tx_remaining; - } - if (can_get && rx_remaining) { - *rxbuf++ = (uint8_t)*(uint32_t*)(XIP_SSI_BASE + SSI_DR0_OFFSET); - --rx_remaining; - } - } - flash_cs_force(1); - - flash_flush_cache_func(); - flash_enable_xip_via_boot2(); -} - -*/ -import "C" +//go:linkname flash_erase_blocks C.flash_erase_blocks +func flash_erase_blocks(c.Uint32T, c.SizeT) func enterBootloader() { - C.reset_usb_boot(0, 0) + reset_usb_boot(0, 0) } func doFlashCommand(tx []byte, rx []byte) error { @@ -207,19 +34,26 @@ func doFlashCommand(tx []byte, rx []byte) error { return errFlashInvalidWriteLength } - C.flash_do_cmd( - (*C.uint8_t)(unsafe.Pointer(&tx[0])), - (*C.uint8_t)(unsafe.Pointer(&rx[0])), - C.ulong(len(tx))) + // C.flash_do_cmd( + // (*C.uint8_t)(unsafe.Pointer(&tx[0])), + // (*C.uint8_t)(unsafe.Pointer(&rx[0])), + // C.ulong(len(tx))) + flash_do_cmd( + (*c.Uint8T)(unsafe.Pointer(&tx[0])), + (*c.Uint8T)(unsafe.Pointer(&rx[0])), + c.SizeT(len(tx)), + ) return nil } // Flash related code -const memoryStart = C.XIP_BASE // memory start for purpose of erase +// const memoryStart = C.XIP_BASE // memory start for purpose of erase +const XIP_BASE = 0x10000000 +const memoryStart = XIP_BASE // memory start for purpose of erase func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) { - if writeAddress(off)+uintptr(C.XIP_BASE) > FlashDataEnd() { + if writeAddress(off)+uintptr(XIP_BASE) > FlashDataEnd() { return 0, errFlashCannotWritePastEOF } @@ -232,23 +66,28 @@ func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) { address := writeAddress(off) padded := flashPad(p, int(f.WriteBlockSize())) - C.flash_range_write(C.uint32_t(address), - (*C.uint8_t)(unsafe.Pointer(&padded[0])), - C.ulong(len(padded))) + // C.flash_range_write(C.uint32_t(address), + // (*C.uint8_t)(unsafe.Pointer(&padded[0])), + // C.ulong(len(padded))) + flash_range_write( + c.Uint32T(address), + (*c.Uint8T)(unsafe.Pointer(&padded[0])), + c.SizeT(len(padded)), + ) return len(padded), nil } func (f flashBlockDevice) eraseBlocks(start, length int64) error { address := writeAddress(start * f.EraseBlockSize()) - if address+uintptr(C.XIP_BASE) > FlashDataEnd() { + if address+uintptr(XIP_BASE) > FlashDataEnd() { return errFlashCannotErasePastEOF } state := interrupt.Disable() defer interrupt.Restore(state) - C.flash_erase_blocks(C.uint32_t(address), C.ulong(length*f.EraseBlockSize())) - + // C.flash_erase_blocks(C.uint32_t(address), C.ulong(length*f.EraseBlockSize())) + flash_erase_blocks(c.Uint32T(address), c.SizeT(length*f.EraseBlockSize())) return nil } diff --git a/machine/machine_rp2040_rtc.go b/machine/machine_rp2040_rtc.go index 192e187..0864761 100644 --- a/machine/machine_rp2040_rtc.go +++ b/machine/machine_rp2040_rtc.go @@ -6,9 +6,9 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" "errors" - "runtime/interrupt" + "github.com/goplus/emb/runtime/interrupt" "unsafe" ) diff --git a/machine/machine_rp2040_usb.go b/machine/machine_rp2040_usb.go index 087e3bf..398db27 100644 --- a/machine/machine_rp2040_usb.go +++ b/machine/machine_rp2040_usb.go @@ -3,9 +3,9 @@ package machine import ( - "device/rp" - "machine/usb" - "runtime/interrupt" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/interrupt" ) // Configure the USB peripheral. The config is here for compatibility with the UART interface. diff --git a/machine/machine_rp2040_usb_fix_usb_device_enumeration.go b/machine/machine_rp2040_usb_fix_usb_device_enumeration.go index f027f94..f42ce58 100644 --- a/machine/machine_rp2040_usb_fix_usb_device_enumeration.go +++ b/machine/machine_rp2040_usb_fix_usb_device_enumeration.go @@ -3,8 +3,8 @@ package machine import ( - "device/arm" - "device/rp" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/rp" ) // https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/rp2040_usb_device_enumeration.c diff --git a/machine/machine_rp2350_rom.go b/machine/machine_rp2350_rom.go index 665464a..299e081 100644 --- a/machine/machine_rp2350_rom.go +++ b/machine/machine_rp2350_rom.go @@ -1,511 +1,32 @@ -//go:build tinygo && rp2350 +//go:build llgo && rp2350 package machine import ( - "runtime/interrupt" "unsafe" -) - -/* -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned long uint32_t; -typedef unsigned long size_t; -typedef unsigned long uintptr_t; -typedef long int intptr_t; - -typedef const volatile uint16_t io_ro_16; -typedef const volatile uint32_t io_ro_32; -typedef volatile uint16_t io_rw_16; -typedef volatile uint32_t io_rw_32; -typedef volatile uint32_t io_wo_32; - -#define false 0 -#define true 1 -typedef int bool; - -#define ram_func __attribute__((section(".ramfuncs"),noinline)) - -typedef void (*flash_exit_xip_fn)(void); -typedef void (*flash_flush_cache_fn)(void); -typedef void (*flash_connect_internal_fn)(void); -typedef void (*flash_range_erase_fn)(uint32_t, size_t, uint32_t, uint16_t); -typedef void (*flash_range_program_fn)(uint32_t, const uint8_t*, size_t); -static inline __attribute__((always_inline)) void __compiler_memory_barrier(void) { - __asm__ volatile ("" : : : "memory"); -} - -// https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf -// 13.9. Predefined OTP Data Locations -// OTP_DATA: FLASH_DEVINFO Register - -#define OTP_DATA_FLASH_DEVINFO_CS0_SIZE_BITS 0x0F00 -#define OTP_DATA_FLASH_DEVINFO_CS0_SIZE_LSB 8 -#define OTP_DATA_FLASH_DEVINFO_CS1_SIZE_BITS 0xF000 -#define OTP_DATA_FLASH_DEVINFO_CS1_SIZE_LSB 12 - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2350/hardware_regs/include/hardware/regs/addressmap.h - -#define REG_ALIAS_RW_BITS (0x0 << 12) -#define REG_ALIAS_XOR_BITS (0x1 << 12) -#define REG_ALIAS_SET_BITS (0x2 << 12) -#define REG_ALIAS_CLR_BITS (0x3 << 12) - -#define XIP_BASE 0x10000000 -#define XIP_QMI_BASE 0x400d0000 -#define IO_QSPI_BASE 0x40030000 -#define BOOTRAM_BASE 0x400e0000 - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/hardware_base/include/hardware/address_mapped.h - -#define hw_alias_check_addr(addr) ((uintptr_t)(addr)) -#define hw_set_alias_untyped(addr) ((void *)(REG_ALIAS_SET_BITS + hw_alias_check_addr(addr))) -#define hw_clear_alias_untyped(addr) ((void *)(REG_ALIAS_CLR_BITS + hw_alias_check_addr(addr))) -#define hw_xor_alias_untyped(addr) ((void *)(REG_ALIAS_XOR_BITS + hw_alias_check_addr(addr))) - -__attribute__((always_inline)) -static void hw_set_bits(io_rw_32 *addr, uint32_t mask) { - *(io_rw_32 *) hw_set_alias_untyped((volatile void *) addr) = mask; -} - -__attribute__((always_inline)) -static void hw_clear_bits(io_rw_32 *addr, uint32_t mask) { - *(io_rw_32 *) hw_clear_alias_untyped((volatile void *) addr) = mask; -} - -__attribute__((always_inline)) -static void hw_xor_bits(io_rw_32 *addr, uint32_t mask) { - *(io_rw_32 *) hw_xor_alias_untyped((volatile void *) addr) = mask; -} - -__attribute__((always_inline)) -static void hw_write_masked(io_rw_32 *addr, uint32_t values, uint32_t write_mask) { - hw_xor_bits(addr, (*addr ^ values) & write_mask); -} - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/pico_platform_compiler/include/pico/platform/compiler.h - -#define pico_default_asm_volatile(...) __asm volatile (".syntax unified\n" __VA_ARGS__) - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2350/pico_platform/include/pico/platform.h - -static bool pico_processor_state_is_nonsecure(void) { -// // todo add a define to disable NS checking at all? -// // IDAU-Exempt addresses return S=1 when tested in the Secure state, -// // whereas executing a tt in the NonSecure state will always return S=0. -// uint32_t tt; -// pico_default_asm_volatile ( -// "movs %0, #0\n" -// "tt %0, %0\n" -// : "=r" (tt) : : "cc" -// ); -// return !(tt & (1u << 22)); - return false; -} - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/pico_bootrom/include/pico/bootrom_constants.h - -// RP2040 & RP2350 -#define ROM_DATA_SOFTWARE_GIT_REVISION ROM_TABLE_CODE('G', 'R') -#define ROM_FUNC_FLASH_ENTER_CMD_XIP ROM_TABLE_CODE('C', 'X') -#define ROM_FUNC_FLASH_EXIT_XIP ROM_TABLE_CODE('E', 'X') -#define ROM_FUNC_FLASH_FLUSH_CACHE ROM_TABLE_CODE('F', 'C') -#define ROM_FUNC_CONNECT_INTERNAL_FLASH ROM_TABLE_CODE('I', 'F') -#define ROM_FUNC_FLASH_RANGE_ERASE ROM_TABLE_CODE('R', 'E') -#define ROM_FUNC_FLASH_RANGE_PROGRAM ROM_TABLE_CODE('R', 'P') - -// RP2350 only -#define ROM_FUNC_PICK_AB_PARTITION ROM_TABLE_CODE('A', 'B') -#define ROM_FUNC_CHAIN_IMAGE ROM_TABLE_CODE('C', 'I') -#define ROM_FUNC_EXPLICIT_BUY ROM_TABLE_CODE('E', 'B') -#define ROM_FUNC_FLASH_RUNTIME_TO_STORAGE_ADDR ROM_TABLE_CODE('F', 'A') -#define ROM_DATA_FLASH_DEVINFO16_PTR ROM_TABLE_CODE('F', 'D') -#define ROM_FUNC_FLASH_OP ROM_TABLE_CODE('F', 'O') -#define ROM_FUNC_GET_B_PARTITION ROM_TABLE_CODE('G', 'B') -#define ROM_FUNC_GET_PARTITION_TABLE_INFO ROM_TABLE_CODE('G', 'P') -#define ROM_FUNC_GET_SYS_INFO ROM_TABLE_CODE('G', 'S') -#define ROM_FUNC_GET_UF2_TARGET_PARTITION ROM_TABLE_CODE('G', 'U') -#define ROM_FUNC_LOAD_PARTITION_TABLE ROM_TABLE_CODE('L', 'P') -#define ROM_FUNC_OTP_ACCESS ROM_TABLE_CODE('O', 'A') -#define ROM_DATA_PARTITION_TABLE_PTR ROM_TABLE_CODE('P', 'T') -#define ROM_FUNC_FLASH_RESET_ADDRESS_TRANS ROM_TABLE_CODE('R', 'A') -#define ROM_FUNC_REBOOT ROM_TABLE_CODE('R', 'B') -#define ROM_FUNC_SET_ROM_CALLBACK ROM_TABLE_CODE('R', 'C') -#define ROM_FUNC_SECURE_CALL ROM_TABLE_CODE('S', 'C') -#define ROM_FUNC_SET_NS_API_PERMISSION ROM_TABLE_CODE('S', 'P') -#define ROM_FUNC_BOOTROM_STATE_RESET ROM_TABLE_CODE('S', 'R') -#define ROM_FUNC_SET_BOOTROM_STACK ROM_TABLE_CODE('S', 'S') -#define ROM_DATA_SAVED_XIP_SETUP_FUNC_PTR ROM_TABLE_CODE('X', 'F') -#define ROM_FUNC_FLASH_SELECT_XIP_READ_MODE ROM_TABLE_CODE('X', 'M') -#define ROM_FUNC_VALIDATE_NS_BUFFER ROM_TABLE_CODE('V', 'B') - -#define BOOTSEL_FLAG_GPIO_PIN_SPECIFIED 0x20 - -#define BOOTROM_FUNC_TABLE_OFFSET 0x14 - -// todo remove this (or #ifdef it for A1/A2) -#define BOOTROM_IS_A2() ((*(volatile uint8_t *)0x13) == 2) -#define BOOTROM_WELL_KNOWN_PTR_SIZE (BOOTROM_IS_A2() ? 2 : 4) - -#define BOOTROM_VTABLE_OFFSET 0x00 -#define BOOTROM_TABLE_LOOKUP_OFFSET (BOOTROM_FUNC_TABLE_OFFSET + BOOTROM_WELL_KNOWN_PTR_SIZE) - - -// https://github.com/raspberrypi/pico-sdk -// src/common/boot_picoboot_headers/include/boot/picoboot_constants.h - -// values 0-7 are secure/non-secure -#define REBOOT2_FLAG_REBOOT_TYPE_NORMAL 0x0 // param0 = diagnostic partition -#define REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL 0x2 // param0 = bootsel_flags, param1 = gpio_config -#define REBOOT2_FLAG_REBOOT_TYPE_RAM_IMAGE 0x3 // param0 = image_base, param1 = image_end -#define REBOOT2_FLAG_REBOOT_TYPE_FLASH_UPDATE 0x4 // param0 = update_base - -#define REBOOT2_FLAG_NO_RETURN_ON_SUCCESS 0x100 - -#define RT_FLAG_FUNC_ARM_SEC 0x0004 -#define RT_FLAG_FUNC_ARM_NONSEC 0x0010 -#define RT_FLAG_DATA 0x0040 - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/pico_bootrom/include/pico/bootrom.h - -#define ROM_TABLE_CODE(c1, c2) ((c1) | ((c2) << 8)) - -typedef void *(*rom_table_lookup_fn)(uint32_t code, uint32_t mask); - -__attribute__((always_inline)) -static void *rom_func_lookup_inline(uint32_t code) { - rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET); - if (pico_processor_state_is_nonsecure()) { - return rom_table_lookup(code, RT_FLAG_FUNC_ARM_NONSEC); - } else { - return rom_table_lookup(code, RT_FLAG_FUNC_ARM_SEC); - } -} - -__attribute__((always_inline)) -static void *rom_data_lookup_inline(uint32_t code) { - rom_table_lookup_fn rom_table_lookup = (rom_table_lookup_fn) (uintptr_t)*(uint16_t*)(BOOTROM_TABLE_LOOKUP_OFFSET); - return rom_table_lookup(code, RT_FLAG_DATA); -} - -typedef int (*rom_reboot_fn)(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1); - -__attribute__((always_inline)) -int rom_reboot(uint32_t flags, uint32_t delay_ms, uint32_t p0, uint32_t p1) { - rom_reboot_fn func = (rom_reboot_fn) rom_func_lookup_inline(ROM_FUNC_REBOOT); - return func(flags, delay_ms, p0, p1); -} - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/pico_bootrom/bootrom.c - -void reset_usb_boot(uint32_t usb_activity_gpio_pin_mask, uint32_t disable_interface_mask) { - uint32_t flags = disable_interface_mask; - if (usb_activity_gpio_pin_mask) { - flags |= BOOTSEL_FLAG_GPIO_PIN_SPECIFIED; - // the parameter is actually the gpio number, but we only care if BOOTSEL_FLAG_GPIO_PIN_SPECIFIED - usb_activity_gpio_pin_mask = (uint32_t)__builtin_ctz(usb_activity_gpio_pin_mask); - } - rom_reboot(REBOOT2_FLAG_REBOOT_TYPE_BOOTSEL | REBOOT2_FLAG_NO_RETURN_ON_SUCCESS, 10, flags, usb_activity_gpio_pin_mask); - __builtin_unreachable(); -} - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2350/hardware_regs/include/hardware/regs/qmi.h - -#define QMI_DIRECT_CSR_EN_BITS 0x00000001 -#define QMI_DIRECT_CSR_RXEMPTY_BITS 0x00010000 -#define QMI_DIRECT_CSR_TXFULL_BITS 0x00000400 -#define QMI_M1_WFMT_RESET 0x00001000 -#define QMI_M1_WCMD_RESET 0x0000a002 - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2350/hardware_regs/include/hardware/regs/io_qspi.h - -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS 0x00003000 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB 12 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW 0x2 -#define IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH 0x3 - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2350/hardware_structs/include/hardware/structs/io_qspi.h - -typedef struct { - io_rw_32 inte; // IO_QSPI_PROC0_INTE - io_rw_32 intf; // IO_QSPI_PROC0_INTF - io_ro_32 ints; // IO_QSPI_PROC0_INTS -} io_qspi_irq_ctrl_hw_t; - -typedef struct { - io_ro_32 status; // IO_QSPI_GPIO_QSPI_SCLK_STATUS - io_rw_32 ctrl; // IO_QSPI_GPIO_QSPI_SCLK_CTRL -} io_qspi_status_ctrl_hw_t; - -typedef struct { - io_ro_32 usbphy_dp_status; // IO_QSPI_USBPHY_DP_STATUS - io_rw_32 usbphy_dp_ctrl; // IO_QSPI_USBPHY_DP_CTRL - io_ro_32 usbphy_dm_status; // IO_QSPI_USBPHY_DM_STATUS - io_rw_32 usbphy_dm_ctrl; // IO_QSPI_USBPHY_DM_CTRL - io_qspi_status_ctrl_hw_t io[6]; - uint32_t _pad0[112]; - io_ro_32 irqsummary_proc0_secure; // IO_QSPI_IRQSUMMARY_PROC0_SECURE - io_ro_32 irqsummary_proc0_nonsecure; // IO_QSPI_IRQSUMMARY_PROC0_NONSECURE - io_ro_32 irqsummary_proc1_secure; // IO_QSPI_IRQSUMMARY_PROC1_SECURE - io_ro_32 irqsummary_proc1_nonsecure; // IO_QSPI_IRQSUMMARY_PROC1_NONSECURE - io_ro_32 irqsummary_dormant_wake_secure; // IO_QSPI_IRQSUMMARY_DORMANT_WAKE_SECURE - io_ro_32 irqsummary_dormant_wake_nonsecure; // IO_QSPI_IRQSUMMARY_DORMANT_WAKE_NONSECURE - io_rw_32 intr; // IO_QSPI_INTR - - union { - struct { - io_qspi_irq_ctrl_hw_t proc0_irq_ctrl; - io_qspi_irq_ctrl_hw_t proc1_irq_ctrl; - io_qspi_irq_ctrl_hw_t dormant_wake_irq_ctrl; - }; - io_qspi_irq_ctrl_hw_t irq_ctrl[3]; - }; -} io_qspi_hw_t; - -#define io_qspi_hw ((io_qspi_hw_t *)IO_QSPI_BASE) - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2350/hardware_structs/include/hardware/structs/qmi.h - -typedef struct { - io_rw_32 timing; // QMI_M0_TIMING - io_rw_32 rfmt; // QMI_M0_RFMT - io_rw_32 rcmd; // QMI_M0_RCMD - io_rw_32 wfmt; // QMI_M0_WFMT - io_rw_32 wcmd; // QMI_M0_WCMD -} qmi_mem_hw_t; - -typedef struct { - io_rw_32 direct_csr; // QMI_DIRECT_CSR - io_wo_32 direct_tx; // QMI_DIRECT_TX - io_ro_32 direct_rx; // QMI_DIRECT_RX - qmi_mem_hw_t m[2]; - io_rw_32 atrans[8]; // QMI_ATRANS0 -} qmi_hw_t; - -#define qmi_hw ((qmi_hw_t *)XIP_QMI_BASE) - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/hardware_xip_cache/include/hardware/xip_cache.h - -// Noop unless using XIP Cache-as-SRAM -// Non-noop version in src/rp2_common/hardware_xip_cache/xip_cache.c -static inline void xip_cache_clean_all(void) {} - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/hardware_flash/include/hardware/flash.h - -#define FLASH_PAGE_SIZE (1u << 8) -#define FLASH_SECTOR_SIZE (1u << 12) -#define FLASH_BLOCK_SIZE (1u << 16) - - -// https://github.com/raspberrypi/pico-sdk -// src/rp2_common/hardware_flash/flash.c - -#define BOOT2_SIZE_WORDS 64 -#define FLASH_BLOCK_ERASE_CMD 0xd8 - -static uint32_t boot2_copyout[BOOT2_SIZE_WORDS]; -static bool boot2_copyout_valid = false; - -static ram_func void flash_init_boot2_copyout(void) { - if (boot2_copyout_valid) - return; - for (int i = 0; i < BOOT2_SIZE_WORDS; ++i) - boot2_copyout[i] = ((uint32_t *)BOOTRAM_BASE)[i]; - __compiler_memory_barrier(); - boot2_copyout_valid = true; -} - -static ram_func void flash_enable_xip_via_boot2(void) { - ((void (*)(void))((intptr_t)boot2_copyout+1))(); -} - -// This is a static symbol because the layout of FLASH_DEVINFO is liable to change from device to -// device, so fields must have getters/setters. -static io_rw_16 * ram_func flash_devinfo_ptr(void) { - // Note the lookup returns a pointer to a 32-bit pointer literal in the ROM - io_rw_16 **p = (io_rw_16 **) rom_data_lookup_inline(ROM_DATA_FLASH_DEVINFO16_PTR); - return *p; -} - -// This is a RAM function because may be called during flash programming to enable save/restore of -// QMI window 1 registers on RP2350: -uint8_t ram_func flash_devinfo_get_cs_size(uint8_t cs) { - io_ro_16 *devinfo = (io_ro_16 *) flash_devinfo_ptr(); - if (cs == 0u) { - return (uint8_t) ( - (*devinfo & OTP_DATA_FLASH_DEVINFO_CS0_SIZE_BITS) >> OTP_DATA_FLASH_DEVINFO_CS0_SIZE_LSB - ); - } else { - return (uint8_t) ( - (*devinfo & OTP_DATA_FLASH_DEVINFO_CS1_SIZE_BITS) >> OTP_DATA_FLASH_DEVINFO_CS1_SIZE_LSB - ); - } -} - -// This is specifically for saving/restoring the registers modified by RP2350 -// flash_exit_xip() ROM func, not the entirety of the QMI window state. -typedef struct flash_rp2350_qmi_save_state { - uint32_t timing; - uint32_t rcmd; - uint32_t rfmt; -} flash_rp2350_qmi_save_state_t; - -static ram_func void flash_rp2350_save_qmi_cs1(flash_rp2350_qmi_save_state_t *state) { - state->timing = qmi_hw->m[1].timing; - state->rcmd = qmi_hw->m[1].rcmd; - state->rfmt = qmi_hw->m[1].rfmt; -} - -static ram_func void flash_rp2350_restore_qmi_cs1(const flash_rp2350_qmi_save_state_t *state) { - if (flash_devinfo_get_cs_size(1) == 0) { - // Case 1: The RP2350 ROM sets QMI to a clean (03h read) configuration - // during flash_exit_xip(), even though when CS1 is not enabled via - // FLASH_DEVINFO it does not issue an XIP exit sequence to CS1. In - // this case, restore the original register config for CS1 as it is - // still the correct config. - qmi_hw->m[1].timing = state->timing; - qmi_hw->m[1].rcmd = state->rcmd; - qmi_hw->m[1].rfmt = state->rfmt; - } else { - // Case 2: If RAM is attached to CS1, and the ROM has issued an XIP - // exit sequence to it, then the ROM re-initialisation of the QMI - // registers has actually not gone far enough. The old XIP write mode - // is no longer valid when the QSPI RAM is returned to a serial - // command state. Restore the default 02h serial write command config. - qmi_hw->m[1].wfmt = QMI_M1_WFMT_RESET; - qmi_hw->m[1].wcmd = QMI_M1_WCMD_RESET; - } -} - -void ram_func flash_cs_force(bool high) { - uint32_t field_val = high ? - IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_HIGH : - IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_VALUE_LOW; - hw_write_masked(&io_qspi_hw->io[1].ctrl, - field_val << IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_LSB, - IO_QSPI_GPIO_QSPI_SS_CTRL_OUTOVER_BITS - ); -} - -// Adapted from flash_range_program() -void ram_func flash_range_write(uint32_t offset, const uint8_t *data, size_t count) { - flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); - flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); - flash_range_program_fn flash_range_program_func = (flash_range_program_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_PROGRAM); - flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); - flash_init_boot2_copyout(); - xip_cache_clean_all(); - flash_rp2350_qmi_save_state_t qmi_save; - flash_rp2350_save_qmi_cs1(&qmi_save); - - __compiler_memory_barrier(); - - flash_connect_internal_func(); - flash_exit_xip_func(); - flash_range_program_func(offset, data, count); - flash_flush_cache_func(); // Note this is needed to remove CSn IO force as well as cache flushing - flash_enable_xip_via_boot2(); - flash_rp2350_restore_qmi_cs1(&qmi_save); -} - -// Adapted from flash_range_erase() -void ram_func flash_erase_blocks(uint32_t offset, size_t count) { - flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); - flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); - flash_range_erase_fn flash_range_erase_func = (flash_range_erase_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_RANGE_ERASE); - flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); - flash_init_boot2_copyout(); - // Commit any pending writes to external RAM, to avoid losing them in the subsequent flush: - xip_cache_clean_all(); - flash_rp2350_qmi_save_state_t qmi_save; - flash_rp2350_save_qmi_cs1(&qmi_save); - - // No flash accesses after this point - __compiler_memory_barrier(); - - flash_connect_internal_func(); - flash_exit_xip_func(); - flash_range_erase_func(offset, count, FLASH_BLOCK_SIZE, FLASH_BLOCK_ERASE_CMD); - flash_flush_cache_func(); // Note this is needed to remove CSn IO force as well as cache flushing - flash_enable_xip_via_boot2(); - flash_rp2350_restore_qmi_cs1(&qmi_save); -} - -void ram_func flash_do_cmd(const uint8_t *txbuf, uint8_t *rxbuf, size_t count) { - flash_connect_internal_fn flash_connect_internal_func = (flash_connect_internal_fn)rom_func_lookup_inline(ROM_FUNC_CONNECT_INTERNAL_FLASH); - flash_exit_xip_fn flash_exit_xip_func = (flash_exit_xip_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_EXIT_XIP); - flash_flush_cache_fn flash_flush_cache_func = (flash_flush_cache_fn)rom_func_lookup_inline(ROM_FUNC_FLASH_FLUSH_CACHE); - flash_init_boot2_copyout(); - xip_cache_clean_all(); - - flash_rp2350_qmi_save_state_t qmi_save; - flash_rp2350_save_qmi_cs1(&qmi_save); - - __compiler_memory_barrier(); - flash_connect_internal_func(); - flash_exit_xip_func(); + "github.com/goplus/lib/c" + "github.com/goplus/emb/runtime/interrupt" +) - flash_cs_force(0); - size_t tx_remaining = count; - size_t rx_remaining = count; +const ( + LLGoFiles = "_wrap/machine_rp2050_rom.c" +) - // QMI version -- no need to bound FIFO contents as QMI stalls on full DIRECT_RX. - hw_set_bits(&qmi_hw->direct_csr, QMI_DIRECT_CSR_EN_BITS); - while (tx_remaining || rx_remaining) { - uint32_t flags = qmi_hw->direct_csr; - bool can_put = !(flags & QMI_DIRECT_CSR_TXFULL_BITS); - bool can_get = !(flags & QMI_DIRECT_CSR_RXEMPTY_BITS); - if (can_put && tx_remaining) { - qmi_hw->direct_tx = *txbuf++; - --tx_remaining; - } - if (can_get && rx_remaining) { - *rxbuf++ = (uint8_t)qmi_hw->direct_rx; - --rx_remaining; - } - } - hw_clear_bits(&qmi_hw->direct_csr, QMI_DIRECT_CSR_EN_BITS); +//go:linkname reset_usb_boot C.reset_usb_boot +func reset_usb_boot(c.Uint32T, c.Uint32T) - flash_cs_force(1); +//go:linkname flash_do_cmd C.flash_do_cmd +func flash_do_cmd(*c.Uint8T, *c.Uint8T, c.SizeT) - flash_flush_cache_func(); - flash_enable_xip_via_boot2(); - flash_rp2350_restore_qmi_cs1(&qmi_save); -} +//go:linkname flash_range_write C.flash_range_write +func flash_range_write(c.Uint32T, *c.Uint8T, c.SizeT) -*/ -import "C" +//go:linkname flash_erase_blocks C.flash_erase_blocks +func flash_erase_blocks(c.Uint32T, c.SizeT) func enterBootloader() { - C.reset_usb_boot(0, 0) + reset_usb_boot(0, 0) } func doFlashCommand(tx []byte, rx []byte) error { @@ -513,19 +34,26 @@ func doFlashCommand(tx []byte, rx []byte) error { return errFlashInvalidWriteLength } - C.flash_do_cmd( - (*C.uint8_t)(unsafe.Pointer(&tx[0])), - (*C.uint8_t)(unsafe.Pointer(&rx[0])), - C.ulong(len(tx))) + // C.flash_do_cmd( + // (*C.uint8_t)(unsafe.Pointer(&tx[0])), + // (*C.uint8_t)(unsafe.Pointer(&rx[0])), + // C.ulong(len(tx))) + flash_do_cmd( + (*c.Uint8T)(unsafe.Pointer(&tx[0])), + (*c.Uint8T)(unsafe.Pointer(&rx[0])), + c.SizeT(len(tx)), + ) return nil } // Flash related code -const memoryStart = C.XIP_BASE // memory start for purpose of erase +// const memoryStart = C.XIP_BASE // memory start for purpose of erase +const XIP_BASE = 0x10000000 +const memoryStart = XIP_BASE // memory start for purpose of erase func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) { - if writeAddress(off)+uintptr(C.XIP_BASE) > FlashDataEnd() { + if writeAddress(off)+uintptr(XIP_BASE) > FlashDataEnd() { return 0, errFlashCannotWritePastEOF } @@ -538,23 +66,28 @@ func (f flashBlockDevice) writeAt(p []byte, off int64) (n int, err error) { address := writeAddress(off) padded := flashPad(p, int(f.WriteBlockSize())) - C.flash_range_write(C.uint32_t(address), - (*C.uint8_t)(unsafe.Pointer(&padded[0])), - C.ulong(len(padded))) + // C.flash_range_write(C.uint32_t(address), + // (*C.uint8_t)(unsafe.Pointer(&padded[0])), + // C.ulong(len(padded))) + flash_range_write( + c.Uint32T(address), + (*c.Uint8T)(unsafe.Pointer(&padded[0])), + c.SizeT(len(padded)), + ) return len(padded), nil } func (f flashBlockDevice) eraseBlocks(start, length int64) error { address := writeAddress(start * f.EraseBlockSize()) - if address+uintptr(C.XIP_BASE) > FlashDataEnd() { + if address+uintptr(XIP_BASE) > FlashDataEnd() { return errFlashCannotErasePastEOF } state := interrupt.Disable() defer interrupt.Restore(state) - C.flash_erase_blocks(C.uint32_t(address), C.ulong(length*f.EraseBlockSize())) - + // C.flash_erase_blocks(C.uint32_t(address), C.ulong(length*f.EraseBlockSize())) + flash_erase_blocks(c.Uint32T(address), c.SizeT(length*f.EraseBlockSize())) return nil } diff --git a/machine/machine_rp2350_usb.go b/machine/machine_rp2350_usb.go index ca09262..237bff1 100644 --- a/machine/machine_rp2350_usb.go +++ b/machine/machine_rp2350_usb.go @@ -3,9 +3,9 @@ package machine import ( - "device/rp" - "machine/usb" - "runtime/interrupt" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/interrupt" ) // Configure the USB peripheral. The config is here for compatibility with the UART interface. diff --git a/machine/machine_rp2_2040.go b/machine/machine_rp2_2040.go index 9cdb3a0..c8743fd 100644 --- a/machine/machine_rp2_2040.go +++ b/machine/machine_rp2_2040.go @@ -3,8 +3,8 @@ package machine import ( - "device/rp" - "runtime/volatile" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_2350.go b/machine/machine_rp2_2350.go index efb39a6..669031f 100644 --- a/machine/machine_rp2_2350.go +++ b/machine/machine_rp2_2350.go @@ -3,8 +3,8 @@ package machine import ( - "device/rp" - "runtime/volatile" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_adc.go b/machine/machine_rp2_adc.go index d5f21b1..4c71eac 100644 --- a/machine/machine_rp2_adc.go +++ b/machine/machine_rp2_adc.go @@ -3,7 +3,7 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" "errors" "sync" ) diff --git a/machine/machine_rp2_clocks.go b/machine/machine_rp2_clocks.go index dafebbe..f927377 100644 --- a/machine/machine_rp2_clocks.go +++ b/machine/machine_rp2_clocks.go @@ -3,9 +3,9 @@ package machine import ( - "device/arm" - "device/rp" - "runtime/volatile" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_gpio.go b/machine/machine_rp2_gpio.go index 25d7626..c98db1b 100644 --- a/machine/machine_rp2_gpio.go +++ b/machine/machine_rp2_gpio.go @@ -3,9 +3,9 @@ package machine import ( - "device/rp" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_i2c.go b/machine/machine_rp2_i2c.go index 54a5e53..1276ad9 100644 --- a/machine/machine_rp2_i2c.go +++ b/machine/machine_rp2_i2c.go @@ -3,9 +3,10 @@ package machine import ( - "device/rp" "errors" - "internal/itoa" + + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/internal/itoa" ) // I2C on the RP2040/RP2350 diff --git a/machine/machine_rp2_pll.go b/machine/machine_rp2_pll.go index d576084..af0294f 100644 --- a/machine/machine_rp2_pll.go +++ b/machine/machine_rp2_pll.go @@ -3,11 +3,11 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" "errors" "math" "math/bits" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_pwm.go b/machine/machine_rp2_pwm.go index 772811e..e0014eb 100644 --- a/machine/machine_rp2_pwm.go +++ b/machine/machine_rp2_pwm.go @@ -3,10 +3,10 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" "errors" "math" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_resets.go b/machine/machine_rp2_resets.go index 245436c..f532fc0 100644 --- a/machine/machine_rp2_resets.go +++ b/machine/machine_rp2_resets.go @@ -3,7 +3,7 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" "unsafe" ) diff --git a/machine/machine_rp2_rng.go b/machine/machine_rp2_rng.go index e619f05..22170c0 100644 --- a/machine/machine_rp2_rng.go +++ b/machine/machine_rp2_rng.go @@ -6,7 +6,7 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" ) const numberOfCycles = 32 diff --git a/machine/machine_rp2_spi.go b/machine/machine_rp2_spi.go index d9cfc11..478eb48 100644 --- a/machine/machine_rp2_spi.go +++ b/machine/machine_rp2_spi.go @@ -3,7 +3,7 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" "errors" "unsafe" ) diff --git a/machine/machine_rp2_timer.go b/machine/machine_rp2_timer.go index a78ed70..1608dfa 100644 --- a/machine/machine_rp2_timer.go +++ b/machine/machine_rp2_timer.go @@ -3,9 +3,9 @@ package machine import ( - "device/arm" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/arm" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) const numTimers = 4 diff --git a/machine/machine_rp2_uart.go b/machine/machine_rp2_uart.go index 03ebb9d..5f72afe 100644 --- a/machine/machine_rp2_uart.go +++ b/machine/machine_rp2_uart.go @@ -3,8 +3,8 @@ package machine import ( - "device/rp" - "runtime/interrupt" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/interrupt" ) // UART on the RP2040. @@ -104,7 +104,10 @@ func (uart *UART) SetBaudRate(br uint32) { func (uart *UART) writeByte(c byte) error { // wait until buffer is not full for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) { - gosched() + // TODO(zzy):interrupt + // if !interrupt.In() { + gosched() + // } } // write data @@ -114,7 +117,10 @@ func (uart *UART) writeByte(c byte) error { func (uart *UART) flush() { for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) { - gosched() + // TODO(zzy):interrupt + // if !interrupt.In() { + gosched() + // } } } diff --git a/machine/machine_rp2_usb.go b/machine/machine_rp2_usb.go index 297cc9d..c10de00 100644 --- a/machine/machine_rp2_usb.go +++ b/machine/machine_rp2_usb.go @@ -3,8 +3,8 @@ package machine import ( - "machine/usb" - "runtime/volatile" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_rp2_watchdog.go b/machine/machine_rp2_watchdog.go index f776c5c..0b242f2 100644 --- a/machine/machine_rp2_watchdog.go +++ b/machine/machine_rp2_watchdog.go @@ -3,7 +3,7 @@ package machine import ( - "device/rp" + "github.com/goplus/emb/device/rp" ) // Watchdog provides access to the hardware watchdog available diff --git a/machine/machine_rp2_xosc.go b/machine/machine_rp2_xosc.go index c9ce583..cf97c67 100644 --- a/machine/machine_rp2_xosc.go +++ b/machine/machine_rp2_xosc.go @@ -3,8 +3,8 @@ package machine import ( - "device/rp" - "runtime/volatile" + "github.com/goplus/emb/device/rp" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32.go b/machine/machine_stm32.go index 1edaa2c..9ebb553 100644 --- a/machine/machine_stm32.go +++ b/machine/machine_stm32.go @@ -3,9 +3,9 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32_adc_f1.go b/machine/machine_stm32_adc_f1.go index 7076bdd..e4de832 100644 --- a/machine/machine_stm32_adc_f1.go +++ b/machine/machine_stm32_adc_f1.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "unsafe" ) diff --git a/machine/machine_stm32_adc_f4.go b/machine/machine_stm32_adc_f4.go index df4984c..22f2430 100644 --- a/machine/machine_stm32_adc_f4.go +++ b/machine/machine_stm32_adc_f4.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "unsafe" ) diff --git a/machine/machine_stm32_exti_afio.go b/machine/machine_stm32_exti_afio.go index 89a9506..35561f6 100644 --- a/machine/machine_stm32_exti_afio.go +++ b/machine/machine_stm32_exti_afio.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/volatile" ) func getEXTIConfigRegister(pin uint8) *volatile.Register32 { diff --git a/machine/machine_stm32_exti_exti.go b/machine/machine_stm32_exti_exti.go index 874a043..8d55068 100644 --- a/machine/machine_stm32_exti_exti.go +++ b/machine/machine_stm32_exti_exti.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/volatile" ) func getEXTIConfigRegister(pin uint8) *volatile.Register32 { diff --git a/machine/machine_stm32_exti_syscfg.go b/machine/machine_stm32_exti_syscfg.go index f7c91f8..85f3895 100644 --- a/machine/machine_stm32_exti_syscfg.go +++ b/machine/machine_stm32_exti_syscfg.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/volatile" ) func getEXTIConfigRegister(pin uint8) *volatile.Register32 { diff --git a/machine/machine_stm32_exti_syscfg_noenable.go b/machine/machine_stm32_exti_syscfg_noenable.go index 85f47fa..9cd1e72 100644 --- a/machine/machine_stm32_exti_syscfg_noenable.go +++ b/machine/machine_stm32_exti_syscfg_noenable.go @@ -3,8 +3,8 @@ package machine import ( - "device/stm32" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/volatile" ) func getEXTIConfigRegister(pin uint8) *volatile.Register32 { diff --git a/machine/machine_stm32_flash.go b/machine/machine_stm32_flash.go index 280dc89..5dfeb43 100644 --- a/machine/machine_stm32_flash.go +++ b/machine/machine_stm32_flash.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "unsafe" ) diff --git a/machine/machine_stm32_gpio_reva.go b/machine/machine_stm32_gpio_reva.go index 2fb5a03..e2f4f07 100644 --- a/machine/machine_stm32_gpio_reva.go +++ b/machine/machine_stm32_gpio_reva.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" ) // This variant of the GPIO input interrupt logic is for diff --git a/machine/machine_stm32_gpio_revb.go b/machine/machine_stm32_gpio_revb.go index 49094c7..1d2fd25 100644 --- a/machine/machine_stm32_gpio_revb.go +++ b/machine/machine_stm32_gpio_revb.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" ) // This variant of the GPIO input interrupt logic is for diff --git a/machine/machine_stm32_gpio_revb_mp.go b/machine/machine_stm32_gpio_revb_mp.go index 2124b16..337bcd0 100644 --- a/machine/machine_stm32_gpio_revb_mp.go +++ b/machine/machine_stm32_gpio_revb_mp.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" ) // diff --git a/machine/machine_stm32_i2c_reva.go b/machine/machine_stm32_i2c_reva.go index 1e4fd28..13fcc2f 100644 --- a/machine/machine_stm32_i2c_reva.go +++ b/machine/machine_stm32_i2c_reva.go @@ -6,7 +6,7 @@ package machine // of MCUs. import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "unsafe" ) diff --git a/machine/machine_stm32_i2c_revb.go b/machine/machine_stm32_i2c_revb.go index 006661f..1330d06 100644 --- a/machine/machine_stm32_i2c_revb.go +++ b/machine/machine_stm32_i2c_revb.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "unsafe" ) diff --git a/machine/machine_stm32_iwdg.go b/machine/machine_stm32_iwdg.go index 1139d54..f9541aa 100644 --- a/machine/machine_stm32_iwdg.go +++ b/machine/machine_stm32_iwdg.go @@ -2,7 +2,7 @@ package machine -import "device/stm32" +import "github.com/goplus/emb/device/stm32" var ( Watchdog = &watchdogImpl{} diff --git a/machine/machine_stm32_moder_gpio.go b/machine/machine_stm32_moder_gpio.go index b8585c2..215b03b 100644 --- a/machine/machine_stm32_moder_gpio.go +++ b/machine/machine_stm32_moder_gpio.go @@ -3,7 +3,7 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" ) // GPIO for the stm32 families except the stm32f1xx which uses a simpler but diff --git a/machine/machine_stm32_rng.go b/machine/machine_stm32_rng.go index 5eaff96..6ac7126 100644 --- a/machine/machine_stm32_rng.go +++ b/machine/machine_stm32_rng.go @@ -2,7 +2,7 @@ package machine -import "device/stm32" +import "github.com/goplus/emb/device/stm32" var rngInitDone = false diff --git a/machine/machine_stm32_spi.go b/machine/machine_stm32_spi.go index 3c6e0b6..3c2729c 100644 --- a/machine/machine_stm32_spi.go +++ b/machine/machine_stm32_spi.go @@ -5,8 +5,8 @@ package machine // Peripheral abstraction layer for SPI on the stm32 family import ( - "device/stm32" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32_tim.go b/machine/machine_stm32_tim.go index 4898ed9..e8d8179 100644 --- a/machine/machine_stm32_tim.go +++ b/machine/machine_stm32_tim.go @@ -6,9 +6,9 @@ package machine // depending on the size of that register in the MCU's TIM_Type structure. import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" ) const PWM_MODE1 = 0x6 diff --git a/machine/machine_stm32_uart.go b/machine/machine_stm32_uart.go index 6e8806c..35788aa 100644 --- a/machine/machine_stm32_uart.go +++ b/machine/machine_stm32_uart.go @@ -5,9 +5,9 @@ package machine // Peripheral abstraction layer for UARTs on the stm32 family. import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32f103.go b/machine/machine_stm32f103.go index 9e7bb34..2993a70 100644 --- a/machine/machine_stm32f103.go +++ b/machine/machine_stm32f103.go @@ -5,9 +5,9 @@ package machine // Peripheral abstraction layer for the stm32. import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32f4.go b/machine/machine_stm32f4.go index 31f1d2c..ede6788 100644 --- a/machine/machine_stm32f4.go +++ b/machine/machine_stm32f4.go @@ -5,12 +5,12 @@ package machine // Peripheral abstraction layer for the stm32f4 import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "errors" - "internal/binary" + "github.com/goplus/emb/internal/binary" "math/bits" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32f7.go b/machine/machine_stm32f7.go index 11eff11..b0803ef 100644 --- a/machine/machine_stm32f7.go +++ b/machine/machine_stm32f7.go @@ -5,9 +5,9 @@ package machine // Peripheral abstraction layer for the stm32f4 import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32f7x2.go b/machine/machine_stm32f7x2.go index 7da4070..630e473 100644 --- a/machine/machine_stm32f7x2.go +++ b/machine/machine_stm32f7x2.go @@ -5,7 +5,7 @@ package machine // Peripheral abstraction layer for the stm32f407 import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" ) func CPUFrequency() uint32 { diff --git a/machine/machine_stm32l0.go b/machine/machine_stm32l0.go index 1ecd958..bea6403 100644 --- a/machine/machine_stm32l0.go +++ b/machine/machine_stm32l0.go @@ -5,8 +5,8 @@ package machine // Peripheral abstraction layer for the stm32l0 import ( - "device/stm32" - "runtime/interrupt" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" ) func CPUFrequency() uint32 { diff --git a/machine/machine_stm32l0x1.go b/machine/machine_stm32l0x1.go index f0d23ca..a235151 100644 --- a/machine/machine_stm32l0x1.go +++ b/machine/machine_stm32l0x1.go @@ -5,9 +5,9 @@ package machine // Peripheral abstraction layer for the stm32l0 import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32l0x2.go b/machine/machine_stm32l0x2.go index 2a74792..4543ae6 100644 --- a/machine/machine_stm32l0x2.go +++ b/machine/machine_stm32l0x2.go @@ -5,9 +5,9 @@ package machine // Peripheral abstraction layer for the stm32l0 import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32l4.go b/machine/machine_stm32l4.go index b5babc0..976420e 100644 --- a/machine/machine_stm32l4.go +++ b/machine/machine_stm32l4.go @@ -3,11 +3,11 @@ package machine import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "errors" - "internal/binary" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/internal/binary" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32l5.go b/machine/machine_stm32l5.go index faa583c..2410de3 100644 --- a/machine/machine_stm32l5.go +++ b/machine/machine_stm32l5.go @@ -5,9 +5,9 @@ package machine // Peripheral abstraction layer for the stm32l5 import ( - "device/stm32" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/device/stm32" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_stm32l5x2.go b/machine/machine_stm32l5x2.go index 82ca1ec..5694d58 100644 --- a/machine/machine_stm32l5x2.go +++ b/machine/machine_stm32l5x2.go @@ -5,7 +5,7 @@ package machine // Peripheral abstraction layer for the stm32f407 import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" ) func CPUFrequency() uint32 { diff --git a/machine/machine_stm32wlx.go b/machine/machine_stm32wlx.go index 80ca791..69514ea 100644 --- a/machine/machine_stm32wlx.go +++ b/machine/machine_stm32wlx.go @@ -5,12 +5,12 @@ package machine // Peripheral abstraction layer for the stm32wle5 import ( - "device/stm32" + "github.com/goplus/emb/device/stm32" "errors" - "internal/binary" + "github.com/goplus/emb/internal/binary" "math/bits" - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/machine_tkey.go b/machine/machine_tkey.go index 78863d8..3bb4518 100644 --- a/machine/machine_tkey.go +++ b/machine/machine_tkey.go @@ -3,7 +3,7 @@ package machine import ( - "device/tkey" + "github.com/goplus/emb/device/tkey" "errors" "strconv" ) diff --git a/machine/serial-rtt.go b/machine/serial-rtt.go index 15f6463..efe7a0f 100644 --- a/machine/serial-rtt.go +++ b/machine/serial-rtt.go @@ -10,8 +10,8 @@ package machine import ( - "runtime/interrupt" - "runtime/volatile" + "github.com/goplus/emb/runtime/interrupt" + "github.com/goplus/emb/runtime/volatile" "unsafe" ) diff --git a/machine/usb.go b/machine/usb.go index 434ee0f..a43a971 100644 --- a/machine/usb.go +++ b/machine/usb.go @@ -3,8 +3,8 @@ package machine import ( - "machine/usb" - "machine/usb/descriptor" + "github.com/goplus/emb/machine/_usb" + "github.com/goplus/emb/machine/_usb/descriptor" "errors" ) diff --git a/machine/virt.go b/machine/virt.go index 2b28ae6..846bb00 100644 --- a/machine/virt.go +++ b/machine/virt.go @@ -8,7 +8,7 @@ package machine import ( "errors" - "runtime/volatile" + "github.com/goplus/emb/runtime/volatile" "sync" "unsafe" ) From e6acc2adb2e302a4584c8b1192b1c3e5cd0b781a Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 21 Nov 2025 18:59:28 +0800 Subject: [PATCH 3/6] feat: Add runtime/interrupt and internal packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add runtime/interrupt package with architecture-specific implementations - Add internal/binary, internal/bytealg, internal/itoa packages - Update import paths to github.com/goplus/emb 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- internal/binary/binary.go | 37 ++ internal/bytealg/bytealg.go | 352 ++++++++++++++++++ internal/itoa/itoa.go | 57 +++ runtime/interrupt/checkpoint.go | 67 ++++ runtime/interrupt/interrupt.go | 39 ++ runtime/interrupt/interrupt_avr.go | 45 +++ runtime/interrupt/interrupt_cortexm.go | 65 ++++ runtime/interrupt/interrupt_esp32c3.go | 239 ++++++++++++ runtime/interrupt/interrupt_gameboyadvance.go | 104 ++++++ runtime/interrupt/interrupt_k210.go | 27 ++ runtime/interrupt/interrupt_none.go | 31 ++ runtime/interrupt/interrupt_sifive.go | 18 + runtime/interrupt/interrupt_tinygoriscv.go | 38 ++ runtime/interrupt/interrupt_xtensa.go | 39 ++ 14 files changed, 1158 insertions(+) create mode 100644 internal/binary/binary.go create mode 100644 internal/bytealg/bytealg.go create mode 100644 internal/itoa/itoa.go create mode 100644 runtime/interrupt/checkpoint.go create mode 100644 runtime/interrupt/interrupt.go create mode 100644 runtime/interrupt/interrupt_avr.go create mode 100644 runtime/interrupt/interrupt_cortexm.go create mode 100644 runtime/interrupt/interrupt_esp32c3.go create mode 100644 runtime/interrupt/interrupt_gameboyadvance.go create mode 100644 runtime/interrupt/interrupt_k210.go create mode 100644 runtime/interrupt/interrupt_none.go create mode 100644 runtime/interrupt/interrupt_sifive.go create mode 100644 runtime/interrupt/interrupt_tinygoriscv.go create mode 100644 runtime/interrupt/interrupt_xtensa.go diff --git a/internal/binary/binary.go b/internal/binary/binary.go new file mode 100644 index 0000000..25f8d39 --- /dev/null +++ b/internal/binary/binary.go @@ -0,0 +1,37 @@ +// Package binary is a lightweight replacement package for encoding/binary. +package binary + +// This file contains small helper functions for working with binary data. + +var LittleEndian = littleEndian{} + +type littleEndian struct{} + +// Encode data like encoding/binary.LittleEndian.Uint16. +func (littleEndian) Uint16(b []byte) uint16 { + return uint16(b[0]) | uint16(b[1])<<8 +} + +// Store data like binary.LittleEndian.PutUint16. +func (littleEndian) PutUint16(b []byte, v uint16) { + b[0] = byte(v) + b[1] = byte(v >> 8) +} + +// Append data like binary.LittleEndian.AppendUint16. +func (littleEndian) AppendUint16(b []byte, v uint16) []byte { + return append(b, + byte(v), + byte(v>>8), + ) +} + +// Encode data like encoding/binary.LittleEndian.Uint32. +func (littleEndian) Uint32(b []byte) uint32 { + return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 +} + +func (littleEndian) Uint64(b []byte) uint64 { + return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | + uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 +} diff --git a/internal/bytealg/bytealg.go b/internal/bytealg/bytealg.go new file mode 100644 index 0000000..33ece2b --- /dev/null +++ b/internal/bytealg/bytealg.go @@ -0,0 +1,352 @@ +package bytealg + +// Some code in this file has been copied from the Go source code, and has +// copyright of their original authors: +// +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. +// +// This is indicated specifically in the file. + +const ( + // Index can search any valid length of string. + + MaxLen = int(-1) >> 31 + MaxBruteForce = MaxLen +) + +// Compare two byte slices. +// Returns -1 if the first differing byte is lower in a, or 1 if the first differing byte is greater in b. +// If the byte slices are equal, returns 0. +// If the lengths are different and there are no differing bytes, compares based on length. +func Compare(a, b []byte) int { + // Compare for differing bytes. + for i := 0; i < len(a) && i < len(b); i++ { + switch { + case a[i] < b[i]: + return -1 + case a[i] > b[i]: + return 1 + } + } + + // Compare lengths. + switch { + case len(a) > len(b): + return 1 + case len(a) < len(b): + return -1 + default: + return 0 + } +} + +// This function was copied from the Go 1.23 source tree (with runtime_cmpstring +// manually inlined). +func CompareString(a, b string) int { + l := len(a) + if len(b) < l { + l = len(b) + } + for i := 0; i < l; i++ { + c1, c2 := a[i], b[i] + if c1 < c2 { + return -1 + } + if c1 > c2 { + return +1 + } + } + if len(a) < len(b) { + return -1 + } + if len(a) > len(b) { + return +1 + } + return 0 +} + +// Count the number of instances of a byte in a slice. +func Count(b []byte, c byte) int { + // Use a simple implementation, as there is no intrinsic that does this like we want. + n := 0 + for _, v := range b { + if v == c { + n++ + } + } + return n +} + +// Count the number of instances of a byte in a string. +func CountString(s string, c byte) int { + // Use a simple implementation, as there is no intrinsic that does this like we want. + // Currently, the compiler does not generate zero-copy byte-string conversions, so this needs to be separate from Count. + n := 0 + for i := 0; i < len(s); i++ { + if s[i] == c { + n++ + } + } + return n +} + +// Cutover is not reachable in TinyGo, but must exist as it is referenced. +func Cutover(n int) int { + // Setting MaxLen and MaxBruteForce should force a different path to be taken. + // This should never be called. + panic("cutover is unreachable") +} + +// Equal checks if two byte slices are equal. +// It is equivalent to bytes.Equal. +func Equal(a, b []byte) bool { + if len(a) != len(b) { + return false + } + + for i, v := range a { + if v != b[i] { + return false + } + } + + return true +} + +// Index finds the base index of the first instance of the byte sequence b in a. +// If a does not contain b, this returns -1. +func Index(a, b []byte) int { + for i := 0; i <= len(a)-len(b); i++ { + if Equal(a[i:i+len(b)], b) { + return i + } + } + return -1 +} + +// Index finds the index of the first instance of the specified byte in the slice. +// If the byte is not found, this returns -1. +func IndexByte(b []byte, c byte) int { + for i, v := range b { + if v == c { + return i + } + } + return -1 +} + +// Index finds the index of the first instance of the specified byte in the string. +// If the byte is not found, this returns -1. +func IndexByteString(s string, c byte) int { + for i := 0; i < len(s); i++ { + if s[i] == c { + return i + } + } + return -1 +} + +// Index finds the base index of the first instance of a substring in a string. +// If the substring is not found, this returns -1. +func IndexString(str, sub string) int { + for i := 0; i <= len(str)-len(sub); i++ { + if str[i:i+len(sub)] == sub { + return i + } + } + return -1 +} + +// The following code has been copied from the Go 1.15 release tree. + +// PrimeRK is the prime base used in Rabin-Karp algorithm. +const PrimeRK = 16777619 + +// HashStrBytes returns the hash and the appropriate multiplicative +// factor for use in Rabin-Karp algorithm. +// +// This function was removed in Go 1.22. +func HashStrBytes(sep []byte) (uint32, uint32) { + hash := uint32(0) + for i := 0; i < len(sep); i++ { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// HashStr returns the hash and the appropriate multiplicative +// factor for use in Rabin-Karp algorithm. +// +// This function was removed in Go 1.22. +func HashStr[T string | []byte](sep T) (uint32, uint32) { + hash := uint32(0) + for i := 0; i < len(sep); i++ { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// HashStrRevBytes returns the hash of the reverse of sep and the +// appropriate multiplicative factor for use in Rabin-Karp algorithm. +// +// This function was removed in Go 1.22. +func HashStrRevBytes(sep []byte) (uint32, uint32) { + hash := uint32(0) + for i := len(sep) - 1; i >= 0; i-- { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// HashStrRev returns the hash of the reverse of sep and the +// appropriate multiplicative factor for use in Rabin-Karp algorithm. +// +// Copied from the Go 1.22rc1 source tree. +func HashStrRev[T string | []byte](sep T) (uint32, uint32) { + hash := uint32(0) + for i := len(sep) - 1; i >= 0; i-- { + hash = hash*PrimeRK + uint32(sep[i]) + } + var pow, sq uint32 = 1, PrimeRK + for i := len(sep); i > 0; i >>= 1 { + if i&1 != 0 { + pow *= sq + } + sq *= sq + } + return hash, pow +} + +// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the +// first occurrence of substr in s, or -1 if not present. +// +// This function was removed in Go 1.22. +func IndexRabinKarpBytes(s, sep []byte) int { + // Rabin-Karp search + hashsep, pow := HashStrBytes(sep) + n := len(sep) + var h uint32 + for i := 0; i < n; i++ { + h = h*PrimeRK + uint32(s[i]) + } + if h == hashsep && Equal(s[:n], sep) { + return 0 + } + for i := n; i < len(s); { + h *= PrimeRK + h += uint32(s[i]) + h -= pow * uint32(s[i-n]) + i++ + if h == hashsep && Equal(s[i-n:i], sep) { + return i - n + } + } + return -1 +} + +// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the +// first occurrence of sep in s, or -1 if not present. +// +// Copied from the Go 1.22rc1 source tree. +func IndexRabinKarp[T string | []byte](s, sep T) int { + // Rabin-Karp search + hashss, pow := HashStr(sep) + n := len(sep) + var h uint32 + for i := 0; i < n; i++ { + h = h*PrimeRK + uint32(s[i]) + } + if h == hashss && string(s[:n]) == string(sep) { + return 0 + } + for i := n; i < len(s); { + h *= PrimeRK + h += uint32(s[i]) + h -= pow * uint32(s[i-n]) + i++ + if h == hashss && string(s[i-n:i]) == string(sep) { + return i - n + } + } + return -1 +} + +// MakeNoZero makes a slice of length and capacity n without zeroing the bytes. +// It is the caller's responsibility to ensure uninitialized bytes +// do not leak to the end user. +func MakeNoZero(n int) []byte { + // Note: this does zero the buffer even though that's not necessary. + // For performance reasons we might want to change this (similar to the + // malloc function implemented in the runtime). + return make([]byte, n) +} + +// Copied from the Go 1.22rc1 source tree. +func LastIndexByte(s []byte, c byte) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == c { + return i + } + } + return -1 +} + +// Copied from the Go 1.22rc1 source tree. +func LastIndexByteString(s string, c byte) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == c { + return i + } + } + return -1 +} + +// LastIndexRabinKarp uses the Rabin-Karp search algorithm to return the last index of the +// occurrence of sep in s, or -1 if not present. +// +// Copied from the Go 1.22rc1 source tree. +func LastIndexRabinKarp[T string | []byte](s, sep T) int { + // Rabin-Karp search from the end of the string + hashss, pow := HashStrRev(sep) + n := len(sep) + last := len(s) - n + var h uint32 + for i := len(s) - 1; i >= last; i-- { + h = h*PrimeRK + uint32(s[i]) + } + if h == hashss && string(s[last:]) == string(sep) { + return last + } + for i := last - 1; i >= 0; i-- { + h *= PrimeRK + h += uint32(s[i]) + h -= pow * uint32(s[i+n]) + if h == hashss && string(s[i:i+n]) == string(sep) { + return i + } + } + return -1 +} diff --git a/internal/itoa/itoa.go b/internal/itoa/itoa.go new file mode 100644 index 0000000..4340ae0 --- /dev/null +++ b/internal/itoa/itoa.go @@ -0,0 +1,57 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Simple conversions to avoid depending on strconv. + +package itoa + +// Itoa converts val to a decimal string. +func Itoa(val int) string { + if val < 0 { + return "-" + Uitoa(uint(-val)) + } + return Uitoa(uint(val)) +} + +// Uitoa converts val to a decimal string. +func Uitoa(val uint) string { + if val == 0 { // avoid string allocation + return "0" + } + var buf [20]byte // big enough for 64bit value base 10 + i := len(buf) - 1 + for val >= 10 { + q := val / 10 + buf[i] = byte('0' + val - q*10) + i-- + val = q + } + // val < 10 + buf[i] = byte('0' + val) + return string(buf[i:]) +} + +const hex = "0123456789abcdef" + +// Uitox converts val (a uint) to a hexadecimal string. +func Uitox(val uint) string { + if val == 0 { // avoid string allocation + return "0x0" + } + var buf [20]byte // big enough for 64bit value base 16 + 0x + i := len(buf) - 1 + for val >= 16 { + q := val / 16 + buf[i] = hex[val%16] + i-- + val = q + } + // val < 16 + buf[i] = hex[val%16] + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + return string(buf[i:]) +} diff --git a/runtime/interrupt/checkpoint.go b/runtime/interrupt/checkpoint.go new file mode 100644 index 0000000..2ce0b31 --- /dev/null +++ b/runtime/interrupt/checkpoint.go @@ -0,0 +1,67 @@ +package interrupt + +import _ "unsafe" + +// A checkpoint is a setjmp like buffer, that can be used as a flag for +// interrupts. +// +// It can be used as follows: +// +// // global var +// var c Checkpoint +// +// // to set up the checkpoint and wait for it +// if c.Save() { +// setupInterrupt() +// for { +// waitForInterrupt() +// } +// } +// +// // Inside the interrupt handler: +// if c.Saved() { +// c.Jump() +// } +type Checkpoint struct { + jumpSP uintptr + jumpPC uintptr +} + +// Save the execution state in the given checkpoint, overwriting a previous +// saved checkpoint. +// +// This function returns twice: once the normal way after saving (returning +// true) and once after jumping (returning false). +// +// This function is a compiler intrinsic, it is not implemented in Go. +// TODO(zzy): implement Save +func (c *Checkpoint) Save() bool { + panic("todo:Checkpoint.Save") +} + +// Returns whether a jump point was saved (and not erased due to a jump). +func (c *Checkpoint) Saved() bool { + return c.jumpPC != 0 +} + +// Jump to the point where the execution state was saved, and erase the saved +// jump point. This must *only* be called from inside an interrupt. +// +// This method does not return in the conventional way, it resumes execution at +// the last point a checkpoint was saved. +func (c *Checkpoint) Jump() { + if !c.Saved() { + panic("runtime/interrupt: no checkpoint was saved") + } + jumpPC := c.jumpPC + jumpSP := c.jumpSP + c.jumpPC = 0 + c.jumpSP = 0 + if jumpPC == 0 { + panic("jumping to 0") + } + checkpointJump(jumpSP, jumpPC) +} + +//go:linkname checkpointJump __llgo_checkpointJump +func checkpointJump(jumpSP, jumpPC uintptr) diff --git a/runtime/interrupt/interrupt.go b/runtime/interrupt/interrupt.go new file mode 100644 index 0000000..aa3f149 --- /dev/null +++ b/runtime/interrupt/interrupt.go @@ -0,0 +1,39 @@ +// Package interrupt provides access to hardware interrupts. It provides a way +// to define interrupts and to enable/disable them. +package interrupt + +import "unsafe" + +// Interrupt provides direct access to hardware interrupts. You can configure +// this interrupt through this interface. +// +// Do not use the zero value of an Interrupt object. Instead, call New to obtain +// an interrupt handle. +type Interrupt struct { + // Make this number unexported so it cannot be set directly. This provides + // some encapsulation. + num int +} + +// New is a compiler intrinsic that creates a new Interrupt object. You may call +// it only once, and must pass constant parameters to it. That means that the +// interrupt ID must be a Go constant and that the handler must be a simple +// function: closures are not supported. +// TODO(zzy): implement New +func New(id int, handler func(Interrupt)) Interrupt { + panic("todo:interrupt.New") +} + +// handle is used internally, between IR generation and interrupt lowering. The +// frontend will create runtime/interrupt.handle objects, cast them to an int, +// and use that in an Interrupt object. That way the compiler will be able to +// optimize away all interrupt handles that are never used in a program. +// This system only works when interrupts need to be enabled before use and this +// is done only through calling Enable() on this object. If interrupts cannot +// individually be enabled/disabled, the compiler should create a pseudo-call +// (like runtime/interrupt.use()) that keeps the interrupt alive. +type handle struct { + context unsafe.Pointer + funcPtr uintptr + Interrupt +} diff --git a/runtime/interrupt/interrupt_avr.go b/runtime/interrupt/interrupt_avr.go new file mode 100644 index 0000000..9e75cf7 --- /dev/null +++ b/runtime/interrupt/interrupt_avr.go @@ -0,0 +1,45 @@ +//go:build avr + +package interrupt + +import "github.com/goplus/emb/device" + +// State represents the previous global interrupt state. +type State uint8 + +// Disable disables all interrupts and returns the previous interrupt state. It +// can be used in a critical section like this: +// +// state := interrupt.Disable() +// // critical section +// interrupt.Restore(state) +// +// Critical sections can be nested. Make sure to call Restore in the same order +// as you called Disable (this happens naturally with the pattern above). +func Disable() (state State) { + // SREG is at I/O address 0x3f. + return State(device.AsmFull(` + in {}, 0x3f + cli + `, nil)) +} + +// Restore restores interrupts to what they were before. Give the previous state +// returned by Disable as a parameter. If interrupts were disabled before +// calling Disable, this will not re-enable interrupts, allowing for nested +// critical sections. +func Restore(state State) { + // SREG is at I/O address 0x3f. + device.AsmFull("out 0x3f, {state}", map[string]interface{}{ + "state": state, + }) +} + +// In returns whether the system is currently in an interrupt. +// +// Warning: this always returns false on AVR, as there does not appear to be a +// reliable way to determine whether we're currently running inside an interrupt +// handler. +func In() bool { + return false +} diff --git a/runtime/interrupt/interrupt_cortexm.go b/runtime/interrupt/interrupt_cortexm.go new file mode 100644 index 0000000..467d08a --- /dev/null +++ b/runtime/interrupt/interrupt_cortexm.go @@ -0,0 +1,65 @@ +//go:build cortexm + +package interrupt + +import ( + "github.com/goplus/emb/device/arm" +) + +// Enable enables this interrupt. Right after calling this function, the +// interrupt may be invoked if it was already pending. +func (irq Interrupt) Enable() { + // Clear the ARM pending bit, an asserting device may still + // trigger the interrupt once enabled. + arm.ClearPendingIRQ(uint32(irq.num)) + arm.EnableIRQ(uint32(irq.num)) +} + +// Disable disables this interrupt. +func (irq Interrupt) Disable() { + arm.DisableIRQ(uint32(irq.num)) +} + +// SetPriority sets the interrupt priority for this interrupt. A lower number +// means a higher priority. Additionally, most hardware doesn't implement all +// priority bits (only the uppoer bits). +// +// Examples: 0xff (lowest priority), 0xc0 (low priority), 0x00 (highest possible +// priority). +func (irq Interrupt) SetPriority(priority uint8) { + arm.SetPriority(uint32(irq.num), uint32(priority)) +} + +// State represents the previous global interrupt state. +type State uintptr + +// Disable disables all interrupts and returns the previous interrupt state. It +// can be used in a critical section like this: +// +// state := interrupt.Disable() +// // critical section +// interrupt.Restore(state) +// +// Critical sections can be nested. Make sure to call Restore in the same order +// as you called Disable (this happens naturally with the pattern above). +func Disable() (state State) { + return State(arm.DisableInterrupts()) +} + +// Restore restores interrupts to what they were before. Give the previous state +// returned by Disable as a parameter. If interrupts were disabled before +// calling Disable, this will not re-enable interrupts, allowing for nested +// critical sections. +func Restore(state State) { + arm.EnableInterrupts(uintptr(state)) +} + +// In returns whether the system is currently in an interrupt. +func In() bool { + // The VECTACTIVE field gives the instruction vector that is currently + // active (in handler mode), or 0 if not in an interrupt. + // Documentation: + // https://developer.arm.com/documentation/dui0497/a/cortex-m0-peripherals/system-control-block/interrupt-control-and-state-register + vectactive := uint8(arm.SCB.ICSR.Get()) + return vectactive != 0 +} diff --git a/runtime/interrupt/interrupt_esp32c3.go b/runtime/interrupt/interrupt_esp32c3.go new file mode 100644 index 0000000..359c980 --- /dev/null +++ b/runtime/interrupt/interrupt_esp32c3.go @@ -0,0 +1,239 @@ +//go:build esp32c3 + +package interrupt + +import ( + "errors" + "unsafe" + + "github.com/goplus/emb/device/esp" + "github.com/goplus/emb/device/riscv" + "github.com/goplus/emb/runtime/volatile" +) + +// Enable register CPU interrupt with interrupt.Interrupt. +// The ESP32-C3 has 31 CPU independent interrupts. +// The Interrupt.New(x, f) (x = [1..31]) attaches CPU interrupt to function f. +// Caller must map the selected interrupt using following sequence (for example using id 5): +// +// // map interrupt 5 to my XXXX module +// esp.INTERRUPT_CORE0.XXXX_INTERRUPT_PRO_MAP.Set( 5 ) +// _ = Interrupt.New(5, func(interrupt.Interrupt) { +// ... +// }).Enable() +func (i Interrupt) Enable() error { + if i.num < 1 && i.num > 31 { + return errors.New("interrupt for ESP32-C3 must be in range of 1 through 31") + } + + // TODO(zzy):https://github.com/goplus/llgo/issues/1290 + // mask := riscv.DisableInterrupts() + // defer riscv.EnableInterrupts(mask) + + // enable CPU interrupt number i.num + esp.INTERRUPT_CORE0.CPU_INT_ENABLE.SetBits(1 << i.num) + + // Set pulse interrupt type (rising edge detection) + esp.INTERRUPT_CORE0.CPU_INT_TYPE.SetBits(1 << i.num) + + // Set default threshold to defaultThreshold + reg := (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.INTERRUPT_CORE0.CPU_INT_PRI_0), i.num*4)) + reg.Set(defaultThreshold) + + // Reset interrupt before reenabling + esp.INTERRUPT_CORE0.CPU_INT_CLEAR.SetBits(1 << i.num) + esp.INTERRUPT_CORE0.CPU_INT_CLEAR.ClearBits(1 << i.num) + + // we must wait for any pending write operations to complete + riscv.Asm("fence") + return nil +} + +// Adding pseudo function calls that is replaced by the compiler with the actual +// functions registered through interrupt.New. +// +//go:linkname callHandlers runtime/interrupt.callHandlers +func callHandlers(num int) + +const ( + IRQNUM_1 = 1 + iota + IRQNUM_2 + IRQNUM_3 + IRQNUM_4 + IRQNUM_5 + IRQNUM_6 + IRQNUM_7 + IRQNUM_8 + IRQNUM_9 + IRQNUM_10 + IRQNUM_11 + IRQNUM_12 + IRQNUM_13 + IRQNUM_14 + IRQNUM_15 + IRQNUM_16 + IRQNUM_17 + IRQNUM_18 + IRQNUM_19 + IRQNUM_20 + IRQNUM_21 + IRQNUM_22 + IRQNUM_23 + IRQNUM_24 + IRQNUM_25 + IRQNUM_26 + IRQNUM_27 + IRQNUM_28 + IRQNUM_29 + IRQNUM_30 + IRQNUM_31 +) + +const ( + defaultThreshold = 5 + disableThreshold = 10 +) + +//go:inline +func callHandler(n int) { + switch n { + case IRQNUM_1: + callHandlers(IRQNUM_1) + case IRQNUM_2: + callHandlers(IRQNUM_2) + case IRQNUM_3: + callHandlers(IRQNUM_3) + case IRQNUM_4: + callHandlers(IRQNUM_4) + case IRQNUM_5: + callHandlers(IRQNUM_5) + case IRQNUM_6: + callHandlers(IRQNUM_6) + case IRQNUM_7: + callHandlers(IRQNUM_7) + case IRQNUM_8: + callHandlers(IRQNUM_8) + case IRQNUM_9: + callHandlers(IRQNUM_9) + case IRQNUM_10: + callHandlers(IRQNUM_10) + case IRQNUM_11: + callHandlers(IRQNUM_11) + case IRQNUM_12: + callHandlers(IRQNUM_12) + case IRQNUM_13: + callHandlers(IRQNUM_13) + case IRQNUM_14: + callHandlers(IRQNUM_14) + case IRQNUM_15: + callHandlers(IRQNUM_15) + case IRQNUM_16: + callHandlers(IRQNUM_16) + case IRQNUM_17: + callHandlers(IRQNUM_17) + case IRQNUM_18: + callHandlers(IRQNUM_18) + case IRQNUM_19: + callHandlers(IRQNUM_19) + case IRQNUM_20: + callHandlers(IRQNUM_20) + case IRQNUM_21: + callHandlers(IRQNUM_21) + case IRQNUM_22: + callHandlers(IRQNUM_22) + case IRQNUM_23: + callHandlers(IRQNUM_23) + case IRQNUM_24: + callHandlers(IRQNUM_24) + case IRQNUM_25: + callHandlers(IRQNUM_25) + case IRQNUM_26: + callHandlers(IRQNUM_26) + case IRQNUM_27: + callHandlers(IRQNUM_27) + case IRQNUM_28: + callHandlers(IRQNUM_28) + case IRQNUM_29: + callHandlers(IRQNUM_29) + case IRQNUM_30: + callHandlers(IRQNUM_30) + case IRQNUM_31: + callHandlers(IRQNUM_31) + } +} + +//TODO(zzy): origin with export handleInterrupt +// func handleInterrupt() { +// mcause := riscv.MCAUSE.Get() +// exception := mcause&(1<<31) == 0 +// interruptNumber := uint32(mcause & 0x1f) + +// if !exception && interruptNumber > 0 { +// // save MSTATUS & MEPC, which could be overwritten by another CPU interrupt +// mstatus := riscv.MSTATUS.Get() +// mepc := riscv.MEPC.Get() +// // Using threshold to temporary disable this interrupts. +// // FYI: using CPU interrupt enable bit make runtime to loose interrupts. +// reg := (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&esp.INTERRUPT_CORE0.CPU_INT_PRI_0), interruptNumber*4)) +// thresholdSave := reg.Get() +// reg.Set(disableThreshold) +// riscv.Asm("fence") + +// interruptBit := uint32(1 << interruptNumber) + +// // reset pending status interrupt +// if esp.INTERRUPT_CORE0.CPU_INT_TYPE.Get()&interruptBit != 0 { +// // this is edge type interrupt +// esp.INTERRUPT_CORE0.CPU_INT_CLEAR.SetBits(interruptBit) +// esp.INTERRUPT_CORE0.CPU_INT_CLEAR.ClearBits(interruptBit) +// } else { +// // this is level type interrupt +// esp.INTERRUPT_CORE0.CPU_INT_CLEAR.ClearBits(interruptBit) +// } + +// // enable CPU interrupts +// riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE) + +// // Call registered interrupt handler(s) +// callHandler(int(interruptNumber)) + +// // disable CPU interrupts +// riscv.MSTATUS.ClearBits(riscv.MSTATUS_MIE) + +// // restore interrupt threshold to enable interrupt again +// reg.Set(thresholdSave) +// riscv.Asm("fence") + +// // restore MSTATUS & MEPC +// riscv.MSTATUS.Set(mstatus) +// riscv.MEPC.Set(mepc) + +// // do not enable CPU interrupts now +// // the 'MRET' in src/device/riscv/handleinterrupt.S will copies the state of MPIE back into MIE, and subsequently clears MPIE. +// // riscv.MSTATUS.SetBits(riscv.MSTATUS_MIE) +// } else { +// // Topmost bit is clear, so it is an exception of some sort. +// // We could implement support for unsupported instructions here (such as +// // misaligned loads). However, for now we'll just print a fatal error. +// handleException(mcause) +// } +// } + +func handleException(mcause uintptr) { + println("*** Exception: pc:", riscv.MEPC.Get()) + println("*** Exception: code:", uint32(mcause&0x1f)) + println("*** Exception: mcause:", mcause) + switch uint32(mcause & 0x1f) { + case riscv.InstructionAccessFault: + println("*** virtual address:", riscv.MTVAL.Get()) + case riscv.IllegalInstruction: + println("*** opcode:", riscv.MTVAL.Get()) + case riscv.LoadAccessFault: + println("*** read address:", riscv.MTVAL.Get()) + case riscv.StoreOrAMOAccessFault: + println("*** write address:", riscv.MTVAL.Get()) + } + for { + riscv.Asm("wfi") + } +} diff --git a/runtime/interrupt/interrupt_gameboyadvance.go b/runtime/interrupt/interrupt_gameboyadvance.go new file mode 100644 index 0000000..ca3da76 --- /dev/null +++ b/runtime/interrupt/interrupt_gameboyadvance.go @@ -0,0 +1,104 @@ +//go:build gameboyadvance + +package interrupt + +// This is good documentation of the GBA: https://www.akkit.org/info/gbatek.htm + +import ( + "github.com/goplus/emb/device/gba" +) + +// Enable enables this interrupt. Right after calling this function, the +// interrupt may be invoked if it was already pending. +func (irq Interrupt) Enable() { + gba.INTERRUPT.IE.SetBits(1 << uint(irq.num)) +} + +var inInterrupt bool + +//TODO(zzy): origin with export handleInterrupt +// func handleInterrupt() { +// inInterrupt = true +// flags := gba.INTERRUPT.IF.Get() +// for i := 0; i < 14; i++ { +// if flags&(1< Date: Fri, 21 Nov 2025 19:01:43 +0800 Subject: [PATCH 4/6] fix: Change LLGoPackage from "decl" to "link" in volatile.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/validate-embed-packages.yml | 2 +- runtime/volatile/volatile.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/validate-embed-packages.yml b/.github/workflows/validate-embed-packages.yml index 38d4b26..a35f27c 100644 --- a/.github/workflows/validate-embed-packages.yml +++ b/.github/workflows/validate-embed-packages.yml @@ -38,7 +38,7 @@ jobs: - name: Setup LLGO uses: ./.github/actions/setup-llgo with: - commit-hash: 2d80951e7d8f5823c1fa92c8a7cb5dd351a10e6a + commit-hash: b25ae1b4e7c06a302d1d09eb9e9b0ad1e3a43abd - name: Run Machine Package Validation run: | ./.github/scripts/validate_embed_packages.sh machine diff --git a/runtime/volatile/volatile.go b/runtime/volatile/volatile.go index ead2e7d..b96248e 100644 --- a/runtime/volatile/volatile.go +++ b/runtime/volatile/volatile.go @@ -18,7 +18,7 @@ package volatile import _ "unsafe" const ( - LLGoPackage = "decl" + LLGoPackage = "link" ) // LoadUint8 loads the volatile value *addr. From 07f161b1baea1b44228812837915b50609791c3c Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 21 Nov 2025 19:49:22 +0800 Subject: [PATCH 5/6] chore: Add github.com/goplus/lib dependency for lib/c package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- go.mod | 2 ++ go.sum | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 go.sum diff --git a/go.mod b/go.mod index 49127c4..691754b 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/goplus/emb go 1.20 + +require github.com/goplus/lib v0.3.1 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..ef2a092 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/goplus/lib v0.3.1 h1:Xws4DBVvgOMu58awqB972wtvTacDbk3nqcbHjdx9KSg= +github.com/goplus/lib v0.3.1/go.mod h1:SgJv3oPqLLHCu0gcL46ejOP3x7/2ry2Jtxu7ta32kp0= From ed381fd483a876435fc0d68630d20fa256e1bc95 Mon Sep 17 00:00:00 2001 From: luoliwoshang <2643523683@qq.com> Date: Fri, 21 Nov 2025 22:04:08 +0800 Subject: [PATCH 6/6] ci:test esp32-mini32,esp32c3-supermini --- .github/scripts/validate_embed_packages.sh | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/scripts/validate_embed_packages.sh b/.github/scripts/validate_embed_packages.sh index 2c413c9..967cdb0 100755 --- a/.github/scripts/validate_embed_packages.sh +++ b/.github/scripts/validate_embed_packages.sh @@ -175,13 +175,9 @@ MACHINE_VALIDATION_TARGETS=( # 2 errors generated. # panic: export object of internal/abi failed: exit status 1 - # "esp32-mini32" - # ld.lld: error: section 'text' will not fit in region 'iram_seg': overflowed by 13157 bytes - # binaray too large https://github.com/goplus/llgo/issues/1317 - - # "esp32c3-supermini" - # ld.lld: error: region DRAM overflowed by .data and .bss sections + "esp32-mini32" + "esp32c3-supermini" # "nodemcu" # compile picolibcnewlib/libc/tinystdio/puts.c fail