diff --git a/.github/workflows/micropython.yml b/.github/workflows/micropython.yml index 2f920eb..2f2f8dc 100644 --- a/.github/workflows/micropython.yml +++ b/.github/workflows/micropython.yml @@ -66,12 +66,14 @@ jobs: board: PIMORONI_TINYFX env: - RELEASE_FILE: pimoroni-${{matrix.shortname}}-${{github.event.release.tag_name || github.sha}}-micropython.uf2 - RELEASE_FILE_WITH_OS: pimoroni-${{matrix.shortname}}-${{github.event.release.tag_name || github.sha}}-micropython-with-examples.uf2 + RELEASE_FILE: pimoroni-${{matrix.shortname}}-${{github.event.release.tag_name || github.sha}}-micropython FIRMWARE_DIR: "$GITHUB_WORKSPACE/picofx/boards" ROOT_DIR: "$GITHUB_WORKSPACE/picofx" BOARD_DIR: "$GITHUB_WORKSPACE/picofx/boards/${{matrix.board}}" EXAMPLES_DIR: "$GITHUB_WORKSPACE/picofx/examples/${{matrix.shortname}}" + FILESYSTEM_DIR: "$GITHUB_WORKSPACE/picofx/temp" + FILESYSTEM_SUFFIX: "with-libs-and-examples" + BOARD: "PIMORONI_TINYFX" steps: - name: Compiler Cache @@ -123,12 +125,12 @@ jobs: working-directory: micropython run: | git apply "${{env.FIRMWARE_DIR}}/932f76c6ba64c5a3e68de3324556d9979f09303b.patch" - + - name: Install Arm GNU Toolchain (arm-none-eabi-gcc) uses: carlosperate/arm-none-eabi-gcc-action@v1 with: release: '9-2020-q2' - + - name: Install CCache run: | sudo apt update && sudo apt install ccache @@ -152,36 +154,39 @@ jobs: shell: bash working-directory: micropython/ports/rp2/build run: | - cp firmware.uf2 ${{env.RELEASE_FILE}} + cp firmware.uf2 ${{env.RELEASE_FILE}}.uf2 - name: "Py_Decl: Verify UF2" shell: bash run: | - python3 py_decl/py_decl.py --to-json --verify micropython/ports/rp2/build/${{ env.RELEASE_FILE }} + python3 py_decl/py_decl.py --to-json --verify micropython/ports/rp2/build/${{ env.RELEASE_FILE }}.uf2 - name: "HACK: Mangle PicoFX Lib into user filesystem" shell: bash run: | - mkdir -p ${{env.EXAMPLES_DIR}}/lib - cp -v -r ${{env.ROOT_DIR}}/picofx ${{env.EXAMPLES_DIR}}/lib + mkdir -p ${{env.FILESYSTEM_DIR}}/lib + cp -v -r ${{env.ROOT_DIR}}/picofx ${{env.FILESYSTEM_DIR}}/lib + cp -v -r ${{env.BOARD_DIR}}/visible_libs/. ${{env.FILESYSTEM_DIR}}/lib + cp -v -r ${{env.EXAMPLES_DIR}}/. ${{env.FILESYSTEM_DIR}} - name: Append Filesystem shell: bash run: | python3 -m pip install littlefs-python==0.12.0 - ./dir2uf2/dir2uf2 --fs-compact --append-to micropython/ports/rp2/build/${{env.RELEASE_FILE}} --manifest ${{env.EXAMPLES_DIR}}/uf2-manifest.txt --filename with-examples.uf2 ${{env.EXAMPLES_DIR}}/ + ./dir2uf2/dir2uf2 --fs-compact --append-to micropython/ports/rp2/build/${{env.RELEASE_FILE}}.uf2 --manifest ${{env.BOARD_DIR}}/uf2-manifest.txt --filename ${{env.FILESYSTEM_SUFFIX}}.uf2 ${{env.FILESYSTEM_DIR}}/ + - name: Store .uf2 as artifact uses: actions/upload-artifact@v4 with: name: ${{env.RELEASE_FILE}} - path: micropython/ports/rp2/build/${{env.RELEASE_FILE}} + path: micropython/ports/rp2/build/${{env.RELEASE_FILE}}.uf2 - - name: Store .uf2 + Examples as artifact + - name: Store .uf2 + Filesystem as artifact uses: actions/upload-artifact@v4 with: - name: ${{env.RELEASE_FILE_WITH_OS}} - path: ${{env.RELEASE_FILE_WITH_OS}} + name: ${{env.RELEASE_FILE}}-${{env.FILESYSTEM_SUFFIX}} + path: ${{env.RELEASE_FILE}}-${{env.FILESYSTEM_SUFFIX}}.uf2 - name: Upload .uf2 if: github.event_name == 'release' @@ -189,18 +194,18 @@ jobs: env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} with: - asset_path: micropython/ports/rp2/build/${{env.RELEASE_FILE}} + asset_path: micropython/ports/rp2/build/${{env.RELEASE_FILE}}.uf2 upload_url: ${{github.event.release.upload_url}} - asset_name: ${{env.RELEASE_FILE}} + asset_name: ${{env.RELEASE_FILE}}.uf2 asset_content_type: application/octet-stream - - name: Upload .uf2 + Examples + - name: Upload .uf2 + Filesystem if: github.event_name == 'release' uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} with: - asset_path: ${{env.RELEASE_FILE_WITH_OS}} + asset_path: ${{env.RELEASE_FILE}}-${{env.FILESYSTEM_SUFFIX}}.uf2 upload_url: ${{github.event.release.upload_url}} - asset_name: ${{env.RELEASE_FILE_WITH_OS}} + asset_name: ${{env.RELEASE_FILE}}-${{env.FILESYSTEM_SUFFIX}}.uf2 asset_content_type: application/octet-stream diff --git a/boards/PIMORONI_TINYFX/frozen_libs/pimoroni.py b/boards/PIMORONI_TINYFX/frozen_libs/pimoroni.py index 9fe1d4d..c5e047c 100644 --- a/boards/PIMORONI_TINYFX/frozen_libs/pimoroni.py +++ b/boards/PIMORONI_TINYFX/frozen_libs/pimoroni.py @@ -142,47 +142,6 @@ def is_pressed(self): return self.raw() -class RGBLED: - def __init__(self, r, g, b, invert=True, gamma=1): - self._gamma = gamma - self.led_r = PWM(Pin(r), freq=1000, duty_u16=0, invert=invert) - self.led_g = PWM(Pin(g), freq=1000, duty_u16=0, invert=invert) - self.led_b = PWM(Pin(b), freq=1000, duty_u16=0, invert=invert) - - def _rgb(self, r, g, b): - self.led_r.duty_u16(int(pow(r, self._gamma) * 65535 + 0.5)) - self.led_g.duty_u16(int(pow(g, self._gamma) * 65535 + 0.5)) - self.led_b.duty_u16(int(pow(b, self._gamma) * 65535 + 0.5)) - - def set_rgb(self, r, g, b): - r = min(255, max(0, r)) - g = min(255, max(0, g)) - b = min(255, max(0, b)) - self._rgb(r / 255, g / 255, b / 255) - - def set_hsv(self, h, s, v): - if s == 0.0: - self._rgb(v, v, v) - else: - i = int(h * 6.0) - f = (h * 6.0) - i - p, q, t = v * (1.0 - s), v * (1.0 - s * f), v * (1.0 - s * (1.0 - f)) - - i = i % 6 - if i == 0: - self._rgb(v, t, p) - elif i == 1: - self._rgb(q, v, p) - elif i == 2: - self._rgb(p, v, t) - elif i == 3: - self._rgb(p, q, v) - elif i == 4: - self._rgb(t, p, v) - elif i == 5: - self._rgb(v, p, q) - - # A simple class for handling Proportional, Integral & Derivative (PID) control calculations class PID: def __init__(self, kp, ki, kd, sample_rate): @@ -246,25 +205,3 @@ def read(self): def is_set(self, mask): return self.read() & mask == mask - - -# A basic wrapper for PWM with regular on/off and toggle functions from Pin -# Intended to be used for driving LEDs with brightness control & compatibility with Pin -class PWMLED: - def __init__(self, pin, invert=False, gamma=1): - self._gamma = gamma - self._led = PWM(Pin(pin), freq=1000, duty_u16=0, invert=invert) - - def brightness(self, brightness): - brightness = min(1.0, max(0.0, brightness)) - self._brightness = brightness - self._led.duty_u16(int(pow(brightness, self._gamma) * 65535 + 0.5)) - - def on(self): - self.brightness(1) - - def off(self): - self.brightness(0) - - def toggle(self): - self.brightness(1 - self._brightness) diff --git a/examples/tiny_fx/uf2-manifest.txt b/boards/PIMORONI_TINYFX/uf2-manifest.txt similarity index 100% rename from examples/tiny_fx/uf2-manifest.txt rename to boards/PIMORONI_TINYFX/uf2-manifest.txt diff --git a/examples/tiny_fx/lib/audio.py b/boards/PIMORONI_TINYFX/visible_libs/audio.py similarity index 100% rename from examples/tiny_fx/lib/audio.py rename to boards/PIMORONI_TINYFX/visible_libs/audio.py diff --git a/examples/tiny_fx/lib/tiny_fx.py b/boards/PIMORONI_TINYFX/visible_libs/tiny_fx.py similarity index 98% rename from examples/tiny_fx/lib/tiny_fx.py rename to boards/PIMORONI_TINYFX/visible_libs/tiny_fx.py index e7b2591..b3a7f34 100644 --- a/examples/tiny_fx/lib/tiny_fx.py +++ b/boards/PIMORONI_TINYFX/visible_libs/tiny_fx.py @@ -3,8 +3,8 @@ # SPDX-License-Identifier: MIT from machine import ADC, Pin -from pimoroni import PWMLED, RGBLED from pimoroni_i2c import PimoroniI2C +from picofx import PWMLED, RGBLED class TinyFX: diff --git a/picofx/__init__.py b/picofx/__init__.py index da0002b..67766e3 100644 --- a/picofx/__init__.py +++ b/picofx/__init__.py @@ -2,7 +2,65 @@ # # SPDX-License-Identifier: MIT -from machine import Timer +from machine import Pin, PWM, Timer + + +# A basic wrapper for PWM with regular on/off and toggle functions from Pin +# Intended to be used for driving LEDs with brightness control & compatibility with Pin +class PWMLED: + def __init__(self, pin, invert=False, gamma=1): + self.__gamma = gamma + self.__led = PWM(Pin(pin), freq=1000, duty_u16=0, invert=invert) + + def brightness(self, brightness): + self.__brightness = min(1.0, max(0.0, brightness)) + self.__led.duty_u16(int(pow(self.__brightness, self.__gamma) * 65535 + 0.5)) + + def on(self): + self.brightness(1) + + def off(self): + self.brightness(0) + + def toggle(self): + self.brightness(1 - self.__brightness) + + +class RGBLED: + def __init__(self, r, g, b, invert=True, gamma=1): + self.led_r = r if isinstance(r, PWMLED) else PWMLED(r, invert=invert, gamma=gamma) + self.led_g = g if isinstance(g, PWMLED) else PWMLED(g, invert=invert, gamma=gamma) + self.led_b = b if isinstance(b, PWMLED) else PWMLED(b, invert=invert, gamma=gamma) + + def __rgb(self, r, g, b): + self.led_r.brightness(r) + self.led_g.brightness(g) + self.led_b.brightness(b) + + def set_rgb(self, r, g, b): + self.__rgb(r / 255, g / 255, b / 255) + + def set_hsv(self, h, s, v): + if s == 0.0: + self.__rgb(v, v, v) + else: + i = int(h * 6.0) + f = (h * 6.0) - i + p, q, t = v * (1.0 - s), v * (1.0 - s * f), v * (1.0 - s * (1.0 - f)) + + i = i % 6 + if i == 0: + self.__rgb(v, t, p) + elif i == 1: + self.__rgb(q, v, p) + elif i == 2: + self.__rgb(p, v, t) + elif i == 3: + self.__rgb(p, q, v) + elif i == 4: + self.__rgb(t, p, v) + elif i == 5: + self.__rgb(v, p, q) class Updatable: