Skip to content

Commit

Permalink
Merge pull request #34 from cyber-murmel/rp2040
Browse files Browse the repository at this point in the history
Add support for Raspberry Pi Pico RP2040 board
  • Loading branch information
mossmann authored Jun 19, 2024
2 parents b0ee905 + 52658c4 commit ca445d3
Show file tree
Hide file tree
Showing 23 changed files with 1,204 additions and 11 deletions.
1 change: 1 addition & 0 deletions .github/workflows/firmware.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
- 'qtpy'
- 'cynthion r0.2'
- 'cynthion r0.4'
- 'raspberry_pi_pico'
include:
- target-board: 'cynthion r0.2'
board-major: 0
Expand Down
64 changes: 64 additions & 0 deletions firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
cmake_minimum_required(VERSION 3.17)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# set(CMAKE_C_COMPILER_WORKS 1)

#set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/../lib/tinyusb/hw/bsp/family_support.cmake)

# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})

project(${PROJECT} C CXX ASM)

# Checks this example is valid for the family and initializes the project
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})

# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()

add_executable(${PROJECT})

# Example source
target_sources(${PROJECT} PUBLIC
# ${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/dfu.c
# ${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/usb_descriptors.c
${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/fpga.c
${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/jtag.c
${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/led.c
${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/spi.c
${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}/uart.c
${CMAKE_CURRENT_SOURCE_DIR}/src/mcu/rp2040/dfu.c
${CMAKE_CURRENT_SOURCE_DIR}/src/mcu/rp2040/usb_descriptors.c
${CMAKE_CURRENT_SOURCE_DIR}/src/button.c
${CMAKE_CURRENT_SOURCE_DIR}/src/console.c
${CMAKE_CURRENT_SOURCE_DIR}/src/debug_spi.c
${CMAKE_CURRENT_SOURCE_DIR}/src/fpga_adv.c
${CMAKE_CURRENT_SOURCE_DIR}/src/fpga.c
${CMAKE_CURRENT_SOURCE_DIR}/src/jtag_tap.c
${CMAKE_CURRENT_SOURCE_DIR}/src/jtag.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_switch.c
${CMAKE_CURRENT_SOURCE_DIR}/src/vendor.c
)

# Example include
target_include_directories(${PROJECT} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/boards/${BOARD}
)

target_compile_definitions(${PROJECT} PUBLIC
# CFG_TUSB_OS=OPT_OS_PICO
_BOARD_REVISION_MAJOR_=${BOARD_REVISION_MAJOR}
_BOARD_REVISION_MINOR_=${BOARD_REVISION_MINOR}
VERSION_STRING="${VERSION_STRING}"
)

# Configure compilation flags and libraries for the example... see the corresponding function
# in hw/bsp/FAMILY/family.cmake for details.
# family_configure_device_example(${PROJECT} noos)
family_configure_target(${PROJECT} noos)
target_link_libraries(${PROJECT} PUBLIC pico_stdlib tinyusb_device pico_unique_id pico_fix_rp2040_usb_device_enumeration hardware_spi)

2 changes: 1 addition & 1 deletion firmware/src/boards/cynthion_d11/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void uart_release_pinmux(void)
* Configures the UART we'll use for our system console.
* TODO: support more configuration (parity, stop, etc.)
*/
void uart_init(bool configure_pinmux, unsigned long baudrate)
void uart_initialize(bool configure_pinmux, unsigned long baudrate)
{
// Disable the SERCOM before configuring it, to 1) ensure we're not transacting
// during configuration; and 2) as many of the registers are R/O when the SERCOM is enabled.
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/boards/cynthion_d21/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void uart_release_pinmux(void)
* Configures the UART we'll use for our system console.
* TODO: support more configuration (parity, stop, etc.)
*/
void uart_init(bool configure_pinmux, unsigned long baudrate)
void uart_initialize(bool configure_pinmux, unsigned long baudrate)
{
// Disable the SERCOM before configuring it, to 1) ensure we're not transacting
// during configuration; and 2) as many of the registers are R/O when the SERCOM is enabled.
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/boards/daisho/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* @param configure_pinmux If true, the pinmux will be configured for UART use during init.
* @param baudrate The baud rate to apply, in symbols/second.
*/
void uart_init(bool configure_pinmux, unsigned long baudrate)
void uart_initialize(bool configure_pinmux, unsigned long baudrate)
{
}

Expand Down
2 changes: 1 addition & 1 deletion firmware/src/boards/qtpy/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void uart_release_pinmux(void)
* Configures the UART we'll use for our system console.
* TODO: support more configuration (parity, stop, etc.)
*/
void uart_init(bool configure_pinmux, unsigned long baudrate)
void uart_initialize(bool configure_pinmux, unsigned long baudrate)
{
// Disable the SERCOM before configuring it, to 1) ensure we're not transacting
// during configuration; and 2) as many of the registers are R/O when the SERCOM is enabled.
Expand Down
110 changes: 110 additions & 0 deletions firmware/src/boards/raspberry_pi_pico/apollo_board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* Apollo board definitions for Raspberry Pi Pico
*
* Copyright (c) 2020-2024 Great Scott Gadgets <[email protected]>
* Copyright (c) 2024 Markus Blechschmidt <[email protected]>
* SPDX-License-Identifier: BSD-3-Clause
*/

#ifndef __APOLLO_BOARD_H__
#define __APOLLO_BOARD_H__

#include <stdbool.h>

#include "boards/pico.h"
#include "bsp/rp2040/board.h"
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/sync.h"


#define __NOP() {asm volatile("nop");}


typedef unsigned int gpio_t;


typedef enum gpio_direction{
GPIO_DIRECTION_IN = GPIO_IN,
GPIO_DIRECTION_OUT = GPIO_OUT,
} gpio_direction_t;


typedef enum gpio_pull_mode {
GPIO_PULL_OFF,
GPIO_PULL_UP,
GPIO_PULL_DOWN,
} gpio_pull_mode_t;


/**
* GPIO pins for each of the microcontroller LEDs.
*/
typedef enum {
LED_A = LED_PIN, // Green

LED_COUNT = 1,
} led_t;

/**
* GPIO pin numbers.
*/



enum {
// // Each of the JTAG pins. SPI0
TMS_GPIO = 5,
TDI_GPIO = 3, // MOSI
TDO_GPIO = 4, // MISO
TCK_GPIO = 6, // SCK

// // Connected to orangecrab pins 0 and 1. SERCOM0
UART_RX = UART_RX_PIN,
UART_TX = UART_TX_PIN,

// Connected to orangecrab RSTFPGA_RESET, ecp5 PROGRAMN
PIN_PROG = 7,
};


static inline void gpio_set_pin_level(const gpio_t gpio_pin, bool level) {
gpio_put(gpio_pin, level);
}


static inline bool gpio_get_pin_level(const gpio_t gpio_pin) {
return gpio_get(gpio_pin);
}


static inline void gpio_toggle_pin_level(const gpio_t gpio_pin) {
gpio_set_pin_level(gpio_pin, !gpio_get_pin_level(gpio_pin));
}


static inline void gpio_set_pin_direction(const gpio_t gpio_pin, const enum gpio_direction direction) {
gpio_init(gpio_pin);
gpio_set_dir(gpio_pin, direction);
}


static inline void gpio_set_pin_pull_mode(const gpio_t gpio_pin, const gpio_pull_mode_t pull_mode) {
switch(pull_mode) {
case GPIO_PULL_OFF: {
gpio_disable_pulls(gpio_pin);
} break;
case GPIO_PULL_UP: {
gpio_pull_up(gpio_pin);
} break;
case GPIO_PULL_DOWN: {
gpio_pull_down(gpio_pin);
} break;
default: {

} break;
}
}


#endif
17 changes: 17 additions & 0 deletions firmware/src/boards/raspberry_pi_pico/board.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

# This is an external board, so its identity is determined by its revision number.
# MAJOR = external board
# MINOR = generic Apollo board
BOARD_REVISION_MAJOR := 255
BOARD_REVISION_MINOR := 3

CMAKE_DEFSYM += \
-DBOARD_REVISION_MAJOR=$(BOARD_REVISION_MAJOR) \
-DBOARD_REVISION_MINOR=$(BOARD_REVISION_MINOR) \
-DVERSION_STRING="$(VERSION_STRING)"

ifeq "$(PICO_SDK_PATH)" ""
CMAKE_DEFSYM += -DPICO_SDK_FETCH_FROM_GIT=1
else
CMAKE_DEFSYM += -DPICO_SDK_PATH=$(PICO_SDK_PATH)
endif
60 changes: 60 additions & 0 deletions firmware/src/boards/raspberry_pi_pico/fpga.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Code for basic FPGA interfacing.
*
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]>
* Copyright (c) 2024 Markus Blechschmidt <[email protected]>
* SPDX-License-Identifier: BSD-3-Clause
*/

#include <bsp/board_api.h>
#include <apollo_board.h>

#include "apollo_board.h"
#include "jtag.h"
#include "fpga.h"


/*
* Allows or disallows the FPGA from configuring. When disallowed,
* initialization (erasing of configuration memory) takes place, but the FPGA
* does not proceed to the configuration phase.
*/
void permit_fpga_configuration(bool enable)
{
}

/**
* Sets up the I/O pins needed to configure the FPGA.
*/
void fpga_io_init(void)
{
}


/**
* Requests that the FPGA clear its configuration and try to reconfigure.
*/
void trigger_fpga_reconfiguration(void)
{
/*
* If the JTAG TAP was left in certain states, pulsing PROGRAMN has no
* effect, so we reset the state first.
*/
jtag_init();
jtag_go_to_state(STATE_TEST_LOGIC_RESET);
jtag_wait_time(2);
jtag_deinit();
/*
* Now pulse PROGRAMN to instruct the FPGA to configure itself.
*/
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_OUT);
gpio_set_pin_level(PIN_PROG, false);

board_delay(1);

gpio_set_pin_level(PIN_PROG, true);
gpio_set_pin_direction(PIN_PROG, GPIO_DIRECTION_IN);

// Update internal state.
fpga_set_online(true);
}
33 changes: 33 additions & 0 deletions firmware/src/boards/raspberry_pi_pico/jtag.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2020-2023 Great Scott Gadgets <[email protected]>
* Copyright (c) 2024 Markus Blechschmidt <[email protected]>
* SPDX-License-Identifier: BSD-3-Clause
*/


#include <tusb.h>
#include <apollo_board.h>
#include "spi.h"

#include <jtag.h>

extern uint8_t jtag_in_buffer[256];
extern uint8_t jtag_out_buffer[256];


/**
* Hook that performs hardware-specific initialization.
*/
void jtag_platform_init(void)
{
// Set up our SPI port for SPI-accelerated JTAG.
spi_initialize(SPI_FPGA_JTAG, true, false, 1, 1, 1);
}


/**
* Hook that performs hardware-specific deinitialization.
*/
void jtag_platform_deinit(void)
{
}
Loading

0 comments on commit ca445d3

Please sign in to comment.