From a159937fa931cb5c6d33555fe225a564be4a0a4e Mon Sep 17 00:00:00 2001 From: rmanach Date: Wed, 19 Feb 2025 11:22:12 +0100 Subject: [PATCH] init repository --- .gitignore | 7 +++ Makefile | 28 ++++++++++ README.md | 83 ++++++++++++++++++++++++++++++ scripts/install_picotool.bash | 75 +++++++++++++++++++++++++++ scripts/install_sdk.bash | 55 ++++++++++++++++++++ scripts/scaffold_project.bash | 82 +++++++++++++++++++++++++++++ simple_led/CMakeLists.txt | 39 ++++++++++++++ simple_led/main.c | 97 +++++++++++++++++++++++++++++++++++ templates/CMakeLists.txt.tpl | 38 ++++++++++++++ templates/main.c.tpl | 12 +++++ 10 files changed, 516 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100755 scripts/install_picotool.bash create mode 100755 scripts/install_sdk.bash create mode 100755 scripts/scaffold_project.bash create mode 100644 simple_led/CMakeLists.txt create mode 100644 simple_led/main.c create mode 100644 templates/CMakeLists.txt.tpl create mode 100644 templates/main.c.tpl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf13ba6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.vscode + +picotool +sdk + +build +toolchain \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e5f192f --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +export INSTALL_PATH := $(PWD) + +SDK_VERSION := 2.1.0 +PICOTOOL := $(INSTALL_PATH)/picotool/$(SDK_VERSION)/build/picotool + +export PICO_SDK_PATH=$(INSTALL_PATH)/sdk/$(SDK_VERSION) + # if using a different platform or arch, set ot here +export PICO_PLATFORM=rp2350 + +# project name, need to be passed as make input (ex: make project name=test) +name := "" + +install: + @./scripts/install_sdk.bash $(SDK_VERSION) + @./scripts/install_picotool.bash $(SDK_VERSION) + +info: + @$(PICOTOOL) info -a + +project: + @./scripts/scaffold_project.bash $(name) $(SDK_VERSION) + +compile: + @(test -d ${name} && mkdir -p ${name}/build && cd ${name}/build && cmake .. && make -j$(nproc) && echo "project compile successfully") || echo "error: unable to compile project: $(name)" + +push: compile + @(test -f $(name)/build/$(name).elf && $(PICOTOOL) load -fx -v $(name)/build/$(name).elf) || echo "error: unable to push project $(name) to device" + diff --git a/README.md b/README.md new file mode 100644 index 0000000..756d06e --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# Picoco + +A repository to store Rasbperry Pico C projects. + +It uses the **Freenove Super Starter Kit For Raspberry Pi Pico**, the tutorial and ressources can be found [here](https://github.com/Freenove/Freenove_Super_Starter_Kit_for_Raspberry_Pi_Pico). + +The official documentation to start with the Raspberry Pi Pico: [Getting started with Raspberry Pi Pico-series](https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf). + +## Installation + +In order to build and deploy the binary in the Raspberry Pi Pico, you have to install the **Pico C SDK** and **Picotool**. + +So, you need to execute the following command that will installed both: +```bash +make install +``` + +**NOTE**: this will install the **SDK** and **Picotool** in the current directory. If you want to set an other intallation path, +set the `INSTALL_PATH` variable. The `INSTALL_PATH` directory must exists, create it before and make sure user have write rights. + +The **SDK** and **Picotool** version used is: **2.1.0**. + + +## Generate a project + +You can generate a new Pico C project with the command: +``` +make project name= +``` + +It will create a new project in the current directory and build it. + +## Compile + +Update you `main.c` file and then launch: +``` +make compile name= +``` + +It will generate the `.elf` file in the `build` directory. + +## Load binary into the device + +You can combine both **compilation** and **load** with the following command: +```bash +make push name= +``` + +**NOTE**: you have to USB plug your Pico device in **BOOTSEL** mode before executing the command. + +After the load, the device will automatically reboot and be unpluged. And the program fresly pushed will start. + +## Get device info +When plugging your device in **BOOTSEL** mode, you can get the device information using: +```bash +make info + +Program Information + name: simple_led + version: 0.1 + binary start: 0x10000000 + binary end: 0x10001744 + target chip: RP2350 + image type: ARM Secure + +Fixed Pin Information + none + +Build Information + sdk version: 2.1.0 + pico_board: pico2 + boot2_name: boot2_w25q080 + build date: Feb 18 2025 + build attributes: Release + +Metadata Block 1 + address: 0x10000138 + next block address: 0x10001730 + block type: image def + target chip: RP2350 + image type: ARM Secure +``` + diff --git a/scripts/install_picotool.bash b/scripts/install_picotool.bash new file mode 100755 index 0000000..ea8218b --- /dev/null +++ b/scripts/install_picotool.bash @@ -0,0 +1,75 @@ +#!/bin/bash + +############################################### +# +# Download and compile `picotool`. +# src: https://github.com/raspberrypi/picotool +# +# The Pico C SDK must be installed before, +# see: `install_sdk.bash`. +# +# ex: ./install_picotool.bash 2.1.0 +# NOTE: the version passed must match the SDK +# version installed +# +############################################### + +PICOTOOL_VERSION=$1 +REGEX_VERSION="^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$" + +if [[ -z ${INSTALL_PATH} ]] +then + INSTALL_PATH=${PWD} +fi + +usage() { + echo "usage:" + echo "./install_picotool.bash (ex: ./install_picotool.bash 2.1.0)" +} + +if [[ ! "${PICOTOOL_VERSION}" =~ ${REGEX_VERSION} ]] +then + echo "error: unable to parse the picotool version: '${PICOTOOL_VERSION}'" + usage + exit 1 +fi + +if [[ ! -d ${INSTALL_PATH}/sdk/${PICOTOOL_VERSION} ]] +then + echo "error: SDK ${PICOTOOL_VERSION} must be installed" + exit 1 +fi + +if [[ ! -d ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION} ]] +then + echo "install dependencies..." + sudo apt install build-essential pkg-config libusb-1.0-0-dev cmake + + echo "installing picotool..." + wget https://github.com/raspberrypi/picotool/releases/download/${PICOTOOL_VERSION}/picotool-${PICOTOOL_VERSION}.tar.gz -P ${INSTALL_PATH} + if [[ $? != 0 ]] + then + echo "error: unable to get picotool VERSION: ${PICOTOOL_VERSION}" + exit 1 + fi + + mkdir -p ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION} + tar xzvf ${INSTALL_PATH}/picotool-${PICOTOOL_VERSION}.tar.gz -C ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION} + rm ${INSTALL_PATH}/picotool-${PICOTOOL_VERSION}.tar.gz +fi + +echo "building picotool..." +mkdir -p ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION}/build +PICO_SDK_PATH=${INSTALL_PATH}/sdk/${PICOTOOL_VERSION} + +cd ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION}/build +cmake .. +make -C ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION}/build + +picotool_version=$(${INSTALL_PATH}/picotool/${PICOTOOL_VERSION}/build/picotool version) +echo "${picotool_version} compiled successfully" + +echo "adding udev picotool rules..." +sudo cp ${INSTALL_PATH}/picotool/${PICOTOOL_VERSION}/udev/99-picotool.rules /etc/udev/rules.d/ + +echo "picotool installation completed" diff --git a/scripts/install_sdk.bash b/scripts/install_sdk.bash new file mode 100755 index 0000000..1214772 --- /dev/null +++ b/scripts/install_sdk.bash @@ -0,0 +1,55 @@ +#!/bin/bash + +############################################### +# +# Download and install Pico C SDK. +# src: https://github.com/raspberrypi/pico-sdk +# +# ex: ./install_sdk.bash 2.1.0 +# +############################################### + +PICO_SDK_VERSION=$1 +REGEX_VERSION="^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$" + +if [[ -z ${INSTALL_PATH} ]] +then + INSTALL_PATH=${PWD} +fi + +usage() { + echo "usage:" + echo "./install_sdk.bash (ex: ./install_sdk.bash 2.1.0)" +} + +if [[ ! "${PICO_SDK_VERSION}" =~ ${REGEX_VERSION} ]] +then + echo "error: unable to parse the SDK version: '${PICO_SDK_VERSION}'" + usage + exit 1 +fi + +if [[ ! -d ${INSTALL_PATH}/sdk/${PICO_SDK_VERSION} ]] +then + echo "installing dependencies..." + sudo apt install cmake python3 build-essential gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib + + echo "installing Pico C SDK ${PICO_SDK_VERSION}" + + pico_tar_file="pico-sdk-${PICO_SDK_VERSION}.tar.gz" + wget https://github.com/raspberrypi/pico-sdk/releases/download/${PICO_SDK_VERSION}/pico-sdk-${PICO_SDK_VERSION}.tar.gz -P ${INSTALL_PATH} + if [[ $? != 0 ]] + then + echo "error: unable to get pico SDK VERSION: ${PICO_SDK_VERSION}" + exit 1 + fi + + mkdir -p ${INSTALL_PATH}/sdk/${PICO_SDK_VERSION} + tar xzvf ${INSTALL_PATH}/${pico_tar_file} -C ${INSTALL_PATH}/sdk/${PICO_SDK_VERSION} + rm ${INSTALL_PATH}/${pico_tar_file} + + echo "Pico C SDK installed successfully: ${INSTALL_PATH}/sdk/${PICO_SDK_VERSION}" + exit 0 +fi + +echo "Pico C SDK already exists: ${INSTALL_PATH}/sdk/${PICO_SDK_VERSION}" \ No newline at end of file diff --git a/scripts/scaffold_project.bash b/scripts/scaffold_project.bash new file mode 100755 index 0000000..3debc8e --- /dev/null +++ b/scripts/scaffold_project.bash @@ -0,0 +1,82 @@ +#!/bin/bash + +####################################################################### +# +# Generate a new project from templates. +# It scaffold a project, ready to use, in the current directory with: +# * CMakeLists.txt +# * main.c +# +# ./install_sdk.bash +# ex: ./install_sdk.bash +# +# The SDK must be installed before using the script. +# If the SDK is located in a different directory than the project +# set the `INSTALL_PATH` env var to point to the SDK directory. +# +####################################################################### + +PROJECT_NAME=$1 +PICO_SDK_VERSION=$2 +REGEX_VERSION="^[0-9]{1,}\.[0-9]{1,}\.[0-9]{1,}$" + +if [[ -z ${INSTALL_PATH} ]] +then + INSTALL_PATH=${PWD} +fi + +usage() { + echo "usage:" + echo "./scaffold_project.bash (ex: ./scaffold_project.bash test 2.1.0)" +} + +if [[ -z ${PROJECT_NAME} ]] +then + echo "error: project name must not be empty" + usage + exit 1 +fi + +PROJECT_DIR="${PROJECT_NAME}" +if [[ -d ${PROJECT_DIR} ]] +then + echo "error: a project with same name: ${PROJECT_NAME} already exists" + exit 1 +fi + +if [[ ! "${PICO_SDK_VERSION}" =~ ${REGEX_VERSION} ]] +then + echo "error: unable to parse the SDK version: '${PICO_SDK_VERSION}' (ex: ./install_sdk 2.1.0)" + exit 1 +fi + +if [[ ! -d ${INSTALL_PATH}/sdk/${PICO_SDK_VERSION} ]] +then + echo "error: no SDK v${PICO_SDK_VERSION} exists, please make an install first" + exit 1 +fi + +PICO_SDK_PATH=${INSTALL_PATH}/sdk/${PICO_SDK_VERSION} + +mkdir -p ${PROJECT_DIR} + +echo "generating templates..." + +# build from the cmake list template +cp templates/CMakeLists.txt.tpl templates/CMakeLists.txt.tmp +sed -i "s//${PROJECT_NAME}/g" templates/CMakeLists.txt.tmp +mv templates/CMakeLists.txt.tmp ${PROJECT_DIR}/CMakeLists.txt + +# move the c src file into the project folder +cp templates/main.c.tpl templates/main.c.tmp +sed -i "s//${PROJECT_NAME}/g" templates/main.c.tmp +mv templates/main.c.tmp ${PROJECT_DIR}/main.c + +echo "building the project: ${PROJECT_NAME}..." +cd ${PROJECT_DIR} +mkdir -p build +cd build +cmake .. +make -j$(nproc) + +echo "project ${PROJECT_NAME} successfully generated" diff --git a/simple_led/CMakeLists.txt b/simple_led/CMakeLists.txt new file mode 100644 index 0000000..1b47dd3 --- /dev/null +++ b/simple_led/CMakeLists.txt @@ -0,0 +1,39 @@ +# Generated Cmake Pico project file + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_C_COMPILER "/home/romain/Downloads/pico-sdk/toolchain/riscv/bin/riscv32-unknown-elf-gcc") + +# Pull in Raspberry Pi Pico SDK (must be before project) +include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) + +project(simple_led C CXX ASM) + +# Initialise the Raspberry Pi Pico SDK +pico_sdk_init() + +# Add executable. Default name is the project name, version 0.1 + +add_executable(simple_led main.c ) + +pico_set_program_name(simple_led "simple_led") +pico_set_program_version(simple_led "0.1") + +# Modify the below lines to enable/disable output over UART/USB +pico_enable_stdio_uart(simple_led 0) +pico_enable_stdio_usb(simple_led 1) + +# Add the standard library to the build +target_link_libraries(simple_led + pico_stdlib) + +# Add the standard include files to the build +target_include_directories(simple_led PRIVATE + ${CMAKE_CURRENT_LIST_DIR} +) + +pico_add_extra_outputs(simple_led) + diff --git a/simple_led/main.c b/simple_led/main.c new file mode 100644 index 0000000..1483b01 --- /dev/null +++ b/simple_led/main.c @@ -0,0 +1,97 @@ +#include +#include "pico/stdlib.h" +#include + +#ifndef LED_DELAY_MS + #define LED_DELAY_MS 250 +#endif + +#define GPIO_15 15 +#define GPIO_13 13 + +void pico_led_init(void) { + #ifdef PICO_DEFAULT_LED_PIN + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); + #endif + + gpio_init(GPIO_15); + gpio_set_dir(GPIO_15, GPIO_OUT); +} + +void blink_led(void) { + pico_led_init(); + + while (true) { + gpio_put(GPIO_15, false); + gpio_put(PICO_DEFAULT_LED_PIN, true); + + sleep_ms(LED_DELAY_MS); + + gpio_put(GPIO_15, true); + gpio_put(PICO_DEFAULT_LED_PIN, false); + + sleep_ms(1000); + } +} + +enum button_state {OFF, ON}; + +typedef struct state state; +struct state { + int counter; + int bs; + bool can_incr; +}; + +static state global_state = (state) { + .counter = 0, + .can_incr = true +}; + +void incr_counter(state *s) { + if (s != NULL) { + if (s->can_incr) { + s->counter++; + s->can_incr = false; + } + } +} + +void set_can_incr(state *s, bool v) { + if (s != NULL) { + s->can_incr = v; + } +} + +bool can_push(state *s) { + if (s != NULL) + return s->counter <= 10; + return true; +} + + +int main() +{ + gpio_init(GPIO_15); + gpio_set_dir(GPIO_15, GPIO_OUT); + + gpio_init(GPIO_13); + gpio_set_dir(GPIO_13, GPIO_IN); + + while (1) { + // return low level when the button is pressed + if (!gpio_get(GPIO_13)) { + sleep_ms(20); // avoid "bounce" phenomenon (buffeting) + if (!gpio_get(GPIO_13)) { + incr_counter(&global_state); + if (can_push(&global_state)) + gpio_put(GPIO_15, true); + continue; + } + } + set_can_incr(&global_state, true); + gpio_put(GPIO_15, false); + } + +} \ No newline at end of file diff --git a/templates/CMakeLists.txt.tpl b/templates/CMakeLists.txt.tpl new file mode 100644 index 0000000..c8db396 --- /dev/null +++ b/templates/CMakeLists.txt.tpl @@ -0,0 +1,38 @@ +# Generated Cmake Pico project file + +cmake_minimum_required(VERSION 3.13) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Pull in Raspberry Pi Pico SDK (must be before project) +include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake) + +project( C CXX ASM) + +# Initialise the Raspberry Pi Pico SDK +pico_sdk_init() + +# Add executable. Default name is the project name, version 0.1 + +add_executable( main.c ) + +pico_set_program_name( "") +pico_set_program_version( "0.1") + +# Modify the below lines to enable/disable output over UART/USB +pico_enable_stdio_uart( 0) +pico_enable_stdio_usb( 1) + +# Add the standard library to the build +target_link_libraries( + pico_stdlib) + +# Add the standard include files to the build +target_include_directories( PRIVATE + ${CMAKE_CURRENT_LIST_DIR} +) + +pico_add_extra_outputs() + diff --git a/templates/main.c.tpl b/templates/main.c.tpl new file mode 100644 index 0000000..8b848ac --- /dev/null +++ b/templates/main.c.tpl @@ -0,0 +1,12 @@ +#include +#include + +int main() +{ + stdio_init_all(); + + while (true) { + printf(" is running...\n"); + sleep_ms(1000); + } +} \ No newline at end of file