├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── main.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CMakeLists.txt ├── CNAME ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── amaranth ├── debouncer.py ├── handshake.py ├── install_dependencies.sh ├── pico_ice.py ├── spi.py └── spibone.py ├── cmake └── preinit_pico_ice_sdk.cmake ├── examples ├── README.md ├── ice_apio_blinky │ ├── .gitignore │ ├── README.md │ ├── apio.ini │ ├── top.v │ └── up5k.pcf ├── ice_apio_uart_echo │ ├── .gitignore │ ├── README.md │ ├── apio.ini │ ├── pico_ice.pcf │ └── top.v ├── ice_makefile_blinky │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── ice40.pcf │ └── top.sv ├── ice_makefile_iverilog_counter │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── ice40.pcf │ ├── ice40.sv │ ├── iverilog.vvp │ ├── testbench.sv │ ├── top.sv │ ├── verilator.cpp │ └── vsim.h ├── ice_makefile_verilator_counter │ ├── .gitignore │ ├── Makefile │ ├── README.md │ ├── ice40.pcf │ ├── ice40.sv │ ├── top.sv │ ├── verilator.cpp │ └── vsim.h ├── rp2_blinky │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ └── pico_sdk_import.cmake ├── rp2_blinky_cplusplus │ ├── CMakeLists.txt │ ├── README.md │ ├── main.cpp │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ ├── tusb_config.h │ └── usb_descriptors.c ├── rp2_cram │ ├── CMakeLists.txt │ ├── README.md │ ├── bitstream.h │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ ├── rgb_blink.bin │ ├── rgb_blink.h │ └── rgb_blink.py ├── rp2_flash │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ └── test.py ├── rp2_flash_repl │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ └── test.py ├── rp2_fpga │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ └── pico_sdk_import.cmake ├── rp2_fpga_io │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ ├── soc.py │ ├── top.py │ ├── tusb_config.h │ └── usb_descriptors.c ├── rp2_hello_world │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ └── test.py ├── rp2_ice_blinky │ ├── CMakeLists.txt │ ├── README.md │ ├── bin2header.py │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_ice.pcf │ ├── pico_sdk_import.cmake │ └── top.v ├── rp2_sram │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ └── test.py ├── rp2_usb_fpga │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ ├── test.py │ ├── tusb_config.h │ └── usb_descriptors.c ├── rp2_usb_keyboard │ ├── CMakeLists.txt │ ├── README.md │ ├── STATUS_UNSUPPORTED │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ └── tusb_config.h ├── rp2_usb_spi │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_ice_spi.py │ ├── pico_sdk_import.cmake │ ├── test.py │ ├── tusb_config.h │ └── usb_descriptors.c ├── rp2_usb_uart │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ ├── main.c │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ ├── tusb_config.h │ └── usb_descriptors.c └── rp2_usb_uf2 │ ├── .gitignore │ ├── CMakeLists.txt │ ├── README.md │ ├── blinky.uf2 │ ├── main.c │ ├── null.uf2 │ ├── pico-ice-sdk │ ├── pico-sdk │ ├── pico_sdk_import.cmake │ ├── tusb_config.h │ └── usb_descriptors.c ├── include ├── boards.h ├── boards │ ├── ice40up5k.h │ ├── pico2_ice.h │ └── pico_ice.h ├── ice_HAL.h ├── ice_cram.h ├── ice_flash.h ├── ice_fpga.h ├── ice_fpga_data.h ├── ice_led.h ├── ice_pmod.h └── ice_usb.h ├── rtl └── pico_ice.pcf ├── src ├── ice_cram.c ├── ice_cram.pio ├── ice_flash.c ├── ice_fpga.c ├── ice_fpga_data.c ├── ice_led.c ├── ice_usb.c ├── pico-sdk_ice_hal.c ├── tinyuf2_board.c ├── tinyuf2_include.c └── tinyuf2_main.c └── tools ├── .gitignore └── 70-pico-ice.rules /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ../CONTRIBUTING.md -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: build_on_push 2 | 3 | on: 4 | push: 5 | branches: [ "main", "rp2350_ice", "pico2-ice_develop" ] 6 | pull_request: 7 | branches: [ "main", "develop", "pico2-ice_develop" ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | firmware: 12 | runs-on: ubuntu-24.04 13 | 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | cmake_build_type: [Debug] 18 | pico: [ {board: "pico_ice", platform: "rp2040"}, {board: "pico2_ice", platform: "rp2350"}, {board: "pico2_ice", platform: "rp2350-riscv"}] 19 | 20 | example: 21 | - rp2_blinky 22 | - rp2_blinky_cplusplus 23 | - rp2_cram 24 | - rp2_flash 25 | - rp2_flash_repl 26 | - rp2_fpga 27 | - rp2_fpga_io 28 | - rp2_hello_world 29 | - rp2_sram 30 | - rp2_usb_fpga 31 | - rp2_usb_keyboard 32 | - rp2_usb_spi 33 | - rp2_usb_uart 34 | - rp2_usb_uf2 35 | steps: 36 | - uses: actions/checkout@v4 37 | 38 | - name: arm-none-eabi-gcc GNU Arm Embedded Toolchain 39 | if: ${{ !contains(matrix.pico.platform, 'riscv') }} 40 | uses: carlosperate/arm-none-eabi-gcc-action@v1.10.0 41 | 42 | - name: riscv Toolchain env 43 | if: ${{ contains(matrix.pico.platform, 'riscv') }} 44 | run: | 45 | echo "PICO_TOOLCHAIN_PATH=${PWD}/riscv_toolchain/corev-openhw-gcc-ubuntu2204-20240530" >> $GITHUB_ENV 46 | 47 | - name: Setup cmake 48 | uses: jwlawson/actions-setup-cmake@v2 49 | 50 | - name: Cache Submodules 51 | id: cache-submodules 52 | uses: actions/cache@v4 53 | with: 54 | path: lib 55 | key: ${{ runner.os }}-build-submodules-${{ hashFiles('lib/**') }} 56 | restore-keys: | 57 | ${{ runner.os }}-build-submodules 58 | 59 | - name: Cache riscv toolchain 60 | id: cache-riscv-toolchain 61 | if: ${{ contains(matrix.pico.platform, 'riscv') }} 62 | uses: actions/cache@v4 63 | with: 64 | path: riscv_toolchain 65 | key: ${{ runner.os }}-build-riscv_toolchain-${{ hashFiles('riscv_toolchain/**') }} 66 | restore-keys: | 67 | ${{ runner.os }}-build-riscv_toolchain 68 | 69 | - name: Fetch submodules 70 | if: steps.cache-submodules.outputs.cache-hit != 'true' 71 | run: | 72 | git submodule update --init 73 | git -C lib/pico-sdk submodule update --init 74 | 75 | - name: Fetch riscv toolchain 76 | if: ${{ contains(matrix.pico.platform, 'riscv') && steps.cache-riscv-toolchain.outputs.cache-hit != 'true'}} 77 | run: | 78 | mkdir riscv_toolchain 79 | cd riscv_toolchain 80 | export TC_NAME=corev-openhw-gcc-ubuntu2204-20240530 81 | wget https://buildbot.embecosm.com/job/corev-gcc-ubuntu2204/47/artifact/${TC_NAME}.tar.gz 82 | tar -xf ${TC_NAME}.tar.gz 83 | 84 | - name: Build each example on every commit 85 | run: | 86 | cd examples/${{ matrix.example }} 87 | mkdir -p build 88 | cd build 89 | cmake -DCMAKE_BUILD_TYPE=${{ matrix.cmake_build_type }} -DPICO_BOARD=${{ matrix.pico.board }} -DPICO_PLATFORM=${{ matrix.pico.platform }} .. 90 | make 91 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | __pycache__ 3 | *.vcd 4 | *.gtkw 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/pico-sdk"] 2 | path = lib/pico-sdk 3 | url = https://github.com/raspberrypi/pico-sdk 4 | [submodule "lib/tinyuf2"] 5 | path = lib/tinyuf2 6 | url = https://github.com/adafruit/tinyuf2 7 | [submodule "doc/doxygen-awesome-css"] 8 | path = doc/doxygen-awesome-css 9 | url = https://github.com/jothepro/doxygen-awesome-css.git 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | ## v2.0.0b 3 | 4 | * BETA: initial changes for pico2-ice 5 | 6 | 7 | ## v1.5.0 8 | 9 | * In the USB DFU interface, swap the alt=0 and alt=1 numbers to get APIO and 10 | IceStudio to work again out of the box. 11 | 12 | * Fix DFU CRAM programming. 13 | 14 | ## v1.3.1 15 | 16 | * Make USB enumerate better in MacOS and everywhere (@dicristina). 17 | 18 | ## v1.3.0 19 | 20 | * Switch SPI to hardware back-end with DMA (@MichaelBell). 21 | This applies to all code as `` is used everywhere. 22 | 23 | * Introduce ICE_USB_SPI_CDC: a new USB protocol to access the various SPI 24 | parts, along with a new host-side python library for it. 25 | 26 | ## v1.2.1 27 | 28 | * With the default firmware, the FPGA was rebooting after a few seconds due 29 | to the operating system reading the USB interface. We now let the FPGA run 30 | even when that happens, and only reset it on write calls. 31 | 32 | ## v1.2.0 33 | 34 | * Fix UART forwarding in the SDK while used in combination with the TinyUF2 35 | firmware, which resurfced again. 36 | 37 | * Offer a reduced API for configuring forwarding of UART among other things. 38 | Improved documentation in parallel. 39 | 40 | ## v1.1.2 41 | 42 | * Fix TinyUF2 stopping the FPGA while being read, which happens at every boot 43 | with the operating system peeking at the various files in the USB drive out 44 | of curiosity. 45 | 46 | * Fix UART forwarding in the SDK while used in combination with the TinyUF2 47 | firmware, which takes over the default UART for logging. 48 | 49 | ## v1.1.1 50 | 51 | * Fix UART forwarding in the SDK and example. 52 | 53 | ## v1.1.0 54 | 55 | * Fix TinyUF2 on Windows 56 | * Easier USB configuration only requiring to change `tusb_config.h`. 57 | 58 | ## v1.0.0 59 | 60 | * Libraries to communicate with each chip of the device 61 | * All exapmles working except pico_fpga_io and pico_usb_keyboard 62 | 63 | ## v0.1.0 64 | 65 | * (fix) PIO-based CRAM programming works again 66 | * The bit-banged SPI library does not need any `tx_rx_swapp` parameter anymore. 67 | 68 | ## v0.0.0 69 | 70 | * (new) USB configuration works, 71 | * (new) bit-banged ice_spi.h that can swap TX/RX and API ready for DMA (not DMA support yet), 72 | * DFU to iCE40 external flash works, 73 | * LEDs control works, 74 | * Everything else does not work yet 75 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | execute_process(COMMAND git -C "${CMAKE_CURRENT_LIST_DIR}" describe --tags 4 | OUTPUT_VARIABLE PICO_ICE_SDK_VERSION 5 | OUTPUT_STRIP_TRAILING_WHITESPACE 6 | ) 7 | set(PICO_ICE_SDK_VERSION ${PICO_ICE_SDK_VERSION} PARENT_SCOPE) 8 | 9 | add_library(pico_ice_sdk INTERFACE) 10 | 11 | target_sources(pico_ice_sdk INTERFACE 12 | src/ice_fpga.c 13 | src/ice_flash.c 14 | src/ice_led.c 15 | src/ice_cram.c 16 | src/ice_fpga_data.c 17 | src/pico-sdk_ice_hal.c 18 | ) 19 | target_include_directories(pico_ice_sdk INTERFACE 20 | include 21 | ) 22 | target_link_libraries(pico_ice_sdk INTERFACE 23 | pico_ice_preinit_common 24 | hardware_flash 25 | hardware_gpio 26 | hardware_pio 27 | hardware_spi 28 | hardware_dma 29 | hardware_uart 30 | pico_stdlib 31 | ) 32 | pico_generate_pio_header(pico_ice_sdk 33 | ${CMAKE_CURRENT_LIST_DIR}/src/ice_cram.pio 34 | ) 35 | target_include_directories(pico_ice_sdk INTERFACE 36 | include 37 | ) 38 | 39 | add_library(pico_ice_usb INTERFACE) 40 | 41 | target_sources(pico_ice_usb INTERFACE 42 | src/ice_usb.c 43 | src/tinyuf2_main.c 44 | src/tinyuf2_board.c 45 | src/tinyuf2_include.c 46 | ) 47 | target_include_directories(pico_ice_usb INTERFACE 48 | include 49 | lib/tinyuf2/src 50 | ) 51 | target_link_libraries(pico_ice_usb INTERFACE 52 | pico_ice_preinit_common 53 | pico_multicore 54 | pico_unique_id 55 | tinyusb_device 56 | tinyusb_board 57 | ) 58 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | pico-ice.tinyvision.ai -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Required: 2 | - Contributions go to `develop` rather than `main` or `master` 3 | 4 | Appreciated: 5 | - 4 spaces indents 6 | - `if (...) { single_statement(); }` always with braces 7 | - `function() {` with the brace on the same line 8 | - `//` comments everywhere 9 | - https://www.kernel.org/doc/html/v4.10/process/coding-style.html for the rest 10 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 tinyVision.ai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pico-ice-sdk 2 | 3 | [Doc](http://pico-ice.tinyvision.ai/) 4 | | [Hardware](https://github.com/tinyvision-ai-inc/pico-ice) 5 | | [SDK](https://github.com/tinyvision-ai-inc/pico-ice-sdk) 6 | | [Schematic](https://raw.githubusercontent.com/tinyvision-ai-inc/pico-ice/main/Board/Rev3/pico-ice.pdf) 7 | | [Assembly](https://htmlpreview.github.io/?https://github.com/tinyvision-ai-inc/pico-ice/blob/main/Board/Rev3/bom/ibom.html) 8 | | [Discord](https://discord.gg/t2CzbAYeD2) 9 | 10 | This is the SDK for building custom firmware for the RP2040 on the [pico-ice](https://pico-ice.tinyvision.ai/) board and RP2350 on [pico2-ice](https://pico2-ice.tinyvision.ai/) board. 11 | 12 | ### To quickly get started: 13 | Provided you have the compilers setup. 14 | For riscv, you may add `-DPICO_GCC_TRIPLE=riscv64-unknown-elf` to the cmake command if your 'riscv64' compiler supports rp2350/rv32. 15 | 16 | - clone the repository 17 | - run `git submodules update --init` 18 | - got into the folder of the example you wish to try 19 | - `mkdir build && cd build` 20 | - `cmake -DPICO_BOARD=pico_ice ..` or `cmake -DPICO_BOARD=pico2_ice ..` or `cmake -DPICO_BOARD=pico2_ice -DPICO_PLATFORM=rp2350-riscv ..` 21 | - `make -j8` 22 | - Copy the generated uf2 to the board after setting it to flashing mode 23 | -------------------------------------------------------------------------------- /amaranth/debouncer.py: -------------------------------------------------------------------------------- 1 | # amaranth 2 | from amaranth import * 3 | 4 | 5 | __all__ = [ "Debouncer" ] 6 | 7 | 8 | class Debouncer(Elaboratable): 9 | """ 10 | Debounce a signal by rejecting jitter. 11 | """ 12 | 13 | def __init__(self, *, width): 14 | self.width = width 15 | 16 | self.i = Signal(1) 17 | self.o = Signal(1) 18 | 19 | def elaborate(self, platform): 20 | m = Module() 21 | buffer = Signal(self.width) 22 | 23 | m.d.sync += buffer.eq(Cat(self.i, buffer)) 24 | 25 | with m.If(buffer.any() == 0): 26 | m.d.sync += self.o.eq(0) 27 | 28 | with m.If(buffer.all() == 1): 29 | m.d.sync += self.o.eq(1) 30 | 31 | return m 32 | -------------------------------------------------------------------------------- /amaranth/install_dependencies.sh: -------------------------------------------------------------------------------- 1 | set -eux 2 | 3 | # download the latest development packages 4 | pip3 install "amaranth[builtin-yosys] @ git+https://github.com/amaranth-lang/amaranth.git" 5 | pip3 install "amaranth-boards[builtin-yosys] @ git+https://github.com/amaranth-lang/amaranth-boards.git" 6 | 7 | # download the dependencies 8 | sudo apt-get install yosys dfu-util nextpnr-ice40 9 | 10 | # icestorm is not packaged very often 11 | git clone https://github.com/cliffordwolf/icestorm.git /tmp/icestorm 12 | make -C /tmp/icestorm/icepack/ 13 | sudo cp /tmp/icestorm/icepack/icepack /usr/local/bin/icepack 14 | -------------------------------------------------------------------------------- /amaranth/pico_ice.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from amaranth.build import * 4 | from amaranth.vendor.lattice_ice40 import * 5 | from amaranth_boards.resources import * 6 | 7 | 8 | __all__ = ["PicoIcePlatform"] 9 | 10 | 11 | class PicoIcePlatform(LatticeICE40Platform): 12 | device = "iCE40UP5K" 13 | package = "SG48" 14 | default_clk = "SB_HFOSC" 15 | hfosc_div = 1 16 | resources = [ 17 | *LEDResources(pins="39 40", invert=True, attrs=Attrs(IO_STANDARD="SB_LVCMOS")), 18 | Resource("led_g", 0, PinsN("39", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), 19 | Resource("led_b", 0, PinsN("40", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), 20 | # led_r is used as a cs_n pin for iCE40 <-> RP2040 I/O 21 | #Resource("led_r", 0, PinsN("41", dir="o"), Attrs(IO_STANDARD="SB_LVCMOS")), 22 | *ButtonResources(pins="11", invert=True, 23 | attrs=Attrs(IO_STANDARD="SB_LVCMOS")), 24 | *SPIFlashResources(0, cs_n="16", clk="15", copi="14", cipo="17", 25 | attrs=Attrs(IO_STANDARD="SB_LVCMOS")), 26 | SPIResource("sram", 0, cs_n="37", clk="15", copi="14", cipo="17", 27 | attrs=Attrs(IO_STANDARD="SB_LVCMOS"), role="controller"), 28 | SPIResource("rp2040", 0, cs_n="41", clk="15", copi="14", cipo="17", 29 | attrs=Attrs(IO_STANDARD="SB_LVCMOS"), role="peripheral"), 30 | ] 31 | connectors = [ 32 | Connector("pmod", 1, " 4 2 47 45 - - 3 48 46 44 - -"), 33 | Connector("pmod", 2, "43 38 34 31 - - 42 36 32 28 - -"), 34 | Connector("pmod", 3, "25 19 27 21 - - 23 18 26 20 - -"), 35 | ] 36 | 37 | def toolchain_program(self, products, name, dfu_vid="1209", dfu_pid="b1c0", dfu_alt=0): 38 | dfu_util = os.environ.get("DFU_UTIL", "dfu-util") 39 | dfu_args = ["-d", f"{dfu_vid}:{dfu_pid}", "-a", str(dfu_alt)] 40 | with products.extract(f"{name}.bin") as bitstream_filename: 41 | subprocess.check_call([dfu_util, "-D", bitstream_filename] + dfu_args) 42 | -------------------------------------------------------------------------------- /cmake/preinit_pico_ice_sdk.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | add_library(pico_ice_preinit_common INTERFACE) 4 | 5 | if (NOT DEFINED PICO_BOARD OR PICO_BOARD STREQUAL pico_ice) 6 | set(PICO_BOARD pico_ice) 7 | target_compile_definitions(pico_ice_preinit_common INTERFACE PICO_ICE) 8 | endif() 9 | if (PICO_BOARD STREQUAL pico2_ice) 10 | if (NOT DEFINED PICO_PLATFORM) 11 | set(PICO_PLATFORM rp2350) 12 | endif() 13 | target_compile_definitions(pico_ice_preinit_common INTERFACE PICO2_ICE) 14 | endif() 15 | list(APPEND PICO_BOARD_HEADER_DIRS "${CMAKE_CURRENT_LIST_DIR}/../include/boards") 16 | 17 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # pico-ice examples 2 | 3 | This directory contains examples for using the RP2040 and iCE40 of the pico-ice board. 4 | 5 | - The `pico_...` examples show usage of the `pico-ice-sdk` in C and C++ 6 | - The `ice_...` examples show usage of Hardware Description Language to [load on the iCE40](https://pico-ice.tinyvision.ai/programming_the_fpga.html) 7 | - The `pico_ice_...` examples show usage of combined firmware/gateware to upload to the FPGA as a single combined image. 8 | -------------------------------------------------------------------------------- /examples/ice_apio_blinky/.gitignore: -------------------------------------------------------------------------------- 1 | hardware.* 2 | .scons* 3 | -------------------------------------------------------------------------------- /examples/ice_apio_blinky/README.md: -------------------------------------------------------------------------------- 1 | # ice_apio_blinky 2 | 3 | This example makes use of the [apio](https://apiodoc.readthedocs.io/) command line build system for [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build). 4 | 5 | Build with `apio build` and deploy with `apio upload`. 6 | See the [doc](https://pico-ice.tinyvision.ai/using_apio.html) for more. 7 | 8 | @example top.v 9 | -------------------------------------------------------------------------------- /examples/ice_apio_blinky/apio.ini: -------------------------------------------------------------------------------- 1 | [env] 2 | board = pico-ice 3 | 4 | -------------------------------------------------------------------------------- /examples/ice_apio_blinky/top.v: -------------------------------------------------------------------------------- 1 | module top ( 2 | input clk, 3 | output led_blue, 4 | output led_green, 5 | output led_red 6 | ); 7 | localparam N = 24; 8 | 9 | reg [N-1:0] counter; 10 | 11 | always @(posedge clk) begin 12 | counter <= counter + 1; 13 | end 14 | 15 | assign led_green = counter[N - 1]; 16 | assign led_blue = counter[N - 2]; 17 | assign led_red = counter[N - 3]; 18 | endmodule 19 | -------------------------------------------------------------------------------- /examples/ice_apio_blinky/up5k.pcf: -------------------------------------------------------------------------------- 1 | 2 | set_io --warn-no-port led_blue 40 3 | set_io --warn-no-port led_green 39 4 | set_io --warn-no-port led_red 41 5 | set_io --warn-no-port clk 35 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/ice_apio_uart_echo/.gitignore: -------------------------------------------------------------------------------- 1 | hardware.* 2 | .scons* 3 | -------------------------------------------------------------------------------- /examples/ice_apio_uart_echo/README.md: -------------------------------------------------------------------------------- 1 | # ice_apio_uart_echo 2 | 3 | This example makes use of the [apio](https://apiodoc.readthedocs.io/) command line build system for [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build). 4 | 5 | Build with `apio build` and deploy with `apio upload`. 6 | See the [doc](https://pico-ice.tinyvision.ai/using_apio.html) for more. 7 | 8 | It makes use of the default firmware's USB UART forwarding feature: 9 | 10 | 1. Connect the board to the host with an USB cable 11 | 2. Connect to the USB-UART interface of the [default firmware](https://pico-ice.tinyvision.ai/getting_started.html#default-firmware). 12 | 3. In the terminal window that opens, only when this example is loaded, everything typed in should be echoed back. 13 | 14 | It is possible to verify if it worked by loading the RGB blink example: with it, nothing should be echoed back. 15 | -------------------------------------------------------------------------------- /examples/ice_apio_uart_echo/apio.ini: -------------------------------------------------------------------------------- 1 | [env] 2 | board = pico-ice 3 | 4 | -------------------------------------------------------------------------------- /examples/ice_apio_uart_echo/top.v: -------------------------------------------------------------------------------- 1 | module top ( 2 | input CLK, 3 | input UART_RX, 4 | output UART_TX 5 | ); 6 | assign UART_TX = UART_RX; 7 | endmodule 8 | -------------------------------------------------------------------------------- /examples/ice_makefile_blinky/.gitignore: -------------------------------------------------------------------------------- 1 | gateware.* 2 | -------------------------------------------------------------------------------- /examples/ice_makefile_blinky/Makefile: -------------------------------------------------------------------------------- 1 | YOSYS = $(OSS_CAD_SUITE)/bin/yosys 2 | NEXTPNR = $(OSS_CAD_SUITE)/bin/nextpnr-ice40 3 | ICEPACK = $(OSS_CAD_SUITE)/bin/icepack 4 | DFU_UTIL = $(OSS_CAD_SUITE)/bin/dfu-util 5 | BIN2UF2 = bin2uf2 6 | 7 | RTL = top.sv 8 | 9 | all: gateware.bin 10 | 11 | clean: 12 | $(RM) *.json *.asc *.bin *.uf2 13 | 14 | prog: gateware.bin 15 | $(DFU_UTIL) -d 1209:b1c0 -a 1 -D gateware.bin -R 16 | 17 | gateware.bin: $(RTL) 18 | $(YOSYS) -q -p "read_verilog -sv $(RTL); synth_ice40 -top top -json $*.json" 19 | $(NEXTPNR) -q --randomize-seed --up5k --package sg48 --pcf ice40.pcf --json $*.json --asc $*.asc 20 | $(ICEPACK) $*.asc $@ 21 | 22 | .bin.uf2: 23 | $(BIN2UF2) -o $@ $< 24 | 25 | .SUFFIXES: .v .sv .asc .bin .uf2 26 | -------------------------------------------------------------------------------- /examples/ice_makefile_blinky/README.md: -------------------------------------------------------------------------------- 1 | # ice_makefile_blinky 2 | 3 | Example project using a standard [Makefile](https://en.wikipedia.org/wiki/Make_%28software%29) 4 | to build a project that can be loaded onto the board. 5 | 6 | It needs [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build) installed. 7 | See the [doc](https://pico-ice.tinyvision.ai/using_oss_cad_suite.html) for more. 8 | 9 | Build with `make` and deploy it to the pico-ice with `make prog`, and `make gateware.uf2` to generate an 10 | [uf2 image](https://pico-ice.tinyvision.ai/programming_the_fpga.html#using-a-drag-drop-or-file-copy-scheme) 11 | to program with drag-and-drop. 12 | 13 | A very complete `Makefile` example is provided for the UPduino v3 by Xark: 14 | 15 | -------------------------------------------------------------------------------- /examples/ice_makefile_blinky/ice40.pcf: -------------------------------------------------------------------------------- 1 | set_io -nowarn LED_G 39 # active-low 2 | set_io -nowarn LED_B 40 # active-low 3 | set_io -nowarn LED_R 41 # active-low 4 | set_io -nowarn CLK 35 5 | -------------------------------------------------------------------------------- /examples/ice_makefile_blinky/top.sv: -------------------------------------------------------------------------------- 1 | 2 | module top ( 3 | input CLK, 4 | output LED_R, 5 | output LED_G, 6 | output LED_B, 7 | ); 8 | 9 | localparam N = 22; 10 | 11 | reg [N:0] counter; 12 | 13 | always @(posedge CLK) begin 14 | counter <= counter + 1; 15 | end 16 | 17 | assign LED_R = 1'b1; 18 | assign LED_G = counter[N]; 19 | assign LED_B = 1'b1; 20 | 21 | endmodule 22 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/.gitignore: -------------------------------------------------------------------------------- 1 | gateware.* 2 | /obj_dir/ 3 | *.vcd 4 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/Makefile: -------------------------------------------------------------------------------- 1 | YOSYS = $(OSS_CAD_SUITE)/bin/yosys 2 | NEXTPNR = $(OSS_CAD_SUITE)/bin/nextpnr-ice40 3 | ICEPACK = $(OSS_CAD_SUITE)/bin/icepack 4 | DFU_UTIL = $(OSS_CAD_SUITE)/bin/dfu-util 5 | BIN2UF2 = bin2uf2 6 | 7 | IVERILOG = $(OSS_CAD_SUITE)/bin/iverilog 8 | VVP = $(OSS_CAD_SUITE)/bin/vvp 9 | 10 | RTL = top.sv 11 | 12 | all: gateware.bin iverilog.vcd 13 | 14 | clean: 15 | $(RM) -r obj_dir *.json *.asc *.bin *.uf2 *.elf 16 | 17 | prog: gateware.bin 18 | $(DFU_UTIL) -d 1209:b1c0 -a 1 -D gateware.bin -R 19 | 20 | gateware.bin: ice40.sv $(RTL) 21 | $(YOSYS) -q -p "read_verilog -sv ice40.sv $(RTL); synth_ice40 -top ice40 -json $*.json" 22 | $(NEXTPNR) -q --randomize-seed --up5k --package sg48 --pcf ice40.pcf --json $*.json --asc $*.asc 23 | $(ICEPACK) $*.asc $@ 24 | 25 | iverilog.vcd: testbench.sv $(RTL) 26 | $(IVERILOG) -g2012 -Wall -o $*.vvp testbench.sv $(RTL) 27 | $(VVP) $*.vvp $@ 28 | 29 | .bin.uf2: 30 | $(BIN2UF2) -o $@ $< 31 | 32 | .SUFFIXES: .v .sv .vcd .bin .uf2 33 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/README.md: -------------------------------------------------------------------------------- 1 | # ice_makefile_iverilog_counter 2 | 3 | Example project using a standard [Makefile](https://en.wikipedia.org/wiki/Make_%28software%29) 4 | to build a project with an [Icarus Verilog](https://steveicarus.github.io/iverilog/) simulation test bench. 5 | 6 | It needs [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build) installed. 7 | See the [doc](https://pico-ice.tinyvision.ai/using_oss_cad_suite.html) for more. 8 | 9 | Build with `make`. This should simulate the design, producing a `iverilog.vcd` that can be browsed with `gtkwave iverilog.vcd`. 10 | 11 | `ice40.sv` wraps `top.sv` and can be deployed to the pico-ice with `make prog`, and `make gateware.uf2` to generate an 12 | [uf2 image](https://pico-ice.tinyvision.ai/programming_the_fpga.html#using-a-drag-drop-or-file-copy-scheme) 13 | to program with drag-and-drop. 14 | 15 | A very complete `Makefile` example is provided for the UPduino v3 by Xark: 16 | 17 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/ice40.pcf: -------------------------------------------------------------------------------- 1 | set_io --warn-no-port led_blue 40 2 | set_io --warn-no-port led_green 39 3 | set_io --warn-no-port led_red 41 4 | set_io --warn-no-port clk 35 5 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/ice40.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `default_nettype none 3 | 4 | module ice40 ( 5 | input clk, 6 | output led_red, 7 | output led_green, 8 | output led_blue 9 | ); 10 | 11 | top top0 ( 12 | .clk_i(clk), 13 | .rst_ni(1), 14 | .cnt_o({ led_red, led_green, led_blue }), 15 | ); 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/iverilog.vvp: -------------------------------------------------------------------------------- 1 | #! /home/pack/oss-cad-suite-2023-08-31/bin/vvp 2 | :ivl_version "13.0 (devel)" "(s20221226-267-g77f7609b6)"; 3 | :ivl_delay_selection "TYPICAL"; 4 | :vpi_time_precision - 12; 5 | :vpi_module "/home/pack/oss-cad-suite-2023-08-31/lib/ivl/system.vpi"; 6 | :vpi_module "/home/pack/oss-cad-suite-2023-08-31/lib/ivl/vhdl_sys.vpi"; 7 | :vpi_module "/home/pack/oss-cad-suite-2023-08-31/lib/ivl/vhdl_textio.vpi"; 8 | :vpi_module "/home/pack/oss-cad-suite-2023-08-31/lib/ivl/v2005_math.vpi"; 9 | :vpi_module "/home/pack/oss-cad-suite-2023-08-31/lib/ivl/va_math.vpi"; 10 | :vpi_module "/home/pack/oss-cad-suite-2023-08-31/lib/ivl/v2009.vpi"; 11 | S_0x5555565874d0 .scope package, "$unit" "$unit" 2 1; 12 | .timescale 0 0; 13 | S_0x55555659aea0 .scope module, "testbench" "testbench" 3 4; 14 | .timescale -9 -12; 15 | v0x5555565aca90_0 .var "clk", 0 0; 16 | v0x5555565acb60_0 .net "cnt_d", 2 0, L_0x5555565acd30; 1 drivers 17 | v0x5555565acc30_0 .var "rst", 0 0; 18 | S_0x55555659b030 .scope module, "uut" "top" 3 8, 4 4 0, S_0x55555659aea0; 19 | .timescale -9 -12; 20 | .port_info 0 /INPUT 1 "clk_i"; 21 | .port_info 1 /INPUT 1 "rst_ni"; 22 | .port_info 2 /OUTPUT 3 "cnt_o"; 23 | v0x5555565609d0_0 .net "clk_i", 0 0, v0x5555565aca90_0; 1 drivers 24 | v0x5555565ac7b0_0 .net "cnt_o", 2 0, L_0x5555565acd30; alias, 1 drivers 25 | v0x5555565ac890_0 .var "cnt_q", 20 0; 26 | v0x5555565ac950_0 .net "rst_ni", 0 0, v0x5555565acc30_0; 1 drivers 27 | E_0x5555565618d0 .event posedge, v0x5555565609d0_0; 28 | L_0x5555565acd30 .part v0x5555565ac890_0, 18, 3; 29 | .scope S_0x55555659b030; 30 | T_0 ; 31 | %wait E_0x5555565618d0; 32 | %load/vec4 v0x5555565ac950_0; 33 | %flag_set/vec4 8; 34 | %jmp/0xz T_0.0, 8; 35 | %load/vec4 v0x5555565ac890_0; 36 | %addi 1, 0, 21; 37 | %assign/vec4 v0x5555565ac890_0, 0; 38 | %jmp T_0.1; 39 | T_0.0 ; 40 | %pushi/vec4 0, 0, 21; 41 | %assign/vec4 v0x5555565ac890_0, 0; 42 | T_0.1 ; 43 | %jmp T_0; 44 | .thread T_0; 45 | .scope S_0x55555659aea0; 46 | T_1 ; 47 | %delay 5000, 0; 48 | %load/vec4 v0x5555565aca90_0; 49 | %inv; 50 | %store/vec4 v0x5555565aca90_0, 0, 1; 51 | %jmp T_1; 52 | .thread T_1; 53 | .scope S_0x55555659aea0; 54 | T_2 ; 55 | %vpi_call/w 3 20 "$dumpfile", "iverilog.vcd" {0 0 0}; 56 | %vpi_call/w 3 21 "$dumpvars", 32'sb00000000000000000000000000000000, S_0x55555659aea0 {0 0 0}; 57 | %pushi/vec4 0, 0, 1; 58 | %store/vec4 v0x5555565aca90_0, 0, 1; 59 | %pushi/vec4 0, 0, 1; 60 | %store/vec4 v0x5555565acc30_0, 0, 1; 61 | %delay 10000, 0; 62 | %pushi/vec4 1, 0, 1; 63 | %store/vec4 v0x5555565acc30_0, 0, 1; 64 | %delay 10000000, 0; 65 | %vpi_call/w 3 30 "$finish" {0 0 0}; 66 | %end; 67 | .thread T_2; 68 | # The file index is used to find the file name in the following table. 69 | :file_names 5; 70 | "N/A"; 71 | ""; 72 | "-"; 73 | "testbench.sv"; 74 | "top.sv"; 75 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/testbench.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `default_nettype none 3 | 4 | module testbench; 5 | logic clk, rst; 6 | logic [2:0] cnt_d; 7 | 8 | top uut ( 9 | .clk_i(clk), 10 | .rst_ni(rst), 11 | .cnt_o(cnt_d) 12 | ); 13 | 14 | 15 | always begin 16 | #5 clk = ~clk; 17 | end 18 | 19 | initial begin 20 | $dumpfile("iverilog.vcd"); 21 | $dumpvars(0, testbench); 22 | 23 | clk = 0; 24 | rst = 0; 25 | 26 | #10 27 | rst = 1; 28 | 29 | #10000 30 | $finish(); 31 | end 32 | 33 | endmodule 34 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/top.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `default_nettype none 3 | 4 | module top ( 5 | input clk_i, 6 | input rst_ni, 7 | 8 | // output the counter's value 9 | output [2:0] cnt_o 10 | ); 11 | logic [20:0] cnt_q; 12 | 13 | always_ff @(posedge clk_i) begin 14 | if (rst_ni) begin 15 | cnt_q <= cnt_q + 1; 16 | end else begin 17 | cnt_q <= 0; 18 | end 19 | end 20 | 21 | assign cnt_o = cnt_q[20:18]; 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/verilator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Vtop.h" 3 | #include "vsim.h" 4 | 5 | #define CLK_SYS_PERIOD 30 6 | #define CLK_SYS_PHASE 3 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | vsim_init(argc, argv); 12 | 13 | for (nanosecond_t ns = 100; ns < 100 * 1000; ns++) { 14 | if (POSEDGE(ns, CLK_SYS_PERIOD, CLK_SYS_PHASE)) { 15 | vsim->clk_i = 1; 16 | vsim_eval(); 17 | } 18 | if (NEGEDGE(ns, CLK_SYS_PERIOD, CLK_SYS_PHASE)) { 19 | vsim->clk_i = 0; 20 | vsim_eval(); 21 | } 22 | vsim_tick(ns); 23 | } 24 | vsim_finish(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /examples/ice_makefile_iverilog_counter/vsim.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "verilated_vcd_c.h" 4 | 5 | typedef uint64_t nanosecond_t; 6 | 7 | Vtop *vsim; 8 | VerilatedVcdC *vcd; 9 | 10 | int vsim_changed = 0; 11 | 12 | #define POSEDGE(ns, period, phase) \ 13 | ((ns) % (period) == (phase)) 14 | 15 | #define NEGEDGE(ns, period, phase) \ 16 | ((ns) % (period) == ((phase) + (period)) / 2 % (period)) 17 | 18 | static void 19 | vsim_fatal(char const *fmt, ...) 20 | { 21 | va_list va; 22 | 23 | va_start(va, fmt); 24 | fputs("fatal: ", stderr); 25 | vfprintf(stderr, fmt, va); 26 | fputs("\n", stderr); 27 | } 28 | 29 | #ifdef NDEBUG 30 | #define debug(...) 0 31 | #else 32 | 33 | static void 34 | debug(char const *fmt, ...) 35 | { 36 | va_list va; 37 | 38 | va_start(va, fmt); 39 | vfprintf(stderr, fmt, va); 40 | fputs("\n", stderr); 41 | } 42 | #endif 43 | 44 | static void 45 | vsim_put(char const *var, uint64_t u64, uint8_t size) 46 | { 47 | printf(" %s:", var); 48 | for (u64 <<= 64 - size; size > 0; size--, u64 <<= 1) 49 | putchar(u64 & (1ull << 63) ? '1' : '0'); 50 | } 51 | 52 | static void 53 | vsim_eval(void) 54 | { 55 | vsim->eval(); 56 | vsim_changed = 1; 57 | } 58 | 59 | static void 60 | vsim_init(int argc, char **argv) 61 | { 62 | Verilated::commandArgs(argc, argv); 63 | Verilated::traceEverOn(true); 64 | 65 | vsim = new Vtop; 66 | vcd = new VerilatedVcdC; 67 | 68 | vsim->trace(vcd, 99); 69 | vcd->open("/dev/stdout"); 70 | 71 | vsim->rst_ni = 0; 72 | vsim->eval(); 73 | vcd->dump(0); 74 | vsim->rst_ni = 1; 75 | } 76 | 77 | static void 78 | vsim_tick(nanosecond_t ns) 79 | { 80 | if (vsim_changed) 81 | vcd->dump(ns); 82 | vsim_changed = 0; 83 | } 84 | 85 | static void 86 | vsim_finish(void) 87 | { 88 | vcd->flush(); 89 | } 90 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/.gitignore: -------------------------------------------------------------------------------- 1 | gateware.* 2 | /obj_dir/ 3 | *.vcd 4 | *.elf 5 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/Makefile: -------------------------------------------------------------------------------- 1 | YOSYS = $(OSS_CAD_SUITE)/bin/yosys 2 | NEXTPNR = $(OSS_CAD_SUITE)/bin/nextpnr-ice40 3 | ICEPACK = $(OSS_CAD_SUITE)/bin/icepack 4 | DFU_UTIL = $(OSS_CAD_SUITE)/bin/dfu-util 5 | BIN2UF2 = bin2uf2 6 | 7 | VERILATOR = $(OSS_CAD_SUITE)/bin/verilator 8 | VERILATOR_INC = $(OSS_CAD_SUITE)/share/verilator/include 9 | VERILATOR_SRC = $(VERILATOR_INC)/verilated.cpp $(VERILATOR_INC)/verilated_vcd_c.cpp $(VERILATOR_INC)/verilated_threads.cpp 10 | CXX = c++ -I$(VERILATOR_INC) #-DNDEBUG 11 | 12 | RTL = top.sv 13 | 14 | all: gateware.bin verilator.vcd 15 | 16 | clean: 17 | $(RM) -r obj_dir *.json *.asc *.bin *.uf2 *.elf 18 | 19 | prog: gateware.bin 20 | $(DFU_UTIL) -d 1209:b1c0 -a 1 -D gateware.bin -R 21 | 22 | gateware.bin: ice40.sv $(RTL) 23 | $(YOSYS) -q -p "read_verilog -sv ice40.sv $(RTL); synth_ice40 -top ice40 -json $*.json" 24 | $(NEXTPNR) -q --randomize-seed --up5k --package sg48 --pcf ice40.pcf --json $*.json --asc $*.asc 25 | $(ICEPACK) $*.asc $@ 26 | 27 | verilator.vcd: verilator.cpp vsim.h $(RTL) 28 | $(VERILATOR) -Wall -DSIMULATION -Irtl --trace --sv --trace-structs --cc --top-module top $(RTL) 29 | $(MAKE) -C obj_dir -f Vtop.mk 30 | $(CXX) -Iobj_dir -o verilator.elf $(VERILATOR_SRC) verilator.cpp obj_dir/Vtop__ALL.a 31 | ./verilator.elf >$@ 32 | 33 | .bin.uf2: 34 | $(BIN2UF2) -o $@ $< 35 | 36 | .SUFFIXES: .v .sv .vcd .bin .uf2 37 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/README.md: -------------------------------------------------------------------------------- 1 | # ice_makefile_verilator_counter 2 | 3 | Example project using a standard [Makefile](https://en.wikipedia.org/wiki/Make_%28software%29) 4 | to build a project with a [Verilator](https://verilator.org/) simulation test bench. 5 | 6 | It needs [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build) installed. 7 | See the [doc](https://pico-ice.tinyvision.ai/using_oss_cad_suite.html) for more. 8 | 9 | It also requires a C++ compiler, to compile the Verilator simulation, converted from Verilog to C++. 10 | 11 | Build with `make`. This should simulate the design, producing a `verilator.vcd` that can be browsed with `gtkwave verilator.vcd`. 12 | 13 | `ice40.sv` wraps `top.sv` and can be deployed to the pico-ice with `make prog`, and `make gateware.uf2` to generate an 14 | [uf2 image](https://pico-ice.tinyvision.ai/programming_the_fpga.html#using-a-drag-drop-or-file-copy-scheme) 15 | to program with drag-and-drop. 16 | 17 | A very complete `Makefile` example is provided for the UPduino v3 by Xark: 18 | 19 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/ice40.pcf: -------------------------------------------------------------------------------- 1 | set_io --warn-no-port led_blue 40 2 | set_io --warn-no-port led_green 30 3 | set_io --warn-no-port led_red 41 4 | set_io --warn-no-port clk 35 5 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/ice40.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `default_nettype none 3 | 4 | module ice40 ( 5 | input clk, 6 | output led_red, 7 | output led_green, 8 | output led_blue 9 | ); 10 | 11 | top top0 ( 12 | .clk_i(clk), 13 | .rst_ni(1), 14 | .cnt_o({ led_red, led_green, led_blue }), 15 | ); 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/top.sv: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | `default_nettype none 3 | 4 | module top ( 5 | input clk_i, 6 | input rst_ni, 7 | 8 | // output the counter's value 9 | output [2:0] cnt_o 10 | ); 11 | logic [20:0] cnt_q; 12 | 13 | always_ff @(posedge clk_i) begin 14 | if (rst_ni) begin 15 | cnt_q <= cnt_q + 1; 16 | end else begin 17 | cnt_q <= 0; 18 | end 19 | end 20 | 21 | assign cnt_o = cnt_q[20:18]; 22 | 23 | endmodule 24 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/verilator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Vtop.h" 3 | #include "vsim.h" 4 | 5 | #define CLK_SYS_PERIOD 30 6 | #define CLK_SYS_PHASE 3 7 | 8 | int 9 | main(int argc, char **argv) 10 | { 11 | vsim_init(argc, argv); 12 | 13 | for (nanosecond_t ns = 100; ns < 100 * 1000; ns++) { 14 | if (POSEDGE(ns, CLK_SYS_PERIOD, CLK_SYS_PHASE)) { 15 | vsim->clk_i = 1; 16 | vsim_eval(); 17 | } 18 | if (NEGEDGE(ns, CLK_SYS_PERIOD, CLK_SYS_PHASE)) { 19 | vsim->clk_i = 0; 20 | vsim_eval(); 21 | } 22 | vsim_tick(ns); 23 | } 24 | vsim_finish(); 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /examples/ice_makefile_verilator_counter/vsim.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "verilated_vcd_c.h" 4 | 5 | typedef uint64_t nanosecond_t; 6 | 7 | Vtop *vsim; 8 | VerilatedVcdC *vcd; 9 | 10 | int vsim_changed = 0; 11 | 12 | #define POSEDGE(ns, period, phase) \ 13 | ((ns) % (period) == (phase)) 14 | 15 | #define NEGEDGE(ns, period, phase) \ 16 | ((ns) % (period) == ((phase) + (period)) / 2 % (period)) 17 | 18 | static void 19 | vsim_fatal(char const *fmt, ...) 20 | { 21 | va_list va; 22 | 23 | va_start(va, fmt); 24 | fputs("fatal: ", stderr); 25 | vfprintf(stderr, fmt, va); 26 | fputs("\n", stderr); 27 | } 28 | 29 | #ifdef NDEBUG 30 | #define debug(...) 0 31 | #else 32 | 33 | static void 34 | debug(char const *fmt, ...) 35 | { 36 | va_list va; 37 | 38 | va_start(va, fmt); 39 | vfprintf(stderr, fmt, va); 40 | fputs("\n", stderr); 41 | } 42 | #endif 43 | 44 | static void 45 | vsim_put(char const *var, uint64_t u64, uint8_t size) 46 | { 47 | printf(" %s:", var); 48 | for (u64 <<= 64 - size; size > 0; size--, u64 <<= 1) 49 | putchar(u64 & (1ull << 63) ? '1' : '0'); 50 | } 51 | 52 | static void 53 | vsim_eval(void) 54 | { 55 | vsim->eval(); 56 | vsim_changed = 1; 57 | } 58 | 59 | static void 60 | vsim_init(int argc, char **argv) 61 | { 62 | Verilated::commandArgs(argc, argv); 63 | Verilated::traceEverOn(true); 64 | 65 | vsim = new Vtop; 66 | vcd = new VerilatedVcdC; 67 | 68 | vsim->trace(vcd, 99); 69 | vcd->open("/dev/stdout"); 70 | 71 | vsim->rst_ni = 0; 72 | vsim->eval(); 73 | vcd->dump(0); 74 | vsim->rst_ni = 1; 75 | } 76 | 77 | static void 78 | vsim_tick(nanosecond_t ns) 79 | { 80 | if (vsim_changed) 81 | vcd->dump(ns); 82 | vsim_changed = 0; 83 | } 84 | 85 | static void 86 | vsim_finish(void) 87 | { 88 | vcd->flush(); 89 | } 90 | -------------------------------------------------------------------------------- /examples/rp2_blinky/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_blinky C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | ) 23 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 24 | ${CMAKE_CURRENT_LIST_DIR} 25 | ) 26 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 27 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 28 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 29 | -------------------------------------------------------------------------------- /examples/rp2_blinky/README.md: -------------------------------------------------------------------------------- 1 | # rp2_blinky 2 | 3 | Red led blinking once per second. 4 | -------------------------------------------------------------------------------- /examples/rp2_blinky/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdlib.h" 26 | #include "boards.h" 27 | #include "ice_led.h" 28 | 29 | int main(void) { 30 | // Note that the FPGA demo might as well making use of the LED. 31 | // In that case, the LED "on" state win over the "off" state, 32 | // but LEDs work fine nonetheless. 33 | ice_led_init(); 34 | 35 | for (bool red = false;; red = !red) { 36 | ice_led_red(red); 37 | sleep_ms(500); 38 | } 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /examples/rp2_blinky/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_blinky/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_blinky/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_blinky_cplusplus C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.cpp 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | pico_ice_usb 23 | ) 24 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 25 | ${CMAKE_CURRENT_LIST_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/README.md: -------------------------------------------------------------------------------- 1 | # rp2_blinky_cplusplus 2 | 3 | Red led blinking once per second, showcasing C++ support. 4 | -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/main.cpp: -------------------------------------------------------------------------------- 1 | #include "pico/stdlib.h" 2 | #include "boards.h" 3 | 4 | // Deliberately adding all pico-ice-sdk headers here, even ones not needed for blinky, so that continuous integration 5 | // verifies that all SDK headers can be compiled as C++. 6 | #include "ice_cram.h" 7 | #include "ice_flash.h" 8 | #include "ice_fpga.h" 9 | #include "ice_led.h" 10 | #include "ice_pmod.h" 11 | #include "ice_usb.h" 12 | 13 | int main(void) { 14 | ice_led_init(); 15 | 16 | for (bool red = false;; red = !red) { 17 | ice_led_red(red); 18 | sleep_ms(500); 19 | } 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | #include "ice_flash.h" 30 | 31 | // RHPort number used for device can be defined by board.mk, port 0 for pico-ice 32 | #define BOARD_DEVICE_RHPORT_NUM 0 33 | 34 | // Device mode with rhport and speed defined by board.mk 35 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE 36 | 37 | // Either full or high speed supported by RP2040 38 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 39 | 40 | // Enable Device stack 41 | #define CFG_TUD_ENABLED 1 42 | 43 | // Default is max speed that hardware controller could support with on-chip PHY 44 | #define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED 45 | 46 | // Device classes 47 | #define CFG_TUD_CDC 0 48 | #define CFG_TUD_MSC 0 49 | #define CFG_TUD_DFU 1 50 | #define CFG_TUD_DFU_ALT 2 51 | #define CFG_TUD_HID 0 52 | #define CFG_TUD_MIDI 0 53 | #define CFG_TUD_VENDOR 0 54 | 55 | // CDC FIFO size of TX and RX and Endpoint buffer size 56 | #define CFG_TUD_CDC_RX_BUFSIZE 512 57 | #define CFG_TUD_CDC_TX_BUFSIZE 512 58 | #define CFG_TUD_CDC_EP_BUFSIZE 512 59 | 60 | // MSC Buffer size of Device Mass storage 61 | #define CFG_TUD_MSC_BUFSIZE ICE_FLASH_SECTOR_SIZE 62 | 63 | // Must be a multiple of flash page size 64 | #define CFG_TUD_DFU_XFER_BUFSIZE 256 65 | -------------------------------------------------------------------------------- /examples/rp2_blinky_cplusplus/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "ice_usb.h" 27 | 28 | enum { 29 | ITF_NUM_DFU, 30 | ITF_NUM_TOTAL 31 | }; 32 | 33 | uint8_t const tud_desc_configuration[CONFIG_TOTAL_LEN] = { 34 | TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 500/*mA*/), 35 | TUD_DFU_DESCRIPTOR(ITF_NUM_DFU, CFG_TUD_DFU_ALT, STRID_DFU, DFU_ATTR_CAN_DOWNLOAD, 1000, CFG_TUD_DFU_XFER_BUFSIZE), 36 | }; 37 | 38 | char const *tud_string_desc[STRID_NUM_TOTAL] = { 39 | [STRID_LANGID] = USB_LANG_EN, 40 | [STRID_MANUFACTURER] = USB_MANUFACTURER, 41 | [STRID_PRODUCT] = USB_PRODUCT, 42 | [STRID_SERIAL_NUMBER] = usb_serial_number, 43 | [STRID_VENDOR] = USB_VENDOR, 44 | [STRID_DFU+0] = "iCE40 DFU (Flash)", 45 | [STRID_DFU+1] = "iCE40 DFU (CRAM)", 46 | }; 47 | -------------------------------------------------------------------------------- /examples/rp2_cram/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_cram C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | ) 23 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 24 | ${CMAKE_CURRENT_LIST_DIR} 25 | ) 26 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 27 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 28 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 29 | -------------------------------------------------------------------------------- /examples/rp2_cram/README.md: -------------------------------------------------------------------------------- 1 | # rp2_cram 2 | 3 | Program an `rgb_blink.bin` bitstream, prior embedded into a code array (see `rgb_blink.py` and `rgb_blink.h` to the FPGA CRAM. 4 | -------------------------------------------------------------------------------- /examples/rp2_cram/bitstream.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyvision-ai-inc/pico-ice-sdk/0bb23bd0d871628196eb9e2b1eab3091dec66b0e/examples/rp2_cram/bitstream.h -------------------------------------------------------------------------------- /examples/rp2_cram/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdlib.h" 26 | #include "pico/stdio.h" 27 | #include "boards.h" 28 | #include "ice_cram.h" 29 | #include "ice_fpga.h" 30 | #include "ice_led.h" 31 | #include "rgb_blink.h" 32 | 33 | int main(void) { 34 | ice_led_init(); 35 | ice_fpga_init(FPGA_DATA, 48); 36 | ice_fpga_start(FPGA_DATA); 37 | 38 | // Write the whole bitstream to the FPGA CRAM 39 | ice_cram_open(FPGA_DATA); 40 | ice_cram_write(rgb_blink, sizeof(rgb_blink)); 41 | ice_cram_close(); 42 | 43 | while (1); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /examples/rp2_cram/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_cram/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_cram/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_cram/rgb_blink.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyvision-ai-inc/pico-ice-sdk/0bb23bd0d871628196eb9e2b1eab3091dec66b0e/examples/rp2_cram/rgb_blink.bin -------------------------------------------------------------------------------- /examples/rp2_cram/rgb_blink.py: -------------------------------------------------------------------------------- 1 | print('#include ') 2 | print('uint8_t const rgb_blink[] = {') 3 | 4 | i = 0 5 | for byte in open('rgb_blink.bin', 'rb').read(): 6 | if i == 0: 7 | print(' ', end='') 8 | print(' 0x%02X,' % byte, end='') 9 | i += 1 10 | if i == 16: 11 | print('') 12 | i = 0 13 | if i != 1: 14 | print('') 15 | print('};') 16 | -------------------------------------------------------------------------------- /examples/rp2_flash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_flash C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | pico_stdio_usb 23 | ) 24 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 25 | ${CMAKE_CURRENT_LIST_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | -------------------------------------------------------------------------------- /examples/rp2_flash/README.md: -------------------------------------------------------------------------------- 1 | # rp2_flash 2 | 3 | Program a register of the flash chip, read it back, and dump its content over USB-UART #0. 4 | -------------------------------------------------------------------------------- /examples/rp2_flash/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include "pico/stdlib.h" 27 | #include "boards.h" 28 | #include "ice_flash.h" 29 | 30 | #define MY_BASE_ADDRESS 0x00000 31 | 32 | static inline void memdump(uint8_t const *buf, size_t sz) { 33 | for (size_t i = 0; i < sz; i++) { 34 | printf(" %02X", buf[i]); 35 | if (i % 0x20 == (0x20 - 1)) { 36 | printf("\r\n"); 37 | } 38 | } 39 | printf("\r\n"); 40 | } 41 | 42 | #include "ice_led.h" // TODO debug 43 | 44 | int main(void) { 45 | uint8_t buf_r[ICE_FLASH_PAGE_SIZE] = {0}; 46 | uint8_t buf_w[ICE_FLASH_PAGE_SIZE] = {0}; 47 | 48 | // Enable USB-UART 0 output 49 | stdio_init_all(); 50 | 51 | sleep_ms(2000); 52 | 53 | // Booted up, now take control of the Flash 54 | ice_flash_init(FPGA_DATA.bus, ICE_FLASH_BAUDRATE); 55 | 56 | // Write data: known pattern, not very random! 57 | for (size_t i = 0; i < sizeof buf_w; i++) { 58 | buf_w[i] = i; 59 | } 60 | 61 | for (uint16_t i = 0;; i++) { 62 | // Erase a sector, program the page and then read it back. 63 | // Note that the FPGA bitfile which is at 0x000000 64 | ice_flash_erase_sector(FPGA_DATA.bus, MY_BASE_ADDRESS); 65 | ice_flash_read(FPGA_DATA.bus, MY_BASE_ADDRESS, buf_r, sizeof buf_r); 66 | memdump(buf_r, sizeof buf_r); 67 | ice_flash_program_page(FPGA_DATA.bus, MY_BASE_ADDRESS, buf_w); 68 | ice_flash_read(FPGA_DATA.bus, MY_BASE_ADDRESS, buf_r, sizeof buf_r); 69 | memdump(buf_r, sizeof buf_r); 70 | 71 | sleep_ms(5000); 72 | } 73 | 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /examples/rp2_flash/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_flash/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_flash/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_flash/test.py: -------------------------------------------------------------------------------- 1 | from pexpect import fdpexpect 2 | import sys, os 3 | 4 | tty = os.open(sys.argv[1], os.O_RDWR) 5 | p = fdpexpect.fdspawn(tty, timeout=6) 6 | 7 | for i in range(0x0, 0x100, 0x20): 8 | print(f'from 0x{i:X} to 0x{i + 0x20 - 1:X}') 9 | p.expect(' '.join(f'{n:02X}' for n in range(i, i + 0x20))) 10 | 11 | print('done') 12 | p.close() 13 | -------------------------------------------------------------------------------- /examples/rp2_flash_repl/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_flash_repl C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | pico_stdio_usb 23 | ) 24 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 25 | ${CMAKE_CURRENT_LIST_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | -------------------------------------------------------------------------------- /examples/rp2_flash_repl/README.md: -------------------------------------------------------------------------------- 1 | # rp2_flash_tool 2 | 3 | It will offer a REPL accessible over the USB-UART #0 with commands for 4 | interacting with the flash chip for debugging purposes: 5 | 6 | ## `0x00000000` 7 | 8 | Writing a hexadecimal address in this format sets the current address. 9 | 10 | ### `w 00 00 00 00 [...] 00` 11 | 12 | Program memory at the current address with content `00 00 00 00 [...] 00`. 13 | The address must be a multiple of 256 (0x100). 14 | The content must containt 256 bytes. 15 | 16 | ### `r` 17 | 18 | Read memory page at the current address and print it as hexadecimal such as `00 00 00 00 [...] 00`. 19 | 20 | ### `e` 21 | 22 | Erase memory page at the current address which will set it to `FF FF FF FF [...] FF`. 23 | 24 | ### `z` 25 | 26 | Fill memory page at the current address with zeroes, which will set it to `00 00 00 00 [...] 00`. 27 | 28 | ### `w` 29 | 30 | Issue a wake-up command to the flash. 31 | 32 | ### `i` 33 | 34 | Run the complete `flash_init()` function. 35 | -------------------------------------------------------------------------------- /examples/rp2_flash_repl/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_flash_repl/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_flash_repl/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_flash_repl/test.py: -------------------------------------------------------------------------------- 1 | from pexpect import fdpexpect 2 | import sys, os 3 | 4 | FF = 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 5 | OO = '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' 6 | 7 | tty = os.open(sys.argv[1], os.O_RDWR) 8 | p = fdpexpect.fdspawn(tty, timeout=1) 9 | 10 | print('resetting position') 11 | p.sendline('0x00000000') 12 | p.expect('0x00000000>') 13 | 14 | print('erase command') 15 | p.sendline('e') 16 | p.expect('repl_command_erase 0x00000000 done') 17 | p.expect('0x00000000>') 18 | 19 | print('read command') 20 | p.sendline('r') 21 | p.expect('repl_command_read 0x00000000 done') 22 | p.expect(f'0x00000000: {FF}') 23 | p.expect(f'0x00000020: {FF}') 24 | p.expect(f'0x00000040: {FF}') 25 | p.expect(f'0x00000060: {FF}') 26 | p.expect(f'0x00000080: {FF}') 27 | p.expect(f'0x000000A0: {FF}') 28 | p.expect(f'0x000000C0: {FF}') 29 | p.expect(f'0x000000E0: {FF}') 30 | 31 | print('zero command') 32 | p.sendline('z') 33 | p.expect('repl_command_zero 0x00000000 done') 34 | p.expect('0x00000000>') 35 | 36 | print('read command') 37 | p.sendline('r') 38 | p.expect('repl_command_read 0x00000000 done') 39 | p.expect(f'0x00000000: {OO}') 40 | p.expect(f'0x00000020: {OO}') 41 | p.expect(f'0x00000040: {OO}') 42 | p.expect(f'0x00000060: {OO}') 43 | p.expect(f'0x00000080: {OO}') 44 | p.expect(f'0x000000A0: {OO}') 45 | p.expect(f'0x000000C0: {OO}') 46 | p.expect(f'0x000000E0: {OO}') 47 | 48 | print('done') 49 | p.close() 50 | -------------------------------------------------------------------------------- /examples/rp2_fpga/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_fpga C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | ) 23 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 24 | ${CMAKE_CURRENT_LIST_DIR} 25 | ) 26 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 27 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 28 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 29 | -------------------------------------------------------------------------------- /examples/rp2_fpga/README.md: -------------------------------------------------------------------------------- 1 | # rp2_fpga 2 | 3 | Does nothing except letting the FPGA start from flash. 4 | The bitstream must already be configured. 5 | -------------------------------------------------------------------------------- /examples/rp2_fpga/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdlib.h" 26 | #include "pico/stdio.h" 27 | #include "boards.h" 28 | #include "ice_fpga.h" 29 | #include "ice_flash.h" 30 | #include "ice_led.h" 31 | 32 | int main(void) { 33 | ice_led_init(); 34 | ice_fpga_init(FPGA_DATA, 48); 35 | ice_fpga_start(FPGA_DATA); 36 | 37 | while (true) { 38 | // let the FPGA run 39 | } 40 | 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /examples/rp2_fpga/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_fpga/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_fpga/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_fpga_io C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | usb_descriptors.c 20 | ) 21 | target_link_libraries(${CMAKE_PROJECT_NAME} 22 | pico_ice_sdk 23 | pico_ice_usb 24 | ) 25 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 26 | ${CMAKE_CURRENT_LIST_DIR} 27 | ) 28 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 29 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 30 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 31 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/README.md: -------------------------------------------------------------------------------- 1 | # rp2_ssram_io 2 | 3 | This example shows you how to use a DMA to write and read the SPI SSRAM on the board. It uses an instance of the SPI to do this. 4 | 5 | Thanks to @z80 for this example. 6 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdlib.h" 26 | #include "pico/stdio.h" 27 | #include "boards.h" 28 | #include "ice_fpga.h" 29 | #include "ice_spi.h" 30 | #include "ice_led.h" 31 | #include "tusb.h" 32 | 33 | #define DATA_LEN 8 34 | #define START_ADDR 0xdead 35 | 36 | int main(void) { 37 | tusb_init(); 38 | ice_led_init(); 39 | ice_fpga_init(12); 40 | ice_fpga_start(); 41 | 42 | for (uint8_t i = 0;; i++) { 43 | uint8_t buffer[] = { i }; 44 | 45 | tud_task(); 46 | ice_fpga_write(0x55551001, buffer, sizeof buffer); 47 | ice_fpga_read(0x55551001, buffer, sizeof buffer); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_fpga_io/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_fpga_io/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/top.py: -------------------------------------------------------------------------------- 1 | import sys, os 2 | sys.path.append(os.path.dirname(__file__) + "/pico-ice-sdk/amaranth") 3 | 4 | # amaranth 5 | from amaranth import * 6 | from amaranth.build import * 7 | from amaranth.cli import main 8 | from amaranth_boards.resources import * 9 | 10 | # pico-ice-sdk 11 | from pico_ice import * 12 | from debouncer import * 13 | 14 | # local 15 | from soc import * 16 | 17 | 18 | __all__ = [ "Top" ] 19 | 20 | 21 | class Top(Elaboratable): 22 | 23 | def elaborate(self): 24 | m = Module() 25 | 26 | rp2040 = platform.request("rp2040", 0) 27 | 28 | # debounce SPI signals, should really be needed? 29 | m.submodules.spi_cs = m_spi_cs = Debouncer(width=1) 30 | m.d.comb += m_spi_cs.i.eq(rp2040.cs) 31 | m.submodules.spi_clk = m_spi_clk = Debouncer(width=1) 32 | m.d.comb += m_spi_clk.i.eq(rp2040.clk) 33 | m.submodules.spi_copi = m_spi_copi = Debouncer(width=1) 34 | m.d.comb += m_spi_copi.i.eq(rp2040.copi) 35 | 36 | # instantiate the main SoC module 37 | m.submodules.soc = m_soc = SoC() 38 | m.d.comb += m_soc.spi.cs.eq(m_spi_cs.o) 39 | m.d.comb += m_soc.spi.copi.eq(m_spi_copi.o) 40 | m.d.comb += m_soc.spi.clk.eq(m_spi_clk.o) 41 | m.d.comb += rp2040.cipo.eq(m_soc.spi.cipo) 42 | 43 | return m 44 | 45 | 46 | if __name__ == "__main__": 47 | platform = PicoIcePlatform() 48 | platform.add_resources([ 49 | Resource("debug", 0, Pins("1 2 3 4 7 8 9 10", conn=("pmod", 3), dir="o")) 50 | ]) 51 | platform.build(Top, do_program=True, program_opts={"dfu_alt": 1}) 52 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | #include "ice_flash.h" 30 | 31 | // RHPort number used for device can be defined by board.mk, port 0 for pico-ice 32 | #define BOARD_DEVICE_RHPORT_NUM 0 33 | 34 | // Device mode with rhport and speed defined by board.mk 35 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE 36 | 37 | // Either full or high speed supported by RP2040 38 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 39 | 40 | // Enable Device stack 41 | #define CFG_TUD_ENABLED 1 42 | 43 | // Default is max speed that hardware controller could support with on-chip PHY 44 | #define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED 45 | 46 | // Device classes 47 | #define CFG_TUD_CDC 0 48 | #define CFG_TUD_MSC 0 49 | #define CFG_TUD_DFU 1 50 | #define CFG_TUD_DFU_ALT 2 51 | #define CFG_TUD_HID 0 52 | #define CFG_TUD_MIDI 0 53 | #define CFG_TUD_VENDOR 0 54 | 55 | // CDC FIFO size of TX and RX and Endpoint buffer size 56 | #define CFG_TUD_CDC_RX_BUFSIZE 512 57 | #define CFG_TUD_CDC_TX_BUFSIZE 512 58 | #define CFG_TUD_CDC_EP_BUFSIZE 512 59 | 60 | // MSC Buffer size of Device Mass storage 61 | #define CFG_TUD_MSC_BUFSIZE ICE_FLASH_SECTOR_SIZE 62 | 63 | // Must be a multiple of flash page size 64 | #define CFG_TUD_DFU_XFER_BUFSIZE 256 65 | -------------------------------------------------------------------------------- /examples/rp2_fpga_io/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "ice_usb.h" 27 | 28 | enum { 29 | ITF_NUM_DFU, 30 | ITF_NUM_TOTAL 31 | }; 32 | 33 | uint8_t const tud_desc_configuration[CONFIG_TOTAL_LEN] = { 34 | TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 500/*mA*/), 35 | TUD_DFU_DESCRIPTOR(ITF_NUM_DFU, CFG_TUD_DFU_ALT, STRID_DFU, DFU_ATTR_CAN_DOWNLOAD, 1000, CFG_TUD_DFU_XFER_BUFSIZE), 36 | }; 37 | 38 | char const *tud_string_desc[STRID_NUM_TOTAL] = { 39 | [STRID_LANGID] = USB_LANG_EN, 40 | [STRID_MANUFACTURER] = USB_MANUFACTURER, 41 | [STRID_PRODUCT] = USB_PRODUCT, 42 | [STRID_SERIAL_NUMBER] = usb_serial_number, 43 | [STRID_VENDOR] = USB_VENDOR, 44 | [STRID_DFU+0] = "iCE40 DFU (Flash)", 45 | [STRID_DFU+1] = "iCE40 DFU (CRAM)", 46 | }; 47 | -------------------------------------------------------------------------------- /examples/rp2_hello_world/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_hello_world C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | pico_stdio_usb 23 | ) 24 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 25 | ${CMAKE_CURRENT_LIST_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | -------------------------------------------------------------------------------- /examples/rp2_hello_world/README.md: -------------------------------------------------------------------------------- 1 | # rp2_usb_hello_world 2 | 3 | In addition to `pico_usb`, print "hello world" in loop across the USB-UART 0. 4 | -------------------------------------------------------------------------------- /examples/rp2_hello_world/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // libc 26 | #include 27 | #include 28 | 29 | // pico-sdk 30 | #include "pico/stdlib.h" 31 | #include "boards.h" 32 | 33 | // tinyusb 34 | #include "tusb.h" 35 | 36 | int main(void) { 37 | tusb_init(); 38 | stdio_init_all(); 39 | 40 | while (true) { 41 | tud_task(); 42 | printf("hello world\r\n"); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /examples/rp2_hello_world/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_hello_world/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_hello_world/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_hello_world/test.py: -------------------------------------------------------------------------------- 1 | from pexpect import fdpexpect 2 | import sys, os 3 | 4 | tty = os.open(sys.argv[1], os.O_RDWR) 5 | p = fdpexpect.fdspawn(tty, timeout=1) 6 | 7 | print('expect hello world') 8 | p.expect('hello world') 9 | 10 | print('done') 11 | p.close() 12 | -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_ice_blinky C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | ) 23 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 24 | ${CMAKE_CURRENT_LIST_DIR} 25 | ${CMAKE_CURRENT_BINARY_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | 31 | set(VERILOG ${CMAKE_CURRENT_LIST_DIR}/top.v) 32 | add_custom_target(bitstream.h 33 | DEPENDS ${VERILOG} 34 | COMMAND yosys -p 'synth_ice40 -abc9 -top top -json bitstream.json' ${VERILOG} 35 | COMMAND nextpnr-ice40 --package sg48 --up5k --freq 48 --top top --pcf ${CMAKE_SOURCE_DIR}/pico_ice.pcf --json bitstream.json --asc bitstream.asc 36 | COMMAND icepack bitstream.asc bitstream.bin 37 | COMMAND python ${CMAKE_CURRENT_LIST_DIR}/bin2header.py bitstream.bin >bitstream.h 38 | ) 39 | add_dependencies(${CMAKE_PROJECT_NAME} bitstream.h) 40 | -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/README.md: -------------------------------------------------------------------------------- 1 | # rp2_ice_blinky 2 | 3 | Example of a basic firmware that embeds the FPGA bitstream inside a same image, to be programmed onto the RP2040. 4 | 5 | The RP2040 the further program the iCE40 with that embedded image, and the flash chip does not get used at all. 6 | 7 | It needs a local [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build) toolchain installed, 8 | or at least `yosys`, `nextpnr-ice40`, `icepack` and `python` in the execution path. 9 | 10 | Originally from 11 | -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/bin2header.py: -------------------------------------------------------------------------------- 1 | # Convert a binary file to a C header 2 | 3 | import sys 4 | 5 | # Read the input file 6 | binary_data = open(sys.argv[1], 'rb').read() 7 | 8 | # Print it as hexadecimal 9 | print(', '.join(map(hex, binary_data))) 10 | -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdlib.h" 26 | #include "pico/stdio.h" 27 | #include "boards.h" 28 | #include "ice_cram.h" 29 | #include "ice_fpga.h" 30 | #include "ice_led.h" 31 | 32 | uint8_t bitstream[] = { 33 | #include "bitstream.h" 34 | }; 35 | 36 | int main(void) { 37 | ice_led_init(); 38 | ice_fpga_init(FPGA_DATA, 48); 39 | ice_fpga_start(FPGA_DATA); 40 | 41 | // Write the whole bitstream to the FPGA CRAM 42 | ice_cram_open(FPGA_DATA); 43 | ice_cram_write(bitstream, sizeof(bitstream)); 44 | ice_cram_close(); 45 | 46 | while (1); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../.. -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_ice_blinky/top.v: -------------------------------------------------------------------------------- 1 | /* Blink the RGB LED */ 2 | 3 | module top ( 4 | input clock, 5 | output LED_R, 6 | output LED_G, 7 | output LED_B 8 | ); 9 | reg [31:0] counter=0; 10 | 11 | always@(posedge clock) begin 12 | counter <= counter +1; 13 | end 14 | 15 | assign {LED_R,LED_G,LED_B} = counter[28:26]; 16 | 17 | endmodule 18 | -------------------------------------------------------------------------------- /examples/rp2_sram/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_sram C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_sdk 22 | pico_stdio_usb 23 | ) 24 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 25 | ${CMAKE_CURRENT_LIST_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | -------------------------------------------------------------------------------- /examples/rp2_sram/README.md: -------------------------------------------------------------------------------- 1 | # rp2_sram 2 | 3 | Write to a page of RAM, read it back, and dump the data read to USB-UART #0 4 | -------------------------------------------------------------------------------- /examples/rp2_sram/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // libc 26 | #include 27 | 28 | // pico-sdk 29 | #include "pico/stdlib.h" 30 | 31 | // pico-ice-sdk 32 | #include "boards.h" 33 | #include "ice_sram.h" 34 | 35 | int main(void) { 36 | stdio_init_all(); 37 | ice_sram_init(FPGA_DATA.bus); 38 | 39 | while (1) { 40 | uint8_t buf[8]; 41 | 42 | ice_sram_get_id(FPGA_DATA.bus, buf); 43 | printf("ChipID: %02X %02X %02X %02X %02X %02X %02X %02X\r\n", 44 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); 45 | 46 | ice_sram_write_blocking(FPGA_DATA.bus, 0x0000, "\x01\x02\x03\x04\x05\x06\x07\x08", 8); 47 | ice_sram_read_blocking(FPGA_DATA.bus, 0x0000, buf, sizeof buf); 48 | printf("0x0000: %02X %02X %02X %02X %02X %02X %02X %02X\r\n", 49 | buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /examples/rp2_sram/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_sram/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_sram/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_sram/test.py: -------------------------------------------------------------------------------- 1 | from pexpect import fdpexpect 2 | import sys, os 3 | 4 | tty = os.open(sys.argv[1], os.O_RDWR) 5 | p = fdpexpect.fdspawn(tty, timeout=1) 6 | 7 | print('expect Chip ID') 8 | p.expect('ChipID: 0D 5D 5A B1 C0 21 9D B2') 9 | 10 | print('expect memory data') 11 | p.expect('0x0000: 01 02 03 04 05 06 07 08') 12 | 13 | print('done') 14 | p.close() 15 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_usb_uart C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | usb_descriptors.c 20 | ) 21 | target_link_libraries(${CMAKE_PROJECT_NAME} 22 | pico_ice_sdk 23 | pico_ice_usb 24 | pico_stdio_usb 25 | ) 26 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 27 | ${CMAKE_CURRENT_LIST_DIR} 28 | ) 29 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 30 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/README.md: -------------------------------------------------------------------------------- 1 | # rp2_usb_fpga 2 | 3 | In addition to the main USB-UART interface, used for the standard I/O (as used by ``) (#0), 4 | a second USB-UART (#1) interface is created: 5 | 6 | - Accept 7 | [wishbone-serial](https://wishbone-utils.readthedocs.io/en/latest/wishbone-tool/#serial-bridge) 8 | requests from USB CDC. 9 | - Mirrors all requests over 10 | [wishbone-spi](https://wishbone-utils.readthedocs.io/en/latest/wishbone-tool/#spi-bridge) 11 | to the FPGA over SPI. 12 | 13 | Any shared I/O pins can be used. In this example, pins 0 and 1 are used. 14 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // pico-sdk 26 | #include "pico/stdio.h" 27 | #include "hardware/irq.h" 28 | #include "hardware/gpio.h" 29 | #include "hardware/uart.h" 30 | 31 | // pico-ice-sdk 32 | #include "ice_usb.h" 33 | #include "ice_fpga.h" 34 | 35 | int main(void) { 36 | stdio_init_all(); // uses CDC0, next available is CDC1 37 | tusb_init(); 38 | 39 | // Configure the piping as configured in 40 | ice_usb_init(); 41 | 42 | // Let the FPGA start 43 | ice_fpga_init(FPGA_DATA, 12); 44 | 45 | // Enable the UART (not done by ice_usb_init()) 46 | uart_init(uart0, 115200); 47 | gpio_set_function(0, GPIO_FUNC_UART); 48 | gpio_set_function(1, GPIO_FUNC_UART); 49 | 50 | while (true) { 51 | tud_task(); 52 | // ice_usb has callbacks for TinyUSB and UART all setup 53 | } 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/test.py: -------------------------------------------------------------------------------- 1 | import pexpect 2 | import sys, os 3 | 4 | FF = 'FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF' 5 | OO = '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00' 6 | 7 | p = pexpect.spawn("dfu-util -l", timeout=1) 8 | 9 | print('expecting two interfaces from dfu-util') 10 | p.expect('1209:b1c0') 11 | p.expect('1209:b1c0') 12 | 13 | print('done') 14 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | #include "ice_flash.h" 30 | 31 | // RHPort number used for device can be defined by board.mk, port 0 for pico-ice 32 | #define BOARD_DEVICE_RHPORT_NUM 0 33 | 34 | // Device mode with rhport and speed defined by board.mk 35 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE 36 | 37 | // Either full or high speed supported by RP2040 38 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 39 | 40 | // Enable Device stack 41 | #define CFG_TUD_ENABLED 1 42 | 43 | // Default is max speed that hardware controller could support with on-chip PHY 44 | #define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED 45 | 46 | // Device classes 47 | #define CFG_TUD_CDC 2 48 | #define CFG_TUD_MSC 0 49 | #define CFG_TUD_DFU 1 50 | #define CFG_TUD_DFU_ALT 2 51 | #define CFG_TUD_HID 0 52 | #define CFG_TUD_MIDI 0 53 | #define CFG_TUD_VENDOR 0 54 | 55 | // Configure piping between USB CDC and UART 56 | #define ICE_USB_UART0_CDC 1 57 | 58 | // CDC FIFO size of TX and RX and Endpoint buffer size 59 | #define CFG_TUD_CDC_RX_BUFSIZE 512 60 | #define CFG_TUD_CDC_TX_BUFSIZE 512 61 | #define CFG_TUD_CDC_EP_BUFSIZE 512 62 | 63 | // MSC Buffer size of Device Mass storage 64 | #define CFG_TUD_MSC_BUFSIZE ICE_FLASH_SECTOR_SIZE 65 | 66 | // Must be a multiple of flash page size 67 | #define CFG_TUD_DFU_XFER_BUFSIZE 256 68 | -------------------------------------------------------------------------------- /examples/rp2_usb_fpga/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "ice_usb.h" 27 | 28 | enum { 29 | ITF_NUM_CDC0, ITF_NUM_CDC0_DATA, 30 | ITF_NUM_CDC1, ITF_NUM_CDC1_DATA, 31 | ITF_NUM_DFU, 32 | ITF_NUM_TOTAL 33 | }; 34 | 35 | uint8_t const tud_desc_configuration[CONFIG_TOTAL_LEN] = { 36 | TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 500/*mA*/), 37 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC0, STRID_CDC+0, EPIN+1, 8, EPOUT+2, EPIN+2, 64), 38 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, STRID_CDC+1, EPIN+3, 8, EPOUT+4, EPIN+4, 64), 39 | TUD_DFU_DESCRIPTOR(ITF_NUM_DFU, CFG_TUD_DFU_ALT, STRID_DFU, DFU_ATTR_CAN_DOWNLOAD, 1000, CFG_TUD_DFU_XFER_BUFSIZE), 40 | }; 41 | 42 | char const *tud_string_desc[STRID_NUM_TOTAL] = { 43 | [STRID_LANGID] = USB_LANG_EN, 44 | [STRID_MANUFACTURER] = USB_MANUFACTURER, 45 | [STRID_PRODUCT] = USB_PRODUCT, 46 | [STRID_SERIAL_NUMBER] = usb_serial_number, 47 | [STRID_VENDOR] = USB_VENDOR, 48 | [STRID_CDC+0] = "RP2040 logs", 49 | [STRID_CDC+1] = "iCE40 UART", 50 | [STRID_DFU+0] = "iCE40 DFU (Flash)", 51 | [STRID_DFU+1] = "iCE40 DFU (CRAM)", 52 | }; 53 | -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_usb_keyboard C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | ) 20 | target_link_libraries(${CMAKE_PROJECT_NAME} 21 | pico_ice_preinit_common 22 | tinyusb_host 23 | ) 24 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 25 | ${CMAKE_CURRENT_LIST_DIR} 26 | ) 27 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 28 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 29 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 30 | -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/README.md: -------------------------------------------------------------------------------- 1 | # rp2_usb_keyboard 2 | 3 | Connect an USB keyboard and an external 5V power supply to VDC/VCC. 4 | 5 | Blink the LED whenever a key is pressed. 6 | The pattern blinked by the LED is the HID key code. 7 | -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/STATUS_UNSUPPORTED: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyvision-ai-inc/pico-ice-sdk/0bb23bd0d871628196eb9e2b1eab3091dec66b0e/examples/rp2_usb_keyboard/STATUS_UNSUPPORTED -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdlib.h" 26 | #include "ice_led.h" 27 | #include "tusb.h" 28 | 29 | #define MAX_REPORT 4 30 | 31 | static struct { 32 | uint8_t report_count; 33 | tuh_hid_report_info_t report_info[MAX_REPORT]; 34 | } g_hid_info[CFG_TUH_HID]; 35 | 36 | // Invoked when device with hid interface is mounted 37 | void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, const uint8_t *desc_report, uint16_t desc_len) { 38 | // Interface protocol (hid_interface_protocol_enum_t) 39 | uint8_t itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); 40 | 41 | // By default host stack will use activate boot protocol on supported interface. 42 | // Therefore for this simple example, we only need to parse generic report descriptor (with built-in parser) 43 | if (itf_protocol == HID_ITF_PROTOCOL_NONE) { 44 | g_hid_info[instance].report_count = tuh_hid_parse_report_descriptor(g_hid_info[instance].report_info, MAX_REPORT, desc_report, desc_len); 45 | } 46 | 47 | // request to receive report 48 | // tuh_hid_report_received_cb() will be invoked when report is available 49 | tuh_hid_receive_report(dev_addr, instance); 50 | } 51 | 52 | // Invoked when device with hid interface is un-mounted 53 | void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { 54 | } 55 | 56 | // Invoked when report is available. 57 | void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, const uint8_t *report, uint16_t len) { 58 | uint8_t itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); 59 | 60 | if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { 61 | const hid_keyboard_report_t *kbd_report = (const hid_keyboard_report_t *) report; 62 | 63 | for (int i = 0; i < count_of(kbd_report->keycode); ++i) { 64 | int key_code = kbd_report->keycode[i]; 65 | if (key_code == 0) continue; 66 | 67 | // Output 8-bit key code as short blink for 0 bit, long blink for 1 bit. 68 | for (int i = 0; i < 8; ++i) { 69 | ice_led_red(false); 70 | sleep_ms(key_code & 1 ? 25 : 50); 71 | ice_led_red(true); 72 | sleep_ms(50); 73 | 74 | key_code >>= 1; 75 | } 76 | } 77 | } 78 | 79 | tuh_hid_receive_report(dev_addr, instance); 80 | } 81 | 82 | int main(void) { 83 | tusb_init(); 84 | ice_led_init(); 85 | 86 | while (1) { 87 | tuh_task(); 88 | } 89 | 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk/ -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_usb_keyboard/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | 30 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_HOST 31 | 32 | // USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. 33 | // Tinyusb use follows macros to declare transferring memory so that they can be put 34 | // into those specific section. 35 | // e.g 36 | // - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) 37 | // - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) 38 | #ifndef CFG_TUSB_MEM_SECTION 39 | #define CFG_TUSB_MEM_SECTION 40 | #endif 41 | 42 | #ifndef CFG_TUSB_MEM_ALIGN 43 | #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) 44 | #endif 45 | 46 | // Size of buffer to hold descriptors and other data used for enumeration 47 | #define CFG_TUH_ENUMERATION_BUFSIZE 256 48 | 49 | #define CFG_TUH_HUB 1 50 | #define CFG_TUH_CDC 0 51 | #define CFG_TUH_HID 4 // typical keyboard + mouse device can have 3-4 HID interfaces 52 | #define CFG_TUH_MSC 0 53 | #define CFG_TUH_VENDOR 0 54 | 55 | // max device support (excluding hub device) 56 | #define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports 57 | 58 | #define CFG_TUH_HID_EPIN_BUFSIZE 64 59 | #define CFG_TUH_HID_EPOUT_BUFSIZE 64 60 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_usb_spi C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | usb_descriptors.c 20 | ) 21 | target_link_libraries(${CMAKE_PROJECT_NAME} 22 | pico_ice_preinit_common 23 | pico_ice_sdk 24 | pico_ice_usb 25 | pico_stdio_usb 26 | ) 27 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 28 | ${CMAKE_CURRENT_LIST_DIR} 29 | ) 30 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 31 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 32 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 33 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/README.md: -------------------------------------------------------------------------------- 1 | # rp2_usb_spi 2 | 3 | In addition to the main USB-CDC interface, used for the standard I/O (as used by ``) (#0), 4 | a second USB-CDC (#1) interface is created: 5 | 6 | - mirrors all input from the USB-CDC to the SPI bus, 7 | - mirrors back all SPI data to the USB-CDC 8 | 9 | Use `/dev/ttyACM#` on Linux-like systems, and `COM#` on Windows system, replacing the `#` by the interface number, usually `2`. 10 | 11 | ```shell 12 | python3 test.py /dev/ttyACM2 13 | ``` 14 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // libc 26 | #include 27 | #include 28 | 29 | // pico-sdk 30 | #include "pico/stdlib.h" 31 | #include "boards.h" 32 | 33 | // tinyusb 34 | #include "tusb.h" 35 | 36 | // pico-ice-sdk 37 | #include "ice_usb.h" 38 | #include "ice_spi.h" 39 | 40 | int main(void) { 41 | tusb_init(); 42 | stdio_init_all(); 43 | 44 | // Setup the SPI forwarding as configured in tusb_config.h 45 | ice_usb_init(); 46 | 47 | while (true) { 48 | tud_task(); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_usb_spi/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk -------------------------------------------------------------------------------- /examples/rp2_usb_spi/pico_ice_spi.py: -------------------------------------------------------------------------------- 1 | import serial 2 | import sys 3 | 4 | class PicoIceSpi: 5 | USE_FPGA = 0x00 6 | USE_SRAM = 0x01 7 | USE_FLASH = 0x02 8 | 9 | def __init__(self, port): 10 | self.ser = serial.Serial(port) 11 | 12 | def write(self, buffer): 13 | for chunk in [buffer[i:i + 0x7F] for i in range(0, len(buffer), 0x7F)]: 14 | self.ser.write(bytes([len(chunk) | (0 << 7)])) 15 | self.ser.write(chunk) 16 | 17 | def read(self, length): 18 | buffer = bytearray() 19 | while length > 0: 20 | self.ser.write(bytes([min(0x7F, length) | (1 << 7)])) 21 | buffer.extend(self.ser.read(size=min(0x7F, length))) 22 | length -= 0x7F 23 | return buffer 24 | 25 | def done(self): 26 | self.ser.write(b'\x00') 27 | 28 | def command(self, byte): 29 | self.ser.write([0x80, byte]) 30 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/test.py: -------------------------------------------------------------------------------- 1 | from pico_ice_spi import * 2 | import binascii 3 | 4 | # Open the port given as argument 5 | spi = PicoIceSpi(sys.argv[1]) 6 | 7 | # Query the SRAM ID 8 | spi.command(spi.USE_SRAM) 9 | spi.write(b'\x9F\x00\x00\x00') 10 | id = spi.read(8) 11 | print('SRAM ID: ' + str(binascii.b2a_hex(id, ' '))) 12 | spi.done() 13 | 14 | # Query the FLASH ID 15 | spi.command(spi.USE_FLASH) 16 | spi.write(bytes(b'\xAB\x00\x00\x00')) 17 | id = spi.read(1) 18 | print('FLASH ID: ' + str(binascii.b2a_hex(id, ' '))) 19 | spi.done() 20 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | #include "ice_flash.h" 30 | 31 | // RHPort number used for device can be defined by board.mk, port 0 for pico-ice 32 | #define BOARD_DEVICE_RHPORT_NUM 0 33 | 34 | // Device mode with rhport and speed defined by board.mk 35 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE 36 | 37 | // Either full or high speed supported by RP2040 38 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 39 | 40 | // Enable Device stack 41 | #define CFG_TUD_ENABLED 1 42 | 43 | // Default is max speed that hardware controller could support with on-chip PHY 44 | #define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED 45 | 46 | // Device classes 47 | #define CFG_TUD_CDC 2 48 | #define CFG_TUD_MSC 0 49 | #define CFG_TUD_DFU 1 50 | #define CFG_TUD_DFU_ALT 2 51 | #define CFG_TUD_HID 0 52 | #define CFG_TUD_MIDI 0 53 | #define CFG_TUD_VENDOR 0 54 | 55 | // Configure forwarding between USB CDC and SPI 56 | #define ICE_USB_SPI_CDC 1 57 | 58 | // CDC FIFO size of TX and RX and Endpoint buffer size 59 | #define CFG_TUD_CDC_RX_BUFSIZE 512 60 | #define CFG_TUD_CDC_TX_BUFSIZE 512 61 | #define CFG_TUD_CDC_EP_BUFSIZE 512 62 | 63 | // MSC Buffer size of Device Mass storage 64 | #define CFG_TUD_MSC_BUFSIZE ICE_FLASH_SECTOR_SIZE 65 | 66 | // Must be a multiple of flash page size 67 | #define CFG_TUD_DFU_XFER_BUFSIZE 256 68 | -------------------------------------------------------------------------------- /examples/rp2_usb_spi/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "ice_usb.h" 27 | 28 | enum { 29 | ITF_NUM_CDC0, ITF_NUM_CDC0_DATA, 30 | ITF_NUM_CDC1, ITF_NUM_CDC1_DATA, 31 | ITF_NUM_DFU, 32 | ITF_NUM_TOTAL 33 | }; 34 | 35 | uint8_t const tud_desc_configuration[CONFIG_TOTAL_LEN] = { 36 | TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 500/*mA*/), 37 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC0, STRID_CDC+0, EPIN+1, 8, EPOUT+2, EPIN+2, 64), 38 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, STRID_CDC+1, EPIN+3, 8, EPOUT+4, EPIN+4, 64), 39 | TUD_DFU_DESCRIPTOR(ITF_NUM_DFU, CFG_TUD_DFU_ALT, STRID_DFU, DFU_ATTR_CAN_DOWNLOAD, 1000, CFG_TUD_DFU_XFER_BUFSIZE), 40 | }; 41 | 42 | char const *tud_string_desc[STRID_NUM_TOTAL] = { 43 | [STRID_LANGID] = USB_LANG_EN, 44 | [STRID_MANUFACTURER] = USB_MANUFACTURER, 45 | [STRID_PRODUCT] = USB_PRODUCT, 46 | [STRID_SERIAL_NUMBER] = usb_serial_number, 47 | [STRID_VENDOR] = USB_VENDOR, 48 | [STRID_CDC+0] = "RP2040 logs", 49 | [STRID_CDC+1] = "SPI", 50 | [STRID_DFU+0] = "iCE40 DFU (Flash)", 51 | [STRID_DFU+1] = "iCE40 DFU (CRAM)", 52 | }; 53 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_usb_uart C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | usb_descriptors.c 20 | ) 21 | target_link_libraries(${CMAKE_PROJECT_NAME} 22 | pico_ice_sdk 23 | pico_ice_usb 24 | ) 25 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 26 | ${CMAKE_CURRENT_LIST_DIR} 27 | ) 28 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 29 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/README.md: -------------------------------------------------------------------------------- 1 | # rp2_usb_uart 2 | 3 | In addition to the main USB-UART interface, used for the standard I/O (as used by ``) (#0), 4 | a second USB-UART (#1) interface is created: 5 | 6 | - mirrors all input from the USB-UART to the FPGA as UART data, 7 | - mirrors back all UART data from the FPGA to the USB-UART 8 | 9 | Any shared I/O pins can be used. In this example, pins 0 and 1 are used. 10 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // pico-sdk 26 | #include "pico/stdio.h" 27 | #include "hardware/irq.h" 28 | #include "hardware/gpio.h" 29 | #include "hardware/uart.h" 30 | 31 | // pico-ice-sdk 32 | #include "ice_usb.h" 33 | #include "ice_fpga.h" 34 | 35 | #define UART_TX_PIN 0 36 | #define UART_RX_PIN 1 37 | 38 | int main(void) { 39 | // Enable the UART 40 | uart_init(uart0, 115200); 41 | gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART); 42 | gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART); 43 | 44 | // Configure the piping as configured in 45 | ice_usb_init(); 46 | 47 | // Initialize the FPGA 48 | ice_fpga_init(FPGA_DATA, 48); 49 | 50 | // Let the FPGA start 51 | ice_fpga_start(FPGA_DATA); 52 | 53 | while (true) { 54 | tud_task(); 55 | } 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_usb_uart/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk -------------------------------------------------------------------------------- /examples/rp2_usb_uart/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | #include "ice_flash.h" 30 | 31 | // RHPort number used for device can be defined by board.mk, port 0 for pico-ice 32 | #define BOARD_DEVICE_RHPORT_NUM 0 33 | 34 | // Device mode with rhport and speed defined by board.mk 35 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE 36 | 37 | // Either full or high speed supported by RP2040 38 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 39 | 40 | // Enable Device stack 41 | #define CFG_TUD_ENABLED 1 42 | 43 | // Default is max speed that hardware controller could support with on-chip PHY 44 | #define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED 45 | 46 | // Device classes 47 | #define CFG_TUD_CDC 2 48 | #define CFG_TUD_MSC 0 49 | #define CFG_TUD_DFU 1 50 | #define CFG_TUD_DFU_ALT 2 51 | #define CFG_TUD_HID 0 52 | #define CFG_TUD_MIDI 0 53 | #define CFG_TUD_VENDOR 0 54 | 55 | // Configure forwarding between USB CDC and UART 56 | #define ICE_USB_UART0_CDC 1 57 | 58 | // CDC FIFO size of TX and RX and Endpoint buffer size 59 | #define CFG_TUD_CDC_RX_BUFSIZE 512 60 | #define CFG_TUD_CDC_TX_BUFSIZE 512 61 | #define CFG_TUD_CDC_EP_BUFSIZE 512 62 | 63 | // MSC Buffer size of Device Mass storage 64 | #define CFG_TUD_MSC_BUFSIZE ICE_FLASH_SECTOR_SIZE 65 | 66 | // Must be a multiple of flash page size 67 | #define CFG_TUD_DFU_XFER_BUFSIZE 256 68 | -------------------------------------------------------------------------------- /examples/rp2_usb_uart/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "ice_usb.h" 27 | 28 | enum { 29 | ITF_NUM_CDC0, ITF_NUM_CDC0_DATA, 30 | ITF_NUM_CDC1, ITF_NUM_CDC1_DATA, 31 | ITF_NUM_DFU, 32 | ITF_NUM_TOTAL 33 | }; 34 | 35 | uint8_t const tud_desc_configuration[CONFIG_TOTAL_LEN] = { 36 | TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 500/*mA*/), 37 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC0, STRID_CDC+0, EPIN+1, 8, EPOUT+2, EPIN+2, 64), 38 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC1, STRID_CDC+1, EPIN+3, 8, EPOUT+4, EPIN+4, 64), 39 | TUD_DFU_DESCRIPTOR(ITF_NUM_DFU, CFG_TUD_DFU_ALT, STRID_DFU, DFU_ATTR_CAN_DOWNLOAD, 1000, CFG_TUD_DFU_XFER_BUFSIZE), 40 | }; 41 | 42 | char const *tud_string_desc[STRID_NUM_TOTAL] = { 43 | [STRID_LANGID] = USB_LANG_EN, 44 | [STRID_MANUFACTURER] = USB_MANUFACTURER, 45 | [STRID_PRODUCT] = USB_PRODUCT, 46 | [STRID_SERIAL_NUMBER] = usb_serial_number, 47 | [STRID_VENDOR] = USB_VENDOR, 48 | [STRID_CDC+0] = "RP2040 logs", 49 | [STRID_CDC+1] = "iCE40 UART", 50 | [STRID_DFU+0] = "iCE40 DFU (Flash)", 51 | [STRID_DFU+1] = "iCE40 DFU (CRAM)", 52 | }; 53 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | include(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/cmake/preinit_pico_ice_sdk.cmake) 4 | 5 | # import the pico-sdk 6 | set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/) 7 | include(pico_sdk_import.cmake) 8 | 9 | # configure the pico-sdk project 10 | project(rp2_usb_uf2 C CXX ASM) 11 | pico_sdk_init() 12 | 13 | # add the pico-ice-sdk 14 | add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/) 15 | 16 | # add the local files 17 | add_executable(${CMAKE_PROJECT_NAME} 18 | main.c 19 | usb_descriptors.c 20 | ) 21 | target_link_libraries(${CMAKE_PROJECT_NAME} 22 | pico_ice_sdk 23 | pico_ice_usb 24 | ) 25 | target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC 26 | ${CMAKE_CURRENT_LIST_DIR} 27 | ) 28 | pico_add_extra_outputs(${CMAKE_PROJECT_NAME}) 29 | pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 0) 30 | pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0) 31 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/README.md: -------------------------------------------------------------------------------- 1 | # rp2_ice_uf2 2 | 3 | Provides an example for how to configure the TinyUF2 USB interface. 4 | 5 | Once connected to an USB host, it will bring an MSC (storage device) interface, that can be mountd as a regular FAT pendrive. 6 | An `UF2`-formatted bitstream can be copied to it, as generated by the [`uf2tools`](../../../tools/). 7 | 8 | After unmounting the drive, the bitstream will be programmed onto the flash chip of the pico-ice board. 9 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/blinky.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyvision-ai-inc/pico-ice-sdk/0bb23bd0d871628196eb9e2b1eab3091dec66b0e/examples/rp2_usb_uf2/blinky.uf2 -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "pico/stdio.h" 26 | #include "hardware/irq.h" 27 | #include "hardware/gpio.h" 28 | #include "hardware/uart.h" 29 | #include "ice_usb.h" 30 | #include "ice_fpga.h" 31 | 32 | int main(void) { 33 | ice_usb_init(); 34 | 35 | // Initialize the FPGA 36 | ice_fpga_init(FPGA_DATA, 48); 37 | 38 | // Let the FPGA start 39 | ice_fpga_start(FPGA_DATA); 40 | 41 | while (true) { 42 | tud_task(); 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/null.uf2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tinyvision-ai-inc/pico-ice-sdk/0bb23bd0d871628196eb9e2b1eab3091dec66b0e/examples/rp2_usb_uf2/null.uf2 -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/pico-ice-sdk: -------------------------------------------------------------------------------- 1 | ../../ -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/pico-sdk: -------------------------------------------------------------------------------- 1 | ../../lib/pico-sdk -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/pico_sdk_import.cmake: -------------------------------------------------------------------------------- 1 | # This is a copy of /external/pico_sdk_import.cmake 2 | 3 | # This can be dropped into an external project to help locate this SDK 4 | # It should be include()ed prior to project() 5 | 6 | if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) 7 | set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) 8 | message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") 9 | endif () 10 | 11 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) 12 | set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) 13 | message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") 14 | endif () 15 | 16 | if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) 17 | set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) 18 | message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") 19 | endif () 20 | 21 | set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") 22 | set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") 23 | set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") 24 | 25 | if (NOT PICO_SDK_PATH) 26 | if (PICO_SDK_FETCH_FROM_GIT) 27 | include(FetchContent) 28 | set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) 29 | if (PICO_SDK_FETCH_FROM_GIT_PATH) 30 | get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") 31 | endif () 32 | # GIT_SUBMODULES_RECURSE was added in 3.17 33 | if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0") 34 | FetchContent_Declare( 35 | pico_sdk 36 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 37 | GIT_TAG master 38 | GIT_SUBMODULES_RECURSE FALSE 39 | ) 40 | else () 41 | FetchContent_Declare( 42 | pico_sdk 43 | GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk 44 | GIT_TAG master 45 | ) 46 | endif () 47 | 48 | if (NOT pico_sdk) 49 | message("Downloading Raspberry Pi Pico SDK") 50 | FetchContent_Populate(pico_sdk) 51 | set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) 52 | endif () 53 | set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) 54 | else () 55 | message(FATAL_ERROR 56 | "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." 57 | ) 58 | endif () 59 | endif () 60 | 61 | get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") 62 | if (NOT EXISTS ${PICO_SDK_PATH}) 63 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") 64 | endif () 65 | 66 | set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) 67 | if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) 68 | message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") 69 | endif () 70 | 71 | set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) 72 | 73 | include(${PICO_SDK_INIT_CMAKE_FILE}) 74 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/tusb_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #pragma once 26 | 27 | // pico-ice-sdk 28 | #include "boards.h" 29 | #include "ice_flash.h" 30 | 31 | // RHPort number used for device can be defined by board.mk, port 0 for pico-ice 32 | #define BOARD_DEVICE_RHPORT_NUM 0 33 | 34 | // Device mode with rhport and speed defined by board.mk 35 | #define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE 36 | 37 | // Either full or high speed supported by RP2040 38 | #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED 39 | 40 | // Enable Device stack 41 | #define CFG_TUD_ENABLED 1 42 | 43 | // Default is max speed that hardware controller could support with on-chip PHY 44 | #define CFG_TUD_MAX_SPEED OPT_MODE_FULL_SPEED 45 | 46 | // Device classes 47 | #define CFG_TUD_CDC 1 48 | #define CFG_TUD_MSC 1 49 | #define CFG_TUD_DFU 1 50 | #define CFG_TUD_DFU_ALT 2 51 | #define CFG_TUD_HID 0 52 | #define CFG_TUD_MIDI 0 53 | #define CFG_TUD_VENDOR 0 54 | 55 | // Enable TinyUF2 56 | #define ICE_USB_USE_TINYUF2_MSC 1 57 | 58 | // CDC FIFO size of TX and RX and Endpoint buffer size 59 | #define CFG_TUD_CDC_RX_BUFSIZE 512 60 | #define CFG_TUD_CDC_TX_BUFSIZE 512 61 | #define CFG_TUD_CDC_EP_BUFSIZE 512 62 | 63 | // MSC Buffer size of Device Mass storage 64 | #define CFG_TUD_MSC_BUFSIZE ICE_FLASH_SECTOR_SIZE 65 | 66 | // Must be a multiple of flash page size 67 | #define CFG_TUD_DFU_XFER_BUFSIZE 256 68 | -------------------------------------------------------------------------------- /examples/rp2_usb_uf2/usb_descriptors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2019 Ha Thach (tinyusb.org) 5 | * Copyright (c) 2022 TinyVision.ai Inc. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #include "ice_usb.h" 27 | 28 | enum { 29 | ITF_NUM_CDC0, ITF_NUM_CDC0_DATA, 30 | ITF_NUM_MSC0, 31 | ITF_NUM_DFU, 32 | ITF_NUM_TOTAL 33 | }; 34 | 35 | uint8_t const tud_desc_configuration[CONFIG_TOTAL_LEN] = { 36 | TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 500/*mA*/), 37 | TUD_CDC_DESCRIPTOR(ITF_NUM_CDC0, STRID_CDC+0, EPIN+1, 8, EPOUT+2, EPIN+2, 64), 38 | TUD_MSC_DESCRIPTOR(ITF_NUM_MSC0, STRID_MSC+0, EPOUT+3, EPIN+3, 64), 39 | TUD_DFU_DESCRIPTOR(ITF_NUM_DFU, CFG_TUD_DFU_ALT, STRID_DFU, DFU_ATTR_CAN_DOWNLOAD, 1000, CFG_TUD_DFU_XFER_BUFSIZE), 40 | }; 41 | 42 | char const *tud_string_desc[STRID_NUM_TOTAL] = { 43 | [STRID_LANGID] = USB_LANG_EN, 44 | [STRID_MANUFACTURER] = USB_MANUFACTURER, 45 | [STRID_PRODUCT] = USB_PRODUCT, 46 | [STRID_SERIAL_NUMBER] = usb_serial_number, 47 | [STRID_VENDOR] = USB_VENDOR, 48 | [STRID_CDC+0] = "RP2040 logs", 49 | [STRID_MSC+0] = "iCE40 MSC (Flash)", 50 | [STRID_DFU+0] = "iCE40 DFU (Flash)", 51 | [STRID_DFU+1] = "iCE40 DFU (CRAM)", 52 | }; 53 | -------------------------------------------------------------------------------- /include/boards.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | #ifndef BOARDS_H_ 25 | #define BOARDS_H_ 26 | 27 | #ifdef PICO2_ICE 28 | #include "boards/pico2_ice.h" 29 | #elif defined(PICO_ICE) 30 | #include "boards/pico_ice.h" 31 | #else 32 | #error "pico-ice board model not found, check the value of PICO_BOARD" 33 | #endif 34 | 35 | #define ICE_FLASH_BAUDRATE 10000000 36 | 37 | // Allow compilation of TinyUF2 without changing any source file. 38 | // For board detection 39 | #define TINYVISION_AI_INC_PICO_ICE 40 | #define UF2_VERSION "0" 41 | #define UF2_INDEX_URL "https://pico-ice.tinyvision.ai/" 42 | #define UF2_VOLUME_LABEL PICO_ICE_BOARD_NAME 43 | #define UF2_PRODUCT_NAME PICO_ICE_BOARD_NAME 44 | #define UF2_BOARD_ID PICO_ICE_BOARD_NAME 45 | #define BOARD_UF2_FAMILY_ID ICE_UF2_FAMILY_ID 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/boards/ice40up5k.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * Copyright (c) 2023 TinyVision.ai Inc. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | // ----------------------------------------------------- 9 | // NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO 10 | // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES 11 | // ----------------------------------------------------- 12 | #ifndef ICE40UP5K_H_ 13 | #define ICE40UP5K_H_ 14 | 15 | // ICE40 FPGA IO (PACKAGE NAMES) 16 | #define ICE_FPGA_27_PIN 0 17 | #define ICE_FPGA_25_PIN 1 18 | #define ICE_FPGA_21_PIN 2 19 | #define ICE_FPGA_19_PIN 3 20 | #define ICE_FPGA_26_PIN 4 21 | #define ICE_FPGA_23_PIN 5 22 | #define ICE_FPGA_20_PIN 6 23 | #define ICE_FPGA_18_PIN 7 24 | #define ICE_FPGA_14_PIN 8 25 | #define ICE_FPGA_16_PIN 9 26 | #define ICE_FPGA_15_PIN 10 27 | #define ICE_FPGA_17_PIN 11 28 | #define ICE_FPGA_37_PIN 14 29 | #define ICE_FPGA_35_PIN 24 30 | #define ICE_FPGA_7_PIN 26 # CDONE 31 | #define ICE_FPGA_8_PIN 27 # RESET 32 | // ICE40 FPGA IO (SILICON DIE NAMES) 33 | #define ICE_FPGA_IOB_6a_PIN ICE_FPGA_2_PIN 34 | #define ICE_FPGA_IOB_9b_PIN ICE_FPGA_3_PIN 35 | #define ICE_FPGA_IOB_8a_PIN ICE_FPGA_4_PIN 36 | #define ICE_FPGA_IOB_13b_PIN ICE_FPGA_6_PIN 37 | #define ICE_FPGA_IOB_16a_PIN ICE_FPGA_9_PIN 38 | #define ICE_FPGA_IOB_18a_PIN ICE_FPGA_10_PIN 39 | #define ICE_FPGA_IOB_20a_PIN ICE_FPGA_11_PIN 40 | #define ICE_FPGA_IOB_31b_PIN ICE_FPGA_18_PIN 41 | #define ICE_FPGA_IOB_29b_PIN ICE_FPGA_19_PIN 42 | #define ICE_FPGA_IOB_25b_PIN ICE_FPGA_20_PIN 43 | #define ICE_FPGA_IOT_23b_PIN ICE_FPGA_21_PIN 44 | #define ICE_FPGA_IOT_37a_PIN ICE_FPGA_23_PIN 45 | #define ICE_FPGA_IOT_36b_PIN ICE_FPGA_25_PIN 46 | #define ICE_FPGA_IOT_39a_PIN ICE_FPGA_26_PIN 47 | #define ICE_FPGA_IOT_38b_PIN ICE_FPGA_27_PIN 48 | #define ICE_FPGA_IOT_41a_PIN ICE_FPGA_28_PIN 49 | #define ICE_FPGA_IOT_42b_PIN ICE_FPGA_31_PIN 50 | #define ICE_FPGA_IOT_43a_PIN ICE_FPGA_32_PIN 51 | #define ICE_FPGA_IOT_44b_PIN ICE_FPGA_34_PIN 52 | #define ICE_FPGA_IOT_46b_PIN ICE_FPGA_35_PIN 53 | #define ICE_FPGA_IOT_48b_PIN ICE_FPGA_36_PIN 54 | #define ICE_FPGA_IOT_50b_PIN ICE_FPGA_38_PIN 55 | #define ICE_FPGA_IOT_51a_PIN ICE_FPGA_42_PIN 56 | #define ICE_FPGA_IOT_49a_PIN ICE_FPGA_43_PIN 57 | #define ICE_FPGA_IOB_3b_PIN ICE_FPGA_44_PIN 58 | #define ICE_FPGA_IOB_5b_PIN ICE_FPGA_45_PIN 59 | #define ICE_FPGA_IOB_0a_PIN ICE_FPGA_46_PIN 60 | #define ICE_FPGA_IOB_2b_PIN ICE_FPGA_47_PIN 61 | #define ICE_FPGA_IOB_4a_PIN ICE_FPGA_48_PIN 62 | #define ICE_FPGA_IOB_22a_PIN ICE_FPGA_12_PIN 63 | #define ICE_FPGA_IOB_24a_PIN ICE_FPGA_13_PIN 64 | #define ICE_FPGA_IOB_18a_PIN ICE_FPGA_10_PIN 65 | #define ICE_FPGA_IOB_32a_PIN ICE_FPGA_14_PIN 66 | #define ICE_FPGA_IOB_33b_PIN ICE_FPGA_17_PIN 67 | #define ICE_FPGA_IOB_34a_PIN ICE_FPGA_15_PIN 68 | #define ICE_FPGA_IOB_35b_PIN ICE_FPGA_16_PIN 69 | #define ICE_FPGA_IOT_45a_PIN ICE_FPGA_37_PIN 70 | 71 | #endif -------------------------------------------------------------------------------- /include/boards/pico2_ice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * Copyright (c) 2023 TinyVision.ai Inc. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | // ----------------------------------------------------- 9 | // NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO 10 | // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES 11 | // ----------------------------------------------------- 12 | 13 | #ifndef PICO2_ICE_H_ 14 | #define PICO2_ICE_H_ 15 | #include "ice40up5k.h" 16 | 17 | // For board detection 18 | #ifndef PICO2_ICE 19 | #define PICO2_ICE 2 20 | #endif 21 | #ifndef PICO_ICE_BOARD_ID 22 | #define PICO_ICE_BOARD_ID PICO2_ICE 23 | #endif 24 | #define PICO_ICE_BOARD_NAME "pico2-ice" 25 | 26 | // --- RP2350 VARIANT --- 27 | #define PICO_RP2350B 1 28 | 29 | // On some samples, the xosc can take longer to stabilize than is usual 30 | #ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER 31 | #define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 32 | #endif 33 | 34 | // --- LED --- 35 | #ifndef PICO_DEFAULT_LED_PIN 36 | #define PICO_DEFAULT_LED_PIN 1 37 | #endif 38 | 39 | // --- I2C --- 40 | #ifndef PICO_DEFAULT_I2C 41 | #define PICO_DEFAULT_I2C 0 42 | #endif 43 | #ifndef PICO_DEFAULT_I2C_SDA_PIN 44 | #define PICO_DEFAULT_I2C_SDA_PIN 12 45 | #endif 46 | #ifndef PICO_DEFAULT_I2C_SCL_PIN 47 | #define PICO_DEFAULT_I2C_SCL_PIN 13 48 | #endif 49 | 50 | // --- SPI --- 51 | #define PICO_DEFAULT_SPI 1 //timo foo original value 0 52 | #define PICO_DEFAULT_SPI_SCK_PIN 34 //PICO_PMOD_A4 SCK 53 | #define PICO_DEFAULT_SPI_TX_PIN 35 //PICO_PMOD_A2 TX 54 | #define PICO_DEFAULT_SPI_RX_PIN 32 //PICO_PMOD_A3 RX 55 | #define PICO_DEFAULT_CSN_PIN 33 //PICO_PMOD_A1 SSn 56 | 57 | // --- FLASH --- 58 | #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 59 | #ifndef PICO_FLASH_SIZE_BYTES 60 | #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) 61 | #endif 62 | #ifndef PICO_FLASH_SPI_CLKDIV 63 | #define PICO_FLASH_SPI_CLKDIV 2 64 | #endif 65 | #ifndef PICO_RP2350_A2_SUPPORTED 66 | #define PICO_RP2350_A2_SUPPORTED 1 67 | #endif 68 | 69 | // --- BOARD SPECIFIC --- 70 | // LED 71 | #define ICE_LED_RED_PIN 1 72 | #define ICE_LED_GREEN_PIN 0 73 | #define ICE_LED_BLUE_PIN 9 74 | // FLASH 75 | #ifndef ICE_FLASH_SIZE_BYTES 76 | #define ICE_FLASH_SIZE_BYTES (4 * 1024 * 1024) 77 | #endif 78 | // SRAM 79 | #ifndef ICE_SRAM_SIZE_BYTES 80 | #define ICE_SRAM_SIZE_BYTES (8 * 1024 * 1024) 81 | #endif 82 | // MISC 83 | #define ICE_GPOUT_CLOCK_PIN 22 //PICO_CLKOUT 84 | #define ICE_RESET_BUTTON_PIN 42 //ADC2|PB 85 | // FPGA UART 86 | #define ICE_UART_TX 255 87 | #define ICE_UART_RX 255 88 | 89 | #define FPGA_DATA pico2_fpga 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /include/boards/pico_ice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 | * Copyright (c) 2023 TinyVision.ai Inc. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | // ----------------------------------------------------- 9 | // NOTE: THIS HEADER IS ALSO INCLUDED BY ASSEMBLER SO 10 | // SHOULD ONLY CONSIST OF PREPROCESSOR DIRECTIVES 11 | // ----------------------------------------------------- 12 | 13 | #ifndef PICO_ICE_H_ 14 | #define PICO_ICE_H_ 15 | #include "ice40up5k.h" 16 | 17 | // For board detection 18 | #ifndef PICO_ICE 19 | #define PICO_ICE 1 20 | #endif 21 | #ifndef PICO_ICE_BOARD_ID 22 | #define PICO_ICE_BOARD_ID PICO_ICE 23 | #endif 24 | #define PICO_ICE_BOARD_NAME "pico-ice" 25 | 26 | // --- LED --- 27 | #ifndef PICO_DEFAULT_LED_PIN 28 | #define PICO_DEFAULT_LED_PIN 15 29 | #endif 30 | 31 | // --- I2C --- 32 | #ifndef PICO_DEFAULT_I2C 33 | #define PICO_DEFAULT_I2C 0 34 | #endif 35 | #ifndef PICO_DEFAULT_I2C_SDA_PIN 36 | #define PICO_DEFAULT_I2C_SDA_PIN 12 37 | #endif 38 | #ifndef PICO_DEFAULT_I2C_SCL_PIN 39 | #define PICO_DEFAULT_I2C_SCL_PIN 13 40 | #endif 41 | 42 | // --- SPI --- 43 | #ifndef PICO_DEFAULT_SPI 44 | #define PICO_DEFAULT_SPI 0 45 | #endif 46 | #ifndef PICO_DEFAULT_SPI_SCK_PIN 47 | #define PICO_DEFAULT_SPI_SCK_PIN 18 48 | #endif 49 | #ifndef PICO_DEFAULT_SPI_TX_PIN 50 | #define PICO_DEFAULT_SPI_TX_PIN 19 51 | #endif 52 | #ifndef PICO_DEFAULT_SPI_RX_PIN 53 | #define PICO_DEFAULT_SPI_RX_PIN 16 54 | #endif 55 | #ifndef PICO_DEFAULT_CSN_PIN 56 | #define PICO_DEFAULT_CSN_PIN 17 57 | #endif 58 | 59 | // --- FLASH --- 60 | #define PICO_BOOT_STAGE2_CHOOSE_W25Q080 1 61 | #ifndef PICO_FLASH_SIZE_BYTES 62 | #define PICO_FLASH_SIZE_BYTES (4 * 1024 * 1024) 63 | #endif 64 | #ifndef PICO_FLASH_SPI_CLKDIV 65 | #define PICO_FLASH_SPI_CLKDIV 2 66 | #endif 67 | #ifndef PICO_RP2040_B0_SUPPORTED 68 | #define PICO_RP2040_B0_SUPPORTED 1 69 | #endif 70 | #ifndef PICO_RP2040_B1_SUPPORTED 71 | #define PICO_RP2040_B1_SUPPORTED 0 72 | #endif 73 | 74 | // --- BOARD SPECIFIC --- 75 | // LED 76 | #define ICE_LED_RED_PIN 13 77 | #define ICE_LED_GREEN_PIN 12 78 | #define ICE_LED_BLUE_PIN 15 79 | // FLASH 80 | #ifndef ICE_FLASH_SIZE_BYTES 81 | #define ICE_FLASH_SIZE_BYTES (4 * 1024 * 1024) 82 | #endif 83 | // SRAM 84 | #ifndef ICE_SRAM_SIZE_BYTES 85 | #define ICE_SRAM_SIZE_BYTES (8 * 1024 * 1024) 86 | #endif 87 | // MISC 88 | #define ICE_GPOUT_CLOCK_PIN 25 89 | #define ICE_RESET_BUTTON_PIN 28 90 | // UART 91 | #ifndef ICE_FPGA_UART_TX 92 | #define ICE_FPGA_UART_TX 0 93 | #endif 94 | #ifndef ICE_FPGA_UART_RX 95 | #define ICE_FPGA_UART_RX 1 96 | #endif 97 | 98 | #define FPGA_DATA pico_fpga 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /include/ice_cram.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @defgroup ice_cram 27 | * @brief FPGA CRAM access 28 | * @{ 29 | */ 30 | 31 | #pragma once 32 | #include 33 | #include 34 | #include 35 | 36 | #include "ice_fpga_data.h" 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | /** 43 | * @brief Reset the iCE40 and set it to CRAM configuration mode and prepare the 44 | * incoming SPI transfer. 45 | */ 46 | bool ice_cram_open(const ice_fpga fpga); 47 | 48 | /** 49 | * @brief Send the bitstream to the iCE40 CRAM, which configures the FPGA 50 | * circuitry. 51 | * 52 | * @param buf pointer to bitstream data to flush to the iCE40 53 | * @param len size of that buffer 54 | * @returns 0, or negative error 55 | */ 56 | int ice_cram_write(const uint8_t *buf, size_t len); 57 | 58 | /** 59 | * @brief Terminate the SPI transaction and prepare the FPGA to start, 60 | * waiting until it finishes booting. 61 | * 62 | * @return true if the FPGA configuration succeeded or `false` if it timed out. 63 | */ 64 | bool ice_cram_close(void); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | /** @} */ 71 | -------------------------------------------------------------------------------- /include/ice_fpga.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @defgroup ice_fpga 27 | * @brief FPGA I/O and control 28 | * @{ 29 | * 30 | * Depending on the RTL loaded onto the FPGA, it can use its internal RC 31 | * oscillator or a more accurate clock signal provided by the RP2040. This 32 | * library allows to configure this signal, control the FPGA startup, and 33 | * communicate over SPI to the same pins used for SRAM or FLASH access. 34 | * An LED pin is used for communicating with the FPGA. 35 | */ 36 | 37 | #pragma once 38 | #include 39 | #include 40 | 41 | #include "ice_fpga_data.h" 42 | 43 | #ifdef __cplusplus 44 | extern "C" { 45 | #endif 46 | 47 | /** 48 | * @brief Let the FPGA start and export a clock for it over `ICE_FPGA_CLOCK_PIN`. 49 | * @param freq_mhz Exported clock frequency in MHz. Valid values: 48MHz, 24MHz, 50 | * 16MHz 12MHz, 8MHz, 6MHz, 4MHz, 3MHz, 2MHz, 1MHz. 51 | * 52 | * The RP2040 exports its own crystal-based clock to the iCE40, through the 53 | * dedicated [`CLOCK GPOUT0`](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf) 54 | * feature. 55 | * @return 0 on success, negative on fail 56 | */ 57 | int ice_fpga_init(const ice_fpga fpga, uint8_t freq_mhz); 58 | 59 | /** 60 | * @brief Release the stop mode if it was present, and wait that the FPGA 61 | * confirms its startup with ICE_FPGA_CDONE_PIN. 62 | * @return 0 on success, negative on fail 63 | */ 64 | int ice_fpga_start(const ice_fpga fpga); 65 | 66 | /** 67 | * @brief Set the ICE_FPGA_CRESET_B_PIN to LOW which keeps the FPGA in reset 68 | * mode. 69 | * @return 0 on success, negative on fail 70 | */ 71 | int ice_fpga_stop(const ice_fpga fpga); 72 | 73 | /** 74 | * @brief Set the ICE_FPGA_CRESET_B_PIN to LOW which keeps the FPGA in reset 75 | * mode. 76 | * @return 0 on success, negative on fail 77 | */ 78 | int ice_fpga_stop(const ice_fpga fpga); 79 | 80 | /** 81 | * @brief deinit and free FPGA and associated resources 82 | * @return 0 on success, negative on fail 83 | */ 84 | int ice_fpga_deinit(const ice_fpga fpga); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | /** @} */ 91 | -------------------------------------------------------------------------------- /include/ice_fpga_data.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2025 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | #include 27 | 28 | #include "hardware/spi.h" 29 | 30 | typedef struct { 31 | spi_inst_t *peripheral; 32 | uint8_t MISO; 33 | uint8_t MOSI; 34 | uint8_t SCK; 35 | uint8_t CS_flash; 36 | uint8_t CS_cram; 37 | uint8_t CS_psram; 38 | } ice_spibus; 39 | 40 | typedef struct { 41 | ice_spibus bus; 42 | uint8_t pin_cdone; 43 | uint8_t pin_clock; 44 | uint8_t pin_creset; 45 | } ice_fpga; 46 | 47 | extern const ice_fpga pico_fpga; 48 | extern const ice_fpga pico2_fpga; 49 | -------------------------------------------------------------------------------- /include/ice_led.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | /** 26 | * @defgroup ice_led 27 | * @brief RGB LEDs 28 | * @{ 29 | * 30 | * They are active-low and shared with the iCE40: 31 | * - A LED will be bright if either the iCE40 or RP2040 are pulling its line low. 32 | * - A LED will be dark if none of the iCE40 or RP2040 are pulling its line low. 33 | * 34 | * A line pulled high does not give consitent result, they are controlled with 35 | * high-impedance or pulled-down. 36 | * 37 | * ## Troubleshooting 38 | * 39 | * If the GPIO LEDs do not turn on. 40 | * 41 | * Unlike the Raspberry Pi Pico board, which has a green LED attached to the GPIO pin 25, 42 | * the pico-ice has three LEDs attached to the RP2040 GPIO13 (red), GPIO12 (green), GPIO15 (blue). 43 | * 44 | * Moreover, the leds are "active-low", so you would need to turn their pin down for them to 45 | * be turned on. 46 | * 47 | * Finally, the FPGA is also connected to these LEDs. 48 | */ 49 | 50 | #pragma once 51 | #include 52 | 53 | #ifdef __cplusplus 54 | extern "C" { 55 | #endif 56 | 57 | /** 58 | * @brief Initialise the GPIO pins for use with open-drain LED control, shared 59 | * with the iCE40. 60 | */ 61 | void ice_led_init(void); 62 | 63 | /** 64 | * @brief Control the red LED. 65 | * @param state Bright if true, dark if false. 66 | */ 67 | void ice_led_red(bool state); 68 | 69 | /** 70 | * @brief Control the green LED. 71 | * @param state Bright if true, dark if false. 72 | */ 73 | void ice_led_green(bool state); 74 | 75 | /** 76 | * @brief Control the blue LED. 77 | * @param state Bright if true, dark if false. 78 | */ 79 | void ice_led_blue(bool state); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | /** @} */ 86 | -------------------------------------------------------------------------------- /src/ice_cram.pio: -------------------------------------------------------------------------------- 1 | ; SPI controller capable of transmitting up to one bit per 4 system clocks, ignoring response. 2 | .program ice_cram 3 | .side_set 1 opt 4 | ; SDO SCLK 5 | nop side 1 ; receiver samples on rising SCLK edge 6 | out x, 1 7 | mov pins, x [1] side 0 ; shift out on falling SCLK edge 8 | -------------------------------------------------------------------------------- /src/ice_fpga.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2025 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // pico-sdk 26 | #include "hardware/clocks.h" 27 | #include "pico/stdlib.h" 28 | 29 | // pico-ice-sdk 30 | #include "ice_HAL.h" 31 | #include "ice_fpga.h" 32 | 33 | int ice_fpga_init(const ice_fpga fpga, uint8_t freq_mhz) 34 | { 35 | uint src = CLOCKS_CLK_GPOUT0_CTRL_AUXSRC_VALUE_CLK_USB; 36 | 37 | clock_gpio_init(fpga.pin_clock, src, 48 / freq_mhz); 38 | ice_hal_gpio_init(fpga.pin_creset); 39 | 40 | return 0; 41 | } 42 | 43 | int ice_fpga_stop(const ice_fpga fpga) 44 | { 45 | ice_hal_gpio_init(fpga.pin_creset); 46 | ice_hal_gpio_set_0(fpga.pin_creset); 47 | 48 | return 0; 49 | } 50 | 51 | // Datasheet iCE40 Programming Configuration - 3.1. Mode Selection 52 | int ice_fpga_start(const ice_fpga fpga) 53 | { 54 | // To take the FPGA out of reset 55 | ice_hal_gpio_init(fpga.pin_creset); 56 | ice_hal_gpio_set_1(fpga.pin_creset); 57 | 58 | return 0; 59 | } 60 | 61 | int ice_fpga_configured(const ice_fpga fpga) 62 | { 63 | // For sensing configuration status. 64 | ice_hal_gpio_init(fpga.pin_cdone); 65 | 66 | /* Wait that the configuration is finished before interferring. 67 | * This makes sure the SPI bus is not driven by both the FPGA 68 | * (reading from flash) and the RP2040 (configuring the flash). 69 | * Note that if the flash is corrupted, this function will timeout! 70 | */ 71 | for (uint8_t timeout = 100; !ice_hal_gpio_get(fpga.pin_cdone); timeout--) { 72 | if (timeout == 0) { 73 | // if the FPGA could not start, it would keep the clock active, 74 | // which disturpts the rest of the signals, including SWD 75 | ice_fpga_stop(fpga); 76 | return -ENODEV; 77 | } 78 | sleep_ms(1); 79 | } 80 | return 0; 81 | } 82 | 83 | int ice_fpga_deinit(const ice_fpga fpga) 84 | { 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /src/ice_fpga_data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2025 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "ice_fpga_data.h" 26 | 27 | const ice_spibus pico2_spibus = { 28 | .peripheral = spi0, 29 | .MISO = 4, //ICE_SI 30 | .MOSI = 7, //ICE_SO 31 | .SCK = 6, //ICE_SCK 32 | .CS_flash = 5, //ICE_SSN 33 | .CS_cram = 5, 34 | .CS_psram = -1, // No FPGA SRAM on pico2-ice 35 | }; 36 | 37 | const ice_fpga pico2_fpga = { 38 | .bus = pico2_spibus, 39 | .pin_cdone = 40, //ICE_DONE_ADC0 40 | .pin_clock = 21, //ICE_CLK 41 | .pin_creset = 31, //ICE_RST 42 | }; 43 | 44 | const ice_spibus pico_spibus = { 45 | .peripheral = spi1, 46 | .MISO = 8, 47 | .MOSI = 11, 48 | .SCK = 10, 49 | .CS_flash = 9, 50 | .CS_cram = 9, 51 | .CS_psram = 14, 52 | }; 53 | 54 | const ice_fpga pico_fpga = { 55 | .bus = pico_spibus, 56 | .pin_cdone = 26, 57 | .pin_clock = 24, 58 | .pin_creset = 27, 59 | }; 60 | -------------------------------------------------------------------------------- /src/ice_led.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // pico-ice-sdk 26 | #include "boards.h" 27 | #include "ice_HAL.h" 28 | #include "ice_led.h" 29 | 30 | // Rather than driving LEDs up and down, we always drive the wire down, 31 | // but connect or disconnect the pin (high-impedance vs pull-down). 32 | void ice_led_init(void) 33 | { 34 | ice_hal_gpio_init(ICE_LED_RED_PIN); 35 | ice_hal_gpio_init(ICE_LED_GREEN_PIN); 36 | ice_hal_gpio_init(ICE_LED_BLUE_PIN); 37 | 38 | ice_hal_gpio_set_0(ICE_LED_RED_PIN); 39 | ice_hal_gpio_set_0(ICE_LED_GREEN_PIN); 40 | ice_hal_gpio_set_0(ICE_LED_BLUE_PIN); 41 | 42 | ice_hal_gpio_set_high_z(ICE_LED_RED_PIN); 43 | ice_hal_gpio_set_high_z(ICE_LED_GREEN_PIN); 44 | ice_hal_gpio_set_high_z(ICE_LED_BLUE_PIN); 45 | } 46 | 47 | void ice_led_red(bool state) 48 | { 49 | if (state) { 50 | ice_hal_gpio_set_0(ICE_LED_RED_PIN); 51 | } else { 52 | ice_hal_gpio_set_high_z(ICE_LED_RED_PIN); 53 | } 54 | } 55 | 56 | void ice_led_green(bool state) 57 | { 58 | if (state) { 59 | ice_hal_gpio_set_0(ICE_LED_RED_PIN); 60 | } else { 61 | ice_hal_gpio_set_high_z(ICE_LED_RED_PIN); 62 | } 63 | } 64 | 65 | void ice_led_blue(bool state) 66 | { 67 | if (state) { 68 | ice_hal_gpio_set_0(ICE_LED_RED_PIN); 69 | } else { 70 | ice_hal_gpio_set_high_z(ICE_LED_RED_PIN); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/tinyuf2_board.c: -------------------------------------------------------------------------------- 1 | // stdlib 2 | #include 3 | #include 4 | 5 | // pico-sdk 6 | #include "pico/time.h" 7 | #include "hardware/watchdog.h" 8 | #include "hardware/timer.h" 9 | 10 | // tinyuf2 11 | #include "board_api.h" 12 | 13 | // pico-ice-sdk 14 | #include "boards.h" 15 | #include "ice_fpga_data.h" 16 | #include "ice_flash.h" 17 | #include "ice_fpga.h" 18 | 19 | static alarm_id_t alarm_id; 20 | static bool spi_ready; 21 | static uint32_t flash_erased[ICE_FLASH_SIZE_BYTES / (ICE_FLASH_BLOCK_SIZE * 32)]; 22 | 23 | void board_flash_read(uint32_t addr, void *buffer, uint32_t len) 24 | { 25 | ice_flash_read(FPGA_DATA.bus, addr, buffer, len); 26 | } 27 | 28 | bool board_flash_write(uint32_t addr, const void *data, uint32_t len) 29 | { 30 | if (!spi_ready) { 31 | ice_fpga_stop(FPGA_DATA); 32 | ice_flash_init(FPGA_DATA.bus, ICE_FLASH_BAUDRATE); 33 | spi_ready = true; 34 | } 35 | 36 | int flash_erase_idx = addr / ICE_FLASH_BLOCK_SIZE; 37 | if ((flash_erased[flash_erase_idx >> 5] & (1u << (flash_erase_idx & 0x1F))) == 0) { 38 | ice_flash_erase_block(FPGA_DATA.bus, addr & ~(ICE_FLASH_BLOCK_SIZE - 1)); 39 | flash_erased[flash_erase_idx >> 5] |= 1u << (flash_erase_idx & 0x1F); 40 | } 41 | if (len != ICE_FLASH_PAGE_SIZE) { 42 | printf("%s: expected len=%u got len=%ld\r\n", __func__, ICE_FLASH_PAGE_SIZE, len); 43 | return false; 44 | } else { 45 | ice_flash_program_page(FPGA_DATA.bus, addr, data); 46 | } 47 | 48 | return true; 49 | } 50 | 51 | void board_flash_flush(void) 52 | { 53 | } 54 | 55 | uint32_t board_flash_size(void) 56 | { 57 | return ICE_FLASH_SIZE_BYTES; 58 | } 59 | 60 | void board_rgb_write(const uint8_t rgb[]) 61 | { 62 | (void)rgb; 63 | } 64 | 65 | int64_t board_timer_handler_cb(alarm_id_t id, void *data) 66 | { 67 | board_timer_handler(); 68 | return 0; 69 | } 70 | 71 | void board_timer_start(uint32_t ms) 72 | { 73 | alarm_id = add_alarm_in_ms(ms, board_timer_handler_cb, NULL, true); 74 | } 75 | 76 | void board_timer_stop(void) 77 | { 78 | cancel_alarm(alarm_id); 79 | } 80 | 81 | void board_dfu_complete(void) 82 | { 83 | watchdog_reboot(0, 0, 1000); 84 | } 85 | -------------------------------------------------------------------------------- /src/tinyuf2_include.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 tinyVision.ai 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | // pico-ice-sdk 26 | #include "ice_usb.h" 27 | 28 | #if ICE_USB_USE_TINYUF2_MSC 29 | 30 | // TinyUF2 source guarded by an #ifdef 31 | #include "../lib/tinyuf2/src/ghostfat.c" 32 | #include "../lib/tinyuf2/src/msc.c" 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /tools/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /tools/70-pico-ice.rules: -------------------------------------------------------------------------------- 1 | SUBSYSTEM=="usb", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="b1c0", MODE="0666" 2 | ACTION=="add|change", ATTRS{idVendor}=="1209", ATTRS{idProduct}=="b1c0", TAG+="uaccess" 3 | --------------------------------------------------------------------------------