Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

initial pico default firmware #9

Merged
merged 1 commit into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions Firmware/pico2-ice-default/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
cmake_minimum_required(VERSION 3.13)

# import the pico-sdk
set(PICO_SDK_PATH ${CMAKE_CURRENT_SOURCE_DIR}/pico-sdk/)
include(pico_sdk_import.cmake)

# Configure the build based on the selected pico ice board
# Pass board in make "cmake -DPICO_ICE_BOARD=pico-ice ..." or "cmake -DPICO_ICE_BOARD=pico-ice ..."
if(PICO_ICE_BOARD STREQUAL "pico-ice")
project(pico_ice_default C CXX ASM)
elseif(PICO_ICE_BOARD STREQUAL "pico2-ice")
project(pico2_ice_default C CXX ASM)
else()
message(STATUS "Pico ice not passed in cmake.")
endif()

# configure the pico-sdk project
#project(pico2_ice_default C CXX ASM)
pico_sdk_init()

# add the pico-ice-sdk
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pico-ice-sdk/)
add_compile_definitions(VERSION=\"${PICO_ICE_SDK_VERSION}\")

# add the local files
add_executable(${CMAKE_PROJECT_NAME}
main.c
usb_descriptors.c
)


# Configure the build based on the selected pico ice board
# Pass board in make "cmake -DPICO_ICE_BOARD=pico-ice ..." or "cmake -DPICO_ICE_BOARD=pico-ice ..."
if(PICO_ICE_BOARD STREQUAL "pico-ice")
target_compile_definitions(${PROJECT_NAME} PRIVATE PICO_ICE_BOARD_ID=1)
message(STATUS "Configuring for pico-ice (rp2040)")
elseif(PICO_ICE_BOARD STREQUAL "pico2-ice")
target_compile_definitions(${PROJECT_NAME} PRIVATE PICO_ICE_BOARD_ID=2)
message(STATUS "Configuring for pico2-ice (rp2350)")
else()
message(STATUS "Pico ice not passed in cmake.")
# target_compile_definitions(${PROJECT_NAME} PRIVATE PICO_ICE_BOARD_ID=2)
# message(STATUS "Pico ice not passed in cmake. It will use default pico-ice (rp2040)")
endif()

target_link_libraries(${CMAKE_PROJECT_NAME}
pico_ice_sdk
pico_ice_usb
pico_stdio_usb
)
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
pico_add_extra_outputs(${CMAKE_PROJECT_NAME})
pico_enable_stdio_usb(${CMAKE_PROJECT_NAME} 1)
pico_enable_stdio_uart(${CMAKE_PROJECT_NAME} 0)
22 changes: 22 additions & 0 deletions Firmware/pico2-ice-default/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Default Firmware

Downloads: [releases](https://github.com/tinyvision-ai-inc/pico-ice/releases/)

- A first USB-UART (#0) is used for the and a REPL command line interface
for now only showing help message and version information.

- A second USB-UART (#1) is used for mirroring everything between
this USB interface UART TX on RP20 with ICE27, UART RX on RP30 with ICE25.

- A third USB-UART (#2) is exchanging data with the main SPI bus onboard
([doc](https://pico2-ice.tinyvision.ai/ice_usb.html#usb-spi-fpgasramflash-forwarding)).

- A 12 MHz clock is exported from the RP2350 pin 24 toward the iCE40 pin 35.

- An USB DFU interface allows programming through [dfu-utils](https://dfu-util.sourceforge.net/)
as shipped with [oss-cad-suite](https://github.com/YosysHQ/oss-cad-suite-build).

- An USB MSC interface allows programming the board by copying a file to an USB device
([doc](https://pico-ice.tinyvision.ai/programming_the_fpga.html#using-a-drag-drop-or-file-copy-scheme)).

See the [documentation](https://pico-ice.tinyvision.ai/) for how to use them.
182 changes: 182 additions & 0 deletions Firmware/pico2-ice-default/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* MIT License
*
* Copyright (c) 2023 tinyVision.ai
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

// pico-sdk
#include <stdio.h>
#include "pico/stdio.h"
#include "hardware/irq.h"
#include "hardware/gpio.h"
#include "hardware/uart.h"

// pico-ice-sdk
#include "boards.h"
#include "ice_usb.h"
#include "ice_fpga.h"
#include "ice_led.h"

#if PICO_ICE_BOARD_ID == PICO_ICE
#define UART_TX_PIN 0 //ICE_27
#define UART_RX_PIN 1 //ICE_25
#elif PICO_ICE_BOARD_ID == PICO2_ICE
#define UART_TX_PIN 20 //ICE_27
#define UART_RX_PIN 30 //ICE_25
#else
#error "pico-ice board model not found"
#endif

#define DOC_FORWARD_SPI \
"https://pico-ice.tinyvision.ai/group__ice__usb.html#autotoc_md2"

#define DOC_DEFAULT_FIRMWARE \
"https://github.com/tinyvision-ai-inc/pico-ice/tree/main/Firmware/pico-ice-default"

// for repl_ungetchar() to take back the last character from repl_getchar():
int repl_last_char;
bool repl_last_held;

static int repl_getchar(void)
{
int c;

if (repl_last_held) {
repl_last_held = false;
return repl_last_char;
}

c = getchar_timeout_us(0);
if (c == PICO_ERROR_TIMEOUT)
return c;

if (c == '\r' || c == '\n') {
printf("\r\n");
} else {
putchar(c);
}
return c;
}

static void repl_ungetchar(int c)
{
assert(!repl_last_held);
repl_last_char = c;
repl_last_held = true;
}

static inline bool repl_parse_error(char *msg, char c)
{
// reset whatever was being input
repl_last_held = false;

printf("\nerror: expected %s got '%c'\n", msg, c);
return false;
}

static bool repl_parse_newline(void)
{
int c;

switch (c = repl_getchar()) {
case '\r':
case '\n':
case EOF:
return true;
default:
repl_ungetchar(c);
return repl_parse_error("newline", c);
}
}

static void repl_command_version(void)
{
if (!repl_parse_newline()) {
return;
}
printf("pico-ice-sdk %s\r\n", VERSION);
}

static void repl_prompt(void)
{
printf("\x1b[1m%s>\x1b[m ", PICO_ICE_BOARD_NAME);
}

int main(void)
{
// Configure USB as defined in tusb_config.h
ice_usb_init();

// Enable USB-CDC #0 (serial console)
stdio_init_all();

// Enable the physical UART
uart_init(uart0, 115200);
gpio_set_function(UART_TX_PIN, GPIO_FUNC_UART);
gpio_set_function(UART_RX_PIN, GPIO_FUNC_UART);

// Let the FPGA start
ice_fpga_init(12);
ice_fpga_start();

// Prevent the LEDs from glowing slightly
ice_led_init();

// Print repl prompt
repl_prompt();

while (true) {
tud_task();

int chr = repl_getchar();
if (chr == PICO_ERROR_TIMEOUT)
continue;

// not timeout, something received

switch (chr) {
case 'v':
repl_command_version();
break;
default:
printf("\r\n");
printf("pico-ice default firmware\r\n", VERSION);
printf(" %s\r\n", DOC_DEFAULT_FIRMWARE);
printf("\r\n");
printf("Serial port #0 - this shell, with commands:\r\n");
printf(" v - print pico-ice-sdk version\r\n");
printf("\r\n");
printf("Serial port #1 - forwarding to UART\r\n");
printf(" UART TX on RP%d = ICE27\r\n", UART_TX_PIN );
printf(" UART RX on RP%d = ICE25\r\n", UART_RX_PIN );
printf("\r\n");
printf("Serial port #2 - forwarding to SPI:\r\n");
printf(" %s\r\n", DOC_FORWARD_SPI);
printf("\r\n");
break;
}

// reprint prompt
repl_prompt();
}

return 0;
}
1 change: 1 addition & 0 deletions Firmware/pico2-ice-default/pico-ice-sdk
1 change: 1 addition & 0 deletions Firmware/pico2-ice-default/pico-sdk
Binary file added Firmware/pico2-ice-default/pico2_ice_default.uf2
Binary file not shown.
73 changes: 73 additions & 0 deletions Firmware/pico2-ice-default/pico_sdk_import.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake

# This can be dropped into an external project to help locate this SDK
# It should be include()ed prior to project()

if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
endif ()

if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
endif ()

set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
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")
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")

if (NOT PICO_SDK_PATH)
if (PICO_SDK_FETCH_FROM_GIT)
include(FetchContent)
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
if (PICO_SDK_FETCH_FROM_GIT_PATH)
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
endif ()
# GIT_SUBMODULES_RECURSE was added in 3.17
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
GIT_SUBMODULES_RECURSE FALSE
)
else ()
FetchContent_Declare(
pico_sdk
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
GIT_TAG master
)
endif ()

if (NOT pico_sdk)
message("Downloading Raspberry Pi Pico SDK")
FetchContent_Populate(pico_sdk)
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
endif ()
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
else ()
message(FATAL_ERROR
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
)
endif ()
endif ()

get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
if (NOT EXISTS ${PICO_SDK_PATH})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
endif ()

set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
endif ()

set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)

include(${PICO_SDK_INIT_CMAKE_FILE})
Loading