Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Gadgetoid authored Aug 13, 2024
0 parents commit 3ecdbf4
Show file tree
Hide file tree
Showing 24 changed files with 770 additions and 0 deletions.
129 changes: 129 additions & 0 deletions .github/workflows/micropython.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
name: MicroPython

on:
push:
pull_request:
release:
types: [created]

env:
MICROPYTHON_VERSION: feature/psram
MICROPYTHON_FLAVOUR: pimoroni
PIMORONI_PICO_VERSION: feature/sdk-2.0.0

jobs:
build:
name: ${{ matrix.name }} (${{ matrix.board }} ${{ matrix.variant }} ${{ matrix.modules }})
runs-on: ubuntu-20.04
continue-on-error: true
strategy:
matrix:
include:
- name: pga2040
board: pga2040
modules: default
- name: pga2350
board: pga2350
modules: default
- name: pga2350-psram # Friendly-name for output files
board: pga2350 # /<board>
variant: PSRAM # /<board>/mpconfigvariant_<variant>.cmake
modules: default # /modules/<modules>.cmake

env:
# MicroPython version will be contained in github.event.release.tag_name for releases
RELEASE_FILE: ${{ matrix.name }}-${{ github.event.release.tag_name || github.sha }}-micropython
PIMORONI_PICO_DIR: "${{ github.workspace }}/pimoroni-pico"
MICROPY_BOARD_DIR: "${{ github.workspace }}/src-${{ github.sha }}/${{ matrix.BOARD }}"
USER_C_MODULES: "${{ github.workspace }}/src-${{ github.sha }}/modules/${{ matrix.modules }}.cmake"
TAG_OR_SHA: ${{ github.event.release.tag_name || github.sha }}
MICROPY_BOARD: ${{ matrix.board }}
MICROPY_BOARD_VARIANT: ${{ matrix.variant }}
BOARD_NAME: ${{ matrix.name }}
BUILD_TOOLS: src-${{ github.sha }}/ci/micropython.sh

steps:
- name: "CCache: Restore saved cache"
uses: actions/cache@v4
with:
path: /home/runner/.ccache
key: ccache-micropython-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
restore-keys: |
ccache-micropython-${{ matrix.name }}-${{ github.ref }}
ccache-micropython-${{ matrix.name }}-
- name: "Src: Checkout"
uses: actions/checkout@v4
with:
submodules: true
path: src-${{ github.sha }}

- name: "Pimoroni Pico: Checkout"
uses: actions/checkout@v4
with:
repository: pimoroni/pimoroni-pico
ref: ${{env.PIMORONI_PICO_VERSION}}
submodules: true
path: pimoroni-pico

- name: Install Arm GNU Toolchain (arm-none-eabi-gcc)
uses: carlosperate/arm-none-eabi-gcc-action@v1
with:
release: '9-2020-q2'

- name: "CCache: Install"
run: |
source $BUILD_TOOLS
apt_install_build_deps
- name: "MicroPython: Checkout"
run: |
source $BUILD_TOOLS
micropython_clone
- name: "Py_Decl: Checkout py_decl"
uses: actions/checkout@v4
with:
repository: gadgetoid/py_decl
ref: v0.0.2
path: py_decl

- name: "MicroPython: Build MPY Cross"
run: |
source $BUILD_TOOLS
micropython_build_mpy_cross
- name: "MicroPython: Configure"
shell: bash
run: |
source $BUILD_TOOLS
micropython_version
cmake_configure
- name: "MicroPython: Build"
shell: bash
run: |
source $BUILD_TOOLS
cmake_build
- name: "Py_Decl: Verify UF2"
shell: bash
run: |
python3 py_decl/py_decl.py --to-json --verify build-${{ matrix.name }}/${{ env.RELEASE_FILE }}.uf2
- name: Store .uf2 as artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_FILE }}.uf2
path: build-${{ matrix.name }}/${{ env.RELEASE_FILE }}.uf2

- name: Upload .uf2
if: github.event_name == 'release'
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
asset_path: build-${{ matrix.name }}/firmware.uf2
upload_url: ${{ github.event.release.upload_url }}
asset_name: ${{ env.RELEASE_FILE }}.uf2
asset_content_type: application/octet-stream
39 changes: 39 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Prerequisites
*.d

# Compiled Object files
*.slo
*.lo
*.o
*.obj

# Precompiled Headers
*.gch
*.pch

# Compiled Dynamic libraries
*.so
*.dylib
*.dll

# Fortran module files
*.mod
*.smod

# Compiled Static libraries
*.lai
*.la
*.a
*.lib

# Executables
*.exe
*.out
*.app

**/build
.vscode

# Apple filesystem cruft
.DS_Store
venv
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Pimoroni PGA Boilerplate

This repository is intended to provide a baseline MicroPython build for PGA2040
and PGA2350, in addition to being a minimal example of how you might set up your
own custom MicroPython flavour to support your PGA-based project.

Use this repository as a boilerplate to set up your own project, and GitHub actions
should automatically handle building MicroPython for you.

## Contents

* pga2040 - MicroPython and Pico SDK board definitions for PGA2040
* pga2350 - MicroPython and Pico SDK board definitions for PGA2350, with PSRAM variant
* modules/c/example - An example MicroPython C++ module, demonstrating C class bindings
* modules/py_frozen - Python files intended to be frozen into the firmware
* modules/py_littlefs - Python files intended to be visible/editable in the LittleFS user filesystem
65 changes: 65 additions & 0 deletions ci/micropython.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
export TERM=${TERM:="xterm-256color"}

function log_success {
echo -e "$(tput setaf 2)$1$(tput sgr0)"
}

function log_inform {
echo -e "$(tput setaf 6)$1$(tput sgr0)"
}

function log_warning {
echo -e "$(tput setaf 1)$1$(tput sgr0)"
}

function micropython_clone {
log_inform "Using MicroPython $MICROPYTHON_VERSION"
git clone https://github.com/$MICROPYTHON_FLAVOUR/micropython
cd micropython
git checkout $MICROPYTHON_VERSION
git submodule update --init lib/pico-sdk
git submodule update --init lib/cyw43-driver
git submodule update --init lib/lwip
git submodule update --init lib/mbedtls
git submodule update --init lib/micropython-lib
git submodule update --init lib/tinyusb
git submodule update --init lib/btstack
cd ../
}

function micropython_build_mpy_cross {
cd micropython/mpy-cross
ccache --zero-stats || true
CROSS_COMPILE="ccache " make
ccache --show-stats || true
cd ../../
}

function apt_install_build_deps {
sudo apt update && sudo apt install ccache
}

function micropython_version {
echo "MICROPY_GIT_TAG=$MICROPYTHON_VERSION, $BOARD_NAME $TAG_OR_SHA" >> $GITHUB_ENV
echo "MICROPY_GIT_HASH=$MICROPYTHON_VERSION-$TAG_OR_SHA" >> $GITHUB_ENV
}

function cmake_configure {
cmake -S micropython/ports/rp2 -B build-$BOARD_NAME \
-DPICO_BUILD_DOCS=0 \
-DPICO_NO_COPRO_DIS=1 \
-DUSER_C_MODULES=$USER_C_MODULES \
-DMICROPY_BOARD_DIR=$MICROPY_BOARD_DIR \
-DMICROPY_BOARD=$MICROPY_BOARD \
-DMICROPY_BOARD_VARIANT=$MICROPY_BOARD_VARIANT \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
}

function cmake_build {
ccache --zero-stats || true
cmake --build build-$BOARD_NAME -j 2
ccache --show-stats || true
cd build-$BOARD_NAME
cp firmware.uf2 $RELEASE_FILE.uf2
}
37 changes: 37 additions & 0 deletions modules/c/example/example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <example.h>

MP_DEFINE_CONST_FUN_OBJ_1(example__del__obj, example__del__);

MP_DEFINE_CONST_FUN_OBJ_3(example_method_obj, example_method);

// Class Methods
static const mp_rom_map_elem_t example_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&example__del__obj) },
{ MP_ROM_QSTR(MP_QSTR_mul), MP_ROM_PTR(&example_method_obj) }
};

static MP_DEFINE_CONST_DICT(example_locals_dict, example_locals_dict_table);

MP_DEFINE_CONST_OBJ_TYPE(
Example_type,
MP_QSTR_Example,
MP_TYPE_FLAG_NONE,
make_new, example_make_new,
locals_dict, (mp_obj_dict_t*)&example_locals_dict
);

// Module Methods
static const mp_map_elem_t example_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_example) }, // Module name
{ MP_OBJ_NEW_QSTR(MP_QSTR_Example), (mp_obj_t)&Example_type }, // Class name & type
};

static MP_DEFINE_CONST_DICT(mp_module_example_globals, example_globals_table);

const mp_obj_module_t example_user_c_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t*)&mp_module_example_globals,
};

// First argument should match the __name__ given in the globals table
MP_REGISTER_MODULE(MP_QSTR_example, example_user_c_module);
67 changes: 67 additions & 0 deletions modules/c/example/example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include <new> // Required for allocating C classes into MicroPython heap with placement new

class Example {
public:
Example () {

}

int mul(int a, int b) {
return a * b;
}

~Example () {

}
};

// Explicitly typed variant of MP_OBJ_TO_PTR to make C++ happy
#define MP_OBJ_TO_PTR_T(o, t) ((t *)(o))

// Macro for assigning *self in class methods
#define __self__ MP_OBJ_TO_PTR_T(self_in, Example_obj_t)


extern "C" {
#include "example.h"

typedef struct Example_obj_t {
mp_obj_base_t base;
void *pins;
Example *cls;
} Example_obj_t;

mp_obj_t example_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
Example_obj_t *self = mp_obj_malloc_with_finaliser(Example_obj_t, &Example_type);

// Use C++ "placement new" to place an instance of our C++ class in
// memory allocated by MicroPython's m_new.
self->cls = new(m_new(Example, 1)) Example();

return MP_OBJ_FROM_PTR(self);
}

mp_obj_t example__del__(mp_obj_t self_in) {
// Explicitly call the destructor
// self->class->~Example();

// Or use delete
delete(__self__->cls);

// Explicitly inform the GC that the memory is free
// Usually this object is deleted and the pointer goes out of scope
// and gets GC'd anyway so we don't *need* to do this.
m_del(Example, __self__->cls, 1);

return mp_const_none;
}

mp_obj_t example_method(mp_obj_t self_in, mp_obj_t a_in, mp_obj_t b_in) {
int a = mp_obj_get_int(a_in);
int b = mp_obj_get_int(b_in);

int c = __self__->cls->mul(a, b);

return mp_obj_new_int(c);
}
};
8 changes: 8 additions & 0 deletions modules/c/example/example.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "py/runtime.h"

extern const mp_obj_type_t Example_type;

extern mp_obj_t example_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
extern mp_obj_t example__del__(mp_obj_t self_in);

extern mp_obj_t example_method(mp_obj_t self_in, mp_obj_t a_in, mp_obj_t b_in);
16 changes: 16 additions & 0 deletions modules/c/example/micropython.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Create an INTERFACE library for our CPP module.
add_library(usermod_pga_example INTERFACE)

# Add our source files to the library.
target_sources(usermod_pga_example INTERFACE
${CMAKE_CURRENT_LIST_DIR}/example.cpp
${CMAKE_CURRENT_LIST_DIR}/example.c
)

# Add the current directory as an include directory.
target_include_directories(usermod_pga_example INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)

# Link our INTERFACE library to the usermod target.
target_link_libraries(usermod INTERFACE usermod_pga_example)
Loading

0 comments on commit 3ecdbf4

Please sign in to comment.