diff --git a/examples/device/board_test/CMakeLists.txt b/examples/device/board_test/CMakeLists.txt index ee0d7ef5..62759c49 100644 --- a/examples/device/board_test/CMakeLists.txt +++ b/examples/device/board_test/CMakeLists.txt @@ -4,13 +4,40 @@ cmake_minimum_required(VERSION 3.5) set(TOP "../../..") get_filename_component(TOP "${TOP}" REALPATH) +set(PROJECT board_test) + # Check for -DFAMILY= if(NOT DEFINED FAMILY) message(FATAL_ERROR "Invalid FAMILY specified") endif() include(${TOP}/hw/bsp/${FAMILY}/family.cmake) +project(${PROJECT}) -project(board_test) +if(FAMILY STREQUAL "rp2040") -include(${TOP}/hw/bsp/${FAMILY}/family_extra.cmake OPTIONAL) +pico_sdk_init() + +add_executable(${PROJECT}) + +target_sources(${PROJECT} PRIVATE + src/main.c + "${TOP}/hw/bsp/rp2040/boards/raspberry_pi_pico/board_raspberry_pi_pico.c" +) + +target_include_directories(${PROJECT} PRIVATE + "src/" + "${TOP}/hw" + "${TOP}/src" +) + +target_compile_definitions(${PROJECT} PUBLIC + CFG_TUSB_MCU=OPT_MCU_RP2040 + CFG_TUSB_OS=OPT_OS_PICO +) + +target_link_libraries(${PROJECT} pico_stdlib) + +pico_add_extra_outputs(${PROJECT}) + +endif() diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico/board_raspberry_pi_pico.c b/hw/bsp/rp2040/boards/raspberry_pi_pico/board_raspberry_pi_pico.c index efdb5473..606d9a04 100644 --- a/hw/bsp/rp2040/boards/raspberry_pi_pico/board_raspberry_pi_pico.c +++ b/hw/bsp/rp2040/boards/raspberry_pi_pico/board_raspberry_pi_pico.c @@ -25,21 +25,73 @@ */ #include "pico/stdlib.h" -#include "../board.h" +#include "hardware/gpio.h" +#include "hardware/sync.h" +#include "hardware/structs/ioqspi.h" +#include "hardware/structs/sio.h" -#ifndef LED_PIN -#define LED_PIN PICO_DEFAULT_LED_PIN -#endif +#include "bsp/board.h" + +#define LED_PIN PICO_DEFAULT_LED_PIN +#define LED_STATE_ON 1 + +// Button pin is BOOTSEL which is flash CS pin +// #define BUTTON_PIN +#define BUTTON_STATE_ACTIVE 0 + +// This example blinks the Picoboard LED when the BOOTSEL button is pressed. +// +// Picoboard has a button attached to the flash CS pin, which the bootrom +// checks, and jumps straight to the USB bootcode if the button is pressed +// (pulling flash CS low). We can check this pin in by jumping to some code in +// SRAM (so that the XIP interface is not required), floating the flash CS +// pin, and observing whether it is pulled low. +// +// This doesn't work if others are trying to access flash at the same time, +// e.g. XIP streamer, or the other core. + +bool __no_inline_not_in_flash_func(get_bootsel_button)() { + const uint CS_PIN_INDEX = 1; + + // Must disable interrupts, as interrupt handlers may be in flash, and we + // are about to temporarily disable flash access! + uint32_t flags = save_and_disable_interrupts(); + + // Set chip select to Hi-Z + hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, + GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); + + // Note we can't call into any sleep functions in flash right now + for (volatile int i = 0; i < 1000; ++i); + + // The HI GPIO registers in SIO can observe and control the 6 QSPI pins. + // Note the button pulls the pin *low* when pressed. + bool button_state = (sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX)); + + // Need to restore the state of chip select, else we are going to have a + // bad time when we return to code in flash! + hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, + GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); + + restore_interrupts(flags); + + return button_state; +} void board_init(void) { setup_default_uart(); gpio_init(LED_PIN); - gpio_set_dir(LED_PIN, 1); + gpio_set_dir(LED_PIN, GPIO_OUT); // Button // todo probably set up device mode? +#if TUSB_OPT_DEVICE_ENABLED + +#endif #if TUSB_OPT_HOST_ENABLED // set portfunc to host !!! @@ -66,12 +118,12 @@ void board_init(void) void board_led_write(bool state) { - gpio_put(LED_PIN, state); + gpio_put(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) { - return 0; + return BUTTON_STATE_ACTIVE == get_bootsel_button(); } int board_uart_read(uint8_t* buf, int len) @@ -84,16 +136,8 @@ int board_uart_read(uint8_t* buf, int len) int board_uart_write(void const * buf, int len) { -// UART_Send(BOARD_UART_PORT, &c, 1, BLOCKING); for(int i=0;i